text: "use strict";
  var __extends = (this && this.__extends) || function (d, b) {
      for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
      function __() { this.constructor = d; }
      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  };
  /**
   * Increment through IDs for FreeStyle, which can't generate hashed IDs.
   */
  var instanceId = 0;
  /**
   * CSS properties that are valid unit-less numbers.
   */
  var CSS_NUMBER = {
      'box-flex': true,
      'box-flex-group': true,
      'column-count': true,
      'flex': true,
      'flex-grow': true,
      'flex-positive': true,
      'flex-shrink': true,
      'flex-negative': true,
      'font-weight': true,
      'line-clamp': true,
      'line-height': true,
      'opacity': true,
      'order': true,
      'orphans': true,
      'tab-size': true,
      'widows': true,
      'z-index': true,
      'zoom': true,
      // SVG properties.
      'fill-opacity': true,
      'stroke-dashoffset': true,
      'stroke-opacity': true,
      'stroke-width': true
  };
  // Add vendor prefixes to all unit-less properties.
  for (var _i = 0, _a = ['-webkit-', '-ms-', '-moz-', '-o-']; _i < _a.length; _i++) {
      var prefix = _a[_i];
      for (var _b = 0, _c = Object.keys(CSS_NUMBER); _b < _c.length; _b++) {
          var property = _c[_b];
          CSS_NUMBER[prefix + property] = true;
      }
  }
  /**
   * Transform a JavaScript property into a CSS property.
   */
  function hyphenate(propertyName) {
      return propertyName
          .replace(/([A-Z])/g, '-$1')
          .replace(/^ms-/, '-ms-') // Internet Explorer vendor prefix.
          .toLowerCase();
  }
  /**
   * Check if a property name should pop to the top level of CSS.
   */
  function isAtRule(propertyName) {
      return propertyName.charAt(0) === '@';
  }
  /**
   * Check if a value is a nested style definition.
   */
  function isNestedStyle(value) {
      return value != null && typeof value === 'object' && !Array.isArray(value);
  }
  /**
   * Generate a hash value from a string.
   */
  function stringHash(str) {
      var value = 5381;
      var i = str.length;
      while (i) {
          value = (value * 33) ^ str.charCodeAt(--i);
      }
      return (value >>> 0).toString(36);
  }
  exports.stringHash = stringHash;
  /**
   * Transform a style string to a CSS string.
   */
  function styleToString(name, value) {
      if (typeof value === 'number' && value !== 0 && !CSS_NUMBER[name]) {
          value += 'px';
      }
      return name + ":" + String(value).replace(/([\{\}\[\]])/g, '\\$1');
  }
  /**
   * Sort an array of tuples by first value.
   */
  function sortTuples(value) {
      return value.sort(function (a, b) { return a[0] > b[0] ? 1 : -1; });
  }
  /**
   * Categorize user styles.
   */
  function parseUserStyles(styles, hasNestedStyles) {
      var properties = [];
      var nestedStyles = [];
      // Sort keys before adding to styles.
      for (var _i = 0, _a = Object.keys(styles); _i < _a.length; _i++) {
          var key = _a[_i];
          var value = styles[key];
          if (isNestedStyle(value)) {
              nestedStyles.push([key.trim(), value]);
          }
          else {
              properties.push([hyphenate(key.trim()), value]);
          }
      }
      return {
          properties: sortTuples(properties),
          nestedStyles: hasNestedStyles ? nestedStyles : sortTuples(nestedStyles)
      };
  }
  /**
   * Stringify an array of property tuples.
   */
  function stringifyProperties(properties) {
      var result = [];
      var _loop_1 = function(name_1, value) {
          if (value != null) {
              if (Array.isArray(value)) {
                  result.push(value.filter(function (x) { return x != null; }).map(function (x) { return styleToString(name_1, x); }).join(';'));
              }
              else {
                  result.push(styleToString(name_1, value));
              }
          }
      };
      for (var _i = 0, properties_1 = properties; _i < properties_1.length; _i++) {
          var _a = properties_1[_i], name_1 = _a[0], value = _a[1];
          _loop_1(name_1, value);
      }
      return result.join(';');
  }
  /**
   * Interpolate CSS selectors.
   */
  function interpolate(selector, parent) {
      if (selector.indexOf('&') > -1) {
          return selector.replace(/&/g, parent);
      }
      return parent + " " + selector;
  }
  /**
   * Register all styles, but collect for post-selector correction using the hash.
   */
  function collectHashedStyles(container, userStyles, isStyle, displayName) {
      var styles = [];
      function stylize(cache, userStyles, selector) {
          var _a = parseUserStyles(userStyles, isStyle), properties = _a.properties, nestedStyles = _a.nestedStyles;
          var styleString = stringifyProperties(properties);
          var pid = styleString;
          // Only create style instances when styles exists.
          if (styleString) {
              var style = new Style(styleString, cache.hash);
              cache.add(style);
              styles.push([cache, selector, style]);
          }
          for (var _i = 0, nestedStyles_1 = nestedStyles; _i < nestedStyles_1.length; _i++) {
              var _b = nestedStyles_1[_i], name_2 = _b[0], value = _b[1];
              pid += name_2;
              if (isAtRule(name_2)) {
                  var rule = cache.add(new Rule(name_2, undefined, cache.hash));
                  pid += stylize(rule, value, selector);
              }
              else {
                  pid += stylize(cache, value, isStyle ? interpolate(name_2, selector) : name_2);
              }
          }
          return pid;
      }
      // Create a temporary cache to handle changes/mutations before re-assigning later.
      var cache = new Cache(container.hash);
      var pid = stylize(cache, userStyles, '&');
      var hash = "f" + cache.hash(pid);
      var id = displayName ? displayName + "_" + hash : hash;
      for (var _i = 0, styles_1 = styles; _i < styles_1.length; _i++) {
          var _a = styles_1[_i], cache_1 = _a[0], selector = _a[1], style = _a[2];
          var key = isStyle ? interpolate(selector, "." + id) : selector;
          cache_1.get(style).add(new Selector(key, style.hash, undefined, pid));
      }
      container.merge(cache);
      return { pid: pid, id: id };
  }
  /**
   * Recursively register styles on a container instance.
   */
  function registerUserStyles(container, styles, displayName) {
      return collectHashedStyles(container, styles, true, displayName).id;
  }
  /**
   * Create user rule. Simplified collection of styles, since it doesn't need a unique id hash.
   */
  function registerUserRule(container, selector, styles) {
      var _a = parseUserStyles(styles, false), properties = _a.properties, nestedStyles = _a.nestedStyles;
      // Throw when using properties and nested styles together in rule.
      if (properties.length && nestedStyles.length) {
          throw new TypeError("Registering a CSS rule can not use properties with nested styles");
      }
      var styleString = stringifyProperties(properties);
      var rule = new Rule(selector, styleString, container.hash);
      for (var _i = 0, nestedStyles_2 = nestedStyles; _i < nestedStyles_2.length; _i++) {
          var _b = nestedStyles_2[_i], name_3 = _b[0], value = _b[1];
          registerUserRule(rule, name_3, value);
      }
      container.add(rule);
  }
  /**
   * Parse and register keyframes on the current instance.
   */
  function registerUserHashedRule(container, prefix, styles, displayName) {
      var bucket = new Cache(container.hash);
      var _a = collectHashedStyles(bucket, styles, false, displayName), pid = _a.pid, id = _a.id;
      var atRule = new Rule(prefix + " " + id, undefined, container.hash, undefined, pid);
      atRule.merge(bucket);
      container.add(atRule);
      return id;
  }
  /**
   * Get the styles string for a container class.
   */
  function getStyles(container) {
      return container.values().map(function (style) { return style.getStyles(); }).join('');
  }
  /**
   * Implement a cache/event emitter.
   */
  var Cache = (function () {
      function Cache(hash) {
          this.hash = hash;
          this.changeId = 0;
          this._children = {};
          this._keys = [];
          this._counts = {};
      }
      Cache.prototype.values = function () {
          var _this = this;
          return this._keys.map(function (x) { return _this._children[x]; });
      };
      Cache.prototype.add = function (style) {
          var count = this._counts[style.id] || 0;
          var item = this._children[style.id] || style.clone();
          this._counts[style.id] = count + 1;
          if (count === 0) {
              this._keys.push(item.id);
              this._children[item.id] = item;
              this.changeId++;
          }
          else {
              // Check if contents are different.
              if (item.getIdentifier() !== style.getIdentifier()) {
                  throw new TypeError("Hash collision: " + style.getStyles() + " === " + item.getStyles());
              }
              this._keys.splice(this._keys.indexOf(style.id), 1);
              this._keys.push(style.id);
              if (item instanceof Cache && style instanceof Cache) {
                  var prevChangeId = item.changeId;
                  item.merge(style);
                  if (item.changeId !== prevChangeId) {
                      this.changeId++;
                  }
              }
          }
          return item;
      };
      Cache.prototype.remove = function (style) {
          var count = this._counts[style.id];
          if (count > 0) {
              this._counts[style.id] = count - 1;
              var item = this._children[style.id];
              if (count === 1) {
                  delete this._counts[style.id];
                  delete this._children[style.id];
                  this._keys.splice(this._keys.indexOf(style.id), 1);
                  this.changeId++;
              }
              else if (item instanceof Cache && style instanceof Cache) {
                  var prevChangeId = item.changeId;
                  item.unmerge(style);
                  if (item.changeId !== prevChangeId) {
                      this.changeId++;
                  }
              }
          }
      };
      Cache.prototype.get = function (container) {
          return this._children[container.id];
      };
      Cache.prototype.merge = function (cache) {
          for (var _i = 0, _a = cache.values(); _i < _a.length; _i++) {
              var value = _a[_i];
              this.add(value);
          }
          return this;
      };
      Cache.prototype.unmerge = function (cache) {
          for (var _i = 0, _a = cache.values(); _i < _a.length; _i++) {
              var value = _a[_i];
              this.remove(value);
          }
          return this;
      };
      Cache.prototype.clone = function () {
          return new Cache(this.hash).merge(this);
      };
      return Cache;
  }());
  exports.Cache = Cache;
  /**
   * Selector is a dumb class made to represent nested CSS selectors.
   */
  var Selector = (function () {
      function Selector(selector, hash, id, pid) {
          if (id === void 0) { id = "s" + hash(selector); }
          if (pid === void 0) { pid = ''; }
          this.selector = selector;
          this.hash = hash;
          this.id = id;
          this.pid = pid;
      }
      Selector.prototype.getStyles = function () {
          return this.selector;
      };
      Selector.prototype.getIdentifier = function () {
          return this.pid + "." + this.selector;
      };
      Selector.prototype.clone = function () {
          return new Selector(this.selector, this.hash, this.id, this.pid);
      };
      return Selector;
  }());
  exports.Selector = Selector;
  /**
   * The style container registers a style string with selectors.
   */
  var Style = (function (_super) {
      __extends(Style, _super);
      function Style(style, hash, id) {
          if (id === void 0) { id = "c" + hash(style); }
          _super.call(this, hash);
          this.style = style;
          this.hash = hash;
          this.id = id;
      }
      Style.prototype.getStyles = function () {
          return this.values().map(function (x) { return x.selector; }).join(',') + "{" + this.style + "}";
      };
      Style.prototype.getIdentifier = function () {
          return this.style;
      };
      Style.prototype.clone = function () {
          return new Style(this.style, this.hash, this.id).merge(this);
      };
      return Style;
  }(Cache));
  exports.Style = Style;
  /**
   * Implement rule logic for style output.
   */
  var Rule = (function (_super) {
      __extends(Rule, _super);
      function Rule(rule, style, hash, id, pid) {
          if (style === void 0) { style = ''; }
          if (id === void 0) { id = "a" + hash(rule + "." + style); }
          if (pid === void 0) { pid = ''; }
          _super.call(this, hash);
          this.rule = rule;
          this.style = style;
          this.hash = hash;
          this.id = id;
          this.pid = pid;
      }
      Rule.prototype.getStyles = function () {
          return this.rule + "{" + this.style + getStyles(this) + "}";
      };
      Rule.prototype.getIdentifier = function () {
          return this.pid + "." + this.rule + "." + this.style;
      };
      Rule.prototype.clone = function () {
          return new Rule(this.rule, this.style, this.hash, this.id, this.pid).merge(this);
      };
      return Rule;
  }(Cache));
  exports.Rule = Rule;
  /**
   * The FreeStyle class implements the API for everything else.
   */
  var FreeStyle = (function (_super) {
      __extends(FreeStyle, _super);
      function FreeStyle(hash, debug, id) {
          if (id === void 0) { id = "f" + (++instanceId).toString(36); }
          _super.call(this, hash);
          this.hash = hash;
          this.debug = debug;
          this.id = id;
      }
      FreeStyle.prototype.registerStyle = function (styles, displayName) {
          return registerUserStyles(this, styles, this.debug ? displayName : undefined);
      };
      FreeStyle.prototype.registerKeyframes = function (keyframes, displayName) {
          return registerUserHashedRule(this, '@keyframes', keyframes, this.debug ? displayName : undefined);
      };
      FreeStyle.prototype.registerRule = function (rule, styles) {
          return registerUserRule(this, rule, styles);
      };
      FreeStyle.prototype.getStyles = function () {
          return getStyles(this);
      };
      FreeStyle.prototype.getIdentifier = function () {
          return this.id;
      };
      FreeStyle.prototype.clone = function () {
          return new FreeStyle(this.hash, this.debug, this.id).merge(this);
      };
      return FreeStyle;
  }(Cache));
  exports.FreeStyle = FreeStyle;
  /**
   * Exports a simple function to create a new instance.
   */
  function create(hash, debug) {
      if (hash === void 0) { hash = stringHash; }
      if (debug === void 0) { debug = process.env.NODE_ENV !== 'production'; }
      return new FreeStyle(hash, debug);
  }
  exports.create = create;
  //# sourceMappingURL=free-style.js.map