text: /**
   * Copyright (c) Nicolas Gallagher.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   *
   * 
   */
  var slice = Array.prototype.slice;
  /**
   * Order-based insertion of CSS.
   *
   * Each rule is associated with a numerically defined group.
   * Groups are ordered within the style sheet according to their number, with the
   * lowest first.
   *
   * Groups are implemented using marker rules. The selector of the first rule of
   * each group is used only to encode the group number for hydration. An
   * alternative implementation could rely on CSSMediaRule, allowing groups to be
   * treated as a sub-sheet, but the Edge implementation of CSSMediaRule is
   * broken.
   * https://developer.mozilla.org/en-US/docs/Web/API/CSSMediaRule
   * https://gist.github.com/necolas/aa0c37846ad6bd3b05b727b959e82674
   */
  
  export default function createOrderedCSSStyleSheet(sheet) {
    var groups = {};
    var selectors = {};
    /**
     * Hydrate approximate record from any existing rules in the sheet.
     */
  
    if (sheet != null) {
      var group;
      slice.call(sheet.cssRules).forEach(function (cssRule, i) {
        var cssText = cssRule.cssText; // Create record of existing selectors and rules
  
        if (cssText.indexOf('stylesheet-group') > -1) {
          group = decodeGroupRule(cssRule);
          groups[group] = {
            start: i,
            rules: [cssText]
          };
        } else {
          var selectorText = getSelectorText(cssText);
  
          if (selectorText != null) {
            selectors[selectorText] = true;
            groups[group].rules.push(cssText);
          }
        }
      });
    }
  
    function sheetInsert(sheet, group, text) {
      var orderedGroups = getOrderedGroups(groups);
      var groupIndex = orderedGroups.indexOf(group);
      var nextGroupIndex = groupIndex + 1;
      var nextGroup = orderedGroups[nextGroupIndex]; // Insert rule before the next group, or at the end of the stylesheet
  
      var position = nextGroup != null && groups[nextGroup].start != null ? groups[nextGroup].start : sheet.cssRules.length;
      var isInserted = insertRuleAt(sheet, text, position);
  
      if (isInserted) {
        // Set the starting index of the new group
        if (groups[group].start == null) {
          groups[group].start = position;
        } // Increment the starting index of all subsequent groups
  
  
        for (var i = nextGroupIndex; i < orderedGroups.length; i += 1) {
          var groupNumber = orderedGroups[i];
          var previousStart = groups[groupNumber].start || 0;
          groups[groupNumber].start = previousStart + 1;
        }
      }
  
      return isInserted;
    }
  
    var OrderedCSSStyleSheet = {
      /**
       * The textContent of the style sheet.
       */
      getTextContent: function getTextContent() {
        return getOrderedGroups(groups).map(function (group) {
          var rules = groups[group].rules;
          return rules.join('\n');
        }).join('\n');
      },
  
      /**
       * Insert a rule into the style sheet
       */
      insert: function insert(cssText, groupValue) {
        var group = Number(groupValue); // Create a new group.
  
        if (groups[group] == null) {
          var markerRule = encodeGroupRule(group); // Create the internal record.
  
          groups[group] = {
            start: null,
            rules: [markerRule]
          }; // Update CSSOM.
  
          if (sheet != null) {
            sheetInsert(sheet, group, markerRule);
          }
        } // selectorText is more reliable than cssText for insertion checks. The
        // browser excludes vendor-prefixed properties and rewrites certain values
        // making cssText more likely to be different from what was inserted.
  
  
        var selectorText = getSelectorText(cssText);
  
        if (selectorText != null && selectors[selectorText] == null) {
          // Update the internal records.
          selectors[selectorText] = true;
          groups[group].rules.push(cssText); // Update CSSOM.
  
          if (sheet != null) {
            var isInserted = sheetInsert(sheet, group, cssText);
  
            if (!isInserted) {
              // Revert internal record change if a rule was rejected (e.g.,
              // unrecognized pseudo-selector)
              groups[group].rules.pop();
            }
          }
        }
      }
    };
    return OrderedCSSStyleSheet;
  }
  /**
   * Helper functions
   */
  
  function encodeGroupRule(group) {
    return "[stylesheet-group=\"" + group + "\"]{}";
  }
  
  function decodeGroupRule(cssRule) {
    return Number(cssRule.selectorText.split(/["']/)[1]);
  }
  
  function getOrderedGroups(obj) {
    return Object.keys(obj).map(Number).sort(function (a, b) {
      return a > b ? 1 : -1;
    });
  }
  
  var pattern = /\s*([,])\s*/g;
  
  function getSelectorText(cssText) {
    var selector = cssText.split('{')[0].trim();
    return selector !== '' ? selector.replace(pattern, '$1') : null;
  }
  
  function insertRuleAt(root, cssText, position) {
    try {
      // $FlowFixMe: Flow is missing CSSOM types needed to type 'root'.
      root.insertRule(cssText, position);
      return true;
    } catch (e) {
      // JSDOM doesn't support `CSSSMediaRule#insertRule`.
      // Also ignore errors that occur from attempting to insert vendor-prefixed selectors.
      return false;
    }
  }