text: /**
   * Copyright (c) 2013-present, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * LICENSE file in the root directory of this source tree. An additional grant
   * of patent rights can be found in the PATENTS file in the same directory.
   *
   * @format
   * 
   * @emails oncall+draft_js
   */
  
  'use strict';
  
  var _assign = require('object-assign');
  
  var _extends = _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; };
  
  var ContentBlock = require('./ContentBlock');
  var ContentBlockNode = require('./ContentBlockNode');
  var DraftStringKey = require('./DraftStringKey');
  
  var encodeEntityRanges = require('./encodeEntityRanges');
  var encodeInlineStyleRanges = require('./encodeInlineStyleRanges');
  var invariant = require('fbjs/lib/invariant');
  
  var createRawBlock = function createRawBlock(block, entityStorageMap) {
    return {
      key: block.getKey(),
      text: block.getText(),
      type: block.getType(),
      depth: block.getDepth(),
      inlineStyleRanges: encodeInlineStyleRanges(block),
      entityRanges: encodeEntityRanges(block, entityStorageMap),
      data: block.getData().toObject()
    };
  };
  
  var insertRawBlock = function insertRawBlock(block, entityMap, rawBlocks, blockCacheRef) {
    if (block instanceof ContentBlock) {
      rawBlocks.push(createRawBlock(block, entityMap));
      return;
    }
  
    !(block instanceof ContentBlockNode) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'block is not a BlockNode') : invariant(false) : void 0;
  
    var parentKey = block.getParentKey();
    var rawBlock = blockCacheRef[block.getKey()] = _extends({}, createRawBlock(block, entityMap), {
      children: []
    });
  
    if (parentKey) {
      blockCacheRef[parentKey].children.push(rawBlock);
      return;
    }
  
    rawBlocks.push(rawBlock);
  };
  
  var encodeRawBlocks = function encodeRawBlocks(contentState, rawState) {
    var entityMap = rawState.entityMap;
  
  
    var rawBlocks = [];
  
    var blockCacheRef = {};
    var entityCacheRef = {};
    var entityStorageKey = 0;
  
    contentState.getBlockMap().forEach(function (block) {
      block.findEntityRanges(function (character) {
        return character.getEntity() !== null;
      }, function (start) {
        var entityKey = block.getEntityAt(start);
        // Stringify to maintain order of otherwise numeric keys.
        var stringifiedEntityKey = DraftStringKey.stringify(entityKey);
        // This makes this function resilient to two entities
        // erroneously having the same key
        if (entityCacheRef[stringifiedEntityKey]) {
          return;
        }
        entityCacheRef[stringifiedEntityKey] = entityKey;
        // we need the `any` casting here since this is a temporary state
        // where we will later on flip the entity map and populate it with
        // real entity, at this stage we just need to map back the entity
        // key used by the BlockNode
        entityMap[stringifiedEntityKey] = '' + entityStorageKey;
        entityStorageKey++;
      });
  
      insertRawBlock(block, entityMap, rawBlocks, blockCacheRef);
    });
  
    return {
      blocks: rawBlocks,
      entityMap: entityMap
    };
  };
  
  // Flip storage map so that our storage keys map to global
  // DraftEntity keys.
  var encodeRawEntityMap = function encodeRawEntityMap(contentState, rawState) {
    var blocks = rawState.blocks,
        entityMap = rawState.entityMap;
  
  
    var rawEntityMap = {};
  
    Object.keys(entityMap).forEach(function (key, index) {
      var entity = contentState.getEntity(DraftStringKey.unstringify(key));
      rawEntityMap[index] = {
        type: entity.getType(),
        mutability: entity.getMutability(),
        data: entity.getData()
      };
    });
  
    return {
      blocks: blocks,
      entityMap: rawEntityMap
    };
  };
  
  var convertFromDraftStateToRaw = function convertFromDraftStateToRaw(contentState) {
    var rawDraftContentState = {
      entityMap: {},
      blocks: []
    };
  
    // add blocks
    rawDraftContentState = encodeRawBlocks(contentState, rawDraftContentState);
  
    // add entities
    rawDraftContentState = encodeRawEntityMap(contentState, rawDraftContentState);
  
    return rawDraftContentState;
  };
  
  module.exports = convertFromDraftStateToRaw;