From 18440158b37be12126eb0ff4ecc5b316fb0b26b7 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Sun, 26 Feb 2017 13:24:53 -0800 Subject: [PATCH] Add comparative performance benchmarks Includes a 'css-modules' implementation of the nested trees to act as a baseline for comparison. --- .gitignore | 7 +- package.json | 5 +- performance/README.md | 36 + performance/benchmark.js | 67 -- .../benchmarks/deepTree/createDeepTree.js | 96 -- performance/benchmarks/deepTree/index.js | 31 - .../implementations/css-modules/Box/index.js | 21 + .../css-modules/Box/styles.css | 36 + .../implementations/css-modules/View/index.js | 8 + .../css-modules/View/styles.css | 21 + .../implementations/css-modules/index.js | 7 + .../implementations/glamor/Box/index.js | 49 + .../implementations/glamor/View/index.js | 32 + performance/implementations/glamor/index.js | 7 + .../react-native-web/Box/index.js | 49 + .../react-native-web/Box/lite.js | 49 + .../react-native-web/View/index.js | 2 + .../react-native-web/View/lite.js | 32 + .../implementations/react-native-web/index.js | 7 + .../implementations/react-native-web/lite.js | 7 + .../styled-components/Box/index.js | 31 + .../styled-components/View/index.js | 25 + .../styled-components/index.js | 7 + performance/index.html | 2 +- performance/index.js | 38 +- performance/modules/NestedTree.js | 49 + performance/modules/benchmark.js | 93 ++ performance/modules/createRenderBenchmark.js | 20 + performance/package.json | 14 + performance/tests/renderDeepTree.js | 21 + performance/tests/renderWideTree.js | 21 + performance/webpack.config.js | 22 +- performance/yarn.lock | 970 ++++++++++++++++++ yarn.lock | 4 - 34 files changed, 1657 insertions(+), 229 deletions(-) create mode 100644 performance/README.md delete mode 100644 performance/benchmark.js delete mode 100644 performance/benchmarks/deepTree/createDeepTree.js delete mode 100644 performance/benchmarks/deepTree/index.js create mode 100644 performance/implementations/css-modules/Box/index.js create mode 100644 performance/implementations/css-modules/Box/styles.css create mode 100644 performance/implementations/css-modules/View/index.js create mode 100644 performance/implementations/css-modules/View/styles.css create mode 100644 performance/implementations/css-modules/index.js create mode 100644 performance/implementations/glamor/Box/index.js create mode 100644 performance/implementations/glamor/View/index.js create mode 100644 performance/implementations/glamor/index.js create mode 100644 performance/implementations/react-native-web/Box/index.js create mode 100644 performance/implementations/react-native-web/Box/lite.js create mode 100644 performance/implementations/react-native-web/View/index.js create mode 100644 performance/implementations/react-native-web/View/lite.js create mode 100644 performance/implementations/react-native-web/index.js create mode 100644 performance/implementations/react-native-web/lite.js create mode 100644 performance/implementations/styled-components/Box/index.js create mode 100644 performance/implementations/styled-components/View/index.js create mode 100644 performance/implementations/styled-components/index.js create mode 100644 performance/modules/NestedTree.js create mode 100644 performance/modules/benchmark.js create mode 100644 performance/modules/createRenderBenchmark.js create mode 100644 performance/package.json create mode 100644 performance/tests/renderDeepTree.js create mode 100644 performance/tests/renderWideTree.js create mode 100644 performance/yarn.lock diff --git a/.gitignore b/.gitignore index 0a7ae798..0c264cb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -/dist -/dist-examples -/dist-performance -/node_modules +node_modules +dist +dist-examples diff --git a/package.json b/package.json index 99136449..371989f3 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,11 @@ "scripts": { "build": "del ./dist && mkdir dist && babel src -d dist --ignore **/__tests__", "build:examples": "build-storybook -o dist-examples -c ./examples/.storybook", - "build:performance": "cd performance && webpack", + "build:performance": "cd performance && yarn && webpack", "build:umd": "webpack --config webpack.config.js --sort-assets-by --progress", "deploy:examples": "git checkout gh-pages && rm -rf ./storybook && mv dist-examples storybook && git add -A && git commit -m \"Storybook deploy\" && git push origin gh-pages && git checkout -", "examples": "start-storybook -p 9001 -c ./examples/.storybook --dont-track", - "lint": "eslint performance src", + "lint": "eslint performance src --ignore-path .gitignore", "prepublish": "npm run build && npm run build:umd", "test": "npm run lint && npm run test:jest", "test:jest": "jest", @@ -51,7 +51,6 @@ "eslint-plugin-react": "^6.1.2", "file-loader": "^0.9.0", "jest": "^16.0.2", - "marky": "^1.1.1", "node-libs-browser": "^0.5.3", "react": "~15.4.1", "react-addons-test-utils": "~15.4.1", diff --git a/performance/README.md b/performance/README.md new file mode 100644 index 00000000..4d39669a --- /dev/null +++ b/performance/README.md @@ -0,0 +1,36 @@ +# Performance + +To run these benchmarks: + +``` +npm run build:performance +open ./performance/index.html +``` + +## Notes + +The components used in the render benchmarks are simple enough to be +implemented by multiple styling libraries. The implementations are not +equivalent but are useful for framing the relative performance of +`react-native-web` against these tests. + +The implementations are not equivalent. For example, the `react-native-web` +implementation of `View` does more than just styling. The +`react-native-web/lite` variant implements a minimal `View` that allows for a +more direct comparison with the `css-modules` baseline. + +## Benchmark results + +Typical render timings*: mean / two standard deviations + +Version: 0.0.73 + +| Implementation | Deep tree (ms) | Wide tree (ms) | +| :--- | ---: | ---: | +| css-modules | `80.47` `±18.04` | `166.91` `±19.90` | +| react-native-web/lite | `87.91` `±13.37` | `181.45` `±20.06` | +| react-native-web | `113.45` `±09.27` | `237.33` `±38.77` | +| styled-components | `170.86` `±15.67` | `378.83` `±36.11` | +| glamor | `275.41` `±19.56` | `474.76` `±29.02` | + +*MacBook Pro (13-inch, Early 2011); 2.7 GHz Intel Core i7; 16 GB 1600 MHz DDR3. Google Chrome 56. diff --git a/performance/benchmark.js b/performance/benchmark.js deleted file mode 100644 index e21c4aab..00000000 --- a/performance/benchmark.js +++ /dev/null @@ -1,67 +0,0 @@ -import * as marky from 'marky'; - -const fmt = (time) => `${Math.round(time * 100) / 100}ms`; - -const measure = (name, fn) => { - marky.mark(name); - fn(); - const performanceMeasure = marky.stop(name); - return performanceMeasure.duration; -}; - -const benchmark = ({ name, description, setup, teardown, task, runs }) => { - return new Promise((resolve) => { - const durations = []; - let i = 0; - - console.group(`[benchmark] ${name}`); - console.log(description); - - setup(); - const first = measure('first', task); - teardown(); - - const done = () => { - const mean = durations.reduce((sum, duration) => { - return sum + duration; - }, 0) / runs; - - const firstDuration = fmt(first); - const meanDuration = fmt(mean); - - console.log(`First: ${firstDuration}`); - console.log(`Mean: ${meanDuration}`); - console.groupEnd(); - resolve(mean); - }; - - const a = () => { - setup(); - window.requestAnimationFrame(b); - }; - - const b = () => { - const duration = measure('mean', task); - durations.push(duration); - c(); - }; - - const c = () => { - teardown(); - window.requestAnimationFrame(d); - }; - - const d = () => { - i += 1; - if (i < runs) { - window.requestAnimationFrame(a); - } else { - window.requestAnimationFrame(done); - } - }; - - window.requestAnimationFrame(a); - }); -}; - -module.exports = benchmark; diff --git a/performance/benchmarks/deepTree/createDeepTree.js b/performance/benchmarks/deepTree/createDeepTree.js deleted file mode 100644 index a9e27886..00000000 --- a/performance/benchmarks/deepTree/createDeepTree.js +++ /dev/null @@ -1,96 +0,0 @@ -import React, { Component, PropTypes } from 'react'; - -/* eslint-disable */ -const base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg=='; -/* eslint-enable */ - -const createDeepTree = (implementation, options = {}) => { - const { Image, StyleSheet, View } = implementation; - const TerminalComponent = options.leafComponent ? implementation[options.leafComponent] : View; - - class DeepTree extends Component { - static propTypes = { - breadth: PropTypes.number.isRequired, - depth: PropTypes.number.isRequired, - id: PropTypes.number.isRequired, - wrap: PropTypes.number.isRequired - }; - - render() { - const { breadth, depth, id, wrap } = this.props; - - let result = ( - - {depth === 0 && ( - - )} - {depth !== 0 && Array.from({ length: breadth }).map((el, i) => ( - - ))} - - ); - for (let i = 0; i < wrap; i++) { - result = {result}; - } - return result; - } - } - - const stylesObject = { - outer: { - padding: 4 - }, - odd: { - flexDirection: 'row' - }, - even: { - flexDirection: 'column' - }, - custom0: { - backgroundColor: '#222' - }, - custom1: { - backgroundColor: '#666' - }, - custom2: { - backgroundColor: '#999' - }, - terminal: { - width: 20, - height: 20 - }, - terminal0: { - backgroundColor: 'blue' - }, - terminal1: { - backgroundColor: 'orange' - }, - terminal2: { - backgroundColor: 'red' - } - }; - - const styles = options.registerStyles ? StyleSheet.create(stylesObject) : stylesObject; - - return DeepTree; -}; - -module.exports = createDeepTree; diff --git a/performance/benchmarks/deepTree/index.js b/performance/benchmarks/deepTree/index.js deleted file mode 100644 index dcdc4199..00000000 --- a/performance/benchmarks/deepTree/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import benchmark from '../../benchmark'; -import createDeepTree from './createDeepTree'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import ReactNative from 'react-native'; - -const deepTreeBenchmark = (config, node) => () => { - const { breadth, depth, leafComponent = 'View', registerStyles = true, runs, wrap } = config; - - // React Native for Web implementation of the tree - const DeepTree = createDeepTree(ReactNative, { registerStyles }); - - const setup = () => {}; - const teardown = () => ReactDOM.unmountComponentAtNode(node); - - let name = `DeepTree: ${leafComponent}`; - if (!registerStyles) { - name += ' (unregistered styles)'; - } - - return benchmark({ - name, - description: `depth=${depth}, breadth=${breadth}, wrap=${wrap}`, - runs, - setup, - teardown, - task: () => ReactDOM.render(, node) - }); -}; - -module.exports = deepTreeBenchmark; diff --git a/performance/implementations/css-modules/Box/index.js b/performance/implementations/css-modules/Box/index.js new file mode 100644 index 00000000..d3f5001d --- /dev/null +++ b/performance/implementations/css-modules/Box/index.js @@ -0,0 +1,21 @@ +/* eslint-disable react/prop-types */ +import classnames from 'classnames'; +import React from 'react'; +import View from '../View'; +import styles from './styles.css'; + +const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => ( + +); + +module.exports = Box; diff --git a/performance/implementations/css-modules/Box/styles.css b/performance/implementations/css-modules/Box/styles.css new file mode 100644 index 00000000..d5605b7f --- /dev/null +++ b/performance/implementations/css-modules/Box/styles.css @@ -0,0 +1,36 @@ +.outer { + padding: 4px; +} + +.row { + flex-direction: row; +} + +.color0 { + background-color: #222; +} + +.color1 { + background-color: #666; +} + +.color2 { + background-color: #999; +} + +.color3 { + background-color: blue; +} + +.color4 { + background-color: orange; +} + +.color5 { + background-color: red; +} + +.fixed { + width: 20px; + height: 20px; +} diff --git a/performance/implementations/css-modules/View/index.js b/performance/implementations/css-modules/View/index.js new file mode 100644 index 00000000..2763c5a7 --- /dev/null +++ b/performance/implementations/css-modules/View/index.js @@ -0,0 +1,8 @@ +/* eslint-disable react/prop-types */ +import classnames from 'classnames'; +import React from 'react'; +import styles from './styles.css'; + +const View = (props) =>
; + +module.exports = View; diff --git a/performance/implementations/css-modules/View/styles.css b/performance/implementations/css-modules/View/styles.css new file mode 100644 index 00000000..74608166 --- /dev/null +++ b/performance/implementations/css-modules/View/styles.css @@ -0,0 +1,21 @@ +.initial { + align-items: stretch; + border-width: 0; + border-style: solid; + box-sizing: border-box; + display: flex; + flex-basis: auto; + flex-direction: column; + flex-shrink: 0; + margin: 0; + padding: 0; + position: relative; + background-color: transparent; + color: inherit; + font: inherit; + text-align: inherit; + text-decoration: none; + list-style: none; + min-height: 0; + min-width: 0; +}; diff --git a/performance/implementations/css-modules/index.js b/performance/implementations/css-modules/index.js new file mode 100644 index 00000000..0ca161ab --- /dev/null +++ b/performance/implementations/css-modules/index.js @@ -0,0 +1,7 @@ +import Box from './Box'; +import View from './View'; + +export default { + Box, + View +}; diff --git a/performance/implementations/glamor/Box/index.js b/performance/implementations/glamor/Box/index.js new file mode 100644 index 00000000..822c2ec4 --- /dev/null +++ b/performance/implementations/glamor/Box/index.js @@ -0,0 +1,49 @@ +/* eslint-disable react/prop-types */ +import { css } from 'glamor'; +import React from 'react'; +import View from '../View'; + +const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => ( + +); + +const styles = { + outer: css({ + padding: 4 + }), + row: css({ + flexDirection: 'row' + }), + color0: css({ + backgroundColor: '#222' + }), + color1: css({ + backgroundColor: '#666' + }), + color2: css({ + backgroundColor: '#999' + }), + color3: css({ + backgroundColor: 'blue' + }), + color4: css({ + backgroundColor: 'orange' + }), + color5: css({ + backgroundColor: 'red' + }), + fixed: css({ + width: 20, + height: 20 + }) +}; + +module.exports = Box; diff --git a/performance/implementations/glamor/View/index.js b/performance/implementations/glamor/View/index.js new file mode 100644 index 00000000..a8de5305 --- /dev/null +++ b/performance/implementations/glamor/View/index.js @@ -0,0 +1,32 @@ +/* eslint-disable react/prop-types */ +import { css } from 'glamor'; +import React from 'react'; + +const View = (props) =>
; + +const viewStyle = { + alignItems: 'stretch', + borderWidth: 0, + borderStyle: 'solid', + boxSizing: 'border-box', + display: 'flex', + flexBasis: 'auto', + flexDirection: 'column', + flexShrink: 0, + margin: 0, + padding: 0, + position: 'relative', + // button and anchor reset + backgroundColor: 'transparent', + color: 'inherit', + font: 'inherit', + textAlign: 'inherit', + textDecorationLine: 'none', + // list reset + listStyle: 'none', + // fix flexbox bugs + minHeight: 0, + minWidth: 0 +}; + +module.exports = View; diff --git a/performance/implementations/glamor/index.js b/performance/implementations/glamor/index.js new file mode 100644 index 00000000..0ca161ab --- /dev/null +++ b/performance/implementations/glamor/index.js @@ -0,0 +1,7 @@ +import Box from './Box'; +import View from './View'; + +export default { + Box, + View +}; diff --git a/performance/implementations/react-native-web/Box/index.js b/performance/implementations/react-native-web/Box/index.js new file mode 100644 index 00000000..34494109 --- /dev/null +++ b/performance/implementations/react-native-web/Box/index.js @@ -0,0 +1,49 @@ +/* eslint-disable react/prop-types */ +import React from 'react'; +import StyleSheet from 'react-native/apis/StyleSheet'; +import View from '../View'; + +const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => ( + +); + +const styles = StyleSheet.create({ + outer: { + padding: 4 + }, + row: { + flexDirection: 'row' + }, + color0: { + backgroundColor: '#222' + }, + color1: { + backgroundColor: '#666' + }, + color2: { + backgroundColor: '#999' + }, + color3: { + backgroundColor: 'blue' + }, + color4: { + backgroundColor: 'orange' + }, + color5: { + backgroundColor: 'red' + }, + fixed: { + width: 20, + height: 20 + } +}); + +module.exports = Box; diff --git a/performance/implementations/react-native-web/Box/lite.js b/performance/implementations/react-native-web/Box/lite.js new file mode 100644 index 00000000..47ad5e98 --- /dev/null +++ b/performance/implementations/react-native-web/Box/lite.js @@ -0,0 +1,49 @@ +/* eslint-disable react/prop-types */ +import React from 'react'; +import StyleSheet from 'react-native/apis/StyleSheet'; +import View from '../View/lite'; + +const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) => ( + +); + +const styles = StyleSheet.create({ + outer: { + padding: 4 + }, + row: { + flexDirection: 'row' + }, + color0: { + backgroundColor: '#222' + }, + color1: { + backgroundColor: '#666' + }, + color2: { + backgroundColor: '#999' + }, + color3: { + backgroundColor: 'blue' + }, + color4: { + backgroundColor: 'orange' + }, + color5: { + backgroundColor: 'red' + }, + fixed: { + width: 20, + height: 20 + } +}); + +module.exports = Box; diff --git a/performance/implementations/react-native-web/View/index.js b/performance/implementations/react-native-web/View/index.js new file mode 100644 index 00000000..a7c7f7dd --- /dev/null +++ b/performance/implementations/react-native-web/View/index.js @@ -0,0 +1,2 @@ +import View from 'react-native/components/View'; +export default View; diff --git a/performance/implementations/react-native-web/View/lite.js b/performance/implementations/react-native-web/View/lite.js new file mode 100644 index 00000000..6269fb63 --- /dev/null +++ b/performance/implementations/react-native-web/View/lite.js @@ -0,0 +1,32 @@ +import createDOMElement from 'react-native/modules/createDOMElement'; +import StyleSheet from 'react-native/apis/StyleSheet'; + +const View = (props) => createDOMElement('div', { ...props, style: [ styles.initial, props.style ] }); + +const styles = StyleSheet.create({ + initial: { + alignItems: 'stretch', + borderWidth: 0, + borderStyle: 'solid', + boxSizing: 'border-box', + display: 'flex', + flexBasis: 'auto', + flexDirection: 'column', + margin: 0, + padding: 0, + position: 'relative', + // button and anchor reset + backgroundColor: 'transparent', + color: 'inherit', + font: 'inherit', + textAlign: 'inherit', + textDecorationLine: 'none', + // list reset + listStyle: 'none', + // fix flexbox bugs + minHeight: 0, + minWidth: 0 + } +}); + +module.exports = View; diff --git a/performance/implementations/react-native-web/index.js b/performance/implementations/react-native-web/index.js new file mode 100644 index 00000000..0ca161ab --- /dev/null +++ b/performance/implementations/react-native-web/index.js @@ -0,0 +1,7 @@ +import Box from './Box'; +import View from './View'; + +export default { + Box, + View +}; diff --git a/performance/implementations/react-native-web/lite.js b/performance/implementations/react-native-web/lite.js new file mode 100644 index 00000000..94249602 --- /dev/null +++ b/performance/implementations/react-native-web/lite.js @@ -0,0 +1,7 @@ +import Box from './Box/lite'; +import View from './View/lite'; + +export default { + Box, + View +}; diff --git a/performance/implementations/styled-components/Box/index.js b/performance/implementations/styled-components/Box/index.js new file mode 100644 index 00000000..35738979 --- /dev/null +++ b/performance/implementations/styled-components/Box/index.js @@ -0,0 +1,31 @@ +import styled from 'styled-components'; +import View from '../View'; + +const getColor = (color) => { + switch (color) { + case 0: + return '#222'; + case 1: + return '#666'; + case 2: + return '#999'; + case 3: + return 'blue'; + case 4: + return 'orange'; + case 5: + return 'red'; + default: + return 'transparent'; + } +}; + +const Box = styled(View)` + flex-direction: ${(props) => props.layout === 'column' ? 'column' : 'row'}; + padding: ${(props) => props.outer ? '4px' : '0'}; + height: ${(props) => props.fixed ? '20px' : 'auto'}; + width: ${(props) => props.fixed ? '20px' : 'auto'}; + background-color: ${(props) => getColor(props.color)}; +`; + +module.exports = Box; diff --git a/performance/implementations/styled-components/View/index.js b/performance/implementations/styled-components/View/index.js new file mode 100644 index 00000000..aa15c4c7 --- /dev/null +++ b/performance/implementations/styled-components/View/index.js @@ -0,0 +1,25 @@ +import styled from 'styled-components'; + +const View = styled.div` + align-items: stretch; + border-width: 0; + border-style: solid; + box-sizing: border-box; + display: flex; + flex-basis: auto; + flex-direction: column; + flex-shrink: 0; + margin: 0; + padding: 0; + position: relative; + background-color: transparent; + color: inherit; + font: inherit; + text-align: inherit; + text-decoration: none; + list-style: none; + min-height: 0; + min-width: 0; +`; + +module.exports = View; diff --git a/performance/implementations/styled-components/index.js b/performance/implementations/styled-components/index.js new file mode 100644 index 00000000..0ca161ab --- /dev/null +++ b/performance/implementations/styled-components/index.js @@ -0,0 +1,7 @@ +import Box from './Box'; +import View from './View'; + +export default { + Box, + View +}; diff --git a/performance/index.html b/performance/index.html index 0e3fcfc3..28bfda18 100644 --- a/performance/index.html +++ b/performance/index.html @@ -6,6 +6,6 @@
- + diff --git a/performance/index.js b/performance/index.js index 69f100f7..d9593197 100644 --- a/performance/index.js +++ b/performance/index.js @@ -1,16 +1,28 @@ -import createDeepTree from './benchmarks/deepTree/createDeepTree'; -import deepTree from './benchmarks/deepTree'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import ReactNative from 'react-native'; +import cssModules from './implementations/css-modules'; +import glamor from './implementations/glamor'; +import reactNative from './implementations/react-native-web'; +import reactNativeLite from './implementations/react-native-web/lite'; +import styledComponents from './implementations/styled-components'; -const node = document.querySelector('.root'); -const DeepTree = createDeepTree(ReactNative); +import renderDeepTree from './tests/renderDeepTree'; +import renderWideTree from './tests/renderWideTree'; -Promise.resolve() - .then(deepTree({ wrap: 4, depth: 3, breadth: 10, runs: 5, registerStyles: false }, node)) - .then(deepTree({ wrap: 4, depth: 3, breadth: 10, runs: 5 }, node)) - .then(deepTree({ wrap: 4, depth: 3, breadth: 10, runs: 5, leafComponent: 'Image' }, node)) - .then(deepTree({ wrap: 1, depth: 5, breadth: 3, runs: 10 }, node)) - .then(() => ReactDOM.render(, node)); +const tests = [ + // deep tree + () => renderDeepTree('css-modules', cssModules), + () => renderDeepTree('react-native-web/lite', reactNativeLite), + () => renderDeepTree('react-native-web', reactNative), + () => renderDeepTree('styled-components', styledComponents), + () => renderDeepTree('glamor', glamor), + // wide tree + () => renderWideTree('css-modules', cssModules), + () => renderWideTree('react-native-web/lite', reactNativeLite), + () => renderWideTree('react-native-web', reactNative), + () => renderWideTree('styled-components', styledComponents), + () => renderWideTree('glamor', glamor) +]; +// run benchmarks +tests.reduce((promise, test) => { + return promise.then(test()); +}, Promise.resolve()); diff --git a/performance/modules/NestedTree.js b/performance/modules/NestedTree.js new file mode 100644 index 00000000..d076d0e1 --- /dev/null +++ b/performance/modules/NestedTree.js @@ -0,0 +1,49 @@ +import React, { Component, PropTypes } from 'react'; + +class DeepTree extends Component { + static propTypes = { + breadth: PropTypes.number.isRequired, + components: PropTypes.object, + depth: PropTypes.number.isRequired, + id: PropTypes.number.isRequired, + wrap: PropTypes.number.isRequired + }; + + render() { + const { breadth, components, depth, id, wrap } = this.props; + const { Box } = components; + + let result = ( + + {depth === 0 && ( + + )} + {depth !== 0 && Array.from({ length: breadth }).map((el, i) => ( + + ))} + + ); + for (let i = 0; i < wrap; i++) { + result = {result}; + } + return result; + } +} + +module.exports = DeepTree; diff --git a/performance/modules/benchmark.js b/performance/modules/benchmark.js new file mode 100644 index 00000000..6b05a3f7 --- /dev/null +++ b/performance/modules/benchmark.js @@ -0,0 +1,93 @@ +import * as marky from 'marky'; + +const fmt = (time) => `${Math.round(time * 100) / 100}ms`; + +const measure = (name, fn) => { + marky.mark(name); + fn(); + const performanceMeasure = marky.stop(name); + return performanceMeasure.duration; +}; + +const mean = (values) => { + const sum = values.reduce((sum, value) => sum + value, 0); + return sum / values.length; +}; + +const median = (values) => { + if (!Array.isArray(values)) { return 0; } + if (values.length === 1) { return values[0]; } + + const numbers = [ ...values ].sort((a, b) => a - b); + return (numbers[(numbers.length - 1) >> 1] + numbers[numbers.length >> 1]) / 2; +}; + +const standardDeviation = (values) => { + const avg = mean(values); + + const squareDiffs = values.map((value) => { + const diff = value - avg; + return diff * diff; + }); + + const meanSquareDiff = mean(squareDiffs); + return Math.sqrt(meanSquareDiff); +}; + +const benchmark = ({ name, description, setup, teardown, task, runs }) => { + return new Promise((resolve) => { + const durations = []; + let i = 0; + + setup(); + const first = measure('first', task); + teardown(); + + const done = () => { + const stdDev = standardDeviation(durations); + const formattedFirst = fmt(first); + const formattedMean = fmt(mean(durations)); + const formattedMedian = fmt(median(durations)); + const formattedStdDev = fmt(stdDev); + + console.groupCollapsed(`${name}\n${formattedMean} ±${fmt(2 * stdDev)}`); + description && console.log(description); + console.log(`First: ${formattedFirst}`); + console.log(`Median: ${formattedMedian}`); + console.log(`Mean: ${formattedMean}`); + console.log(`Standard deviation: ${formattedStdDev}`); + console.log(durations); + console.groupEnd(); + resolve(); + }; + + const a = () => { + setup(); + window.requestAnimationFrame(b); + }; + + const b = () => { + const duration = measure('mean', task); + durations.push(duration); + window.requestAnimationFrame(c); + }; + + const c = () => { + teardown(); + window.requestAnimationFrame(d); + }; + + const d = () => { + i += 1; + if (i < runs) { + window.requestAnimationFrame(a); + } else { + window.requestAnimationFrame(done); + } + }; + + window.requestAnimationFrame(a); + }); +}; + +export default benchmark; diff --git a/performance/modules/createRenderBenchmark.js b/performance/modules/createRenderBenchmark.js new file mode 100644 index 00000000..79384a10 --- /dev/null +++ b/performance/modules/createRenderBenchmark.js @@ -0,0 +1,20 @@ +import benchmark from './benchmark'; +import ReactDOM from 'react-dom'; + +const node = document.querySelector('.root'); + +const createRenderBenchmark = ({ description, getElement, name, runs }) => () => { + const setup = () => {}; + const teardown = () => ReactDOM.unmountComponentAtNode(node); + + return benchmark({ + name, + description, + runs, + setup, + teardown, + task: () => ReactDOM.render(getElement(), node) + }); +}; + +export default createRenderBenchmark; diff --git a/performance/package.json b/performance/package.json new file mode 100644 index 00000000..c7fe5c36 --- /dev/null +++ b/performance/package.json @@ -0,0 +1,14 @@ +{ + "name": "performance", + "private": true, + "dependencies": { + "classnames": "^2.2.5", + "glamor": "^2.20.24", + "marky": "^1.1.3", + "styled-components": "^1.4.3" + }, + "devDependencies": { + "css-loader": "^0.26.2", + "style-loader": "^0.13.2" + } +} diff --git a/performance/tests/renderDeepTree.js b/performance/tests/renderDeepTree.js new file mode 100644 index 00000000..0af3d95e --- /dev/null +++ b/performance/tests/renderDeepTree.js @@ -0,0 +1,21 @@ +import createRenderBenchmark from '../modules/createRenderBenchmark'; +import NestedTree from '../modules/NestedTree'; +import React from 'react'; + +const renderDeepTree = (label, components) => createRenderBenchmark({ + name: `Deep tree [${label}]`, + runs: 20, + getElement() { + return ( + + ); + } +}); + +export default renderDeepTree; diff --git a/performance/tests/renderWideTree.js b/performance/tests/renderWideTree.js new file mode 100644 index 00000000..922b1352 --- /dev/null +++ b/performance/tests/renderWideTree.js @@ -0,0 +1,21 @@ +import createRenderBenchmark from '../modules/createRenderBenchmark'; +import NestedTree from '../modules/NestedTree'; +import React from 'react'; + +const renderWideTree = (label, components) => createRenderBenchmark({ + name: `Wide tree [${label}]`, + runs: 20, + getElement() { + return ( + + ); + } +}); + +export default renderWideTree; diff --git a/performance/webpack.config.js b/performance/webpack.config.js index 0adaab4a..0a07089a 100644 --- a/performance/webpack.config.js +++ b/performance/webpack.config.js @@ -1,17 +1,20 @@ +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const path = require('path'); const webpack = require('webpack'); -// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { - entry: { - performance: './index' - }, + context: __dirname, + entry: './index', output: { - path: path.resolve(__dirname, '../dist-performance'), + path: path.resolve(__dirname, 'dist'), filename: 'performance.bundle.js' }, module: { loaders: [ + { + test: /\.css$/, + loader: 'style-loader!css-loader?module&localIdentName=[hash:base64:8]' + }, { test: /\.js$/, exclude: /node_modules/, @@ -21,13 +24,12 @@ module.exports = { ] }, plugins: [ + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false + }), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }), new webpack.optimize.DedupePlugin(), - // https://github.com/animatedjs/animated/issues/40 - new webpack.NormalModuleReplacementPlugin( - /es6-set/, - path.join(__dirname, '../src/modules/polyfills/Set.js') - ), new webpack.optimize.OccurenceOrderPlugin(), new webpack.optimize.UglifyJsPlugin({ compress: { diff --git a/performance/yarn.lock b/performance/yarn.lock new file mode 100644 index 00000000..e7958f22 --- /dev/null +++ b/performance/yarn.lock @@ -0,0 +1,970 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +asap@~2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" + +autoprefixer@^6.3.1: + version "6.7.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.5.tgz#50848f39dc08730091d9495023487e7cc21f518d" + dependencies: + browserslist "^1.7.5" + caniuse-db "^1.0.30000624" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^5.2.15" + postcss-value-parser "^3.2.3" + +babel-code-frame@^6.11.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +babel-runtime@^6.18.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +balanced-match@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +base64-js@^1.0.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" + +big.js@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978" + +bowser@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.6.0.tgz#37fc387b616cb6aef370dab4d6bd402b74c5c54d" + +browserslist@^1.0.1, browserslist@^1.5.2, browserslist@^1.7.5: + version "1.7.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.5.tgz#eca4713897b51e444283241facf3985de49a9e2b" + dependencies: + caniuse-db "^1.0.30000624" + electron-to-chromium "^1.2.3" + +buffer@^5.0.2: + version "5.0.5" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.0.5.tgz#35c9393244a90aff83581063d16f0882cecc9418" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +caniuse-api@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.5.3.tgz#5018e674b51c393e4d50614275dc017e27c4a2a2" + dependencies: + browserslist "^1.0.1" + caniuse-db "^1.0.30000346" + lodash.memoize "^4.1.0" + lodash.uniq "^4.3.0" + +caniuse-db@^1.0.30000346, caniuse-db@^1.0.30000624: + version "1.0.30000628" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000628.tgz#3d010e2a8e2537a8d135792e90e4f2ce0eb838cc" + +chalk@^1.1.0, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +clap@^1.0.9: + version "1.1.2" + resolved "https://registry.yarnpkg.com/clap/-/clap-1.1.2.tgz#316545bf22229225a2cecaa6824cd2f56a9709ed" + dependencies: + chalk "^1.1.3" + +classnames@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" + +clone@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" + +coa@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.1.tgz#7f959346cfc8719e3f7233cd6852854a7c67d8a3" + dependencies: + q "^1.1.2" + +color-convert@^1.3.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" + dependencies: + color-name "^1.1.1" + +color-name@^1.0.0, color-name@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" + +color-string@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" + dependencies: + color-name "^1.0.0" + +color@^0.11.0: + version "0.11.4" + resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" + dependencies: + clone "^1.0.2" + color-convert "^1.3.0" + color-string "^0.3.0" + +colormin@^1.0.5: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" + dependencies: + color "^0.11.0" + css-color-names "0.0.4" + has "^1.0.1" + +colors@0.5.x: + version "0.5.1" + resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774" + +colors@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +css-color-list@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/css-color-list/-/css-color-list-0.0.1.tgz#8718e8695ae7a2cc8787be8715f1c008a7f28b15" + dependencies: + css-color-names "0.0.1" + +css-color-names@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.1.tgz#5d0548fa256456ede4a9a0c2ac7ab19d3eb1ad81" + +css-color-names@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + +css-loader@^0.26.2: + version "0.26.2" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.26.2.tgz#a9cd4c2b1a559b45d8efc04fc311ab5d2aaccb9d" + dependencies: + babel-code-frame "^6.11.0" + css-selector-tokenizer "^0.7.0" + cssnano ">=2.6.1 <4" + loader-utils "^1.0.2" + lodash.camelcase "^4.3.0" + object-assign "^4.0.1" + postcss "^5.0.6" + postcss-modules-extract-imports "^1.0.0" + postcss-modules-local-by-default "^1.0.1" + postcss-modules-scope "^1.0.0" + postcss-modules-values "^1.1.0" + source-list-map "^0.1.7" + +css-selector-tokenizer@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.6.0.tgz#6445f582c7930d241dcc5007a43d6fcb8f073152" + dependencies: + cssesc "^0.1.0" + fastparse "^1.1.1" + regexpu-core "^1.0.0" + +css-selector-tokenizer@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86" + dependencies: + cssesc "^0.1.0" + fastparse "^1.1.1" + regexpu-core "^1.0.0" + +css-to-react-native@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-1.0.6.tgz#728c7e774e56536558a0ecaa990d9507c43a4ac4" + dependencies: + css-color-list "0.0.1" + fbjs "^0.8.5" + nearley "^2.7.7" + +cssesc@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" + +"cssnano@>=2.6.1 <4": + version "3.10.0" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" + dependencies: + autoprefixer "^6.3.1" + decamelize "^1.1.2" + defined "^1.0.0" + has "^1.0.1" + object-assign "^4.0.1" + postcss "^5.0.14" + postcss-calc "^5.2.0" + postcss-colormin "^2.1.8" + postcss-convert-values "^2.3.4" + postcss-discard-comments "^2.0.4" + postcss-discard-duplicates "^2.0.1" + postcss-discard-empty "^2.0.1" + postcss-discard-overridden "^0.1.1" + postcss-discard-unused "^2.2.1" + postcss-filter-plugins "^2.0.0" + postcss-merge-idents "^2.1.5" + postcss-merge-longhand "^2.0.1" + postcss-merge-rules "^2.0.3" + postcss-minify-font-values "^1.0.2" + postcss-minify-gradients "^1.0.1" + postcss-minify-params "^1.0.4" + postcss-minify-selectors "^2.0.4" + postcss-normalize-charset "^1.1.0" + postcss-normalize-url "^3.0.7" + postcss-ordered-values "^2.1.0" + postcss-reduce-idents "^2.2.2" + postcss-reduce-initial "^1.0.0" + postcss-reduce-transforms "^1.0.3" + postcss-svgo "^2.1.1" + postcss-unique-selectors "^2.0.2" + postcss-value-parser "^3.2.3" + postcss-zindex "^2.0.1" + +csso@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.1.tgz#4f8d91a156f2f1c2aebb40b8fb1b5eb83d94d3b9" + dependencies: + clap "^1.0.9" + source-map "^0.5.3" + +decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + +discontinuous-range@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" + +electron-to-chromium@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.2.4.tgz#9751cbea89fa120bf88c226ba41eb8d0b6f1b597" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +escape-string-regexp@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +esprima@^2.6.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +fastparse@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" + +fbjs@^0.8.5, fbjs@^0.8.7, fbjs@^0.8.8: + version "0.8.9" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.9.tgz#180247fbd347dcc9004517b904f865400a0c8f14" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +flatten@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" + +function-bind@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" + +glamor@^2.20.12, glamor@^2.20.24: + version "2.20.24" + resolved "https://registry.yarnpkg.com/glamor/-/glamor-2.20.24.tgz#a299af2eec687322634ba38e4a0854d8743d2041" + dependencies: + babel-runtime "^6.18.0" + fbjs "^0.8.8" + object-assign "^4.1.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +html-comment-regex@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" + +hyphenate-style-name@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" + +iconv-lite@~0.4.13: + version "0.4.15" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" + +icss-replace-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.0.2.tgz#cb0b6054eb3af6edc9ab1d62d01933e2d4c8bfa5" + +ieee754@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + +inline-style-prefixer@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-2.0.5.tgz#c153c7e88fd84fef5c602e95a8168b2770671fe7" + dependencies: + bowser "^1.0.0" + hyphenate-style-name "^1.0.1" + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + +is-function@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-plain-object@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.1.tgz#4d7ca539bc9db9b737b8acb612f2318ef92f294f" + dependencies: + isobject "^1.0.0" + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-svg@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" + dependencies: + html-comment-regex "^1.1.0" + +isobject@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-1.0.2.tgz#f0f9b8ce92dd540fa0740882e3835a2e022ec78a" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +js-base64@^2.1.9: + version "2.1.9" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" + +js-tokens@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" + +js-yaml@~3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" + dependencies: + argparse "^1.0.7" + esprima "^2.6.0" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +loader-utils@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.0.2.tgz#a9f923c865a974623391a8602d031137fad74830" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + +lodash.memoize@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + +lodash.uniq@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +macaddress@^0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12" + +marky@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/marky/-/marky-1.1.3.tgz#b5b914c661f73355862a77acf21aadfc60745e37" + +math-expression-evaluator@^1.2.14: + version "1.2.16" + resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.16.tgz#b357fa1ca9faefb8e48d10c14ef2bcb2d9f0a7c9" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +nearley@^2.7.7: + version "2.7.13" + resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.7.13.tgz#ae19927cc821a4b517de91962db9ed0e90d991fa" + dependencies: + nomnom "~1.6.2" + railroad-diagrams "^1.0.0" + randexp "^0.4.2" + +node-fetch@^1.0.1: + version "1.6.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +nomnom@~1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.6.2.tgz#84a66a260174408fc5b77a18f888eccc44fb6971" + dependencies: + colors "0.5.x" + underscore "~1.4.4" + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + +normalize-url@^1.4.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.0.tgz#c2bb50035edee62cd81edb2d45da68dc25e3423e" + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +postcss-calc@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" + dependencies: + postcss "^5.0.2" + postcss-message-helpers "^2.0.0" + reduce-css-calc "^1.2.6" + +postcss-colormin@^2.1.8: + version "2.2.2" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" + dependencies: + colormin "^1.0.5" + postcss "^5.0.13" + postcss-value-parser "^3.2.3" + +postcss-convert-values@^2.3.4: + version "2.6.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" + dependencies: + postcss "^5.0.11" + postcss-value-parser "^3.1.2" + +postcss-discard-comments@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" + dependencies: + postcss "^5.0.14" + +postcss-discard-duplicates@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.0.2.tgz#02be520e91571ffb10738766a981d5770989bb32" + dependencies: + postcss "^5.0.4" + +postcss-discard-empty@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" + dependencies: + postcss "^5.0.14" + +postcss-discard-overridden@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" + dependencies: + postcss "^5.0.16" + +postcss-discard-unused@^2.2.1: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" + dependencies: + postcss "^5.0.14" + uniqs "^2.0.0" + +postcss-filter-plugins@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz#6d85862534d735ac420e4a85806e1f5d4286d84c" + dependencies: + postcss "^5.0.4" + uniqid "^4.0.0" + +postcss-merge-idents@^2.1.5: + version "2.1.7" + resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" + dependencies: + has "^1.0.1" + postcss "^5.0.10" + postcss-value-parser "^3.1.1" + +postcss-merge-longhand@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658" + dependencies: + postcss "^5.0.4" + +postcss-merge-rules@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" + dependencies: + browserslist "^1.5.2" + caniuse-api "^1.5.2" + postcss "^5.0.4" + postcss-selector-parser "^2.2.2" + vendors "^1.0.0" + +postcss-message-helpers@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" + +postcss-minify-font-values@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" + dependencies: + object-assign "^4.0.1" + postcss "^5.0.4" + postcss-value-parser "^3.0.2" + +postcss-minify-gradients@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" + dependencies: + postcss "^5.0.12" + postcss-value-parser "^3.3.0" + +postcss-minify-params@^1.0.4: + version "1.2.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" + dependencies: + alphanum-sort "^1.0.1" + postcss "^5.0.2" + postcss-value-parser "^3.0.2" + uniqs "^2.0.0" + +postcss-minify-selectors@^2.0.4: + version "2.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" + dependencies: + alphanum-sort "^1.0.2" + has "^1.0.1" + postcss "^5.0.14" + postcss-selector-parser "^2.0.0" + +postcss-modules-extract-imports@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.0.1.tgz#8fb3fef9a6dd0420d3f6d4353cf1ff73f2b2a341" + dependencies: + postcss "^5.0.4" + +postcss-modules-local-by-default@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.1.1.tgz#29a10673fa37d19251265ca2ba3150d9040eb4ce" + dependencies: + css-selector-tokenizer "^0.6.0" + postcss "^5.0.4" + +postcss-modules-scope@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.0.2.tgz#ff977395e5e06202d7362290b88b1e8cd049de29" + dependencies: + css-selector-tokenizer "^0.6.0" + postcss "^5.0.4" + +postcss-modules-values@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.2.2.tgz#f0e7d476fe1ed88c5e4c7f97533a3e772ad94ca1" + dependencies: + icss-replace-symbols "^1.0.2" + postcss "^5.0.14" + +postcss-normalize-charset@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" + dependencies: + postcss "^5.0.5" + +postcss-normalize-url@^3.0.7: + version "3.0.8" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^1.4.0" + postcss "^5.0.14" + postcss-value-parser "^3.2.3" + +postcss-ordered-values@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" + dependencies: + postcss "^5.0.4" + postcss-value-parser "^3.0.1" + +postcss-reduce-idents@^2.2.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" + dependencies: + postcss "^5.0.4" + postcss-value-parser "^3.0.2" + +postcss-reduce-initial@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" + dependencies: + postcss "^5.0.4" + +postcss-reduce-transforms@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" + dependencies: + has "^1.0.1" + postcss "^5.0.8" + postcss-value-parser "^3.0.1" + +postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-svgo@^2.1.1: + version "2.1.6" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" + dependencies: + is-svg "^2.0.0" + postcss "^5.0.14" + postcss-value-parser "^3.2.3" + svgo "^0.7.0" + +postcss-unique-selectors@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" + dependencies: + alphanum-sort "^1.0.1" + postcss "^5.0.4" + uniqs "^2.0.0" + +postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" + +postcss-zindex@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" + dependencies: + has "^1.0.1" + postcss "^5.0.4" + uniqs "^2.0.0" + +postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.15: + version "5.2.15" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.15.tgz#a9e8685e50e06cc5b3fdea5297273246c26f5b30" + dependencies: + chalk "^1.1.3" + js-base64 "^2.1.9" + source-map "^0.5.6" + supports-color "^3.2.3" + +prepend-http@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +promise@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" + dependencies: + asap "~2.0.3" + +q@^1.1.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" + +query-string@^4.1.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.2.tgz#ec0fd765f58a50031a3968c2431386f8947a5cdd" + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +railroad-diagrams@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e" + +randexp@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.4.tgz#ba68265f4a9f9e85f5814d34e160291f939f168e" + dependencies: + discontinuous-range "1.0.0" + ret "~0.1.10" + +reduce-css-calc@^1.2.6: + version "1.3.0" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" + dependencies: + balanced-match "^0.4.2" + math-expression-evaluator "^1.2.14" + reduce-function-call "^1.0.1" + +reduce-function-call@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.2.tgz#5a200bf92e0e37751752fe45b0ab330fd4b6be99" + dependencies: + balanced-match "^0.4.2" + +regenerate@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" + +regenerator-runtime@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e" + +regexpu-core@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +ret@~0.1.10: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.13.tgz#38c2702ece654978941edd8b7dfac6aeeef4067d" + +sax@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" + +source-map@^0.5.3, source-map@^0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +style-loader@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.13.2.tgz#74533384cf698c7104c7951150b49717adc2f3bb" + dependencies: + loader-utils "^1.0.2" + +styled-components@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-1.4.3.tgz#83fa44e553882aaa3ddc4363ccc435814d690706" + dependencies: + buffer "^5.0.2" + css-to-react-native "^1.0.6" + fbjs "^0.8.7" + glamor "^2.20.12" + inline-style-prefixer "^2.0.5" + is-function "^1.0.1" + is-plain-object "^2.0.1" + supports-color "^3.1.2" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.2, supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +svgo@^0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" + dependencies: + coa "~1.0.1" + colors "~1.1.2" + csso "~2.3.1" + js-yaml "~3.7.0" + mkdirp "~0.5.1" + sax "~1.2.1" + whet.extend "~0.9.9" + +ua-parser-js@^0.7.9: + version "0.7.12" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" + +underscore@~1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + +uniqid@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/uniqid/-/uniqid-4.1.1.tgz#89220ddf6b751ae52b5f72484863528596bb84c1" + dependencies: + macaddress "^0.2.8" + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + +vendors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22" + +whatwg-fetch@>=0.10.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.2.tgz#fe294d1d89e36c5be8b3195057f2e4bc74fc980e" + +whet.extend@~0.9.9: + version "0.9.9" + resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" diff --git a/yarn.lock b/yarn.lock index fddcac83..0ff6ae2b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3765,10 +3765,6 @@ marked@^0.3.6: version "0.3.6" resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.6.tgz#b2c6c618fccece4ef86c4fc6cb8a7cbf5aeda8d7" -marky@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/marky/-/marky-1.1.1.tgz#dcd1eba3e2c6412619a76981f635b3698a8761e8" - math-expression-evaluator@^1.2.14: version "1.2.14" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.14.tgz#39511771ed9602405fba9affff17eb4d2a3843ab"