{"ast":null,"code":"import { ConnectableObservable, isObservable, of, Subject } from 'rxjs';\nimport * as i0 from '@angular/core';\nimport { InjectionToken, Injectable } from '@angular/core';\nclass DataSource {}\n/** Checks whether an object is a data source. */\nfunction isDataSource(value) {\n  // Check if the value is a DataSource by observing if it has a connect function. Cannot\n  // be checked as an `instanceof DataSource` since people could create their own sources\n  // that match the interface, but don't extend DataSource. We also can't use `isObservable`\n  // here, because of some internal apps.\n  return value && typeof value.connect === 'function' && !(value instanceof ConnectableObservable);\n}\n\n/** DataSource wrapper for a native array. */\nclass ArrayDataSource extends DataSource {\n  constructor(_data) {\n    super();\n    this._data = _data;\n  }\n  connect() {\n    return isObservable(this._data) ? this._data : of(this._data);\n  }\n  disconnect() {}\n}\n\n/** Indicates how a view was changed by a {@link _ViewRepeater}. */\nvar _ViewRepeaterOperation = /*#__PURE__*/function (_ViewRepeaterOperation) {\n  /** The content of an existing view was replaced with another item. */\n  _ViewRepeaterOperation[_ViewRepeaterOperation[\"REPLACED\"] = 0] = \"REPLACED\";\n  /** A new view was created with `createEmbeddedView`. */\n  _ViewRepeaterOperation[_ViewRepeaterOperation[\"INSERTED\"] = 1] = \"INSERTED\";\n  /** The position of a view changed, but the content remains the same. */\n  _ViewRepeaterOperation[_ViewRepeaterOperation[\"MOVED\"] = 2] = \"MOVED\";\n  /** A view was detached from the view container. */\n  _ViewRepeaterOperation[_ViewRepeaterOperation[\"REMOVED\"] = 3] = \"REMOVED\";\n  return _ViewRepeaterOperation;\n}(_ViewRepeaterOperation || {});\n/**\n * Injection token for {@link _ViewRepeater}. This token is for use by Angular Material only.\n * @docs-private\n */\nconst _VIEW_REPEATER_STRATEGY = /*#__PURE__*/new InjectionToken('_ViewRepeater');\n\n/**\n * A repeater that destroys views when they are removed from a\n * {@link ViewContainerRef}. When new items are inserted into the container,\n * the repeater will always construct a new embedded view for each item.\n *\n * @template T The type for the embedded view's $implicit property.\n * @template R The type for the item in each IterableDiffer change record.\n * @template C The type for the context passed to each embedded view.\n */\nclass _DisposeViewRepeaterStrategy {\n  applyChanges(changes, viewContainerRef, itemContextFactory, itemValueResolver, itemViewChanged) {\n    changes.forEachOperation((record, adjustedPreviousIndex, currentIndex) => {\n      let view;\n      let operation;\n      if (record.previousIndex == null) {\n        const insertContext = itemContextFactory(record, adjustedPreviousIndex, currentIndex);\n        view = viewContainerRef.createEmbeddedView(insertContext.templateRef, insertContext.context, insertContext.index);\n        operation = _ViewRepeaterOperation.INSERTED;\n      } else if (currentIndex == null) {\n        viewContainerRef.remove(adjustedPreviousIndex);\n        operation = _ViewRepeaterOperation.REMOVED;\n      } else {\n        view = viewContainerRef.get(adjustedPreviousIndex);\n        viewContainerRef.move(view, currentIndex);\n        operation = _ViewRepeaterOperation.MOVED;\n      }\n      if (itemViewChanged) {\n        itemViewChanged({\n          context: view?.context,\n          operation,\n          record\n        });\n      }\n    });\n  }\n  detach() {}\n}\n\n/**\n * A repeater that caches views when they are removed from a\n * {@link ViewContainerRef}. When new items are inserted into the container,\n * the repeater will reuse one of the cached views instead of creating a new\n * embedded view. Recycling cached views reduces the quantity of expensive DOM\n * inserts.\n *\n * @template T The type for the embedded view's $implicit property.\n * @template R The type for the item in each IterableDiffer change record.\n * @template C The type for the context passed to each embedded view.\n */\nclass _RecycleViewRepeaterStrategy {\n  constructor() {\n    /**\n     * The size of the cache used to store unused views.\n     * Setting the cache size to `0` will disable caching. Defaults to 20 views.\n     */\n    this.viewCacheSize = 20;\n    /**\n     * View cache that stores embedded view instances that have been previously stamped out,\n     * but don't are not currently rendered. The view repeater will reuse these views rather than\n     * creating brand new ones.\n     *\n     * TODO(michaeljamesparsons) Investigate whether using a linked list would improve performance.\n     */\n    this._viewCache = [];\n  }\n  /** Apply changes to the DOM. */\n  applyChanges(changes, viewContainerRef, itemContextFactory, itemValueResolver, itemViewChanged) {\n    // Rearrange the views to put them in the right location.\n    changes.forEachOperation((record, adjustedPreviousIndex, currentIndex) => {\n      let view;\n      let operation;\n      if (record.previousIndex == null) {\n        // Item added.\n        const viewArgsFactory = () => itemContextFactory(record, adjustedPreviousIndex, currentIndex);\n        view = this._insertView(viewArgsFactory, currentIndex, viewContainerRef, itemValueResolver(record));\n        operation = view ? _ViewRepeaterOperation.INSERTED : _ViewRepeaterOperation.REPLACED;\n      } else if (currentIndex == null) {\n        // Item removed.\n        this._detachAndCacheView(adjustedPreviousIndex, viewContainerRef);\n        operation = _ViewRepeaterOperation.REMOVED;\n      } else {\n        // Item moved.\n        view = this._moveView(adjustedPreviousIndex, currentIndex, viewContainerRef, itemValueResolver(record));\n        operation = _ViewRepeaterOperation.MOVED;\n      }\n      if (itemViewChanged) {\n        itemViewChanged({\n          context: view?.context,\n          operation,\n          record\n        });\n      }\n    });\n  }\n  detach() {\n    for (const view of this._viewCache) {\n      view.destroy();\n    }\n    this._viewCache = [];\n  }\n  /**\n   * Inserts a view for a new item, either from the cache or by creating a new\n   * one. Returns `undefined` if the item was inserted into a cached view.\n   */\n  _insertView(viewArgsFactory, currentIndex, viewContainerRef, value) {\n    const cachedView = this._insertViewFromCache(currentIndex, viewContainerRef);\n    if (cachedView) {\n      cachedView.context.$implicit = value;\n      return undefined;\n    }\n    const viewArgs = viewArgsFactory();\n    return viewContainerRef.createEmbeddedView(viewArgs.templateRef, viewArgs.context, viewArgs.index);\n  }\n  /** Detaches the view at the given index and inserts into the view cache. */\n  _detachAndCacheView(index, viewContainerRef) {\n    const detachedView = viewContainerRef.detach(index);\n    this._maybeCacheView(detachedView, viewContainerRef);\n  }\n  /** Moves view at the previous index to the current index. */\n  _moveView(adjustedPreviousIndex, currentIndex, viewContainerRef, value) {\n    const view = viewContainerRef.get(adjustedPreviousIndex);\n    viewContainerRef.move(view, currentIndex);\n    view.context.$implicit = value;\n    return view;\n  }\n  /**\n   * Cache the given detached view. If the cache is full, the view will be\n   * destroyed.\n   */\n  _maybeCacheView(view, viewContainerRef) {\n    if (this._viewCache.length < this.viewCacheSize) {\n      this._viewCache.push(view);\n    } else {\n      const index = viewContainerRef.indexOf(view);\n      // The host component could remove views from the container outside of\n      // the view repeater. It's unlikely this will occur, but just in case,\n      // destroy the view on its own, otherwise destroy it through the\n      // container to ensure that all the references are removed.\n      if (index === -1) {\n        view.destroy();\n      } else {\n        viewContainerRef.remove(index);\n      }\n    }\n  }\n  /** Inserts a recycled view from the cache at the given index. */\n  _insertViewFromCache(index, viewContainerRef) {\n    const cachedView = this._viewCache.pop();\n    if (cachedView) {\n      viewContainerRef.insert(cachedView, index);\n    }\n    return cachedView || null;\n  }\n}\n\n/**\n * Class to be used to power selecting one or more options from a list.\n */\nclass SelectionModel {\n  /** Selected values. */\n  get selected() {\n    if (!this._selected) {\n      this._selected = Array.from(this._selection.values());\n    }\n    return this._selected;\n  }\n  constructor(_multiple = false, initiallySelectedValues, _emitChanges = true, compareWith) {\n    this._multiple = _multiple;\n    this._emitChanges = _emitChanges;\n    this.compareWith = compareWith;\n    /** Currently-selected values. */\n    this._selection = new Set();\n    /** Keeps track of the deselected options that haven't been emitted by the change event. */\n    this._deselectedToEmit = [];\n    /** Keeps track of the selected options that haven't been emitted by the change event. */\n    this._selectedToEmit = [];\n    /** Event emitted when the value has changed. */\n    this.changed = new Subject();\n    if (initiallySelectedValues && initiallySelectedValues.length) {\n      if (_multiple) {\n        initiallySelectedValues.forEach(value => this._markSelected(value));\n      } else {\n        this._markSelected(initiallySelectedValues[0]);\n      }\n      // Clear the array in order to avoid firing the change event for preselected values.\n      this._selectedToEmit.length = 0;\n    }\n  }\n  /**\n   * Selects a value or an array of values.\n   * @param values The values to select\n   * @return Whether the selection changed as a result of this call\n   * @breaking-change 16.0.0 make return type boolean\n   */\n  select(...values) {\n    this._verifyValueAssignment(values);\n    values.forEach(value => this._markSelected(value));\n    const changed = this._hasQueuedChanges();\n    this._emitChangeEvent();\n    return changed;\n  }\n  /**\n   * Deselects a value or an array of values.\n   * @param values The values to deselect\n   * @return Whether the selection changed as a result of this call\n   * @breaking-change 16.0.0 make return type boolean\n   */\n  deselect(...values) {\n    this._verifyValueAssignment(values);\n    values.forEach(value => this._unmarkSelected(value));\n    const changed = this._hasQueuedChanges();\n    this._emitChangeEvent();\n    return changed;\n  }\n  /**\n   * Sets the selected values\n   * @param values The new selected values\n   * @return Whether the selection changed as a result of this call\n   * @breaking-change 16.0.0 make return type boolean\n   */\n  setSelection(...values) {\n    this._verifyValueAssignment(values);\n    const oldValues = this.selected;\n    const newSelectedSet = new Set(values);\n    values.forEach(value => this._markSelected(value));\n    oldValues.filter(value => !newSelectedSet.has(this._getConcreteValue(value, newSelectedSet))).forEach(value => this._unmarkSelected(value));\n    const changed = this._hasQueuedChanges();\n    this._emitChangeEvent();\n    return changed;\n  }\n  /**\n   * Toggles a value between selected and deselected.\n   * @param value The value to toggle\n   * @return Whether the selection changed as a result of this call\n   * @breaking-change 16.0.0 make return type boolean\n   */\n  toggle(value) {\n    return this.isSelected(value) ? this.deselect(value) : this.select(value);\n  }\n  /**\n   * Clears all of the selected values.\n   * @param flushEvent Whether to flush the changes in an event.\n   *   If false, the changes to the selection will be flushed along with the next event.\n   * @return Whether the selection changed as a result of this call\n   * @breaking-change 16.0.0 make return type boolean\n   */\n  clear(flushEvent = true) {\n    this._unmarkAll();\n    const changed = this._hasQueuedChanges();\n    if (flushEvent) {\n      this._emitChangeEvent();\n    }\n    return changed;\n  }\n  /**\n   * Determines whether a value is selected.\n   */\n  isSelected(value) {\n    return this._selection.has(this._getConcreteValue(value));\n  }\n  /**\n   * Determines whether the model does not have a value.\n   */\n  isEmpty() {\n    return this._selection.size === 0;\n  }\n  /**\n   * Determines whether the model has a value.\n   */\n  hasValue() {\n    return !this.isEmpty();\n  }\n  /**\n   * Sorts the selected values based on a predicate function.\n   */\n  sort(predicate) {\n    if (this._multiple && this.selected) {\n      this._selected.sort(predicate);\n    }\n  }\n  /**\n   * Gets whether multiple values can be selected.\n   */\n  isMultipleSelection() {\n    return this._multiple;\n  }\n  /** Emits a change event and clears the records of selected and deselected values. */\n  _emitChangeEvent() {\n    // Clear the selected values so they can be re-cached.\n    this._selected = null;\n    if (this._selectedToEmit.length || this._deselectedToEmit.length) {\n      this.changed.next({\n        source: this,\n        added: this._selectedToEmit,\n        removed: this._deselectedToEmit\n      });\n      this._deselectedToEmit = [];\n      this._selectedToEmit = [];\n    }\n  }\n  /** Selects a value. */\n  _markSelected(value) {\n    value = this._getConcreteValue(value);\n    if (!this.isSelected(value)) {\n      if (!this._multiple) {\n        this._unmarkAll();\n      }\n      if (!this.isSelected(value)) {\n        this._selection.add(value);\n      }\n      if (this._emitChanges) {\n        this._selectedToEmit.push(value);\n      }\n    }\n  }\n  /** Deselects a value. */\n  _unmarkSelected(value) {\n    value = this._getConcreteValue(value);\n    if (this.isSelected(value)) {\n      this._selection.delete(value);\n      if (this._emitChanges) {\n        this._deselectedToEmit.push(value);\n      }\n    }\n  }\n  /** Clears out the selected values. */\n  _unmarkAll() {\n    if (!this.isEmpty()) {\n      this._selection.forEach(value => this._unmarkSelected(value));\n    }\n  }\n  /**\n   * Verifies the value assignment and throws an error if the specified value array is\n   * including multiple values while the selection model is not supporting multiple values.\n   */\n  _verifyValueAssignment(values) {\n    if (values.length > 1 && !this._multiple && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n      throw getMultipleValuesInSingleSelectionError();\n    }\n  }\n  /** Whether there are queued up change to be emitted. */\n  _hasQueuedChanges() {\n    return !!(this._deselectedToEmit.length || this._selectedToEmit.length);\n  }\n  /** Returns a value that is comparable to inputValue by applying compareWith function, returns the same inputValue otherwise. */\n  _getConcreteValue(inputValue, selection) {\n    if (!this.compareWith) {\n      return inputValue;\n    } else {\n      selection = selection ?? this._selection;\n      for (let selectedValue of selection) {\n        if (this.compareWith(inputValue, selectedValue)) {\n          return selectedValue;\n        }\n      }\n      return inputValue;\n    }\n  }\n}\n/**\n * Returns an error that reports that multiple values are passed into a selection model\n * with a single value.\n * @docs-private\n */\nfunction getMultipleValuesInSingleSelectionError() {\n  return Error('Cannot pass multiple values into SelectionModel with single-value mode.');\n}\n\n/**\n * Class to coordinate unique selection based on name.\n * Intended to be consumed as an Angular service.\n * This service is needed because native radio change events are only fired on the item currently\n * being selected, and we still need to uncheck the previous selection.\n *\n * This service does not *store* any IDs and names because they may change at any time, so it is\n * less error-prone if they are simply passed through when the events occur.\n */\nlet UniqueSelectionDispatcher = /*#__PURE__*/(() => {\n  class UniqueSelectionDispatcher {\n    constructor() {\n      this._listeners = [];\n    }\n    /**\n     * Notify other items that selection for the given name has been set.\n     * @param id ID of the item.\n     * @param name Name of the item.\n     */\n    notify(id, name) {\n      for (let listener of this._listeners) {\n        listener(id, name);\n      }\n    }\n    /**\n     * Listen for future changes to item selection.\n     * @return Function used to deregister listener\n     */\n    listen(listener) {\n      this._listeners.push(listener);\n      return () => {\n        this._listeners = this._listeners.filter(registered => {\n          return listener !== registered;\n        });\n      };\n    }\n    ngOnDestroy() {\n      this._listeners = [];\n    }\n    static #_ = this.ɵfac = function UniqueSelectionDispatcher_Factory(t) {\n      return new (t || UniqueSelectionDispatcher)();\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: UniqueSelectionDispatcher,\n      factory: UniqueSelectionDispatcher.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return UniqueSelectionDispatcher;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { ArrayDataSource, DataSource, SelectionModel, UniqueSelectionDispatcher, _DisposeViewRepeaterStrategy, _RecycleViewRepeaterStrategy, _VIEW_REPEATER_STRATEGY, _ViewRepeaterOperation, getMultipleValuesInSingleSelectionError, isDataSource };\n//# sourceMappingURL=collections.mjs.map","map":null,"metadata":{},"sourceType":"module","externalDependencies":[]}