Index: frontend/node_modules/cssstyle/LICENSE
===================================================================
--- frontend/node_modules/cssstyle/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+Copyright (c) Chad Walker
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Index: frontend/node_modules/cssstyle/README.md
===================================================================
--- frontend/node_modules/cssstyle/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,15 @@
+# CSSStyleDeclaration
+
+A Node JS implementation of the CSS Object Model [CSSStyleDeclaration interface](https://www.w3.org/TR/cssom-1/#the-cssstyledeclaration-interface).
+
+[![NpmVersion](https://img.shields.io/npm/v/cssstyle.svg)](https://www.npmjs.com/package/cssstyle) [![Build Status](https://travis-ci.org/jsdom/cssstyle.svg?branch=master)](https://travis-ci.org/jsdom/cssstyle) [![codecov](https://codecov.io/gh/jsdom/cssstyle/branch/master/graph/badge.svg)](https://codecov.io/gh/jsdom/cssstyle)
+
+---
+
+#### Background
+
+This package is an extension of the CSSStyleDeclaration class in Nikita Vasilyev's [CSSOM](https://github.com/NV/CSSOM) with added support for CSS 2 & 3 properties. The primary use case is for testing browser code in a Node environment. 
+
+It was originally created by Chad Walker, it is now maintaind by Jon Sakas and other open source contributors.
+
+Bug reports and pull requests are welcome.
Index: frontend/node_modules/cssstyle/lib/CSSStyleDeclaration.js
===================================================================
--- frontend/node_modules/cssstyle/lib/CSSStyleDeclaration.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/CSSStyleDeclaration.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,260 @@
+/*********************************************************************
+ * This is a fork from the CSS Style Declaration part of
+ * https://github.com/NV/CSSOM
+ ********************************************************************/
+'use strict';
+var CSSOM = require('cssom');
+var allProperties = require('./allProperties');
+var allExtraProperties = require('./allExtraProperties');
+var implementedProperties = require('./implementedProperties');
+var { dashedToCamelCase } = require('./parsers');
+var getBasicPropertyDescriptor = require('./utils/getBasicPropertyDescriptor');
+
+/**
+ * @constructor
+ * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
+ */
+var CSSStyleDeclaration = function CSSStyleDeclaration(onChangeCallback) {
+  this._values = {};
+  this._importants = {};
+  this._length = 0;
+  this._onChange =
+    onChangeCallback ||
+    function() {
+      return;
+    };
+};
+CSSStyleDeclaration.prototype = {
+  constructor: CSSStyleDeclaration,
+
+  /**
+   *
+   * @param {string} name
+   * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-getPropertyValue
+   * @return {string} the value of the property if it has been explicitly set for this declaration block.
+   * Returns the empty string if the property has not been set.
+   */
+  getPropertyValue: function(name) {
+    if (!this._values.hasOwnProperty(name)) {
+      return '';
+    }
+    return this._values[name].toString();
+  },
+
+  /**
+   *
+   * @param {string} name
+   * @param {string} value
+   * @param {string} [priority=null] "important" or null
+   * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-setProperty
+   */
+  setProperty: function(name, value, priority) {
+    if (value === undefined) {
+      return;
+    }
+    if (value === null || value === '') {
+      this.removeProperty(name);
+      return;
+    }
+    var isCustomProperty = name.indexOf('--') === 0;
+    if (isCustomProperty) {
+      this._setProperty(name, value, priority);
+      return;
+    }
+    var lowercaseName = name.toLowerCase();
+    if (!allProperties.has(lowercaseName) && !allExtraProperties.has(lowercaseName)) {
+      return;
+    }
+
+    this[lowercaseName] = value;
+    this._importants[lowercaseName] = priority;
+  },
+  _setProperty: function(name, value, priority) {
+    if (value === undefined) {
+      return;
+    }
+    if (value === null || value === '') {
+      this.removeProperty(name);
+      return;
+    }
+    if (this._values[name]) {
+      // Property already exist. Overwrite it.
+      var index = Array.prototype.indexOf.call(this, name);
+      if (index < 0) {
+        this[this._length] = name;
+        this._length++;
+      }
+    } else {
+      // New property.
+      this[this._length] = name;
+      this._length++;
+    }
+    this._values[name] = value;
+    this._importants[name] = priority;
+    this._onChange(this.cssText);
+  },
+
+  /**
+   *
+   * @param {string} name
+   * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-removeProperty
+   * @return {string} the value of the property if it has been explicitly set for this declaration block.
+   * Returns the empty string if the property has not been set or the property name does not correspond to a known CSS property.
+   */
+  removeProperty: function(name) {
+    if (!this._values.hasOwnProperty(name)) {
+      return '';
+    }
+
+    var prevValue = this._values[name];
+    delete this._values[name];
+    delete this._importants[name];
+
+    var index = Array.prototype.indexOf.call(this, name);
+    if (index < 0) {
+      return prevValue;
+    }
+
+    // That's what WebKit and Opera do
+    Array.prototype.splice.call(this, index, 1);
+
+    // That's what Firefox does
+    //this[index] = ""
+
+    this._onChange(this.cssText);
+    return prevValue;
+  },
+
+  /**
+   *
+   * @param {String} name
+   */
+  getPropertyPriority: function(name) {
+    return this._importants[name] || '';
+  },
+
+  getPropertyCSSValue: function() {
+    //FIXME
+    return;
+  },
+
+  /**
+   *   element.style.overflow = "auto"
+   *   element.style.getPropertyShorthand("overflow-x")
+   *   -> "overflow"
+   */
+  getPropertyShorthand: function() {
+    //FIXME
+    return;
+  },
+
+  isPropertyImplicit: function() {
+    //FIXME
+    return;
+  },
+
+  /**
+   *   http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-item
+   */
+  item: function(index) {
+    index = parseInt(index, 10);
+    if (index < 0 || index >= this._length) {
+      return '';
+    }
+    return this[index];
+  },
+};
+
+Object.defineProperties(CSSStyleDeclaration.prototype, {
+  cssText: {
+    get: function() {
+      var properties = [];
+      var i;
+      var name;
+      var value;
+      var priority;
+      for (i = 0; i < this._length; i++) {
+        name = this[i];
+        value = this.getPropertyValue(name);
+        priority = this.getPropertyPriority(name);
+        if (priority !== '') {
+          priority = ' !' + priority;
+        }
+        properties.push([name, ': ', value, priority, ';'].join(''));
+      }
+      return properties.join(' ');
+    },
+    set: function(value) {
+      var i;
+      this._values = {};
+      Array.prototype.splice.call(this, 0, this._length);
+      this._importants = {};
+      var dummyRule;
+      try {
+        dummyRule = CSSOM.parse('#bogus{' + value + '}').cssRules[0].style;
+      } catch (err) {
+        // malformed css, just return
+        return;
+      }
+      var rule_length = dummyRule.length;
+      var name;
+      for (i = 0; i < rule_length; ++i) {
+        name = dummyRule[i];
+        this.setProperty(
+          dummyRule[i],
+          dummyRule.getPropertyValue(name),
+          dummyRule.getPropertyPriority(name)
+        );
+      }
+      this._onChange(this.cssText);
+    },
+    enumerable: true,
+    configurable: true,
+  },
+  parentRule: {
+    get: function() {
+      return null;
+    },
+    enumerable: true,
+    configurable: true,
+  },
+  length: {
+    get: function() {
+      return this._length;
+    },
+    /**
+     * This deletes indices if the new length is less then the current
+     * length. If the new length is more, it does nothing, the new indices
+     * will be undefined until set.
+     **/
+    set: function(value) {
+      var i;
+      for (i = value; i < this._length; i++) {
+        delete this[i];
+      }
+      this._length = value;
+    },
+    enumerable: true,
+    configurable: true,
+  },
+});
+
+require('./properties')(CSSStyleDeclaration.prototype);
+
+allProperties.forEach(function(property) {
+  if (!implementedProperties.has(property)) {
+    var declaration = getBasicPropertyDescriptor(property);
+    Object.defineProperty(CSSStyleDeclaration.prototype, property, declaration);
+    Object.defineProperty(CSSStyleDeclaration.prototype, dashedToCamelCase(property), declaration);
+  }
+});
+
+allExtraProperties.forEach(function(property) {
+  if (!implementedProperties.has(property)) {
+    var declaration = getBasicPropertyDescriptor(property);
+    Object.defineProperty(CSSStyleDeclaration.prototype, property, declaration);
+    Object.defineProperty(CSSStyleDeclaration.prototype, dashedToCamelCase(property), declaration);
+  }
+});
+
+exports.CSSStyleDeclaration = CSSStyleDeclaration;
Index: frontend/node_modules/cssstyle/lib/CSSStyleDeclaration.test.js
===================================================================
--- frontend/node_modules/cssstyle/lib/CSSStyleDeclaration.test.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/CSSStyleDeclaration.test.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,556 @@
+'use strict';
+
+var { CSSStyleDeclaration } = require('./CSSStyleDeclaration');
+
+var allProperties = require('./allProperties');
+var allExtraProperties = require('./allExtraProperties');
+var implementedProperties = require('./implementedProperties');
+var parsers = require('./parsers');
+
+var dashedProperties = [...allProperties, ...allExtraProperties];
+var allowedProperties = dashedProperties.map(parsers.dashedToCamelCase);
+implementedProperties = Array.from(implementedProperties).map(parsers.dashedToCamelCase);
+var invalidProperties = implementedProperties.filter(prop => !allowedProperties.includes(prop));
+
+describe('CSSStyleDeclaration', () => {
+  test('has only valid properties implemented', () => {
+    expect(invalidProperties.length).toEqual(0);
+  });
+
+  test('has all properties', () => {
+    var style = new CSSStyleDeclaration();
+    allProperties.forEach(property => {
+      expect(style.__lookupGetter__(property)).toBeTruthy();
+      expect(style.__lookupSetter__(property)).toBeTruthy();
+    });
+  });
+
+  test('has dashed properties', () => {
+    var style = new CSSStyleDeclaration();
+    dashedProperties.forEach(property => {
+      expect(style.__lookupGetter__(property)).toBeTruthy();
+      expect(style.__lookupSetter__(property)).toBeTruthy();
+    });
+  });
+
+  test('has all functions', () => {
+    var style = new CSSStyleDeclaration();
+
+    expect(typeof style.item).toEqual('function');
+    expect(typeof style.getPropertyValue).toEqual('function');
+    expect(typeof style.setProperty).toEqual('function');
+    expect(typeof style.getPropertyPriority).toEqual('function');
+    expect(typeof style.removeProperty).toEqual('function');
+
+    // TODO - deprecated according to MDN and not implemented at all, can we remove?
+    expect(typeof style.getPropertyCSSValue).toEqual('function');
+  });
+
+  test('has special properties', () => {
+    var style = new CSSStyleDeclaration();
+
+    expect(style.__lookupGetter__('cssText')).toBeTruthy();
+    expect(style.__lookupSetter__('cssText')).toBeTruthy();
+    expect(style.__lookupGetter__('length')).toBeTruthy();
+    expect(style.__lookupSetter__('length')).toBeTruthy();
+    expect(style.__lookupGetter__('parentRule')).toBeTruthy();
+  });
+
+  test('from style string', () => {
+    var style = new CSSStyleDeclaration();
+    style.cssText = 'color: blue; background-color: red; width: 78%; height: 50vh;';
+    expect(style.length).toEqual(4);
+    expect(style.cssText).toEqual('color: blue; background-color: red; width: 78%; height: 50vh;');
+    expect(style.getPropertyValue('color')).toEqual('blue');
+    expect(style.item(0)).toEqual('color');
+    expect(style[1]).toEqual('background-color');
+    expect(style.backgroundColor).toEqual('red');
+    style.cssText = '';
+    expect(style.cssText).toEqual('');
+    expect(style.length).toEqual(0);
+  });
+
+  test('from properties', () => {
+    var style = new CSSStyleDeclaration();
+    style.color = 'blue';
+    expect(style.length).toEqual(1);
+    expect(style[0]).toEqual('color');
+    expect(style.cssText).toEqual('color: blue;');
+    expect(style.item(0)).toEqual('color');
+    expect(style.color).toEqual('blue');
+    style.backgroundColor = 'red';
+    expect(style.length).toEqual(2);
+    expect(style[0]).toEqual('color');
+    expect(style[1]).toEqual('background-color');
+    expect(style.cssText).toEqual('color: blue; background-color: red;');
+    expect(style.backgroundColor).toEqual('red');
+    style.removeProperty('color');
+    expect(style[0]).toEqual('background-color');
+  });
+
+  test('shorthand properties', () => {
+    var style = new CSSStyleDeclaration();
+    style.background = 'blue url(http://www.example.com/some_img.jpg)';
+    expect(style.backgroundColor).toEqual('blue');
+    expect(style.backgroundImage).toEqual('url(http://www.example.com/some_img.jpg)');
+    expect(style.background).toEqual('blue url(http://www.example.com/some_img.jpg)');
+    style.border = '0 solid black';
+    expect(style.borderWidth).toEqual('0px');
+    expect(style.borderStyle).toEqual('solid');
+    expect(style.borderColor).toEqual('black');
+    expect(style.borderTopWidth).toEqual('0px');
+    expect(style.borderLeftStyle).toEqual('solid');
+    expect(style.borderBottomColor).toEqual('black');
+    style.font = '12em monospace';
+    expect(style.fontSize).toEqual('12em');
+    expect(style.fontFamily).toEqual('monospace');
+  });
+
+  test('width and height properties and null and empty strings', () => {
+    var style = new CSSStyleDeclaration();
+    style.height = 6;
+    expect(style.height).toEqual('');
+    style.width = 0;
+    expect(style.width).toEqual('0px');
+    style.height = '34%';
+    expect(style.height).toEqual('34%');
+    style.height = '100vh';
+    expect(style.height).toEqual('100vh');
+    style.height = '100vw';
+    expect(style.height).toEqual('100vw');
+    style.height = '';
+    expect(1).toEqual(style.length);
+    expect(style.cssText).toEqual('width: 0px;');
+    style.width = null;
+    expect(0).toEqual(style.length);
+    expect(style.cssText).toEqual('');
+  });
+
+  test('implicit properties', () => {
+    var style = new CSSStyleDeclaration();
+    style.borderWidth = 0;
+    expect(style.length).toEqual(1);
+    expect(style.borderWidth).toEqual('0px');
+    expect(style.borderTopWidth).toEqual('0px');
+    expect(style.borderBottomWidth).toEqual('0px');
+    expect(style.borderLeftWidth).toEqual('0px');
+    expect(style.borderRightWidth).toEqual('0px');
+    expect(style.cssText).toEqual('border-width: 0px;');
+  });
+
+  test('top, left, right, bottom properties', () => {
+    var style = new CSSStyleDeclaration();
+    style.top = 0;
+    style.left = '0%';
+    style.right = '5em';
+    style.bottom = '12pt';
+    expect(style.top).toEqual('0px');
+    expect(style.left).toEqual('0%');
+    expect(style.right).toEqual('5em');
+    expect(style.bottom).toEqual('12pt');
+    expect(style.length).toEqual(4);
+    expect(style.cssText).toEqual('top: 0px; left: 0%; right: 5em; bottom: 12pt;');
+  });
+
+  test('clear and clip properties', () => {
+    var style = new CSSStyleDeclaration();
+    style.clear = 'none';
+    expect(style.clear).toEqual('none');
+    style.clear = 'lfet';
+    expect(style.clear).toEqual('none');
+    style.clear = 'left';
+    expect(style.clear).toEqual('left');
+    style.clear = 'right';
+    expect(style.clear).toEqual('right');
+    style.clear = 'both';
+    expect(style.clear).toEqual('both');
+    style.clip = 'elipse(5px, 10px)';
+    expect(style.clip).toEqual('');
+    expect(style.length).toEqual(1);
+    style.clip = 'rect(0, 3Em, 2pt, 50%)';
+    expect(style.clip).toEqual('rect(0px, 3em, 2pt, 50%)');
+    expect(style.length).toEqual(2);
+    expect(style.cssText).toEqual('clear: both; clip: rect(0px, 3em, 2pt, 50%);');
+  });
+
+  test('colors', () => {
+    var style = new CSSStyleDeclaration();
+    style.color = 'rgba(0,0,0,0)';
+    expect(style.color).toEqual('rgba(0, 0, 0, 0)');
+    style.color = 'rgba(5%, 10%, 20%, 0.4)';
+    expect(style.color).toEqual('rgba(12, 25, 51, 0.4)');
+    style.color = 'rgb(33%, 34%, 33%)';
+    expect(style.color).toEqual('rgb(84, 86, 84)');
+    style.color = 'rgba(300, 200, 100, 1.5)';
+    expect(style.color).toEqual('rgb(255, 200, 100)');
+    style.color = 'hsla(0, 1%, 2%, 0.5)';
+    expect(style.color).toEqual('rgba(5, 5, 5, 0.5)');
+    style.color = 'hsl(0, 1%, 2%)';
+    expect(style.color).toEqual('rgb(5, 5, 5)');
+    style.color = 'rebeccapurple';
+    expect(style.color).toEqual('rebeccapurple');
+    style.color = 'transparent';
+    expect(style.color).toEqual('transparent');
+    style.color = 'currentcolor';
+    expect(style.color).toEqual('currentcolor');
+    style.color = '#ffffffff';
+    expect(style.color).toEqual('rgba(255, 255, 255, 1)');
+    style.color = '#fffa';
+    expect(style.color).toEqual('rgba(255, 255, 255, 0.667)');
+    style.color = '#ffffff66';
+    expect(style.color).toEqual('rgba(255, 255, 255, 0.4)');
+  });
+
+  test('short hand properties with embedded spaces', () => {
+    var style = new CSSStyleDeclaration();
+    style.background = 'rgb(0, 0, 0) url(/something/somewhere.jpg)';
+    expect(style.backgroundColor).toEqual('rgb(0, 0, 0)');
+    expect(style.backgroundImage).toEqual('url(/something/somewhere.jpg)');
+    expect(style.cssText).toEqual('background: rgb(0, 0, 0) url(/something/somewhere.jpg);');
+    style = new CSSStyleDeclaration();
+    style.border = '  1px  solid   black  ';
+    expect(style.border).toEqual('1px solid black');
+  });
+
+  test('setting shorthand properties to an empty string should clear all dependent properties', () => {
+    var style = new CSSStyleDeclaration();
+    style.borderWidth = '1px';
+    expect(style.cssText).toEqual('border-width: 1px;');
+    style.border = '';
+    expect(style.cssText).toEqual('');
+  });
+
+  test('setting implicit properties to an empty string should clear all dependent properties', () => {
+    var style = new CSSStyleDeclaration();
+    style.borderTopWidth = '1px';
+    expect(style.cssText).toEqual('border-top-width: 1px;');
+    style.borderWidth = '';
+    expect(style.cssText).toEqual('');
+  });
+
+  test('setting a shorthand property, whose shorthands are implicit properties, to an empty string should clear all dependent properties', () => {
+    var style = new CSSStyleDeclaration();
+    style.borderTopWidth = '1px';
+    expect(style.cssText).toEqual('border-top-width: 1px;');
+    style.border = '';
+    expect(style.cssText).toEqual('');
+    style.borderTop = '1px solid black';
+    expect(style.cssText).toEqual('border-top: 1px solid black;');
+    style.border = '';
+    expect(style.cssText).toEqual('');
+  });
+
+  test('setting border values to "none" should clear dependent values', () => {
+    var style = new CSSStyleDeclaration();
+    style.borderTopWidth = '1px';
+    expect(style.cssText).toEqual('border-top-width: 1px;');
+    style.border = 'none';
+    expect(style.cssText).toEqual('');
+    style.borderTopWidth = '1px';
+    expect(style.cssText).toEqual('border-top-width: 1px;');
+    style.borderTopStyle = 'none';
+    expect(style.cssText).toEqual('');
+    style.borderTopWidth = '1px';
+    expect(style.cssText).toEqual('border-top-width: 1px;');
+    style.borderTop = 'none';
+    expect(style.cssText).toEqual('');
+    style.borderTopWidth = '1px';
+    style.borderLeftWidth = '1px';
+    expect(style.cssText).toEqual('border-top-width: 1px; border-left-width: 1px;');
+    style.borderTop = 'none';
+    expect(style.cssText).toEqual('border-left-width: 1px;');
+  });
+
+  test('setting border to 0 should be okay', () => {
+    var style = new CSSStyleDeclaration();
+    style.border = 0;
+    expect(style.cssText).toEqual('border: 0px;');
+  });
+
+  test('setting values implicit and shorthand properties via csstext and setproperty should propagate to dependent properties', () => {
+    var style = new CSSStyleDeclaration();
+    style.cssText = 'border: 1px solid black;';
+    expect(style.cssText).toEqual('border: 1px solid black;');
+    expect(style.borderTop).toEqual('1px solid black');
+    style.border = '';
+    expect(style.cssText).toEqual('');
+    style.setProperty('border', '1px solid black');
+    expect(style.cssText).toEqual('border: 1px solid black;');
+  });
+
+  test('setting opacity should work', () => {
+    var style = new CSSStyleDeclaration();
+    style.setProperty('opacity', 0.75);
+    expect(style.cssText).toEqual('opacity: 0.75;');
+    style.opacity = '0.50';
+    expect(style.cssText).toEqual('opacity: 0.5;');
+    style.opacity = 1;
+    expect(style.cssText).toEqual('opacity: 1;');
+  });
+
+  test('width and height of auto should work', () => {
+    var style = new CSSStyleDeclaration();
+    style.width = 'auto';
+    expect(style.cssText).toEqual('width: auto;');
+    expect(style.width).toEqual('auto');
+    style = new CSSStyleDeclaration();
+    style.height = 'auto';
+    expect(style.cssText).toEqual('height: auto;');
+    expect(style.height).toEqual('auto');
+  });
+
+  test('padding and margin should set/clear shorthand properties', () => {
+    var style = new CSSStyleDeclaration();
+    var parts = ['Top', 'Right', 'Bottom', 'Left'];
+    var testParts = function(name, v, V) {
+      style[name] = v;
+      for (var i = 0; i < 4; i++) {
+        var part = name + parts[i];
+        expect(style[part]).toEqual(V[i]);
+      }
+
+      expect(style[name]).toEqual(v);
+      style[name] = '';
+    };
+    testParts('padding', '1px', ['1px', '1px', '1px', '1px']);
+    testParts('padding', '1px 2%', ['1px', '2%', '1px', '2%']);
+    testParts('padding', '1px 2px 3px', ['1px', '2px', '3px', '2px']);
+    testParts('padding', '1px 2px 3px 4px', ['1px', '2px', '3px', '4px']);
+    style.paddingTop = style.paddingRight = style.paddingBottom = style.paddingLeft = '1px';
+    testParts('padding', '', ['', '', '', '']);
+    testParts('margin', '1px', ['1px', '1px', '1px', '1px']);
+    testParts('margin', '1px auto', ['1px', 'auto', '1px', 'auto']);
+    testParts('margin', '1px 2% 3px', ['1px', '2%', '3px', '2%']);
+    testParts('margin', '1px 2px 3px 4px', ['1px', '2px', '3px', '4px']);
+    style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = '1px';
+    testParts('margin', '', ['', '', '', '']);
+  });
+
+  test('padding and margin shorthands should set main properties', () => {
+    var style = new CSSStyleDeclaration();
+    var parts = ['Top', 'Right', 'Bottom', 'Left'];
+    var testParts = function(name, v, V) {
+      var expected;
+      for (var i = 0; i < 4; i++) {
+        style[name] = v;
+        style[name + parts[i]] = V;
+        expected = v.split(/ /);
+        expected[i] = V;
+        expected = expected.join(' ');
+
+        expect(style[name]).toEqual(expected);
+      }
+    };
+    testParts('padding', '1px 2px 3px 4px', '10px');
+    testParts('margin', '1px 2px 3px 4px', '10px');
+    testParts('margin', '1px 2px 3px 4px', 'auto');
+  });
+
+  test('setting a value to 0 should return the string value', () => {
+    var style = new CSSStyleDeclaration();
+    style.setProperty('fill-opacity', 0);
+    expect(style.fillOpacity).toEqual('0');
+  });
+
+  test('onchange callback should be called when the csstext changes', () => {
+    var style = new CSSStyleDeclaration(function(cssText) {
+      expect(cssText).toEqual('opacity: 0;');
+    });
+    style.setProperty('opacity', 0);
+  });
+
+  test('setting float should work the same as cssfloat', () => {
+    var style = new CSSStyleDeclaration();
+    style.float = 'left';
+    expect(style.cssFloat).toEqual('left');
+  });
+
+  test('setting improper css to csstext should not throw', () => {
+    var style = new CSSStyleDeclaration();
+    style.cssText = 'color: ';
+    expect(style.cssText).toEqual('');
+    style.color = 'black';
+    style.cssText = 'float: ';
+    expect(style.cssText).toEqual('');
+  });
+
+  test('url parsing works with quotes', () => {
+    var style = new CSSStyleDeclaration();
+    style.backgroundImage = 'url(http://some/url/here1.png)';
+    expect(style.backgroundImage).toEqual('url(http://some/url/here1.png)');
+    style.backgroundImage = "url('http://some/url/here2.png')";
+    expect(style.backgroundImage).toEqual('url(http://some/url/here2.png)');
+    style.backgroundImage = 'url("http://some/url/here3.png")';
+    expect(style.backgroundImage).toEqual('url(http://some/url/here3.png)');
+  });
+
+  test('setting 0 to a padding or margin works', () => {
+    var style = new CSSStyleDeclaration();
+    style.padding = 0;
+    expect(style.cssText).toEqual('padding: 0px;');
+    style.margin = '1em';
+    style.marginTop = '0';
+    expect(style.marginTop).toEqual('0px');
+  });
+
+  test('setting ex units to a padding or margin works', () => {
+    var style = new CSSStyleDeclaration();
+    style.padding = '1ex';
+    expect(style.cssText).toEqual('padding: 1ex;');
+    style.margin = '1em';
+    style.marginTop = '0.5ex';
+    expect(style.marginTop).toEqual('0.5ex');
+  });
+
+  test('setting null to background works', () => {
+    var style = new CSSStyleDeclaration();
+    style.background = 'red';
+    expect(style.cssText).toEqual('background: red;');
+    style.background = null;
+    expect(style.cssText).toEqual('');
+  });
+
+  test('flex properties should keep their values', () => {
+    var style = new CSSStyleDeclaration();
+    style.flexDirection = 'column';
+    expect(style.cssText).toEqual('flex-direction: column;');
+    style.flexDirection = 'row';
+    expect(style.cssText).toEqual('flex-direction: row;');
+  });
+
+  test('camelcase properties are not assigned with `.setproperty()`', () => {
+    var style = new CSSStyleDeclaration();
+    style.setProperty('fontSize', '12px');
+    expect(style.cssText).toEqual('');
+  });
+
+  test('casing is ignored in `.setproperty()`', () => {
+    var style = new CSSStyleDeclaration();
+    style.setProperty('FoNt-SiZe', '12px');
+    expect(style.fontSize).toEqual('12px');
+    expect(style.getPropertyValue('font-size')).toEqual('12px');
+  });
+
+  test('support non string entries in border-spacing', () => {
+    var style = new CSSStyleDeclaration();
+    style.borderSpacing = 0;
+    expect(style.cssText).toEqual('border-spacing: 0px;');
+  });
+
+  test('float should be valid property for `.setproperty()`', () => {
+    var style = new CSSStyleDeclaration();
+    style.setProperty('float', 'left');
+    expect(style.float).toEqual('left');
+    expect(style.getPropertyValue('float')).toEqual('left');
+  });
+
+  test('flex-shrink works', () => {
+    var style = new CSSStyleDeclaration();
+    style.setProperty('flex-shrink', 0);
+    expect(style.getPropertyValue('flex-shrink')).toEqual('0');
+    style.setProperty('flex-shrink', 1);
+    expect(style.getPropertyValue('flex-shrink')).toEqual('1');
+    expect(style.cssText).toEqual('flex-shrink: 1;');
+  });
+
+  test('flex-grow works', () => {
+    var style = new CSSStyleDeclaration();
+    style.setProperty('flex-grow', 2);
+    expect(style.getPropertyValue('flex-grow')).toEqual('2');
+    expect(style.cssText).toEqual('flex-grow: 2;');
+  });
+
+  test('flex-basis works', () => {
+    var style = new CSSStyleDeclaration();
+    style.setProperty('flex-basis', 0);
+    expect(style.getPropertyValue('flex-basis')).toEqual('0px');
+    style.setProperty('flex-basis', '250px');
+    expect(style.getPropertyValue('flex-basis')).toEqual('250px');
+    style.setProperty('flex-basis', '10em');
+    expect(style.getPropertyValue('flex-basis')).toEqual('10em');
+    style.setProperty('flex-basis', '30%');
+    expect(style.getPropertyValue('flex-basis')).toEqual('30%');
+    expect(style.cssText).toEqual('flex-basis: 30%;');
+  });
+
+  test('shorthand flex works', () => {
+    var style = new CSSStyleDeclaration();
+    style.setProperty('flex', 'none');
+    expect(style.getPropertyValue('flex-grow')).toEqual('0');
+    expect(style.getPropertyValue('flex-shrink')).toEqual('0');
+    expect(style.getPropertyValue('flex-basis')).toEqual('auto');
+    style.removeProperty('flex');
+    style.removeProperty('flex-basis');
+    style.setProperty('flex', 'auto');
+    expect(style.getPropertyValue('flex-grow')).toEqual('');
+    expect(style.getPropertyValue('flex-shrink')).toEqual('');
+    expect(style.getPropertyValue('flex-basis')).toEqual('auto');
+    style.removeProperty('flex');
+    style.setProperty('flex', '0 1 250px');
+    expect(style.getPropertyValue('flex')).toEqual('0 1 250px');
+    expect(style.getPropertyValue('flex-grow')).toEqual('0');
+    expect(style.getPropertyValue('flex-shrink')).toEqual('1');
+    expect(style.getPropertyValue('flex-basis')).toEqual('250px');
+    style.removeProperty('flex');
+    style.setProperty('flex', '2');
+    expect(style.getPropertyValue('flex-grow')).toEqual('2');
+    expect(style.getPropertyValue('flex-shrink')).toEqual('');
+    expect(style.getPropertyValue('flex-basis')).toEqual('');
+    style.removeProperty('flex');
+    style.setProperty('flex', '20%');
+    expect(style.getPropertyValue('flex-grow')).toEqual('');
+    expect(style.getPropertyValue('flex-shrink')).toEqual('');
+    expect(style.getPropertyValue('flex-basis')).toEqual('20%');
+    style.removeProperty('flex');
+    style.setProperty('flex', '2 2');
+    expect(style.getPropertyValue('flex-grow')).toEqual('2');
+    expect(style.getPropertyValue('flex-shrink')).toEqual('2');
+    expect(style.getPropertyValue('flex-basis')).toEqual('');
+    style.removeProperty('flex');
+  });
+
+  test('font-size get a valid value', () => {
+    var style = new CSSStyleDeclaration();
+    const invalidValue = '1r5px';
+    style.cssText = 'font-size: 15px';
+    expect(1).toEqual(style.length);
+    style.cssText = `font-size: ${invalidValue}`;
+    expect(0).toEqual(style.length);
+    expect(undefined).toEqual(style[0]);
+  });
+
+  test('getPropertyValue for custom properties in cssText', () => {
+    const style = new CSSStyleDeclaration();
+    style.cssText = '--foo: red';
+
+    expect(style.getPropertyValue('--foo')).toEqual('red');
+  });
+
+  test('getPropertyValue for custom properties with setProperty', () => {
+    const style = new CSSStyleDeclaration();
+    style.setProperty('--bar', 'blue');
+
+    expect(style.getPropertyValue('--bar')).toEqual('blue');
+  });
+
+  test('getPropertyValue for custom properties with object setter', () => {
+    const style = new CSSStyleDeclaration();
+    style['--baz'] = 'yellow';
+
+    expect(style.getPropertyValue('--baz')).toEqual('');
+  });
+
+  test('custom properties are case-sensitive', () => {
+    const style = new CSSStyleDeclaration();
+    style.cssText = '--fOo: purple';
+
+    expect(style.getPropertyValue('--foo')).toEqual('');
+    expect(style.getPropertyValue('--fOo')).toEqual('purple');
+  });
+
+  test('supports calc', () => {
+    const style = new CSSStyleDeclaration();
+    style.setProperty('width', 'calc(100% - 100px)');
+    expect(style.getPropertyValue('width')).toEqual('calc(100% - 100px)');
+  });
+});
Index: frontend/node_modules/cssstyle/lib/allExtraProperties.js
===================================================================
--- frontend/node_modules/cssstyle/lib/allExtraProperties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/allExtraProperties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,67 @@
+'use strict';
+
+/**
+ * This file contains all implemented properties that are not a part of any
+ * current specifications or drafts, but are handled by browsers nevertheless.
+ */
+
+var allWebkitProperties = require('./allWebkitProperties');
+
+module.exports = new Set(
+  [
+    'background-position-x',
+    'background-position-y',
+    'background-repeat-x',
+    'background-repeat-y',
+    'color-interpolation',
+    'color-profile',
+    'color-rendering',
+    'css-float',
+    'enable-background',
+    'fill',
+    'fill-opacity',
+    'fill-rule',
+    'glyph-orientation-horizontal',
+    'image-rendering',
+    'kerning',
+    'marker',
+    'marker-end',
+    'marker-mid',
+    'marker-offset',
+    'marker-start',
+    'marks',
+    'pointer-events',
+    'shape-rendering',
+    'size',
+    'src',
+    'stop-color',
+    'stop-opacity',
+    'stroke',
+    'stroke-dasharray',
+    'stroke-dashoffset',
+    'stroke-linecap',
+    'stroke-linejoin',
+    'stroke-miterlimit',
+    'stroke-opacity',
+    'stroke-width',
+    'text-anchor',
+    'text-line-through',
+    'text-line-through-color',
+    'text-line-through-mode',
+    'text-line-through-style',
+    'text-line-through-width',
+    'text-overline',
+    'text-overline-color',
+    'text-overline-mode',
+    'text-overline-style',
+    'text-overline-width',
+    'text-rendering',
+    'text-underline',
+    'text-underline-color',
+    'text-underline-mode',
+    'text-underline-style',
+    'text-underline-width',
+    'unicode-range',
+    'vector-effect',
+  ].concat(allWebkitProperties)
+);
Index: frontend/node_modules/cssstyle/lib/allProperties.js
===================================================================
--- frontend/node_modules/cssstyle/lib/allProperties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/allProperties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,462 @@
+'use strict';
+
+// autogenerated - 4/29/2020
+
+/*
+ *
+ * https://www.w3.org/Style/CSS/all-properties.en.html
+ */
+
+module.exports = new Set([
+  'align-content',
+  'align-items',
+  'align-self',
+  'alignment-baseline',
+  'all',
+  'animation',
+  'animation-delay',
+  'animation-direction',
+  'animation-duration',
+  'animation-fill-mode',
+  'animation-iteration-count',
+  'animation-name',
+  'animation-play-state',
+  'animation-timing-function',
+  'appearance',
+  'azimuth',
+  'background',
+  'background-attachment',
+  'background-blend-mode',
+  'background-clip',
+  'background-color',
+  'background-image',
+  'background-origin',
+  'background-position',
+  'background-repeat',
+  'background-size',
+  'baseline-shift',
+  'block-overflow',
+  'block-size',
+  'bookmark-label',
+  'bookmark-level',
+  'bookmark-state',
+  'border',
+  'border-block',
+  'border-block-color',
+  'border-block-end',
+  'border-block-end-color',
+  'border-block-end-style',
+  'border-block-end-width',
+  'border-block-start',
+  'border-block-start-color',
+  'border-block-start-style',
+  'border-block-start-width',
+  'border-block-style',
+  'border-block-width',
+  'border-bottom',
+  'border-bottom-color',
+  'border-bottom-left-radius',
+  'border-bottom-right-radius',
+  'border-bottom-style',
+  'border-bottom-width',
+  'border-boundary',
+  'border-collapse',
+  'border-color',
+  'border-end-end-radius',
+  'border-end-start-radius',
+  'border-image',
+  'border-image-outset',
+  'border-image-repeat',
+  'border-image-slice',
+  'border-image-source',
+  'border-image-width',
+  'border-inline',
+  'border-inline-color',
+  'border-inline-end',
+  'border-inline-end-color',
+  'border-inline-end-style',
+  'border-inline-end-width',
+  'border-inline-start',
+  'border-inline-start-color',
+  'border-inline-start-style',
+  'border-inline-start-width',
+  'border-inline-style',
+  'border-inline-width',
+  'border-left',
+  'border-left-color',
+  'border-left-style',
+  'border-left-width',
+  'border-radius',
+  'border-right',
+  'border-right-color',
+  'border-right-style',
+  'border-right-width',
+  'border-spacing',
+  'border-start-end-radius',
+  'border-start-start-radius',
+  'border-style',
+  'border-top',
+  'border-top-color',
+  'border-top-left-radius',
+  'border-top-right-radius',
+  'border-top-style',
+  'border-top-width',
+  'border-width',
+  'bottom',
+  'box-decoration-break',
+  'box-shadow',
+  'box-sizing',
+  'box-snap',
+  'break-after',
+  'break-before',
+  'break-inside',
+  'caption-side',
+  'caret',
+  'caret-color',
+  'caret-shape',
+  'chains',
+  'clear',
+  'clip',
+  'clip-path',
+  'clip-rule',
+  'color',
+  'color-adjust',
+  'color-interpolation-filters',
+  'color-scheme',
+  'column-count',
+  'column-fill',
+  'column-gap',
+  'column-rule',
+  'column-rule-color',
+  'column-rule-style',
+  'column-rule-width',
+  'column-span',
+  'column-width',
+  'columns',
+  'contain',
+  'content',
+  'continue',
+  'counter-increment',
+  'counter-reset',
+  'counter-set',
+  'cue',
+  'cue-after',
+  'cue-before',
+  'cursor',
+  'direction',
+  'display',
+  'dominant-baseline',
+  'elevation',
+  'empty-cells',
+  'filter',
+  'flex',
+  'flex-basis',
+  'flex-direction',
+  'flex-flow',
+  'flex-grow',
+  'flex-shrink',
+  'flex-wrap',
+  'float',
+  'flood-color',
+  'flood-opacity',
+  'flow',
+  'flow-from',
+  'flow-into',
+  'font',
+  'font-family',
+  'font-feature-settings',
+  'font-kerning',
+  'font-language-override',
+  'font-optical-sizing',
+  'font-palette',
+  'font-size',
+  'font-size-adjust',
+  'font-stretch',
+  'font-style',
+  'font-synthesis',
+  'font-synthesis-small-caps',
+  'font-synthesis-style',
+  'font-synthesis-weight',
+  'font-variant',
+  'font-variant-alternates',
+  'font-variant-caps',
+  'font-variant-east-asian',
+  'font-variant-emoji',
+  'font-variant-ligatures',
+  'font-variant-numeric',
+  'font-variant-position',
+  'font-variation-settings',
+  'font-weight',
+  'footnote-display',
+  'footnote-policy',
+  'forced-color-adjust',
+  'gap',
+  'glyph-orientation-vertical',
+  'grid',
+  'grid-area',
+  'grid-auto-columns',
+  'grid-auto-flow',
+  'grid-auto-rows',
+  'grid-column',
+  'grid-column-end',
+  'grid-column-start',
+  'grid-row',
+  'grid-row-end',
+  'grid-row-start',
+  'grid-template',
+  'grid-template-areas',
+  'grid-template-columns',
+  'grid-template-rows',
+  'hanging-punctuation',
+  'height',
+  'hyphenate-character',
+  'hyphenate-limit-chars',
+  'hyphenate-limit-last',
+  'hyphenate-limit-lines',
+  'hyphenate-limit-zone',
+  'hyphens',
+  'image-orientation',
+  'image-rendering',
+  'image-resolution',
+  'initial-letters',
+  'initial-letters-align',
+  'initial-letters-wrap',
+  'inline-size',
+  'inline-sizing',
+  'inset',
+  'inset-block',
+  'inset-block-end',
+  'inset-block-start',
+  'inset-inline',
+  'inset-inline-end',
+  'inset-inline-start',
+  'isolation',
+  'justify-content',
+  'justify-items',
+  'justify-self',
+  'left',
+  'letter-spacing',
+  'lighting-color',
+  'line-break',
+  'line-clamp',
+  'line-grid',
+  'line-height',
+  'line-padding',
+  'line-snap',
+  'list-style',
+  'list-style-image',
+  'list-style-position',
+  'list-style-type',
+  'margin',
+  'margin-block',
+  'margin-block-end',
+  'margin-block-start',
+  'margin-bottom',
+  'margin-inline',
+  'margin-inline-end',
+  'margin-inline-start',
+  'margin-left',
+  'margin-right',
+  'margin-top',
+  'marker-side',
+  'mask',
+  'mask-border',
+  'mask-border-mode',
+  'mask-border-outset',
+  'mask-border-repeat',
+  'mask-border-slice',
+  'mask-border-source',
+  'mask-border-width',
+  'mask-clip',
+  'mask-composite',
+  'mask-image',
+  'mask-mode',
+  'mask-origin',
+  'mask-position',
+  'mask-repeat',
+  'mask-size',
+  'mask-type',
+  'max-block-size',
+  'max-height',
+  'max-inline-size',
+  'max-lines',
+  'max-width',
+  'min-block-size',
+  'min-height',
+  'min-inline-size',
+  'min-width',
+  'mix-blend-mode',
+  'nav-down',
+  'nav-left',
+  'nav-right',
+  'nav-up',
+  'object-fit',
+  'object-position',
+  'offset',
+  'offset-after',
+  'offset-anchor',
+  'offset-before',
+  'offset-distance',
+  'offset-end',
+  'offset-path',
+  'offset-position',
+  'offset-rotate',
+  'offset-start',
+  'opacity',
+  'order',
+  'orphans',
+  'outline',
+  'outline-color',
+  'outline-offset',
+  'outline-style',
+  'outline-width',
+  'overflow',
+  'overflow-block',
+  'overflow-inline',
+  'overflow-wrap',
+  'overflow-x',
+  'overflow-y',
+  'padding',
+  'padding-block',
+  'padding-block-end',
+  'padding-block-start',
+  'padding-bottom',
+  'padding-inline',
+  'padding-inline-end',
+  'padding-inline-start',
+  'padding-left',
+  'padding-right',
+  'padding-top',
+  'page',
+  'page-break-after',
+  'page-break-before',
+  'page-break-inside',
+  'pause',
+  'pause-after',
+  'pause-before',
+  'pitch',
+  'pitch-range',
+  'place-content',
+  'place-items',
+  'place-self',
+  'play-during',
+  'position',
+  'quotes',
+  'region-fragment',
+  'resize',
+  'rest',
+  'rest-after',
+  'rest-before',
+  'richness',
+  'right',
+  'row-gap',
+  'ruby-align',
+  'ruby-merge',
+  'ruby-position',
+  'running',
+  'scroll-behavior',
+  'scroll-margin',
+  'scroll-margin-block',
+  'scroll-margin-block-end',
+  'scroll-margin-block-start',
+  'scroll-margin-bottom',
+  'scroll-margin-inline',
+  'scroll-margin-inline-end',
+  'scroll-margin-inline-start',
+  'scroll-margin-left',
+  'scroll-margin-right',
+  'scroll-margin-top',
+  'scroll-padding',
+  'scroll-padding-block',
+  'scroll-padding-block-end',
+  'scroll-padding-block-start',
+  'scroll-padding-bottom',
+  'scroll-padding-inline',
+  'scroll-padding-inline-end',
+  'scroll-padding-inline-start',
+  'scroll-padding-left',
+  'scroll-padding-right',
+  'scroll-padding-top',
+  'scroll-snap-align',
+  'scroll-snap-stop',
+  'scroll-snap-type',
+  'shape-image-threshold',
+  'shape-inside',
+  'shape-margin',
+  'shape-outside',
+  'spatial-navigation-action',
+  'spatial-navigation-contain',
+  'spatial-navigation-function',
+  'speak',
+  'speak-as',
+  'speak-header',
+  'speak-numeral',
+  'speak-punctuation',
+  'speech-rate',
+  'stress',
+  'string-set',
+  'tab-size',
+  'table-layout',
+  'text-align',
+  'text-align-all',
+  'text-align-last',
+  'text-combine-upright',
+  'text-decoration',
+  'text-decoration-color',
+  'text-decoration-line',
+  'text-decoration-style',
+  'text-emphasis',
+  'text-emphasis-color',
+  'text-emphasis-position',
+  'text-emphasis-style',
+  'text-group-align',
+  'text-indent',
+  'text-justify',
+  'text-orientation',
+  'text-overflow',
+  'text-shadow',
+  'text-space-collapse',
+  'text-space-trim',
+  'text-spacing',
+  'text-transform',
+  'text-underline-position',
+  'text-wrap',
+  'top',
+  'transform',
+  'transform-box',
+  'transform-origin',
+  'transition',
+  'transition-delay',
+  'transition-duration',
+  'transition-property',
+  'transition-timing-function',
+  'unicode-bidi',
+  'user-select',
+  'vertical-align',
+  'visibility',
+  'voice-balance',
+  'voice-duration',
+  'voice-family',
+  'voice-pitch',
+  'voice-range',
+  'voice-rate',
+  'voice-stress',
+  'voice-volume',
+  'volume',
+  'white-space',
+  'widows',
+  'width',
+  'will-change',
+  'word-boundary-detection',
+  'word-boundary-expansion',
+  'word-break',
+  'word-spacing',
+  'word-wrap',
+  'wrap-after',
+  'wrap-before',
+  'wrap-flow',
+  'wrap-inside',
+  'wrap-through',
+  'writing-mode',
+  'z-index',
+]);
Index: frontend/node_modules/cssstyle/lib/allWebkitProperties.js
===================================================================
--- frontend/node_modules/cssstyle/lib/allWebkitProperties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/allWebkitProperties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,194 @@
+'use strict';
+
+/**
+ * This file contains all implemented properties that are not a part of any
+ * current specifications or drafts, but are handled by browsers nevertheless.
+ */
+
+module.exports = [
+  'animation',
+  'animation-delay',
+  'animation-direction',
+  'animation-duration',
+  'animation-fill-mode',
+  'animation-iteration-count',
+  'animation-name',
+  'animation-play-state',
+  'animation-timing-function',
+  'appearance',
+  'aspect-ratio',
+  'backface-visibility',
+  'background-clip',
+  'background-composite',
+  'background-origin',
+  'background-size',
+  'border-after',
+  'border-after-color',
+  'border-after-style',
+  'border-after-width',
+  'border-before',
+  'border-before-color',
+  'border-before-style',
+  'border-before-width',
+  'border-end',
+  'border-end-color',
+  'border-end-style',
+  'border-end-width',
+  'border-fit',
+  'border-horizontal-spacing',
+  'border-image',
+  'border-radius',
+  'border-start',
+  'border-start-color',
+  'border-start-style',
+  'border-start-width',
+  'border-vertical-spacing',
+  'box-align',
+  'box-direction',
+  'box-flex',
+  'box-flex-group',
+  'box-lines',
+  'box-ordinal-group',
+  'box-orient',
+  'box-pack',
+  'box-reflect',
+  'box-shadow',
+  'color-correction',
+  'column-axis',
+  'column-break-after',
+  'column-break-before',
+  'column-break-inside',
+  'column-count',
+  'column-gap',
+  'column-rule',
+  'column-rule-color',
+  'column-rule-style',
+  'column-rule-width',
+  'columns',
+  'column-span',
+  'column-width',
+  'filter',
+  'flex-align',
+  'flex-direction',
+  'flex-flow',
+  'flex-item-align',
+  'flex-line-pack',
+  'flex-order',
+  'flex-pack',
+  'flex-wrap',
+  'flow-from',
+  'flow-into',
+  'font-feature-settings',
+  'font-kerning',
+  'font-size-delta',
+  'font-smoothing',
+  'font-variant-ligatures',
+  'highlight',
+  'hyphenate-character',
+  'hyphenate-limit-after',
+  'hyphenate-limit-before',
+  'hyphenate-limit-lines',
+  'hyphens',
+  'line-align',
+  'line-box-contain',
+  'line-break',
+  'line-clamp',
+  'line-grid',
+  'line-snap',
+  'locale',
+  'logical-height',
+  'logical-width',
+  'margin-after',
+  'margin-after-collapse',
+  'margin-before',
+  'margin-before-collapse',
+  'margin-bottom-collapse',
+  'margin-collapse',
+  'margin-end',
+  'margin-start',
+  'margin-top-collapse',
+  'marquee',
+  'marquee-direction',
+  'marquee-increment',
+  'marquee-repetition',
+  'marquee-speed',
+  'marquee-style',
+  'mask',
+  'mask-attachment',
+  'mask-box-image',
+  'mask-box-image-outset',
+  'mask-box-image-repeat',
+  'mask-box-image-slice',
+  'mask-box-image-source',
+  'mask-box-image-width',
+  'mask-clip',
+  'mask-composite',
+  'mask-image',
+  'mask-origin',
+  'mask-position',
+  'mask-position-x',
+  'mask-position-y',
+  'mask-repeat',
+  'mask-repeat-x',
+  'mask-repeat-y',
+  'mask-size',
+  'match-nearest-mail-blockquote-color',
+  'max-logical-height',
+  'max-logical-width',
+  'min-logical-height',
+  'min-logical-width',
+  'nbsp-mode',
+  'overflow-scrolling',
+  'padding-after',
+  'padding-before',
+  'padding-end',
+  'padding-start',
+  'perspective',
+  'perspective-origin',
+  'perspective-origin-x',
+  'perspective-origin-y',
+  'print-color-adjust',
+  'region-break-after',
+  'region-break-before',
+  'region-break-inside',
+  'region-overflow',
+  'rtl-ordering',
+  'svg-shadow',
+  'tap-highlight-color',
+  'text-combine',
+  'text-decorations-in-effect',
+  'text-emphasis',
+  'text-emphasis-color',
+  'text-emphasis-position',
+  'text-emphasis-style',
+  'text-fill-color',
+  'text-orientation',
+  'text-security',
+  'text-size-adjust',
+  'text-stroke',
+  'text-stroke-color',
+  'text-stroke-width',
+  'transform',
+  'transform-origin',
+  'transform-origin-x',
+  'transform-origin-y',
+  'transform-origin-z',
+  'transform-style',
+  'transition',
+  'transition-delay',
+  'transition-duration',
+  'transition-property',
+  'transition-timing-function',
+  'user-drag',
+  'user-modify',
+  'user-select',
+  'wrap',
+  'wrap-flow',
+  'wrap-margin',
+  'wrap-padding',
+  'wrap-shape-inside',
+  'wrap-shape-outside',
+  'wrap-through',
+  'writing-mode',
+  'zoom',
+].map(prop => 'webkit-' + prop);
Index: frontend/node_modules/cssstyle/lib/constants.js
===================================================================
--- frontend/node_modules/cssstyle/lib/constants.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/constants.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,6 @@
+'use strict';
+
+module.exports.POSITION_AT_SHORTHAND = {
+  first: 0,
+  second: 1,
+};
Index: frontend/node_modules/cssstyle/lib/implementedProperties.js
===================================================================
--- frontend/node_modules/cssstyle/lib/implementedProperties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/implementedProperties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,90 @@
+'use strict';
+
+// autogenerated - 4/29/2020
+
+/*
+ *
+ * https://www.w3.org/Style/CSS/all-properties.en.html
+ */
+
+var implementedProperties = new Set();
+implementedProperties.add("azimuth");
+implementedProperties.add("background");
+implementedProperties.add("background-attachment");
+implementedProperties.add("background-color");
+implementedProperties.add("background-image");
+implementedProperties.add("background-position");
+implementedProperties.add("background-repeat");
+implementedProperties.add("border");
+implementedProperties.add("border-bottom");
+implementedProperties.add("border-bottom-color");
+implementedProperties.add("border-bottom-style");
+implementedProperties.add("border-bottom-width");
+implementedProperties.add("border-collapse");
+implementedProperties.add("border-color");
+implementedProperties.add("border-left");
+implementedProperties.add("border-left-color");
+implementedProperties.add("border-left-style");
+implementedProperties.add("border-left-width");
+implementedProperties.add("border-right");
+implementedProperties.add("border-right-color");
+implementedProperties.add("border-right-style");
+implementedProperties.add("border-right-width");
+implementedProperties.add("border-spacing");
+implementedProperties.add("border-style");
+implementedProperties.add("border-top");
+implementedProperties.add("border-top-color");
+implementedProperties.add("border-top-style");
+implementedProperties.add("border-top-width");
+implementedProperties.add("border-width");
+implementedProperties.add("bottom");
+implementedProperties.add("clear");
+implementedProperties.add("clip");
+implementedProperties.add("color");
+implementedProperties.add("css-float");
+implementedProperties.add("flex");
+implementedProperties.add("flex-basis");
+implementedProperties.add("flex-grow");
+implementedProperties.add("flex-shrink");
+implementedProperties.add("float");
+implementedProperties.add("flood-color");
+implementedProperties.add("font");
+implementedProperties.add("font-family");
+implementedProperties.add("font-size");
+implementedProperties.add("font-style");
+implementedProperties.add("font-variant");
+implementedProperties.add("font-weight");
+implementedProperties.add("height");
+implementedProperties.add("left");
+implementedProperties.add("lighting-color");
+implementedProperties.add("line-height");
+implementedProperties.add("margin");
+implementedProperties.add("margin-bottom");
+implementedProperties.add("margin-left");
+implementedProperties.add("margin-right");
+implementedProperties.add("margin-top");
+implementedProperties.add("opacity");
+implementedProperties.add("outline-color");
+implementedProperties.add("padding");
+implementedProperties.add("padding-bottom");
+implementedProperties.add("padding-left");
+implementedProperties.add("padding-right");
+implementedProperties.add("padding-top");
+implementedProperties.add("right");
+implementedProperties.add("stop-color");
+implementedProperties.add("text-line-through-color");
+implementedProperties.add("text-overline-color");
+implementedProperties.add("text-underline-color");
+implementedProperties.add("top");
+implementedProperties.add("webkit-border-after-color");
+implementedProperties.add("webkit-border-before-color");
+implementedProperties.add("webkit-border-end-color");
+implementedProperties.add("webkit-border-start-color");
+implementedProperties.add("webkit-column-rule-color");
+implementedProperties.add("webkit-match-nearest-mail-blockquote-color");
+implementedProperties.add("webkit-tap-highlight-color");
+implementedProperties.add("webkit-text-emphasis-color");
+implementedProperties.add("webkit-text-fill-color");
+implementedProperties.add("webkit-text-stroke-color");
+implementedProperties.add("width");
+module.exports = implementedProperties;
Index: frontend/node_modules/cssstyle/lib/named_colors.json
===================================================================
--- frontend/node_modules/cssstyle/lib/named_colors.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/named_colors.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,152 @@
+[
+  "aliceblue",
+  "antiquewhite",
+  "aqua",
+  "aquamarine",
+  "azure",
+  "beige",
+  "bisque",
+  "black",
+  "blanchedalmond",
+  "blue",
+  "blueviolet",
+  "brown",
+  "burlywood",
+  "cadetblue",
+  "chartreuse",
+  "chocolate",
+  "coral",
+  "cornflowerblue",
+  "cornsilk",
+  "crimson",
+  "cyan",
+  "darkblue",
+  "darkcyan",
+  "darkgoldenrod",
+  "darkgray",
+  "darkgreen",
+  "darkgrey",
+  "darkkhaki",
+  "darkmagenta",
+  "darkolivegreen",
+  "darkorange",
+  "darkorchid",
+  "darkred",
+  "darksalmon",
+  "darkseagreen",
+  "darkslateblue",
+  "darkslategray",
+  "darkslategrey",
+  "darkturquoise",
+  "darkviolet",
+  "deeppink",
+  "deepskyblue",
+  "dimgray",
+  "dimgrey",
+  "dodgerblue",
+  "firebrick",
+  "floralwhite",
+  "forestgreen",
+  "fuchsia",
+  "gainsboro",
+  "ghostwhite",
+  "gold",
+  "goldenrod",
+  "gray",
+  "green",
+  "greenyellow",
+  "grey",
+  "honeydew",
+  "hotpink",
+  "indianred",
+  "indigo",
+  "ivory",
+  "khaki",
+  "lavender",
+  "lavenderblush",
+  "lawngreen",
+  "lemonchiffon",
+  "lightblue",
+  "lightcoral",
+  "lightcyan",
+  "lightgoldenrodyellow",
+  "lightgray",
+  "lightgreen",
+  "lightgrey",
+  "lightpink",
+  "lightsalmon",
+  "lightseagreen",
+  "lightskyblue",
+  "lightslategray",
+  "lightslategrey",
+  "lightsteelblue",
+  "lightyellow",
+  "lime",
+  "limegreen",
+  "linen",
+  "magenta",
+  "maroon",
+  "mediumaquamarine",
+  "mediumblue",
+  "mediumorchid",
+  "mediumpurple",
+  "mediumseagreen",
+  "mediumslateblue",
+  "mediumspringgreen",
+  "mediumturquoise",
+  "mediumvioletred",
+  "midnightblue",
+  "mintcream",
+  "mistyrose",
+  "moccasin",
+  "navajowhite",
+  "navy",
+  "oldlace",
+  "olive",
+  "olivedrab",
+  "orange",
+  "orangered",
+  "orchid",
+  "palegoldenrod",
+  "palegreen",
+  "paleturquoise",
+  "palevioletred",
+  "papayawhip",
+  "peachpuff",
+  "peru",
+  "pink",
+  "plum",
+  "powderblue",
+  "purple",
+  "rebeccapurple",
+  "red",
+  "rosybrown",
+  "royalblue",
+  "saddlebrown",
+  "salmon",
+  "sandybrown",
+  "seagreen",
+  "seashell",
+  "sienna",
+  "silver",
+  "skyblue",
+  "slateblue",
+  "slategray",
+  "slategrey",
+  "snow",
+  "springgreen",
+  "steelblue",
+  "tan",
+  "teal",
+  "thistle",
+  "tomato",
+  "turquoise",
+  "violet",
+  "wheat",
+  "white",
+  "whitesmoke",
+  "yellow",
+  "yellowgreen",
+  "transparent",
+  "currentcolor"
+]
Index: frontend/node_modules/cssstyle/lib/parsers.js
===================================================================
--- frontend/node_modules/cssstyle/lib/parsers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/parsers.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,722 @@
+/*********************************************************************
+ * These are commonly used parsers for CSS Values they take a string *
+ * to parse and return a string after it's been converted, if needed *
+ ********************************************************************/
+'use strict';
+
+const namedColors = require('./named_colors.json');
+const { hslToRgb } = require('./utils/colorSpace');
+
+exports.TYPES = {
+  INTEGER: 1,
+  NUMBER: 2,
+  LENGTH: 3,
+  PERCENT: 4,
+  URL: 5,
+  COLOR: 6,
+  STRING: 7,
+  ANGLE: 8,
+  KEYWORD: 9,
+  NULL_OR_EMPTY_STR: 10,
+  CALC: 11,
+};
+
+// rough regular expressions
+var integerRegEx = /^[-+]?[0-9]+$/;
+var numberRegEx = /^[-+]?[0-9]*\.?[0-9]+$/;
+var lengthRegEx = /^(0|[-+]?[0-9]*\.?[0-9]+(in|cm|em|mm|pt|pc|px|ex|rem|vh|vw|ch))$/;
+var percentRegEx = /^[-+]?[0-9]*\.?[0-9]+%$/;
+var urlRegEx = /^url\(\s*([^)]*)\s*\)$/;
+var stringRegEx = /^("[^"]*"|'[^']*')$/;
+var colorRegEx1 = /^#([0-9a-fA-F]{3,4}){1,2}$/;
+var colorRegEx2 = /^rgb\(([^)]*)\)$/;
+var colorRegEx3 = /^rgba\(([^)]*)\)$/;
+var calcRegEx = /^calc\(([^)]*)\)$/;
+var colorRegEx4 = /^hsla?\(\s*(-?\d+|-?\d*.\d+)\s*,\s*(-?\d+|-?\d*.\d+)%\s*,\s*(-?\d+|-?\d*.\d+)%\s*(,\s*(-?\d+|-?\d*.\d+)\s*)?\)/;
+var angleRegEx = /^([-+]?[0-9]*\.?[0-9]+)(deg|grad|rad)$/;
+
+// This will return one of the above types based on the passed in string
+exports.valueType = function valueType(val) {
+  if (val === '' || val === null) {
+    return exports.TYPES.NULL_OR_EMPTY_STR;
+  }
+  if (typeof val === 'number') {
+    val = val.toString();
+  }
+
+  if (typeof val !== 'string') {
+    return undefined;
+  }
+
+  if (integerRegEx.test(val)) {
+    return exports.TYPES.INTEGER;
+  }
+  if (numberRegEx.test(val)) {
+    return exports.TYPES.NUMBER;
+  }
+  if (lengthRegEx.test(val)) {
+    return exports.TYPES.LENGTH;
+  }
+  if (percentRegEx.test(val)) {
+    return exports.TYPES.PERCENT;
+  }
+  if (urlRegEx.test(val)) {
+    return exports.TYPES.URL;
+  }
+  if (calcRegEx.test(val)) {
+    return exports.TYPES.CALC;
+  }
+  if (stringRegEx.test(val)) {
+    return exports.TYPES.STRING;
+  }
+  if (angleRegEx.test(val)) {
+    return exports.TYPES.ANGLE;
+  }
+  if (colorRegEx1.test(val)) {
+    return exports.TYPES.COLOR;
+  }
+
+  var res = colorRegEx2.exec(val);
+  var parts;
+  if (res !== null) {
+    parts = res[1].split(/\s*,\s*/);
+    if (parts.length !== 3) {
+      return undefined;
+    }
+    if (
+      parts.every(percentRegEx.test.bind(percentRegEx)) ||
+      parts.every(integerRegEx.test.bind(integerRegEx))
+    ) {
+      return exports.TYPES.COLOR;
+    }
+    return undefined;
+  }
+  res = colorRegEx3.exec(val);
+  if (res !== null) {
+    parts = res[1].split(/\s*,\s*/);
+    if (parts.length !== 4) {
+      return undefined;
+    }
+    if (
+      parts.slice(0, 3).every(percentRegEx.test.bind(percentRegEx)) ||
+      parts.slice(0, 3).every(integerRegEx.test.bind(integerRegEx))
+    ) {
+      if (numberRegEx.test(parts[3])) {
+        return exports.TYPES.COLOR;
+      }
+    }
+    return undefined;
+  }
+
+  if (colorRegEx4.test(val)) {
+    return exports.TYPES.COLOR;
+  }
+
+  // could still be a color, one of the standard keyword colors
+  val = val.toLowerCase();
+
+  if (namedColors.includes(val)) {
+    return exports.TYPES.COLOR;
+  }
+
+  switch (val) {
+    // the following are deprecated in CSS3
+    case 'activeborder':
+    case 'activecaption':
+    case 'appworkspace':
+    case 'background':
+    case 'buttonface':
+    case 'buttonhighlight':
+    case 'buttonshadow':
+    case 'buttontext':
+    case 'captiontext':
+    case 'graytext':
+    case 'highlight':
+    case 'highlighttext':
+    case 'inactiveborder':
+    case 'inactivecaption':
+    case 'inactivecaptiontext':
+    case 'infobackground':
+    case 'infotext':
+    case 'menu':
+    case 'menutext':
+    case 'scrollbar':
+    case 'threeddarkshadow':
+    case 'threedface':
+    case 'threedhighlight':
+    case 'threedlightshadow':
+    case 'threedshadow':
+    case 'window':
+    case 'windowframe':
+    case 'windowtext':
+      return exports.TYPES.COLOR;
+    default:
+      return exports.TYPES.KEYWORD;
+  }
+};
+
+exports.parseInteger = function parseInteger(val) {
+  var type = exports.valueType(val);
+  if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
+    return val;
+  }
+  if (type !== exports.TYPES.INTEGER) {
+    return undefined;
+  }
+  return String(parseInt(val, 10));
+};
+
+exports.parseNumber = function parseNumber(val) {
+  var type = exports.valueType(val);
+  if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
+    return val;
+  }
+  if (type !== exports.TYPES.NUMBER && type !== exports.TYPES.INTEGER) {
+    return undefined;
+  }
+  return String(parseFloat(val));
+};
+
+exports.parseLength = function parseLength(val) {
+  if (val === 0 || val === '0') {
+    return '0px';
+  }
+  var type = exports.valueType(val);
+  if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
+    return val;
+  }
+  if (type !== exports.TYPES.LENGTH) {
+    return undefined;
+  }
+  return val;
+};
+
+exports.parsePercent = function parsePercent(val) {
+  if (val === 0 || val === '0') {
+    return '0%';
+  }
+  var type = exports.valueType(val);
+  if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
+    return val;
+  }
+  if (type !== exports.TYPES.PERCENT) {
+    return undefined;
+  }
+  return val;
+};
+
+// either a length or a percent
+exports.parseMeasurement = function parseMeasurement(val) {
+  var type = exports.valueType(val);
+  if (type === exports.TYPES.CALC) {
+    return val;
+  }
+
+  var length = exports.parseLength(val);
+  if (length !== undefined) {
+    return length;
+  }
+  return exports.parsePercent(val);
+};
+
+exports.parseUrl = function parseUrl(val) {
+  var type = exports.valueType(val);
+  if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
+    return val;
+  }
+  var res = urlRegEx.exec(val);
+  // does it match the regex?
+  if (!res) {
+    return undefined;
+  }
+  var str = res[1];
+  // if it starts with single or double quotes, does it end with the same?
+  if ((str[0] === '"' || str[0] === "'") && str[0] !== str[str.length - 1]) {
+    return undefined;
+  }
+  if (str[0] === '"' || str[0] === "'") {
+    str = str.substr(1, str.length - 2);
+  }
+
+  var i;
+  for (i = 0; i < str.length; i++) {
+    switch (str[i]) {
+      case '(':
+      case ')':
+      case ' ':
+      case '\t':
+      case '\n':
+      case "'":
+      case '"':
+        return undefined;
+      case '\\':
+        i++;
+        break;
+    }
+  }
+
+  return 'url(' + str + ')';
+};
+
+exports.parseString = function parseString(val) {
+  var type = exports.valueType(val);
+  if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
+    return val;
+  }
+  if (type !== exports.TYPES.STRING) {
+    return undefined;
+  }
+  var i;
+  for (i = 1; i < val.length - 1; i++) {
+    switch (val[i]) {
+      case val[0]:
+        return undefined;
+      case '\\':
+        i++;
+        while (i < val.length - 1 && /[0-9A-Fa-f]/.test(val[i])) {
+          i++;
+        }
+        break;
+    }
+  }
+  if (i >= val.length) {
+    return undefined;
+  }
+  return val;
+};
+
+exports.parseColor = function parseColor(val) {
+  var type = exports.valueType(val);
+  if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
+    return val;
+  }
+  var red,
+    green,
+    blue,
+    hue,
+    saturation,
+    lightness,
+    alpha = 1;
+  var parts;
+  var res = colorRegEx1.exec(val);
+  // is it #aaa, #ababab, #aaaa, #abababaa
+  if (res) {
+    var defaultHex = val.substr(1);
+    var hex = val.substr(1);
+    if (hex.length === 3 || hex.length === 4) {
+      hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
+
+      if (defaultHex.length === 4) {
+        hex = hex + defaultHex[3] + defaultHex[3];
+      }
+    }
+    red = parseInt(hex.substr(0, 2), 16);
+    green = parseInt(hex.substr(2, 2), 16);
+    blue = parseInt(hex.substr(4, 2), 16);
+    if (hex.length === 8) {
+      var hexAlpha = hex.substr(6, 2);
+      var hexAlphaToRgbaAlpha = Number((parseInt(hexAlpha, 16) / 255).toFixed(3));
+
+      return 'rgba(' + red + ', ' + green + ', ' + blue + ', ' + hexAlphaToRgbaAlpha + ')';
+    }
+    return 'rgb(' + red + ', ' + green + ', ' + blue + ')';
+  }
+
+  res = colorRegEx2.exec(val);
+  if (res) {
+    parts = res[1].split(/\s*,\s*/);
+    if (parts.length !== 3) {
+      return undefined;
+    }
+    if (parts.every(percentRegEx.test.bind(percentRegEx))) {
+      red = Math.floor((parseFloat(parts[0].slice(0, -1)) * 255) / 100);
+      green = Math.floor((parseFloat(parts[1].slice(0, -1)) * 255) / 100);
+      blue = Math.floor((parseFloat(parts[2].slice(0, -1)) * 255) / 100);
+    } else if (parts.every(integerRegEx.test.bind(integerRegEx))) {
+      red = parseInt(parts[0], 10);
+      green = parseInt(parts[1], 10);
+      blue = parseInt(parts[2], 10);
+    } else {
+      return undefined;
+    }
+    red = Math.min(255, Math.max(0, red));
+    green = Math.min(255, Math.max(0, green));
+    blue = Math.min(255, Math.max(0, blue));
+    return 'rgb(' + red + ', ' + green + ', ' + blue + ')';
+  }
+
+  res = colorRegEx3.exec(val);
+  if (res) {
+    parts = res[1].split(/\s*,\s*/);
+    if (parts.length !== 4) {
+      return undefined;
+    }
+    if (parts.slice(0, 3).every(percentRegEx.test.bind(percentRegEx))) {
+      red = Math.floor((parseFloat(parts[0].slice(0, -1)) * 255) / 100);
+      green = Math.floor((parseFloat(parts[1].slice(0, -1)) * 255) / 100);
+      blue = Math.floor((parseFloat(parts[2].slice(0, -1)) * 255) / 100);
+      alpha = parseFloat(parts[3]);
+    } else if (parts.slice(0, 3).every(integerRegEx.test.bind(integerRegEx))) {
+      red = parseInt(parts[0], 10);
+      green = parseInt(parts[1], 10);
+      blue = parseInt(parts[2], 10);
+      alpha = parseFloat(parts[3]);
+    } else {
+      return undefined;
+    }
+    if (isNaN(alpha)) {
+      alpha = 1;
+    }
+    red = Math.min(255, Math.max(0, red));
+    green = Math.min(255, Math.max(0, green));
+    blue = Math.min(255, Math.max(0, blue));
+    alpha = Math.min(1, Math.max(0, alpha));
+    if (alpha === 1) {
+      return 'rgb(' + red + ', ' + green + ', ' + blue + ')';
+    }
+    return 'rgba(' + red + ', ' + green + ', ' + blue + ', ' + alpha + ')';
+  }
+
+  res = colorRegEx4.exec(val);
+  if (res) {
+    const [, _hue, _saturation, _lightness, _alphaString = ''] = res;
+    const _alpha = parseFloat(_alphaString.replace(',', '').trim());
+    if (!_hue || !_saturation || !_lightness) {
+      return undefined;
+    }
+    hue = parseFloat(_hue);
+    saturation = parseInt(_saturation, 10);
+    lightness = parseInt(_lightness, 10);
+    if (_alpha && numberRegEx.test(_alpha)) {
+      alpha = parseFloat(_alpha);
+    }
+
+    const [r, g, b] = hslToRgb(hue, saturation / 100, lightness / 100);
+    if (!_alphaString || alpha === 1) {
+      return 'rgb(' + r + ', ' + g + ', ' + b + ')';
+    }
+    return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + alpha + ')';
+  }
+
+  if (type === exports.TYPES.COLOR) {
+    return val;
+  }
+  return undefined;
+};
+
+exports.parseAngle = function parseAngle(val) {
+  var type = exports.valueType(val);
+  if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
+    return val;
+  }
+  if (type !== exports.TYPES.ANGLE) {
+    return undefined;
+  }
+  var res = angleRegEx.exec(val);
+  var flt = parseFloat(res[1]);
+  if (res[2] === 'rad') {
+    flt *= 180 / Math.PI;
+  } else if (res[2] === 'grad') {
+    flt *= 360 / 400;
+  }
+
+  while (flt < 0) {
+    flt += 360;
+  }
+  while (flt > 360) {
+    flt -= 360;
+  }
+  return flt + 'deg';
+};
+
+exports.parseKeyword = function parseKeyword(val, valid_keywords) {
+  var type = exports.valueType(val);
+  if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
+    return val;
+  }
+  if (type !== exports.TYPES.KEYWORD) {
+    return undefined;
+  }
+  val = val.toString().toLowerCase();
+  var i;
+  for (i = 0; i < valid_keywords.length; i++) {
+    if (valid_keywords[i].toLowerCase() === val) {
+      return valid_keywords[i];
+    }
+  }
+  return undefined;
+};
+
+// utility to translate from border-width to borderWidth
+var dashedToCamelCase = function(dashed) {
+  var i;
+  var camel = '';
+  var nextCap = false;
+  for (i = 0; i < dashed.length; i++) {
+    if (dashed[i] !== '-') {
+      camel += nextCap ? dashed[i].toUpperCase() : dashed[i];
+      nextCap = false;
+    } else {
+      nextCap = true;
+    }
+  }
+  return camel;
+};
+exports.dashedToCamelCase = dashedToCamelCase;
+
+var is_space = /\s/;
+var opening_deliminators = ['"', "'", '('];
+var closing_deliminators = ['"', "'", ')'];
+// this splits on whitespace, but keeps quoted and parened parts together
+var getParts = function(str) {
+  var deliminator_stack = [];
+  var length = str.length;
+  var i;
+  var parts = [];
+  var current_part = '';
+  var opening_index;
+  var closing_index;
+  for (i = 0; i < length; i++) {
+    opening_index = opening_deliminators.indexOf(str[i]);
+    closing_index = closing_deliminators.indexOf(str[i]);
+    if (is_space.test(str[i])) {
+      if (deliminator_stack.length === 0) {
+        if (current_part !== '') {
+          parts.push(current_part);
+        }
+        current_part = '';
+      } else {
+        current_part += str[i];
+      }
+    } else {
+      if (str[i] === '\\') {
+        i++;
+        current_part += str[i];
+      } else {
+        current_part += str[i];
+        if (
+          closing_index !== -1 &&
+          closing_index === deliminator_stack[deliminator_stack.length - 1]
+        ) {
+          deliminator_stack.pop();
+        } else if (opening_index !== -1) {
+          deliminator_stack.push(opening_index);
+        }
+      }
+    }
+  }
+  if (current_part !== '') {
+    parts.push(current_part);
+  }
+  return parts;
+};
+
+/*
+ * this either returns undefined meaning that it isn't valid
+ * or returns an object where the keys are dashed short
+ * hand properties and the values are the values to set
+ * on them
+ */
+exports.shorthandParser = function parse(v, shorthand_for) {
+  var obj = {};
+  var type = exports.valueType(v);
+  if (type === exports.TYPES.NULL_OR_EMPTY_STR) {
+    Object.keys(shorthand_for).forEach(function(property) {
+      obj[property] = '';
+    });
+    return obj;
+  }
+
+  if (typeof v === 'number') {
+    v = v.toString();
+  }
+
+  if (typeof v !== 'string') {
+    return undefined;
+  }
+
+  if (v.toLowerCase() === 'inherit') {
+    return {};
+  }
+  var parts = getParts(v);
+  var valid = true;
+  parts.forEach(function(part, i) {
+    var part_valid = false;
+    Object.keys(shorthand_for).forEach(function(property) {
+      if (shorthand_for[property].isValid(part, i)) {
+        part_valid = true;
+        obj[property] = part;
+      }
+    });
+    valid = valid && part_valid;
+  });
+  if (!valid) {
+    return undefined;
+  }
+  return obj;
+};
+
+exports.shorthandSetter = function(property, shorthand_for) {
+  return function(v) {
+    var obj = exports.shorthandParser(v, shorthand_for);
+    if (obj === undefined) {
+      return;
+    }
+    //console.log('shorthandSetter for:', property, 'obj:', obj);
+    Object.keys(obj).forEach(function(subprop) {
+      // in case subprop is an implicit property, this will clear
+      // *its* subpropertiesX
+      var camel = dashedToCamelCase(subprop);
+      this[camel] = obj[subprop];
+      // in case it gets translated into something else (0 -> 0px)
+      obj[subprop] = this[camel];
+      this.removeProperty(subprop);
+      // don't add in empty properties
+      if (obj[subprop] !== '') {
+        this._values[subprop] = obj[subprop];
+      }
+    }, this);
+    Object.keys(shorthand_for).forEach(function(subprop) {
+      if (!obj.hasOwnProperty(subprop)) {
+        this.removeProperty(subprop);
+        delete this._values[subprop];
+      }
+    }, this);
+    // in case the value is something like 'none' that removes all values,
+    // check that the generated one is not empty, first remove the property
+    // if it already exists, then call the shorthandGetter, if it's an empty
+    // string, don't set the property
+    this.removeProperty(property);
+    var calculated = exports.shorthandGetter(property, shorthand_for).call(this);
+    if (calculated !== '') {
+      this._setProperty(property, calculated);
+    }
+  };
+};
+
+exports.shorthandGetter = function(property, shorthand_for) {
+  return function() {
+    if (this._values[property] !== undefined) {
+      return this.getPropertyValue(property);
+    }
+    return Object.keys(shorthand_for)
+      .map(function(subprop) {
+        return this.getPropertyValue(subprop);
+      }, this)
+      .filter(function(value) {
+        return value !== '';
+      })
+      .join(' ');
+  };
+};
+
+// isValid(){1,4} | inherit
+// if one, it applies to all
+// if two, the first applies to the top and bottom, and the second to left and right
+// if three, the first applies to the top, the second to left and right, the third bottom
+// if four, top, right, bottom, left
+exports.implicitSetter = function(property_before, property_after, isValid, parser) {
+  property_after = property_after || '';
+  if (property_after !== '') {
+    property_after = '-' + property_after;
+  }
+  var part_names = ['top', 'right', 'bottom', 'left'];
+
+  return function(v) {
+    if (typeof v === 'number') {
+      v = v.toString();
+    }
+    if (typeof v !== 'string') {
+      return undefined;
+    }
+    var parts;
+    if (v.toLowerCase() === 'inherit' || v === '') {
+      parts = [v];
+    } else {
+      parts = getParts(v);
+    }
+    if (parts.length < 1 || parts.length > 4) {
+      return undefined;
+    }
+
+    if (!parts.every(isValid)) {
+      return undefined;
+    }
+
+    parts = parts.map(function(part) {
+      return parser(part);
+    });
+    this._setProperty(property_before + property_after, parts.join(' '));
+    if (parts.length === 1) {
+      parts[1] = parts[0];
+    }
+    if (parts.length === 2) {
+      parts[2] = parts[0];
+    }
+    if (parts.length === 3) {
+      parts[3] = parts[1];
+    }
+
+    for (var i = 0; i < 4; i++) {
+      var property = property_before + '-' + part_names[i] + property_after;
+      this.removeProperty(property);
+      if (parts[i] !== '') {
+        this._values[property] = parts[i];
+      }
+    }
+    return v;
+  };
+};
+
+//
+//  Companion to implicitSetter, but for the individual parts.
+//  This sets the individual value, and checks to see if all four
+//  sub-parts are set.  If so, it sets the shorthand version and removes
+//  the individual parts from the cssText.
+//
+exports.subImplicitSetter = function(prefix, part, isValid, parser) {
+  var property = prefix + '-' + part;
+  var subparts = [prefix + '-top', prefix + '-right', prefix + '-bottom', prefix + '-left'];
+
+  return function(v) {
+    if (typeof v === 'number') {
+      v = v.toString();
+    }
+    if (typeof v !== 'string') {
+      return undefined;
+    }
+    if (!isValid(v)) {
+      return undefined;
+    }
+    v = parser(v);
+    this._setProperty(property, v);
+    var parts = [];
+    for (var i = 0; i < 4; i++) {
+      if (this._values[subparts[i]] == null || this._values[subparts[i]] === '') {
+        break;
+      }
+      parts.push(this._values[subparts[i]]);
+    }
+    if (parts.length === 4) {
+      for (i = 0; i < 4; i++) {
+        this.removeProperty(subparts[i]);
+        this._values[subparts[i]] = parts[i];
+      }
+      this._setProperty(prefix, parts.join(' '));
+    }
+    return v;
+  };
+};
+
+var camel_to_dashed = /[A-Z]/g;
+var first_segment = /^\([^-]\)-/;
+var vendor_prefixes = ['o', 'moz', 'ms', 'webkit'];
+exports.camelToDashed = function(camel_case) {
+  var match;
+  var dashed = camel_case.replace(camel_to_dashed, '-$&').toLowerCase();
+  match = dashed.match(first_segment);
+  if (match && vendor_prefixes.indexOf(match[1]) !== -1) {
+    dashed = '-' + dashed;
+  }
+  return dashed;
+};
Index: frontend/node_modules/cssstyle/lib/parsers.test.js
===================================================================
--- frontend/node_modules/cssstyle/lib/parsers.test.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/parsers.test.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,139 @@
+'use strict';
+
+const parsers = require('./parsers');
+
+describe('valueType', () => {
+  it('returns color for red', () => {
+    let input = 'red';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.COLOR);
+  });
+
+  it('returns color for #nnnnnn', () => {
+    let input = '#fefefe';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.COLOR);
+  });
+
+  it('returns color for rgb(n, n, n)', () => {
+    let input = 'rgb(10, 10, 10)';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.COLOR);
+  });
+
+  it('returns color for rgb(p, p, p)', () => {
+    let input = 'rgb(10%, 10%, 10%)';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.COLOR);
+  });
+
+  it('returns color for rgba(n, n, n, n)', () => {
+    let input = 'rgba(10, 10, 10, 1)';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.COLOR);
+  });
+
+  it('returns color for rgba(n, n, n, n) with decimal alpha', () => {
+    let input = 'rgba(10, 10, 10, 0.5)';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.COLOR);
+  });
+
+  it('returns color for rgba(p, p, p, n)', () => {
+    let input = 'rgba(10%, 10%, 10%, 1)';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.COLOR);
+  });
+
+  it('returns color for rgba(p, p, p, n) with decimal alpha', () => {
+    let input = 'rgba(10%, 10%, 10%, 0.5)';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.COLOR);
+  });
+
+  it('returns length for 100ch', () => {
+    let input = '100ch';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.LENGTH);
+  });
+
+  it('returns calc from calc(100px * 2)', () => {
+    let input = 'calc(100px * 2)';
+    let output = parsers.valueType(input);
+
+    expect(output).toEqual(parsers.TYPES.CALC);
+  });
+});
+describe('parseInteger', () => {
+  it.todo('test');
+});
+describe('parseNumber', () => {
+  it.todo('test');
+});
+describe('parseLength', () => {
+  it.todo('test');
+});
+describe('parsePercent', () => {
+  it.todo('test');
+});
+describe('parseMeasurement', () => {
+  it.todo('test');
+});
+describe('parseUrl', () => {
+  it.todo('test');
+});
+describe('parseString', () => {
+  it.todo('test');
+});
+describe('parseColor', () => {
+  it('should convert hsl to rgb values', () => {
+    let input = 'hsla(0, 1%, 2%)';
+    let output = parsers.parseColor(input);
+
+    expect(output).toEqual('rgb(5, 5, 5)');
+  });
+  it('should convert hsla to rgba values', () => {
+    let input = 'hsla(0, 1%, 2%, 0.5)';
+    let output = parsers.parseColor(input);
+
+    expect(output).toEqual('rgba(5, 5, 5, 0.5)');
+  });
+
+  it.todo('Add more tests');
+});
+describe('parseAngle', () => {
+  it.todo('test');
+});
+describe('parseKeyword', () => {
+  it.todo('test');
+});
+describe('dashedToCamelCase', () => {
+  it.todo('test');
+});
+describe('shorthandParser', () => {
+  it.todo('test');
+});
+describe('shorthandSetter', () => {
+  it.todo('test');
+});
+describe('shorthandGetter', () => {
+  it.todo('test');
+});
+describe('implicitSetter', () => {
+  it.todo('test');
+});
+describe('subImplicitSetter', () => {
+  it.todo('test');
+});
+describe('camelToDashed', () => {
+  it.todo('test');
+});
Index: frontend/node_modules/cssstyle/lib/properties.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,1833 @@
+'use strict';
+
+// autogenerated - 4/29/2020
+
+/*
+ *
+ * https://www.w3.org/Style/CSS/all-properties.en.html
+ */
+
+var external_dependency_parsers_0 = require("./parsers.js");
+
+var external_dependency_constants_1 = require("./constants.js");
+
+var azimuth_export_definition;
+azimuth_export_definition = {
+  set: function (v) {
+    var valueType = external_dependency_parsers_0.valueType(v);
+
+    if (valueType === external_dependency_parsers_0.TYPES.ANGLE) {
+      return this._setProperty('azimuth', external_dependency_parsers_0.parseAngle(v));
+    }
+
+    if (valueType === external_dependency_parsers_0.TYPES.KEYWORD) {
+      var keywords = v.toLowerCase().trim().split(/\s+/);
+      var hasBehind = false;
+
+      if (keywords.length > 2) {
+        return;
+      }
+
+      var behindIndex = keywords.indexOf('behind');
+      hasBehind = behindIndex !== -1;
+
+      if (keywords.length === 2) {
+        if (!hasBehind) {
+          return;
+        }
+
+        keywords.splice(behindIndex, 1);
+      }
+
+      if (keywords[0] === 'leftwards' || keywords[0] === 'rightwards') {
+        if (hasBehind) {
+          return;
+        }
+
+        return this._setProperty('azimuth', keywords[0]);
+      }
+
+      if (keywords[0] === 'behind') {
+        return this._setProperty('azimuth', '180deg');
+      }
+
+      switch (keywords[0]) {
+        case 'left-side':
+          return this._setProperty('azimuth', '270deg');
+
+        case 'far-left':
+          return this._setProperty('azimuth', (hasBehind ? 240 : 300) + 'deg');
+
+        case 'left':
+          return this._setProperty('azimuth', (hasBehind ? 220 : 320) + 'deg');
+
+        case 'center-left':
+          return this._setProperty('azimuth', (hasBehind ? 200 : 340) + 'deg');
+
+        case 'center':
+          return this._setProperty('azimuth', (hasBehind ? 180 : 0) + 'deg');
+
+        case 'center-right':
+          return this._setProperty('azimuth', (hasBehind ? 160 : 20) + 'deg');
+
+        case 'right':
+          return this._setProperty('azimuth', (hasBehind ? 140 : 40) + 'deg');
+
+        case 'far-right':
+          return this._setProperty('azimuth', (hasBehind ? 120 : 60) + 'deg');
+
+        case 'right-side':
+          return this._setProperty('azimuth', '90deg');
+
+        default:
+          return;
+      }
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('azimuth');
+  },
+  enumerable: true,
+  configurable: true
+};
+var backgroundColor_export_isValid, backgroundColor_export_definition;
+
+var backgroundColor_local_var_parse = function parse(v) {
+  var parsed = external_dependency_parsers_0.parseColor(v);
+
+  if (parsed !== undefined) {
+    return parsed;
+  }
+
+  if (external_dependency_parsers_0.valueType(v) === external_dependency_parsers_0.TYPES.KEYWORD && (v.toLowerCase() === 'transparent' || v.toLowerCase() === 'inherit')) {
+    return v;
+  }
+
+  return undefined;
+};
+
+backgroundColor_export_isValid = function isValid(v) {
+  return backgroundColor_local_var_parse(v) !== undefined;
+};
+
+backgroundColor_export_definition = {
+  set: function (v) {
+    var parsed = backgroundColor_local_var_parse(v);
+
+    if (parsed === undefined) {
+      return;
+    }
+
+    this._setProperty('background-color', parsed);
+  },
+  get: function () {
+    return this.getPropertyValue('background-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var backgroundImage_export_isValid, backgroundImage_export_definition;
+
+var backgroundImage_local_var_parse = function parse(v) {
+  var parsed = external_dependency_parsers_0.parseUrl(v);
+
+  if (parsed !== undefined) {
+    return parsed;
+  }
+
+  if (external_dependency_parsers_0.valueType(v) === external_dependency_parsers_0.TYPES.KEYWORD && (v.toLowerCase() === 'none' || v.toLowerCase() === 'inherit')) {
+    return v;
+  }
+
+  return undefined;
+};
+
+backgroundImage_export_isValid = function isValid(v) {
+  return backgroundImage_local_var_parse(v) !== undefined;
+};
+
+backgroundImage_export_definition = {
+  set: function (v) {
+    this._setProperty('background-image', backgroundImage_local_var_parse(v));
+  },
+  get: function () {
+    return this.getPropertyValue('background-image');
+  },
+  enumerable: true,
+  configurable: true
+};
+var backgroundRepeat_export_isValid, backgroundRepeat_export_definition;
+
+var backgroundRepeat_local_var_parse = function parse(v) {
+  if (external_dependency_parsers_0.valueType(v) === external_dependency_parsers_0.TYPES.KEYWORD && (v.toLowerCase() === 'repeat' || v.toLowerCase() === 'repeat-x' || v.toLowerCase() === 'repeat-y' || v.toLowerCase() === 'no-repeat' || v.toLowerCase() === 'inherit')) {
+    return v;
+  }
+
+  return undefined;
+};
+
+backgroundRepeat_export_isValid = function isValid(v) {
+  return backgroundRepeat_local_var_parse(v) !== undefined;
+};
+
+backgroundRepeat_export_definition = {
+  set: function (v) {
+    this._setProperty('background-repeat', backgroundRepeat_local_var_parse(v));
+  },
+  get: function () {
+    return this.getPropertyValue('background-repeat');
+  },
+  enumerable: true,
+  configurable: true
+};
+var backgroundAttachment_export_isValid, backgroundAttachment_export_definition;
+
+var backgroundAttachment_local_var_isValid = backgroundAttachment_export_isValid = function isValid(v) {
+  return external_dependency_parsers_0.valueType(v) === external_dependency_parsers_0.TYPES.KEYWORD && (v.toLowerCase() === 'scroll' || v.toLowerCase() === 'fixed' || v.toLowerCase() === 'inherit');
+};
+
+backgroundAttachment_export_definition = {
+  set: function (v) {
+    if (!backgroundAttachment_local_var_isValid(v)) {
+      return;
+    }
+
+    this._setProperty('background-attachment', v);
+  },
+  get: function () {
+    return this.getPropertyValue('background-attachment');
+  },
+  enumerable: true,
+  configurable: true
+};
+var backgroundPosition_export_isValid, backgroundPosition_export_definition;
+var backgroundPosition_local_var_valid_keywords = ['top', 'center', 'bottom', 'left', 'right'];
+
+var backgroundPosition_local_var_parse = function parse(v) {
+  if (v === '' || v === null) {
+    return undefined;
+  }
+
+  var parts = v.split(/\s+/);
+
+  if (parts.length > 2 || parts.length < 1) {
+    return undefined;
+  }
+
+  var types = [];
+  parts.forEach(function (part, index) {
+    types[index] = external_dependency_parsers_0.valueType(part);
+  });
+
+  if (parts.length === 1) {
+    if (types[0] === external_dependency_parsers_0.TYPES.LENGTH || types[0] === external_dependency_parsers_0.TYPES.PERCENT) {
+      return v;
+    }
+
+    if (types[0] === external_dependency_parsers_0.TYPES.KEYWORD) {
+      if (backgroundPosition_local_var_valid_keywords.indexOf(v.toLowerCase()) !== -1 || v.toLowerCase() === 'inherit') {
+        return v;
+      }
+    }
+
+    return undefined;
+  }
+
+  if ((types[0] === external_dependency_parsers_0.TYPES.LENGTH || types[0] === external_dependency_parsers_0.TYPES.PERCENT) && (types[1] === external_dependency_parsers_0.TYPES.LENGTH || types[1] === external_dependency_parsers_0.TYPES.PERCENT)) {
+    return v;
+  }
+
+  if (types[0] !== external_dependency_parsers_0.TYPES.KEYWORD || types[1] !== external_dependency_parsers_0.TYPES.KEYWORD) {
+    return undefined;
+  }
+
+  if (backgroundPosition_local_var_valid_keywords.indexOf(parts[0]) !== -1 && backgroundPosition_local_var_valid_keywords.indexOf(parts[1]) !== -1) {
+    return v;
+  }
+
+  return undefined;
+};
+
+backgroundPosition_export_isValid = function isValid(v) {
+  return backgroundPosition_local_var_parse(v) !== undefined;
+};
+
+backgroundPosition_export_definition = {
+  set: function (v) {
+    this._setProperty('background-position', backgroundPosition_local_var_parse(v));
+  },
+  get: function () {
+    return this.getPropertyValue('background-position');
+  },
+  enumerable: true,
+  configurable: true
+};
+var background_export_definition;
+var background_local_var_shorthand_for = {
+  'background-color': {
+    isValid: backgroundColor_export_isValid,
+    definition: backgroundColor_export_definition
+  },
+  'background-image': {
+    isValid: backgroundImage_export_isValid,
+    definition: backgroundImage_export_definition
+  },
+  'background-repeat': {
+    isValid: backgroundRepeat_export_isValid,
+    definition: backgroundRepeat_export_definition
+  },
+  'background-attachment': {
+    isValid: backgroundAttachment_export_isValid,
+    definition: backgroundAttachment_export_definition
+  },
+  'background-position': {
+    isValid: backgroundPosition_export_isValid,
+    definition: backgroundPosition_export_definition
+  }
+};
+background_export_definition = {
+  set: external_dependency_parsers_0.shorthandSetter('background', background_local_var_shorthand_for),
+  get: external_dependency_parsers_0.shorthandGetter('background', background_local_var_shorthand_for),
+  enumerable: true,
+  configurable: true
+};
+var borderWidth_export_isValid, borderWidth_export_definition;
+// the valid border-widths:
+var borderWidth_local_var_widths = ['thin', 'medium', 'thick'];
+
+borderWidth_export_isValid = function parse(v) {
+  var length = external_dependency_parsers_0.parseLength(v);
+
+  if (length !== undefined) {
+    return true;
+  }
+
+  if (typeof v !== 'string') {
+    return false;
+  }
+
+  if (v === '') {
+    return true;
+  }
+
+  v = v.toLowerCase();
+
+  if (borderWidth_local_var_widths.indexOf(v) === -1) {
+    return false;
+  }
+
+  return true;
+};
+
+var borderWidth_local_var_isValid = borderWidth_export_isValid;
+
+var borderWidth_local_var_parser = function (v) {
+  var length = external_dependency_parsers_0.parseLength(v);
+
+  if (length !== undefined) {
+    return length;
+  }
+
+  if (borderWidth_local_var_isValid(v)) {
+    return v.toLowerCase();
+  }
+
+  return undefined;
+};
+
+borderWidth_export_definition = {
+  set: external_dependency_parsers_0.implicitSetter('border', 'width', borderWidth_local_var_isValid, borderWidth_local_var_parser),
+  get: function () {
+    return this.getPropertyValue('border-width');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderStyle_export_isValid, borderStyle_export_definition;
+// the valid border-styles:
+var borderStyle_local_var_styles = ['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'];
+
+borderStyle_export_isValid = function parse(v) {
+  return typeof v === 'string' && (v === '' || borderStyle_local_var_styles.indexOf(v) !== -1);
+};
+
+var borderStyle_local_var_isValid = borderStyle_export_isValid;
+
+var borderStyle_local_var_parser = function (v) {
+  if (borderStyle_local_var_isValid(v)) {
+    return v.toLowerCase();
+  }
+
+  return undefined;
+};
+
+borderStyle_export_definition = {
+  set: external_dependency_parsers_0.implicitSetter('border', 'style', borderStyle_local_var_isValid, borderStyle_local_var_parser),
+  get: function () {
+    return this.getPropertyValue('border-style');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderColor_export_isValid, borderColor_export_definition;
+
+borderColor_export_isValid = function parse(v) {
+  if (typeof v !== 'string') {
+    return false;
+  }
+
+  return v === '' || v.toLowerCase() === 'transparent' || external_dependency_parsers_0.valueType(v) === external_dependency_parsers_0.TYPES.COLOR;
+};
+
+var borderColor_local_var_isValid = borderColor_export_isValid;
+
+var borderColor_local_var_parser = function (v) {
+  if (borderColor_local_var_isValid(v)) {
+    return v.toLowerCase();
+  }
+
+  return undefined;
+};
+
+borderColor_export_definition = {
+  set: external_dependency_parsers_0.implicitSetter('border', 'color', borderColor_local_var_isValid, borderColor_local_var_parser),
+  get: function () {
+    return this.getPropertyValue('border-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var border_export_definition;
+var border_local_var_shorthand_for = {
+  'border-width': {
+    isValid: borderWidth_export_isValid,
+    definition: borderWidth_export_definition
+  },
+  'border-style': {
+    isValid: borderStyle_export_isValid,
+    definition: borderStyle_export_definition
+  },
+  'border-color': {
+    isValid: borderColor_export_isValid,
+    definition: borderColor_export_definition
+  }
+};
+var border_local_var_myShorthandSetter = external_dependency_parsers_0.shorthandSetter('border', border_local_var_shorthand_for);
+var border_local_var_myShorthandGetter = external_dependency_parsers_0.shorthandGetter('border', border_local_var_shorthand_for);
+border_export_definition = {
+  set: function (v) {
+    if (v.toString().toLowerCase() === 'none') {
+      v = '';
+    }
+
+    border_local_var_myShorthandSetter.call(this, v);
+    this.removeProperty('border-top');
+    this.removeProperty('border-left');
+    this.removeProperty('border-right');
+    this.removeProperty('border-bottom');
+    this._values['border-top'] = this._values.border;
+    this._values['border-left'] = this._values.border;
+    this._values['border-right'] = this._values.border;
+    this._values['border-bottom'] = this._values.border;
+  },
+  get: border_local_var_myShorthandGetter,
+  enumerable: true,
+  configurable: true
+};
+var borderBottomWidth_export_isValid, borderBottomWidth_export_definition;
+var borderBottomWidth_local_var_isValid = borderBottomWidth_export_isValid = borderWidth_export_isValid;
+borderBottomWidth_export_definition = {
+  set: function (v) {
+    if (borderBottomWidth_local_var_isValid(v)) {
+      this._setProperty('border-bottom-width', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-bottom-width');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderBottomStyle_export_isValid, borderBottomStyle_export_definition;
+borderBottomStyle_export_isValid = borderStyle_export_isValid;
+borderBottomStyle_export_definition = {
+  set: function (v) {
+    if (borderStyle_export_isValid(v)) {
+      if (v.toLowerCase() === 'none') {
+        v = '';
+        this.removeProperty('border-bottom-width');
+      }
+
+      this._setProperty('border-bottom-style', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-bottom-style');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderBottomColor_export_isValid, borderBottomColor_export_definition;
+var borderBottomColor_local_var_isValid = borderBottomColor_export_isValid = borderColor_export_isValid;
+borderBottomColor_export_definition = {
+  set: function (v) {
+    if (borderBottomColor_local_var_isValid(v)) {
+      this._setProperty('border-bottom-color', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-bottom-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderBottom_export_definition;
+var borderBottom_local_var_shorthand_for = {
+  'border-bottom-width': {
+    isValid: borderBottomWidth_export_isValid,
+    definition: borderBottomWidth_export_definition
+  },
+  'border-bottom-style': {
+    isValid: borderBottomStyle_export_isValid,
+    definition: borderBottomStyle_export_definition
+  },
+  'border-bottom-color': {
+    isValid: borderBottomColor_export_isValid,
+    definition: borderBottomColor_export_definition
+  }
+};
+borderBottom_export_definition = {
+  set: external_dependency_parsers_0.shorthandSetter('border-bottom', borderBottom_local_var_shorthand_for),
+  get: external_dependency_parsers_0.shorthandGetter('border-bottom', borderBottom_local_var_shorthand_for),
+  enumerable: true,
+  configurable: true
+};
+var borderCollapse_export_definition;
+
+var borderCollapse_local_var_parse = function parse(v) {
+  if (external_dependency_parsers_0.valueType(v) === external_dependency_parsers_0.TYPES.KEYWORD && (v.toLowerCase() === 'collapse' || v.toLowerCase() === 'separate' || v.toLowerCase() === 'inherit')) {
+    return v;
+  }
+
+  return undefined;
+};
+
+borderCollapse_export_definition = {
+  set: function (v) {
+    this._setProperty('border-collapse', borderCollapse_local_var_parse(v));
+  },
+  get: function () {
+    return this.getPropertyValue('border-collapse');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderLeftWidth_export_isValid, borderLeftWidth_export_definition;
+var borderLeftWidth_local_var_isValid = borderLeftWidth_export_isValid = borderWidth_export_isValid;
+borderLeftWidth_export_definition = {
+  set: function (v) {
+    if (borderLeftWidth_local_var_isValid(v)) {
+      this._setProperty('border-left-width', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-left-width');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderLeftStyle_export_isValid, borderLeftStyle_export_definition;
+borderLeftStyle_export_isValid = borderStyle_export_isValid;
+borderLeftStyle_export_definition = {
+  set: function (v) {
+    if (borderStyle_export_isValid(v)) {
+      if (v.toLowerCase() === 'none') {
+        v = '';
+        this.removeProperty('border-left-width');
+      }
+
+      this._setProperty('border-left-style', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-left-style');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderLeftColor_export_isValid, borderLeftColor_export_definition;
+var borderLeftColor_local_var_isValid = borderLeftColor_export_isValid = borderColor_export_isValid;
+borderLeftColor_export_definition = {
+  set: function (v) {
+    if (borderLeftColor_local_var_isValid(v)) {
+      this._setProperty('border-left-color', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-left-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderLeft_export_definition;
+var borderLeft_local_var_shorthand_for = {
+  'border-left-width': {
+    isValid: borderLeftWidth_export_isValid,
+    definition: borderLeftWidth_export_definition
+  },
+  'border-left-style': {
+    isValid: borderLeftStyle_export_isValid,
+    definition: borderLeftStyle_export_definition
+  },
+  'border-left-color': {
+    isValid: borderLeftColor_export_isValid,
+    definition: borderLeftColor_export_definition
+  }
+};
+borderLeft_export_definition = {
+  set: external_dependency_parsers_0.shorthandSetter('border-left', borderLeft_local_var_shorthand_for),
+  get: external_dependency_parsers_0.shorthandGetter('border-left', borderLeft_local_var_shorthand_for),
+  enumerable: true,
+  configurable: true
+};
+var borderRightWidth_export_isValid, borderRightWidth_export_definition;
+var borderRightWidth_local_var_isValid = borderRightWidth_export_isValid = borderWidth_export_isValid;
+borderRightWidth_export_definition = {
+  set: function (v) {
+    if (borderRightWidth_local_var_isValid(v)) {
+      this._setProperty('border-right-width', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-right-width');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderRightStyle_export_isValid, borderRightStyle_export_definition;
+borderRightStyle_export_isValid = borderStyle_export_isValid;
+borderRightStyle_export_definition = {
+  set: function (v) {
+    if (borderStyle_export_isValid(v)) {
+      if (v.toLowerCase() === 'none') {
+        v = '';
+        this.removeProperty('border-right-width');
+      }
+
+      this._setProperty('border-right-style', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-right-style');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderRightColor_export_isValid, borderRightColor_export_definition;
+var borderRightColor_local_var_isValid = borderRightColor_export_isValid = borderColor_export_isValid;
+borderRightColor_export_definition = {
+  set: function (v) {
+    if (borderRightColor_local_var_isValid(v)) {
+      this._setProperty('border-right-color', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-right-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderRight_export_definition;
+var borderRight_local_var_shorthand_for = {
+  'border-right-width': {
+    isValid: borderRightWidth_export_isValid,
+    definition: borderRightWidth_export_definition
+  },
+  'border-right-style': {
+    isValid: borderRightStyle_export_isValid,
+    definition: borderRightStyle_export_definition
+  },
+  'border-right-color': {
+    isValid: borderRightColor_export_isValid,
+    definition: borderRightColor_export_definition
+  }
+};
+borderRight_export_definition = {
+  set: external_dependency_parsers_0.shorthandSetter('border-right', borderRight_local_var_shorthand_for),
+  get: external_dependency_parsers_0.shorthandGetter('border-right', borderRight_local_var_shorthand_for),
+  enumerable: true,
+  configurable: true
+};
+var borderSpacing_export_definition;
+
+// <length> <length>? | inherit
+// if one, it applies to both horizontal and verical spacing
+// if two, the first applies to the horizontal and the second applies to vertical spacing
+var borderSpacing_local_var_parse = function parse(v) {
+  if (v === '' || v === null) {
+    return undefined;
+  }
+
+  if (v === 0) {
+    return '0px';
+  }
+
+  if (v.toLowerCase() === 'inherit') {
+    return v;
+  }
+
+  var parts = v.split(/\s+/);
+
+  if (parts.length !== 1 && parts.length !== 2) {
+    return undefined;
+  }
+
+  parts.forEach(function (part) {
+    if (external_dependency_parsers_0.valueType(part) !== external_dependency_parsers_0.TYPES.LENGTH) {
+      return undefined;
+    }
+  });
+  return v;
+};
+
+borderSpacing_export_definition = {
+  set: function (v) {
+    this._setProperty('border-spacing', borderSpacing_local_var_parse(v));
+  },
+  get: function () {
+    return this.getPropertyValue('border-spacing');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderTopWidth_export_isValid, borderTopWidth_export_definition;
+borderTopWidth_export_isValid = borderWidth_export_isValid;
+borderTopWidth_export_definition = {
+  set: function (v) {
+    if (borderWidth_export_isValid(v)) {
+      this._setProperty('border-top-width', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-top-width');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderTopStyle_export_isValid, borderTopStyle_export_definition;
+borderTopStyle_export_isValid = borderStyle_export_isValid;
+borderTopStyle_export_definition = {
+  set: function (v) {
+    if (borderStyle_export_isValid(v)) {
+      if (v.toLowerCase() === 'none') {
+        v = '';
+        this.removeProperty('border-top-width');
+      }
+
+      this._setProperty('border-top-style', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-top-style');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderTopColor_export_isValid, borderTopColor_export_definition;
+var borderTopColor_local_var_isValid = borderTopColor_export_isValid = borderColor_export_isValid;
+borderTopColor_export_definition = {
+  set: function (v) {
+    if (borderTopColor_local_var_isValid(v)) {
+      this._setProperty('border-top-color', v);
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('border-top-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var borderTop_export_definition;
+var borderTop_local_var_shorthand_for = {
+  'border-top-width': {
+    isValid: borderTopWidth_export_isValid,
+    definition: borderTopWidth_export_definition
+  },
+  'border-top-style': {
+    isValid: borderTopStyle_export_isValid,
+    definition: borderTopStyle_export_definition
+  },
+  'border-top-color': {
+    isValid: borderTopColor_export_isValid,
+    definition: borderTopColor_export_definition
+  }
+};
+borderTop_export_definition = {
+  set: external_dependency_parsers_0.shorthandSetter('border-top', borderTop_local_var_shorthand_for),
+  get: external_dependency_parsers_0.shorthandGetter('border-top', borderTop_local_var_shorthand_for),
+  enumerable: true,
+  configurable: true
+};
+var bottom_export_definition;
+bottom_export_definition = {
+  set: function (v) {
+    this._setProperty('bottom', external_dependency_parsers_0.parseMeasurement(v));
+  },
+  get: function () {
+    return this.getPropertyValue('bottom');
+  },
+  enumerable: true,
+  configurable: true
+};
+var clear_export_definition;
+var clear_local_var_clear_keywords = ['none', 'left', 'right', 'both', 'inherit'];
+clear_export_definition = {
+  set: function (v) {
+    this._setProperty('clear', external_dependency_parsers_0.parseKeyword(v, clear_local_var_clear_keywords));
+  },
+  get: function () {
+    return this.getPropertyValue('clear');
+  },
+  enumerable: true,
+  configurable: true
+};
+var clip_export_definition;
+var clip_local_var_shape_regex = /^rect\((.*)\)$/i;
+
+var clip_local_var_parse = function (val) {
+  if (val === '' || val === null) {
+    return val;
+  }
+
+  if (typeof val !== 'string') {
+    return undefined;
+  }
+
+  val = val.toLowerCase();
+
+  if (val === 'auto' || val === 'inherit') {
+    return val;
+  }
+
+  var matches = val.match(clip_local_var_shape_regex);
+
+  if (!matches) {
+    return undefined;
+  }
+
+  var parts = matches[1].split(/\s*,\s*/);
+
+  if (parts.length !== 4) {
+    return undefined;
+  }
+
+  var valid = parts.every(function (part, index) {
+    var measurement = external_dependency_parsers_0.parseMeasurement(part);
+    parts[index] = measurement;
+    return measurement !== undefined;
+  });
+
+  if (!valid) {
+    return undefined;
+  }
+
+  parts = parts.join(', ');
+  return val.replace(matches[1], parts);
+};
+
+clip_export_definition = {
+  set: function (v) {
+    this._setProperty('clip', clip_local_var_parse(v));
+  },
+  get: function () {
+    return this.getPropertyValue('clip');
+  },
+  enumerable: true,
+  configurable: true
+};
+var color_export_definition;
+color_export_definition = {
+  set: function (v) {
+    this._setProperty('color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var cssFloat_export_definition;
+cssFloat_export_definition = {
+  set: function (v) {
+    this._setProperty('float', v);
+  },
+  get: function () {
+    return this.getPropertyValue('float');
+  },
+  enumerable: true,
+  configurable: true
+};
+var flexGrow_export_isValid, flexGrow_export_definition;
+
+flexGrow_export_isValid = function isValid(v, positionAtFlexShorthand) {
+  return external_dependency_parsers_0.parseNumber(v) !== undefined && positionAtFlexShorthand === external_dependency_constants_1.POSITION_AT_SHORTHAND.first;
+};
+
+flexGrow_export_definition = {
+  set: function (v) {
+    this._setProperty('flex-grow', external_dependency_parsers_0.parseNumber(v));
+  },
+  get: function () {
+    return this.getPropertyValue('flex-grow');
+  },
+  enumerable: true,
+  configurable: true
+};
+var flexShrink_export_isValid, flexShrink_export_definition;
+
+flexShrink_export_isValid = function isValid(v, positionAtFlexShorthand) {
+  return external_dependency_parsers_0.parseNumber(v) !== undefined && positionAtFlexShorthand === external_dependency_constants_1.POSITION_AT_SHORTHAND.second;
+};
+
+flexShrink_export_definition = {
+  set: function (v) {
+    this._setProperty('flex-shrink', external_dependency_parsers_0.parseNumber(v));
+  },
+  get: function () {
+    return this.getPropertyValue('flex-shrink');
+  },
+  enumerable: true,
+  configurable: true
+};
+var flexBasis_export_isValid, flexBasis_export_definition;
+
+function flexBasis_local_fn_parse(v) {
+  if (String(v).toLowerCase() === 'auto') {
+    return 'auto';
+  }
+
+  if (String(v).toLowerCase() === 'inherit') {
+    return 'inherit';
+  }
+
+  return external_dependency_parsers_0.parseMeasurement(v);
+}
+
+flexBasis_export_isValid = function isValid(v) {
+  return flexBasis_local_fn_parse(v) !== undefined;
+};
+
+flexBasis_export_definition = {
+  set: function (v) {
+    this._setProperty('flex-basis', flexBasis_local_fn_parse(v));
+  },
+  get: function () {
+    return this.getPropertyValue('flex-basis');
+  },
+  enumerable: true,
+  configurable: true
+};
+var flex_export_isValid, flex_export_definition;
+var flex_local_var_shorthand_for = {
+  'flex-grow': {
+    isValid: flexGrow_export_isValid,
+    definition: flexGrow_export_definition
+  },
+  'flex-shrink': {
+    isValid: flexShrink_export_isValid,
+    definition: flexShrink_export_definition
+  },
+  'flex-basis': {
+    isValid: flexBasis_export_isValid,
+    definition: flexBasis_export_definition
+  }
+};
+var flex_local_var_myShorthandSetter = external_dependency_parsers_0.shorthandSetter('flex', flex_local_var_shorthand_for);
+
+flex_export_isValid = function isValid(v) {
+  return external_dependency_parsers_0.shorthandParser(v, flex_local_var_shorthand_for) !== undefined;
+};
+
+flex_export_definition = {
+  set: function (v) {
+    var normalizedValue = String(v).trim().toLowerCase();
+
+    if (normalizedValue === 'none') {
+      flex_local_var_myShorthandSetter.call(this, '0 0 auto');
+      return;
+    }
+
+    if (normalizedValue === 'initial') {
+      flex_local_var_myShorthandSetter.call(this, '0 1 auto');
+      return;
+    }
+
+    if (normalizedValue === 'auto') {
+      this.removeProperty('flex-grow');
+      this.removeProperty('flex-shrink');
+      this.setProperty('flex-basis', normalizedValue);
+      return;
+    }
+
+    flex_local_var_myShorthandSetter.call(this, v);
+  },
+  get: external_dependency_parsers_0.shorthandGetter('flex', flex_local_var_shorthand_for),
+  enumerable: true,
+  configurable: true
+};
+var float_export_definition;
+float_export_definition = {
+  set: function (v) {
+    this._setProperty('float', v);
+  },
+  get: function () {
+    return this.getPropertyValue('float');
+  },
+  enumerable: true,
+  configurable: true
+};
+var floodColor_export_definition;
+floodColor_export_definition = {
+  set: function (v) {
+    this._setProperty('flood-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('flood-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var fontFamily_export_isValid, fontFamily_export_definition;
+var fontFamily_local_var_partsRegEx = /\s*,\s*/;
+
+fontFamily_export_isValid = function isValid(v) {
+  if (v === '' || v === null) {
+    return true;
+  }
+
+  var parts = v.split(fontFamily_local_var_partsRegEx);
+  var len = parts.length;
+  var i;
+  var type;
+
+  for (i = 0; i < len; i++) {
+    type = external_dependency_parsers_0.valueType(parts[i]);
+
+    if (type === external_dependency_parsers_0.TYPES.STRING || type === external_dependency_parsers_0.TYPES.KEYWORD) {
+      return true;
+    }
+  }
+
+  return false;
+};
+
+fontFamily_export_definition = {
+  set: function (v) {
+    this._setProperty('font-family', v);
+  },
+  get: function () {
+    return this.getPropertyValue('font-family');
+  },
+  enumerable: true,
+  configurable: true
+};
+var fontSize_export_isValid, fontSize_export_definition;
+var fontSize_local_var_absoluteSizes = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'];
+var fontSize_local_var_relativeSizes = ['larger', 'smaller'];
+
+fontSize_export_isValid = function (v) {
+  var type = external_dependency_parsers_0.valueType(v.toLowerCase());
+  return type === external_dependency_parsers_0.TYPES.LENGTH || type === external_dependency_parsers_0.TYPES.PERCENT || type === external_dependency_parsers_0.TYPES.KEYWORD && fontSize_local_var_absoluteSizes.indexOf(v.toLowerCase()) !== -1 || type === external_dependency_parsers_0.TYPES.KEYWORD && fontSize_local_var_relativeSizes.indexOf(v.toLowerCase()) !== -1;
+};
+
+function fontSize_local_fn_parse(v) {
+  const valueAsString = String(v).toLowerCase();
+  const optionalArguments = fontSize_local_var_absoluteSizes.concat(fontSize_local_var_relativeSizes);
+  const isOptionalArgument = optionalArguments.some(stringValue => stringValue.toLowerCase() === valueAsString);
+  return isOptionalArgument ? valueAsString : external_dependency_parsers_0.parseMeasurement(v);
+}
+
+fontSize_export_definition = {
+  set: function (v) {
+    this._setProperty('font-size', fontSize_local_fn_parse(v));
+  },
+  get: function () {
+    return this.getPropertyValue('font-size');
+  },
+  enumerable: true,
+  configurable: true
+};
+var fontStyle_export_isValid, fontStyle_export_definition;
+var fontStyle_local_var_valid_styles = ['normal', 'italic', 'oblique', 'inherit'];
+
+fontStyle_export_isValid = function (v) {
+  return fontStyle_local_var_valid_styles.indexOf(v.toLowerCase()) !== -1;
+};
+
+fontStyle_export_definition = {
+  set: function (v) {
+    this._setProperty('font-style', v);
+  },
+  get: function () {
+    return this.getPropertyValue('font-style');
+  },
+  enumerable: true,
+  configurable: true
+};
+var fontVariant_export_isValid, fontVariant_export_definition;
+var fontVariant_local_var_valid_variants = ['normal', 'small-caps', 'inherit'];
+
+fontVariant_export_isValid = function isValid(v) {
+  return fontVariant_local_var_valid_variants.indexOf(v.toLowerCase()) !== -1;
+};
+
+fontVariant_export_definition = {
+  set: function (v) {
+    this._setProperty('font-variant', v);
+  },
+  get: function () {
+    return this.getPropertyValue('font-variant');
+  },
+  enumerable: true,
+  configurable: true
+};
+var fontWeight_export_isValid, fontWeight_export_definition;
+var fontWeight_local_var_valid_weights = ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'inherit'];
+
+fontWeight_export_isValid = function isValid(v) {
+  return fontWeight_local_var_valid_weights.indexOf(v.toLowerCase()) !== -1;
+};
+
+fontWeight_export_definition = {
+  set: function (v) {
+    this._setProperty('font-weight', v);
+  },
+  get: function () {
+    return this.getPropertyValue('font-weight');
+  },
+  enumerable: true,
+  configurable: true
+};
+var lineHeight_export_isValid, lineHeight_export_definition;
+
+lineHeight_export_isValid = function isValid(v) {
+  var type = external_dependency_parsers_0.valueType(v);
+  return type === external_dependency_parsers_0.TYPES.KEYWORD && v.toLowerCase() === 'normal' || v.toLowerCase() === 'inherit' || type === external_dependency_parsers_0.TYPES.NUMBER || type === external_dependency_parsers_0.TYPES.LENGTH || type === external_dependency_parsers_0.TYPES.PERCENT;
+};
+
+lineHeight_export_definition = {
+  set: function (v) {
+    this._setProperty('line-height', v);
+  },
+  get: function () {
+    return this.getPropertyValue('line-height');
+  },
+  enumerable: true,
+  configurable: true
+};
+var font_export_definition;
+var font_local_var_shorthand_for = {
+  'font-family': {
+    isValid: fontFamily_export_isValid,
+    definition: fontFamily_export_definition
+  },
+  'font-size': {
+    isValid: fontSize_export_isValid,
+    definition: fontSize_export_definition
+  },
+  'font-style': {
+    isValid: fontStyle_export_isValid,
+    definition: fontStyle_export_definition
+  },
+  'font-variant': {
+    isValid: fontVariant_export_isValid,
+    definition: fontVariant_export_definition
+  },
+  'font-weight': {
+    isValid: fontWeight_export_isValid,
+    definition: fontWeight_export_definition
+  },
+  'line-height': {
+    isValid: lineHeight_export_isValid,
+    definition: lineHeight_export_definition
+  }
+};
+var font_local_var_static_fonts = ['caption', 'icon', 'menu', 'message-box', 'small-caption', 'status-bar', 'inherit'];
+var font_local_var_setter = external_dependency_parsers_0.shorthandSetter('font', font_local_var_shorthand_for);
+font_export_definition = {
+  set: function (v) {
+    var short = external_dependency_parsers_0.shorthandParser(v, font_local_var_shorthand_for);
+
+    if (short !== undefined) {
+      return font_local_var_setter.call(this, v);
+    }
+
+    if (external_dependency_parsers_0.valueType(v) === external_dependency_parsers_0.TYPES.KEYWORD && font_local_var_static_fonts.indexOf(v.toLowerCase()) !== -1) {
+      this._setProperty('font', v);
+    }
+  },
+  get: external_dependency_parsers_0.shorthandGetter('font', font_local_var_shorthand_for),
+  enumerable: true,
+  configurable: true
+};
+var height_export_definition;
+
+function height_local_fn_parse(v) {
+  if (String(v).toLowerCase() === 'auto') {
+    return 'auto';
+  }
+
+  if (String(v).toLowerCase() === 'inherit') {
+    return 'inherit';
+  }
+
+  return external_dependency_parsers_0.parseMeasurement(v);
+}
+
+height_export_definition = {
+  set: function (v) {
+    this._setProperty('height', height_local_fn_parse(v));
+  },
+  get: function () {
+    return this.getPropertyValue('height');
+  },
+  enumerable: true,
+  configurable: true
+};
+var left_export_definition;
+left_export_definition = {
+  set: function (v) {
+    this._setProperty('left', external_dependency_parsers_0.parseMeasurement(v));
+  },
+  get: function () {
+    return this.getPropertyValue('left');
+  },
+  enumerable: true,
+  configurable: true
+};
+var lightingColor_export_definition;
+lightingColor_export_definition = {
+  set: function (v) {
+    this._setProperty('lighting-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('lighting-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var margin_export_definition, margin_export_isValid, margin_export_parser;
+var margin_local_var_TYPES = external_dependency_parsers_0.TYPES;
+
+var margin_local_var_isValid = function (v) {
+  if (v.toLowerCase() === 'auto') {
+    return true;
+  }
+
+  var type = external_dependency_parsers_0.valueType(v);
+  return type === margin_local_var_TYPES.LENGTH || type === margin_local_var_TYPES.PERCENT || type === margin_local_var_TYPES.INTEGER && (v === '0' || v === 0);
+};
+
+var margin_local_var_parser = function (v) {
+  var V = v.toLowerCase();
+
+  if (V === 'auto') {
+    return V;
+  }
+
+  return external_dependency_parsers_0.parseMeasurement(v);
+};
+
+var margin_local_var_mySetter = external_dependency_parsers_0.implicitSetter('margin', '', margin_local_var_isValid, margin_local_var_parser);
+var margin_local_var_myGlobal = external_dependency_parsers_0.implicitSetter('margin', '', function () {
+  return true;
+}, function (v) {
+  return v;
+});
+margin_export_definition = {
+  set: function (v) {
+    if (typeof v === 'number') {
+      v = String(v);
+    }
+
+    if (typeof v !== 'string') {
+      return;
+    }
+
+    var V = v.toLowerCase();
+
+    switch (V) {
+      case 'inherit':
+      case 'initial':
+      case 'unset':
+      case '':
+        margin_local_var_myGlobal.call(this, V);
+        break;
+
+      default:
+        margin_local_var_mySetter.call(this, v);
+        break;
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('margin');
+  },
+  enumerable: true,
+  configurable: true
+};
+margin_export_isValid = margin_local_var_isValid;
+margin_export_parser = margin_local_var_parser;
+var marginBottom_export_definition;
+marginBottom_export_definition = {
+  set: external_dependency_parsers_0.subImplicitSetter('margin', 'bottom', {
+    definition: margin_export_definition,
+    isValid: margin_export_isValid,
+    parser: margin_export_parser
+  }.isValid, {
+    definition: margin_export_definition,
+    isValid: margin_export_isValid,
+    parser: margin_export_parser
+  }.parser),
+  get: function () {
+    return this.getPropertyValue('margin-bottom');
+  },
+  enumerable: true,
+  configurable: true
+};
+var marginLeft_export_definition;
+marginLeft_export_definition = {
+  set: external_dependency_parsers_0.subImplicitSetter('margin', 'left', {
+    definition: margin_export_definition,
+    isValid: margin_export_isValid,
+    parser: margin_export_parser
+  }.isValid, {
+    definition: margin_export_definition,
+    isValid: margin_export_isValid,
+    parser: margin_export_parser
+  }.parser),
+  get: function () {
+    return this.getPropertyValue('margin-left');
+  },
+  enumerable: true,
+  configurable: true
+};
+var marginRight_export_definition;
+marginRight_export_definition = {
+  set: external_dependency_parsers_0.subImplicitSetter('margin', 'right', {
+    definition: margin_export_definition,
+    isValid: margin_export_isValid,
+    parser: margin_export_parser
+  }.isValid, {
+    definition: margin_export_definition,
+    isValid: margin_export_isValid,
+    parser: margin_export_parser
+  }.parser),
+  get: function () {
+    return this.getPropertyValue('margin-right');
+  },
+  enumerable: true,
+  configurable: true
+};
+var marginTop_export_definition;
+marginTop_export_definition = {
+  set: external_dependency_parsers_0.subImplicitSetter('margin', 'top', {
+    definition: margin_export_definition,
+    isValid: margin_export_isValid,
+    parser: margin_export_parser
+  }.isValid, {
+    definition: margin_export_definition,
+    isValid: margin_export_isValid,
+    parser: margin_export_parser
+  }.parser),
+  get: function () {
+    return this.getPropertyValue('margin-top');
+  },
+  enumerable: true,
+  configurable: true
+};
+var opacity_export_definition;
+opacity_export_definition = {
+  set: function (v) {
+    this._setProperty('opacity', external_dependency_parsers_0.parseNumber(v));
+  },
+  get: function () {
+    return this.getPropertyValue('opacity');
+  },
+  enumerable: true,
+  configurable: true
+};
+var outlineColor_export_definition;
+outlineColor_export_definition = {
+  set: function (v) {
+    this._setProperty('outline-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('outline-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var padding_export_definition, padding_export_isValid, padding_export_parser;
+var padding_local_var_TYPES = external_dependency_parsers_0.TYPES;
+
+var padding_local_var_isValid = function (v) {
+  var type = external_dependency_parsers_0.valueType(v);
+  return type === padding_local_var_TYPES.LENGTH || type === padding_local_var_TYPES.PERCENT || type === padding_local_var_TYPES.INTEGER && (v === '0' || v === 0);
+};
+
+var padding_local_var_parser = function (v) {
+  return external_dependency_parsers_0.parseMeasurement(v);
+};
+
+var padding_local_var_mySetter = external_dependency_parsers_0.implicitSetter('padding', '', padding_local_var_isValid, padding_local_var_parser);
+var padding_local_var_myGlobal = external_dependency_parsers_0.implicitSetter('padding', '', function () {
+  return true;
+}, function (v) {
+  return v;
+});
+padding_export_definition = {
+  set: function (v) {
+    if (typeof v === 'number') {
+      v = String(v);
+    }
+
+    if (typeof v !== 'string') {
+      return;
+    }
+
+    var V = v.toLowerCase();
+
+    switch (V) {
+      case 'inherit':
+      case 'initial':
+      case 'unset':
+      case '':
+        padding_local_var_myGlobal.call(this, V);
+        break;
+
+      default:
+        padding_local_var_mySetter.call(this, v);
+        break;
+    }
+  },
+  get: function () {
+    return this.getPropertyValue('padding');
+  },
+  enumerable: true,
+  configurable: true
+};
+padding_export_isValid = padding_local_var_isValid;
+padding_export_parser = padding_local_var_parser;
+var paddingBottom_export_definition;
+paddingBottom_export_definition = {
+  set: external_dependency_parsers_0.subImplicitSetter('padding', 'bottom', {
+    definition: padding_export_definition,
+    isValid: padding_export_isValid,
+    parser: padding_export_parser
+  }.isValid, {
+    definition: padding_export_definition,
+    isValid: padding_export_isValid,
+    parser: padding_export_parser
+  }.parser),
+  get: function () {
+    return this.getPropertyValue('padding-bottom');
+  },
+  enumerable: true,
+  configurable: true
+};
+var paddingLeft_export_definition;
+paddingLeft_export_definition = {
+  set: external_dependency_parsers_0.subImplicitSetter('padding', 'left', {
+    definition: padding_export_definition,
+    isValid: padding_export_isValid,
+    parser: padding_export_parser
+  }.isValid, {
+    definition: padding_export_definition,
+    isValid: padding_export_isValid,
+    parser: padding_export_parser
+  }.parser),
+  get: function () {
+    return this.getPropertyValue('padding-left');
+  },
+  enumerable: true,
+  configurable: true
+};
+var paddingRight_export_definition;
+paddingRight_export_definition = {
+  set: external_dependency_parsers_0.subImplicitSetter('padding', 'right', {
+    definition: padding_export_definition,
+    isValid: padding_export_isValid,
+    parser: padding_export_parser
+  }.isValid, {
+    definition: padding_export_definition,
+    isValid: padding_export_isValid,
+    parser: padding_export_parser
+  }.parser),
+  get: function () {
+    return this.getPropertyValue('padding-right');
+  },
+  enumerable: true,
+  configurable: true
+};
+var paddingTop_export_definition;
+paddingTop_export_definition = {
+  set: external_dependency_parsers_0.subImplicitSetter('padding', 'top', {
+    definition: padding_export_definition,
+    isValid: padding_export_isValid,
+    parser: padding_export_parser
+  }.isValid, {
+    definition: padding_export_definition,
+    isValid: padding_export_isValid,
+    parser: padding_export_parser
+  }.parser),
+  get: function () {
+    return this.getPropertyValue('padding-top');
+  },
+  enumerable: true,
+  configurable: true
+};
+var right_export_definition;
+right_export_definition = {
+  set: function (v) {
+    this._setProperty('right', external_dependency_parsers_0.parseMeasurement(v));
+  },
+  get: function () {
+    return this.getPropertyValue('right');
+  },
+  enumerable: true,
+  configurable: true
+};
+var stopColor_export_definition;
+stopColor_export_definition = {
+  set: function (v) {
+    this._setProperty('stop-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('stop-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var textLineThroughColor_export_definition;
+textLineThroughColor_export_definition = {
+  set: function (v) {
+    this._setProperty('text-line-through-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('text-line-through-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var textOverlineColor_export_definition;
+textOverlineColor_export_definition = {
+  set: function (v) {
+    this._setProperty('text-overline-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('text-overline-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var textUnderlineColor_export_definition;
+textUnderlineColor_export_definition = {
+  set: function (v) {
+    this._setProperty('text-underline-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('text-underline-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var top_export_definition;
+top_export_definition = {
+  set: function (v) {
+    this._setProperty('top', external_dependency_parsers_0.parseMeasurement(v));
+  },
+  get: function () {
+    return this.getPropertyValue('top');
+  },
+  enumerable: true,
+  configurable: true
+};
+var webkitBorderAfterColor_export_definition;
+webkitBorderAfterColor_export_definition = {
+  set: function (v) {
+    this._setProperty('-webkit-border-after-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('-webkit-border-after-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var webkitBorderBeforeColor_export_definition;
+webkitBorderBeforeColor_export_definition = {
+  set: function (v) {
+    this._setProperty('-webkit-border-before-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('-webkit-border-before-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var webkitBorderEndColor_export_definition;
+webkitBorderEndColor_export_definition = {
+  set: function (v) {
+    this._setProperty('-webkit-border-end-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('-webkit-border-end-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var webkitBorderStartColor_export_definition;
+webkitBorderStartColor_export_definition = {
+  set: function (v) {
+    this._setProperty('-webkit-border-start-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('-webkit-border-start-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var webkitColumnRuleColor_export_definition;
+webkitColumnRuleColor_export_definition = {
+  set: function (v) {
+    this._setProperty('-webkit-column-rule-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('-webkit-column-rule-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var webkitMatchNearestMailBlockquoteColor_export_definition;
+webkitMatchNearestMailBlockquoteColor_export_definition = {
+  set: function (v) {
+    this._setProperty('-webkit-match-nearest-mail-blockquote-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('-webkit-match-nearest-mail-blockquote-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var webkitTapHighlightColor_export_definition;
+webkitTapHighlightColor_export_definition = {
+  set: function (v) {
+    this._setProperty('-webkit-tap-highlight-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('-webkit-tap-highlight-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var webkitTextEmphasisColor_export_definition;
+webkitTextEmphasisColor_export_definition = {
+  set: function (v) {
+    this._setProperty('-webkit-text-emphasis-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('-webkit-text-emphasis-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var webkitTextFillColor_export_definition;
+webkitTextFillColor_export_definition = {
+  set: function (v) {
+    this._setProperty('-webkit-text-fill-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('-webkit-text-fill-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var webkitTextStrokeColor_export_definition;
+webkitTextStrokeColor_export_definition = {
+  set: function (v) {
+    this._setProperty('-webkit-text-stroke-color', external_dependency_parsers_0.parseColor(v));
+  },
+  get: function () {
+    return this.getPropertyValue('-webkit-text-stroke-color');
+  },
+  enumerable: true,
+  configurable: true
+};
+var width_export_definition;
+
+function width_local_fn_parse(v) {
+  if (String(v).toLowerCase() === 'auto') {
+    return 'auto';
+  }
+
+  if (String(v).toLowerCase() === 'inherit') {
+    return 'inherit';
+  }
+
+  return external_dependency_parsers_0.parseMeasurement(v);
+}
+
+width_export_definition = {
+  set: function (v) {
+    this._setProperty('width', width_local_fn_parse(v));
+  },
+  get: function () {
+    return this.getPropertyValue('width');
+  },
+  enumerable: true,
+  configurable: true
+};
+
+module.exports = function (prototype) {
+  Object.defineProperties(prototype, {
+    azimuth: azimuth_export_definition,
+    backgroundColor: backgroundColor_export_definition,
+    "background-color": backgroundColor_export_definition,
+    backgroundImage: backgroundImage_export_definition,
+    "background-image": backgroundImage_export_definition,
+    backgroundRepeat: backgroundRepeat_export_definition,
+    "background-repeat": backgroundRepeat_export_definition,
+    backgroundAttachment: backgroundAttachment_export_definition,
+    "background-attachment": backgroundAttachment_export_definition,
+    backgroundPosition: backgroundPosition_export_definition,
+    "background-position": backgroundPosition_export_definition,
+    background: background_export_definition,
+    borderWidth: borderWidth_export_definition,
+    "border-width": borderWidth_export_definition,
+    borderStyle: borderStyle_export_definition,
+    "border-style": borderStyle_export_definition,
+    borderColor: borderColor_export_definition,
+    "border-color": borderColor_export_definition,
+    border: border_export_definition,
+    borderBottomWidth: borderBottomWidth_export_definition,
+    "border-bottom-width": borderBottomWidth_export_definition,
+    borderBottomStyle: borderBottomStyle_export_definition,
+    "border-bottom-style": borderBottomStyle_export_definition,
+    borderBottomColor: borderBottomColor_export_definition,
+    "border-bottom-color": borderBottomColor_export_definition,
+    borderBottom: borderBottom_export_definition,
+    "border-bottom": borderBottom_export_definition,
+    borderCollapse: borderCollapse_export_definition,
+    "border-collapse": borderCollapse_export_definition,
+    borderLeftWidth: borderLeftWidth_export_definition,
+    "border-left-width": borderLeftWidth_export_definition,
+    borderLeftStyle: borderLeftStyle_export_definition,
+    "border-left-style": borderLeftStyle_export_definition,
+    borderLeftColor: borderLeftColor_export_definition,
+    "border-left-color": borderLeftColor_export_definition,
+    borderLeft: borderLeft_export_definition,
+    "border-left": borderLeft_export_definition,
+    borderRightWidth: borderRightWidth_export_definition,
+    "border-right-width": borderRightWidth_export_definition,
+    borderRightStyle: borderRightStyle_export_definition,
+    "border-right-style": borderRightStyle_export_definition,
+    borderRightColor: borderRightColor_export_definition,
+    "border-right-color": borderRightColor_export_definition,
+    borderRight: borderRight_export_definition,
+    "border-right": borderRight_export_definition,
+    borderSpacing: borderSpacing_export_definition,
+    "border-spacing": borderSpacing_export_definition,
+    borderTopWidth: borderTopWidth_export_definition,
+    "border-top-width": borderTopWidth_export_definition,
+    borderTopStyle: borderTopStyle_export_definition,
+    "border-top-style": borderTopStyle_export_definition,
+    borderTopColor: borderTopColor_export_definition,
+    "border-top-color": borderTopColor_export_definition,
+    borderTop: borderTop_export_definition,
+    "border-top": borderTop_export_definition,
+    bottom: bottom_export_definition,
+    clear: clear_export_definition,
+    clip: clip_export_definition,
+    color: color_export_definition,
+    cssFloat: cssFloat_export_definition,
+    "css-float": cssFloat_export_definition,
+    flexGrow: flexGrow_export_definition,
+    "flex-grow": flexGrow_export_definition,
+    flexShrink: flexShrink_export_definition,
+    "flex-shrink": flexShrink_export_definition,
+    flexBasis: flexBasis_export_definition,
+    "flex-basis": flexBasis_export_definition,
+    flex: flex_export_definition,
+    float: float_export_definition,
+    floodColor: floodColor_export_definition,
+    "flood-color": floodColor_export_definition,
+    fontFamily: fontFamily_export_definition,
+    "font-family": fontFamily_export_definition,
+    fontSize: fontSize_export_definition,
+    "font-size": fontSize_export_definition,
+    fontStyle: fontStyle_export_definition,
+    "font-style": fontStyle_export_definition,
+    fontVariant: fontVariant_export_definition,
+    "font-variant": fontVariant_export_definition,
+    fontWeight: fontWeight_export_definition,
+    "font-weight": fontWeight_export_definition,
+    lineHeight: lineHeight_export_definition,
+    "line-height": lineHeight_export_definition,
+    font: font_export_definition,
+    height: height_export_definition,
+    left: left_export_definition,
+    lightingColor: lightingColor_export_definition,
+    "lighting-color": lightingColor_export_definition,
+    margin: margin_export_definition,
+    marginBottom: marginBottom_export_definition,
+    "margin-bottom": marginBottom_export_definition,
+    marginLeft: marginLeft_export_definition,
+    "margin-left": marginLeft_export_definition,
+    marginRight: marginRight_export_definition,
+    "margin-right": marginRight_export_definition,
+    marginTop: marginTop_export_definition,
+    "margin-top": marginTop_export_definition,
+    opacity: opacity_export_definition,
+    outlineColor: outlineColor_export_definition,
+    "outline-color": outlineColor_export_definition,
+    padding: padding_export_definition,
+    paddingBottom: paddingBottom_export_definition,
+    "padding-bottom": paddingBottom_export_definition,
+    paddingLeft: paddingLeft_export_definition,
+    "padding-left": paddingLeft_export_definition,
+    paddingRight: paddingRight_export_definition,
+    "padding-right": paddingRight_export_definition,
+    paddingTop: paddingTop_export_definition,
+    "padding-top": paddingTop_export_definition,
+    right: right_export_definition,
+    stopColor: stopColor_export_definition,
+    "stop-color": stopColor_export_definition,
+    textLineThroughColor: textLineThroughColor_export_definition,
+    "text-line-through-color": textLineThroughColor_export_definition,
+    textOverlineColor: textOverlineColor_export_definition,
+    "text-overline-color": textOverlineColor_export_definition,
+    textUnderlineColor: textUnderlineColor_export_definition,
+    "text-underline-color": textUnderlineColor_export_definition,
+    top: top_export_definition,
+    webkitBorderAfterColor: webkitBorderAfterColor_export_definition,
+    "webkit-border-after-color": webkitBorderAfterColor_export_definition,
+    webkitBorderBeforeColor: webkitBorderBeforeColor_export_definition,
+    "webkit-border-before-color": webkitBorderBeforeColor_export_definition,
+    webkitBorderEndColor: webkitBorderEndColor_export_definition,
+    "webkit-border-end-color": webkitBorderEndColor_export_definition,
+    webkitBorderStartColor: webkitBorderStartColor_export_definition,
+    "webkit-border-start-color": webkitBorderStartColor_export_definition,
+    webkitColumnRuleColor: webkitColumnRuleColor_export_definition,
+    "webkit-column-rule-color": webkitColumnRuleColor_export_definition,
+    webkitMatchNearestMailBlockquoteColor: webkitMatchNearestMailBlockquoteColor_export_definition,
+    "webkit-match-nearest-mail-blockquote-color": webkitMatchNearestMailBlockquoteColor_export_definition,
+    webkitTapHighlightColor: webkitTapHighlightColor_export_definition,
+    "webkit-tap-highlight-color": webkitTapHighlightColor_export_definition,
+    webkitTextEmphasisColor: webkitTextEmphasisColor_export_definition,
+    "webkit-text-emphasis-color": webkitTextEmphasisColor_export_definition,
+    webkitTextFillColor: webkitTextFillColor_export_definition,
+    "webkit-text-fill-color": webkitTextFillColor_export_definition,
+    webkitTextStrokeColor: webkitTextStrokeColor_export_definition,
+    "webkit-text-stroke-color": webkitTextStrokeColor_export_definition,
+    width: width_export_definition
+  });
+};
Index: frontend/node_modules/cssstyle/lib/properties/azimuth.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/azimuth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/azimuth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,67 @@
+'use strict';
+
+var parsers = require('../parsers');
+
+module.exports.definition = {
+  set: function(v) {
+    var valueType = parsers.valueType(v);
+    if (valueType === parsers.TYPES.ANGLE) {
+      return this._setProperty('azimuth', parsers.parseAngle(v));
+    }
+    if (valueType === parsers.TYPES.KEYWORD) {
+      var keywords = v
+        .toLowerCase()
+        .trim()
+        .split(/\s+/);
+      var hasBehind = false;
+      if (keywords.length > 2) {
+        return;
+      }
+      var behindIndex = keywords.indexOf('behind');
+      hasBehind = behindIndex !== -1;
+
+      if (keywords.length === 2) {
+        if (!hasBehind) {
+          return;
+        }
+        keywords.splice(behindIndex, 1);
+      }
+      if (keywords[0] === 'leftwards' || keywords[0] === 'rightwards') {
+        if (hasBehind) {
+          return;
+        }
+        return this._setProperty('azimuth', keywords[0]);
+      }
+      if (keywords[0] === 'behind') {
+        return this._setProperty('azimuth', '180deg');
+      }
+      switch (keywords[0]) {
+        case 'left-side':
+          return this._setProperty('azimuth', '270deg');
+        case 'far-left':
+          return this._setProperty('azimuth', (hasBehind ? 240 : 300) + 'deg');
+        case 'left':
+          return this._setProperty('azimuth', (hasBehind ? 220 : 320) + 'deg');
+        case 'center-left':
+          return this._setProperty('azimuth', (hasBehind ? 200 : 340) + 'deg');
+        case 'center':
+          return this._setProperty('azimuth', (hasBehind ? 180 : 0) + 'deg');
+        case 'center-right':
+          return this._setProperty('azimuth', (hasBehind ? 160 : 20) + 'deg');
+        case 'right':
+          return this._setProperty('azimuth', (hasBehind ? 140 : 40) + 'deg');
+        case 'far-right':
+          return this._setProperty('azimuth', (hasBehind ? 120 : 60) + 'deg');
+        case 'right-side':
+          return this._setProperty('azimuth', '90deg');
+        default:
+          return;
+      }
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('azimuth');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/background.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/background.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/background.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,19 @@
+'use strict';
+
+var shorthandSetter = require('../parsers').shorthandSetter;
+var shorthandGetter = require('../parsers').shorthandGetter;
+
+var shorthand_for = {
+  'background-color': require('./backgroundColor'),
+  'background-image': require('./backgroundImage'),
+  'background-repeat': require('./backgroundRepeat'),
+  'background-attachment': require('./backgroundAttachment'),
+  'background-position': require('./backgroundPosition'),
+};
+
+module.exports.definition = {
+  set: shorthandSetter('background', shorthand_for),
+  get: shorthandGetter('background', shorthand_for),
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/backgroundAttachment.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/backgroundAttachment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/backgroundAttachment.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,24 @@
+'use strict';
+
+var parsers = require('../parsers');
+
+var isValid = (module.exports.isValid = function isValid(v) {
+  return (
+    parsers.valueType(v) === parsers.TYPES.KEYWORD &&
+    (v.toLowerCase() === 'scroll' || v.toLowerCase() === 'fixed' || v.toLowerCase() === 'inherit')
+  );
+});
+
+module.exports.definition = {
+  set: function(v) {
+    if (!isValid(v)) {
+      return;
+    }
+    this._setProperty('background-attachment', v);
+  },
+  get: function() {
+    return this.getPropertyValue('background-attachment');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/backgroundColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/backgroundColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/backgroundColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+'use strict';
+
+var parsers = require('../parsers');
+
+var parse = function parse(v) {
+  var parsed = parsers.parseColor(v);
+  if (parsed !== undefined) {
+    return parsed;
+  }
+  if (
+    parsers.valueType(v) === parsers.TYPES.KEYWORD &&
+    (v.toLowerCase() === 'transparent' || v.toLowerCase() === 'inherit')
+  ) {
+    return v;
+  }
+  return undefined;
+};
+
+module.exports.isValid = function isValid(v) {
+  return parse(v) !== undefined;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    var parsed = parse(v);
+    if (parsed === undefined) {
+      return;
+    }
+    this._setProperty('background-color', parsed);
+  },
+  get: function() {
+    return this.getPropertyValue('background-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/backgroundImage.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/backgroundImage.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/backgroundImage.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,32 @@
+'use strict';
+
+var parsers = require('../parsers');
+
+var parse = function parse(v) {
+  var parsed = parsers.parseUrl(v);
+  if (parsed !== undefined) {
+    return parsed;
+  }
+  if (
+    parsers.valueType(v) === parsers.TYPES.KEYWORD &&
+    (v.toLowerCase() === 'none' || v.toLowerCase() === 'inherit')
+  ) {
+    return v;
+  }
+  return undefined;
+};
+
+module.exports.isValid = function isValid(v) {
+  return parse(v) !== undefined;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('background-image', parse(v));
+  },
+  get: function() {
+    return this.getPropertyValue('background-image');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/backgroundPosition.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/backgroundPosition.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/backgroundPosition.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,58 @@
+'use strict';
+
+var parsers = require('../parsers');
+
+var valid_keywords = ['top', 'center', 'bottom', 'left', 'right'];
+
+var parse = function parse(v) {
+  if (v === '' || v === null) {
+    return undefined;
+  }
+  var parts = v.split(/\s+/);
+  if (parts.length > 2 || parts.length < 1) {
+    return undefined;
+  }
+  var types = [];
+  parts.forEach(function(part, index) {
+    types[index] = parsers.valueType(part);
+  });
+  if (parts.length === 1) {
+    if (types[0] === parsers.TYPES.LENGTH || types[0] === parsers.TYPES.PERCENT) {
+      return v;
+    }
+    if (types[0] === parsers.TYPES.KEYWORD) {
+      if (valid_keywords.indexOf(v.toLowerCase()) !== -1 || v.toLowerCase() === 'inherit') {
+        return v;
+      }
+    }
+    return undefined;
+  }
+  if (
+    (types[0] === parsers.TYPES.LENGTH || types[0] === parsers.TYPES.PERCENT) &&
+    (types[1] === parsers.TYPES.LENGTH || types[1] === parsers.TYPES.PERCENT)
+  ) {
+    return v;
+  }
+  if (types[0] !== parsers.TYPES.KEYWORD || types[1] !== parsers.TYPES.KEYWORD) {
+    return undefined;
+  }
+  if (valid_keywords.indexOf(parts[0]) !== -1 && valid_keywords.indexOf(parts[1]) !== -1) {
+    return v;
+  }
+  return undefined;
+};
+
+module.exports.isValid = function isValid(v) {
+  return parse(v) !== undefined;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('background-position', parse(v));
+  },
+  get: function() {
+    return this.getPropertyValue('background-position');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/backgroundRepeat.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/backgroundRepeat.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/backgroundRepeat.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,32 @@
+'use strict';
+
+var parsers = require('../parsers');
+
+var parse = function parse(v) {
+  if (
+    parsers.valueType(v) === parsers.TYPES.KEYWORD &&
+    (v.toLowerCase() === 'repeat' ||
+      v.toLowerCase() === 'repeat-x' ||
+      v.toLowerCase() === 'repeat-y' ||
+      v.toLowerCase() === 'no-repeat' ||
+      v.toLowerCase() === 'inherit')
+  ) {
+    return v;
+  }
+  return undefined;
+};
+
+module.exports.isValid = function isValid(v) {
+  return parse(v) !== undefined;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('background-repeat', parse(v));
+  },
+  get: function() {
+    return this.getPropertyValue('background-repeat');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/border.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/border.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/border.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,33 @@
+'use strict';
+
+var shorthandSetter = require('../parsers').shorthandSetter;
+var shorthandGetter = require('../parsers').shorthandGetter;
+
+var shorthand_for = {
+  'border-width': require('./borderWidth'),
+  'border-style': require('./borderStyle'),
+  'border-color': require('./borderColor'),
+};
+
+var myShorthandSetter = shorthandSetter('border', shorthand_for);
+var myShorthandGetter = shorthandGetter('border', shorthand_for);
+
+module.exports.definition = {
+  set: function(v) {
+    if (v.toString().toLowerCase() === 'none') {
+      v = '';
+    }
+    myShorthandSetter.call(this, v);
+    this.removeProperty('border-top');
+    this.removeProperty('border-left');
+    this.removeProperty('border-right');
+    this.removeProperty('border-bottom');
+    this._values['border-top'] = this._values.border;
+    this._values['border-left'] = this._values.border;
+    this._values['border-right'] = this._values.border;
+    this._values['border-bottom'] = this._values.border;
+  },
+  get: myShorthandGetter,
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderBottom.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderBottom.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderBottom.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+'use strict';
+
+var shorthandSetter = require('../parsers').shorthandSetter;
+var shorthandGetter = require('../parsers').shorthandGetter;
+
+var shorthand_for = {
+  'border-bottom-width': require('./borderBottomWidth'),
+  'border-bottom-style': require('./borderBottomStyle'),
+  'border-bottom-color': require('./borderBottomColor'),
+};
+
+module.exports.definition = {
+  set: shorthandSetter('border-bottom', shorthand_for),
+  get: shorthandGetter('border-bottom', shorthand_for),
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderBottomColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderBottomColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderBottomColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,16 @@
+'use strict';
+
+var isValid = (module.exports.isValid = require('./borderColor').isValid);
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      this._setProperty('border-bottom-color', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-bottom-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderBottomStyle.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderBottomStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderBottomStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+'use strict';
+
+var isValid = require('./borderStyle').isValid;
+module.exports.isValid = isValid;
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      if (v.toLowerCase() === 'none') {
+        v = '';
+        this.removeProperty('border-bottom-width');
+      }
+      this._setProperty('border-bottom-style', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-bottom-style');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderBottomWidth.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderBottomWidth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderBottomWidth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,16 @@
+'use strict';
+
+var isValid = (module.exports.isValid = require('./borderWidth').isValid);
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      this._setProperty('border-bottom-width', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-bottom-width');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderCollapse.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderCollapse.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderCollapse.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,26 @@
+'use strict';
+
+var parsers = require('../parsers');
+
+var parse = function parse(v) {
+  if (
+    parsers.valueType(v) === parsers.TYPES.KEYWORD &&
+    (v.toLowerCase() === 'collapse' ||
+      v.toLowerCase() === 'separate' ||
+      v.toLowerCase() === 'inherit')
+  ) {
+    return v;
+  }
+  return undefined;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('border-collapse', parse(v));
+  },
+  get: function() {
+    return this.getPropertyValue('border-collapse');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,30 @@
+'use strict';
+
+var parsers = require('../parsers');
+var implicitSetter = require('../parsers').implicitSetter;
+
+module.exports.isValid = function parse(v) {
+  if (typeof v !== 'string') {
+    return false;
+  }
+  return (
+    v === '' || v.toLowerCase() === 'transparent' || parsers.valueType(v) === parsers.TYPES.COLOR
+  );
+};
+var isValid = module.exports.isValid;
+
+var parser = function(v) {
+  if (isValid(v)) {
+    return v.toLowerCase();
+  }
+  return undefined;
+};
+
+module.exports.definition = {
+  set: implicitSetter('border', 'color', isValid, parser),
+  get: function() {
+    return this.getPropertyValue('border-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderLeft.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderLeft.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderLeft.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+'use strict';
+
+var shorthandSetter = require('../parsers').shorthandSetter;
+var shorthandGetter = require('../parsers').shorthandGetter;
+
+var shorthand_for = {
+  'border-left-width': require('./borderLeftWidth'),
+  'border-left-style': require('./borderLeftStyle'),
+  'border-left-color': require('./borderLeftColor'),
+};
+
+module.exports.definition = {
+  set: shorthandSetter('border-left', shorthand_for),
+  get: shorthandGetter('border-left', shorthand_for),
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderLeftColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderLeftColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderLeftColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,16 @@
+'use strict';
+
+var isValid = (module.exports.isValid = require('./borderColor').isValid);
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      this._setProperty('border-left-color', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-left-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderLeftStyle.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderLeftStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderLeftStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+'use strict';
+
+var isValid = require('./borderStyle').isValid;
+module.exports.isValid = isValid;
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      if (v.toLowerCase() === 'none') {
+        v = '';
+        this.removeProperty('border-left-width');
+      }
+      this._setProperty('border-left-style', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-left-style');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderLeftWidth.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderLeftWidth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderLeftWidth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,16 @@
+'use strict';
+
+var isValid = (module.exports.isValid = require('./borderWidth').isValid);
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      this._setProperty('border-left-width', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-left-width');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderRight.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderRight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderRight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+'use strict';
+
+var shorthandSetter = require('../parsers').shorthandSetter;
+var shorthandGetter = require('../parsers').shorthandGetter;
+
+var shorthand_for = {
+  'border-right-width': require('./borderRightWidth'),
+  'border-right-style': require('./borderRightStyle'),
+  'border-right-color': require('./borderRightColor'),
+};
+
+module.exports.definition = {
+  set: shorthandSetter('border-right', shorthand_for),
+  get: shorthandGetter('border-right', shorthand_for),
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderRightColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderRightColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderRightColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,16 @@
+'use strict';
+
+var isValid = (module.exports.isValid = require('./borderColor').isValid);
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      this._setProperty('border-right-color', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-right-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderRightStyle.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderRightStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderRightStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+'use strict';
+
+var isValid = require('./borderStyle').isValid;
+module.exports.isValid = isValid;
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      if (v.toLowerCase() === 'none') {
+        v = '';
+        this.removeProperty('border-right-width');
+      }
+      this._setProperty('border-right-style', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-right-style');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderRightWidth.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderRightWidth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderRightWidth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,16 @@
+'use strict';
+
+var isValid = (module.exports.isValid = require('./borderWidth').isValid);
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      this._setProperty('border-right-width', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-right-width');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderSpacing.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderSpacing.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderSpacing.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,41 @@
+'use strict';
+
+var parsers = require('../parsers');
+
+// <length> <length>? | inherit
+// if one, it applies to both horizontal and verical spacing
+// if two, the first applies to the horizontal and the second applies to vertical spacing
+
+var parse = function parse(v) {
+  if (v === '' || v === null) {
+    return undefined;
+  }
+  if (v === 0) {
+    return '0px';
+  }
+  if (v.toLowerCase() === 'inherit') {
+    return v;
+  }
+  var parts = v.split(/\s+/);
+  if (parts.length !== 1 && parts.length !== 2) {
+    return undefined;
+  }
+  parts.forEach(function(part) {
+    if (parsers.valueType(part) !== parsers.TYPES.LENGTH) {
+      return undefined;
+    }
+  });
+
+  return v;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('border-spacing', parse(v));
+  },
+  get: function() {
+    return this.getPropertyValue('border-spacing');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderStyle.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,38 @@
+'use strict';
+
+var implicitSetter = require('../parsers').implicitSetter;
+
+// the valid border-styles:
+var styles = [
+  'none',
+  'hidden',
+  'dotted',
+  'dashed',
+  'solid',
+  'double',
+  'groove',
+  'ridge',
+  'inset',
+  'outset',
+];
+
+module.exports.isValid = function parse(v) {
+  return typeof v === 'string' && (v === '' || styles.indexOf(v) !== -1);
+};
+var isValid = module.exports.isValid;
+
+var parser = function(v) {
+  if (isValid(v)) {
+    return v.toLowerCase();
+  }
+  return undefined;
+};
+
+module.exports.definition = {
+  set: implicitSetter('border', 'style', isValid, parser),
+  get: function() {
+    return this.getPropertyValue('border-style');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderTop.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderTop.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderTop.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+'use strict';
+
+var shorthandSetter = require('../parsers').shorthandSetter;
+var shorthandGetter = require('../parsers').shorthandGetter;
+
+var shorthand_for = {
+  'border-top-width': require('./borderTopWidth'),
+  'border-top-style': require('./borderTopStyle'),
+  'border-top-color': require('./borderTopColor'),
+};
+
+module.exports.definition = {
+  set: shorthandSetter('border-top', shorthand_for),
+  get: shorthandGetter('border-top', shorthand_for),
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderTopColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderTopColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderTopColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,16 @@
+'use strict';
+
+var isValid = (module.exports.isValid = require('./borderColor').isValid);
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      this._setProperty('border-top-color', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-top-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderTopStyle.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderTopStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderTopStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+'use strict';
+
+var isValid = require('./borderStyle').isValid;
+module.exports.isValid = isValid;
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      if (v.toLowerCase() === 'none') {
+        v = '';
+        this.removeProperty('border-top-width');
+      }
+      this._setProperty('border-top-style', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-top-style');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderTopWidth.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderTopWidth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderTopWidth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+'use strict';
+
+var isValid = require('./borderWidth').isValid;
+module.exports.isValid = isValid;
+
+module.exports.definition = {
+  set: function(v) {
+    if (isValid(v)) {
+      this._setProperty('border-top-width', v);
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('border-top-width');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/borderWidth.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/borderWidth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/borderWidth.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,46 @@
+'use strict';
+
+var parsers = require('../parsers');
+var implicitSetter = require('../parsers').implicitSetter;
+
+// the valid border-widths:
+var widths = ['thin', 'medium', 'thick'];
+
+module.exports.isValid = function parse(v) {
+  var length = parsers.parseLength(v);
+  if (length !== undefined) {
+    return true;
+  }
+  if (typeof v !== 'string') {
+    return false;
+  }
+  if (v === '') {
+    return true;
+  }
+  v = v.toLowerCase();
+  if (widths.indexOf(v) === -1) {
+    return false;
+  }
+  return true;
+};
+var isValid = module.exports.isValid;
+
+var parser = function(v) {
+  var length = parsers.parseLength(v);
+  if (length !== undefined) {
+    return length;
+  }
+  if (isValid(v)) {
+    return v.toLowerCase();
+  }
+  return undefined;
+};
+
+module.exports.definition = {
+  set: implicitSetter('border', 'width', isValid, parser),
+  get: function() {
+    return this.getPropertyValue('border-width');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/bottom.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/bottom.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/bottom.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseMeasurement = require('../parsers').parseMeasurement;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('bottom', parseMeasurement(v));
+  },
+  get: function() {
+    return this.getPropertyValue('bottom');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/clear.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/clear.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/clear.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,16 @@
+'use strict';
+
+var parseKeyword = require('../parsers').parseKeyword;
+
+var clear_keywords = ['none', 'left', 'right', 'both', 'inherit'];
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('clear', parseKeyword(v, clear_keywords));
+  },
+  get: function() {
+    return this.getPropertyValue('clear');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/clip.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/clip.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/clip.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,47 @@
+'use strict';
+
+var parseMeasurement = require('../parsers').parseMeasurement;
+
+var shape_regex = /^rect\((.*)\)$/i;
+
+var parse = function(val) {
+  if (val === '' || val === null) {
+    return val;
+  }
+  if (typeof val !== 'string') {
+    return undefined;
+  }
+  val = val.toLowerCase();
+  if (val === 'auto' || val === 'inherit') {
+    return val;
+  }
+  var matches = val.match(shape_regex);
+  if (!matches) {
+    return undefined;
+  }
+  var parts = matches[1].split(/\s*,\s*/);
+  if (parts.length !== 4) {
+    return undefined;
+  }
+  var valid = parts.every(function(part, index) {
+    var measurement = parseMeasurement(part);
+    parts[index] = measurement;
+    return measurement !== undefined;
+  });
+  if (!valid) {
+    return undefined;
+  }
+  parts = parts.join(', ');
+  return val.replace(matches[1], parts);
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('clip', parse(v));
+  },
+  get: function() {
+    return this.getPropertyValue('clip');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/color.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/color.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/color.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/cssFloat.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/cssFloat.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/cssFloat.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,12 @@
+'use strict';
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('float', v);
+  },
+  get: function() {
+    return this.getPropertyValue('float');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/flex.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/flex.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/flex.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,45 @@
+'use strict';
+
+var shorthandParser = require('../parsers').shorthandParser;
+var shorthandSetter = require('../parsers').shorthandSetter;
+var shorthandGetter = require('../parsers').shorthandGetter;
+
+var shorthand_for = {
+  'flex-grow': require('./flexGrow'),
+  'flex-shrink': require('./flexShrink'),
+  'flex-basis': require('./flexBasis'),
+};
+
+var myShorthandSetter = shorthandSetter('flex', shorthand_for);
+
+module.exports.isValid = function isValid(v) {
+  return shorthandParser(v, shorthand_for) !== undefined;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    var normalizedValue = String(v)
+      .trim()
+      .toLowerCase();
+
+    if (normalizedValue === 'none') {
+      myShorthandSetter.call(this, '0 0 auto');
+      return;
+    }
+    if (normalizedValue === 'initial') {
+      myShorthandSetter.call(this, '0 1 auto');
+      return;
+    }
+    if (normalizedValue === 'auto') {
+      this.removeProperty('flex-grow');
+      this.removeProperty('flex-shrink');
+      this.setProperty('flex-basis', normalizedValue);
+      return;
+    }
+
+    myShorthandSetter.call(this, v);
+  },
+  get: shorthandGetter('flex', shorthand_for),
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/flexBasis.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/flexBasis.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/flexBasis.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,28 @@
+'use strict';
+
+var parseMeasurement = require('../parsers').parseMeasurement;
+
+function parse(v) {
+  if (String(v).toLowerCase() === 'auto') {
+    return 'auto';
+  }
+  if (String(v).toLowerCase() === 'inherit') {
+    return 'inherit';
+  }
+  return parseMeasurement(v);
+}
+
+module.exports.isValid = function isValid(v) {
+  return parse(v) !== undefined;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('flex-basis', parse(v));
+  },
+  get: function() {
+    return this.getPropertyValue('flex-basis');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/flexGrow.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/flexGrow.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/flexGrow.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,19 @@
+'use strict';
+
+var parseNumber = require('../parsers').parseNumber;
+var POSITION_AT_SHORTHAND = require('../constants').POSITION_AT_SHORTHAND;
+
+module.exports.isValid = function isValid(v, positionAtFlexShorthand) {
+  return parseNumber(v) !== undefined && positionAtFlexShorthand === POSITION_AT_SHORTHAND.first;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('flex-grow', parseNumber(v));
+  },
+  get: function() {
+    return this.getPropertyValue('flex-grow');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/flexShrink.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/flexShrink.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/flexShrink.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,19 @@
+'use strict';
+
+var parseNumber = require('../parsers').parseNumber;
+var POSITION_AT_SHORTHAND = require('../constants').POSITION_AT_SHORTHAND;
+
+module.exports.isValid = function isValid(v, positionAtFlexShorthand) {
+  return parseNumber(v) !== undefined && positionAtFlexShorthand === POSITION_AT_SHORTHAND.second;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('flex-shrink', parseNumber(v));
+  },
+  get: function() {
+    return this.getPropertyValue('flex-shrink');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/float.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/float.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/float.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,12 @@
+'use strict';
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('float', v);
+  },
+  get: function() {
+    return this.getPropertyValue('float');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/floodColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/floodColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/floodColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('flood-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('flood-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/font.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/font.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/font.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+'use strict';
+
+var TYPES = require('../parsers').TYPES;
+var valueType = require('../parsers').valueType;
+var shorthandParser = require('../parsers').shorthandParser;
+var shorthandSetter = require('../parsers').shorthandSetter;
+var shorthandGetter = require('../parsers').shorthandGetter;
+
+var shorthand_for = {
+  'font-family': require('./fontFamily'),
+  'font-size': require('./fontSize'),
+  'font-style': require('./fontStyle'),
+  'font-variant': require('./fontVariant'),
+  'font-weight': require('./fontWeight'),
+  'line-height': require('./lineHeight'),
+};
+
+var static_fonts = [
+  'caption',
+  'icon',
+  'menu',
+  'message-box',
+  'small-caption',
+  'status-bar',
+  'inherit',
+];
+
+var setter = shorthandSetter('font', shorthand_for);
+
+module.exports.definition = {
+  set: function(v) {
+    var short = shorthandParser(v, shorthand_for);
+    if (short !== undefined) {
+      return setter.call(this, v);
+    }
+    if (valueType(v) === TYPES.KEYWORD && static_fonts.indexOf(v.toLowerCase()) !== -1) {
+      this._setProperty('font', v);
+    }
+  },
+  get: shorthandGetter('font', shorthand_for),
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/fontFamily.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/fontFamily.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/fontFamily.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,33 @@
+'use strict';
+
+var TYPES = require('../parsers').TYPES;
+var valueType = require('../parsers').valueType;
+
+var partsRegEx = /\s*,\s*/;
+module.exports.isValid = function isValid(v) {
+  if (v === '' || v === null) {
+    return true;
+  }
+  var parts = v.split(partsRegEx);
+  var len = parts.length;
+  var i;
+  var type;
+  for (i = 0; i < len; i++) {
+    type = valueType(parts[i]);
+    if (type === TYPES.STRING || type === TYPES.KEYWORD) {
+      return true;
+    }
+  }
+  return false;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('font-family', v);
+  },
+  get: function() {
+    return this.getPropertyValue('font-family');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/fontSize.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/fontSize.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/fontSize.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,38 @@
+'use strict';
+
+var TYPES = require('../parsers').TYPES;
+var valueType = require('../parsers').valueType;
+var parseMeasurement = require('../parsers').parseMeasurement;
+
+var absoluteSizes = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'];
+var relativeSizes = ['larger', 'smaller'];
+
+module.exports.isValid = function(v) {
+  var type = valueType(v.toLowerCase());
+  return (
+    type === TYPES.LENGTH ||
+    type === TYPES.PERCENT ||
+    (type === TYPES.KEYWORD && absoluteSizes.indexOf(v.toLowerCase()) !== -1) ||
+    (type === TYPES.KEYWORD && relativeSizes.indexOf(v.toLowerCase()) !== -1)
+  );
+};
+
+function parse(v) {
+  const valueAsString = String(v).toLowerCase();
+  const optionalArguments = absoluteSizes.concat(relativeSizes);
+  const isOptionalArgument = optionalArguments.some(
+    stringValue => stringValue.toLowerCase() === valueAsString
+  );
+  return isOptionalArgument ? valueAsString : parseMeasurement(v);
+}
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('font-size', parse(v));
+  },
+  get: function() {
+    return this.getPropertyValue('font-size');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/fontStyle.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/fontStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/fontStyle.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,18 @@
+'use strict';
+
+var valid_styles = ['normal', 'italic', 'oblique', 'inherit'];
+
+module.exports.isValid = function(v) {
+  return valid_styles.indexOf(v.toLowerCase()) !== -1;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('font-style', v);
+  },
+  get: function() {
+    return this.getPropertyValue('font-style');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/fontVariant.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/fontVariant.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/fontVariant.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,18 @@
+'use strict';
+
+var valid_variants = ['normal', 'small-caps', 'inherit'];
+
+module.exports.isValid = function isValid(v) {
+  return valid_variants.indexOf(v.toLowerCase()) !== -1;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('font-variant', v);
+  },
+  get: function() {
+    return this.getPropertyValue('font-variant');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/fontWeight.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/fontWeight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/fontWeight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,33 @@
+'use strict';
+
+var valid_weights = [
+  'normal',
+  'bold',
+  'bolder',
+  'lighter',
+  '100',
+  '200',
+  '300',
+  '400',
+  '500',
+  '600',
+  '700',
+  '800',
+  '900',
+  'inherit',
+];
+
+module.exports.isValid = function isValid(v) {
+  return valid_weights.indexOf(v.toLowerCase()) !== -1;
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('font-weight', v);
+  },
+  get: function() {
+    return this.getPropertyValue('font-weight');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/height.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/height.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/height.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,24 @@
+'use strict';
+
+var parseMeasurement = require('../parsers').parseMeasurement;
+
+function parse(v) {
+  if (String(v).toLowerCase() === 'auto') {
+    return 'auto';
+  }
+  if (String(v).toLowerCase() === 'inherit') {
+    return 'inherit';
+  }
+  return parseMeasurement(v);
+}
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('height', parse(v));
+  },
+  get: function() {
+    return this.getPropertyValue('height');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/left.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/left.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/left.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseMeasurement = require('../parsers').parseMeasurement;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('left', parseMeasurement(v));
+  },
+  get: function() {
+    return this.getPropertyValue('left');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/lightingColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/lightingColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/lightingColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('lighting-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('lighting-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/lineHeight.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/lineHeight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/lineHeight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,26 @@
+'use strict';
+
+var TYPES = require('../parsers').TYPES;
+var valueType = require('../parsers').valueType;
+
+module.exports.isValid = function isValid(v) {
+  var type = valueType(v);
+  return (
+    (type === TYPES.KEYWORD && v.toLowerCase() === 'normal') ||
+    v.toLowerCase() === 'inherit' ||
+    type === TYPES.NUMBER ||
+    type === TYPES.LENGTH ||
+    type === TYPES.PERCENT
+  );
+};
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('line-height', v);
+  },
+  get: function() {
+    return this.getPropertyValue('line-height');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/margin.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/margin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/margin.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,68 @@
+'use strict';
+
+var parsers = require('../parsers.js');
+var TYPES = parsers.TYPES;
+
+var isValid = function(v) {
+  if (v.toLowerCase() === 'auto') {
+    return true;
+  }
+  var type = parsers.valueType(v);
+  return (
+    type === TYPES.LENGTH ||
+    type === TYPES.PERCENT ||
+    (type === TYPES.INTEGER && (v === '0' || v === 0))
+  );
+};
+
+var parser = function(v) {
+  var V = v.toLowerCase();
+  if (V === 'auto') {
+    return V;
+  }
+  return parsers.parseMeasurement(v);
+};
+
+var mySetter = parsers.implicitSetter('margin', '', isValid, parser);
+var myGlobal = parsers.implicitSetter(
+  'margin',
+  '',
+  function() {
+    return true;
+  },
+  function(v) {
+    return v;
+  }
+);
+
+module.exports.definition = {
+  set: function(v) {
+    if (typeof v === 'number') {
+      v = String(v);
+    }
+    if (typeof v !== 'string') {
+      return;
+    }
+    var V = v.toLowerCase();
+    switch (V) {
+      case 'inherit':
+      case 'initial':
+      case 'unset':
+      case '':
+        myGlobal.call(this, V);
+        break;
+
+      default:
+        mySetter.call(this, v);
+        break;
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('margin');
+  },
+  enumerable: true,
+  configurable: true,
+};
+
+module.exports.isValid = isValid;
+module.exports.parser = parser;
Index: frontend/node_modules/cssstyle/lib/properties/marginBottom.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/marginBottom.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/marginBottom.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+'use strict';
+
+var margin = require('./margin.js');
+var parsers = require('../parsers.js');
+
+module.exports.definition = {
+  set: parsers.subImplicitSetter('margin', 'bottom', margin.isValid, margin.parser),
+  get: function() {
+    return this.getPropertyValue('margin-bottom');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/marginLeft.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/marginLeft.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/marginLeft.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+'use strict';
+
+var margin = require('./margin.js');
+var parsers = require('../parsers.js');
+
+module.exports.definition = {
+  set: parsers.subImplicitSetter('margin', 'left', margin.isValid, margin.parser),
+  get: function() {
+    return this.getPropertyValue('margin-left');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/marginRight.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/marginRight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/marginRight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+'use strict';
+
+var margin = require('./margin.js');
+var parsers = require('../parsers.js');
+
+module.exports.definition = {
+  set: parsers.subImplicitSetter('margin', 'right', margin.isValid, margin.parser),
+  get: function() {
+    return this.getPropertyValue('margin-right');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/marginTop.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/marginTop.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/marginTop.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+'use strict';
+
+var margin = require('./margin.js');
+var parsers = require('../parsers.js');
+
+module.exports.definition = {
+  set: parsers.subImplicitSetter('margin', 'top', margin.isValid, margin.parser),
+  get: function() {
+    return this.getPropertyValue('margin-top');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/opacity.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/opacity.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/opacity.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseNumber = require('../parsers').parseNumber;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('opacity', parseNumber(v));
+  },
+  get: function() {
+    return this.getPropertyValue('opacity');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/outlineColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/outlineColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/outlineColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('outline-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('outline-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/padding.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/padding.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/padding.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,61 @@
+'use strict';
+
+var parsers = require('../parsers.js');
+var TYPES = parsers.TYPES;
+
+var isValid = function(v) {
+  var type = parsers.valueType(v);
+  return (
+    type === TYPES.LENGTH ||
+    type === TYPES.PERCENT ||
+    (type === TYPES.INTEGER && (v === '0' || v === 0))
+  );
+};
+
+var parser = function(v) {
+  return parsers.parseMeasurement(v);
+};
+
+var mySetter = parsers.implicitSetter('padding', '', isValid, parser);
+var myGlobal = parsers.implicitSetter(
+  'padding',
+  '',
+  function() {
+    return true;
+  },
+  function(v) {
+    return v;
+  }
+);
+
+module.exports.definition = {
+  set: function(v) {
+    if (typeof v === 'number') {
+      v = String(v);
+    }
+    if (typeof v !== 'string') {
+      return;
+    }
+    var V = v.toLowerCase();
+    switch (V) {
+      case 'inherit':
+      case 'initial':
+      case 'unset':
+      case '':
+        myGlobal.call(this, V);
+        break;
+
+      default:
+        mySetter.call(this, v);
+        break;
+    }
+  },
+  get: function() {
+    return this.getPropertyValue('padding');
+  },
+  enumerable: true,
+  configurable: true,
+};
+
+module.exports.isValid = isValid;
+module.exports.parser = parser;
Index: frontend/node_modules/cssstyle/lib/properties/paddingBottom.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/paddingBottom.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/paddingBottom.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+'use strict';
+
+var padding = require('./padding.js');
+var parsers = require('../parsers.js');
+
+module.exports.definition = {
+  set: parsers.subImplicitSetter('padding', 'bottom', padding.isValid, padding.parser),
+  get: function() {
+    return this.getPropertyValue('padding-bottom');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/paddingLeft.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/paddingLeft.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/paddingLeft.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+'use strict';
+
+var padding = require('./padding.js');
+var parsers = require('../parsers.js');
+
+module.exports.definition = {
+  set: parsers.subImplicitSetter('padding', 'left', padding.isValid, padding.parser),
+  get: function() {
+    return this.getPropertyValue('padding-left');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/paddingRight.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/paddingRight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/paddingRight.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+'use strict';
+
+var padding = require('./padding.js');
+var parsers = require('../parsers.js');
+
+module.exports.definition = {
+  set: parsers.subImplicitSetter('padding', 'right', padding.isValid, padding.parser),
+  get: function() {
+    return this.getPropertyValue('padding-right');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/paddingTop.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/paddingTop.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/paddingTop.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,13 @@
+'use strict';
+
+var padding = require('./padding.js');
+var parsers = require('../parsers.js');
+
+module.exports.definition = {
+  set: parsers.subImplicitSetter('padding', 'top', padding.isValid, padding.parser),
+  get: function() {
+    return this.getPropertyValue('padding-top');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/right.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/right.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/right.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseMeasurement = require('../parsers').parseMeasurement;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('right', parseMeasurement(v));
+  },
+  get: function() {
+    return this.getPropertyValue('right');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/stopColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/stopColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/stopColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('stop-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('stop-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/textLineThroughColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/textLineThroughColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/textLineThroughColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('text-line-through-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('text-line-through-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/textOverlineColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/textOverlineColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/textOverlineColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('text-overline-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('text-overline-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/textUnderlineColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/textUnderlineColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/textUnderlineColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('text-underline-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('text-underline-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/top.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/top.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/top.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseMeasurement = require('../parsers').parseMeasurement;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('top', parseMeasurement(v));
+  },
+  get: function() {
+    return this.getPropertyValue('top');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/webkitBorderAfterColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/webkitBorderAfterColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/webkitBorderAfterColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('-webkit-border-after-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('-webkit-border-after-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/webkitBorderBeforeColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/webkitBorderBeforeColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/webkitBorderBeforeColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('-webkit-border-before-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('-webkit-border-before-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/webkitBorderEndColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/webkitBorderEndColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/webkitBorderEndColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('-webkit-border-end-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('-webkit-border-end-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/webkitBorderStartColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/webkitBorderStartColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/webkitBorderStartColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('-webkit-border-start-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('-webkit-border-start-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/webkitColumnRuleColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/webkitColumnRuleColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/webkitColumnRuleColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('-webkit-column-rule-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('-webkit-column-rule-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/webkitMatchNearestMailBlockquoteColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/webkitMatchNearestMailBlockquoteColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/webkitMatchNearestMailBlockquoteColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('-webkit-match-nearest-mail-blockquote-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('-webkit-match-nearest-mail-blockquote-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/webkitTapHighlightColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/webkitTapHighlightColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/webkitTapHighlightColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('-webkit-tap-highlight-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('-webkit-tap-highlight-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/webkitTextEmphasisColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/webkitTextEmphasisColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/webkitTextEmphasisColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('-webkit-text-emphasis-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('-webkit-text-emphasis-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/webkitTextFillColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/webkitTextFillColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/webkitTextFillColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('-webkit-text-fill-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('-webkit-text-fill-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/webkitTextStrokeColor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/webkitTextStrokeColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/webkitTextStrokeColor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+var parseColor = require('../parsers').parseColor;
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('-webkit-text-stroke-color', parseColor(v));
+  },
+  get: function() {
+    return this.getPropertyValue('-webkit-text-stroke-color');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/properties/width.js
===================================================================
--- frontend/node_modules/cssstyle/lib/properties/width.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/properties/width.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,24 @@
+'use strict';
+
+var parseMeasurement = require('../parsers').parseMeasurement;
+
+function parse(v) {
+  if (String(v).toLowerCase() === 'auto') {
+    return 'auto';
+  }
+  if (String(v).toLowerCase() === 'inherit') {
+    return 'inherit';
+  }
+  return parseMeasurement(v);
+}
+
+module.exports.definition = {
+  set: function(v) {
+    this._setProperty('width', parse(v));
+  },
+  get: function() {
+    return this.getPropertyValue('width');
+  },
+  enumerable: true,
+  configurable: true,
+};
Index: frontend/node_modules/cssstyle/lib/utils/colorSpace.js
===================================================================
--- frontend/node_modules/cssstyle/lib/utils/colorSpace.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/utils/colorSpace.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+'use strict';
+
+const hueToRgb = (t1, t2, hue) => {
+  if (hue < 0) hue += 6;
+  if (hue >= 6) hue -= 6;
+
+  if (hue < 1) return (t2 - t1) * hue + t1;
+  else if (hue < 3) return t2;
+  else if (hue < 4) return (t2 - t1) * (4 - hue) + t1;
+  else return t1;
+};
+
+// https://www.w3.org/TR/css-color-4/#hsl-to-rgb
+exports.hslToRgb = (hue, sat, light) => {
+  const t2 = light <= 0.5 ? light * (sat + 1) : light + sat - light * sat;
+  const t1 = light * 2 - t2;
+  const r = hueToRgb(t1, t2, hue + 2);
+  const g = hueToRgb(t1, t2, hue);
+  const b = hueToRgb(t1, t2, hue - 2);
+  return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
+};
Index: frontend/node_modules/cssstyle/lib/utils/getBasicPropertyDescriptor.js
===================================================================
--- frontend/node_modules/cssstyle/lib/utils/getBasicPropertyDescriptor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/lib/utils/getBasicPropertyDescriptor.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,14 @@
+'use strict';
+
+module.exports = function getBasicPropertyDescriptor(name) {
+  return {
+    set: function(v) {
+      this._setProperty(name, v);
+    },
+    get: function() {
+      return this.getPropertyValue(name);
+    },
+    enumerable: true,
+    configurable: true,
+  };
+};
Index: frontend/node_modules/cssstyle/node_modules/cssom/LICENSE.txt
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/LICENSE.txt	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/LICENSE.txt	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+Copyright (c) Nikita Vasilyev
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Index: frontend/node_modules/cssstyle/node_modules/cssom/README.mdown
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/README.mdown	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/README.mdown	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,67 @@
+# CSSOM
+
+CSSOM.js is a CSS parser written in pure JavaScript. It is also a partial implementation of [CSS Object Model](http://dev.w3.org/csswg/cssom/). 
+
+    CSSOM.parse("body {color: black}")
+    -> {
+      cssRules: [
+        {
+          selectorText: "body",
+          style: {
+            0: "color",
+            color: "black",
+            length: 1
+          }
+        }
+      ]
+    }
+
+
+## [Parser demo](http://nv.github.com/CSSOM/docs/parse.html)
+
+Works well in Google Chrome 6+, Safari 5+, Firefox 3.6+, Opera 10.63+.
+Doesn't work in IE < 9 because of unsupported getters/setters.
+
+To use CSSOM.js in the browser you might want to build a one-file version that exposes a single `CSSOM` global variable:
+
+    ➤ git clone https://github.com/NV/CSSOM.git
+    ➤ cd CSSOM
+    ➤ node build.js
+    build/CSSOM.js is done
+
+To use it with Node.js or any other CommonJS loader:
+
+    ➤ npm install cssom
+
+## Don’t use it if...
+
+You parse CSS to mungle, minify or reformat code like this:
+
+```css
+div {
+  background: gray;
+  background: linear-gradient(to bottom, white 0%, black 100%);
+}
+```
+
+This pattern is often used to give browsers that don’t understand linear gradients a fallback solution (e.g. gray color in the example).
+In CSSOM, `background: gray` [gets overwritten](http://nv.github.io/CSSOM/docs/parse.html#css=div%20%7B%0A%20%20%20%20%20%20background%3A%20gray%3B%0A%20%20%20%20background%3A%20linear-gradient(to%20bottom%2C%20white%200%25%2C%20black%20100%25)%3B%0A%7D).
+It doesn't get preserved.
+
+If you do CSS mungling, minification, image inlining, and such, CSSOM.js is no good for you, considere using one of the following:
+
+  * [postcss](https://github.com/postcss/postcss)
+  * [reworkcss/css](https://github.com/reworkcss/css)
+  * [csso](https://github.com/css/csso)
+  * [mensch](https://github.com/brettstimmerman/mensch)
+
+
+## [Tests](http://nv.github.com/CSSOM/spec/)
+
+To run tests locally:
+
+    ➤ git submodule init
+    ➤ git submodule update
+
+
+## [Who uses CSSOM.js](https://github.com/NV/CSSOM/wiki/Who-uses-CSSOM.js)
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSDocumentRule.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSDocumentRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSDocumentRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+//.CommonJS
+var CSSOM = {
+    CSSRule: require("./CSSRule").CSSRule,
+    MatcherList: require("./MatcherList").MatcherList
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see https://developer.mozilla.org/en/CSS/@-moz-document
+ */
+CSSOM.CSSDocumentRule = function CSSDocumentRule() {
+    CSSOM.CSSRule.call(this);
+    this.matcher = new CSSOM.MatcherList();
+    this.cssRules = [];
+};
+
+CSSOM.CSSDocumentRule.prototype = new CSSOM.CSSRule();
+CSSOM.CSSDocumentRule.prototype.constructor = CSSOM.CSSDocumentRule;
+CSSOM.CSSDocumentRule.prototype.type = 10;
+//FIXME
+//CSSOM.CSSDocumentRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule;
+//CSSOM.CSSDocumentRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule;
+
+Object.defineProperty(CSSOM.CSSDocumentRule.prototype, "cssText", {
+  get: function() {
+    var cssTexts = [];
+    for (var i=0, length=this.cssRules.length; i < length; i++) {
+        cssTexts.push(this.cssRules[i].cssText);
+    }
+    return "@-moz-document " + this.matcher.matcherText + " {" + cssTexts.join("") + "}";
+  }
+});
+
+
+//.CommonJS
+exports.CSSDocumentRule = CSSOM.CSSDocumentRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSFontFaceRule.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSFontFaceRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSFontFaceRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+//.CommonJS
+var CSSOM = {
+	CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration,
+	CSSRule: require("./CSSRule").CSSRule
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://dev.w3.org/csswg/cssom/#css-font-face-rule
+ */
+CSSOM.CSSFontFaceRule = function CSSFontFaceRule() {
+	CSSOM.CSSRule.call(this);
+	this.style = new CSSOM.CSSStyleDeclaration();
+	this.style.parentRule = this;
+};
+
+CSSOM.CSSFontFaceRule.prototype = new CSSOM.CSSRule();
+CSSOM.CSSFontFaceRule.prototype.constructor = CSSOM.CSSFontFaceRule;
+CSSOM.CSSFontFaceRule.prototype.type = 5;
+//FIXME
+//CSSOM.CSSFontFaceRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule;
+//CSSOM.CSSFontFaceRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule;
+
+// http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSFontFaceRule.cpp
+Object.defineProperty(CSSOM.CSSFontFaceRule.prototype, "cssText", {
+  get: function() {
+    return "@font-face {" + this.style.cssText + "}";
+  }
+});
+
+
+//.CommonJS
+exports.CSSFontFaceRule = CSSOM.CSSFontFaceRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSHostRule.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSHostRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSHostRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,37 @@
+//.CommonJS
+var CSSOM = {
+	CSSRule: require("./CSSRule").CSSRule
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://www.w3.org/TR/shadow-dom/#host-at-rule
+ */
+CSSOM.CSSHostRule = function CSSHostRule() {
+	CSSOM.CSSRule.call(this);
+	this.cssRules = [];
+};
+
+CSSOM.CSSHostRule.prototype = new CSSOM.CSSRule();
+CSSOM.CSSHostRule.prototype.constructor = CSSOM.CSSHostRule;
+CSSOM.CSSHostRule.prototype.type = 1001;
+//FIXME
+//CSSOM.CSSHostRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule;
+//CSSOM.CSSHostRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule;
+
+Object.defineProperty(CSSOM.CSSHostRule.prototype, "cssText", {
+	get: function() {
+		var cssTexts = [];
+		for (var i=0, length=this.cssRules.length; i < length; i++) {
+			cssTexts.push(this.cssRules[i].cssText);
+		}
+		return "@host {" + cssTexts.join("") + "}";
+	}
+});
+
+
+//.CommonJS
+exports.CSSHostRule = CSSOM.CSSHostRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSImportRule.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSImportRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSImportRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,132 @@
+//.CommonJS
+var CSSOM = {
+	CSSRule: require("./CSSRule").CSSRule,
+	CSSStyleSheet: require("./CSSStyleSheet").CSSStyleSheet,
+	MediaList: require("./MediaList").MediaList
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://dev.w3.org/csswg/cssom/#cssimportrule
+ * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSImportRule
+ */
+CSSOM.CSSImportRule = function CSSImportRule() {
+	CSSOM.CSSRule.call(this);
+	this.href = "";
+	this.media = new CSSOM.MediaList();
+	this.styleSheet = new CSSOM.CSSStyleSheet();
+};
+
+CSSOM.CSSImportRule.prototype = new CSSOM.CSSRule();
+CSSOM.CSSImportRule.prototype.constructor = CSSOM.CSSImportRule;
+CSSOM.CSSImportRule.prototype.type = 3;
+
+Object.defineProperty(CSSOM.CSSImportRule.prototype, "cssText", {
+  get: function() {
+    var mediaText = this.media.mediaText;
+    return "@import url(" + this.href + ")" + (mediaText ? " " + mediaText : "") + ";";
+  },
+  set: function(cssText) {
+    var i = 0;
+
+    /**
+     * @import url(partial.css) screen, handheld;
+     *        ||               |
+     *        after-import     media
+     *         |
+     *         url
+     */
+    var state = '';
+
+    var buffer = '';
+    var index;
+    for (var character; (character = cssText.charAt(i)); i++) {
+
+      switch (character) {
+        case ' ':
+        case '\t':
+        case '\r':
+        case '\n':
+        case '\f':
+          if (state === 'after-import') {
+            state = 'url';
+          } else {
+            buffer += character;
+          }
+          break;
+
+        case '@':
+          if (!state && cssText.indexOf('@import', i) === i) {
+            state = 'after-import';
+            i += 'import'.length;
+            buffer = '';
+          }
+          break;
+
+        case 'u':
+          if (state === 'url' && cssText.indexOf('url(', i) === i) {
+            index = cssText.indexOf(')', i + 1);
+            if (index === -1) {
+              throw i + ': ")" not found';
+            }
+            i += 'url('.length;
+            var url = cssText.slice(i, index);
+            if (url[0] === url[url.length - 1]) {
+              if (url[0] === '"' || url[0] === "'") {
+                url = url.slice(1, -1);
+              }
+            }
+            this.href = url;
+            i = index;
+            state = 'media';
+          }
+          break;
+
+        case '"':
+          if (state === 'url') {
+            index = cssText.indexOf('"', i + 1);
+            if (!index) {
+              throw i + ": '\"' not found";
+            }
+            this.href = cssText.slice(i + 1, index);
+            i = index;
+            state = 'media';
+          }
+          break;
+
+        case "'":
+          if (state === 'url') {
+            index = cssText.indexOf("'", i + 1);
+            if (!index) {
+              throw i + ': "\'" not found';
+            }
+            this.href = cssText.slice(i + 1, index);
+            i = index;
+            state = 'media';
+          }
+          break;
+
+        case ';':
+          if (state === 'media') {
+            if (buffer) {
+              this.media.mediaText = buffer.trim();
+            }
+          }
+          break;
+
+        default:
+          if (state === 'media') {
+            buffer += character;
+          }
+          break;
+      }
+    }
+  }
+});
+
+
+//.CommonJS
+exports.CSSImportRule = CSSOM.CSSImportRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSKeyframeRule.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSKeyframeRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSKeyframeRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,37 @@
+//.CommonJS
+var CSSOM = {
+	CSSRule: require("./CSSRule").CSSRule,
+	CSSStyleDeclaration: require('./CSSStyleDeclaration').CSSStyleDeclaration
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://www.w3.org/TR/css3-animations/#DOM-CSSKeyframeRule
+ */
+CSSOM.CSSKeyframeRule = function CSSKeyframeRule() {
+	CSSOM.CSSRule.call(this);
+	this.keyText = '';
+	this.style = new CSSOM.CSSStyleDeclaration();
+	this.style.parentRule = this;
+};
+
+CSSOM.CSSKeyframeRule.prototype = new CSSOM.CSSRule();
+CSSOM.CSSKeyframeRule.prototype.constructor = CSSOM.CSSKeyframeRule;
+CSSOM.CSSKeyframeRule.prototype.type = 9;
+//FIXME
+//CSSOM.CSSKeyframeRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule;
+//CSSOM.CSSKeyframeRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule;
+
+// http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSKeyframeRule.cpp
+Object.defineProperty(CSSOM.CSSKeyframeRule.prototype, "cssText", {
+  get: function() {
+    return this.keyText + " {" + this.style.cssText + "} ";
+  }
+});
+
+
+//.CommonJS
+exports.CSSKeyframeRule = CSSOM.CSSKeyframeRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSKeyframesRule.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSKeyframesRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSKeyframesRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,39 @@
+//.CommonJS
+var CSSOM = {
+	CSSRule: require("./CSSRule").CSSRule
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://www.w3.org/TR/css3-animations/#DOM-CSSKeyframesRule
+ */
+CSSOM.CSSKeyframesRule = function CSSKeyframesRule() {
+	CSSOM.CSSRule.call(this);
+	this.name = '';
+	this.cssRules = [];
+};
+
+CSSOM.CSSKeyframesRule.prototype = new CSSOM.CSSRule();
+CSSOM.CSSKeyframesRule.prototype.constructor = CSSOM.CSSKeyframesRule;
+CSSOM.CSSKeyframesRule.prototype.type = 8;
+//FIXME
+//CSSOM.CSSKeyframesRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule;
+//CSSOM.CSSKeyframesRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule;
+
+// http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSKeyframesRule.cpp
+Object.defineProperty(CSSOM.CSSKeyframesRule.prototype, "cssText", {
+  get: function() {
+    var cssTexts = [];
+    for (var i=0, length=this.cssRules.length; i < length; i++) {
+      cssTexts.push("  " + this.cssRules[i].cssText);
+    }
+    return "@" + (this._vendorPrefix || '') + "keyframes " + this.name + " { \n" + cssTexts.join("\n") + "\n}";
+  }
+});
+
+
+//.CommonJS
+exports.CSSKeyframesRule = CSSOM.CSSKeyframesRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSMediaRule.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSMediaRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSMediaRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,41 @@
+//.CommonJS
+var CSSOM = {
+	CSSRule: require("./CSSRule").CSSRule,
+	MediaList: require("./MediaList").MediaList
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://dev.w3.org/csswg/cssom/#cssmediarule
+ * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSMediaRule
+ */
+CSSOM.CSSMediaRule = function CSSMediaRule() {
+	CSSOM.CSSRule.call(this);
+	this.media = new CSSOM.MediaList();
+	this.cssRules = [];
+};
+
+CSSOM.CSSMediaRule.prototype = new CSSOM.CSSRule();
+CSSOM.CSSMediaRule.prototype.constructor = CSSOM.CSSMediaRule;
+CSSOM.CSSMediaRule.prototype.type = 4;
+//FIXME
+//CSSOM.CSSMediaRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule;
+//CSSOM.CSSMediaRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule;
+
+// http://opensource.apple.com/source/WebCore/WebCore-658.28/css/CSSMediaRule.cpp
+Object.defineProperty(CSSOM.CSSMediaRule.prototype, "cssText", {
+  get: function() {
+    var cssTexts = [];
+    for (var i=0, length=this.cssRules.length; i < length; i++) {
+      cssTexts.push(this.cssRules[i].cssText);
+    }
+    return "@media " + this.media.mediaText + " {" + cssTexts.join("") + "}";
+  }
+});
+
+
+//.CommonJS
+exports.CSSMediaRule = CSSOM.CSSMediaRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSOM.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSOM.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSOM.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,3 @@
+var CSSOM = {};
+
+
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSRule.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+//.CommonJS
+var CSSOM = {};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://dev.w3.org/csswg/cssom/#the-cssrule-interface
+ * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSRule
+ */
+CSSOM.CSSRule = function CSSRule() {
+	this.parentRule = null;
+	this.parentStyleSheet = null;
+};
+
+CSSOM.CSSRule.UNKNOWN_RULE = 0;                 // obsolete
+CSSOM.CSSRule.STYLE_RULE = 1;
+CSSOM.CSSRule.CHARSET_RULE = 2;                 // obsolete
+CSSOM.CSSRule.IMPORT_RULE = 3;
+CSSOM.CSSRule.MEDIA_RULE = 4;
+CSSOM.CSSRule.FONT_FACE_RULE = 5;
+CSSOM.CSSRule.PAGE_RULE = 6;
+CSSOM.CSSRule.KEYFRAMES_RULE = 7;
+CSSOM.CSSRule.KEYFRAME_RULE = 8;
+CSSOM.CSSRule.MARGIN_RULE = 9;
+CSSOM.CSSRule.NAMESPACE_RULE = 10;
+CSSOM.CSSRule.COUNTER_STYLE_RULE = 11;
+CSSOM.CSSRule.SUPPORTS_RULE = 12;
+CSSOM.CSSRule.DOCUMENT_RULE = 13;
+CSSOM.CSSRule.FONT_FEATURE_VALUES_RULE = 14;
+CSSOM.CSSRule.VIEWPORT_RULE = 15;
+CSSOM.CSSRule.REGION_STYLE_RULE = 16;
+
+
+CSSOM.CSSRule.prototype = {
+	constructor: CSSOM.CSSRule
+	//FIXME
+};
+
+
+//.CommonJS
+exports.CSSRule = CSSOM.CSSRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSStyleDeclaration.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSStyleDeclaration.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSStyleDeclaration.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,148 @@
+//.CommonJS
+var CSSOM = {};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
+ */
+CSSOM.CSSStyleDeclaration = function CSSStyleDeclaration(){
+	this.length = 0;
+	this.parentRule = null;
+
+	// NON-STANDARD
+	this._importants = {};
+};
+
+
+CSSOM.CSSStyleDeclaration.prototype = {
+
+	constructor: CSSOM.CSSStyleDeclaration,
+
+	/**
+	 *
+	 * @param {string} name
+	 * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-getPropertyValue
+	 * @return {string} the value of the property if it has been explicitly set for this declaration block.
+	 * Returns the empty string if the property has not been set.
+	 */
+	getPropertyValue: function(name) {
+		return this[name] || "";
+	},
+
+	/**
+	 *
+	 * @param {string} name
+	 * @param {string} value
+	 * @param {string} [priority=null] "important" or null
+	 * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-setProperty
+	 */
+	setProperty: function(name, value, priority) {
+		if (this[name]) {
+			// Property already exist. Overwrite it.
+			var index = Array.prototype.indexOf.call(this, name);
+			if (index < 0) {
+				this[this.length] = name;
+				this.length++;
+			}
+		} else {
+			// New property.
+			this[this.length] = name;
+			this.length++;
+		}
+		this[name] = value + "";
+		this._importants[name] = priority;
+	},
+
+	/**
+	 *
+	 * @param {string} name
+	 * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-removeProperty
+	 * @return {string} the value of the property if it has been explicitly set for this declaration block.
+	 * Returns the empty string if the property has not been set or the property name does not correspond to a known CSS property.
+	 */
+	removeProperty: function(name) {
+		if (!(name in this)) {
+			return "";
+		}
+		var index = Array.prototype.indexOf.call(this, name);
+		if (index < 0) {
+			return "";
+		}
+		var prevValue = this[name];
+		this[name] = "";
+
+		// That's what WebKit and Opera do
+		Array.prototype.splice.call(this, index, 1);
+
+		// That's what Firefox does
+		//this[index] = ""
+
+		return prevValue;
+	},
+
+	getPropertyCSSValue: function() {
+		//FIXME
+	},
+
+	/**
+	 *
+	 * @param {String} name
+	 */
+	getPropertyPriority: function(name) {
+		return this._importants[name] || "";
+	},
+
+
+	/**
+	 *   element.style.overflow = "auto"
+	 *   element.style.getPropertyShorthand("overflow-x")
+	 *   -> "overflow"
+	 */
+	getPropertyShorthand: function() {
+		//FIXME
+	},
+
+	isPropertyImplicit: function() {
+		//FIXME
+	},
+
+	// Doesn't work in IE < 9
+	get cssText(){
+		var properties = [];
+		for (var i=0, length=this.length; i < length; ++i) {
+			var name = this[i];
+			var value = this.getPropertyValue(name);
+			var priority = this.getPropertyPriority(name);
+			if (priority) {
+				priority = " !" + priority;
+			}
+			properties[i] = name + ": " + value + priority + ";";
+		}
+		return properties.join(" ");
+	},
+
+	set cssText(text){
+		var i, name;
+		for (i = this.length; i--;) {
+			name = this[i];
+			this[name] = "";
+		}
+		Array.prototype.splice.call(this, 0, this.length);
+		this._importants = {};
+
+		var dummyRule = CSSOM.parse('#bogus{' + text + '}').cssRules[0].style;
+		var length = dummyRule.length;
+		for (i = 0; i < length; ++i) {
+			name = dummyRule[i];
+			this.setProperty(dummyRule[i], dummyRule.getPropertyValue(name), dummyRule.getPropertyPriority(name));
+		}
+	}
+};
+
+
+//.CommonJS
+exports.CSSStyleDeclaration = CSSOM.CSSStyleDeclaration;
+CSSOM.parse = require('./parse').parse; // Cannot be included sooner due to the mutual dependency between parse.js and CSSStyleDeclaration.js
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSStyleRule.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSStyleRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSStyleRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,190 @@
+//.CommonJS
+var CSSOM = {
+	CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration,
+	CSSRule: require("./CSSRule").CSSRule
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://dev.w3.org/csswg/cssom/#cssstylerule
+ * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleRule
+ */
+CSSOM.CSSStyleRule = function CSSStyleRule() {
+	CSSOM.CSSRule.call(this);
+	this.selectorText = "";
+	this.style = new CSSOM.CSSStyleDeclaration();
+	this.style.parentRule = this;
+};
+
+CSSOM.CSSStyleRule.prototype = new CSSOM.CSSRule();
+CSSOM.CSSStyleRule.prototype.constructor = CSSOM.CSSStyleRule;
+CSSOM.CSSStyleRule.prototype.type = 1;
+
+Object.defineProperty(CSSOM.CSSStyleRule.prototype, "cssText", {
+	get: function() {
+		var text;
+		if (this.selectorText) {
+			text = this.selectorText + " {" + this.style.cssText + "}";
+		} else {
+			text = "";
+		}
+		return text;
+	},
+	set: function(cssText) {
+		var rule = CSSOM.CSSStyleRule.parse(cssText);
+		this.style = rule.style;
+		this.selectorText = rule.selectorText;
+	}
+});
+
+
+/**
+ * NON-STANDARD
+ * lightweight version of parse.js.
+ * @param {string} ruleText
+ * @return CSSStyleRule
+ */
+CSSOM.CSSStyleRule.parse = function(ruleText) {
+	var i = 0;
+	var state = "selector";
+	var index;
+	var j = i;
+	var buffer = "";
+
+	var SIGNIFICANT_WHITESPACE = {
+		"selector": true,
+		"value": true
+	};
+
+	var styleRule = new CSSOM.CSSStyleRule();
+	var name, priority="";
+
+	for (var character; (character = ruleText.charAt(i)); i++) {
+
+		switch (character) {
+
+		case " ":
+		case "\t":
+		case "\r":
+		case "\n":
+		case "\f":
+			if (SIGNIFICANT_WHITESPACE[state]) {
+				// Squash 2 or more white-spaces in the row into 1
+				switch (ruleText.charAt(i - 1)) {
+					case " ":
+					case "\t":
+					case "\r":
+					case "\n":
+					case "\f":
+						break;
+					default:
+						buffer += " ";
+						break;
+				}
+			}
+			break;
+
+		// String
+		case '"':
+			j = i + 1;
+			index = ruleText.indexOf('"', j) + 1;
+			if (!index) {
+				throw '" is missing';
+			}
+			buffer += ruleText.slice(i, index);
+			i = index - 1;
+			break;
+
+		case "'":
+			j = i + 1;
+			index = ruleText.indexOf("'", j) + 1;
+			if (!index) {
+				throw "' is missing";
+			}
+			buffer += ruleText.slice(i, index);
+			i = index - 1;
+			break;
+
+		// Comment
+		case "/":
+			if (ruleText.charAt(i + 1) === "*") {
+				i += 2;
+				index = ruleText.indexOf("*/", i);
+				if (index === -1) {
+					throw new SyntaxError("Missing */");
+				} else {
+					i = index + 1;
+				}
+			} else {
+				buffer += character;
+			}
+			break;
+
+		case "{":
+			if (state === "selector") {
+				styleRule.selectorText = buffer.trim();
+				buffer = "";
+				state = "name";
+			}
+			break;
+
+		case ":":
+			if (state === "name") {
+				name = buffer.trim();
+				buffer = "";
+				state = "value";
+			} else {
+				buffer += character;
+			}
+			break;
+
+		case "!":
+			if (state === "value" && ruleText.indexOf("!important", i) === i) {
+				priority = "important";
+				i += "important".length;
+			} else {
+				buffer += character;
+			}
+			break;
+
+		case ";":
+			if (state === "value") {
+				styleRule.style.setProperty(name, buffer.trim(), priority);
+				priority = "";
+				buffer = "";
+				state = "name";
+			} else {
+				buffer += character;
+			}
+			break;
+
+		case "}":
+			if (state === "value") {
+				styleRule.style.setProperty(name, buffer.trim(), priority);
+				priority = "";
+				buffer = "";
+			} else if (state === "name") {
+				break;
+			} else {
+				buffer += character;
+			}
+			state = "selector";
+			break;
+
+		default:
+			buffer += character;
+			break;
+
+		}
+	}
+
+	return styleRule;
+
+};
+
+
+//.CommonJS
+exports.CSSStyleRule = CSSOM.CSSStyleRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSStyleSheet.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSStyleSheet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSStyleSheet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,88 @@
+//.CommonJS
+var CSSOM = {
+	StyleSheet: require("./StyleSheet").StyleSheet,
+	CSSStyleRule: require("./CSSStyleRule").CSSStyleRule
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleSheet
+ */
+CSSOM.CSSStyleSheet = function CSSStyleSheet() {
+	CSSOM.StyleSheet.call(this);
+	this.cssRules = [];
+};
+
+
+CSSOM.CSSStyleSheet.prototype = new CSSOM.StyleSheet();
+CSSOM.CSSStyleSheet.prototype.constructor = CSSOM.CSSStyleSheet;
+
+
+/**
+ * Used to insert a new rule into the style sheet. The new rule now becomes part of the cascade.
+ *
+ *   sheet = new Sheet("body {margin: 0}")
+ *   sheet.toString()
+ *   -> "body{margin:0;}"
+ *   sheet.insertRule("img {border: none}", 0)
+ *   -> 0
+ *   sheet.toString()
+ *   -> "img{border:none;}body{margin:0;}"
+ *
+ * @param {string} rule
+ * @param {number} index
+ * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleSheet-insertRule
+ * @return {number} The index within the style sheet's rule collection of the newly inserted rule.
+ */
+CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) {
+	if (index < 0 || index > this.cssRules.length) {
+		throw new RangeError("INDEX_SIZE_ERR");
+	}
+	var cssRule = CSSOM.parse(rule).cssRules[0];
+	cssRule.parentStyleSheet = this;
+	this.cssRules.splice(index, 0, cssRule);
+	return index;
+};
+
+
+/**
+ * Used to delete a rule from the style sheet.
+ *
+ *   sheet = new Sheet("img{border:none} body{margin:0}")
+ *   sheet.toString()
+ *   -> "img{border:none;}body{margin:0;}"
+ *   sheet.deleteRule(0)
+ *   sheet.toString()
+ *   -> "body{margin:0;}"
+ *
+ * @param {number} index within the style sheet's rule list of the rule to remove.
+ * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleSheet-deleteRule
+ */
+CSSOM.CSSStyleSheet.prototype.deleteRule = function(index) {
+	if (index < 0 || index >= this.cssRules.length) {
+		throw new RangeError("INDEX_SIZE_ERR");
+	}
+	this.cssRules.splice(index, 1);
+};
+
+
+/**
+ * NON-STANDARD
+ * @return {string} serialize stylesheet
+ */
+CSSOM.CSSStyleSheet.prototype.toString = function() {
+	var result = "";
+	var rules = this.cssRules;
+	for (var i=0; i<rules.length; i++) {
+		result += rules[i].cssText + "\n";
+	}
+	return result;
+};
+
+
+//.CommonJS
+exports.CSSStyleSheet = CSSOM.CSSStyleSheet;
+CSSOM.parse = require('./parse').parse; // Cannot be included sooner due to the mutual dependency between parse.js and CSSStyleSheet.js
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSSupportsRule.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSSupportsRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSSupportsRule.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,36 @@
+//.CommonJS
+var CSSOM = {
+  CSSRule: require("./CSSRule").CSSRule,
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see https://drafts.csswg.org/css-conditional-3/#the-csssupportsrule-interface
+ */
+CSSOM.CSSSupportsRule = function CSSSupportsRule() {
+  CSSOM.CSSRule.call(this);
+  this.conditionText = '';
+  this.cssRules = [];
+};
+
+CSSOM.CSSSupportsRule.prototype = new CSSOM.CSSRule();
+CSSOM.CSSSupportsRule.prototype.constructor = CSSOM.CSSSupportsRule;
+CSSOM.CSSSupportsRule.prototype.type = 12;
+
+Object.defineProperty(CSSOM.CSSSupportsRule.prototype, "cssText", {
+  get: function() {
+    var cssTexts = [];
+
+    for (var i = 0, length = this.cssRules.length; i < length; i++) {
+      cssTexts.push(this.cssRules[i].cssText);
+    }
+
+    return "@supports " + this.conditionText + " {" + cssTexts.join("") + "}";
+  }
+});
+
+//.CommonJS
+exports.CSSSupportsRule = CSSOM.CSSSupportsRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSValue.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSValue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSValue.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,43 @@
+//.CommonJS
+var CSSOM = {};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSValue
+ *
+ * TODO: add if needed
+ */
+CSSOM.CSSValue = function CSSValue() {
+};
+
+CSSOM.CSSValue.prototype = {
+	constructor: CSSOM.CSSValue,
+
+	// @see: http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSValue
+	set cssText(text) {
+		var name = this._getConstructorName();
+
+		throw new Error('DOMException: property "cssText" of "' + name + '" is readonly and can not be replaced with "' + text + '"!');
+	},
+
+	get cssText() {
+		var name = this._getConstructorName();
+
+		throw new Error('getter "cssText" of "' + name + '" is not implemented!');
+	},
+
+	_getConstructorName: function() {
+		var s = this.constructor.toString(),
+				c = s.match(/function\s([^\(]+)/),
+				name = c[1];
+
+		return name;
+	}
+};
+
+
+//.CommonJS
+exports.CSSValue = CSSOM.CSSValue;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSValueExpression.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSValueExpression.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/CSSValueExpression.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,344 @@
+//.CommonJS
+var CSSOM = {
+	CSSValue: require('./CSSValue').CSSValue
+};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://msdn.microsoft.com/en-us/library/ms537634(v=vs.85).aspx
+ *
+ */
+CSSOM.CSSValueExpression = function CSSValueExpression(token, idx) {
+	this._token = token;
+	this._idx = idx;
+};
+
+CSSOM.CSSValueExpression.prototype = new CSSOM.CSSValue();
+CSSOM.CSSValueExpression.prototype.constructor = CSSOM.CSSValueExpression;
+
+/**
+ * parse css expression() value
+ *
+ * @return {Object}
+ *         - error:
+ *         or
+ *         - idx:
+ *         - expression:
+ *
+ * Example:
+ *
+ * .selector {
+ *		zoom: expression(documentElement.clientWidth > 1000 ? '1000px' : 'auto');
+ * }
+ */
+CSSOM.CSSValueExpression.prototype.parse = function() {
+	var token = this._token,
+			idx = this._idx;
+
+	var character = '',
+			expression = '',
+			error = '',
+			info,
+			paren = [];
+
+
+	for (; ; ++idx) {
+		character = token.charAt(idx);
+
+		// end of token
+		if (character === '') {
+			error = 'css expression error: unfinished expression!';
+			break;
+		}
+
+		switch(character) {
+			case '(':
+				paren.push(character);
+				expression += character;
+				break;
+
+			case ')':
+				paren.pop(character);
+				expression += character;
+				break;
+
+			case '/':
+				if ((info = this._parseJSComment(token, idx))) { // comment?
+					if (info.error) {
+						error = 'css expression error: unfinished comment in expression!';
+					} else {
+						idx = info.idx;
+						// ignore the comment
+					}
+				} else if ((info = this._parseJSRexExp(token, idx))) { // regexp
+					idx = info.idx;
+					expression += info.text;
+				} else { // other
+					expression += character;
+				}
+				break;
+
+			case "'":
+			case '"':
+				info = this._parseJSString(token, idx, character);
+				if (info) { // string
+					idx = info.idx;
+					expression += info.text;
+				} else {
+					expression += character;
+				}
+				break;
+
+			default:
+				expression += character;
+				break;
+		}
+
+		if (error) {
+			break;
+		}
+
+		// end of expression
+		if (paren.length === 0) {
+			break;
+		}
+	}
+
+	var ret;
+	if (error) {
+		ret = {
+			error: error
+		};
+	} else {
+		ret = {
+			idx: idx,
+			expression: expression
+		};
+	}
+
+	return ret;
+};
+
+
+/**
+ *
+ * @return {Object|false}
+ *          - idx:
+ *          - text:
+ *          or
+ *          - error:
+ *          or
+ *          false
+ *
+ */
+CSSOM.CSSValueExpression.prototype._parseJSComment = function(token, idx) {
+	var nextChar = token.charAt(idx + 1),
+			text;
+
+	if (nextChar === '/' || nextChar === '*') {
+		var startIdx = idx,
+				endIdx,
+				commentEndChar;
+
+		if (nextChar === '/') { // line comment
+			commentEndChar = '\n';
+		} else if (nextChar === '*') { // block comment
+			commentEndChar = '*/';
+		}
+
+		endIdx = token.indexOf(commentEndChar, startIdx + 1 + 1);
+		if (endIdx !== -1) {
+			endIdx = endIdx + commentEndChar.length - 1;
+			text = token.substring(idx, endIdx + 1);
+			return {
+				idx: endIdx,
+				text: text
+			};
+		} else {
+			var error = 'css expression error: unfinished comment in expression!';
+			return {
+				error: error
+			};
+		}
+	} else {
+		return false;
+	}
+};
+
+
+/**
+ *
+ * @return {Object|false}
+ *					- idx:
+ *					- text:
+ *					or 
+ *					false
+ *
+ */
+CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep) {
+	var endIdx = this._findMatchedIdx(token, idx, sep),
+			text;
+
+	if (endIdx === -1) {
+		return false;
+	} else {
+		text = token.substring(idx, endIdx + sep.length);
+
+		return {
+			idx: endIdx,
+			text: text
+		};
+	}
+};
+
+
+/**
+ * parse regexp in css expression
+ *
+ * @return {Object|false}
+ *				- idx:
+ *				- regExp:
+ *				or 
+ *				false
+ */
+
+/*
+
+all legal RegExp
+ 
+/a/
+(/a/)
+[/a/]
+[12, /a/]
+
+!/a/
+
++/a/
+-/a/
+* /a/
+/ /a/
+%/a/
+
+===/a/
+!==/a/
+==/a/
+!=/a/
+>/a/
+>=/a/
+</a/
+<=/a/
+
+&/a/
+|/a/
+^/a/
+~/a/
+<</a/
+>>/a/
+>>>/a/
+
+&&/a/
+||/a/
+?/a/
+=/a/
+,/a/
+
+		delete /a/
+				in /a/
+instanceof /a/
+				new /a/
+		typeof /a/
+			void /a/
+
+*/
+CSSOM.CSSValueExpression.prototype._parseJSRexExp = function(token, idx) {
+	var before = token.substring(0, idx).replace(/\s+$/, ""),
+			legalRegx = [
+				/^$/,
+				/\($/,
+				/\[$/,
+				/\!$/,
+				/\+$/,
+				/\-$/,
+				/\*$/,
+				/\/\s+/,
+				/\%$/,
+				/\=$/,
+				/\>$/,
+				/<$/,
+				/\&$/,
+				/\|$/,
+				/\^$/,
+				/\~$/,
+				/\?$/,
+				/\,$/,
+				/delete$/,
+				/in$/,
+				/instanceof$/,
+				/new$/,
+				/typeof$/,
+				/void$/
+			];
+
+	var isLegal = legalRegx.some(function(reg) {
+		return reg.test(before);
+	});
+
+	if (!isLegal) {
+		return false;
+	} else {
+		var sep = '/';
+
+		// same logic as string
+		return this._parseJSString(token, idx, sep);
+	}
+};
+
+
+/**
+ *
+ * find next sep(same line) index in `token`
+ *
+ * @return {Number}
+ *
+ */
+CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep) {
+	var startIdx = idx,
+			endIdx;
+
+	var NOT_FOUND = -1;
+
+	while(true) {
+		endIdx = token.indexOf(sep, startIdx + 1);
+
+		if (endIdx === -1) { // not found
+			endIdx = NOT_FOUND;
+			break;
+		} else {
+			var text = token.substring(idx + 1, endIdx),
+					matched = text.match(/\\+$/);
+			if (!matched || matched[0] % 2 === 0) { // not escaped
+				break;
+			} else {
+				startIdx = endIdx;
+			}
+		}
+	}
+
+	// boundary must be in the same line(js sting or regexp)
+	var nextNewLineIdx = token.indexOf('\n', idx + 1);
+	if (nextNewLineIdx < endIdx) {
+		endIdx = NOT_FOUND;
+	}
+
+
+	return endIdx;
+};
+
+
+
+
+//.CommonJS
+exports.CSSValueExpression = CSSOM.CSSValueExpression;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/MatcherList.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/MatcherList.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/MatcherList.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,62 @@
+//.CommonJS
+var CSSOM = {};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see https://developer.mozilla.org/en/CSS/@-moz-document
+ */
+CSSOM.MatcherList = function MatcherList(){
+    this.length = 0;
+};
+
+CSSOM.MatcherList.prototype = {
+
+    constructor: CSSOM.MatcherList,
+
+    /**
+     * @return {string}
+     */
+    get matcherText() {
+        return Array.prototype.join.call(this, ", ");
+    },
+
+    /**
+     * @param {string} value
+     */
+    set matcherText(value) {
+        // just a temporary solution, actually it may be wrong by just split the value with ',', because a url can include ','.
+        var values = value.split(",");
+        var length = this.length = values.length;
+        for (var i=0; i<length; i++) {
+            this[i] = values[i].trim();
+        }
+    },
+
+    /**
+     * @param {string} matcher
+     */
+    appendMatcher: function(matcher) {
+        if (Array.prototype.indexOf.call(this, matcher) === -1) {
+            this[this.length] = matcher;
+            this.length++;
+        }
+    },
+
+    /**
+     * @param {string} matcher
+     */
+    deleteMatcher: function(matcher) {
+        var index = Array.prototype.indexOf.call(this, matcher);
+        if (index !== -1) {
+            Array.prototype.splice.call(this, index, 1);
+        }
+    }
+
+};
+
+
+//.CommonJS
+exports.MatcherList = CSSOM.MatcherList;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/MediaList.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/MediaList.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/MediaList.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,61 @@
+//.CommonJS
+var CSSOM = {};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://dev.w3.org/csswg/cssom/#the-medialist-interface
+ */
+CSSOM.MediaList = function MediaList(){
+	this.length = 0;
+};
+
+CSSOM.MediaList.prototype = {
+
+	constructor: CSSOM.MediaList,
+
+	/**
+	 * @return {string}
+	 */
+	get mediaText() {
+		return Array.prototype.join.call(this, ", ");
+	},
+
+	/**
+	 * @param {string} value
+	 */
+	set mediaText(value) {
+		var values = value.split(",");
+		var length = this.length = values.length;
+		for (var i=0; i<length; i++) {
+			this[i] = values[i].trim();
+		}
+	},
+
+	/**
+	 * @param {string} medium
+	 */
+	appendMedium: function(medium) {
+		if (Array.prototype.indexOf.call(this, medium) === -1) {
+			this[this.length] = medium;
+			this.length++;
+		}
+	},
+
+	/**
+	 * @param {string} medium
+	 */
+	deleteMedium: function(medium) {
+		var index = Array.prototype.indexOf.call(this, medium);
+		if (index !== -1) {
+			Array.prototype.splice.call(this, index, 1);
+		}
+	}
+
+};
+
+
+//.CommonJS
+exports.MediaList = CSSOM.MediaList;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/StyleSheet.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/StyleSheet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/StyleSheet.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+//.CommonJS
+var CSSOM = {};
+///CommonJS
+
+
+/**
+ * @constructor
+ * @see http://dev.w3.org/csswg/cssom/#the-stylesheet-interface
+ */
+CSSOM.StyleSheet = function StyleSheet() {
+	this.parentStyleSheet = null;
+};
+
+
+//.CommonJS
+exports.StyleSheet = CSSOM.StyleSheet;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/clone.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/clone.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/clone.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,82 @@
+//.CommonJS
+var CSSOM = {
+	CSSStyleSheet: require("./CSSStyleSheet").CSSStyleSheet,
+	CSSStyleRule: require("./CSSStyleRule").CSSStyleRule,
+	CSSMediaRule: require("./CSSMediaRule").CSSMediaRule,
+	CSSSupportsRule: require("./CSSSupportsRule").CSSSupportsRule,
+	CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration,
+	CSSKeyframeRule: require('./CSSKeyframeRule').CSSKeyframeRule,
+	CSSKeyframesRule: require('./CSSKeyframesRule').CSSKeyframesRule
+};
+///CommonJS
+
+
+/**
+ * Produces a deep copy of stylesheet — the instance variables of stylesheet are copied recursively.
+ * @param {CSSStyleSheet|CSSOM.CSSStyleSheet} stylesheet
+ * @nosideeffects
+ * @return {CSSOM.CSSStyleSheet}
+ */
+CSSOM.clone = function clone(stylesheet) {
+
+	var cloned = new CSSOM.CSSStyleSheet();
+
+	var rules = stylesheet.cssRules;
+	if (!rules) {
+		return cloned;
+	}
+
+	var RULE_TYPES = {
+		1: CSSOM.CSSStyleRule,
+		4: CSSOM.CSSMediaRule,
+		//3: CSSOM.CSSImportRule,
+		//5: CSSOM.CSSFontFaceRule,
+		//6: CSSOM.CSSPageRule,
+		8: CSSOM.CSSKeyframesRule,
+		9: CSSOM.CSSKeyframeRule,
+		12: CSSOM.CSSSupportsRule
+	};
+
+	for (var i=0, rulesLength=rules.length; i < rulesLength; i++) {
+		var rule = rules[i];
+		var ruleClone = cloned.cssRules[i] = new RULE_TYPES[rule.type]();
+
+		var style = rule.style;
+		if (style) {
+			var styleClone = ruleClone.style = new CSSOM.CSSStyleDeclaration();
+			for (var j=0, styleLength=style.length; j < styleLength; j++) {
+				var name = styleClone[j] = style[j];
+				styleClone[name] = style[name];
+				styleClone._importants[name] = style.getPropertyPriority(name);
+			}
+			styleClone.length = style.length;
+		}
+
+		if (rule.hasOwnProperty('keyText')) {
+			ruleClone.keyText = rule.keyText;
+		}
+
+		if (rule.hasOwnProperty('selectorText')) {
+			ruleClone.selectorText = rule.selectorText;
+		}
+
+		if (rule.hasOwnProperty('mediaText')) {
+			ruleClone.mediaText = rule.mediaText;
+		}
+
+		if (rule.hasOwnProperty('conditionText')) {
+			ruleClone.conditionText = rule.conditionText;
+		}
+
+		if (rule.hasOwnProperty('cssRules')) {
+			ruleClone.cssRules = clone(rule).cssRules;
+		}
+	}
+
+	return cloned;
+
+};
+
+//.CommonJS
+exports.clone = CSSOM.clone;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/index.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,21 @@
+'use strict';
+
+exports.CSSStyleDeclaration = require('./CSSStyleDeclaration').CSSStyleDeclaration;
+exports.CSSRule = require('./CSSRule').CSSRule;
+exports.CSSStyleRule = require('./CSSStyleRule').CSSStyleRule;
+exports.MediaList = require('./MediaList').MediaList;
+exports.CSSMediaRule = require('./CSSMediaRule').CSSMediaRule;
+exports.CSSSupportsRule = require('./CSSSupportsRule').CSSSupportsRule;
+exports.CSSImportRule = require('./CSSImportRule').CSSImportRule;
+exports.CSSFontFaceRule = require('./CSSFontFaceRule').CSSFontFaceRule;
+exports.CSSHostRule = require('./CSSHostRule').CSSHostRule;
+exports.StyleSheet = require('./StyleSheet').StyleSheet;
+exports.CSSStyleSheet = require('./CSSStyleSheet').CSSStyleSheet;
+exports.CSSKeyframesRule = require('./CSSKeyframesRule').CSSKeyframesRule;
+exports.CSSKeyframeRule = require('./CSSKeyframeRule').CSSKeyframeRule;
+exports.MatcherList = require('./MatcherList').MatcherList;
+exports.CSSDocumentRule = require('./CSSDocumentRule').CSSDocumentRule;
+exports.CSSValue = require('./CSSValue').CSSValue;
+exports.CSSValueExpression = require('./CSSValueExpression').CSSValueExpression;
+exports.parse = require('./parse').parse;
+exports.clone = require('./clone').clone;
Index: frontend/node_modules/cssstyle/node_modules/cssom/lib/parse.js
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/lib/parse.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/lib/parse.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,464 @@
+//.CommonJS
+var CSSOM = {};
+///CommonJS
+
+
+/**
+ * @param {string} token
+ */
+CSSOM.parse = function parse(token) {
+
+	var i = 0;
+
+	/**
+		"before-selector" or
+		"selector" or
+		"atRule" or
+		"atBlock" or
+		"conditionBlock" or
+		"before-name" or
+		"name" or
+		"before-value" or
+		"value"
+	*/
+	var state = "before-selector";
+
+	var index;
+	var buffer = "";
+	var valueParenthesisDepth = 0;
+
+	var SIGNIFICANT_WHITESPACE = {
+		"selector": true,
+		"value": true,
+		"value-parenthesis": true,
+		"atRule": true,
+		"importRule-begin": true,
+		"importRule": true,
+		"atBlock": true,
+		"conditionBlock": true,
+		'documentRule-begin': true
+	};
+
+	var styleSheet = new CSSOM.CSSStyleSheet();
+
+	// @type CSSStyleSheet|CSSMediaRule|CSSSupportsRule|CSSFontFaceRule|CSSKeyframesRule|CSSDocumentRule
+	var currentScope = styleSheet;
+
+	// @type CSSMediaRule|CSSSupportsRule|CSSKeyframesRule|CSSDocumentRule
+	var parentRule;
+
+	var ancestorRules = [];
+	var hasAncestors = false;
+	var prevScope;
+
+	var name, priority="", styleRule, mediaRule, supportsRule, importRule, fontFaceRule, keyframesRule, documentRule, hostRule;
+
+	var atKeyframesRegExp = /@(-(?:\w+-)+)?keyframes/g;
+
+	var parseError = function(message) {
+		var lines = token.substring(0, i).split('\n');
+		var lineCount = lines.length;
+		var charCount = lines.pop().length + 1;
+		var error = new Error(message + ' (line ' + lineCount + ', char ' + charCount + ')');
+		error.line = lineCount;
+		/* jshint sub : true */
+		error['char'] = charCount;
+		error.styleSheet = styleSheet;
+		throw error;
+	};
+
+	for (var character; (character = token.charAt(i)); i++) {
+
+		switch (character) {
+
+		case " ":
+		case "\t":
+		case "\r":
+		case "\n":
+		case "\f":
+			if (SIGNIFICANT_WHITESPACE[state]) {
+				buffer += character;
+			}
+			break;
+
+		// String
+		case '"':
+			index = i + 1;
+			do {
+				index = token.indexOf('"', index) + 1;
+				if (!index) {
+					parseError('Unmatched "');
+				}
+			} while (token[index - 2] === '\\');
+			buffer += token.slice(i, index);
+			i = index - 1;
+			switch (state) {
+				case 'before-value':
+					state = 'value';
+					break;
+				case 'importRule-begin':
+					state = 'importRule';
+					break;
+			}
+			break;
+
+		case "'":
+			index = i + 1;
+			do {
+				index = token.indexOf("'", index) + 1;
+				if (!index) {
+					parseError("Unmatched '");
+				}
+			} while (token[index - 2] === '\\');
+			buffer += token.slice(i, index);
+			i = index - 1;
+			switch (state) {
+				case 'before-value':
+					state = 'value';
+					break;
+				case 'importRule-begin':
+					state = 'importRule';
+					break;
+			}
+			break;
+
+		// Comment
+		case "/":
+			if (token.charAt(i + 1) === "*") {
+				i += 2;
+				index = token.indexOf("*/", i);
+				if (index === -1) {
+					parseError("Missing */");
+				} else {
+					i = index + 1;
+				}
+			} else {
+				buffer += character;
+			}
+			if (state === "importRule-begin") {
+				buffer += " ";
+				state = "importRule";
+			}
+			break;
+
+		// At-rule
+		case "@":
+			if (token.indexOf("@-moz-document", i) === i) {
+				state = "documentRule-begin";
+				documentRule = new CSSOM.CSSDocumentRule();
+				documentRule.__starts = i;
+				i += "-moz-document".length;
+				buffer = "";
+				break;
+			} else if (token.indexOf("@media", i) === i) {
+				state = "atBlock";
+				mediaRule = new CSSOM.CSSMediaRule();
+				mediaRule.__starts = i;
+				i += "media".length;
+				buffer = "";
+				break;
+			} else if (token.indexOf("@supports", i) === i) {
+				state = "conditionBlock";
+				supportsRule = new CSSOM.CSSSupportsRule();
+				supportsRule.__starts = i;
+				i += "supports".length;
+				buffer = "";
+				break;
+			} else if (token.indexOf("@host", i) === i) {
+				state = "hostRule-begin";
+				i += "host".length;
+				hostRule = new CSSOM.CSSHostRule();
+				hostRule.__starts = i;
+				buffer = "";
+				break;
+			} else if (token.indexOf("@import", i) === i) {
+				state = "importRule-begin";
+				i += "import".length;
+				buffer += "@import";
+				break;
+			} else if (token.indexOf("@font-face", i) === i) {
+				state = "fontFaceRule-begin";
+				i += "font-face".length;
+				fontFaceRule = new CSSOM.CSSFontFaceRule();
+				fontFaceRule.__starts = i;
+				buffer = "";
+				break;
+			} else {
+				atKeyframesRegExp.lastIndex = i;
+				var matchKeyframes = atKeyframesRegExp.exec(token);
+				if (matchKeyframes && matchKeyframes.index === i) {
+					state = "keyframesRule-begin";
+					keyframesRule = new CSSOM.CSSKeyframesRule();
+					keyframesRule.__starts = i;
+					keyframesRule._vendorPrefix = matchKeyframes[1]; // Will come out as undefined if no prefix was found
+					i += matchKeyframes[0].length - 1;
+					buffer = "";
+					break;
+				} else if (state === "selector") {
+					state = "atRule";
+				}
+			}
+			buffer += character;
+			break;
+
+		case "{":
+			if (state === "selector" || state === "atRule") {
+				styleRule.selectorText = buffer.trim();
+				styleRule.style.__starts = i;
+				buffer = "";
+				state = "before-name";
+			} else if (state === "atBlock") {
+				mediaRule.media.mediaText = buffer.trim();
+
+				if (parentRule) {
+					ancestorRules.push(parentRule);
+				}
+
+				currentScope = parentRule = mediaRule;
+				mediaRule.parentStyleSheet = styleSheet;
+				buffer = "";
+				state = "before-selector";
+			} else if (state === "conditionBlock") {
+				supportsRule.conditionText = buffer.trim();
+
+				if (parentRule) {
+					ancestorRules.push(parentRule);
+				}
+
+				currentScope = parentRule = supportsRule;
+				supportsRule.parentStyleSheet = styleSheet;
+				buffer = "";
+				state = "before-selector";
+			} else if (state === "hostRule-begin") {
+				if (parentRule) {
+					ancestorRules.push(parentRule);
+				}
+
+				currentScope = parentRule = hostRule;
+				hostRule.parentStyleSheet = styleSheet;
+				buffer = "";
+				state = "before-selector";
+			} else if (state === "fontFaceRule-begin") {
+				if (parentRule) {
+					ancestorRules.push(parentRule);
+					fontFaceRule.parentRule = parentRule;
+				}
+				fontFaceRule.parentStyleSheet = styleSheet;
+				styleRule = fontFaceRule;
+				buffer = "";
+				state = "before-name";
+			} else if (state === "keyframesRule-begin") {
+				keyframesRule.name = buffer.trim();
+				if (parentRule) {
+					ancestorRules.push(parentRule);
+					keyframesRule.parentRule = parentRule;
+				}
+				keyframesRule.parentStyleSheet = styleSheet;
+				currentScope = parentRule = keyframesRule;
+				buffer = "";
+				state = "keyframeRule-begin";
+			} else if (state === "keyframeRule-begin") {
+				styleRule = new CSSOM.CSSKeyframeRule();
+				styleRule.keyText = buffer.trim();
+				styleRule.__starts = i;
+				buffer = "";
+				state = "before-name";
+			} else if (state === "documentRule-begin") {
+				// FIXME: what if this '{' is in the url text of the match function?
+				documentRule.matcher.matcherText = buffer.trim();
+				if (parentRule) {
+					ancestorRules.push(parentRule);
+					documentRule.parentRule = parentRule;
+				}
+				currentScope = parentRule = documentRule;
+				documentRule.parentStyleSheet = styleSheet;
+				buffer = "";
+				state = "before-selector";
+			}
+			break;
+
+		case ":":
+			if (state === "name") {
+				name = buffer.trim();
+				buffer = "";
+				state = "before-value";
+			} else {
+				buffer += character;
+			}
+			break;
+
+		case "(":
+			if (state === 'value') {
+				// ie css expression mode
+				if (buffer.trim() === 'expression') {
+					var info = (new CSSOM.CSSValueExpression(token, i)).parse();
+
+					if (info.error) {
+						parseError(info.error);
+					} else {
+						buffer += info.expression;
+						i = info.idx;
+					}
+				} else {
+					state = 'value-parenthesis';
+					//always ensure this is reset to 1 on transition
+					//from value to value-parenthesis
+					valueParenthesisDepth = 1;
+					buffer += character;
+				}
+			} else if (state === 'value-parenthesis') {
+				valueParenthesisDepth++;
+				buffer += character;
+			} else {
+				buffer += character;
+			}
+			break;
+
+		case ")":
+			if (state === 'value-parenthesis') {
+				valueParenthesisDepth--;
+				if (valueParenthesisDepth === 0) state = 'value';
+			}
+			buffer += character;
+			break;
+
+		case "!":
+			if (state === "value" && token.indexOf("!important", i) === i) {
+				priority = "important";
+				i += "important".length;
+			} else {
+				buffer += character;
+			}
+			break;
+
+		case ";":
+			switch (state) {
+				case "value":
+					styleRule.style.setProperty(name, buffer.trim(), priority);
+					priority = "";
+					buffer = "";
+					state = "before-name";
+					break;
+				case "atRule":
+					buffer = "";
+					state = "before-selector";
+					break;
+				case "importRule":
+					importRule = new CSSOM.CSSImportRule();
+					importRule.parentStyleSheet = importRule.styleSheet.parentStyleSheet = styleSheet;
+					importRule.cssText = buffer + character;
+					styleSheet.cssRules.push(importRule);
+					buffer = "";
+					state = "before-selector";
+					break;
+				default:
+					buffer += character;
+					break;
+			}
+			break;
+
+		case "}":
+			switch (state) {
+				case "value":
+					styleRule.style.setProperty(name, buffer.trim(), priority);
+					priority = "";
+					/* falls through */
+				case "before-name":
+				case "name":
+					styleRule.__ends = i + 1;
+					if (parentRule) {
+						styleRule.parentRule = parentRule;
+					}
+					styleRule.parentStyleSheet = styleSheet;
+					currentScope.cssRules.push(styleRule);
+					buffer = "";
+					if (currentScope.constructor === CSSOM.CSSKeyframesRule) {
+						state = "keyframeRule-begin";
+					} else {
+						state = "before-selector";
+					}
+					break;
+				case "keyframeRule-begin":
+				case "before-selector":
+				case "selector":
+					// End of media/supports/document rule.
+					if (!parentRule) {
+						parseError("Unexpected }");
+					}
+
+					// Handle rules nested in @media or @supports
+					hasAncestors = ancestorRules.length > 0;
+
+					while (ancestorRules.length > 0) {
+						parentRule = ancestorRules.pop();
+
+						if (
+							parentRule.constructor.name === "CSSMediaRule"
+							|| parentRule.constructor.name === "CSSSupportsRule"
+						) {
+							prevScope = currentScope;
+							currentScope = parentRule;
+							currentScope.cssRules.push(prevScope);
+							break;
+						}
+
+						if (ancestorRules.length === 0) {
+							hasAncestors = false;
+						}
+					}
+					
+					if (!hasAncestors) {
+						currentScope.__ends = i + 1;
+						styleSheet.cssRules.push(currentScope);
+						currentScope = styleSheet;
+						parentRule = null;
+					}
+
+					buffer = "";
+					state = "before-selector";
+					break;
+			}
+			break;
+
+		default:
+			switch (state) {
+				case "before-selector":
+					state = "selector";
+					styleRule = new CSSOM.CSSStyleRule();
+					styleRule.__starts = i;
+					break;
+				case "before-name":
+					state = "name";
+					break;
+				case "before-value":
+					state = "value";
+					break;
+				case "importRule-begin":
+					state = "importRule";
+					break;
+			}
+			buffer += character;
+			break;
+		}
+	}
+
+	return styleSheet;
+};
+
+
+//.CommonJS
+exports.parse = CSSOM.parse;
+// The following modules cannot be included sooner due to the mutual dependency with parse.js
+CSSOM.CSSStyleSheet = require("./CSSStyleSheet").CSSStyleSheet;
+CSSOM.CSSStyleRule = require("./CSSStyleRule").CSSStyleRule;
+CSSOM.CSSImportRule = require("./CSSImportRule").CSSImportRule;
+CSSOM.CSSMediaRule = require("./CSSMediaRule").CSSMediaRule;
+CSSOM.CSSSupportsRule = require("./CSSSupportsRule").CSSSupportsRule;
+CSSOM.CSSFontFaceRule = require("./CSSFontFaceRule").CSSFontFaceRule;
+CSSOM.CSSHostRule = require("./CSSHostRule").CSSHostRule;
+CSSOM.CSSStyleDeclaration = require('./CSSStyleDeclaration').CSSStyleDeclaration;
+CSSOM.CSSKeyframeRule = require('./CSSKeyframeRule').CSSKeyframeRule;
+CSSOM.CSSKeyframesRule = require('./CSSKeyframesRule').CSSKeyframesRule;
+CSSOM.CSSValueExpression = require('./CSSValueExpression').CSSValueExpression;
+CSSOM.CSSDocumentRule = require('./CSSDocumentRule').CSSDocumentRule;
+///CommonJS
Index: frontend/node_modules/cssstyle/node_modules/cssom/package.json
===================================================================
--- frontend/node_modules/cssstyle/node_modules/cssom/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/node_modules/cssom/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,18 @@
+{
+  "name": "cssom",
+  "description": "CSS Object Model implementation and CSS parser",
+  "keywords": [
+    "CSS",
+    "CSSOM",
+    "parser",
+    "styleSheet"
+  ],
+  "version": "0.3.8",
+  "author": "Nikita Vasilyev <me@elv1s.ru>",
+  "repository": "NV/CSSOM",
+  "files": [
+    "lib/"
+  ],
+  "main": "./lib/index.js",
+  "license": "MIT"
+}
Index: frontend/node_modules/cssstyle/package.json
===================================================================
--- frontend/node_modules/cssstyle/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/cssstyle/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,72 @@
+{
+  "name": "cssstyle",
+  "description": "CSSStyleDeclaration Object Model implementation",
+  "keywords": [
+    "CSS",
+    "CSSStyleDeclaration",
+    "StyleSheet"
+  ],
+  "version": "2.3.0",
+  "homepage": "https://github.com/jsdom/cssstyle",
+  "maintainers": [
+    {
+      "name": "Jon Sakas",
+      "email": "jon.sakas@gmail.com",
+      "url": "https://jon.sakas.co/"
+    },
+    {
+      "name": "Rafał Ruciński",
+      "email": "fatfisz@gmail.com",
+      "url": "https://fatfisz.com"
+    }
+  ],
+  "contributors": [
+    {
+      "name": "Chad Walker",
+      "email": "chad@chad-cat-lore-eddie.com",
+      "url": "https://github.com/chad3814"
+    }
+  ],
+  "repository": "jsdom/cssstyle",
+  "bugs": "https://github.com/jsdom/cssstyle/issues",
+  "directories": {
+    "lib": "./lib"
+  },
+  "files": [
+    "lib/"
+  ],
+  "main": "./lib/CSSStyleDeclaration.js",
+  "dependencies": {
+    "cssom": "~0.3.6"
+  },
+  "devDependencies": {
+    "babel-generator": "~6.26.1",
+    "babel-traverse": "~6.26.0",
+    "babel-types": "~6.26.0",
+    "babylon": "~6.18.0",
+    "eslint": "~6.0.0",
+    "eslint-config-prettier": "~6.0.0",
+    "eslint-plugin-prettier": "~3.1.0",
+    "jest": "^24.8.0",
+    "npm-run-all": "^4.1.5",
+    "prettier": "~1.18.0",
+    "request": "^2.88.0",
+    "resolve": "~1.11.1"
+  },
+  "scripts": {
+    "download": "node ./scripts/download_latest_properties.js && eslint lib/allProperties.js --fix",
+    "generate": "run-p generate:*",
+    "generate:implemented_properties": "node ./scripts/generate_implemented_properties.js",
+    "generate:properties": "node ./scripts/generate_properties.js",
+    "lint": "npm run generate && eslint . --max-warnings 0",
+    "lint:fix": "eslint . --fix --max-warnings 0",
+    "prepublishOnly": "npm run lint && npm run test",
+    "test": "npm run generate && jest",
+    "test-ci": "npm run lint && npm run test && codecov",
+    "update-authors": "git log --format=\"%aN <%aE>\" | sort -f | uniq > AUTHORS"
+  },
+  "license": "MIT",
+  "engines": {
+    "node": ">=8"
+  }
+}
