text: /**
   * Copyright (c) Facebook, Inc. and its affiliates.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   *
   * 
   * @format
   */
  'use strict';
  
  exports.__esModule = true;
  exports.default = void 0;
  
  var React = _interopRequireWildcard(require("react"));
  
  var _View = _interopRequireDefault(require("../../../exports/View"));
  
  var _VirtualizedList = _interopRequireDefault(require("../VirtualizedList"));
  
  var _invariant = _interopRequireDefault(require("fbjs/lib/invariant"));
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
  
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  
  function _extends() { _extends = Object.assign || 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); }
  
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (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 = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
  
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  
  function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
  
  function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  
  function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  
  /**
   * Right now this just flattens everything into one list and uses VirtualizedList under the
   * hood. The only operation that might not scale well is concatting the data arrays of all the
   * sections when new props are received, which should be plenty fast for up to ~10,000 items.
   */
  var VirtualizedSectionList =
  /*#__PURE__*/
  function (_React$PureComponent) {
    _inheritsLoose(VirtualizedSectionList, _React$PureComponent);
  
    var _proto = VirtualizedSectionList.prototype;
  
    _proto.scrollToLocation = function scrollToLocation(params) {
      var index = params.itemIndex;
  
      for (var i = 0; i < params.sectionIndex; i++) {
        index += this.props.getItemCount(this.props.sections[i].data) + 2;
      }
  
      var viewOffset = 0;
  
      if (params.itemIndex > 0 && this.props.stickySectionHeadersEnabled) {
        var frame = this._listRef._getFrameMetricsApprox(index - params.itemIndex);
  
        viewOffset = frame.length;
      }
  
      var toIndexParams = _objectSpread(_objectSpread({}, params), {}, {
        viewOffset: viewOffset,
        index: index
      });
  
      this._listRef.scrollToIndex(toIndexParams);
    };
  
    _proto.getListRef = function getListRef() {
      return this._listRef;
    };
  
    function VirtualizedSectionList(props, context) {
      var _this;
  
      _this = _React$PureComponent.call(this, props, context) || this;
  
      _this._keyExtractor = function (item, index) {
        var info = _this._subExtractor(index);
  
        return info && info.key || String(index);
      };
  
      _this._convertViewable = function (viewable) {
        (0, _invariant.default)(viewable.index != null, 'Received a broken ViewToken');
  
        var info = _this._subExtractor(viewable.index);
  
        if (!info) {
          return null;
        }
  
        var keyExtractor = info.section.keyExtractor || _this.props.keyExtractor;
        return _objectSpread(_objectSpread({}, viewable), {}, {
          index: info.index,
  
          /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an
           * error found when Flow v0.63 was deployed. To see the error delete this
           * comment and run Flow. */
          key: keyExtractor(viewable.item, info.index),
          section: info.section
        });
      };
  
      _this._onViewableItemsChanged = function (_ref) {
        var viewableItems = _ref.viewableItems,
            changed = _ref.changed;
  
        if (_this.props.onViewableItemsChanged) {
          _this.props.onViewableItemsChanged({
            viewableItems: viewableItems.map(_this._convertViewable, _assertThisInitialized(_this)).filter(Boolean),
            changed: changed.map(_this._convertViewable, _assertThisInitialized(_this)).filter(Boolean)
          });
        }
      };
  
      _this._renderItem = function (_ref2) {
        var item = _ref2.item,
            index = _ref2.index;
  
        var info = _this._subExtractor(index);
  
        if (!info) {
          return null;
        }
  
        var infoIndex = info.index;
  
        if (infoIndex == null) {
          var section = info.section;
  
          if (info.header === true) {
            var renderSectionHeader = _this.props.renderSectionHeader;
            return renderSectionHeader ? renderSectionHeader({
              section: section
            }) : null;
          } else {
            var renderSectionFooter = _this.props.renderSectionFooter;
            return renderSectionFooter ? renderSectionFooter({
              section: section
            }) : null;
          }
        } else {
          var renderItem = info.section.renderItem || _this.props.renderItem;
  
          var SeparatorComponent = _this._getSeparatorComponent(index, info);
  
          (0, _invariant.default)(renderItem, 'no renderItem!');
          return (
            /*#__PURE__*/
            React.createElement(ItemWithSeparator, {
              SeparatorComponent: SeparatorComponent,
              LeadingSeparatorComponent: infoIndex === 0 ? _this.props.SectionSeparatorComponent : undefined,
              cellKey: info.key,
              index: infoIndex,
              item: item,
              leadingItem: info.leadingItem,
              leadingSection: info.leadingSection,
              onUpdateSeparator: _this._onUpdateSeparator,
              prevCellKey: (_this._subExtractor(index - 1) || {}).key,
              ref: function ref(_ref3) {
                _this._cellRefs[info.key] = _ref3;
              },
              renderItem: renderItem,
              section: info.section,
              trailingItem: info.trailingItem,
              trailingSection: info.trailingSection
            })
          );
        }
      };
  
      _this._onUpdateSeparator = function (key, newProps) {
        var ref = _this._cellRefs[key];
        ref && ref.updateSeparatorProps(newProps);
      };
  
      _this._cellRefs = {};
  
      _this._captureRef = function (ref) {
        /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This comment
         * suppresses an error when upgrading Flow's support for React. To see the
         * error delete this comment and run Flow. */
        _this._listRef = ref;
      };
  
      _this.state = _this._computeState(props);
      return _this;
    }
  
    _proto.UNSAFE_componentWillReceiveProps = function UNSAFE_componentWillReceiveProps(nextProps) {
      this.setState(this._computeState(nextProps));
    };
  
    _proto._computeState = function _computeState(props) {
      var offset = props.ListHeaderComponent ? 1 : 0;
      var stickyHeaderIndices = [];
      var itemCount = props.sections ? props.sections.reduce(function (v, section) {
        stickyHeaderIndices.push(v + offset);
        return v + props.getItemCount(section.data) + 2; // Add two for the section header and footer.
      }, 0) : 0;
      return {
        childProps: _objectSpread(_objectSpread({}, props), {}, {
          renderItem: this._renderItem,
          ItemSeparatorComponent: undefined,
          // Rendered with renderItem
          data: props.sections,
          getItemCount: function getItemCount() {
            return itemCount;
          },
          // $FlowFixMe
          getItem: function getItem(sections, index) {
            return _getItem(props, sections, index);
          },
          keyExtractor: this._keyExtractor,
          onViewableItemsChanged: props.onViewableItemsChanged ? this._onViewableItemsChanged : undefined,
          stickyHeaderIndices: props.stickySectionHeadersEnabled ? stickyHeaderIndices : undefined
        })
      };
    };
  
    _proto.render = function render() {
      return (
        /*#__PURE__*/
        React.createElement(_VirtualizedList.default, _extends({}, this.state.childProps, {
          ref: this._captureRef
        }))
      );
    };
  
    _proto._subExtractor = function _subExtractor(index) {
      var itemIndex = index;
      var _this$props = this.props,
          getItem = _this$props.getItem,
          getItemCount = _this$props.getItemCount,
          keyExtractor = _this$props.keyExtractor,
          sections = _this$props.sections;
  
      for (var i = 0; i < sections.length; i++) {
        var section = sections[i];
        var sectionData = section.data;
        var key = section.key || String(i);
        itemIndex -= 1; // The section adds an item for the header
  
        if (itemIndex >= getItemCount(sectionData) + 1) {
          itemIndex -= getItemCount(sectionData) + 1; // The section adds an item for the footer.
        } else if (itemIndex === -1) {
          return {
            section: section,
            key: key + ':header',
            index: null,
            header: true,
            trailingSection: sections[i + 1]
          };
        } else if (itemIndex === getItemCount(sectionData)) {
          return {
            section: section,
            key: key + ':footer',
            index: null,
            header: false,
            trailingSection: sections[i + 1]
          };
        } else {
          var extractor = section.keyExtractor || keyExtractor;
          return {
            section: section,
            key: key + ':' + extractor(getItem(sectionData, itemIndex), itemIndex),
            index: itemIndex,
            leadingItem: getItem(sectionData, itemIndex - 1),
            leadingSection: sections[i - 1],
            trailingItem: getItem(sectionData, itemIndex + 1),
            trailingSection: sections[i + 1]
          };
        }
      }
    };
  
    _proto._getSeparatorComponent = function _getSeparatorComponent(index, info) {
      info = info || this._subExtractor(index);
  
      if (!info) {
        return null;
      }
  
      var ItemSeparatorComponent = info.section.ItemSeparatorComponent || this.props.ItemSeparatorComponent;
      var SectionSeparatorComponent = this.props.SectionSeparatorComponent;
      var isLastItemInList = index === this.state.childProps.getItemCount() - 1;
      var isLastItemInSection = info.index === this.props.getItemCount(info.section.data) - 1;
  
      if (SectionSeparatorComponent && isLastItemInSection) {
        return SectionSeparatorComponent;
      }
  
      if (ItemSeparatorComponent && !isLastItemInSection && !isLastItemInList) {
        return ItemSeparatorComponent;
      }
  
      return null;
    };
  
    return VirtualizedSectionList;
  }(React.PureComponent);
  
  VirtualizedSectionList.defaultProps = _objectSpread(_objectSpread({}, _VirtualizedList.default.defaultProps), {}, {
    data: []
  });
  
  var ItemWithSeparator =
  /*#__PURE__*/
  function (_React$Component) {
    _inheritsLoose(ItemWithSeparator, _React$Component);
  
    function ItemWithSeparator() {
      var _this2;
  
      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }
  
      _this2 = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
      _this2.state = {
        separatorProps: {
          highlighted: false,
          leadingItem: _this2.props.item,
          leadingSection: _this2.props.leadingSection,
          section: _this2.props.section,
          trailingItem: _this2.props.trailingItem,
          trailingSection: _this2.props.trailingSection
        },
        leadingSeparatorProps: {
          highlighted: false,
          leadingItem: _this2.props.leadingItem,
          leadingSection: _this2.props.leadingSection,
          section: _this2.props.section,
          trailingItem: _this2.props.item,
          trailingSection: _this2.props.trailingSection
        }
      };
      _this2._separators = {
        highlight: function highlight() {
          ['leading', 'trailing'].forEach(function (s) {
            return _this2._separators.updateProps(s, {
              highlighted: true
            });
          });
        },
        unhighlight: function unhighlight() {
          ['leading', 'trailing'].forEach(function (s) {
            return _this2._separators.updateProps(s, {
              highlighted: false
            });
          });
        },
        updateProps: function updateProps(select, newProps) {
          var _this2$props = _this2.props,
              LeadingSeparatorComponent = _this2$props.LeadingSeparatorComponent,
              cellKey = _this2$props.cellKey,
              prevCellKey = _this2$props.prevCellKey;
  
          if (select === 'leading' && LeadingSeparatorComponent != null) {
            _this2.setState(function (state) {
              return {
                leadingSeparatorProps: _objectSpread(_objectSpread({}, state.leadingSeparatorProps), newProps)
              };
            });
          } else {
            _this2.props.onUpdateSeparator(select === 'leading' && prevCellKey || cellKey, newProps);
          }
        }
      };
      return _this2;
    }
  
    ItemWithSeparator.getDerivedStateFromProps = function getDerivedStateFromProps(props, prevState) {
      return {
        separatorProps: _objectSpread(_objectSpread({}, prevState.separatorProps), {}, {
          leadingItem: props.item,
          leadingSection: props.leadingSection,
          section: props.section,
          trailingItem: props.trailingItem,
          trailingSection: props.trailingSection
        }),
        leadingSeparatorProps: _objectSpread(_objectSpread({}, prevState.leadingSeparatorProps), {}, {
          leadingItem: props.leadingItem,
          leadingSection: props.leadingSection,
          section: props.section,
          trailingItem: props.item,
          trailingSection: props.trailingSection
        })
      };
    };
  
    var _proto2 = ItemWithSeparator.prototype;
  
    _proto2.updateSeparatorProps = function updateSeparatorProps(newProps) {
      this.setState(function (state) {
        return {
          separatorProps: _objectSpread(_objectSpread({}, state.separatorProps), newProps)
        };
      });
    };
  
    _proto2.render = function render() {
      var _this$props2 = this.props,
          LeadingSeparatorComponent = _this$props2.LeadingSeparatorComponent,
          SeparatorComponent = _this$props2.SeparatorComponent,
          item = _this$props2.item,
          index = _this$props2.index,
          section = _this$props2.section;
      var element = this.props.renderItem({
        item: item,
        index: index,
        section: section,
        separators: this._separators
      });
      var leadingSeparator = LeadingSeparatorComponent &&
      /*#__PURE__*/
      React.createElement(LeadingSeparatorComponent, this.state.leadingSeparatorProps);
      var separator = SeparatorComponent &&
      /*#__PURE__*/
      React.createElement(SeparatorComponent, this.state.separatorProps);
      return leadingSeparator || separator ?
      /*#__PURE__*/
  
      /* $FlowFixMe(>=0.89.0 site=react_native_fb) This comment suppresses an
       * error found when Flow v0.89 was deployed. To see the error, delete
       * this comment and run Flow. */
      React.createElement(_View.default, null, leadingSeparator, element, separator) : element;
    };
  
    return ItemWithSeparator;
  }(React.Component);
  
  function _getItem(props, sections, index) {
    if (!sections) {
      return null;
    }
  
    var itemIdx = index - 1;
  
    for (var i = 0; i < sections.length; i++) {
      var section = sections[i];
      var sectionData = section.data;
      var itemCount = props.getItemCount(sectionData);
  
      if (itemIdx === -1 || itemIdx === itemCount) {
        // We intend for there to be overflow by one on both ends of the list.
        // This will be for headers and footers. When returning a header or footer
        // item the section itself is the item.
        return section;
      } else if (itemIdx < itemCount) {
        // If we are in the bounds of the list's data then return the item.
        return props.getItem(sectionData, itemIdx);
      } else {
        itemIdx -= itemCount + 2; // Add two for the header and footer
      }
    }
  
    return null;
  }
  
  var _default = VirtualizedSectionList;
  exports.default = _default;
  module.exports = exports.default;