[
  {
    "path": ".babelrc",
    "content": "{\n  \"presets\": [\n    [\"@babel/env\", { \"modules\": \"commonjs\", \"loose\": true }],\n    \"@babel/flow\",\n    \"@babel/react\"\n  ],\n  \"plugins\": [\n    [\"@babel/proposal-class-properties\", { \"loose\": true }],\n    [\"transform-react-remove-prop-types\", { \"mode\": \"unsafe-wrap\" }]\n  ],\n  \"env\": {\n    \"test\": {\n      \"plugins\": [\n        \"@babel/transform-modules-commonjs\"\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": ".eslintignore",
    "content": "build\ncoverage\nlib\nnode_modules\n**/*/all.js\nwebpack.*.js\nserver.js\nkarma.*.js\ntest/integration\ndemos/demo6/babel.js\ndemos/*/Demo.jsx\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"parser\": \"babel-eslint\",\n  \"extends\": [\"airbnb\", \"prettier\"],\n  \"env\": {\n    \"browser\": true,\n    \"es6\": true,\n    \"jasmine\": true\n  },\n  \"rules\": {\n    \"eqeqeq\": [2, \"allow-null\"],\n    \"id-length\": 0,\n    \"no-console\": 0, // use it for warnings\n    \"no-nested-ternary\": 0,\n    \"prefer-const\": 0,\n    \"no-multiple-empty-lines\": 0,\n    \"no-useless-escape\": 0,\n    \"no-else-return\": 0,\n    \"comma-dangle\": 0,\n    \"lines-between-class-members\": 0,\n    \"indent\": 0,\n    \"operator-linebreak\": 0,\n    \"object-curly-newline\": 0,\n    \"function-paren-newline\": 0,\n    \"prefer-destructuring\": 0,\n    \"camelcase\": [\"error\", {\"allow\": [\"^UNSAFE_\"]}],\n\n    \"react/jsx-wrap-multilines\": 0,\n    \"react/jsx-one-expression-per-line\": 0,\n    \"react/no-unused-state\": 0,\n    \"react/require-default-props\": 0,\n    \"react/destructuring-assignment\": 0,\n    \"react/no-did-mount-set-state\": 2,\n    \"react/no-multi-comp\": 0,\n    \"react/jsx-boolean-value\": [2, \"always\"],\n    \"react/sort-comp\": [\n      2, {\n        \"order\": [\n          \"displayName\",\n          \"propTypes\",\n          \"contextTypes\",\n          \"childContextTypes\",\n          \"mixins\",\n          \"statics\",\n          \"defaultProps\",\n          \"getDefaultProps\",\n          \"getInitialState\",\n          \"getChildContext\",\n          \"componentWillMount\",\n          \"UNSAFE_componentWillMount\",\n          \"componentDidMount\",\n          \"componentWillReceiveProps\",\n          \"UNSAFE_componentWillReceiveProps\",\n          \"shouldComponentUpdate\",\n          \"componentWillUpdate\",\n          \"UNSAFE_componentWillUpdate\",\n          \"componentDidUpdate\",\n          \"componentWillUnmount\",\n          \"/^on.+$/\",\n          \"/^get.+$/\",\n          \"/^render.+$/\",\n          \"/^.+$/\", // All other methods go here\n          \"render\"\n        ]\n      }\n    ],\n\n    \"max-len\": 0,\n    \"no-mixed-operators\": 0,\n    \"no-continue\": 0,\n    \"no-restricted-syntax\": 0,\n    \"no-plusplus\": 0,\n    \"no-confusing-arrow\": 0,\n    \"arrow-parens\": 0,\n    \"arrow-body-style\": 0,\n    \"react/jsx-indent\": 0,\n    \"react/jsx-indent-props\": 0,\n    \"react/jsx-closing-bracket-location\": 0,\n    \"react/prefer-es6-class\": 0,\n    \"react/jsx-filename-extension\": 0,\n    \"react/prefer-stateless-function\": 0,\n    \"object-curly-spacing\": 0,\n    \"import/imports-first\": 0,\n    \"import/no-unresolved\": 0,\n    \"import/no-extraneous-dependencies\": 0,\n    \"import/order\": 0,\n    \"import/no-webpack-loader-syntax\": 0,\n  }\n}\n"
  },
  {
    "path": ".flowconfig",
    "content": "[ignore]\n.*/node_modules/fbjs/lib/PromiseMap.js\n.*/node_modules/fbjs/lib/fetchWithRetries.js\n.*/node_modules/fbjs/lib/Deferred.js.flow\n.*/node_modules/fbjs/lib/equalsSet.js.flow\n.*/node_modules/fbjs/lib/shallowEqual.js.flow\n.*/node_modules/fbjs/lib/someSet.js.flow\n.*/node_modules/fbjs/lib/everySet.js.flow\n.*/node_modules/fbjs/lib/UnicodeBidi.js.flow\n.*/node_modules/fbjs/lib/UnicodeBidiService.js.flow\n.*/node_modules/kefir/kefir.js.flow\n.*/node_modules/kefir/dist/kefir.js.flow\n.*/test/.*\n.*/node_modules/@webassemblyjs/.*\n.*/node_modules/eslint-plugin-jsx-a11y/.*\n.*/node_modules/rollup-plugin-size-snapshot/.*\n.*/node_modules/babel-plugin-transform-react-remove-prop-types\n\n[include]\n\n[libs]\n\n[options]\n"
  },
  {
    "path": ".gitignore",
    "content": "logs\n*.log\n\npids\n*.pid\n*.seed\n\ncoverage\nnode_modules\nbower_components\n\n.DS_Store\n\n/demos/**/all.*\n/build/\n/lib/\n"
  },
  {
    "path": ".npmignore",
    "content": "/.*\n\n/bower_components/\n\n/coverage/\n/demos/\n/test/\n\n/karma.conf.js\n/webpack.*\n/server.js\n\n# sublime\n/*.sublime-project\n/*.sublime-workspace\n\n/rollup.config.js\n"
  },
  {
    "path": ".size-snapshot.json",
    "content": "{\n  \"build/react-motion.js\": {\n    \"bundled\": 77059,\n    \"minified\": 22596,\n    \"gzipped\": 6616\n  },\n  \"build/react-motion.min.js\": {\n    \"bundled\": 52481,\n    \"minified\": 15210,\n    \"gzipped\": 4446\n  },\n  \"lib/react-motion.esm.js\": {\n    \"bundled\": 43290,\n    \"minified\": 14594,\n    \"gzipped\": 3583,\n    \"treeshaked\": {\n      \"rollup\": {\n        \"code\": 6381,\n        \"import_statements\": 196\n      },\n      \"webpack\": {\n        \"code\": 7588\n      }\n    }\n  }\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\n\nnode_js:\n  - 10\n\nscript:\n - npm run -s lint\n - npm run -s flow_check\n - npm run -s test:travis\n"
  },
  {
    "path": "AUTHORS",
    "content": "Adrian le Bas\nAmadeus Junqueira\nBenjamin San Souci\nBishop Zareh\nBrenton Simpson\nCesar Andreu\nCheng Lou\nDan Abramov\nDaniel Dunderfelt\nDustan Kasten\nFrederick Fogerty\nGaëtan Renaudeau\nGoogle, Inc.\nHenry Zhu\nIvan Starkov\nJeroen van Aert\nJesper Petersson\nJevgeni Geimanen\nJoe Lencioni\nJohn Amiah Ford\nJon Lebensold\nJustin Morris\nKyle Mathews\nLudovico Fischer\nMichael J Hoffman\nMirko Mariani\nNeil Kistner\nNik Butenko\nNikhil Baradwaj\nOlivier Tassinari\nPaolo Moretti\nRaymond Zhou\nRobert Haritonov\nSorin Iclanzan\nStefan Dombrowski\nStephen J. Collings\nSundeep Malladi\nSunil Pai\nTravis Arnold\nWilfred Denton\n"
  },
  {
    "path": "HISTORY.md",
    "content": "Legend:\n- [B]: Breaking\n- [F]: Fix\n- [I]: Improvement\n\n### 0.5.1 (August 28th 2017)\n- [F] New flow definitions, fixes children typing.\n\n### 0.5.0 (April 26th 2017)\n- [B] Dropping support for older React. Currently supported versions are `^0.14.9` || `^15.3.0`\n- [I] Upgraded all React components to use ES6 classes\n- [I] Replace React.PropTypes with prop-types package\n\n### 0.4.8 (April 17th 2017)\n\n- [I] Externalize stripStyle #452 by @bearcott\n- [I] Migrated deprecated React.PropTypes and React.createClass #446 by @Andarist\n- [F] Fix link to TypeScript types #443 by @pshrmn\n- [F] Refactored demo and fixed flow check errors #435 by @therewillbecode\n- [F] Fix broken link #430 by @codler\n- [F] Unmounted component setState fix #420 by @alleycat-at-git\n\n### 0.4.7 (December 15th 2016)\n- [I] `didLeave` for `TransitionMotion`! Please check the README for more.\n\n### 0.4.4 (June 4th 2016)\n- [F] Small fix to component unmounting bug (https://github.com/chenglou/react-motion/commit/49ea396041b0031b95f4941cc7efce200fcca454). It's not clear why this is erroring, but people want the temp fix.\n\n### 0.4.3 (April 19th 2016)\n- [F] `TransitionMotion` `styles` function not being passed `defaultStyles` value upon first call. #296\n- [I] `onRest` callback for `Motion`!\n\n### 0.4.2 (January 30th 2016)\n- [F] `TransitionMotion` keys merging bug. #264\n- [F] `TransitionMotion` rare stale read bug. [https://github.com/chenglou/react-motion/commit/f20dc1b9c8de7b387927b24afdb73e0a5ea0d0a6](https://github.com/chenglou/react-motion/commit/f20dc1b9c8de7b387927b24afdb73e0a5ea0d0a6)\n\n### 0.4.1 (January 26th 2016)\n- [F] Made a mistake while publishing the bower package; fixed.\n\n### 0.4.0 (January 26th 2016)\n- [B] `spring` helper's format has changed from `spring(10, [120, 12])` to `spring(10, {stiffness: 120, damping: 12})`.\n- [B] `style`, `styles` and `styles` of the three respective components now only accept either a number to interpolate, or a `spring` configuration to interpolate. Previously, it accepted (and ignored) random key/value pairs mixed in, such as `{x: spring(0), y: 'helloWorld'}`. `y` Doesn't belong there and should be placed elsewhere, e.g. directly on the (actual react) style of the component you're assigning the interpolating values on.\n- [B] `TransitionMotion` got an all-around clearer API. See the [upgrade guide](https://github.com/chenglou/react-motion/wiki) and [README section](https://github.com/chenglou/react-motion/blob/9877c311cc4a22099eb56fe7c76bad9753519ddb/README.md#transitionmotion-) for more.\n- [B] `Motion`'s' `defaultStyle`, informally accepted the format `{x: spring(0)}`. This is now officially unsupported. The correct format has always been `{x: 0}`. Setting a default style of `{x: spring(whatever)}` did not make sense; the configuration only applies for a `style`, aka destination value. Same modification applies to `StaggeredMotion` and `TransitionMotion`'s `defaultStyles` & `willEnter`.\n- [B] `TransitionMotion`'s `willEnter`/`willLeave`'s signature has changed.\n- [B] The `reorderKeys` helper is no longer needed thanks to the changes to `TransitionMotion`. It's now removed.\n- [B] React-Native specific build gone. RN 0.18+ uses the vanilla Npm React package, so there's no more need for us to export a wrapper.\n- [F] Bunch of bugs gone: #225, #212, #179, #157, #90, #88.\n- [I] `spring` has acquired a new field as part of the new signature: [precision tuning](https://github.com/chenglou/react-motion/blob/9877c311cc4a22099eb56fe7c76bad9753519ddb/README.md#--spring-val-number-config-springhelperconfig--opaqueconfig)!\n- [I] [Fully typed](https://github.com/chenglou/react-motion/blob/05d76f5ec7e9722dbca0237a97c41267e297eb2c/src/Types.js) via [Flow types](http://flowtype.org).\n- [I] Performance improvements.\n\n### 0.3.1 (October 14th 2015)\n- [F] Handle `null` and `undefined` in `style`/`styles`. #181\n- [I] Library's now partially annotated with [Flow](http://flowtype.org).\n- [I] Related to above, the `src/` folder is now exposed on npm so that you can take advantage of Flow by using: `import {Motion} from 'react-motion/src/react-motion'` directly, instead of the old, prebuilt `import {Motion} from 'react-motion'`. **This is experimental** and intentionally undocumented. You'll have to adjust your webpack/browserify configurations to require these original source files correctly. No harm trying of course. It's just some type annotations =).\n\n### 0.3.0 (September 30th 2015)\n- [B] API revamp! See [https://github.com/chenglou/react-motion/wiki](https://github.com/chenglou/react-motion/wiki) for more details. Thanks!\n\n### 0.2.7 (August 6th 2015)\n- [F] Small bug where nested springs don't animate. #123\n- [I] Support for all React 0.14.0 betas.\n\n### 0.2.6 (July 31th 2015)\n- [F] React-native warning's now gone, but also put into a separate file path. To require react-motion on react-native, do `require('react-motion/native')`.\n- [I] Support for React 0.14.0-beta1.\n\n### 0.2.4 (July 29th 2015)\n- [I] React-native support!\n- [I] Allow returning `null` from children function. #101\n- [I] `defaultValue` for specifying a... default value, upon mounting.\n- [I] `TransitionSpring`'s `willLeave` API got simplified and now asks for an object as a return value instead of `null`. `null` is still supported, but is deprecated and will be removed in the next version. See the new docs on it [here](https://github.com/chenglou/react-motion/blob/24d6a7284ef61268c0ead67fe43d7e40bf45d381/README.md#transitionspring-).\n- [I] Exposed a few tasteful default spring configurations under the new exported `presets`.\n\n### 0.2.2 (July 24th 2015)\n- [F] Import some internal modules correctly for Ubuntu/Linux node (case-sensitive for them).\n- [F] Nested springs work again.\n\n### 0.2.0 (July 22th 2015)\n- [B] `willLeave` returning `false` will now keep the key. Only `null` and `undefined` will serve as a signal to kill the disappeared key.\n- [B] `willLeave` previously failed to expose the second argument `correspondingValueOfKeyThatJustLeft`. It's now exposed correctly.\n- [F] Definitively fix the previous problem of mis-detecting React Element as object.\n- [F] `willLeave` is now called only once per disappearing key. It was called more than once previously as a implementation detail. Though you should never have put side-effects in `willLeave`. It's still discouraged now.\n- [F] If you have some `this.props.handlerThatSetStateAndUnmountsSpringInOwnerRender()` in `Spring`'s `endValue`, Spring's already scheduled `requestAnimationFrame` will no longer cause an extra `setState` since it's unmounted. But in general, _please_ don't put side-effect in `endValue`.\n- [I] Stabilize the spring algorithm. No more erratic behavior with a big amount of animated items or tab switching (which usually slows down `requestAnimationFrame`). #57\n- [I] Partial (total?) support for IE9 by using a `requestAnimationFrame` polyfill.\n\n### 0.1.0 (July 14th 2015)\n- [B] Breaking API: `TransitionSpring`'s `willEnter`'s callback signature is now `(keyThatEnters, correspondingValue, endValueYouJustSpecified, currentInterpolatedValue, currentSpeed)` (added `correspondingValue` as the second argument). Same for `willLeave`.\n- [B] `Spring` is now no longer exposed as a default, but simply as \"Spring\": `require('react-motion').Spring`. Or `import {Spring} from 'react-motion'`.\n- [B] `Spring` and `TransitionSpring`'s `children` function now expect a ReactElement. The components will no longer wrap the return value in a `div` for you. #44 #20\n- [I] Move React to from dependencies to peerDependencies. #35\n- [I] Internal cleanups + tests, for happier contributors.\n- [F] Mis-detecting React Element as object.\n- [F] Accidentally updating values at the first level of `endValue` without `{val: ...}` wrapper.\n\n### 0.0.3 (July 9th 2015)\n- [I] Initial release.\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 React Motion authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# React-Motion\n\n[![Build Status](https://travis-ci.org/chenglou/react-motion.svg?branch=master)](https://travis-ci.org/chenglou/react-motion)\n[![npm version](https://badge.fury.io/js/react-motion.svg)](https://www.npmjs.com/package/react-motion)\n[![Bower version](https://badge.fury.io/bo/react-motion.svg)](http://badge.fury.io/bo/react-motion)\n[![react-motion channel on discord](https://img.shields.io/badge/discord-react--motion%40reactiflux-738bd7.svg?style=flat)](https://discordapp.com/invite/0ZcbPKXt5bYzmcI0)\n\n```js\nimport {Motion, spring} from 'react-motion';\n// In your render...\n<Motion defaultStyle={{x: 0}} style={{x: spring(10)}}>\n  {value => <div>{value.x}</div>}\n</Motion>\n```\n\nAnimate a counter from `0` to `10`. For more advanced usage, see below.\n\n### Install\n\n- Npm: `npm install --save react-motion`\n\n- Bower: **do not install with `bower install react-motion`, it won't work**. Use `bower install --save https://unpkg.com/react-motion/bower.zip`. Or in `bower.json`:\n```json\n{\n  \"dependencies\": {\n    \"react-motion\": \"https://unpkg.com/react-motion/bower.zip\"\n  }\n}\n```\nthen include as\n```html\n<script src=\"bower_components/react-motion/build/react-motion.js\"></script>\n```\n\n- 1998 Script Tag:\n```html\n<script src=\"https://unpkg.com/react-motion/build/react-motion.js\"></script>\n(Module exposed as `ReactMotion`)\n```\n\n**Works with React-Native v0.18+**.\n\n### Demos\n- [Simple Transition](http://chenglou.github.io/react-motion/demos/demo0-simple-transition)\n- [Chat Heads](http://chenglou.github.io/react-motion/demos/demo1-chat-heads)\n- [Draggable Balls](http://chenglou.github.io/react-motion/demos/demo2-draggable-balls)\n- [TodoMVC List Transition](http://chenglou.github.io/react-motion/demos/demo3-todomvc-list-transition)\n- [Photo Gallery](http://chenglou.github.io/react-motion/demos/demo4-photo-gallery)\n- [Spring Parameters Chooser](http://chenglou.github.io/react-motion/demos/demo5-spring-parameters-chooser)\n- [Water Ripples](http://chenglou.github.io/react-motion/demos/demo7-water-ripples)\n- [Draggable List](http://chenglou.github.io/react-motion/demos/demo8-draggable-list)\n\n[Check the wiki for more!](https://github.com/chenglou/react-motion/wiki/Gallery-of-third-party-React-Motion-demos)\n\n### Try the Demos Locally\n```sh\ngit clone https://github.com/chenglou/react-motion.git\ncd react-motion\nnpm install\n```\n\n- With hot reloading (**slow, development version**): run `npm start`.\n- Without hot reloading (**faster, production version**): run `npm run build-demos` and open the static `demos/demo_name/index.html` file directly. **Don't forget to use production mode when testing your animation's performance**!\n\nTo build the repo yourself: `npm run prepublish`.\n\n## What does this library try to solve?\n\n[My React-Europe talk](https://www.youtube.com/watch?v=1tavDv5hXpo)\n\nFor 95% of use-cases of animating components, we don't have to resort to using hard-coded easing curves and duration. Set up a stiffness and damping for your UI element, and let the magic of physics take care of the rest. This way, you don't have to worry about petty situations such as interrupted animation behavior. It also greatly simplifies the API.\n\nThis library also provides an alternative, more powerful API for React's `TransitionGroup`.\n\n## API\n\nExports:\n- `spring`\n- `Motion`\n- `StaggeredMotion`\n- `TransitionMotion`\n- `presets`\n\n[Here](https://github.com/chenglou/react-motion/blob/9cb90eca20ecf56e77feb816d101a4a9110c7d70/src/Types.js)'s the well-annotated public [Flow type](http://flowtype.org) definition file (you don't have to use Flow with React-motion, but the types help document the API below).\n\nP.S. using TypeScript? [Here](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-motion/index.d.ts) are the React-motion TypeScript definitions!\n\n---\n\n### Helpers\n\n##### - spring: (val: number, config?: SpringHelperConfig) => OpaqueConfig\nUsed in conjunction with the components below. Specifies the how to animate to the destination value, e.g. `spring(10, {stiffness: 120, damping: 17})` means \"animate to value 10, with a spring of stiffness 120 and damping 17\".\n\n- `val`: the value.\n- `config`: optional, for further adjustments. Possible fields:\n  - `stiffness`: optional, defaults to `170`.\n  - `damping`: optional, defaults to `26`.\n  - `precision`: optional, defaults to `0.01`. Specifies both the rounding of the interpolated value and the speed (internal).\n\n  It's normal not to feel how stiffness and damping affect your spring; use [Spring Parameters Chooser](http://chenglou.github.io/react-motion/demos/demo5-spring-parameters-chooser) to get a feeling. **Usually**, you'd just use the list of tasteful stiffness/damping presets below.\n\n##### - Presets for `{stiffness, damping}`\nCommonly used spring configurations used like so: `spring(10, presets.wobbly)` or `spring(20, {...presets.gentle, precision: 0.1})`. [See here](https://github.com/chenglou/react-motion/blob/9cb90eca20ecf56e77feb816d101a4a9110c7d70/src/presets.js).\n\n---\n\n### &lt;Motion />\n#### Usage\n```jsx\n<Motion defaultStyle={{x: 0}} style={{x: spring(10)}}>\n  {interpolatingStyle => <div style={interpolatingStyle} />}\n</Motion>\n```\n\n#### Props\n\n##### - style: Style\n\nRequired. The `Style` type is an object that maps to either a `number` or an `OpaqueConfig` returned by `spring()` above. Must keep the same keys throughout component's existence. The meaning of the values:\n\n- an `OpaqueConfig` returned from `spring(x)`: interpolate to `x`.\n- a `number` `x`: jump to `x`, do not interpolate.\n\n##### - defaultStyle?: PlainStyle\nOptional. The `PlainStyle` type maps to `number`s. Defaults to an object with the same keys as `style` above, whose values are the initial numbers you're interpolating on. **Note that during subsequent renders, this prop is ignored. The values will interpolate from the current ones to the destination ones (specified by `style`)**.\n\n##### - children: (interpolatedStyle: PlainStyle) => ReactElement\nRequired **function**.\n\n- `interpolatedStyle`: the interpolated style object passed back to you. E.g. if you gave `style={{x: spring(10), y: spring(20)}}`, you'll receive as `interpolatedStyle`, at a certain time, `{x: 5.2, y: 12.1}`, which you can then apply on your `div` or something else.\n\n- Return: must return **one** React element to render.\n\n##### - onRest?: () => void\nOptional. The callback that fires when the animation comes to a rest.\n\n---\n\n### &lt;StaggeredMotion />\nAnimates a collection of (**fixed length**) items whose values depend on each other, creating a natural, springy, \"staggering\" effect [like so](http://chenglou.github.io/react-motion/demos/demo1-chat-heads). This is preferred over hard-coding a delay for an array of `Motions` to achieve a similar (but less natural-looking) effect.\n\n#### Usage\n```jsx\n<StaggeredMotion\n  defaultStyles={[{h: 0}, {h: 0}, {h: 0}]}\n  styles={prevInterpolatedStyles => prevInterpolatedStyles.map((_, i) => {\n    return i === 0\n      ? {h: spring(100)}\n      : {h: spring(prevInterpolatedStyles[i - 1].h)}\n  })}>\n  {interpolatingStyles =>\n    <div>\n      {interpolatingStyles.map((style, i) =>\n        <div key={i} style={{border: '1px solid', height: style.h}} />)\n      }\n    </div>\n  }\n</StaggeredMotion>\n```\n\nAka \"the current spring's destination value is the interpolating value of the previous spring\". Imagine a spring dragging another. Physics, it works!\n\n#### Props\n\n##### - styles: (previousInterpolatedStyles: ?Array&lt;PlainStyle>) => Array&lt;Style>\nRequired **function**. **Don't forget the \"s\"**!\n\n- `previousInterpolatedStyles`: the previously interpolating (array of) styles (`undefined` at first render, unless `defaultStyles` is provided).\n\n- Return: must return an array of `Style`s containing the destination values, e.g. `[{x: spring(10)}, {x: spring(20)}]`.\n\n##### - defaultStyles?: Array&lt;PlainStyle>\nOptional. Similar to `Motion`'s `defaultStyle`, but an array of them.\n\n##### - children: (interpolatedStyles: Array&lt;PlainStyle>) => ReactElement\nRequired **function**. Similar to `Motion`'s `children`, but accepts the array of interpolated styles instead, e.g. `[{x: 5}, {x: 6.4}, {x: 8.1}]`\n\n(No `onRest` for StaggeredMotion because we haven't found a good semantics for it yet. Voice your support in the issues section.)\n\n---\n\n### &lt;TransitionMotion />\n**Helps you to do mounting and unmounting animation**.\n\n#### Usage\n\nYou have items `a`, `b`, `c`, with their respective style configuration, given to `TransitionMotion`'s `styles`. In its `children` function, you're passed the three interpolated styles as params; you map over them and produce three components. All is good.\n\nDuring next render, you give only `a` and `b`, indicating that you want `c` gone, but that you'd like to animate it reaching value `0`, before killing it for good.\n\nFortunately, `TransitionMotion` has kept `c` around and still passes it into the `children` function param. So when you're mapping over these three interpolated styles, you're still producing three components. It'll keep interpolating, while checking `c`'s current value at every frame. Once `c` reaches the specified `0`, `TransitionMotion` will remove it for good (from the interpolated styles passed to your `children` function).\n\nThis time, when mapping through the two remaining interpolated styles, you'll produce only two components. `c` is gone for real.\n\n```jsx\nimport createReactClass from 'create-react-class';\n\nconst Demo = createReactClass({\n  getInitialState() {\n    return {\n      items: [{key: 'a', size: 10}, {key: 'b', size: 20}, {key: 'c', size: 30}],\n    };\n  },\n  componentDidMount() {\n    this.setState({\n      items: [{key: 'a', size: 10}, {key: 'b', size: 20}], // remove c.\n    });\n  },\n  willLeave() {\n    // triggered when c's gone. Keeping c until its width/height reach 0.\n    return {width: spring(0), height: spring(0)};\n  },\n  render() {\n    return (\n      <TransitionMotion\n        willLeave={this.willLeave}\n        styles={this.state.items.map(item => ({\n          key: item.key,\n          style: {width: item.size, height: item.size},\n        }))}>\n        {interpolatedStyles =>\n          // first render: a, b, c. Second: still a, b, c! Only last one's a, b.\n          <div>\n            {interpolatedStyles.map(config => {\n              return <div key={config.key} style={{...config.style, border: '1px solid'}} />\n            })}\n          </div>\n        }\n      </TransitionMotion>\n    );\n  },\n});\n```\n\n#### Props\n\nFirst, two type definitions to ease the comprehension.\n\n- `TransitionStyle`: an object of the format `{key: string, data?: any, style: Style}`.\n\n  - `key`: required. The ID that `TransitionMotion` uses to track which configuration is which across renders, even when things are reordered. Typically reused as the component `key` when you map over the interpolated styles.\n\n  - `data`: optional. Anything you'd like to carry along. This is so that when the previous section example's `c` disappears, you still get to access `c`'s related data, such as the text to display along with it.\n\n  - `style`: required. The actual starting style configuration, similar to what you provide for `Motion`'s `style`. Maps keys to either a number or an `OpaqueConfig` returned by `spring()`.\n\n- `TransitionPlainStyle`: similar to above, except the `style` field's value is of type `PlainStyle`, aka an object that maps to numbers.\n\n##### - styles: Array&lt;TransitionStyle> | (previousInterpolatedStyles: ?Array&lt;TransitionPlainStyle>) => Array&lt;TransitionStyle>\nRequired. Accepts either:\n\n  - an array of `TransitionStyle` configs, e.g. `[{key: 'a', style: {x: spring(0)}}, {key: 'b', style: {x: spring(10)}}]`.\n\n  - a function similar to `StaggeredMotion`, taking the previously interpolating styles (`undefined` at first call, unless `defaultStyles` is provided), and returning the previously mentioned array of configs. __You can do staggered mounting animation with this__.\n\n##### - defaultStyles?: Array&lt;TransitionPlainStyle>\nOptional. Similar to the other components' `defaultStyle`/`defaultStyles`.\n\n##### - children: (interpolatedStyles: Array&lt;TransitionPlainStyle>) => ReactElement\nRequired **function**. Similar to other two components' `children`. Receive back an array similar to what you provided for `defaultStyles`, only that each `style` object's number value represent the currently interpolating value.\n\n##### - willLeave?: (styleThatLeft: TransitionStyle) => ?Style\nOptional. Defaults to `() => null`. **The magic sauce property**.\n\n- `styleThatLeft`: the e.g. `{key: ..., data: ..., style: ...}` object from the `styles` array, identified by `key`, that was present during a previous render, and that is now absent, thus triggering the call to `willLeave`. Note that the style property is exactly what you passed in `styles`, and is not interpolated. For example, if you passed a spring for `x` you will receive an object like `{x: {stiffness, damping, val, precision}}`.\n\n- Return: `null` to indicate you want the `TransitionStyle` gone immediately. A `Style` object to indicate you want to reach transition to the specified value(s) before killing the `TransitionStyle`.\n\n##### - didLeave?: (styleThatLeft: `{key: string, data?: any}`) => void\nOptional. Defaults to `() => {}`.\n\n- `styleThatLeft`: the `{key:..., data:...}` that was removed after the finished transition.\n\n##### - willEnter?: (styleThatEntered: TransitionStyle) => PlainStyle\nOptional. Defaults to `styleThatEntered => stripStyle(styleThatEntered.style)`. Where `stripStyle` turns `{x: spring(10), y: spring(20)}` into `{x: 10, y: 20}`.\n\n- `styleThatEntered`: similar to `willLeave`'s, except the `TransitionStyle` represents the object whose `key` value was absent during the last `render`, and that is now present.\n\n- Return: a `defaultStyle`-like `PlainStyle` configuration, e.g. `{x: 0, y: 0}`, that serves as the starting values of the animation. Under this light, the default provided means \"a style config that has the same starting values as the destination values\".\n\n**Note** that `willEnter` and `defaultStyles` serve different purposes. `willEnter` only triggers when a previously inexistent `TransitionStyle` inside `styles` comes into the new render.\n\n(No `onRest` for TransitionMotion because we haven't found a good semantics for it yet. Voice your support in the issues section.)\n\n---\n\n## FAQ\n\n- How do I set the duration of my animation?\n\n[Hard-coded duration goes against fluid interfaces](https://twitter.com/andy_matuschak/status/566736015188963328). If your animation is interrupted mid-way, you'd get a weird completion animation if you hard-coded the time. That being said, in the demo section there's a great [Spring Parameters Chooser](http://chenglou.github.io/react-motion/demos/demo5-spring-parameters-chooser) for you to have a feel of what spring is appropriate, rather than guessing a duration in the dark.\n\n- How do I unmount the `TransitionMotion` container itself?\n\nYou don't. Unless you put it in another `TransitionMotion`...\n\n- How do I do staggering/chained animation where items animate in one after another?\n\nSee [`StaggeredMotion`](#staggeredmotion-)\n\n- My `ref` doesn't work in the children function.\n\nReact string refs won't work:\n\n```jsx\n<Motion style={...}>{currentValue => <div ref=\"stuff\" />}</Motion>\n```\n\nThis is how React works. Here's the [callback ref solution](https://reactjs.org/docs/refs-and-the-dom.html#callback-refs).\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"react-motion\",\n  \"version\": \"0.5.1\",\n  \"homepage\": \"https://github.com/chenglou/react-motion\",\n  \"authors\": [\n    \"chenglou\"\n  ],\n  \"description\": \"A spring that solves your animation problems.\",\n  \"main\": [\n    \"build/react-motion.js\",\n    \"build/react-motion.map\"\n  ],\n  \"dependencies\": {\n    \"react\": \"^0.14.9 || ^15.3.0\"\n  },\n  \"keywords\": [\n    \"react\",\n    \"component\",\n    \"react-component\",\n    \"transitiongroup\",\n    \"spring\",\n    \"tween\",\n    \"motion\",\n    \"animation\",\n    \"transition\",\n    \"ui\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"test\",\n    \"demo*\",\n    \"server.js\",\n    \"src\",\n    \"webpack.config.js\",\n    \"webpack.prod.config.js\",\n    \"karma.conf.js\",\n    \"package.json\"\n  ]\n}\n"
  },
  {
    "path": "demos/README.md",
    "content": "## Demos folder\n\n**Note**: since this is the master branch, the demos might be a bit ahead of the current stable API. [This commit](https://github.com/chenglou/react-motion/tree/0627243316c564f6c2f480bf615b82135f649a0a/demos) contains the stable demos.\n"
  },
  {
    "path": "demos/demo0-simple-transition/Demo.jsx",
    "content": "import React from 'react';\nimport {Motion, spring} from '../../src/react-motion';\n\nexport default class Demo extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {open: false};\n  };\n\n  handleMouseDown = () => {\n    this.setState({open: !this.state.open});\n  };\n\n  handleTouchStart = (e) => {\n    e.preventDefault();\n    this.handleMouseDown();\n  };\n\n  render() {\n    return (\n      <div>\n        <button\n          onMouseDown={this.handleMouseDown}\n          onTouchStart={this.handleTouchStart}>\n          Toggle\n        </button>\n\n        <Motion style={{x: spring(this.state.open ? 400 : 0)}}>\n          {({x}) =>\n            // children is a callback which should accept the current value of\n            // `style`\n            <div className=\"demo0\">\n              <div className=\"demo0-block\" style={{\n                WebkitTransform: `translate3d(${x}px, 0, 0)`,\n                transform: `translate3d(${x}px, 0, 0)`,\n              }} />\n            </div>\n          }\n        </Motion>\n      </div>\n    );\n  };\n}\n"
  },
  {
    "path": "demos/demo0-simple-transition/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Toggle</title>\n  <style>\n  .demo0 {\n    border-radius: 4px;\n    background-color: rgb(240, 240, 232);\n    position: relative;\n    margin: 5px 3px 10px;\n    width: 450px;\n    height: 50px;\n  }\n  .demo0-block {\n    position: absolute;\n    width: 50px;\n    height: 50px;\n    border-radius: 4px;\n    background-color: rgb(130, 181, 198);\n  }\n  </style>\n</head>\n<body>\n\n<div id=\"content\"></div>\n\n<script src=\"./all.js\"></script>\n\n</body>\n</html>\n"
  },
  {
    "path": "demos/demo0-simple-transition/index.jsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport Demo from './Demo';\n\nReactDOM.render(<Demo />, document.querySelector('#content'));\n"
  },
  {
    "path": "demos/demo1-chat-heads/Demo.jsx",
    "content": "import React from 'react';\nimport {StaggeredMotion, spring, presets} from '../../src/react-motion';\nimport range from 'lodash.range';\n\nexport default class Demo extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {x: 250, y: 300};\n  };\n\n  componentDidMount() {\n    window.addEventListener('mousemove', this.handleMouseMove);\n    window.addEventListener('touchmove', this.handleTouchMove);\n  };\n\n  handleMouseMove = ({pageX: x, pageY: y}) => {\n    this.setState({x, y});\n  };\n\n  handleTouchMove = ({touches}) => {\n    this.handleMouseMove(touches[0]);\n  };\n\n  getStyles = (prevStyles) => {\n    // `prevStyles` is the interpolated value of the last tick\n    const endValue = prevStyles.map((_, i) => {\n      return i === 0\n        ? this.state\n        : {\n          x: spring(prevStyles[i - 1].x, presets.gentle),\n          y: spring(prevStyles[i - 1].y, presets.gentle),\n        };\n    });\n    return endValue;\n  };\n\n  render() {\n    return (\n      <StaggeredMotion\n        defaultStyles={range(6).map(() => ({x: 0, y: 0}))}\n        styles={this.getStyles}>\n        {balls =>\n          <div className=\"demo1\">\n            {balls.map(({x, y}, i) =>\n              <div\n                key={i}\n                className={`demo1-ball ball-${i}`}\n                style={{\n                  WebkitTransform: `translate3d(${x - 25}px, ${y - 25}px, 0)`,\n                  transform: `translate3d(${x - 25}px, ${y - 25}px, 0)`,\n                  zIndex: balls.length - i,\n                }} />\n            )}\n          </div>\n        }\n      </StaggeredMotion>\n    );\n  };\n}\n"
  },
  {
    "path": "demos/demo1-chat-heads/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Chat Heads</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n  <style>\n  * {\n    margin: 0;\n  }\n\n  .demo1 {\n    width: 100%;\n    height: 100%;\n    position: absolute;\n    background: #EEE;\n  }\n\n  .demo1-ball {\n    border-radius: 99px;\n    background-color: white;\n    width: 50px;\n    height: 50px;\n    border: 3px solid white;\n    position: absolute;\n    background-size: 50px;\n  }\n\n  .ball-0 {\n    background-image: url(0.jpg);\n  }\n\n  .ball-1 {\n    background-image: url(1.jpg);\n  }\n\n  .ball-2 {\n    background-image: url(2.jpg);\n  }\n\n  .ball-3 {\n    background-image: url(3.jpg);\n  }\n\n  .ball-4 {\n    background-image: url(4.jpg);\n  }\n\n  .ball-5 {\n    background-image: url(5.jpg);\n  }\n  </style>\n</head>\n\n<body>\n  <div id=\"content\"></div>\n  <script src=\"./all.js\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "demos/demo1-chat-heads/index.jsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport Demo from './Demo';\n\nReactDOM.render(<Demo />, document.querySelector('#content'));\n"
  },
  {
    "path": "demos/demo2-draggable-balls/Demo.jsx",
    "content": "import React from 'react';\nimport {Motion, spring} from '../../src/react-motion';\nimport range from 'lodash.range';\n\nconst springSetting1 = {stiffness: 180, damping: 10};\nconst springSetting2 = {stiffness: 120, damping: 17};\nfunction reinsert(arr, from, to) {\n  const _arr = arr.slice(0);\n  const val = _arr[from];\n  _arr.splice(from, 1);\n  _arr.splice(to, 0, val);\n  return _arr;\n}\n\nfunction clamp(n, min, max) {\n  return Math.max(Math.min(n, max), min);\n}\n\nconst allColors = [\n  '#EF767A', '#456990', '#49BEAA', '#49DCB1', '#EEB868', '#EF767A', '#456990',\n  '#49BEAA', '#49DCB1', '#EEB868', '#EF767A',\n];\nconst [count, width, height] = [11, 70, 90];\n// indexed by visual position\nconst layout = range(count).map(n => {\n  const row = Math.floor(n / 3);\n  const col = n % 3;\n  return [width * col, height * row];\n});\n\nexport default class Demo extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      mouseXY: [0, 0],\n      mouseCircleDelta: [0, 0], // difference between mouse and circle pos for x + y coords, for dragging\n      lastPress: null, // key of the last pressed component\n      isPressed: false,\n      order: range(count), // index: visual position. value: component key/id\n    };\n  };\n\n  componentDidMount() {\n    window.addEventListener('touchmove', this.handleTouchMove);\n    window.addEventListener('touchend', this.handleMouseUp);\n    window.addEventListener('mousemove', this.handleMouseMove);\n    window.addEventListener('mouseup', this.handleMouseUp);\n  };\n\n  handleTouchStart = (key, pressLocation, e) => {\n    this.handleMouseDown(key, pressLocation, e.touches[0]);\n  };\n\n  handleTouchMove = (e) => {\n    e.preventDefault();\n    this.handleMouseMove(e.touches[0]);\n  };\n\n  handleMouseMove = ({pageX, pageY}) => {\n    const {order, lastPress, isPressed, mouseCircleDelta: [dx, dy]} = this.state;\n    if (isPressed) {\n      const mouseXY = [pageX - dx, pageY - dy];\n      const col = clamp(Math.floor(mouseXY[0] / width), 0, 2);\n      const row = clamp(Math.floor(mouseXY[1] / height), 0, Math.floor(count / 3));\n      const index = row * 3 + col;\n      const newOrder = reinsert(order, order.indexOf(lastPress), index);\n      this.setState({mouseXY, order: newOrder});\n    }\n  };\n\n  handleMouseDown = (key, [pressX, pressY], {pageX, pageY}) => {\n    this.setState({\n      lastPress: key,\n      isPressed: true,\n      mouseCircleDelta: [pageX - pressX, pageY - pressY],\n      mouseXY: [pressX, pressY],\n    });\n  };\n\n  handleMouseUp = () => {\n    this.setState({isPressed: false, mouseCircleDelta: [0, 0]});\n  };\n\n  render() {\n    const {order, lastPress, isPressed, mouseXY} = this.state;\n    return (\n      <div className=\"demo2\">\n        {order.map((_, key) => {\n          let style;\n          let x;\n          let y;\n          const visualPosition = order.indexOf(key);\n          if (key === lastPress && isPressed) {\n            [x, y] = mouseXY;\n            style = {\n              translateX: x,\n              translateY: y,\n              scale: spring(1.2, springSetting1),\n              boxShadow: spring((x - (3 * width - 50) / 2) / 15, springSetting1),\n            };\n          } else {\n            [x, y] = layout[visualPosition];\n            style = {\n              translateX: spring(x, springSetting2),\n              translateY: spring(y, springSetting2),\n              scale: spring(1, springSetting1),\n              boxShadow: spring((x - (3 * width - 50) / 2) / 15, springSetting1),\n            };\n          }\n          return (\n            <Motion key={key} style={style}>\n              {({translateX, translateY, scale, boxShadow}) =>\n                <div\n                  onMouseDown={this.handleMouseDown.bind(null, key, [x, y])}\n                  onTouchStart={this.handleTouchStart.bind(null, key, [x, y])}\n                  className=\"demo2-ball\"\n                  style={{\n                    backgroundColor: allColors[key],\n                    WebkitTransform: `translate3d(${translateX}px, ${translateY}px, 0) scale(${scale})`,\n                    transform: `translate3d(${translateX}px, ${translateY}px, 0) scale(${scale})`,\n                    zIndex: key === lastPress ? 99 : visualPosition,\n                    boxShadow: `${boxShadow}px 5px 5px rgba(0,0,0,0.5)`,\n                  }}\n                />\n              }\n            </Motion>\n          );\n        })}\n      </div>\n    );\n  };\n}\n"
  },
  {
    "path": "demos/demo2-draggable-balls/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Grid of Balls</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <style>\n  * {\n    padding: 0;\n    margin: 0;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    user-select: none;\n  }\n\n  .demo2-outer {\n    height: 100%;\n    width: 100%;\n    position: absolute;\n    background-color: #EEE;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    display: -webkit-flex;\n    -webkit-justify-content: center;\n    -webkit-align-items: center;\n  }\n\n  .demo2 {\n    width: 190px;\n    height: 320px;\n  }\n\n  .demo2-ball {\n    position: absolute;\n    border: 1px solid black;\n    border-radius: 99px;\n    width: 50px;\n    height: 50px;\n  }\n  </style>\n</head>\n\n<body>\n  <div class=\"demo2-outer\">\n    <div id=\"content\"></div>\n  </div>\n  <script src=\"./all.js\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "demos/demo2-draggable-balls/index.jsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport Demo from './Demo';\n\nReactDOM.render(<Demo />, document.querySelector('#content'));\n"
  },
  {
    "path": "demos/demo3-todomvc-list-transition/Demo.jsx",
    "content": "import React from 'react';\nimport {TransitionMotion, spring, presets} from '../../src/react-motion';\n\nexport default class Demo extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      todos: [\n        // key is creation date\n        {key: 't1', data: {text: 'Board the plane', isDone: false}},\n        {key: 't2', data: {text: 'Sleep', isDone: false}},\n        {key: 't3', data: {text: 'Try to finish conference slides', isDone: false}},\n        {key: 't4', data: {text: 'Eat cheese and drink wine', isDone: false}},\n        {key: 't5', data: {text: 'Go around in Uber', isDone: false}},\n        {key: 't6', data: {text: 'Talk with conf attendees', isDone: false}},\n        {key: 't7', data: {text: 'Show Demo 1', isDone: false}},\n        {key: 't8', data: {text: 'Show Demo 2', isDone: false}},\n        {key: 't9', data: {text: 'Lament about the state of animation', isDone: false}},\n        {key: 't10', data: {text: 'Show Secret Demo', isDone: false}},\n        {key: 't11', data: {text: 'Go home', isDone: false}},\n      ],\n      value: '',\n      selected: 'all',\n    };\n  };\n\n  // logic from todo, unrelated to animation\n  handleChange = ({target: {value}}) => {\n    this.setState({value});\n  };\n\n  handleSubmit = (e) => {\n    e.preventDefault();\n    const newItem = {\n      key: 't' + Date.now(),\n      data: {text: this.state.value, isDone: false},\n    };\n    // append at head\n    this.setState({todos: [newItem].concat(this.state.todos)});\n  };\n\n  handleDone = (doneKey) => {\n    this.setState({\n      todos: this.state.todos.map(todo => {\n        const {key, data: {text, isDone}} = todo;\n        return key === doneKey\n          ? {key: key, data: {text: text, isDone: !isDone}}\n          : todo;\n      }),\n    });\n  };\n\n  handleToggleAll = () => {\n    const allNotDone = this.state.todos.every(({data}) => data.isDone);\n    this.setState({\n      todos: this.state.todos.map(({key, data: {text, isDone}}) => (\n        {key: key, data: {text: text, isDone: !allNotDone}}\n      )),\n    });\n  };\n\n  handleSelect = (selected) => {\n    this.setState({selected});\n  };\n\n  handleClearCompleted = () => {\n    this.setState({todos: this.state.todos.filter(({data}) => !data.isDone)});\n  };\n\n  handleDestroy = (date) => {\n    this.setState({todos: this.state.todos.filter(({key}) => key !== date)});\n  };\n\n  // actual animation-related logic\n  getDefaultStyles = () => {\n    return this.state.todos.map(todo => ({...todo, style: {height: 0, opacity: 1}}));\n  };\n\n  getStyles = () => {\n    const {todos, value, selected} = this.state;\n    return todos.filter(({data: {isDone, text}}) => {\n      return text.toUpperCase().indexOf(value.toUpperCase()) >= 0 &&\n        (selected === 'completed' && isDone ||\n        selected === 'active' && !isDone ||\n        selected === 'all');\n    })\n    .map((todo, i) => {\n      return {\n        ...todo,\n        style: {\n          height: spring(60, presets.gentle),\n          opacity: spring(1, presets.gentle),\n        }\n      };\n    });\n  };\n\n  willEnter() {\n    return {\n      height: 0,\n      opacity: 1,\n    };\n  };\n\n  willLeave() {\n    return {\n      height: spring(0),\n      opacity: spring(0),\n    };\n  };\n\n  render() {\n    const {todos, value, selected} = this.state;\n    const itemsLeft = todos.filter(({data: {isDone}}) => !isDone).length;\n    return (\n      <section className=\"todoapp\">\n        <header className=\"header\">\n          <h1>todos</h1>\n          <form onSubmit={this.handleSubmit}>\n            <input\n              autoFocus={true}\n              className=\"new-todo\"\n              placeholder=\"What needs to be done?\"\n              value={value}\n              onChange={this.handleChange}\n            />\n          </form>\n        </header>\n        <section className=\"main\">\n          <input\n            className=\"toggle-all\"\n            type=\"checkbox\"\n            checked={itemsLeft === 0} style={{display: todos.length === 0 ? 'none' : 'inline'}}\n            onChange={this.handleToggleAll} />\n          <TransitionMotion\n            defaultStyles={this.getDefaultStyles()}\n            styles={this.getStyles()}\n            willLeave={this.willLeave}\n            willEnter={this.willEnter}>\n            {styles =>\n              <ul className=\"todo-list\">\n                {styles.map(({key, style, data: {isDone, text}}) =>\n                  <li key={key} style={style} className={isDone ? 'completed' : ''}>\n                    <div className=\"view\">\n                      <input\n                        className=\"toggle\"\n                        type=\"checkbox\"\n                        onChange={this.handleDone.bind(null, key)}\n                        checked={isDone}\n                      />\n                      <label>{text}</label>\n                      <button\n                        className=\"destroy\"\n                        onClick={this.handleDestroy.bind(null, key)}\n                      />\n                    </div>\n                  </li>\n                )}\n              </ul>\n            }\n          </TransitionMotion>\n        </section>\n        <footer className=\"footer\">\n          <span className=\"todo-count\">\n            <strong>\n              {itemsLeft}\n            </strong> {itemsLeft === 1 ? 'item' : 'items'} left\n          </span>\n          <ul className=\"filters\">\n            <li>\n              <a\n                className={selected === 'all' ? 'selected' : ''}\n                onClick={this.handleSelect.bind(null, 'all')}>\n                All\n              </a>\n            </li>\n            <li>\n              <a\n                className={selected === 'active' ? 'selected' : ''}\n                onClick={this.handleSelect.bind(null, 'active')}>\n                Active\n              </a>\n            </li>\n            <li>\n              <a\n                className={selected === 'completed' ? 'selected' : ''}\n                onClick={this.handleSelect.bind(null, 'completed')}>\n                Completed\n              </a>\n            </li>\n          </ul>\n          <button className=\"clear-completed\" onClick={this.handleClearCompleted}>\n            Clear completed\n          </button>\n        </footer>\n      </section>\n    );\n  };\n}\n"
  },
  {
    "path": "demos/demo3-todomvc-list-transition/index.css",
    "content": "hr {\n  margin: 20px 0;\n  border: 0;\n  border-top: 1px dashed #c5c5c5;\n  border-bottom: 1px dashed #f7f7f7;\n}\n\n.learn a {\n  font-weight: normal;\n  text-decoration: none;\n  color: #b83f45;\n}\n\n.learn a:hover {\n  text-decoration: underline;\n  color: #787e7e;\n}\n\n.learn h3,\n.learn h4,\n.learn h5 {\n  margin: 10px 0;\n  font-weight: 500;\n  line-height: 1.2;\n  color: #000;\n}\n\n.learn h3 {\n  font-size: 24px;\n}\n\n.learn h4 {\n  font-size: 18px;\n}\n\n.learn h5 {\n  margin-bottom: 0;\n  font-size: 14px;\n}\n\n.learn ul {\n  padding: 0;\n  margin: 0 0 30px 25px;\n}\n\n.learn li {\n  line-height: 20px;\n}\n\n.learn p {\n  font-size: 15px;\n  font-weight: 300;\n  line-height: 1.3;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n\n#issue-count {\n  display: none;\n}\n\n.quote {\n  border: none;\n  margin: 20px 0 60px 0;\n}\n\n.quote p {\n  font-style: italic;\n}\n\n.quote p:before {\n  content: '“';\n  font-size: 50px;\n  opacity: .15;\n  position: absolute;\n  top: -20px;\n  left: 3px;\n}\n\n.quote p:after {\n  content: '”';\n  font-size: 50px;\n  opacity: .15;\n  position: absolute;\n  bottom: -42px;\n  right: 3px;\n}\n\n.quote footer {\n  position: absolute;\n  bottom: -40px;\n  right: 0;\n}\n\n.quote footer img {\n  border-radius: 3px;\n}\n\n.quote footer a {\n  margin-left: 5px;\n  vertical-align: middle;\n}\n\n.speech-bubble {\n  position: relative;\n  padding: 10px;\n  background: rgba(0, 0, 0, .04);\n  border-radius: 5px;\n}\n\n.speech-bubble:after {\n  content: '';\n  position: absolute;\n  top: 100%;\n  right: 30px;\n  border: 13px solid transparent;\n  border-top-color: rgba(0, 0, 0, .04);\n}\n\n.learn-bar > .learn {\n  position: absolute;\n  width: 272px;\n  top: 8px;\n  left: -300px;\n  padding: 10px;\n  border-radius: 5px;\n  background-color: rgba(255, 255, 255, .6);\n  transition-property: left;\n  transition-duration: 500ms;\n}\n\n@media (min-width: 899px) {\n  .learn-bar {\n    width: auto;\n    padding-left: 300px;\n  }\n\n  .learn-bar > .learn {\n    left: 8px;\n  }\n}\n\nhtml,\nbody {\n  margin: 0;\n  padding: 0;\n}\n\nbutton {\n  margin: 0;\n  padding: 0;\n  border: 0;\n  background: none;\n  font-size: 100%;\n  vertical-align: baseline;\n  font-family: inherit;\n  font-weight: inherit;\n  color: inherit;\n  -webkit-appearance: none;\n  appearance: none;\n  -webkit-font-smoothing: antialiased;\n  -moz-font-smoothing: antialiased;\n  font-smoothing: antialiased;\n}\n\nbody {\n  font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;\n  line-height: 1.4em;\n  background: #f5f5f5;\n  color: #4d4d4d;\n  min-width: 230px;\n  max-width: 550px;\n  margin: 0 auto;\n  -webkit-font-smoothing: antialiased;\n  -moz-font-smoothing: antialiased;\n  font-smoothing: antialiased;\n  font-weight: 300;\n}\n\nbutton,\ninput[type=\"checkbox\"] {\n  outline: none;\n}\n\n.hidden {\n  display: none;\n}\n\n.todoapp {\n  background: #fff;\n  margin: 130px 0 40px 0;\n  position: relative;\n  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),\n              0 25px 50px 0 rgba(0, 0, 0, 0.1);\n}\n\n.todoapp input::-webkit-input-placeholder {\n  font-style: italic;\n  font-weight: 300;\n  color: #e6e6e6;\n}\n\n.todoapp input::-moz-placeholder {\n  font-style: italic;\n  font-weight: 300;\n  color: #e6e6e6;\n}\n\n.todoapp input::input-placeholder {\n  font-style: italic;\n  font-weight: 300;\n  color: #e6e6e6;\n}\n\n.todoapp h1 {\n  position: absolute;\n  top: -155px;\n  width: 100%;\n  font-size: 100px;\n  font-weight: 100;\n  text-align: center;\n  color: rgba(175, 47, 47, 0.15);\n  -webkit-text-rendering: optimizeLegibility;\n  -moz-text-rendering: optimizeLegibility;\n  text-rendering: optimizeLegibility;\n}\n\n.new-todo,\n.edit {\n  position: relative;\n  margin: 0;\n  width: 100%;\n  font-size: 24px;\n  font-family: inherit;\n  font-weight: inherit;\n  line-height: 1.4em;\n  border: 0;\n  outline: none;\n  color: inherit;\n  padding: 6px;\n  border: 1px solid #999;\n  box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);\n  box-sizing: border-box;\n  -webkit-font-smoothing: antialiased;\n  -moz-font-smoothing: antialiased;\n  font-smoothing: antialiased;\n}\n\n.new-todo {\n  padding: 16px 16px 16px 60px;\n  border: none;\n  background: rgba(0, 0, 0, 0.003);\n  box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);\n}\n\n.main {\n  position: relative;\n  z-index: 2;\n  border-top: 1px solid #e6e6e6;\n}\n\nlabel[for='toggle-all'] {\n  display: none;\n}\n\n.toggle-all {\n  position: absolute;\n  top: -55px;\n  left: -12px;\n  width: 60px;\n  height: 34px;\n  text-align: center;\n  border: none; /* Mobile Safari */\n}\n\n.toggle-all:before {\n  content: '❯';\n  font-size: 22px;\n  color: #e6e6e6;\n  padding: 10px 27px 10px 27px;\n}\n\n.toggle-all:checked:before {\n  color: #737373;\n}\n\n.todo-list {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n}\n\n.todo-list li {\n  position: relative;\n  font-size: 24px;\n  box-shadow: 0 -1px 0 #ededed;\n  overflow: hidden;\n}\n\n.todo-list li:last-child {\n  border-bottom: none;\n}\n\n.todo-list li.editing {\n  border-bottom: none;\n  padding: 0;\n}\n\n.todo-list li.editing .edit {\n  display: block;\n  width: 506px;\n  padding: 13px 17px 12px 17px;\n  margin: 0 0 0 43px;\n}\n\n.todo-list li.editing .view {\n  display: none;\n}\n\n.todo-list li .toggle {\n  text-align: center;\n  width: 40px;\n  /* auto, since non-WebKit browsers doesn't support input styling */\n  height: auto;\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  margin: auto 0;\n  border: none; /* Mobile Safari */\n  -webkit-appearance: none;\n  appearance: none;\n}\n\n.todo-list li .toggle:after {\n  content: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"-10 -18 100 135\"><circle cx=\"50\" cy=\"50\" r=\"50\" fill=\"none\" stroke=\"#ededed\" stroke-width=\"3\"/></svg>');\n}\n\n.todo-list li .toggle:checked:after {\n  content: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"-10 -18 100 135\"><circle cx=\"50\" cy=\"50\" r=\"50\" fill=\"none\" stroke=\"#bddad5\" stroke-width=\"3\"/><path fill=\"#5dc2af\" d=\"M72 25L42 71 27 56l-4 4 20 20 34-52z\"/></svg>');\n}\n\n.todo-list li label {\n  white-space: pre;\n  word-break: break-word;\n  padding: 15px 60px 15px 15px;\n  margin-left: 45px;\n  display: block;\n  line-height: 1.2;\n  transition: color 0.4s;\n}\n\n.todo-list li.completed label {\n  color: #d9d9d9;\n  text-decoration: line-through;\n}\n\n.todo-list li .destroy {\n  display: none;\n  position: absolute;\n  top: 0;\n  right: 10px;\n  bottom: 0;\n  width: 40px;\n  height: 40px;\n  margin: auto 0;\n  font-size: 30px;\n  color: #cc9a9a;\n  margin-bottom: 11px;\n  transition: color 0.2s ease-out;\n}\n\n.todo-list li .destroy:hover {\n  color: #af5b5e;\n}\n\n.todo-list li .destroy:after {\n  content: '×';\n}\n\n.todo-list li:hover .destroy {\n  display: block;\n}\n\n.todo-list li .edit {\n  display: none;\n}\n\n.todo-list li.editing:last-child {\n  margin-bottom: -1px;\n}\n\n.footer {\n  color: #777;\n  padding: 10px 15px;\n  height: 20px;\n  text-align: center;\n  border-top: 1px solid #e6e6e6;\n}\n\n.footer:before {\n  content: '';\n  position: absolute;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  height: 50px;\n  overflow: hidden;\n  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),\n              0 8px 0 -3px #f6f6f6,\n              0 9px 1px -3px rgba(0, 0, 0, 0.2),\n              0 16px 0 -6px #f6f6f6,\n              0 17px 2px -6px rgba(0, 0, 0, 0.2);\n}\n\n.todo-count {\n  float: left;\n  text-align: left;\n}\n\n.todo-count strong {\n  font-weight: 300;\n}\n\n.filters {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n  position: absolute;\n  right: 0;\n  left: 0;\n}\n\n.filters li {\n  display: inline;\n}\n\n.filters li a {\n  color: inherit;\n  margin: 3px;\n  padding: 3px 7px;\n  text-decoration: none;\n  border: 1px solid transparent;\n  border-radius: 3px;\n}\n\n.filters li a.selected,\n.filters li a:hover {\n  border-color: rgba(175, 47, 47, 0.1);\n}\n\n.filters li a.selected {\n  border-color: rgba(175, 47, 47, 0.2);\n}\n\n.clear-completed,\nhtml .clear-completed:active {\n  float: right;\n  position: relative;\n  line-height: 20px;\n  text-decoration: none;\n  cursor: pointer;\n  position: relative;\n}\n\n.clear-completed:hover {\n  text-decoration: underline;\n}\n\n.info {\n  margin: 65px auto 0;\n  color: #bfbfbf;\n  font-size: 10px;\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\n  text-align: center;\n}\n\n.info p {\n  line-height: 1;\n}\n\n.info a {\n  color: inherit;\n  text-decoration: none;\n  font-weight: 400;\n}\n\n.info a:hover {\n  text-decoration: underline;\n}\n\n/*\n  Hack to remove background from Mobile Safari.\n  Can't use it globally since it destroys checkboxes in Firefox\n*/\n@media screen and (-webkit-min-device-pixel-ratio:0) {\n  .toggle-all,\n  .todo-list li .toggle {\n    background: none;\n  }\n\n  .todo-list li .toggle {\n    height: 40px;\n  }\n\n  .toggle-all {\n    -webkit-transform: rotate(90deg);\n    transform: rotate(90deg);\n    -webkit-appearance: none;\n    appearance: none;\n  }\n}\n\n@media (max-width: 430px) {\n  .footer {\n    height: 50px;\n  }\n\n  .filters {\n    bottom: 10px;\n  }\n}"
  },
  {
    "path": "demos/demo3-todomvc-list-transition/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <title>RedoMVC</title>\n  <link rel=\"stylesheet\" href=\"./index.css\" />\n</head>\n\n<body>\n  <div id=\"content\"></div>\n  <script src=\"./all.js\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "demos/demo3-todomvc-list-transition/index.jsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport Demo from './Demo';\n\nReactDOM.render(<Demo />, document.querySelector('#content'));\n"
  },
  {
    "path": "demos/demo4-photo-gallery/Demo.jsx",
    "content": "import React from 'react';\nimport {Motion, spring} from '../../src/react-motion';\n\nconst springSettings = {stiffness: 170, damping: 26};\nconst NEXT = 'show-next';\n\nexport default class Demo extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      photos: [[500, 350], [800, 600], [800, 400], [700, 500], [200, 650], [600, 600]],\n      currPhoto: 0,\n    };\n  };\n\n  handleChange = ({target: {value}}) => {\n    this.setState({currPhoto: value});\n  };\n\n  clickHandler = (btn) => {\n    let photoIndex = btn === NEXT ? this.state.currPhoto+1 : this.state.currPhoto-1;\n\n    photoIndex = photoIndex >= 0 ? photoIndex : this.state.photos.length - 1;\n    photoIndex = photoIndex >= this.state.photos.length ? 0 : photoIndex;\n\n    this.setState({\n      currPhoto: photoIndex\n    })\n  };\n\n  render() {\n    const {photos, currPhoto} = this.state;\n    const [currWidth, currHeight] = photos[currPhoto];\n\n    const widths = photos.map(([origW, origH]) => currHeight / origH * origW);\n\n    const leftStartCoords = widths\n      .slice(0, currPhoto)\n      .reduce((sum, width) => sum - width, 0);\n\n    let configs = [];\n    photos.reduce((prevLeft, [origW, origH], i) => {\n      configs.push({\n        left: spring(prevLeft, springSettings),\n        height: spring(currHeight, springSettings),\n        width: spring(widths[i], springSettings),\n      });\n      return prevLeft + widths[i];\n    }, leftStartCoords);\n\n    return (\n      <div>\n        <div>Scroll Me</div>\n        <button onClick={this.clickHandler.bind(null, '')}>Previous</button>\n        <input\n          type=\"range\"\n          min={0}\n          max={photos.length - 1}\n          value={currPhoto}\n          onChange={this.handleChange} />\n        <button onClick={this.clickHandler.bind(null, NEXT)}>Next</button>\n        <div className=\"demo4\">\n          <Motion style={{height: spring(currHeight), width: spring(currWidth)}}>\n            {container =>\n              <div className=\"demo4-inner\" style={container}>\n                {configs.map((style, i) =>\n                  <Motion key={i} style={style}>\n                    {style =>\n                      <img className=\"demo4-photo\" src={`./${i}.jpg`} style={style} />\n                    }\n                  </Motion>\n                )}\n              </div>\n            }\n          </Motion>\n        </div>\n      </div>\n    );\n  };\n}\n"
  },
  {
    "path": "demos/demo4-photo-gallery/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <title>How Many Demos Do You Need</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <style>\n  .demo4 {\n    display: flex;\n    display: -webkit-flex;\n    align-items: center;\n    height: 700px;\n    position: relative;\n  }\n\n  .demo4-inner {\n    overflow: hidden;\n    position: relative;\n    margin: auto;\n  }\n\n  .demo4-photo {\n    position: absolute;\n    background-color: lightgray;\n  }\n  </style>\n</head>\n\n<body>\n  <div id=\"content\"></div>\n  <script src=\"./all.js\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "demos/demo4-photo-gallery/index.jsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport Demo from './Demo';\n\nReactDOM.render(<Demo />, document.querySelector('#content'));\n"
  },
  {
    "path": "demos/demo5-spring-parameters-chooser/Demo.jsx",
    "content": "import React from 'react';\nimport {Motion, spring} from '../../src/react-motion';\nimport range from 'lodash.range';\n\nconst gridWidth = 150;\nconst gridHeight = 150;\nconst grid = range(4).map(() => range(6));\n\nexport default class Demo extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      delta: [0, 0],\n      mouse: [0, 0],\n      isPressed: false,\n      firstConfig: [60, 5],\n      slider: {dragged: null, num: 0},\n      lastPressed: [0, 0],\n    };\n  };\n\n  componentDidMount() {\n    window.addEventListener('mousemove', this.handleMouseMove);\n    window.addEventListener('touchmove', this.handleTouchMove);\n    window.addEventListener('mouseup', this.handleMouseUp);\n    window.addEventListener('touchend', this.handleMouseUp);\n  };\n\n  handleTouchStart = (pos, press, e) => {\n    this.handleMouseDown(pos, press, e.touches[0]);\n  };\n\n  handleMouseDown = (pos, [pressX, pressY], {pageX, pageY}) => {\n    this.setState({\n      delta: [pageX - pressX, pageY - pressY],\n      mouse: [pressX, pressY],\n      isPressed: true,\n      lastPressed: pos,\n    });\n  };\n\n  handleTouchMove = (e) => {\n    if (this.state.isPressed) {\n      e.preventDefault();\n    }\n    this.handleMouseMove(e.touches[0]);\n  };\n\n  handleMouseMove = ({pageX, pageY}) => {\n    const {isPressed, delta: [dx, dy]} = this.state;\n    if (isPressed) {\n      this.setState({mouse: [pageX - dx, pageY - dy]});\n    }\n  };\n\n  handleMouseUp = () => {\n    this.setState({\n      isPressed: false,\n      delta: [0, 0],\n      slider: {dragged: null, num: 0},\n    });\n  };\n\n  handleChange = (constant, num, {target}) => {\n    const {firstConfig: [s, d]} = this.state;\n    if (constant === 'stiffness') {\n      this.setState({\n        firstConfig: [target.value - num * 30, d],\n      });\n    } else {\n      this.setState({\n        firstConfig: [s, target.value - num * 2],\n      });\n    }\n  };\n\n  handleMouseDownInput = (constant, num) => {\n    this.setState({\n      slider: {dragged: constant, num: num},\n    });\n  };\n\n  render() {\n    const {\n      mouse, isPressed, lastPressed, firstConfig: [s0, d0], slider: {dragged, num},\n    } = this.state;\n    return (\n      <div className=\"demo5\">\n        {grid.map((row, i) => {\n          return row.map((cell, j) => {\n            const cellStyle = {\n              top: gridHeight * i,\n              left: gridWidth * j,\n              width: gridWidth,\n              height: gridHeight,\n            };\n            const stiffness = s0 + i * 30;\n            const damping = d0 + j * 2;\n            const motionStyle = isPressed\n              ? {x: mouse[0], y: mouse[1]}\n              : {\n                  x: spring(gridWidth / 2 - 25, {stiffness, damping}),\n                  y: spring(gridHeight / 2 - 25, {stiffness, damping}),\n                };\n\n            return (\n              <div style={cellStyle} className=\"demo5-cell\">\n                <input\n                  type=\"range\"\n                  min={0}\n                  max={300}\n                  value={stiffness}\n                  onMouseDown={this.handleMouseDownInput.bind(null, 'stiffness', i)}\n                  onChange={this.handleChange.bind(null, 'stiffness', i)} />\n                <input\n                  type=\"range\"\n                  min={0}\n                  max={40}\n                  value={damping}\n                  onMouseDown={this.handleMouseDownInput.bind(null, 'damping', j)}\n                  onChange={this.handleChange.bind(null, 'damping', j)} />\n                <Motion style={motionStyle}>\n                  {({x, y}) => {\n                    let thing;\n                    if (dragged === 'stiffness') {\n                      thing = i < num ? <div className=\"demo5-minus\">-{(num - i) * 30}</div>\n                        : i > num ? <div className=\"demo5-plus\">+{(i - num) * 30}</div>\n                        : <div className=\"demo5-plus\">0</div>;\n                    } else {\n                      thing = j < num ? <div className=\"demo5-minus\">-{(num - j) * 2}</div>\n                        : j > num ? <div className=\"demo5-plus\">+{(j - num) * 2}</div>\n                        : <div className=\"demo5-plus\">0</div>;\n                    }\n                    const active = lastPressed[0] === i && lastPressed[1] === j\n                      ? 'demo5-ball-active'\n                      : '';\n                    return (\n                      <div\n                        style={{\n                          transform: `translate3d(${x}px, ${y}px, 0)`,\n                          WebkitTransform: `translate3d(${x}px, ${y}px, 0)`,\n                        }}\n                        className={'demo5-ball ' + active}\n                        onMouseDown={this.handleMouseDown.bind(null, [i, j], [x, y])}\n                        onTouchStart={this.handleTouchStart.bind(null, [i, j], [x, y])}>\n                        <div className=\"demo5-preset\">\n                          {stiffness}{dragged === 'stiffness' && thing}\n                        </div>\n                        <div className=\"demo5-preset\">\n                          {damping}{dragged === 'damping' && thing}\n                        </div>\n                      </div>\n                    );\n                  }}\n                </Motion>\n              </div>\n            );\n          });\n        })}\n      </div>\n    );\n  };\n}\n"
  },
  {
    "path": "demos/demo5-spring-parameters-chooser/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Choose your weapon</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <style>\n  * {\n    padding: 0;\n    margin: 0;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    user-select: none;\n  }\n\n  body {\n    background-color: #FFFFFF;\n    font-family: \"HelveticaNeue-Light\", \"Helvetica Neue Light\", \"Helvetica Neue\", Helvetica, Arial, \"Lucida Grande\", sans-serif;\n    font-weight: 300;\n  }\n\n  h3 {\n    margin: 5px 0 16px;\n    font-size: 13px;\n  }\n\n  .demo5-outer {\n    position: absolute;\n    width: 100%;\n    height: 100%;\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    align-items: center;\n    display: -webkit-flex;\n    -webkit-flex-direction: column;\n    -webkit-justify-content: center;\n    -webkit-align-items: center;\n  }\n\n  .demo5 {\n    width: 900px;\n    height: 600px;\n    position: relative;\n  }\n\n  .demo5-cell {\n    position: absolute;\n    border: 1px solid #E4E4E4;\n    display: flex;\n    flex-wrap: wrap;\n    align-content: flex-start;\n    justify-content: center;\n    display: -webkit-flex;\n    -webkit-flex-wrap: wrap;\n    -webkit-align-content: flex-start;\n    -webkit-justify-content: center;\n    padding: 6px;\n    box-sizing: border-box;\n  }\n\n  .demo5-cell input {\n    visibility: hidden;\n    cursor: ew-resize;\n  }\n\n  .demo5-cell:hover input {\n    visibility: visible;\n  }\n\n  .demo5-ball {\n    width: 50px;\n    height: 50px;\n    border-radius: 99px;\n    position: absolute;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    flex-direction: column;\n    display: -webkit-flex;\n    -webkit-justify-content: center;\n    -webkit-align-items: center;\n    -webkit-flex-direction: column;\n    top: 0;\n    left: 0;\n    cursor: pointer;\n    font-size: 12px;\n    background-color: #FDC3C3;\n    z-index: 1;\n  }\n\n  .demo5-ball-active {\n    background-color: #FF8585;\n  }\n\n  .demo5-minus {\n    padding-left: 4px;\n    color: #CC2E2E;\n  }\n\n  .demo5-plus {\n    padding-left: 4px;\n    color: #39A11E;\n  }\n\n  .demo5-preset {\n    display: flex;\n    justify-content: space-around;\n    display: -webkit-flex;\n    -webkit-justify-content: space-around;\n    padding: 0 2px 0 2px;\n  }\n  </style>\n</head>\n\n<body>\n  <div class=\"demo5-outer\">\n    <div>Default: {stiffness: 170, damping: 26}</div>\n    <h3>Drag a circle to see the differences in animation behavior</h3>\n    <div id=\"content\"></div>\n  </div>\n  <script src=\"./all.js\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "demos/demo5-spring-parameters-chooser/index.jsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport Demo from './Demo';\n\nReactDOM.render(<Demo />, document.querySelector('#content'));\n"
  },
  {
    "path": "demos/demo7-water-ripples/Demo.jsx",
    "content": "import React from 'react';\nimport {TransitionMotion, spring} from '../../src/react-motion';\n\nconst leavingSpringConfig = {stiffness: 60, damping: 15};\n\nexport default class Demo extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {mouse: [], now: 't' + 0};\n  };\n\n  handleMouseMove = ({pageX, pageY}) => {\n    // Make sure the state is queued and not batched.\n    this.setState(() => {\n      return {\n        mouse: [pageX - 25, pageY - 25],\n        now: 't' + Date.now(),\n      };\n    });\n  };\n\n  handleTouchMove = (e) => {\n    e.preventDefault();\n    this.handleMouseMove(e.touches[0]);\n  };\n\n  willLeave = (styleCell) => {\n    return {\n      ...styleCell.style,\n      opacity: spring(0, leavingSpringConfig),\n      scale: spring(2, leavingSpringConfig),\n    };\n  };\n\n  render() {\n    const {mouse: [mouseX, mouseY], now} = this.state;\n    const styles = mouseX == null ? [] : [{\n      key: now,\n      style: {\n        opacity: spring(1),\n        scale: spring(0),\n        x: spring(mouseX),\n        y: spring(mouseY),\n      }\n    }];\n    return (\n      <TransitionMotion willLeave={this.willLeave} styles={styles}>\n        {circles =>\n          <div\n            onMouseMove={this.handleMouseMove}\n            onTouchMove={this.handleTouchMove}\n            className=\"demo7\">\n            {circles.map(({key, style: {opacity, scale, x, y}}) =>\n              <div\n                key={key}\n                className=\"demo7-ball\"\n                style={{\n                  opacity: opacity,\n                  scale: scale,\n                  transform: `translate3d(${x}px, ${y}px, 0) scale(${scale})`,\n                  WebkitTransform: `translate3d(${x}px, ${y}px, 0) scale(${scale})`,\n                }} />\n            )}\n          </div>\n        }\n      </TransitionMotion>\n    );\n  };\n}\n"
  },
  {
    "path": "demos/demo7-water-ripples/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Ripples</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <style>\n  * {\n    padding: 0;\n    margin: 0;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    user-select: none;\n  }\n\n  .demo7 {\n    background-color: #1B1B1B;\n    position: absolute;\n    width: 100%;\n    height: 100%;\n  }\n\n  .demo7-ball {\n    width: 50px;\n    height: 50px;\n    border-radius: 99px;\n    position: absolute;\n    border: 1px solid lightblue;\n  }\n  </style>\n</head>\n\n<body>\n  <div id=\"content\"></div>\n  <script src=\"./all.js\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "demos/demo7-water-ripples/index.jsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport Demo from './Demo';\n\nReactDOM.render(<Demo />, document.querySelector('#content'));\n"
  },
  {
    "path": "demos/demo8-draggable-list/Demo.jsx",
    "content": "import React from 'react';\nimport {Motion, spring} from '../../src/react-motion';\nimport range from 'lodash.range';\n\nfunction reinsert(arr, from, to) {\n  const _arr = arr.slice(0);\n  const val = _arr[from];\n  _arr.splice(from, 1);\n  _arr.splice(to, 0, val);\n  return _arr;\n}\n\nfunction clamp(n, min, max) {\n  return Math.max(Math.min(n, max), min);\n}\n\nconst springConfig = {stiffness: 300, damping: 50};\nconst itemsCount = 4;\n\nexport default class Demo extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      topDeltaY: 0,\n      mouseY: 0,\n      isPressed: false,\n      originalPosOfLastPressed: 0,\n      order: range(itemsCount),\n    };\n  };\n\n  componentDidMount() {\n    window.addEventListener('touchmove', this.handleTouchMove);\n    window.addEventListener('touchend', this.handleMouseUp);\n    window.addEventListener('mousemove', this.handleMouseMove);\n    window.addEventListener('mouseup', this.handleMouseUp);\n  };\n\n  handleTouchStart = (key, pressLocation, e) => {\n    this.handleMouseDown(key, pressLocation, e.touches[0]);\n  };\n\n  handleTouchMove = (e) => {\n    e.preventDefault();\n    this.handleMouseMove(e.touches[0]);\n  };\n\n  handleMouseDown = (pos, pressY, {pageY}) => {\n    this.setState({\n      topDeltaY: pageY - pressY,\n      mouseY: pressY,\n      isPressed: true,\n      originalPosOfLastPressed: pos,\n    });\n  };\n\n  handleMouseMove = ({pageY}) => {\n    const {isPressed, topDeltaY, order, originalPosOfLastPressed} = this.state;\n\n    if (isPressed) {\n      const mouseY = pageY - topDeltaY;\n      const currentRow = clamp(Math.round(mouseY / 100), 0, itemsCount - 1);\n      let newOrder = order;\n\n      if (currentRow !== order.indexOf(originalPosOfLastPressed)){\n        newOrder = reinsert(order, order.indexOf(originalPosOfLastPressed), currentRow);\n      }\n\n      this.setState({mouseY: mouseY, order: newOrder});\n    }\n  };\n\n  handleMouseUp = () => {\n    this.setState({isPressed: false, topDeltaY: 0});\n  };\n\n  render() {\n    const {mouseY, isPressed, originalPosOfLastPressed, order} = this.state;\n\n    return (\n      <div className=\"demo8\">\n        {range(itemsCount).map(i => {\n          const style = originalPosOfLastPressed === i && isPressed\n            ? {\n                scale: spring(1.1, springConfig),\n                shadow: spring(16, springConfig),\n                y: mouseY,\n              }\n            : {\n                scale: spring(1, springConfig),\n                shadow: spring(1, springConfig),\n                y: spring(order.indexOf(i) * 100, springConfig),\n              };\n          return (\n            <Motion style={style} key={i}>\n              {({scale, shadow, y}) =>\n                <div\n                  onMouseDown={this.handleMouseDown.bind(null, i, y)}\n                  onTouchStart={this.handleTouchStart.bind(null, i, y)}\n                  className=\"demo8-item\"\n                  style={{\n                    boxShadow: `rgba(0, 0, 0, 0.2) 0px ${shadow}px ${2 * shadow}px 0px`,\n                    transform: `translate3d(0, ${y}px, 0) scale(${scale})`,\n                    WebkitTransform: `translate3d(0, ${y}px, 0) scale(${scale})`,\n                    zIndex: i === originalPosOfLastPressed ? 99 : i,\n                  }}>\n                  {order.indexOf(i) + 1}\n                </div>\n              }\n            </Motion>\n          );\n        })}\n      </div>\n    );\n  };\n}\n"
  },
  {
    "path": "demos/demo8-draggable-list/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Framer cards</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <style>\n  * {\n    padding: 0;\n    margin: 0;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    user-select: none;\n  }\n\n  body {\n    cursor: url('cursor.png') 39 39, auto;\n  }\n\n  .demo8-outer {\n    background-color: #EEE;\n    color: #FFF;\n    position: absolute;\n    width: 100%;\n    height: 100%;\n    font: 28px/1em \"Helvetica\";\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    display: -webkit-flex;\n    -webkit-justify-content: center;\n    -webkit-align-items: center;\n  }\n\n  .demo8 {\n    width: 320px;\n    height: 400px;\n  }\n\n  .demo8-item {\n    position: absolute;\n    width: 320px;\n    height: 90px;\n    overflow: visible;\n    pointer-events: auto;\n    transform-origin: 50% 50% 0px;\n    border-radius: 4px;\n    color: rgb(153, 153, 153);\n    line-height: 96px;\n    padding-left: 32px;\n    font-size: 24px;\n    font-weight: 400;\n    background-color: rgb(255, 255, 255);\n    box-sizing: border-box;\n    -webkit-box-sizing: border-box;\n  }\n\n  .link {\n    position: absolute;\n    color: rgb(76, 76, 76);\n    text-decoration: none;\n    font: 14px/1em \"Helvetica\";\n    padding: 10px;\n    top: 0;\n    left: 0;\n  }\n  </style>\n</head>\n\n<body>\n  <div class=\"demo8-outer\">\n    <div id=\"content\"></div>\n    <a class=\"link\" href=\"http://framerjs.com/examples/preview/#list-sorting.framer\">\n      Original Framer.js Example\n    </a>\n  </div>\n  <script src=\"./all.js\"></script>\n</body>\n\n</html>\n"
  },
  {
    "path": "demos/demo8-draggable-list/index.jsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport Demo from './Demo';\n\nReactDOM.render(<Demo />, document.querySelector('#content'));\n"
  },
  {
    "path": "karma.conf.js",
    "content": "'use strict';\n\nvar path = require('path');\n\nvar withCoverage = process.argv.indexOf('coverage') !== -1 || process.env.COVERAGE;\n\nvar webpackConfig = {\n  mode: 'development',\n  module: {\n    rules: withCoverage ?\n      [\n        {\n          test: /\\.js$/,\n          loader: 'babel-loader',\n          include: [path.resolve('./test')]\n        },\n        {\n          test: /\\.js$/,\n          loader: 'isparta-loader',\n          include: [path.resolve('./src')]\n        },\n      ] :\n      [\n        {\n          test: /\\.js$/,\n          loader: 'babel-loader',\n          include: [path.resolve('./src'), path.resolve('./test')],\n        },\n      ],\n  },\n  stats: {\n    colors: true,\n  }\n};\n\nmodule.exports = function (config) {\n  config.set({\n    basePath: '',\n    frameworks: ['jasmine'],\n    files: [\n      './node_modules/@babel/polyfill/browser.js',\n      'test/index.js',\n    ],\n    webpack: webpackConfig,\n    webpackMiddleware: {\n      stats: {\n        chunkModules: false,\n        colors: true,\n      },\n    },\n    exclude: [],\n    preprocessors: {\n      'test/index.js': ['webpack'],\n    },\n    reporters: ['jasmine-diff', 'progress'],\n    jasmineDiffReporter: {\n      pretty: true,\n      color: {\n        expectedBg: '',\n        expectedFg: 'red',\n        actualBg: '',\n        actualFg: 'green',\n        defaultBg: '',\n        defaultFg: 'grey'\n      }\n    },\n    coverageReporter: {\n      dir: './coverage/',\n      subdir: '.',\n      reporters: [\n        {type: 'html'},\n        {type: 'lcovonly'},\n        {type: 'text', file: 'text.txt'},\n        {type: 'text-summary', file: 'text-summary.txt'},\n      ],\n    },\n    captureTimeout: 90000,\n    browserNoActivityTimeout: 60000,\n    port: 9876,\n    colors: true,\n    logLevel: config.LOG_INFO,\n    autoWatch: false,\n    browsers: ['ChromeHeadless'],\n    singleRun: true,\n  });\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-motion\",\n  \"version\": \"0.5.2\",\n  \"description\": \"A spring that solves your animation problems.\",\n  \"main\": \"lib/react-motion.js\",\n  \"module\": \"lib/react-motion.esm.js\",\n  \"peerDependencies\": {\n    \"react\": \"^0.14.9 || ^15.3.0 || ^16.0.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.0.0-rc.1\",\n    \"@babel/core\": \"^7.7.2\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.7.0\",\n    \"@babel/plugin-transform-modules-commonjs\": \"^7.7.0\",\n    \"@babel/plugin-transform-runtime\": \"^7.6.2\",\n    \"@babel/polyfill\": \"^7.7.0\",\n    \"@babel/preset-env\": \"^7.7.1\",\n    \"@babel/preset-flow\": \"^7.0.0\",\n    \"@babel/preset-react\": \"^7.7.0\",\n    \"babel-eslint\": \"^10.0.3\",\n    \"babel-loader\": \"^8.0.6\",\n    \"babel-plugin-transform-react-remove-prop-types\": \"^0.4.24\",\n    \"codemirror\": \"^5.5.0\",\n    \"cross-env\": \"^5.2.0\",\n    \"css-loader\": \"^0.28.11\",\n    \"eslint\": \"^5.16.0\",\n    \"eslint-config-airbnb\": \"^17.0.0\",\n    \"eslint-config-prettier\": \"^2.9.0\",\n    \"eslint-loader\": \"^2.0.0\",\n    \"eslint-plugin-flowtype\": \"^2.49.3\",\n    \"eslint-plugin-import\": \"^2.13.0\",\n    \"eslint-plugin-jsx-a11y\": \"^6.1.0\",\n    \"eslint-plugin-react\": \"^7.10.0\",\n    \"flow-bin\": \"^0.53.1\",\n    \"flow-copy-source\": \"^1.1.0\",\n    \"husky\": \"^0.14.3\",\n    \"inject-loader\": \"^4.0.1\",\n    \"isparta-loader\": \"^2.0.0\",\n    \"jasmine-core\": \"^3.1.0\",\n    \"karma\": \"^2.0.4\",\n    \"karma-chrome-launcher\": \"^2.2.0\",\n    \"karma-coverage\": \"^1.1.2\",\n    \"karma-jasmine\": \"^1.1.2\",\n    \"karma-jasmine-diff-reporter\": \"^1.2.0\",\n    \"karma-webpack\": \"^3.0.0\",\n    \"lint-staged\": \"^7.2.0\",\n    \"lodash.range\": \"^3.0.1\",\n    \"prettier\": \"^1.14.2\",\n    \"react\": \">=15.5.0\",\n    \"react-codemirror\": \">=0.1.2\",\n    \"react-dom\": \">=15.5.0\",\n    \"rollup\": \"^0.62.0\",\n    \"rollup-plugin-babel\": \"^4.3.3\",\n    \"rollup-plugin-commonjs\": \"^9.1.4\",\n    \"rollup-plugin-node-resolve\": \"^3.3.0\",\n    \"rollup-plugin-replace\": \"^2.0.0\",\n    \"rollup-plugin-size-snapshot\": \"^0.6.0\",\n    \"rollup-plugin-uglify\": \"^4.0.0\",\n    \"style-loader\": \"^0.21.0\",\n    \"webpack\": \"^4.14.0\",\n    \"webpack-command\": \"^0.4.0\",\n    \"webpack-dev-server\": \"^3.1.4\"\n  },\n  \"scripts\": {\n    \"start\": \"node server.js\",\n    \"prebuild:dist\": \"rm -rf build\",\n    \"build:dist\": \"rollup -c\",\n    \"prebuild:lib\": \"rm -rf lib\",\n    \"build:lib\": \"babel src --out-dir lib\",\n    \"build:flow\": \"flow-copy-source -v src lib\",\n    \"build\": \"npm run build:dist && npm run build:lib && npm run build:flow\",\n    \"build-demos\": \"webpack\",\n    \"lint\": \"eslint --ext .js,.jsx .\",\n    \"flow_check\": \"flow check\",\n    \"prepublishOnly\": \"npm run build\",\n    \"test\": \"cross-env NODE_ENV=test karma start ./karma.conf.js --single-run\",\n    \"test:travis\": \"cross-env NODE_ENV=test karma start ./karma.conf.js --single-run\",\n    \"test:dev\": \"cross-env NODE_ENV=test karma start ./karma.conf.js --no-single-run --auto-watch\",\n    \"test:cov\": \"cross-env NODE_ENV=test karma start ./karma.conf.js --single-run --reporters coverage\",\n    \"gh-pages\": \"git fetch origin && git checkout gh-pages && git reset --hard origin/gh-pages && git rebase origin/master --force-rebase && npm run build-demos && git add . && git commit --amend --no-edit && git push origin gh-pages --force && git checkout master\",\n    \"precommit\": \"lint-staged\"\n  },\n  \"lint-staged\": {\n    \"*.js\": [\n      \"prettier --write\",\n      \"git add\"\n    ]\n  },\n  \"prettier\": {\n    \"singleQuote\": true,\n    \"trailingComma\": \"all\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/chenglou/react-motion.git\"\n  },\n  \"keywords\": [\n    \"react\",\n    \"component\",\n    \"react-component\",\n    \"transitiongroup\",\n    \"spring\",\n    \"tween\",\n    \"motion\",\n    \"animation\",\n    \"transition\",\n    \"ui\"\n  ],\n  \"author\": [\n    \"nkbt\",\n    \"chenglou\"\n  ],\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@babel/runtime\": \"7.7.2\",\n    \"performance-now\": \"^2.1.0\",\n    \"prop-types\": \"^15.5.8\",\n    \"raf\": \"^3.1.0\"\n  }\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import nodeResolve from 'rollup-plugin-node-resolve';\nimport commonjs from 'rollup-plugin-commonjs';\nimport babel from 'rollup-plugin-babel';\nimport replace from 'rollup-plugin-replace';\nimport { sizeSnapshot } from 'rollup-plugin-size-snapshot';\nimport { uglify } from 'rollup-plugin-uglify';\nimport pkg from './package.json';\n\nconst input = './src/react-motion.js';\nconst name = 'ReactMotion';\nconst globals = {\n  react: 'React',\n};\n\n// treat as external \"module/path\" modules and reserved rollup paths\nconst external = id =>\n  !id.startsWith('\\0') && !id.startsWith('.') && !id.startsWith('/');\n\nconst getBabelOptions = () => ({\n  babelrc: false,\n  exclude: '**/node_modules/**',\n  runtimeHelpers: true,\n  plugins: [\n    ['@babel/proposal-class-properties', { loose: true }],\n    ['transform-react-remove-prop-types', { mode: 'unsafe-wrap' }],\n    ['@babel/transform-runtime', { useESModules: true }],\n  ],\n  presets: [\n    ['@babel/env', { modules: false, loose: true }],\n    '@babel/flow',\n    '@babel/react',\n  ],\n});\n\nconst commonjsOptions = {\n  include: '**/node_modules/**',\n};\n\nexport default [\n  {\n    input,\n    output: { file: 'build/react-motion.js', format: 'umd', name, globals },\n    external: Object.keys(globals),\n    plugins: [\n      nodeResolve(),\n      babel(getBabelOptions()),\n      commonjs(commonjsOptions),\n      replace({ 'process.env.NODE_ENV': JSON.stringify('development') }),\n      sizeSnapshot(),\n    ],\n  },\n\n  {\n    input,\n    output: { file: 'build/react-motion.min.js', format: 'umd', name, globals },\n    external: Object.keys(globals),\n    plugins: [\n      nodeResolve(),\n      babel(getBabelOptions()),\n      commonjs(commonjsOptions),\n      replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),\n      sizeSnapshot(),\n      uglify(),\n    ],\n  },\n\n  {\n    input,\n    output: { file: pkg.module, format: 'esm' },\n    external,\n    plugins: [babel(getBabelOptions()), sizeSnapshot()],\n  },\n];\n"
  },
  {
    "path": "server.js",
    "content": "'use strict';\n\nprocess.env.NODE_ENV = 'development';\n\nvar webpack = require('webpack');\nvar WebpackDevServer = require('webpack-dev-server');\nvar config = require('./webpack.config');\nvar port = process.env.PORT || 3000;\n\nnew WebpackDevServer(webpack(config), {\n  publicPath: config.output.publicPath,\n  hot: true,\n  stats: {\n    chunkModules: false,\n    colors: true,\n  }\n}).listen(port, '0.0.0.0', function (err) {\n  if (err) {\n    console.log(err);\n  }\n\n  console.log('Listening at 0.0.0.0:' + port);\n});\n"
  },
  {
    "path": "src/Motion.js",
    "content": "/* @flow */\nimport mapToZero from './mapToZero';\nimport stripStyle from './stripStyle';\nimport stepper from './stepper';\nimport defaultNow from 'performance-now';\nimport defaultRaf from 'raf';\nimport shouldStopAnimation from './shouldStopAnimation';\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport type {\n  ReactElement,\n  PlainStyle,\n  Style,\n  Velocity,\n  MotionProps,\n} from './Types';\n\nconst msPerFrame = 1000 / 60;\n\ntype MotionState = {\n  currentStyle: PlainStyle,\n  currentVelocity: Velocity,\n  lastIdealStyle: PlainStyle,\n  lastIdealVelocity: Velocity,\n};\n\nexport default class Motion extends React.Component<MotionProps, MotionState> {\n  static propTypes = {\n    // TOOD: warn against putting a config in here\n    defaultStyle: PropTypes.objectOf(PropTypes.number),\n    style: PropTypes.objectOf(\n      PropTypes.oneOfType([PropTypes.number, PropTypes.object]),\n    ).isRequired,\n    children: PropTypes.func.isRequired,\n    onRest: PropTypes.func,\n  };\n\n  constructor(props: MotionProps) {\n    super(props);\n    this.state = this.defaultState();\n  }\n\n  unmounting: boolean = false;\n  wasAnimating: boolean = false;\n  animationID: ?number = null;\n  prevTime: number = 0;\n  accumulatedTime: number = 0;\n\n  defaultState(): MotionState {\n    const { defaultStyle, style } = this.props;\n    const currentStyle = defaultStyle || stripStyle(style);\n    const currentVelocity = mapToZero(currentStyle);\n    return {\n      currentStyle,\n      currentVelocity,\n      lastIdealStyle: currentStyle,\n      lastIdealVelocity: currentVelocity,\n    };\n  }\n\n  // it's possible that currentStyle's value is stale: if props is immediately\n  // changed from 0 to 400 to spring(0) again, the async currentStyle is still\n  // at 0 (didn't have time to tick and interpolate even once). If we naively\n  // compare currentStyle with destVal it'll be 0 === 0 (no animation, stop).\n  // In reality currentStyle should be 400\n  unreadPropStyle: ?Style = null;\n  // after checking for unreadPropStyle != null, we manually go set the\n  // non-interpolating values (those that are a number, without a spring\n  // config)\n  clearUnreadPropStyle = (destStyle: Style): void => {\n    let dirty = false;\n    let {\n      currentStyle,\n      currentVelocity,\n      lastIdealStyle,\n      lastIdealVelocity,\n    } = this.state;\n\n    for (let key in destStyle) {\n      if (!Object.prototype.hasOwnProperty.call(destStyle, key)) {\n        continue;\n      }\n\n      const styleValue = destStyle[key];\n      if (typeof styleValue === 'number') {\n        if (!dirty) {\n          dirty = true;\n          currentStyle = { ...currentStyle };\n          currentVelocity = { ...currentVelocity };\n          lastIdealStyle = { ...lastIdealStyle };\n          lastIdealVelocity = { ...lastIdealVelocity };\n        }\n\n        currentStyle[key] = styleValue;\n        currentVelocity[key] = 0;\n        lastIdealStyle[key] = styleValue;\n        lastIdealVelocity[key] = 0;\n      }\n    }\n\n    if (dirty) {\n      this.setState({\n        currentStyle,\n        currentVelocity,\n        lastIdealStyle,\n        lastIdealVelocity,\n      });\n    }\n  };\n\n  startAnimationIfNecessary = (): void => {\n    if (this.unmounting || this.animationID != null) {\n      return;\n    }\n\n    // TODO: when config is {a: 10} and dest is {a: 10} do we raf once and\n    // call cb? No, otherwise accidental parent rerender causes cb trigger\n    this.animationID = defaultRaf(timestamp => {\n      // https://github.com/chenglou/react-motion/pull/420\n      // > if execution passes the conditional if (this.unmounting), then\n      // executes async defaultRaf and after that component unmounts and after\n      // that the callback of defaultRaf is called, then setState will be called\n      // on unmounted component.\n      if (this.unmounting) {\n        return;\n      }\n\n      // check if we need to animate in the first place\n      const propsStyle: Style = this.props.style;\n      if (\n        shouldStopAnimation(\n          this.state.currentStyle,\n          propsStyle,\n          this.state.currentVelocity,\n        )\n      ) {\n        if (this.wasAnimating && this.props.onRest) {\n          this.props.onRest();\n        }\n\n        // no need to cancel animationID here; shouldn't have any in flight\n        this.animationID = null;\n        this.wasAnimating = false;\n        this.accumulatedTime = 0;\n        return;\n      }\n\n      this.wasAnimating = true;\n\n      const currentTime = timestamp || defaultNow();\n      const timeDelta = currentTime - this.prevTime;\n      this.prevTime = currentTime;\n      this.accumulatedTime = this.accumulatedTime + timeDelta;\n      // more than 10 frames? prolly switched browser tab. Restart\n      if (this.accumulatedTime > msPerFrame * 10) {\n        this.accumulatedTime = 0;\n      }\n\n      if (this.accumulatedTime === 0) {\n        // no need to cancel animationID here; shouldn't have any in flight\n        this.animationID = null;\n        this.startAnimationIfNecessary();\n        return;\n      }\n\n      let currentFrameCompletion =\n        (this.accumulatedTime -\n          Math.floor(this.accumulatedTime / msPerFrame) * msPerFrame) /\n        msPerFrame;\n      const framesToCatchUp = Math.floor(this.accumulatedTime / msPerFrame);\n\n      let newLastIdealStyle: PlainStyle = {};\n      let newLastIdealVelocity: Velocity = {};\n      let newCurrentStyle: PlainStyle = {};\n      let newCurrentVelocity: Velocity = {};\n\n      for (let key in propsStyle) {\n        if (!Object.prototype.hasOwnProperty.call(propsStyle, key)) {\n          continue;\n        }\n\n        const styleValue = propsStyle[key];\n        if (typeof styleValue === 'number') {\n          newCurrentStyle[key] = styleValue;\n          newCurrentVelocity[key] = 0;\n          newLastIdealStyle[key] = styleValue;\n          newLastIdealVelocity[key] = 0;\n        } else {\n          let newLastIdealStyleValue = this.state.lastIdealStyle[key];\n          let newLastIdealVelocityValue = this.state.lastIdealVelocity[key];\n          for (let i = 0; i < framesToCatchUp; i++) {\n            [newLastIdealStyleValue, newLastIdealVelocityValue] = stepper(\n              msPerFrame / 1000,\n              newLastIdealStyleValue,\n              newLastIdealVelocityValue,\n              styleValue.val,\n              styleValue.stiffness,\n              styleValue.damping,\n              styleValue.precision,\n            );\n          }\n          const [nextIdealX, nextIdealV] = stepper(\n            msPerFrame / 1000,\n            newLastIdealStyleValue,\n            newLastIdealVelocityValue,\n            styleValue.val,\n            styleValue.stiffness,\n            styleValue.damping,\n            styleValue.precision,\n          );\n\n          newCurrentStyle[key] =\n            newLastIdealStyleValue +\n            (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion;\n          newCurrentVelocity[key] =\n            newLastIdealVelocityValue +\n            (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion;\n          newLastIdealStyle[key] = newLastIdealStyleValue;\n          newLastIdealVelocity[key] = newLastIdealVelocityValue;\n        }\n      }\n\n      this.animationID = null;\n      // the amount we're looped over above\n      this.accumulatedTime -= framesToCatchUp * msPerFrame;\n\n      this.setState({\n        currentStyle: newCurrentStyle,\n        currentVelocity: newCurrentVelocity,\n        lastIdealStyle: newLastIdealStyle,\n        lastIdealVelocity: newLastIdealVelocity,\n      });\n\n      this.unreadPropStyle = null;\n\n      this.startAnimationIfNecessary();\n    });\n  };\n\n  componentDidMount() {\n    this.prevTime = defaultNow();\n    this.startAnimationIfNecessary();\n  }\n\n  UNSAFE_componentWillReceiveProps(props: MotionProps) {\n    if (this.unreadPropStyle != null) {\n      // previous props haven't had the chance to be set yet; set them here\n      this.clearUnreadPropStyle(this.unreadPropStyle);\n    }\n\n    this.unreadPropStyle = props.style;\n    if (this.animationID == null) {\n      this.prevTime = defaultNow();\n      this.startAnimationIfNecessary();\n    }\n  }\n\n  componentWillUnmount() {\n    this.unmounting = true;\n    if (this.animationID != null) {\n      defaultRaf.cancel(this.animationID);\n      this.animationID = null;\n    }\n  }\n\n  render(): ReactElement {\n    const renderedChildren = this.props.children(this.state.currentStyle);\n    return renderedChildren && React.Children.only(renderedChildren);\n  }\n}\n"
  },
  {
    "path": "src/StaggeredMotion.js",
    "content": "/* @flow */\nimport mapToZero from './mapToZero';\nimport stripStyle from './stripStyle';\nimport stepper from './stepper';\nimport defaultNow from 'performance-now';\nimport defaultRaf from 'raf';\nimport shouldStopAnimation from './shouldStopAnimation';\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport type {\n  ReactElement,\n  PlainStyle,\n  Style,\n  Velocity,\n  StaggeredProps,\n} from './Types';\n\nconst msPerFrame = 1000 / 60;\n\ntype StaggeredMotionState = {\n  currentStyles: Array<PlainStyle>,\n  currentVelocities: Array<Velocity>,\n  lastIdealStyles: Array<PlainStyle>,\n  lastIdealVelocities: Array<Velocity>,\n};\n\nfunction shouldStopAnimationAll(\n  currentStyles: Array<PlainStyle>,\n  styles: Array<Style>,\n  currentVelocities: Array<Velocity>,\n): boolean {\n  for (let i = 0; i < currentStyles.length; i++) {\n    if (\n      !shouldStopAnimation(currentStyles[i], styles[i], currentVelocities[i])\n    ) {\n      return false;\n    }\n  }\n  return true;\n}\n\nexport default class StaggeredMotion extends React.Component<\n  StaggeredProps,\n  StaggeredMotionState,\n> {\n  static propTypes = {\n    // TOOD: warn against putting a config in here\n    defaultStyles: PropTypes.arrayOf(PropTypes.objectOf(PropTypes.number)),\n    styles: PropTypes.func.isRequired,\n    children: PropTypes.func.isRequired,\n  };\n\n  constructor(props: StaggeredProps) {\n    super(props);\n    this.state = this.defaultState();\n  }\n\n  defaultState(): StaggeredMotionState {\n    const { defaultStyles, styles } = this.props;\n    const currentStyles: Array<PlainStyle> =\n      defaultStyles || styles().map(stripStyle);\n    const currentVelocities = currentStyles.map(currentStyle =>\n      mapToZero(currentStyle),\n    );\n    return {\n      currentStyles,\n      currentVelocities,\n      lastIdealStyles: currentStyles,\n      lastIdealVelocities: currentVelocities,\n    };\n  }\n\n  unmounting: boolean = false;\n  animationID: ?number = null;\n  prevTime = 0;\n  accumulatedTime = 0;\n  // it's possible that currentStyle's value is stale: if props is immediately\n  // changed from 0 to 400 to spring(0) again, the async currentStyle is still\n  // at 0 (didn't have time to tick and interpolate even once). If we naively\n  // compare currentStyle with destVal it'll be 0 === 0 (no animation, stop).\n  // In reality currentStyle should be 400\n  unreadPropStyles: ?Array<Style> = null;\n\n  // after checking for unreadPropStyles != null, we manually go set the\n  // non-interpolating values (those that are a number, without a spring\n  // config)\n  clearUnreadPropStyle = (unreadPropStyles: Array<Style>): void => {\n    let {\n      currentStyles,\n      currentVelocities,\n      lastIdealStyles,\n      lastIdealVelocities,\n    } = this.state;\n\n    let someDirty = false;\n    for (let i = 0; i < unreadPropStyles.length; i++) {\n      const unreadPropStyle = unreadPropStyles[i];\n      let dirty = false;\n\n      for (let key in unreadPropStyle) {\n        if (!Object.prototype.hasOwnProperty.call(unreadPropStyle, key)) {\n          continue;\n        }\n\n        const styleValue = unreadPropStyle[key];\n        if (typeof styleValue === 'number') {\n          if (!dirty) {\n            dirty = true;\n            someDirty = true;\n            currentStyles[i] = { ...currentStyles[i] };\n            currentVelocities[i] = { ...currentVelocities[i] };\n            lastIdealStyles[i] = { ...lastIdealStyles[i] };\n            lastIdealVelocities[i] = { ...lastIdealVelocities[i] };\n          }\n          currentStyles[i][key] = styleValue;\n          currentVelocities[i][key] = 0;\n          lastIdealStyles[i][key] = styleValue;\n          lastIdealVelocities[i][key] = 0;\n        }\n      }\n    }\n\n    if (someDirty) {\n      this.setState({\n        currentStyles,\n        currentVelocities,\n        lastIdealStyles,\n        lastIdealVelocities,\n      });\n    }\n  };\n\n  startAnimationIfNecessary = (): void => {\n    if (this.unmounting || this.animationID != null) {\n      return;\n    }\n\n    // TODO: when config is {a: 10} and dest is {a: 10} do we raf once and\n    // call cb? No, otherwise accidental parent rerender causes cb trigger\n    this.animationID = defaultRaf(timestamp => {\n      // https://github.com/chenglou/react-motion/pull/420\n      // > if execution passes the conditional if (this.unmounting), then\n      // executes async defaultRaf and after that component unmounts and after\n      // that the callback of defaultRaf is called, then setState will be called\n      // on unmounted component.\n      if (this.unmounting) {\n        return;\n      }\n\n      const destStyles: Array<Style> = this.props.styles(\n        this.state.lastIdealStyles,\n      );\n\n      // check if we need to animate in the first place\n      if (\n        shouldStopAnimationAll(\n          this.state.currentStyles,\n          destStyles,\n          this.state.currentVelocities,\n        )\n      ) {\n        // no need to cancel animationID here; shouldn't have any in flight\n        this.animationID = null;\n        this.accumulatedTime = 0;\n        return;\n      }\n\n      const currentTime = timestamp || defaultNow();\n      const timeDelta = currentTime - this.prevTime;\n      this.prevTime = currentTime;\n      this.accumulatedTime = this.accumulatedTime + timeDelta;\n      // more than 10 frames? prolly switched browser tab. Restart\n      if (this.accumulatedTime > msPerFrame * 10) {\n        this.accumulatedTime = 0;\n      }\n\n      if (this.accumulatedTime === 0) {\n        // no need to cancel animationID here; shouldn't have any in flight\n        this.animationID = null;\n        this.startAnimationIfNecessary();\n        return;\n      }\n\n      let currentFrameCompletion =\n        (this.accumulatedTime -\n          Math.floor(this.accumulatedTime / msPerFrame) * msPerFrame) /\n        msPerFrame;\n      const framesToCatchUp = Math.floor(this.accumulatedTime / msPerFrame);\n\n      let newLastIdealStyles = [];\n      let newLastIdealVelocities = [];\n      let newCurrentStyles = [];\n      let newCurrentVelocities = [];\n\n      for (let i = 0; i < destStyles.length; i++) {\n        const destStyle = destStyles[i];\n        let newCurrentStyle: PlainStyle = {};\n        let newCurrentVelocity: Velocity = {};\n        let newLastIdealStyle: PlainStyle = {};\n        let newLastIdealVelocity: Velocity = {};\n\n        for (let key in destStyle) {\n          if (!Object.prototype.hasOwnProperty.call(destStyle, key)) {\n            continue;\n          }\n\n          const styleValue = destStyle[key];\n          if (typeof styleValue === 'number') {\n            newCurrentStyle[key] = styleValue;\n            newCurrentVelocity[key] = 0;\n            newLastIdealStyle[key] = styleValue;\n            newLastIdealVelocity[key] = 0;\n          } else {\n            let newLastIdealStyleValue = this.state.lastIdealStyles[i][key];\n            let newLastIdealVelocityValue = this.state.lastIdealVelocities[i][\n              key\n            ];\n            for (let j = 0; j < framesToCatchUp; j++) {\n              [newLastIdealStyleValue, newLastIdealVelocityValue] = stepper(\n                msPerFrame / 1000,\n                newLastIdealStyleValue,\n                newLastIdealVelocityValue,\n                styleValue.val,\n                styleValue.stiffness,\n                styleValue.damping,\n                styleValue.precision,\n              );\n            }\n            const [nextIdealX, nextIdealV] = stepper(\n              msPerFrame / 1000,\n              newLastIdealStyleValue,\n              newLastIdealVelocityValue,\n              styleValue.val,\n              styleValue.stiffness,\n              styleValue.damping,\n              styleValue.precision,\n            );\n\n            newCurrentStyle[key] =\n              newLastIdealStyleValue +\n              (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion;\n            newCurrentVelocity[key] =\n              newLastIdealVelocityValue +\n              (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion;\n            newLastIdealStyle[key] = newLastIdealStyleValue;\n            newLastIdealVelocity[key] = newLastIdealVelocityValue;\n          }\n        }\n\n        newCurrentStyles[i] = newCurrentStyle;\n        newCurrentVelocities[i] = newCurrentVelocity;\n        newLastIdealStyles[i] = newLastIdealStyle;\n        newLastIdealVelocities[i] = newLastIdealVelocity;\n      }\n\n      this.animationID = null;\n      // the amount we're looped over above\n      this.accumulatedTime -= framesToCatchUp * msPerFrame;\n\n      this.setState({\n        currentStyles: newCurrentStyles,\n        currentVelocities: newCurrentVelocities,\n        lastIdealStyles: newLastIdealStyles,\n        lastIdealVelocities: newLastIdealVelocities,\n      });\n\n      this.unreadPropStyles = null;\n\n      this.startAnimationIfNecessary();\n    });\n  };\n\n  componentDidMount() {\n    this.prevTime = defaultNow();\n    this.startAnimationIfNecessary();\n  }\n\n  UNSAFE_componentWillReceiveProps(props: StaggeredProps) {\n    if (this.unreadPropStyles != null) {\n      // previous props haven't had the chance to be set yet; set them here\n      this.clearUnreadPropStyle(this.unreadPropStyles);\n    }\n\n    this.unreadPropStyles = props.styles(this.state.lastIdealStyles);\n    if (this.animationID == null) {\n      this.prevTime = defaultNow();\n      this.startAnimationIfNecessary();\n    }\n  }\n\n  componentWillUnmount() {\n    this.unmounting = true;\n    if (this.animationID != null) {\n      defaultRaf.cancel(this.animationID);\n      this.animationID = null;\n    }\n  }\n\n  render(): ReactElement {\n    const renderedChildren = this.props.children(this.state.currentStyles);\n    return renderedChildren && React.Children.only(renderedChildren);\n  }\n}\n"
  },
  {
    "path": "src/TransitionMotion.js",
    "content": "/* @flow */\nimport mapToZero from './mapToZero';\nimport stripStyle from './stripStyle';\nimport stepper from './stepper';\nimport mergeDiff from './mergeDiff';\nimport defaultNow from 'performance-now';\nimport defaultRaf from 'raf';\nimport shouldStopAnimation from './shouldStopAnimation';\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport type {\n  ReactElement,\n  PlainStyle,\n  Velocity,\n  TransitionStyle,\n  TransitionPlainStyle,\n  WillEnter,\n  WillLeave,\n  DidLeave,\n  TransitionProps,\n} from './Types';\n\nconst msPerFrame = 1000 / 60;\n\n// the children function & (potential) styles function asks as param an\n// Array<TransitionPlainStyle>, where each TransitionPlainStyle is of the format\n// {key: string, data?: any, style: PlainStyle}. However, the way we keep\n// internal states doesn't contain such a data structure (check the state and\n// TransitionMotionState). So when children function and others ask for such\n// data we need to generate them on the fly by combining mergedPropsStyles and\n// currentStyles/lastIdealStyles\nfunction rehydrateStyles(\n  mergedPropsStyles: Array<TransitionStyle>,\n  unreadPropStyles: ?Array<TransitionStyle>,\n  plainStyles: Array<PlainStyle>,\n): Array<TransitionPlainStyle> {\n  // Copy the value to a `const` so that Flow understands that the const won't\n  // change and will be non-nullable in the callback below.\n  const cUnreadPropStyles = unreadPropStyles;\n  if (cUnreadPropStyles == null) {\n    return mergedPropsStyles.map((mergedPropsStyle, i) => ({\n      key: mergedPropsStyle.key,\n      data: mergedPropsStyle.data,\n      style: plainStyles[i],\n    }));\n  }\n  return mergedPropsStyles.map((mergedPropsStyle, i) => {\n    for (let j = 0; j < cUnreadPropStyles.length; j++) {\n      if (cUnreadPropStyles[j].key === mergedPropsStyle.key) {\n        return {\n          key: cUnreadPropStyles[j].key,\n          data: cUnreadPropStyles[j].data,\n          style: plainStyles[i],\n        };\n      }\n    }\n    return {\n      key: mergedPropsStyle.key,\n      data: mergedPropsStyle.data,\n      style: plainStyles[i],\n    };\n  });\n}\n\nfunction shouldStopAnimationAll(\n  currentStyles: Array<PlainStyle>,\n  destStyles: Array<TransitionStyle>,\n  currentVelocities: Array<Velocity>,\n  mergedPropsStyles: Array<TransitionStyle>,\n): boolean {\n  if (mergedPropsStyles.length !== destStyles.length) {\n    return false;\n  }\n\n  for (let i = 0; i < mergedPropsStyles.length; i++) {\n    if (mergedPropsStyles[i].key !== destStyles[i].key) {\n      return false;\n    }\n  }\n\n  // we have the invariant that mergedPropsStyles and\n  // currentStyles/currentVelocities/last* are synced in terms of cells, see\n  // mergeAndSync comment for more info\n  for (let i = 0; i < mergedPropsStyles.length; i++) {\n    if (\n      !shouldStopAnimation(\n        currentStyles[i],\n        destStyles[i].style,\n        currentVelocities[i],\n      )\n    ) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n// core key merging logic\n\n// things to do: say previously merged style is {a, b}, dest style (prop) is {b,\n// c}, previous current (interpolating) style is {a, b}\n// **invariant**: current[i] corresponds to merged[i] in terms of key\n\n// steps:\n// turn merged style into {a?, b, c}\n//    add c, value of c is destStyles.c\n//    maybe remove a, aka call willLeave(a), then merged is either {b, c} or {a, b, c}\n// turn current (interpolating) style from {a, b} into {a?, b, c}\n//    maybe remove a\n//    certainly add c, value of c is willEnter(c)\n// loop over merged and construct new current\n// dest doesn't change, that's owner's\nfunction mergeAndSync(\n  willEnter: WillEnter,\n  willLeave: WillLeave,\n  didLeave: DidLeave,\n  oldMergedPropsStyles: Array<TransitionStyle>,\n  destStyles: Array<TransitionStyle>,\n  oldCurrentStyles: Array<PlainStyle>,\n  oldCurrentVelocities: Array<Velocity>,\n  oldLastIdealStyles: Array<PlainStyle>,\n  oldLastIdealVelocities: Array<Velocity>,\n): [\n  Array<TransitionStyle>,\n  Array<PlainStyle>,\n  Array<Velocity>,\n  Array<PlainStyle>,\n  Array<Velocity>,\n] {\n  const newMergedPropsStyles = mergeDiff(\n    oldMergedPropsStyles,\n    destStyles,\n    (oldIndex, oldMergedPropsStyle) => {\n      const leavingStyle = willLeave(oldMergedPropsStyle);\n      if (leavingStyle == null) {\n        didLeave({\n          key: oldMergedPropsStyle.key,\n          data: oldMergedPropsStyle.data,\n        });\n        return null;\n      }\n      if (\n        shouldStopAnimation(\n          oldCurrentStyles[oldIndex],\n          leavingStyle,\n          oldCurrentVelocities[oldIndex],\n        )\n      ) {\n        didLeave({\n          key: oldMergedPropsStyle.key,\n          data: oldMergedPropsStyle.data,\n        });\n        return null;\n      }\n      return {\n        key: oldMergedPropsStyle.key,\n        data: oldMergedPropsStyle.data,\n        style: leavingStyle,\n      };\n    },\n  );\n\n  let newCurrentStyles = [];\n  let newCurrentVelocities = [];\n  let newLastIdealStyles = [];\n  let newLastIdealVelocities = [];\n  for (let i = 0; i < newMergedPropsStyles.length; i++) {\n    const newMergedPropsStyleCell = newMergedPropsStyles[i];\n    let foundOldIndex = null;\n    for (let j = 0; j < oldMergedPropsStyles.length; j++) {\n      if (oldMergedPropsStyles[j].key === newMergedPropsStyleCell.key) {\n        foundOldIndex = j;\n        break;\n      }\n    }\n    // TODO: key search code\n    if (foundOldIndex == null) {\n      const plainStyle = willEnter(newMergedPropsStyleCell);\n      newCurrentStyles[i] = plainStyle;\n      newLastIdealStyles[i] = plainStyle;\n\n      const velocity = mapToZero(newMergedPropsStyleCell.style);\n      newCurrentVelocities[i] = velocity;\n      newLastIdealVelocities[i] = velocity;\n    } else {\n      newCurrentStyles[i] = oldCurrentStyles[foundOldIndex];\n      newLastIdealStyles[i] = oldLastIdealStyles[foundOldIndex];\n      newCurrentVelocities[i] = oldCurrentVelocities[foundOldIndex];\n      newLastIdealVelocities[i] = oldLastIdealVelocities[foundOldIndex];\n    }\n  }\n\n  return [\n    newMergedPropsStyles,\n    newCurrentStyles,\n    newCurrentVelocities,\n    newLastIdealStyles,\n    newLastIdealVelocities,\n  ];\n}\n\ntype TransitionMotionDefaultProps = {\n  willEnter: WillEnter,\n  willLeave: WillLeave,\n  didLeave: DidLeave,\n};\n\ntype TransitionMotionState = {\n  // list of styles, each containing interpolating values. Part of what's passed\n  // to children function. Notice that this is\n  // Array<ActualInterpolatingStyleObject>, without the wrapper that is {key: ...,\n  // data: ... style: ActualInterpolatingStyleObject}. Only mergedPropsStyles\n  // contains the key & data info (so that we only have a single source of truth\n  // for these, and to save space). Check the comment for `rehydrateStyles` to\n  // see how we regenerate the entirety of what's passed to children function\n  currentStyles: Array<PlainStyle>,\n  currentVelocities: Array<Velocity>,\n  lastIdealStyles: Array<PlainStyle>,\n  lastIdealVelocities: Array<Velocity>,\n  // the array that keeps track of currently rendered stuff! Including stuff\n  // that you've unmounted but that's still animating. This is where it lives\n  mergedPropsStyles: Array<TransitionStyle>,\n};\n\nexport default class TransitionMotion extends React.Component<\n  TransitionProps,\n  TransitionMotionState,\n> {\n  static propTypes = {\n    defaultStyles: PropTypes.arrayOf(\n      PropTypes.shape({\n        key: PropTypes.string.isRequired,\n        data: PropTypes.any,\n        style: PropTypes.objectOf(PropTypes.number).isRequired,\n      }),\n    ),\n    styles: PropTypes.oneOfType([\n      PropTypes.func,\n      PropTypes.arrayOf(\n        PropTypes.shape({\n          key: PropTypes.string.isRequired,\n          data: PropTypes.any,\n          style: PropTypes.objectOf(\n            PropTypes.oneOfType([PropTypes.number, PropTypes.object]),\n          ).isRequired,\n        }),\n      ),\n    ]).isRequired,\n    children: PropTypes.func.isRequired,\n    willEnter: PropTypes.func,\n    willLeave: PropTypes.func,\n    didLeave: PropTypes.func,\n  };\n\n  static defaultProps: TransitionMotionDefaultProps = {\n    willEnter: styleThatEntered => stripStyle(styleThatEntered.style),\n    // recall: returning null makes the current unmounting TransitionStyle\n    // disappear immediately\n    willLeave: () => null,\n    didLeave: () => {},\n  };\n\n  unmounting: boolean = false;\n  animationID: ?number = null;\n  prevTime = 0;\n  accumulatedTime = 0;\n  // it's possible that currentStyle's value is stale: if props is immediately\n  // changed from 0 to 400 to spring(0) again, the async currentStyle is still\n  // at 0 (didn't have time to tick and interpolate even once). If we naively\n  // compare currentStyle with destVal it'll be 0 === 0 (no animation, stop).\n  // In reality currentStyle should be 400\n  unreadPropStyles: ?Array<TransitionStyle> = null;\n\n  constructor(props: TransitionProps) {\n    super(props);\n    this.state = this.defaultState();\n  }\n\n  defaultState(): TransitionMotionState {\n    const {\n      defaultStyles,\n      styles,\n      willEnter,\n      willLeave,\n      didLeave,\n    } = this.props;\n    const destStyles: Array<TransitionStyle> =\n      typeof styles === 'function' ? styles(defaultStyles) : styles;\n\n    // this is special. for the first time around, we don't have a comparison\n    // between last (no last) and current merged props. we'll compute last so:\n    // say default is {a, b} and styles (dest style) is {b, c}, we'll\n    // fabricate last as {a, b}\n    let oldMergedPropsStyles: Array<TransitionStyle>;\n    if (defaultStyles == null) {\n      oldMergedPropsStyles = destStyles;\n    } else {\n      oldMergedPropsStyles = (defaultStyles: any).map(defaultStyleCell => {\n        // TODO: key search code\n        for (let i = 0; i < destStyles.length; i++) {\n          if (destStyles[i].key === defaultStyleCell.key) {\n            return destStyles[i];\n          }\n        }\n        return defaultStyleCell;\n      });\n    }\n    const oldCurrentStyles =\n      defaultStyles == null\n        ? destStyles.map(s => stripStyle(s.style))\n        : (defaultStyles: any).map(s => stripStyle(s.style));\n    const oldCurrentVelocities =\n      defaultStyles == null\n        ? destStyles.map(s => mapToZero(s.style))\n        : defaultStyles.map(s => mapToZero(s.style));\n    const [\n      mergedPropsStyles,\n      currentStyles,\n      currentVelocities,\n      lastIdealStyles,\n      lastIdealVelocities,\n    ] = mergeAndSync(\n      // Because this is an old-style createReactClass component, Flow doesn't\n      // understand that the willEnter and willLeave props have default values\n      // and will always be present.\n      (willEnter: any),\n      (willLeave: any),\n      (didLeave: any),\n      oldMergedPropsStyles,\n      destStyles,\n      oldCurrentStyles,\n      oldCurrentVelocities,\n      oldCurrentStyles, // oldLastIdealStyles really\n      oldCurrentVelocities, // oldLastIdealVelocities really\n    );\n\n    return {\n      currentStyles,\n      currentVelocities,\n      lastIdealStyles,\n      lastIdealVelocities,\n      mergedPropsStyles,\n    };\n  }\n\n  // after checking for unreadPropStyles != null, we manually go set the\n  // non-interpolating values (those that are a number, without a spring\n  // config)\n  clearUnreadPropStyle = (unreadPropStyles: Array<TransitionStyle>): void => {\n    let [\n      mergedPropsStyles,\n      currentStyles,\n      currentVelocities,\n      lastIdealStyles,\n      lastIdealVelocities,\n    ] = mergeAndSync(\n      (this.props.willEnter: any),\n      (this.props.willLeave: any),\n      (this.props.didLeave: any),\n      this.state.mergedPropsStyles,\n      unreadPropStyles,\n      this.state.currentStyles,\n      this.state.currentVelocities,\n      this.state.lastIdealStyles,\n      this.state.lastIdealVelocities,\n    );\n\n    for (let i = 0; i < unreadPropStyles.length; i++) {\n      const unreadPropStyle = unreadPropStyles[i].style;\n      let dirty = false;\n\n      for (let key in unreadPropStyle) {\n        if (!Object.prototype.hasOwnProperty.call(unreadPropStyle, key)) {\n          continue;\n        }\n\n        const styleValue = unreadPropStyle[key];\n        if (typeof styleValue === 'number') {\n          if (!dirty) {\n            dirty = true;\n            currentStyles[i] = { ...currentStyles[i] };\n            currentVelocities[i] = { ...currentVelocities[i] };\n            lastIdealStyles[i] = { ...lastIdealStyles[i] };\n            lastIdealVelocities[i] = { ...lastIdealVelocities[i] };\n            mergedPropsStyles[i] = {\n              key: mergedPropsStyles[i].key,\n              data: mergedPropsStyles[i].data,\n              style: { ...mergedPropsStyles[i].style },\n            };\n          }\n          currentStyles[i][key] = styleValue;\n          currentVelocities[i][key] = 0;\n          lastIdealStyles[i][key] = styleValue;\n          lastIdealVelocities[i][key] = 0;\n          mergedPropsStyles[i].style[key] = styleValue;\n        }\n      }\n    }\n\n    // unlike the other 2 components, we can't detect staleness and optionally\n    // opt out of setState here. each style object's data might contain new\n    // stuff we're not/cannot compare\n    this.setState({\n      currentStyles,\n      currentVelocities,\n      mergedPropsStyles,\n      lastIdealStyles,\n      lastIdealVelocities,\n    });\n  };\n\n  startAnimationIfNecessary = (): void => {\n    if (this.unmounting || this.animationID != null) {\n      return;\n    }\n\n    // TODO: when config is {a: 10} and dest is {a: 10} do we raf once and\n    // call cb? No, otherwise accidental parent rerender causes cb trigger\n    this.animationID = defaultRaf(timestamp => {\n      // https://github.com/chenglou/react-motion/pull/420\n      // > if execution passes the conditional if (this.unmounting), then\n      // executes async defaultRaf and after that component unmounts and after\n      // that the callback of defaultRaf is called, then setState will be called\n      // on unmounted component.\n      if (this.unmounting) {\n        return;\n      }\n\n      const propStyles = this.props.styles;\n      let destStyles: Array<TransitionStyle> =\n        typeof propStyles === 'function'\n          ? propStyles(\n              rehydrateStyles(\n                this.state.mergedPropsStyles,\n                this.unreadPropStyles,\n                this.state.lastIdealStyles,\n              ),\n            )\n          : propStyles;\n\n      // check if we need to animate in the first place\n      if (\n        shouldStopAnimationAll(\n          this.state.currentStyles,\n          destStyles,\n          this.state.currentVelocities,\n          this.state.mergedPropsStyles,\n        )\n      ) {\n        // no need to cancel animationID here; shouldn't have any in flight\n        this.animationID = null;\n        this.accumulatedTime = 0;\n        return;\n      }\n\n      const currentTime = timestamp || defaultNow();\n      const timeDelta = currentTime - this.prevTime;\n      this.prevTime = currentTime;\n      this.accumulatedTime = this.accumulatedTime + timeDelta;\n      // more than 10 frames? prolly switched browser tab. Restart\n      if (this.accumulatedTime > msPerFrame * 10) {\n        this.accumulatedTime = 0;\n      }\n\n      if (this.accumulatedTime === 0) {\n        // no need to cancel animationID here; shouldn't have any in flight\n        this.animationID = null;\n        this.startAnimationIfNecessary();\n        return;\n      }\n\n      let currentFrameCompletion =\n        (this.accumulatedTime -\n          Math.floor(this.accumulatedTime / msPerFrame) * msPerFrame) /\n        msPerFrame;\n      const framesToCatchUp = Math.floor(this.accumulatedTime / msPerFrame);\n\n      let [\n        newMergedPropsStyles,\n        newCurrentStyles,\n        newCurrentVelocities,\n        newLastIdealStyles,\n        newLastIdealVelocities,\n      ] = mergeAndSync(\n        (this.props.willEnter: any),\n        (this.props.willLeave: any),\n        (this.props.didLeave: any),\n        this.state.mergedPropsStyles,\n        destStyles,\n        this.state.currentStyles,\n        this.state.currentVelocities,\n        this.state.lastIdealStyles,\n        this.state.lastIdealVelocities,\n      );\n      for (let i = 0; i < newMergedPropsStyles.length; i++) {\n        const newMergedPropsStyle = newMergedPropsStyles[i].style;\n        let newCurrentStyle: PlainStyle = {};\n        let newCurrentVelocity: Velocity = {};\n        let newLastIdealStyle: PlainStyle = {};\n        let newLastIdealVelocity: Velocity = {};\n\n        for (let key in newMergedPropsStyle) {\n          if (!Object.prototype.hasOwnProperty.call(newMergedPropsStyle, key)) {\n            continue;\n          }\n\n          const styleValue = newMergedPropsStyle[key];\n          if (typeof styleValue === 'number') {\n            newCurrentStyle[key] = styleValue;\n            newCurrentVelocity[key] = 0;\n            newLastIdealStyle[key] = styleValue;\n            newLastIdealVelocity[key] = 0;\n          } else {\n            let newLastIdealStyleValue = newLastIdealStyles[i][key];\n            let newLastIdealVelocityValue = newLastIdealVelocities[i][key];\n            for (let j = 0; j < framesToCatchUp; j++) {\n              [newLastIdealStyleValue, newLastIdealVelocityValue] = stepper(\n                msPerFrame / 1000,\n                newLastIdealStyleValue,\n                newLastIdealVelocityValue,\n                styleValue.val,\n                styleValue.stiffness,\n                styleValue.damping,\n                styleValue.precision,\n              );\n            }\n            const [nextIdealX, nextIdealV] = stepper(\n              msPerFrame / 1000,\n              newLastIdealStyleValue,\n              newLastIdealVelocityValue,\n              styleValue.val,\n              styleValue.stiffness,\n              styleValue.damping,\n              styleValue.precision,\n            );\n\n            newCurrentStyle[key] =\n              newLastIdealStyleValue +\n              (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion;\n            newCurrentVelocity[key] =\n              newLastIdealVelocityValue +\n              (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion;\n            newLastIdealStyle[key] = newLastIdealStyleValue;\n            newLastIdealVelocity[key] = newLastIdealVelocityValue;\n          }\n        }\n\n        newLastIdealStyles[i] = newLastIdealStyle;\n        newLastIdealVelocities[i] = newLastIdealVelocity;\n        newCurrentStyles[i] = newCurrentStyle;\n        newCurrentVelocities[i] = newCurrentVelocity;\n      }\n\n      this.animationID = null;\n      // the amount we're looped over above\n      this.accumulatedTime -= framesToCatchUp * msPerFrame;\n\n      this.setState({\n        currentStyles: newCurrentStyles,\n        currentVelocities: newCurrentVelocities,\n        lastIdealStyles: newLastIdealStyles,\n        lastIdealVelocities: newLastIdealVelocities,\n        mergedPropsStyles: newMergedPropsStyles,\n      });\n\n      this.unreadPropStyles = null;\n\n      this.startAnimationIfNecessary();\n    });\n  };\n\n  componentDidMount() {\n    this.prevTime = defaultNow();\n    this.startAnimationIfNecessary();\n  }\n\n  UNSAFE_componentWillReceiveProps(props: TransitionProps) {\n    if (this.unreadPropStyles) {\n      // previous props haven't had the chance to be set yet; set them here\n      this.clearUnreadPropStyle(this.unreadPropStyles);\n    }\n\n    const styles = props.styles;\n    if (typeof styles === 'function') {\n      this.unreadPropStyles = styles(\n        rehydrateStyles(\n          this.state.mergedPropsStyles,\n          this.unreadPropStyles,\n          this.state.lastIdealStyles,\n        ),\n      );\n    } else {\n      this.unreadPropStyles = styles;\n    }\n\n    if (this.animationID == null) {\n      this.prevTime = defaultNow();\n      this.startAnimationIfNecessary();\n    }\n  }\n\n  componentWillUnmount() {\n    this.unmounting = true;\n    if (this.animationID != null) {\n      defaultRaf.cancel(this.animationID);\n      this.animationID = null;\n    }\n  }\n\n  render(): ReactElement {\n    const hydratedStyles = rehydrateStyles(\n      this.state.mergedPropsStyles,\n      this.unreadPropStyles,\n      this.state.currentStyles,\n    );\n    const renderedChildren = this.props.children(hydratedStyles);\n    return renderedChildren && React.Children.only(renderedChildren);\n  }\n}\n"
  },
  {
    "path": "src/Types.js",
    "content": "/* @flow */\n\n// Babel 5.x doesn't support type parameters, so we make this alias here out of\n// Babel's sight.\n/* eslint-disable spaced-comment, no-undef */\n/*::\nimport type {Element} from 'react';\nexport type ReactElement = Element<*>;\n*/\n\n// === basic reused types ===\n// type of the second parameter of `spring(val, config)` all fields are optional\nexport type SpringHelperConfig = {\n  stiffness?: number,\n  damping?: number,\n  precision?: number,\n};\n// the object returned by `spring(value, yourConfig)`. For internal usage only!\nexport type OpaqueConfig = {\n  val: number,\n  stiffness: number,\n  damping: number,\n  precision: number,\n};\n// your typical style object given in props. Maps to a number or a spring config\nexport type Style = { [key: string]: number | OpaqueConfig };\n// the interpolating style object, with the same keys as the above Style object,\n// with the values mapped to numbers, naturally\nexport type PlainStyle = { [key: string]: number };\n// internal velocity object. Similar to PlainStyle, but whose numbers represent\n// speed. Might be exposed one day.\nexport type Velocity = { [key: string]: number };\n\n// === Motion ===\nexport type MotionProps = {\n  defaultStyle?: PlainStyle,\n  style: Style,\n  children: (interpolatedStyle: PlainStyle) => ReactElement,\n  onRest?: () => void,\n};\n\n// === StaggeredMotion ===\nexport type StaggeredProps = {\n  defaultStyles?: Array<PlainStyle>,\n  styles: (previousInterpolatedStyles: ?Array<PlainStyle>) => Array<Style>,\n  children: (interpolatedStyles: Array<PlainStyle>) => ReactElement,\n};\n\n// === TransitionMotion ===\nexport type TransitionStyle = {\n  key: string, // unique ID to identify component across render animations\n  data?: any, // optional data you want to carry along the style, e.g. itemText\n  style: Style, // actual style you're passing\n};\nexport type TransitionPlainStyle = {\n  key: string,\n  data?: any,\n  // same as TransitionStyle, passed as argument to style/children function\n  style: PlainStyle,\n};\nexport type WillEnter = (styleThatEntered: TransitionStyle) => PlainStyle;\nexport type WillLeave = (styleThatLeft: TransitionStyle) => ?Style;\nexport type DidLeave = (styleThatLeft: { key: string, data?: any }) => void;\n\nexport type TransitionProps = {\n  defaultStyles?: Array<TransitionPlainStyle>,\n  styles:\n    | Array<TransitionStyle>\n    | ((\n        previousInterpolatedStyles: ?Array<TransitionPlainStyle>,\n      ) => Array<TransitionStyle>),\n  children: (interpolatedStyles: Array<TransitionPlainStyle>) => ReactElement,\n  willEnter?: WillEnter,\n  willLeave?: WillLeave,\n  didLeave?: DidLeave,\n};\n"
  },
  {
    "path": "src/mapToZero.js",
    "content": "/* @flow */\nimport type { PlainStyle, Style } from './Types';\n\n// currently used to initiate the velocity style object to 0\nexport default function mapToZero(obj: Style | PlainStyle): PlainStyle {\n  let ret = {};\n  for (const key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) {\n      ret[key] = 0;\n    }\n  }\n  return ret;\n}\n"
  },
  {
    "path": "src/mergeDiff.js",
    "content": "/* @flow */\nimport type { TransitionStyle } from './Types';\n\n// core keys merging algorithm. If previous render's keys are [a, b], and the\n// next render's [c, b, d], what's the final merged keys and ordering?\n\n// - c and a must both be before b\n// - b before d\n// - ordering between a and c ambiguous\n\n// this reduces to merging two partially ordered lists (e.g. lists where not\n// every item has a definite ordering, like comparing a and c above). For the\n// ambiguous ordering we deterministically choose to place the next render's\n// item after the previous'; so c after a\n\n// this is called a topological sorting. Except the existing algorithms don't\n// work well with js bc of the amount of allocation, and isn't optimized for our\n// current use-case bc the runtime is linear in terms of edges (see wiki for\n// meaning), which is huge when two lists have many common elements\nexport default function mergeDiff(\n  prev: Array<TransitionStyle>,\n  next: Array<TransitionStyle>,\n  onRemove: (\n    prevIndex: number,\n    prevStyleCell: TransitionStyle,\n  ) => ?TransitionStyle,\n): Array<TransitionStyle> {\n  // bookkeeping for easier access of a key's index below. This is 2 allocations +\n  // potentially triggering chrome hash map mode for objs (so it might be faster\n  // to loop through and find a key's index each time), but I no longer care\n  let prevKeyIndex: { [key: string]: number } = {};\n  for (let i = 0; i < prev.length; i++) {\n    prevKeyIndex[prev[i].key] = i;\n  }\n  let nextKeyIndex: { [key: string]: number } = {};\n  for (let i = 0; i < next.length; i++) {\n    nextKeyIndex[next[i].key] = i;\n  }\n\n  // first, an overly elaborate way of merging prev and next, eliminating\n  // duplicates (in terms of keys). If there's dupe, keep the item in next).\n  // This way of writing it saves allocations\n  let ret = [];\n  for (let i = 0; i < next.length; i++) {\n    ret[i] = next[i];\n  }\n  for (let i = 0; i < prev.length; i++) {\n    if (!Object.prototype.hasOwnProperty.call(nextKeyIndex, prev[i].key)) {\n      // this is called my TM's `mergeAndSync`, which calls willLeave. We don't\n      // merge in keys that the user desires to kill\n      const fill = onRemove(i, prev[i]);\n      if (fill != null) {\n        ret.push(fill);\n      }\n    }\n  }\n\n  // now all the items all present. Core sorting logic to have the right order\n  return ret.sort((a, b) => {\n    const nextOrderA = nextKeyIndex[a.key];\n    const nextOrderB = nextKeyIndex[b.key];\n    const prevOrderA = prevKeyIndex[a.key];\n    const prevOrderB = prevKeyIndex[b.key];\n\n    if (nextOrderA != null && nextOrderB != null) {\n      // both keys in next\n      return nextKeyIndex[a.key] - nextKeyIndex[b.key];\n    } else if (prevOrderA != null && prevOrderB != null) {\n      // both keys in prev\n      return prevKeyIndex[a.key] - prevKeyIndex[b.key];\n    } else if (nextOrderA != null) {\n      // key a in next, key b in prev\n\n      // how to determine the order between a and b? We find a \"pivot\" (term\n      // abuse), a key present in both prev and next, that is sandwiched between\n      // a and b. In the context of our above example, if we're comparing a and\n      // d, b's (the only) pivot\n      for (let i = 0; i < next.length; i++) {\n        const pivot = next[i].key;\n        if (!Object.prototype.hasOwnProperty.call(prevKeyIndex, pivot)) {\n          continue;\n        }\n\n        if (\n          nextOrderA < nextKeyIndex[pivot] &&\n          prevOrderB > prevKeyIndex[pivot]\n        ) {\n          return -1;\n        } else if (\n          nextOrderA > nextKeyIndex[pivot] &&\n          prevOrderB < prevKeyIndex[pivot]\n        ) {\n          return 1;\n        }\n      }\n      // pluggable. default to: next bigger than prev\n      return 1;\n    }\n    // prevOrderA, nextOrderB\n    for (let i = 0; i < next.length; i++) {\n      const pivot = next[i].key;\n      if (!Object.prototype.hasOwnProperty.call(prevKeyIndex, pivot)) {\n        continue;\n      }\n      if (\n        nextOrderB < nextKeyIndex[pivot] &&\n        prevOrderA > prevKeyIndex[pivot]\n      ) {\n        return 1;\n      } else if (\n        nextOrderB > nextKeyIndex[pivot] &&\n        prevOrderA < prevKeyIndex[pivot]\n      ) {\n        return -1;\n      }\n    }\n    // pluggable. default to: next bigger than prev\n    return -1;\n  });\n}\n"
  },
  {
    "path": "src/presets.js",
    "content": "/* @flow */\nexport default {\n  noWobble: { stiffness: 170, damping: 26 }, // the default, if nothing provided\n  gentle: { stiffness: 120, damping: 14 },\n  wobbly: { stiffness: 180, damping: 12 },\n  stiff: { stiffness: 210, damping: 20 },\n};\n"
  },
  {
    "path": "src/react-motion.js",
    "content": "/* @flow */\nexport { default as Motion } from './Motion';\nexport { default as StaggeredMotion } from './StaggeredMotion';\nexport { default as TransitionMotion } from './TransitionMotion';\nexport { default as spring } from './spring';\nexport { default as presets } from './presets';\nexport { default as stripStyle } from './stripStyle';\n\n// deprecated, dummy warning function\nexport { default as reorderKeys } from './reorderKeys';\n"
  },
  {
    "path": "src/reorderKeys.js",
    "content": "/* @flow */\n\nlet hasWarned = false;\nexport default function reorderKeys() {\n  if (process.env.NODE_ENV === 'development') {\n    if (!hasWarned) {\n      hasWarned = true;\n      console.error(\n        \"`reorderKeys` has been removed, since it is no longer needed for TransitionMotion's new styles array API.\",\n      );\n    }\n  }\n}\n"
  },
  {
    "path": "src/shouldStopAnimation.js",
    "content": "/* @flow */\nimport type { PlainStyle, Style, Velocity } from './Types';\n\n// usage assumption: currentStyle values have already been rendered but it says\n// nothing of whether currentStyle is stale (see unreadPropStyle)\nexport default function shouldStopAnimation(\n  currentStyle: PlainStyle,\n  style: Style,\n  currentVelocity: Velocity,\n): boolean {\n  for (let key in style) {\n    if (!Object.prototype.hasOwnProperty.call(style, key)) {\n      continue;\n    }\n\n    if (currentVelocity[key] !== 0) {\n      return false;\n    }\n\n    const styleValue =\n      typeof style[key] === 'number' ? style[key] : style[key].val;\n    // stepper will have already taken care of rounding precision errors, so\n    // won't have such thing as 0.9999 !=== 1\n    if (currentStyle[key] !== styleValue) {\n      return false;\n    }\n  }\n\n  return true;\n}\n"
  },
  {
    "path": "src/spring.js",
    "content": "/* @flow */\nimport presets from './presets';\nimport type { OpaqueConfig, SpringHelperConfig } from './Types';\n\nconst defaultConfig = {\n  ...presets.noWobble,\n  precision: 0.01,\n};\n\nexport default function spring(\n  val: number,\n  config?: SpringHelperConfig,\n): OpaqueConfig {\n  return { ...defaultConfig, ...config, val };\n}\n"
  },
  {
    "path": "src/stepper.js",
    "content": "/* @flow */\n\n// stepper is used a lot. Saves allocation to return the same array wrapper.\n// This is fine and danger-free against mutations because the callsite\n// immediately destructures it and gets the numbers inside without passing the\n// array reference around.\nlet reusedTuple: [number, number] = [0, 0];\nexport default function stepper(\n  secondPerFrame: number,\n  x: number,\n  v: number,\n  destX: number,\n  k: number,\n  b: number,\n  precision: number,\n): [number, number] {\n  // Spring stiffness, in kg / s^2\n\n  // for animations, destX is really spring length (spring at rest). initial\n  // position is considered as the stretched/compressed position of a spring\n  const Fspring = -k * (x - destX);\n\n  // Damping, in kg / s\n  const Fdamper = -b * v;\n\n  // usually we put mass here, but for animation purposes, specifying mass is a\n  // bit redundant. you could simply adjust k and b accordingly\n  // let a = (Fspring + Fdamper) / mass;\n  const a = Fspring + Fdamper;\n\n  const newV = v + a * secondPerFrame;\n  const newX = x + newV * secondPerFrame;\n\n  if (Math.abs(newV) < precision && Math.abs(newX - destX) < precision) {\n    reusedTuple[0] = destX;\n    reusedTuple[1] = 0;\n    return reusedTuple;\n  }\n\n  reusedTuple[0] = newX;\n  reusedTuple[1] = newV;\n  return reusedTuple;\n}\n"
  },
  {
    "path": "src/stripStyle.js",
    "content": "/* @flow */\n// turn {x: {val: 1, stiffness: 1, damping: 2}, y: 2} generated by\n// `{x: spring(1, {stiffness: 1, damping: 2}), y: 2}` into {x: 1, y: 2}\n\nimport type { Style, PlainStyle } from './Types';\n\nexport default function stripStyle(style: Style): PlainStyle {\n  let ret = {};\n  for (const key in style) {\n    if (!Object.prototype.hasOwnProperty.call(style, key)) {\n      continue;\n    }\n    ret[key] = typeof style[key] === 'number' ? style[key] : style[key].val;\n  }\n  return ret;\n}\n"
  },
  {
    "path": "test/Motion-test.js",
    "content": "/* eslint-disable class-methods-use-this */\nimport React from 'react';\nimport {spring} from '../src/react-motion';\nimport createMockRaf from './createMockRaf';\nimport TestUtils from 'react-dom/test-utils';\n\nconst {createSpy} = global.jasmine;\n\nconst injector = require('inject-loader!../src/Motion');\n\n// temporarily putting the animation loop test here\n// TODO: put it in the correct file\ndescribe('animation loop', () => {\n  let Motion;\n  let mockRaf;\n\n  beforeEach(() => {\n    mockRaf = createMockRaf();\n    Motion = injector({\n      raf: mockRaf.raf,\n      'performance-now': mockRaf.now,\n    }).default;\n  });\n\n  it('should interpolate correctly when the timer is perfect', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <Motion defaultStyle={{a: 0}} style={{a: spring(10)}}>\n            {({a}) => {\n              count.push(a);\n              return null;\n            }}\n          </Motion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([0]);\n    mockRaf.step(5);\n    expect(count).toEqual([\n      0,\n      0.4722222222222222,\n      1.1897376543209877,\n      2.0123698988340193,\n      2.8557218143909084,\n      3.670989925304686,\n    ]);\n  });\n\n  it('should work with negative numbers', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <Motion defaultStyle={{a: -10}} style={{a: spring(-100)}}>\n            {({a}) => {\n              count.push(a);\n              return null;\n            }}\n          </Motion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    mockRaf.step(5);\n    expect(count).toEqual([\n      -10,\n      -14.25,\n      -20.70763888888889,\n      -28.11132908950617,\n      -35.70149632951818,\n      -43.038909327742175,\n    ]);\n  });\n\n  it('should interpolate correctly when the timer is imperfect', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <Motion defaultStyle={{a: 0}} style={{a: spring(10)}}>\n            {({a}) => {\n              count.push(a);\n              return null;\n            }}\n          </Motion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([0]);\n    mockRaf.step(10, 0);\n    // 0 accumulatedTime, bail out of recalc & render\n    expect(count).toEqual([0]);\n\n    mockRaf.step(3, 0.1);\n    expect(count).toEqual([\n      0,\n      // notice the numbers are all very close together\n      0.002833333333333333,\n      0.005666666666666666,\n      0.0085,\n    ]);\n    // interval too large; bail\n    mockRaf.step(10, 999);\n    expect(count).toEqual([\n      0,\n      0.002833333333333333,\n      0.005666666666666666,\n      0.0085,\n    ]);\n    // more than one theoretical frame passed, each tick\n    mockRaf.step(2, 36);\n    expect(count).toEqual([\n      0,\n      0.002833333333333333,\n      0.005666666666666666,\n      0.0085,\n      1.3213588134430725,\n      3.116607609883317,\n    ]);\n  });\n});\n\ndescribe('Motion', () => {\n  let Motion;\n  let mockRaf;\n\n  beforeEach(() => {\n    mockRaf = createMockRaf();\n    Motion = injector({\n      raf: mockRaf.raf,\n      'performance-now': mockRaf.now,\n    }).default;\n  });\n\n  it('should allow returning null from children function', () => {\n    class App extends React.Component {\n      render() {\n        // shouldn't throw here\n        return <Motion style={{a: 0}}>{() => null}</Motion>;\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n  });\n\n  it('should not throw on unmount', () => {\n    spyOn(console, 'error');\n    let kill = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          kill: false,\n        };\n      }\n      componentWillMount() {\n        kill = () => this.setState({kill: true});\n      }\n      render() {\n        return this.state.kill\n          ? null\n          : <Motion defaultStyle={{a: 0}} style={{a: spring(10)}}>{() => null}</Motion>;\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n    mockRaf.step(2);\n    kill();\n    mockRaf.step(3);\n    expect(console.error).not.toHaveBeenCalled();\n  });\n\n  it('should allow a defaultStyle', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <Motion defaultStyle={{a: 0}} style={{a: spring(10)}}>\n            {({a}) => {\n              count.push(a);\n              return null;\n            }}\n          </Motion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([0]);\n    mockRaf.step(4);\n    expect(count).toEqual([\n      0,\n      0.4722222222222222,\n      1.1897376543209877,\n      2.0123698988340193,\n      2.8557218143909084,\n    ]);\n  });\n\n  it('should accept different spring configs', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <Motion\n              defaultStyle={{a: 0}}\n              style={{a: spring(10, {stiffness: 100, damping: 50, precision: 16})}}>\n            {({a}) => {\n              count.push(a);\n              return null;\n            }}\n          </Motion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    mockRaf.step(99);\n    expect(count).toEqual([\n      0,\n      0.2777777777777778,\n      0.5941358024691358,\n      0.9081361454046639,\n      1.213021309632678,\n      1.5079182450697726,\n      1.7929588941684615,\n      2.0684390330691236,\n      10,\n    ]);\n  });\n\n  it('should interpolate many values', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <Motion\n            defaultStyle={{a: 0, b: 10}}\n            style={{a: spring(10), b: spring(410)}}>\n            {({a, b}) => {\n              count.push([a, b]);\n              return null;\n            }}\n          </Motion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([[0, 10]]);\n    mockRaf.step(4);\n    expect(count).toEqual([\n      [0, 10],\n      [0.4722222222222222, 28.888888888888886],\n      [1.1897376543209877, 57.589506172839506],\n      [2.0123698988340193, 90.49479595336075],\n      [2.8557218143909084, 124.22887257563633],\n    ]);\n  });\n\n  it('should work with nested Motions', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <Motion defaultStyle={{owner: 0}} style={{owner: spring(10)}}>\n            {({owner}) => {\n              count.push(owner);\n              return (\n                <Motion defaultStyle={{child: 10}} style={{child: spring(400)}}>\n                  {({child}) => {\n                    count.push(child);\n                    return null;\n                  }}\n                </Motion>\n              );\n            }}\n          </Motion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([0, 10]);\n    mockRaf.step();\n    expect(count).toEqual([\n      0,\n      10,\n      28.416666666666668, // child\n      0.4722222222222222, // owner\n      28.416666666666668, // child\n    ]);\n    mockRaf.step(2);\n    expect(count).toEqual([\n      0,\n      10,\n      28.416666666666668,\n      0.4722222222222222,\n      28.416666666666668,\n\n      56.39976851851852, // child\n      1.1897376543209877, // owner\n      56.39976851851852, // child\n\n      88.48242605452674, // child\n      2.0123698988340193, // owner\n      88.48242605452674, // child\n    ]);\n  });\n\n  it('should reach destination value', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <Motion defaultStyle={{a: 0}} style={{a: spring(400)}}>\n            {({a}) => {\n              count.push(a);\n              return null;\n            }}\n          </Motion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([0]);\n    mockRaf.step(111);\n    expect(count.slice(0, 5)).toEqual([\n      0,\n      18.888888888888886,\n      47.589506172839506,\n      80.49479595336075,\n      114.22887257563633,\n    ]);\n    expect(count.length).toBe(91);\n    expect(count[count.length - 1]).toEqual(400);\n  });\n\n  it('should support jumping to value', () => {\n    let count = [];\n    let setState = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          p: false,\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <Motion style={{a: this.state.p ? 400 : spring(0)}}>\n            {({a}) => {\n              count.push(a);\n              return null;\n            }}\n          </Motion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([0]);\n    setState({p: true});\n    expect(count).toEqual([\n      0,\n      0, // this new 0 comes from owner update, causing Motion to re-render\n    ]);\n    mockRaf.step(10);\n    // jumped to end, will only have two renders no matter how much we step\n    expect(count).toEqual([\n      0,\n      0,\n      400,\n    ]);\n    setState({p: false});\n    mockRaf.step(3);\n    expect(count).toEqual([\n      0,\n      0,\n      400,\n      400, // redundant 0 comes from owner update again\n      381.1111111111111,\n      352.4104938271605,\n      319.5052040466392,\n    ]);\n  });\n\n  it('should call onRest at the end of an animation', () => {\n    const onRest = createSpy('onRest');\n    let result = 0;\n\n    class App extends React.Component {\n      render() {\n        return (\n          <Motion\n            defaultStyle={{a: 0}}\n            style={{a: spring(5, {stiffness: 380, damping: 18, precision: 1})}}\n            onRest={onRest}\n          >\n            {\n              ({a}) => {\n                result = a;\n                return null;\n              }\n            }\n          </Motion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n\n    mockRaf.step(22);\n\n    expect(result).toEqual(5);\n    expect(onRest.calls.count()).toEqual(1);\n  });\n\n\n  it('should not call onRest if an animation is still in progress', () => {\n    const onRest = createSpy('onRest');\n    let resultA = 0;\n    let resultB = 0;\n\n    class App extends React.Component {\n      render() {\n        return (\n          <Motion\n            defaultStyle={{a: 0, b: 0}}\n            style={{\n              a: spring(5, {stiffness: 380, damping: 18, precision: 1}),\n              b: spring(500, {stiffness: 380, damping: 18, precision: 1}),\n            }}\n            onRest={onRest}\n          >\n            {\n              ({a, b}) => {\n                resultA = a;\n                resultB = b;\n                return null;\n              }\n            }\n          </Motion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n\n    mockRaf.step(22);\n\n    expect(resultA).toEqual(5);\n    expect(resultB).not.toEqual(500);\n    expect(onRest).not.toHaveBeenCalled();\n  });\n\n\n  it('should not call onRest unless an animation occurred', () => {\n    const onRest = createSpy('onRest');\n\n    let setState;\n\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          a: spring(0),\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <Motion\n            defaultStyle={{a: 0}}\n            style={{a: this.state.a}}\n            onRest={onRest}\n          >\n            {() => null}\n          </Motion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n    mockRaf.step();\n    setState({a: 50});\n    mockRaf.step();\n\n    expect(onRest).not.toHaveBeenCalled();\n  });\n\n  it('should behave well when many owner updates come in-between rAFs', () => {\n    let count = [];\n    let setState = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          a: spring(0),\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <Motion style={this.state}>\n            {a => {\n              count.push(a);\n              return null;\n            }}\n          </Motion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([{a: 0}]);\n    setState({a: 400});\n    setState({a: spring(100)});\n    mockRaf.step(2);\n    setState({a: spring(400)});\n    mockRaf.step(2);\n    expect(count).toEqual([\n      {a: 0},\n      {a: 0}, // this new 0 comes from owner update, causing Motion to re-render\n      {a: 400},\n      {a: 385.8333333333333},\n      {a: 364.3078703703703},\n      {a: 364.3078703703703},\n      {a: 353.79556970164606},\n      {a: 350.02047519790233},\n    ]);\n    mockRaf.step(999);\n    expect(count.length).toBe(85);\n    setState({a: spring(400)});\n    // make sure we're still updating children even if there's nothing to interp\n    expect(count.length).toBe(86);\n  });\n});\n"
  },
  {
    "path": "test/StaggeredMotion-test.js",
    "content": "/* eslint-disable class-methods-use-this */\nimport React from 'react';\nimport {spring} from '../src/react-motion';\nimport createMockRaf from './createMockRaf';\nimport TestUtils from 'react-dom/test-utils';\n\nconst injector = require('inject-loader!../src/StaggeredMotion');\n\ndescribe('StaggeredMotion', () => {\n  let StaggeredMotion;\n  let mockRaf;\n\n  beforeEach(() => {\n    mockRaf = createMockRaf();\n    StaggeredMotion = injector({\n      raf: mockRaf.raf,\n      'performance-now': mockRaf.now,\n    }).default;\n  });\n\n  it('should allow returning null from children function', () => {\n    class App extends React.Component {\n      render() {\n        // shouldn't throw here\n        return (\n          <StaggeredMotion styles={() => [{a: 0}]}>\n            {() => null}\n          </StaggeredMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n  });\n\n  it('should not throw on unmount', () => {\n    spyOn(console, 'error');\n    let kill = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          kill: false,\n        };\n      }\n      componentWillMount() {\n        kill = () => this.setState({kill: true});\n      }\n      render() {\n        return this.state.kill\n          ? null\n          : <StaggeredMotion defaultStyles={[{a: 0}]} styles={() => [{a: spring(10)}]}>\n              {() => null}\n            </StaggeredMotion>;\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n    mockRaf.step(2);\n    kill();\n    mockRaf.step(3);\n    expect(console.error).not.toHaveBeenCalled();\n  });\n\n  it('should allow a defaultStyles', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <StaggeredMotion\n            defaultStyles={[{a: 0}]}\n            styles={() => [{a: spring(10)}]}>\n            {([{a}]) => {\n              count.push(a);\n              return null;\n            }}\n          </StaggeredMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([0]);\n    mockRaf.step(4);\n    expect(count).toEqual([\n      0,\n      0.4722222222222222,\n      1.1897376543209877,\n      2.0123698988340193,\n      2.8557218143909084,\n    ]);\n  });\n\n  it('should accept different spring configs', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <StaggeredMotion\n            defaultStyles={[{a: 0}]}\n            styles={() => [{a: spring(10, {stiffness: 100, damping: 50, precision: 16})}]}>\n            {([{a}]) => {\n              count.push(a);\n              return null;\n            }}\n          </StaggeredMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    mockRaf.step(99);\n    expect(count).toEqual([\n      0,\n      0.2777777777777778,\n      0.5941358024691358,\n      0.9081361454046639,\n      1.213021309632678,\n      1.5079182450697726,\n      1.7929588941684615,\n      2.0684390330691236,\n      10,\n    ]);\n  });\n\n  it('should interpolate many values while staggering', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <StaggeredMotion\n            defaultStyles={[{a: 0, b: 10}, {a: 0, b: 10}]}\n            styles={prevStyles => {\n              return prevStyles.map((_, i) => i === 0\n                ? {a: spring(10), b: spring(410)}\n                : {a: spring(prevStyles[i - 1].a), b: spring(prevStyles[i - 1].b)});\n            }}>\n            {([{a, b}, {a: a2, b: b2}]) => {\n              count.push([a, b, a2, b2]);\n              return null;\n            }}\n          </StaggeredMotion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([[0, 10, 0, 10]]);\n    mockRaf.step(4);\n    expect(count).toEqual([\n      [0, 10, 0, 10],\n      [0.4722222222222222, 28.888888888888886, 0, 10],\n      [1.1897376543209877, 57.589506172839506, 0.02229938271604938, 10.891975308641975],\n      [2.0123698988340193, 90.49479595336075, 0.09006472908093276, 13.602589163237312],\n      [2.8557218143909084, 124.22887257563633, 0.18039409126848038, 17.215763650739216],\n    ]);\n  });\n\n  it('should work with nested Motions', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <StaggeredMotion defaultStyles={[{owner: 0}]} styles={() => [{owner: spring(10)}]}>\n            {([{owner}]) => {\n              count.push(owner);\n              return (\n                <StaggeredMotion defaultStyles={[{child: 10}]} styles={() => [{child: spring(400)}]}>\n                  {([{child}]) => {\n                    count.push(child);\n                    return null;\n                  }}\n                </StaggeredMotion>\n              );\n            }}\n          </StaggeredMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([0, 10]);\n    mockRaf.step();\n    expect(count).toEqual([\n      0,\n      10,\n      28.416666666666668, // child\n      0.4722222222222222, // owner\n      28.416666666666668, // child\n    ]);\n    mockRaf.step(2);\n    expect(count).toEqual([\n      0,\n      10,\n      28.416666666666668,\n      0.4722222222222222,\n      28.416666666666668,\n\n      56.39976851851852, // child\n      1.1897376543209877, // owner\n      56.39976851851852, // child\n\n      88.48242605452674, // child\n      2.0123698988340193, // owner\n      88.48242605452674, // child\n    ]);\n  });\n\n  // TODO: should animate one last time to reach true destination\n  // maybe shouldStopAnimation logic has a flaw\n  it('should reach destination value', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <StaggeredMotion\n            defaultStyles={[{a: 0, b: 10}, {a: 0, b: 10}]}\n            styles={prevStyles => {\n              return prevStyles.map((_, i) => i === 0\n                ? {a: spring(10), b: spring(410)}\n                : {a: spring(prevStyles[i - 1].a), b: spring(prevStyles[i - 1].b)});\n            }}>\n            {([{a, b}, {a: a2, b: b2}]) => {\n              count.push([a, b, a2, b2]);\n              return null;\n            }}\n          </StaggeredMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([[0, 10, 0, 10]]);\n    mockRaf.step(111);\n    expect(count.slice(0, 5)).toEqual([\n      [0, 10, 0, 10],\n      [0.4722222222222222, 28.888888888888886, 0, 10],\n      [1.1897376543209877, 57.589506172839506, 0.02229938271604938, 10.891975308641975],\n      [2.0123698988340193, 90.49479595336075, 0.09006472908093276, 13.602589163237312],\n      [2.8557218143909084, 124.22887257563633, 0.18039409126848038, 17.215763650739216],\n    ]);\n    expect(count.length).toBe(111);\n    expect(count[count.length - 1]).toEqual([10, 410, 10, 410]);\n  });\n\n  it('should support jumping to value', () => {\n    let count = [];\n    let setState = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          p: false,\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <StaggeredMotion styles={() => [{a: this.state.p ? 400 : spring(0)}]}>\n            {([{a}]) => {\n              count.push(a);\n              return null;\n            }}\n          </StaggeredMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([0]);\n    setState({p: true});\n    expect(count).toEqual([\n      0,\n      0, // this new 0 comes from owner update, causing StaggeredMotion to re-render\n    ]);\n    mockRaf.step(10);\n    // jumped to end, will only have two renders no matter how much we step\n    expect(count).toEqual([\n      0,\n      0,\n      400,\n    ]);\n    setState({p: false});\n    mockRaf.step(3);\n    expect(count).toEqual([\n      0,\n      0,\n      400,\n      400, // redundant 0 comes from owner update again\n      381.1111111111111,\n      352.4104938271605,\n      319.5052040466392,\n    ]);\n  });\n\n  it('should behave well when many owner updates come in-between rAFs', () => {\n    let count = [];\n    let setState = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          a: spring(0),\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <StaggeredMotion styles={() => [this.state]}>\n            {([a]) => {\n              count.push(a);\n              return null;\n            }}\n          </StaggeredMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([{a: 0}]);\n    setState({a: 400});\n    setState({a: spring(100)});\n    mockRaf.step(2);\n    setState({a: spring(400)});\n    mockRaf.step(2);\n    expect(count).toEqual([\n      {a: 0},\n      {a: 0}, // this new 0 comes from owner update, causing StaggeredMotion to re-render\n      {a: 400},\n      {a: 385.8333333333333},\n      {a: 364.3078703703703},\n      {a: 364.3078703703703},\n      {a: 353.79556970164606},\n      {a: 350.02047519790233},\n    ]);\n    mockRaf.step(999);\n    expect(count.length).toBe(85);\n    setState({a: spring(400)});\n    // make sure we're still updating children even if there's nothing to interp\n    expect(count.length).toBe(86);\n  });\n});\n"
  },
  {
    "path": "test/TransitionMotion-test.js",
    "content": "/* eslint-disable class-methods-use-this */\nimport React from 'react';\nimport {spring} from '../src/react-motion';\nimport createMockRaf from './createMockRaf';\nimport TestUtils from 'react-dom/test-utils';\n\nconst injector = require('inject-loader!../src/TransitionMotion');\n\ndescribe('TransitionMotion', () => {\n  let TransitionMotion;\n  let mockRaf;\n\n  beforeEach(() => {\n    mockRaf = createMockRaf();\n    TransitionMotion = injector({\n      raf: mockRaf.raf,\n      'performance-now': mockRaf.now,\n    }).default;\n  });\n\n  it('should allow returning null from children function', () => {\n    class App extends React.Component {\n      render() {\n        // shouldn't throw here\n        return <TransitionMotion styles={[{key: '1', style: {}}]}>{() => null}</TransitionMotion>;\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n  });\n\n  it('should not throw on unmount', () => {\n    spyOn(console, 'error');\n    let kill = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          kill: false,\n        };\n      }\n      componentWillMount() {\n        kill = () => this.setState({kill: true});\n      }\n      render() {\n        return this.state.kill\n          ? null\n          : <TransitionMotion\n              defaultStyles={[{key: '1', style: {x: 0}}]}\n              styles={[{key: '1', style: {x: spring(10)}}]}>\n              {() => null}\n            </TransitionMotion>;\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n    mockRaf.step(2);\n    kill();\n    mockRaf.step(3);\n    expect(console.error).not.toHaveBeenCalled();\n  });\n\n  it('should not throw on unmount with style function', () => {\n    // similar as above test\n    spyOn(console, 'error');\n    let kill = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n        this.state = {\n          kill: false,\n        };\n      }\n      componentWillMount() {\n        kill = () => this.setState({kill: true});\n      }\n      render() {\n        return this.state.kill\n          ? null\n          : <TransitionMotion\n              defaultStyles={[{key: '1', style: {x: 0}}]}\n              styles={() => [{key: '1', style: {x: spring(10)}}]}>\n              {() => null}\n            </TransitionMotion>;\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n    mockRaf.step(2);\n    kill();\n    mockRaf.step(3);\n    expect(console.error).not.toHaveBeenCalled();\n  });\n\n  it('should allow a defaultStyles', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <TransitionMotion\n            defaultStyles={[{key: '1', style: {a: 0}}]}\n            styles={[{key: '1', style: {a: spring(10)}}]}>\n            {([{style}]) => {\n              count.push(style);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([{a: 0}]);\n    mockRaf.step(4);\n    expect(count).toEqual([\n      {a: 0},\n      {a: 0.4722222222222222},\n      {a: 1.1897376543209877},\n      {a: 2.0123698988340193},\n      {a: 2.8557218143909084},\n    ]);\n  });\n\n  it('should accept different spring configs', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <TransitionMotion\n            defaultStyles={[{key: '1', style: {a: 0}}]}\n            styles={[\n              {key: '1', style: {a: spring(10, {stiffness: 100, damping: 50, precision: 16})}},\n            ]}>\n            {([{style: {a}}]) => {\n              count.push(a);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    mockRaf.step(99);\n    expect(count).toEqual([\n      0,\n      0.2777777777777778,\n      0.5941358024691358,\n      0.9081361454046639,\n      1.213021309632678,\n      1.5079182450697726,\n      1.7929588941684615,\n      2.0684390330691236,\n      10,\n    ]);\n  });\n\n  it('should interpolate many values', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <TransitionMotion\n            defaultStyles={[\n              {key: '1', style: {a: 0, b: 10}},\n              {key: '2', style: {c: 20}},\n            ]}\n            styles={[\n              {key: '1', style: {a: spring(10), b: spring(410)}},\n              {key: '2', style: {c: spring(420)}},\n            ]}>\n            {a => {\n              count.push(a);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([[\n      {key: '1', style: {a: 0, b: 10}, data: undefined},\n      {key: '2', style: {c: 20}, data: undefined},\n    ]]);\n    mockRaf.step(4);\n    expect(count).toEqual([\n      [\n        {key: '1', style: {a: 0, b: 10}, data: undefined},\n        {key: '2', style: {c: 20}, data: undefined},\n      ],\n      [\n        {key: '1', style: {a: 0.4722222222222222, b: 28.888888888888886}, data: undefined},\n        {key: '2', style: {c: 38.888888888888886}, data: undefined},\n      ],\n      [\n        {key: '1', style: {a: 1.1897376543209877, b: 57.589506172839506}, data: undefined},\n        {key: '2', style: {c: 67.589506172839506}, data: undefined},\n      ],\n      [\n        {key: '1', style: {a: 2.0123698988340193, b: 90.49479595336075}, data: undefined},\n        {key: '2', style: {c: 100.49479595336075}, data: undefined},\n      ],\n      [\n        {key: '1', style: {a: 2.8557218143909084, b: 124.22887257563633}, data: undefined},\n        {key: '2', style: {c: 134.22887257563632}, data: undefined},\n      ],\n    ]);\n  });\n\n  it('should invoke didLeave in last frame', () => {\n    let count = [];\n    let setState = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          val: [{key: '1', style: {x: spring(10)}}],\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <TransitionMotion\n            styles={this.state.val}\n            willEnter={() => ({x: 0})}\n            willLeave={() => ({x: spring(0)})}\n            didLeave={(a) => { count.push(a); }}>\n            {() => {\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([]);\n    setState({\n      val: [{key: '2', style: {x: 10}}],\n    });\n    mockRaf.step(999);\n    expect(count).toEqual([\n      {key: '1', data: undefined},\n    ]);\n  });\n\n  it('should work with nested TransitionMotions', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <TransitionMotion\n            defaultStyles={[{key: 'owner', style: {x: 0}}]}\n            styles={[{key: 'owner', style: {x: spring(10)}}]}>\n            {([{style}]) => {\n              count.push(style);\n              return (\n                <TransitionMotion\n                  defaultStyles={[{key: 'child', style: {a: 10}}]}\n                  styles={[{key: 'child', style: {a: spring(400)}}]}>\n                  {([{style: s}]) => {\n                    count.push(s);\n                    return null;\n                  }}\n                </TransitionMotion>\n              );\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([\n      {x: 0},\n      {a: 10},\n    ]);\n    mockRaf.step();\n    expect(count).toEqual([\n      {x: 0},\n      {a: 10},\n      {a: 28.416666666666668}, // child\n      {x: 0.4722222222222222}, // owner\n      {a: 28.416666666666668}, // child\n    ]);\n    mockRaf.step(2);\n    expect(count).toEqual([\n      {x: 0},\n      {a: 10},\n      {a: 28.416666666666668},\n      {x: 0.4722222222222222},\n      {a: 28.416666666666668},\n\n      {a: 56.39976851851852}, // child\n      {x: 1.1897376543209877}, // owner\n      {a: 56.39976851851852}, // child\n\n      {a: 88.48242605452674}, // child\n      {x: 2.0123698988340193}, // owner\n      {a: 88.48242605452674}, // child\n    ]);\n  });\n\n  it('should reach destination value', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <TransitionMotion\n            defaultStyles={[{key: '1', style: {a: 0}}]}\n            styles={[{key: '1', style: {a: spring(400)}}]}>\n            {([{style: {a}}]) => {\n              count.push(a);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([0]);\n    // Move \"time\" until we reach the final styles value\n    mockRaf.step(111);\n    expect(count.slice(0, 5)).toEqual([\n      0,\n      18.888888888888886,\n      47.589506172839506,\n      80.49479595336075,\n      114.22887257563633,\n    ]);\n    expect(count[count.length - 1]).toEqual(400);\n  });\n\n  it('should support jumping to value', () => {\n    let count = [];\n    let setState = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          p: false,\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <TransitionMotion\n            styles={[{key: '1', style: {x: this.state.p ? 400 : spring(0)}}]}>\n            {([{style}]) => {\n              count.push(style);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([{x: 0}]);\n    setState({p: true});\n    expect(count).toEqual([\n      {x: 0},\n      {x: 0}, // this new 0 comes from owner update, causing TransitionMotion to re-render\n    ]);\n    mockRaf.step(10);\n    // jumped to end, will only have two renders no matter how much we step\n    expect(count).toEqual([\n      {x: 0},\n      {x: 0},\n      {x: 400},\n    ]);\n    setState({p: false});\n    mockRaf.step(3);\n    expect(count).toEqual([\n      {x: 0},\n      {x: 0},\n      {x: 400},\n      {x: 400}, // redundant 0 comes from owner update again\n      {x: 381.1111111111111},\n      {x: 352.4104938271605},\n      {x: 319.5052040466392},\n    ]);\n  });\n\n  it('should behave well when many owner updates come in-between rAFs', () => {\n    let count = [];\n    let setState = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          val: [{key: '1', style: {x: spring(0)}}],\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <TransitionMotion\n            styles={this.state.val}\n            willEnter={() => ({y: 0})}\n            willLeave={() => ({y: spring(0)})}>\n            {a => {\n              count.push(a);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([[{key: '1', style: {x: 0}, data: undefined}]]);\n    setState({\n      val: [{key: '1', style: {x: 400}}, {key: '2', style: {y: 10}}],\n    });\n    setState({\n      val: [{key: '1', style: {x: spring(100)}}],\n    });\n    mockRaf.step(2);\n    setState({\n      val: [{key: '1', style: {x: spring(400)}}],\n    });\n    mockRaf.step(2);\n    expect(count).toEqual([\n      [{key: '1', style: {x: 0}, data: undefined}],\n      // this new 0 comes from owner update, causing TransitionMotion to\n      // re-render\n      [{key: '1', style: {x: 0}, data: undefined}],\n      [\n        {key: '1', style: {x: 400}, data: undefined},\n        {key: '2', style: {y: 10}, data: undefined},\n      ],\n      [\n        {key: '1', style: {x: 385.8333333333333}, data: undefined},\n        {key: '2', style: {y: 9.527777777777779}, data: undefined},\n      ],\n      [\n        {key: '1', style: {x: 364.3078703703703}, data: undefined},\n        {key: '2', style: {y: 8.810262345679014}, data: undefined},\n      ],\n      [\n        {key: '1', style: {x: 364.3078703703703}, data: undefined},\n        {key: '2', style: {y: 8.810262345679014}, data: undefined},\n      ],\n      [\n        {key: '1', style: {x: 353.79556970164606}, data: undefined},\n        {key: '2', style: {y: 7.9876301011659825}, data: undefined},\n      ],\n      [\n        {key: '1', style: {x: 350.02047519790233}, data: undefined},\n        {key: '2', style: {y: 7.144278185609093}, data: undefined},\n      ],\n    ]);\n    mockRaf.step(999);\n    expect(count.length).toBe(85);\n    setState({a: spring(400)});\n    // make sure we're still updating children even if there's nothing to interp\n    expect(count.length).toBe(86);\n  });\n\n  it('should behave well when many owner styles function updates come in-between rAFs', () => {\n    let count = [];\n    let setState = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          val: [{key: '1', style: {x: spring(0)}}],\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <TransitionMotion\n            styles={() => this.state.val}\n            willEnter={() => ({y: 0})}\n            willLeave={() => ({y: spring(0)})}>\n            {a => {\n              count.push(a);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([[{key: '1', style: {x: 0}, data: undefined}]]);\n    setState({\n      val: [{key: '1', style: {x: 400}}, {key: '2', style: {y: 10}}],\n    });\n    setState({\n      val: [{key: '1', style: {x: spring(100)}}],\n    });\n    mockRaf.step(2);\n    setState({\n      val: [{key: '1', style: {x: spring(400)}}],\n    });\n    mockRaf.step(2);\n    expect(count).toEqual([\n      [{key: '1', style: {x: 0}, data: undefined}],\n      // this new 0 comes from owner update, causing TransitionMotion to\n      // re-render\n      [{key: '1', style: {x: 0}, data: undefined}],\n      [\n        {key: '1', style: {x: 400}, data: undefined},\n        {key: '2', style: {y: 10}, data: undefined},\n      ],\n      [\n        {key: '1', style: {x: 385.8333333333333}, data: undefined},\n        {key: '2', style: {y: 9.527777777777779}, data: undefined},\n      ],\n      [\n        {key: '1', style: {x: 364.3078703703703}, data: undefined},\n        {key: '2', style: {y: 8.810262345679014}, data: undefined},\n      ],\n      [\n        {key: '1', style: {x: 364.3078703703703}, data: undefined},\n        {key: '2', style: {y: 8.810262345679014}, data: undefined},\n      ],\n      [\n        {key: '1', style: {x: 353.79556970164606}, data: undefined},\n        {key: '2', style: {y: 7.9876301011659825}, data: undefined},\n      ],\n      [\n        {key: '1', style: {x: 350.02047519790233}, data: undefined},\n        {key: '2', style: {y: 7.144278185609093}, data: undefined},\n      ],\n    ]);\n    mockRaf.step(999);\n    expect(count.length).toBe(85);\n    setState({a: spring(400)});\n    // make sure we're still updating children even if there's nothing to interp\n    expect(count.length).toBe(86);\n  });\n\n  it('should transition things in/out at the beginning', () => {\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <TransitionMotion\n            willLeave={() => ({c: spring(0)})}\n            willEnter={() => ({d: 0})}\n            defaultStyles={[{key: '1', style: {a: 0, b: 10}}, {key: '2', style: {c: 20}}]}\n            styles={[\n              {key: '1', style: {a: spring(10), b: spring(410)}},\n              {key: '3', style: {d: spring(10)}},\n            ]}>\n            {a => {\n              count.push(a);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([\n      [\n        {key: '1', style: {a: 0, b: 10}, data: undefined},\n        {key: '2', style: {c: 20}, data: undefined},\n        {key: '3', style: {d: 0}, data: undefined},\n      ],\n    ]);\n    mockRaf.step(2);\n    expect(count).toEqual([\n      [\n        {key: '1', style: {a: 0, b: 10}, data: undefined},\n        {key: '2', style: {c: 20}, data: undefined},\n        {key: '3', style: {d: 0}, data: undefined},\n      ],\n      [\n        {key: '1', style: {a: 0.4722222222222222, b: 28.888888888888886}, data: undefined},\n        {key: '2', style: {c: 19.055555555555557}, data: undefined},\n        {key: '3', style: {d: 0.4722222222222222}, data: undefined},\n      ],\n      [\n        {key: '1', style: {a: 1.1897376543209877, b: 57.589506172839506}, data: undefined},\n        {key: '2', style: {c: 17.62052469135803}, data: undefined},\n        {key: '3', style: {d: 1.1897376543209877}, data: undefined},\n      ],\n    ]);\n    mockRaf.step(999);\n    expect(count.length).toBe(91);\n    expect(count[count.length - 1]).toEqual([\n      {key: '1', style: {a: 10, b: 410}, data: undefined},\n      {key: '3', style: {d: 10}, data: undefined},\n    ]);\n  });\n\n  it('should eliminate things in/out at the beginning', () => {\n    // similar to previous test, but without willEnter/leave\n    let count = [];\n    class App extends React.Component {\n      render() {\n        return (\n          <TransitionMotion\n            defaultStyles={[{key: '1', style: {a: 0, b: 10}}, {key: '2', style: {c: 20}}]}\n            styles={[\n              {key: '1', style: {a: spring(10), b: spring(410)}},\n              {key: '3', style: {d: spring(10)}},\n            ]}>\n            {a => {\n              count.push(a);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n\n    expect(count).toEqual([[\n      {key: '1', style: {a: 0, b: 10}, data: undefined},\n      {key: '3', style: {d: 10}, data: undefined},\n    ]]);\n    mockRaf.step(2);\n    expect(count).toEqual([\n      [\n        {key: '1', style: {a: 0, b: 10}, data: undefined},\n        {key: '3', style: {d: 10}, data: undefined},\n      ],\n      [\n        {key: '1', style: {a: 0.4722222222222222, b: 28.888888888888886}, data: undefined},\n        {key: '3', style: {d: 10}, data: undefined},\n      ],\n      [\n        {key: '1', style: {a: 1.1897376543209877, b: 57.589506172839506}, data: undefined},\n        {key: '3', style: {d: 10}, data: undefined},\n      ],\n    ]);\n  });\n\n  it('should carry around the ignored values', () => {\n    let count = [];\n    let setState = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          val: [\n            {key: '1', style: {a: spring(10), b: spring(410)}, data: [3]},\n            {key: '3', style: {d: spring(10)}, data: [4]},\n          ],\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <TransitionMotion\n            willLeave={() => ({c: spring(0)})}\n            willEnter={() => ({d: 0})}\n            defaultStyles={[\n              {key: '1', style: {a: 0, b: 10}, data: [1]},\n              {key: '2', style: {c: 20}, data: [2]},\n            ]}\n            styles={this.state.val}>\n            {a => {\n              count.push(a);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n\n    // somewhat defined behavior: notice that data is 3, not 1. For simplicity\n    // of current implementation we've decided not to render data: [1] from\n    // defaultStyles (this is a problem unique to TransitionMotion, since no\n    // other component carries unrelated data)\n    expect(count).toEqual([[\n      {key: '1', style: {a: 0, b: 10}, data: [3]},\n      {key: '2', style: {c: 20}, data: [2]},\n      {key: '3', style: {d: 0}, data: [4]},\n    ]]);\n    mockRaf.step(2);\n    setState({\n      val: [\n        {key: '1', style: {a: spring(10), b: spring(410)}, data: [5]},\n        {key: '3', style: {d: spring(10)}, data: [6]},\n      ],\n    });\n    mockRaf.step(1);\n    expect(count).toEqual([\n      [\n        {key: '1', style: {a: 0, b: 10}, data: [3]},\n        {key: '2', style: {c: 20}, data: [2]},\n        {key: '3', style: {d: 0}, data: [4]},\n      ],\n      [\n        {key: '1', style: {a: 0.4722222222222222, b: 28.888888888888886}, data: [3]},\n        {key: '2', style: {c: 19.055555555555557}, data: [2]},\n        {key: '3', style: {d: 0.4722222222222222}, data: [4]},\n      ],\n      [\n        {key: '1', style: {a: 1.1897376543209877, b: 57.589506172839506}, data: [3]},\n        {key: '2', style: {c: 17.62052469135803}, data: [2]},\n        {key: '3', style: {d: 1.1897376543209877}, data: [4]},\n      ],\n      // notice the `data` change!\n      [\n        // from the setState\n        {key: '1', style: {a: 1.1897376543209877, b: 57.589506172839506}, data: [5]},\n        {key: '2', style: {c: 17.62052469135803}, data: [2]},\n        {key: '3', style: {d: 1.1897376543209877}, data: [6]},\n      ],\n      [\n        {key: '1', style: {a: 2.0123698988340193, b: 90.49479595336075}, data: [5]},\n        {key: '2', style: {c: 15.975260202331965}, data: [2]},\n        {key: '3', style: {d: 2.0123698988340193}, data: [6]},\n      ],\n    ]);\n    mockRaf.step(999);\n    expect(count.length).toBe(92);\n    expect(count[count.length - 1]).toEqual([\n      {key: '1', style: {a: 10, b: 410}, data: [5]},\n      {key: '3', style: {d: 10}, data: [6]},\n    ]);\n    setState({\n      val: [\n        // `data` changes again\n        {key: '1', style: {a: spring(10), b: spring(410)}, data: [7]},\n        {key: '3', style: {d: spring(10)}, data: [8]},\n      ],\n    });\n    mockRaf.step(10); // no effect, stopped\n    expect(count.length).toBe(93); // rendered once from setState\n    expect(count[count.length - 1]).toEqual([\n      {key: '1', style: {a: 10, b: 410}, data: [7]},\n      {key: '3', style: {d: 10}, data: [8]},\n    ]);\n  });\n\n  it('should carry around the ignored values in styles function', () => {\n    let count = [];\n    let prevValues = [];\n    let setState = () => {};\n    class App extends React.Component {\n      constructor() {\n        super();\n\n        this.state = {\n          val: [\n            {key: '1', style: {a: spring(10), b: spring(410)}, data: [3]},\n            {key: '3', style: {d: spring(10)}, data: [4]},\n          ],\n        };\n      }\n      componentWillMount() {\n        setState = this.setState.bind(this);\n      }\n      render() {\n        return (\n          <TransitionMotion\n            willLeave={() => ({c: spring(0)})}\n            willEnter={() => ({d: 0})}\n            defaultStyles={[\n              {key: '1', style: {a: 0, b: 10}, data: [1]},\n              {key: '2', style: {c: 20}, data: [2]},\n            ]}\n            styles={a => {\n              prevValues.push(a);\n              return this.state.val;\n            }}>\n            {a => {\n              count.push(a);\n              return null;\n            }}\n          </TransitionMotion>\n        );\n      }\n    }\n\n    TestUtils.renderIntoDocument(<App />);\n\n    // somewhat defined behavior: notice that data is 3, not 1. For simplicity\n    // of current implementation we've decided not to render data: [1] from\n    // defaultStyles (this is a problem unique to TransitionMotion, since no\n    // other component carries unrelated data)\n    expect(count).toEqual([[\n      {key: '1', style: {a: 0, b: 10}, data: [3]},\n      {key: '2', style: {c: 20}, data: [2]},\n      {key: '3', style: {d: 0}, data: [4]},\n    ]]);\n    mockRaf.step(2);\n    setState({\n      val: [\n        {key: '1', style: {a: spring(10), b: spring(410)}, data: [5]},\n        {key: '3', style: {d: spring(10)}, data: [6]},\n      ],\n    });\n    mockRaf.step(1);\n    expect(count).toEqual([\n      [\n        {key: '1', style: {a: 0, b: 10}, data: [3]},\n        {key: '2', style: {c: 20}, data: [2]},\n        {key: '3', style: {d: 0}, data: [4]},\n      ],\n      [\n        {key: '1', style: {a: 0.4722222222222222, b: 28.888888888888886}, data: [3]},\n        {key: '2', style: {c: 19.055555555555557}, data: [2]},\n        {key: '3', style: {d: 0.4722222222222222}, data: [4]},\n      ],\n      [\n        {key: '1', style: {a: 1.1897376543209877, b: 57.589506172839506}, data: [3]},\n        {key: '2', style: {c: 17.62052469135803}, data: [2]},\n        {key: '3', style: {d: 1.1897376543209877}, data: [4]},\n      ],\n      // notice the data change!\n      [\n        // from the setState\n        {key: '1', style: {a: 1.1897376543209877, b: 57.589506172839506}, data: [5]},\n        {key: '2', style: {c: 17.62052469135803}, data: [2]},\n        {key: '3', style: {d: 1.1897376543209877}, data: [6]},\n      ],\n      [\n        {key: '1', style: {a: 2.0123698988340193, b: 90.49479595336075}, data: [5]},\n        {key: '2', style: {c: 15.975260202331965}, data: [2]},\n        {key: '3', style: {d: 2.0123698988340193}, data: [6]},\n      ],\n    ]);\n    mockRaf.step(999);\n    expect(count.length).toBe(92);\n    expect(count[count.length - 1]).toEqual([\n      {key: '1', style: {a: 10, b: 410}, data: [5]},\n      {key: '3', style: {d: 10}, data: [6]},\n    ]);\n    setState({\n      val: [\n        // `data` changes again\n        {key: '1', style: {a: spring(10), b: spring(410)}, data: [7]},\n        {key: '3', style: {d: spring(10)}, data: [8]},\n      ],\n    });\n    mockRaf.step(10); // no effect, stopped\n    expect(count.length).toBe(93); // rendered once from setState\n    expect(count[count.length - 1]).toEqual([\n      {key: '1', style: {a: 10, b: 410}, data: [7]},\n      {key: '3', style: {d: 10}, data: [8]},\n    ]);\n\n    expect(prevValues.slice(0, 3)).toEqual([\n      [\n        {key: '1', style: {a: 0, b: 10}, data: [1]},\n        {key: '2', style: {c: 20}, data: [2]},\n      ],\n      [\n        {key: '1', style: {a: 0, b: 10}, data: [3]},\n        {key: '2', style: {c: 20}, data: [2]},\n        {key: '3', style: {d: 0}, data: [4]},\n      ],\n      [\n        {key: '1', style: {a: 0.4722222222222222, b: 28.888888888888886}, data: [3]},\n        {key: '2', style: {c: 19.055555555555557}, data: [2]},\n        {key: '3', style: {d: 0.4722222222222222}, data: [4]},\n      ],\n    ]);\n    expect(prevValues[prevValues.length - 1]).toEqual([\n      {key: '1', style: {a: 10, b: 410}, data: [7]},\n      {key: '3', style: {d: 10}, data: [8]},\n    ]);\n  });\n});\n"
  },
  {
    "path": "test/createMockRaf.js",
    "content": "/* @flow */\n\ntype Callback = (now: number) => void;\n\nexport default function (): Object {\n  let allCallbacks = [];\n  let prevTime = 0;\n  let id = 0;\n\n  const now = () => prevTime;\n\n  const raf = (cb: Callback) => {\n    id++;\n    allCallbacks.push({id, cb});\n    return id;\n  };\n\n  raf.cancel = id2 => {\n    allCallbacks = allCallbacks.filter(item => item.id !== id2);\n  };\n\n  const defaultTimeInterval = 1000 / 60;\n  const singleStep = ms => {\n    const allCallbacksBefore = allCallbacks;\n    allCallbacks = [];\n\n    prevTime += ms;\n    allCallbacksBefore.forEach(({cb}) => cb(prevTime));\n  };\n\n  const step = (howMany = 1, ms = defaultTimeInterval) => {\n    for (let i = 0; i < howMany; i++) {\n      singleStep(ms);\n    }\n  };\n\n  return {now, raf, step};\n}\n"
  },
  {
    "path": "test/index.js",
    "content": "const testsContext = require.context('./', true, /-test\\.js$/);\n\ntestsContext.keys().forEach(testsContext);\n"
  },
  {
    "path": "test/integration/README.md",
    "content": "Simple folder for testing whether the release worked or not.\n\nPlease run this:\n```\nrm -rf bower_components\nrm -rf node_modules\nbower install\nnpm install\nnode -e 'console.log(require(\"react-motion\"))'\n```\n\nCheck that the output of that looks normal.\n\nFor Bower, please also open up bower.html\n"
  },
  {
    "path": "test/integration/bower.html",
    "content": "<html>\n  <head></head>\n  <body>\n    <script src=\"bower_components/react/react.js\"></script>\n    <script src=\"bower_components/react-motion/build/react-motion.js\"></script>\n    <script>\n      if (ReactMotion.spring && ReactMotion.presets && ReactMotion.TransitionMotion) {\n        document.write('Everything looks fine. Check the console too.');\n      } else {\n        document.write('Something broke. Please check the console.');\n      }\n      console.log(ReactMotion);\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "test/integration/bower.json",
    "content": "{\n  \"name\": \"integration\",\n  \"version\": \"0.4.1\",\n  \"homepage\": \"https://github.com/chenglou/react-motion\",\n  \"authors\": [\n    \"Cheng Lou <chenglou92@gmail.com>\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\"\n  ],\n  \"dependencies\": {\n    \"react-motion\": \"https://unpkg.com/react-motion/bower.zip\"\n  }\n}\n"
  },
  {
    "path": "test/integration/package.json",
    "content": "{\n  \"name\": \"integration\",\n  \"private\": true,\n  \"version\": \"1.0.0\",\n  \"description\": \"Simple folder for testing whether the release worked or not.\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"react-motion\": \"^0.5.1\"\n  }\n}\n"
  },
  {
    "path": "test/mergeDiff-test.js",
    "content": "import mergeDiff from '../src/mergeDiff';\n\nconst id = (_, s) => s;\nconst n = () => null;\n\n// helper to make the tests more concise\nfunction test(prevRaw, nextRaw, expectedRaw, customOnRemove) {\n  // we elaborately construct prev/nextKeyStyleValMap + randomized style value to\n  // check that the style object of the latter correctly merged into the final\n  // output\n  let prev = [];\n  let prevKeyStyleValMap = {};\n  prevRaw.forEach(num => {\n    const styleVal = Math.random();\n    // key needs to be a string; cast it\n    prev.push({key: String(num), style: {a: styleVal}});\n    prevKeyStyleValMap[num] = styleVal;\n  });\n  let next = [];\n  let nextKeyStyleValMap = {};\n  nextRaw.forEach(num => {\n    const styleVal = Math.random();\n    next.push({key: String(num), style: {a: styleVal}});\n    nextKeyStyleValMap[num] = styleVal;\n  });\n\n  const expected = expectedRaw.map(num => {\n    return {\n      key: String(num),\n      style: {a: Object.prototype.hasOwnProperty.call(nextKeyStyleValMap, num) ? nextKeyStyleValMap[num] : prevKeyStyleValMap[num]},\n    };\n  });\n\n  expect(mergeDiff(prev, next, n)).toEqual(next);\n  // some tests pass in a `customOnRemove` to check edge cases; interpret\n  // `expected`/`expectedRaw` as the output of mergeDiff using `customOnRemove`\n  // instead of the default `id` function\n  expect(mergeDiff(prev, next, customOnRemove || id)).toEqual(expected);\n}\n\ndescribe('mergeDiff', () => {\n  it('should work with various merge orders', () => {\n    // most of these tests are significant. Don't casually remove some. Those\n    // marked as \"meh\" are the ones whose order can differ. We've chosen a\n    // deterministic default in our mergeDiff implementation\n    test([4], [], [4]);\n    test([], [3], [3]);\n    test([3], [3], [3]);\n    test([], [], []);\n    test([2, 4, 5, 6], [2, 3, 4, 5], [2, 3, 4, 5, 6]);\n    test([2, 4, 5, 6, 7], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6, 7]);\n    test([1, 2, 3], [2, 3, 4], [1, 2, 3, 4]);\n    test([2, 3, 4], [1, 2, 3], [1, 2, 3, 4]);\n    test([4], [1, 2, 3], [4, 1, 2, 3]); // meh\n    test([1, 2, 3], [4], [1, 2, 3, 4]); // meh\n    test([4, 2], [1, 2, 3], [4, 1, 2, 3]); // meh\n    test([2, 4], [1, 2, 3], [1, 2, 4, 3]); // meh\n    test([1, 5, 10], [3, 5, 7, 10], [1, 3, 5, 7, 10]); // meh\n    test([4, 5, 10], [3, 5, 7, 10], [4, 3, 5, 7, 10]); // meh\n    test([4], [3], [4, 3]); // meh\n    test([1, 5], [5, 3], [1, 5, 3]);\n    test([5, 6], [3, 5], [3, 5, 6]);\n    test([1, 2, 3], [3, 2, 1], [3, 2, 1]);\n    test([3, 2, 1], [1, 2, 3], [1, 2, 3]);\n    test([1, 2, 3], [2, 1, 3], [2, 1, 3]);\n    test([1, 2, 3], [1, 3, 2], [1, 3, 2]);\n    test([1, 2, 3], [1, 2, 3], [1, 2, 3]);\n  });\n\n  it('should work with some more typical onRemove callbacks', () => {\n    test([1, 2, 3], [1, 9], [1, 2, 9], (index, s) => index === 1 ? s : null);\n    test([1, 2, 3, 4], [5, 4, 2], [1, 5, 4, 2], (index, s) => index === 0 ? s : null);\n  });\n\n  it('should not call cb more than once per disappearing key', () => {\n    let count = 0;\n    test([1], [], [], () => {\n      count++;\n      return null;\n    });\n    expect(count).toBe(1);\n  });\n});\n"
  },
  {
    "path": "test/stripStyle-test.js",
    "content": "import stripStyle from '../src/stripStyle';\nimport spring from '../src/spring';\n\ndescribe('stripStyle', () => {\n  it('should return spring object into value', () => {\n    expect(stripStyle({a: spring(1, [1, 2])})).toEqual({a: 1});\n  });\n\n  it('should ignore non-configured values', () => {\n    expect(stripStyle({a: 10, b: 0})).toEqual({a: 10, b: 0});\n  });\n});\n"
  },
  {
    "path": "webpack.config.js",
    "content": "'use strict';\n\nmodule.exports = {\n  mode: \"development\",\n  devtool:\n    process.env.NODE_ENV === 'development' ? 'eval-source-map' : 'source-map',\n  entry: {\n    'demo0-simple-transition': './demos/demo0-simple-transition/index.jsx',\n    'demo1-chat-heads': './demos/demo1-chat-heads/index.jsx',\n    'demo2-draggable-balls': './demos/demo2-draggable-balls/index.jsx',\n    'demo3-todomvc-list-transition': './demos/demo3-todomvc-list-transition/index.jsx',\n    'demo4-photo-gallery': './demos/demo4-photo-gallery/index.jsx',\n    'demo5-spring-parameters-chooser': './demos/demo5-spring-parameters-chooser/index.jsx',\n    'demo7-water-ripples': './demos/demo7-water-ripples/index.jsx',\n    'demo8-draggable-list': './demos/demo8-draggable-list/index.jsx',\n  },\n  output: {\n    filename: '[name]/all.js',\n    publicPath: '/demos/',\n    path: __dirname + '/demos/',\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.jsx?$/,\n        exclude: /build|lib|bower_components|node_modules/,\n        loader: 'babel-loader'\n      },\n      {\n        test: /\\.css$/,\n        use: ['style-loader', 'css-loader']\n      },\n      {\n        test: /\\.jsx?$/,\n        loader: 'eslint-loader',\n        exclude: /build|lib|bower_components|node_modules/\n      },\n    ],\n  },\n  resolve: {\n    extensions: ['.js', '.jsx']\n  },\n};\n"
  }
]