[
  {
    "path": ".eslintrc",
    "content": "// Use this file as a starting point for your project's .eslintrc.\n// Copy this file, and add rule overrides as needed.\n{\n  \"extends\": \"airbnb\",\n  \"parser\": \"babel-eslint\",\n  \"rules\": {\n    \"id-length\": 0,\n    \"no-bitwise\": \"off\",\n    \"no-underscore-dangle\": 0,\n    \"linebreak-style\": \"off\",\n    \"no-mixed-operators\": \"off\",\n    \"no-plusplus\": [\n      0\n    ],\n    \"no-param-reassign\": [\n      2,\n      {\n        \"props\": false\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "/node_modules\n.idea/dictionaries/\n.idea/uiDesigner.xml\n.idea/\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"pages\"]\n\tpath = pages\n\turl = git@github.com:toxicFork/react-three-renderer-example.git\n\tbranch = gh-pages\n"
  },
  {
    "path": "CONTRIBUTORS.md",
    "content": "* [@toxicFork](https://github.com/toxicFork)\n * Original Author\n* [@vkammerer](https://github.com/vkammerer)\n * Added installation instructions\n"
  },
  {
    "path": "README.md",
    "content": "react-three-renderer-example\n============================\n\nExamples for [react-three-renderer](https://github.com/toxicFork/react-three-renderer).\n\nhttps://toxicfork.github.com/react-three-renderer-example/\n\n#### Installation\n``\nnpm install\n``\n#### Local server\n``\nnpm start\n``\n\nThen visit [http://localhost:8080](http://localhost:8080) on your favorite webgl-enabled browser :)\n"
  },
  {
    "path": "assets/advanced.html",
    "content": "<!doctype html>\n<html>\n<head>\n    <style>\n        @font-face {\n            font-family: 'inconsolata';\n            src: url('files/inconsolata.woff') format('woff');\n            font-weight: normal;\n            font-style: normal;\n        }\n\n        * {\n            box-sizing: border-box;\n        }\n\n        html {\n            height: 100%;\n        }\n\n        body {\n            background-color: #ffffff;\n            margin: 0px;\n            height: 100%;\n            color: #555;\n            font-family: 'inconsolata';\n            font-size: 15px;\n            line-height: 18px;\n            overflow: hidden;\n        }\n\n        h1 {\n            margin-top: 30px;\n            margin-bottom: 40px;\n            margin-left: 20px;\n            font-size: 25px;\n            font-weight: normal;\n        }\n\n        h2 {\n            font-size: 20px;\n            font-weight: normal;\n        }\n\n        a {\n            color: #2194CE;\n            text-decoration: none;\n        }\n\n        #panel {\n            position: fixed;\n            left: 0px;\n            width: 310px;\n            height: 100%;\n            overflow: auto;\n            background: #fafafa;\n        }\n\n        #panel #content {\n            padding: 0px 20px;\n        }\n\n        #panel #content .link {\n            color: #2194CE;\n            text-decoration: none;\n            cursor: pointer;\n        }\n\n        #panel #content .selected {\n            color: #ff0000;\n        }\n\n        #panel #content .link:hover {\n            text-decoration: underline;\n        }\n\n        #viewer {\n            position: absolute;\n            border: 0px;\n            left: 310px;\n            width: calc(100% - 310px);\n            height: 100%;\n            overflow: hidden;\n        }\n\n        #button {\n            position: fixed;\n            bottom: 20px;\n            right: 20px;\n            padding: 8px;\n            color: #fff;\n            background-color: #555;\n            opacity: 0.7;\n        }\n\n        #button:hover {\n            cursor: pointer;\n            opacity: 1;\n        }\n\n        /* mobile */\n\n        #expandButton {\n            display: none;\n            position: absolute;\n            right: 20px;\n            top: 12px;\n            width: 32px;\n            height: 32px;\n        }\n\n        #expandButton span {\n            height: 2px;\n            background-color: #2194CE;\n            width: 16px;\n            position: absolute;\n            left: 8px;\n            top: 10px;\n        }\n\n        #expandButton span:nth-child(1) {\n            top: 16px;\n        }\n\n        #expandButton span:nth-child(2) {\n            top: 22px;\n        }\n\n        @media all and ( max-width: 640px ) {\n            h1 {\n                margin-top: 20px;\n                margin-bottom: 20px;\n            }\n\n            #panel {\n                position: absolute;\n                left: 0;\n                top: 0;\n                height: 480px;\n                width: 100%;\n                right: 0;\n                z-index: 100;\n                overflow: hidden;\n                border-bottom: 1px solid #dedede;\n            }\n\n            #content {\n                position: absolute;\n                left: 0;\n                top: 60px;\n                right: 0;\n                bottom: 0;\n                font-size: 17px;\n                line-height: 22px;\n                overflow: auto;\n            }\n\n            #viewer {\n                position: absolute;\n                left: 0;\n                top: 56px;\n                width: 100%;\n                height: calc(100% - 56px);\n                overflow: hidden,\n            }\n\n            #expandButton {\n                display: block;\n            }\n\n            #panel.collapsed {\n                height: 56px;\n            }\n        }\n    </style>\n</head>\n<body>\n<div>\n    <div style=\"padding: 20px;\">\n        <canvas id=\"canvas\" width=\"800\" height=\"600\"></canvas>\n\n        <br/>\n        <br/>\n\n        <a href=\"https://github.com/toxicFork/react-three-renderer-example/blob/master/src/examples/AdvancedExample/index.js\">View\n            Source</a>\n    </div>\n</div>\n</body>\n<script type=\"text/javascript\" charset=\"utf-8\" src=\"js/bundle-commons.js\"></script>\n<script type=\"text/javascript\" charset=\"utf-8\" src=\"js/bundle-advanced.js\"></script>\n<script type=\"text/javascript\">\n    var sc_project = 10775601;\n    var sc_invisible = 1;\n    var sc_security = \"74e09d45\";\n    var sc_https = 1;\n    var sc_remove_link = 1;\n    var scJsHost = ((\"https:\" == document.location.protocol) ?\n            \"https://secure.\" : \"http://www.\");\n    document.write(\"<sc\" + \"ript type='text/javascript' src='\" +\n            scJsHost +\n            \"statcounter.com/counter/counter.js'></\" + \"script>\");\n</script>\n<noscript>\n    <div class=\"statcounter\"><img class=\"statcounter\"\n                                  src=\"http://c.statcounter.com/10775601/0/74e09d45/1/\"\n                                  alt=\"stats\"></div>\n</noscript>\n</html>\n"
  },
  {
    "path": "assets/index.html",
    "content": "<!doctype html>\n<html>\n<head>\n    <style>\n        @font-face {\n            font-family: 'inconsolata';\n            src: url('files/inconsolata.woff') format('woff');\n            font-weight: normal;\n            font-style: normal;\n        }\n\n        * {\n            box-sizing: border-box;\n        }\n\n        html {\n            height: 100%;\n        }\n\n        body {\n            background-color: #ffffff;\n            margin: 0px;\n            height: 100%;\n            color: #555;\n            font-family: 'inconsolata';\n            font-size: 15px;\n            line-height: 18px;\n            overflow: hidden;\n        }\n\n        h1 {\n            margin-top: 30px;\n            margin-bottom: 40px;\n            margin-left: 20px;\n            font-size: 25px;\n            font-weight: normal;\n        }\n\n        h2 {\n            font-size: 20px;\n            font-weight: normal;\n        }\n\n        a {\n            color: #2194CE;\n            text-decoration: none;\n        }\n\n        #panel {\n            position: fixed;\n            left: 0px;\n            width: 310px;\n            height: 100%;\n            overflow: auto;\n            background: #fafafa;\n        }\n\n        #panel #content {\n            padding: 0px 20px;\n        }\n\n        #panel #content .link {\n            color: #2194CE;\n            display: block;\n            text-decoration: none;\n            cursor: pointer;\n        }\n\n        #panel #content .selected {\n            color: #ff0000;\n        }\n\n        #panel #content .link:hover {\n            text-decoration: underline;\n        }\n\n        #viewer {\n            position: absolute;\n            border: 0px;\n            left: 310px;\n            width: calc(100% - 310px);\n            height: 100%;\n            overflow: hidden;\n        }\n\n        #button {\n            position: fixed;\n            bottom: 20px;\n            right: 20px;\n            padding: 8px;\n            color: #fff;\n            background-color: #555;\n            opacity: 0.7;\n        }\n\n        #button:hover {\n            cursor: pointer;\n            opacity: 1;\n        }\n\n        /* mobile */\n\n        #expandButton {\n            display: none;\n            position: absolute;\n            right: 20px;\n            top: 12px;\n            width: 32px;\n            height: 32px;\n        }\n\n        #expandButton span {\n            height: 2px;\n            background-color: #2194CE;\n            width: 16px;\n            position: absolute;\n            left: 8px;\n            top: 10px;\n        }\n\n        #expandButton span:nth-child(1) {\n            top: 16px;\n        }\n\n        #expandButton span:nth-child(2) {\n            top: 22px;\n        }\n\n        @media all and ( max-width: 640px ) {\n            h1 {\n                margin-top: 20px;\n                margin-bottom: 20px;\n            }\n\n            #panel {\n                position: absolute;\n                left: 0;\n                top: 0;\n                height: 480px;\n                width: 100%;\n                right: 0;\n                z-index: 100;\n                overflow: hidden;\n                border-bottom: 1px solid #dedede;\n            }\n\n            #content {\n                position: absolute;\n                left: 0;\n                top: 60px;\n                right: 0;\n                bottom: 0;\n                font-size: 17px;\n                line-height: 22px;\n                overflow: auto;\n            }\n\n            #viewer {\n                position: absolute;\n                left: 0;\n                top: 56px;\n                width: 100%;\n                height: calc(100% - 56px);\n                overflow: hidden,\n            }\n\n            #expandButton {\n                display: block;\n            }\n\n            #panel.collapsed {\n                height: 56px;\n            }\n        }\n    </style>\n</head>\n<body>\n<div id=\"content\"></div>\n</body>\n<script type=\"text/javascript\" charset=\"utf-8\" src=\"js/bundle-commons.js\"></script>\n<script type=\"text/javascript\" charset=\"utf-8\" src=\"js/bundle-app.js\"></script>\n<script type=\"text/javascript\">\n    var sc_project = 10775601;\n    var sc_invisible = 1;\n    var sc_security = \"74e09d45\";\n    var sc_https = 1;\n    var sc_remove_link = 1;\n    var scJsHost = ((\"https:\" == document.location.protocol) ?\n            \"https://secure.\" : \"http://www.\");\n    document.write(\"<sc\" + \"ript type='text/javascript' src='\" +\n            scJsHost +\n            \"statcounter.com/counter/counter.js'></\" + \"script>\");\n</script>\n<noscript>\n    <div class=\"statcounter\"><img class=\"statcounter\"\n                                  src=\"http://c.statcounter.com/10775601/0/74e09d45/1/\"\n                                  alt=\"stats\"></div>\n</noscript>\n</html>\n"
  },
  {
    "path": "config/webpackCommonsChunkPluginConfig.js",
    "content": "/* eslint-disable import/no-extraneous-dependencies */\n\nimport webpack from 'webpack';\nimport path from 'path';\n\n// noinspection WebpackConfigHighlighting\nmodule.exports = new webpack.optimize.CommonsChunkPlugin(\n  {\n    name: 'common',\n    filename: path.join('js', 'bundle-commons.js'),\n  });\n"
  },
  {
    "path": "config/webpackPluginsWithoutUglify.js",
    "content": "/* eslint-disable import/no-extraneous-dependencies */\n\nimport webpack from 'webpack';\n\nimport commonsChunkPluginConfig from './webpackCommonsChunkPluginConfig';\n\n// noinspection WebpackConfigHighlighting\nmodule.exports = [\n  new webpack.DefinePlugin({\n    'process.env': {\n      NODE_ENV: '\"production\"',\n    },\n  }),\n  commonsChunkPluginConfig,\n];\n"
  },
  {
    "path": "gulpfile.babel.js",
    "content": "/* eslint-disable import/no-extraneous-dependencies */\n\nimport gulp from 'gulp';\nimport webpack from 'webpack';\nimport WebpackDevServer from 'webpack-dev-server';\nimport gutil from 'gulp-util';\nimport path from 'path';\nimport runSequence from 'run-sequence';\nimport del from 'del';\n\nimport webpackConfig from './webpack.config.babel';\nimport pluginsWithoutUglify from './config/webpackPluginsWithoutUglify';\nimport webpackCommonsChunkPluginConfig from './config/webpackCommonsChunkPluginConfig';\n\nconst cache = {};\n\nconst config = {\n  prod: false,\n  addon: false,\n  noEval: false,\n};\n\nwebpackConfig.output.devtoolModuleFilenameTemplate = info =>\n  `wp:///${path.relative(__dirname, info.resourcePath)}`;\n\nwebpackConfig.output.devtoolFallbackModuleFilenameTemplate = info =>\n  `wp:///${path.relative(__dirname, info.resourcePath)}?${info.hash}`;\n\nrequire('webpack/lib/ModuleFilenameHelpers').createFooter = () => '';\n\n// pretend it's prod ( still has sourcemaps )\n// slowest compilation\ngulp.task('webpack-dev-server-prod', () => {\n  config.prod = true;\n  config.addon = true;\n\n  runSequence('webpack-dev-server');\n});\n\n// no eval, faster runtime, slower compilation\ngulp.task('webpack-dev-server-no-eval', () => {\n  config.noEval = true;\n\n  runSequence('webpack-dev-server');\n});\n\n// fast compilation, low runtime performance\ngulp.task('webpack-dev-server', () => {\n  const host = '0.0.0.0';\n  const port = 8080;\n\n  webpackConfig.cache = cache;\n\n  webpackConfig.entry.app = [\n    `webpack-dev-server/client?http://${host}:${port}`, // WebpackDevServer host and port\n    'webpack/hot/only-dev-server', // \"only\" prevents reload on syntax errors\n  ].concat(webpackConfig.entry.app);\n\n  webpackConfig.entry.advanced = [\n    `webpack-dev-server/client?http://${host}:${port}`, // WebpackDevServer host and port\n    'webpack/hot/only-dev-server', // \"only\" prevents reload on syntax errors\n  ].concat(webpackConfig.entry.advanced);\n\n  webpackConfig.module.loaders.forEach((loader) => {\n    if (loader.loader === 'babel-loader') {\n      loader.query.plugins.push('react-hot-loader/babel');\n    }\n  });\n\n  if (config.prod) {\n    webpackConfig.devtool = 'source-map';\n  } else if (config.noEval) {\n    webpackConfig.devtool = 'cheap-module-source-map';\n  } else {\n    webpackConfig.devtool = 'eval-cheap-module-source-map';\n  }\n\n  webpackConfig.plugins = [\n    new webpack.HotModuleReplacementPlugin(),\n    webpackCommonsChunkPluginConfig,\n  ];\n\n  if (config.prod) {\n    webpackConfig.plugins.unshift(\n      new webpack.DefinePlugin({\n        'process.env': {\n          NODE_ENV: '\"production\"',\n          ENABLE_REACT_ADDON_HOOKS: config.addon ? '\"true\"' : '\"false\"',\n        },\n      }));\n\n    webpackConfig.plugins.push(\n      new webpack.optimize.UglifyJsPlugin({\n        compress: {\n          warnings: false,\n        },\n        mangle: true,\n      }));\n  }\n\n  // Start a webpack-dev-server\n  const compiler = webpack(webpackConfig);\n\n  new WebpackDevServer(compiler, webpackConfig.devServer).listen(port, host, (err) => {\n    if (err) {\n      throw new gutil.PluginError('webpack-dev-server', err);\n    }\n\n    // Server listening\n    gutil.log('[webpack-dev-server]', 'http://localhost:8080/webpack-dev-server/index.html');\n\n    // keep the server alive or continue?\n    // callback();\n  });\n});\n\n// only enable addon integration, everything else in prod settings\ngulp.task('build-prod-with-addon', (callback) => {\n  webpackConfig.plugins.unshift(new webpack.DefinePlugin({\n    'process.env': {\n      ENABLE_REACT_ADDON_HOOKS: '\"true\"',\n    },\n  }));\n\n  runSequence('build', callback);\n});\n\n// also adds sourceMaps too!\ngulp.task('build-prod-with-addon-no-mangle', (callback) => {\n  webpackConfig.devtool = 'source-map';\n\n  webpackConfig.plugins = pluginsWithoutUglify.concat([\n    new webpack.optimize.UglifyJsPlugin({\n      compress: {\n        warnings: false,\n      },\n      mangle: false,\n    }),\n  ]);\n\n  runSequence('build-prod-with-addon', callback);\n});\n\n// build without production node env\ngulp.task('build-dev', (callback) => {\n  webpackConfig.plugins = [\n    new webpack.optimize.UglifyJsPlugin({\n      compress: {\n        warnings: false,\n      },\n      mangle: true,\n    }),\n  ];\n\n  runSequence('build', callback);\n});\n\ngulp.task('clean-pages', () => del('pages/**/!(.git|README.md)'));\n\ngulp.task('copy-assets', () => gulp\n  .src('assets/**/*')\n  .pipe(gulp.dest('pages/')));\n\n// just run webpack with default config (prod)\ngulp.task('build', ['clean-pages'], (callback) => {\n  webpack(webpackConfig, (err, stats) => {\n    if (err) {\n      throw new gutil.PluginError('webpack', err);\n    }\n\n    gutil.log('[webpack]', stats.toString({\n      // output options\n    }));\n\n    runSequence('copy-assets', callback);\n  });\n});\n\ngulp.task('default', ['webpack-dev-server']);\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-three-renderer-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example showing how to use the react-three-renderer package\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"gulp webpack-dev-server\",\n    \"eslint-internal\": \"eslint ./src/\",\n    \"eslint\": \"npm run eslint-internal -loglevel silent || true\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"reactjs\",\n    \"threejs\",\n    \"renderer\"\n  ],\n  \"author\": \"Firtina \\\"toxicFork\\\" Ozbalikci\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"cannon\": \"^0.6.2\",\n    \"history\": \"^4.6.3\",\n    \"prop-types\": \"^15.5.10\",\n    \"react\": \"^15.6.1\",\n    \"react-dom\": \"^15.6.1\",\n    \"react-router\": \"^4.1.2\",\n    \"react-router-dom\": \"^4.1.2\",\n    \"react-sizeme\": \"^2.3.4\",\n    \"react-three-renderer\": \"^3.2.1\",\n    \"stats.js\": \"^1.0.0\",\n    \"three\": \"^0.86.0\",\n    \"react-addons-perf\": \"^15.4.2\"\n  },\n  \"devDependencies\": {\n    \"babel-eslint\": \"^7.1.1\",\n    \"babel-cli\": \"^6.24.1\",\n    \"babel-core\": \"^6.25.0\",\n    \"babel-loader\": \"^7.1.1\",\n    \"babel-plugin-transform-decorators-legacy\": \"^1.3.4\",\n    \"eslint\": \"^3.11.1\",\n    \"eslint-config-airbnb\": \"^13.0.0\",\n    \"eslint-plugin-import\": \"^2.2.0\",\n    \"eslint-plugin-jsx-a11y\": \"2.2.3\",\n    \"eslint-plugin-react\": \"^6.7.1\",\n    \"babel-plugin-transform-runtime\": \"^6.23.0\",\n    \"babel-polyfill\": \"^6.23.0\",\n    \"babel-preset-es2015\": \"^6.24.1\",\n    \"babel-preset-react\": \"^6.24.1\",\n    \"babel-preset-stage-0\": \"^6.24.1\",\n    \"babel-runtime\": \"^6.25.0\",\n    \"gulp\": \"^3.9.1\",\n    \"gulp-babel\": \"^6.1.2\",\n    \"gulp-util\": \"^3.0.8\",\n    \"json-loader\": \"^0.5.7\",\n    \"raw-loader\": \"^0.5.1\",\n    \"react-hot-loader\": \"^3.0.0-beta.6\",\n    \"run-sequence\": \"^2.1.0\",\n    \"webpack\": \"^3.4.1\",\n    \"webpack-dev-server\": \"^2.6.1\",\n    \"del\": \"latest\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/toxicFork/react-three-renderer-example.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/toxicFork/react-three-renderer-example/issues\"\n  },\n  \"babel\": {\n    \"presets\": [\n      \"es2015\",\n      \"stage-0\",\n      \"react\"\n    ],\n    \"plugins\": [\n      \"transform-runtime\",\n      \"transform-decorators-legacy\"\n    ]\n  },\n  \"homepage\": \"https://github.com/toxicFork/react-three-renderer-example#readme\"\n}\n"
  },
  {
    "path": "src/examples/AdvancedExample/AdvancedComponent.js",
    "content": ""
  },
  {
    "path": "src/examples/AdvancedExample/index.js",
    "content": "// see advanced.html :)\n\nimport React from 'react';\nimport React3Renderer from 'react-three-renderer/lib/React3Renderer';\nimport * as THREE from 'three';\n\n// ^ Look mom, no react-dom!\n\nconst canvas = document.getElementById('canvas');\n\nconst react3Renderer = new React3Renderer();\n\nconst width = 800;\nconst height = 600;\n\nconst cameraPosition = new THREE.Vector3(0, 0, 5);\n\nlet cubeRotation = new THREE.Euler();\n\nfunction onRecreateCanvas() {\n  // no need to deal with this now, but here we'd need to create a new canvas and\n  // re-render the scene there.\n}\n\nfunction animate() {\n  cubeRotation = new THREE.Euler(\n    cubeRotation.x + 0.1,\n    cubeRotation.y + 0.1,\n    0\n  );\n\n  react3Renderer.render(<react3\n    width={width}\n    height={height}\n\n    onRecreateCanvas={onRecreateCanvas}\n\n    context=\"3d\"\n\n    antialias\n    mainCamera=\"camera\"\n  >\n    <scene>\n      <perspectiveCamera\n        name=\"camera\"\n        fov={75}\n        aspect={width / height}\n        near={0.1}\n        far={1000}\n\n        position={cameraPosition}\n      />\n      <mesh\n        rotation={cubeRotation}\n      >\n        <boxGeometry\n          width={1}\n          height={1}\n          depth={1}\n        />\n        <meshBasicMaterial\n          color={0xff0000}\n        />\n      </mesh>\n    </scene>\n  </react3>, canvas);\n\n  requestAnimationFrame(animate);\n}\n\nanimate();\n"
  },
  {
    "path": "src/examples/AnimationCloth/Cloth.js",
    "content": "/*\n * Cloth Simulation using a relaxed constrains solver\n */\n\n// Suggested Readings\n\n// Advanced Character Physics by Thomas Jakobsen Character\n// http://freespace.virgin.net/hugo.elias/models/m_cloth.htm\n// http://en.wikipedia.org/wiki/Cloth_modeling\n// http://cg.alexandra.dk/tag/spring-mass-system/\n// Real-time Cloth Animation http://www.darwin3d.com/gamedev/articles/col0599.pdf\nimport * as THREE from 'three';\n\n\nfunction plane(width, height) {\n  return (u, v) => {\n    const x = (u - 0.5) * width;\n    const y = (v + 0.5) * height;\n    const z = 0;\n\n    return new THREE.Vector3(x, y, z);\n  };\n}\n\nconst DAMPING = 0.03;\nconst DRAG = 1 - DAMPING;\nconst MASS = 0.1;\nconst restDistance = 25;\n\nconst xSegs = 10; //\nconst ySegs = 10; //\n\nconst clothFunction = plane(restDistance * xSegs, restDistance * ySegs);\n\nclass Particle {\n  constructor(x, y, z, mass) {\n    this.position = clothFunction(x, y); // position\n    this.previous = clothFunction(x, y); // previous\n    this.original = clothFunction(x, y);\n    this.a = new THREE.Vector3(0, 0, 0); // acceleration\n    this.mass = mass;\n    this.invMass = 1 / mass;\n    this.tmp = new THREE.Vector3();\n    this.tmp2 = new THREE.Vector3();\n  }\n\n  // Force -> Acceleration\n  addForce(force) {\n    this.a.add(\n      this.tmp2.copy(force).multiplyScalar(this.invMass),\n    );\n  }\n\n  // Performs verlet integration\n  integrate(timesQ) {\n    const newPos = this.tmp.subVectors(this.position, this.previous);\n    newPos.multiplyScalar(DRAG).add(this.position);\n    newPos.add(this.a.multiplyScalar(timesQ));\n\n    this.tmp = this.previous;\n    this.previous = this.position;\n    this.position = newPos;\n\n    this.a.set(0, 0, 0);\n  }\n}\n\nclass Cloth {\n  static clothFunction = clothFunction;\n  static MASS = MASS;\n\n  constructor(w = 10, h = 10) {\n    this.w = w;\n    this.h = h;\n\n    const particles = [];\n    const constrains = [];\n\n    let u;\n    let v;\n\n    // Create particles\n    for (v = 0; v <= h; ++v) {\n      for (u = 0; u <= w; ++u) {\n        particles.push(\n          new Particle(u / w, v / h, 0, MASS),\n        );\n      }\n    }\n\n    function index(indexU, indexV) {\n      return indexU + indexV * (w + 1);\n    }\n\n    // Structural\n\n    for (v = 0; v < h; v++) {\n      for (u = 0; u < w; u++) {\n        constrains.push([\n          particles[index(u, v)],\n          particles[index(u, v + 1)],\n          restDistance,\n        ]);\n\n        constrains.push([\n          particles[index(u, v)],\n          particles[index(u + 1, v)],\n          restDistance,\n        ]);\n      }\n    }\n\n    for (u = w, v = 0; v < h; v++) {\n      constrains.push([\n        particles[index(u, v)],\n        particles[index(u, v + 1)],\n        restDistance,\n      ]);\n    }\n\n    for (v = h, u = 0; u < w; u++) {\n      constrains.push([\n        particles[index(u, v)],\n        particles[index(u + 1, v)],\n        restDistance,\n      ]);\n    }\n\n\n    this.particles = particles;\n    this.constrains = constrains;\n\n    this.index = index;\n  }\n}\n\nexport default Cloth;\n"
  },
  {
    "path": "src/examples/AnimationCloth/ClothGeometry.jsx",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport PureRenderMixin from 'react/lib/ReactComponentWithPureRenderMixin';\n\nimport Cloth from './Cloth';\n\nclass ClothGeometry extends React.Component {\n  static propTypes = {\n    cloth: PropTypes.instanceOf(Cloth).isRequired,\n  };\n\n  componentDidMount() {\n    const geometry = this.geometry;\n\n    geometry.computeFaceNormals();\n  }\n\n  _geometryRef = (geometry) => {\n    this.geometry = geometry;\n  };\n\n  shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate;\n\n  render() {\n    const {\n      cloth,\n    } = this.props;\n\n    return (<parametricGeometry\n      ref={this._geometryRef}\n      parametricFunction={Cloth.clothFunction}\n      slices={cloth.w}\n      stacks={cloth.h}\n      dynamic\n    />);\n  }\n}\n\nexport default ClothGeometry;\n"
  },
  {
    "path": "src/examples/AnimationCloth/Info.js",
    "content": "import React from 'react';\n\nimport PropTypes from 'prop-types';\n\nclass Info extends React.Component {\n  static propTypes = {\n    toggleWind: PropTypes.func.isRequired,\n    toggleSphere: PropTypes.func.isRequired,\n    togglePins: PropTypes.func.isRequired,\n    toggleRotate: PropTypes.func.isRequired,\n    onFrameChange: PropTypes.func.isRequired,\n    minTimePerFrame: PropTypes.number.isRequired,\n    rotating: PropTypes.bool.isRequired,\n    winding: PropTypes.bool.isRequired,\n    balling: PropTypes.bool.isRequired,\n  };\n\n  render() {\n    const linkStyle = {\n      textDecoration: 'underline',\n      cursor: 'pointer',\n    };\n\n    const {\n      toggleRotate,\n      toggleWind,\n      toggleSphere,\n      togglePins,\n      minTimePerFrame,\n      onFrameChange,\n      rotating,\n      winding,\n      balling,\n    } = this.props;\n\n    return (<div\n      style={{\n        textAlign: 'center',\n        padding: 10,\n        zIndex: 10,\n        width: '100%',\n        position: 'absolute',\n        color: '#000',\n      }}\n    >\n      <a\n        href=\"http://threejs.org\"\n        style={{\n          color: '#0080ff',\n        }}\n      >three.js</a> - Simple Cloth Simulation<br/>\n      Verlet integration with Constrains relaxation<br/>\n      Toggle: <a onClick={toggleRotate} style={linkStyle}>Camera{rotating ? '*' : null}</a> |\n      <span> <a onClick={toggleWind} style={linkStyle}>Wind{winding ? '*' : null}</a></span> |\n      <span> <a onClick={toggleSphere} style={linkStyle}>Ball{balling ? '*' : null}</a></span> |\n      <span> <a onClick={togglePins} style={linkStyle}>Pins</a></span> |\n      <span> Time between frames (ms): <input\n        onChange={onFrameChange}\n        value={minTimePerFrame}\n        type=\"number\"\n        style={{ width: 40 }}\n        min=\"0\"\n      /> </span>\n      <br/>\n      <span>Note: add some time between frames (e.g. 60ms)\n        if you would like to inspect the scene through\n        react devtools, because updating every frame kills the addon.</span>\n    </div>);\n  }\n}\n\nexport default Info;\n"
  },
  {
    "path": "src/examples/AnimationCloth/Poles.js",
    "content": "import React from 'react';\n\nimport * as THREE from 'three';\n\nimport PureRenderMixin from 'react/lib/ReactComponentWithPureRenderMixin';\n\nclass Poles extends React.Component {\n  constructor(props, context) {\n    super(props, context);\n\n    this.state = {\n      poleMaterialColor: Number(0xffffff).toString(16),\n      poleMaterialSpecular: Number(0x111111).toString(16),\n      poleMaterialShininess: 100,\n      sidePolePositions: [\n        new THREE.Vector3(-125, -62, 0),\n        new THREE.Vector3(125, -62, 0),\n      ],\n      boxPositions: [\n        new THREE.Vector3(125, -250, 0),\n        new THREE.Vector3(-125, -250, 0),\n      ],\n      topPolePosition: new THREE.Vector3(0, -250 + 750 / 2, 0),\n      subResource: false,\n    };\n  }\n\n  shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate;\n\n  render() {\n    return (<object3D>\n      <resources>\n        <boxGeometry\n          resourceId=\"poleGeometry\"\n          width={5}\n          height={375}\n          depth={5}\n        />\n        <boxGeometry\n          resourceId=\"boxGeometry\"\n          width={10}\n          height={10}\n          depth={10}\n        />\n        <meshPhongMaterial\n          resourceId=\"poleMaterial\"\n          color={Number.parseInt(this.state.poleMaterialColor, 16)}\n          specular={Number.parseInt(this.state.poleMaterialSpecular, 16)}\n          shininess={this.state.poleMaterialShininess}\n        />\n      </resources>\n      {this.state.sidePolePositions.map((position, i) =>\n        (<mesh\n          key={i}\n          position={position}\n          receiveShadow\n          castShadow\n        >\n          <geometryResource\n            resourceId=\"poleGeometry\"\n          />\n          <materialResource\n            resourceId=\"poleMaterial\"\n          />\n        </mesh>))}\n      <mesh\n        position={this.state.topPolePosition}\n        receiveShadow\n        castShadow\n      >\n        <boxGeometry\n          width={255}\n          height={5}\n          depth={5}\n        />\n        <materialResource\n          resourceId=\"poleMaterial\"\n        />\n      </mesh>\n      <object3D>\n        { this.state.subResource ? <resources>\n          {this.state.subResource ? <meshPhongMaterial\n            resourceId=\"poleMaterial\"\n            color={0x00ff00}\n            specular={0x111111}\n            shininess={100}\n          /> : null}\n          {\n            <sphereGeometry\n              resourceId=\"boxGeometry\"\n              radius={20}\n            /> }\n        </resources> : null }\n        {this.state.boxPositions.map((position, i) =>\n          (<mesh\n            key={i}\n            position={position}\n            receiveShadow\n            castShadow\n          >\n            <geometryResource\n              resourceId=\"boxGeometry\"\n            />\n            <materialResource\n              resourceId=\"poleMaterial\"\n            />\n          </mesh>))}\n      </object3D>\n    </object3D>);\n  }\n}\n\nexport default Poles;\n"
  },
  {
    "path": "src/examples/AnimationCloth/Sphere.js",
    "content": "import React from 'react';\n\nimport * as THREE from 'three';\n\nimport PureRenderMixin from 'react/lib/ReactComponentWithPureRenderMixin';\n\nimport PropTypes from 'prop-types';\n\nconst ballSize = 60; // 40\n\nclass Sphere extends React.Component {\n  static propTypes = {\n    visible: PropTypes.bool.isRequired,\n    position: PropTypes.instanceOf(THREE.Vector3).isRequired,\n  };\n\n  constructor(props, context) {\n    super(props, context);\n\n    this.state = {\n      color: '0xaaaaaa',\n    };\n  }\n\n  shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate;\n\n  render() {\n    const {\n      visible,\n      position,\n      } = this.props;\n\n    return (<mesh\n      castShadow\n      receiveShadow\n      visible={visible}\n      position={position}\n    >\n      <sphereGeometry\n        radius={ballSize}\n        widthSegments={20}\n        heightSegments={20}\n      />\n      <meshPhongMaterial\n        color={Number.parseInt(this.state.color, 16)}\n      />\n    </mesh>);\n  }\n}\n\nexport default Sphere;\n"
  },
  {
    "path": "src/examples/AnimationCloth/StaticWorld.js",
    "content": "import React from 'react';\nimport * as THREE from 'three';\nimport PropTypes from 'prop-types';\n\nimport PureRenderMixin from 'react/lib/ReactComponentWithPureRenderMixin';\n\nimport fragmentShaderDepth from 'raw-loader!./shaders/depth.frag';\nimport vertexShaderDepth from 'raw-loader!./shaders/depth.vert';\n\nimport ClothGeometry from './ClothGeometry';\nimport Poles from './Poles';\nimport Cloth from './Cloth';\n\n\nclass StaticWorld extends React.Component {\n  static propTypes = {\n    clothRef: PropTypes.func.isRequired,\n    cloth: PropTypes.instanceOf(Cloth).isRequired,\n  };\n\n  constructor(props, context) {\n    super(props, context);\n\n    this.directionalLightPosition = new THREE.Vector3(50, 200, 100).multiplyScalar(1.3);\n    this.lightTarget = new THREE.Vector3(0, 0, 0);\n    this.groundPosition = new THREE.Vector3(0, -250, 0);\n    this.groundRotation = new THREE.Euler(-Math.PI / 2, 0, 0);\n    this.groundRepeat = new THREE.Vector2(25, 25);\n\n    this.state = {\n      ambientLightColor: '666666',\n      directionalLightColor: 'dfebff',\n      fragmentShaderDepth,\n      vertexShaderDepth,\n    };\n\n    // check if HMR is enabled\n    if (module.hot) {\n      // accept update of dependency\n      module.hot.accept('raw-loader!./shaders/depth.frag', () => {\n        this.setState({\n          fragmentShaderDepth: require('raw-loader!./shaders/depth.frag'),\n        });\n      });\n\n      module.hot.accept('raw-loader!./shaders/depth.vert', () => {\n        this.setState({\n          vertexShaderDepth: require('raw-loader!./shaders/depth.vert'),\n        });\n      });\n    }\n  }\n\n  shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate;\n\n  render() {\n    const shadowCameraSize = 300;\n\n    const {\n      ambientLightColor,\n      directionalLightColor,\n      fragmentShaderDepth: frag,\n      vertexShaderDepth: vert,\n      } = this.state;\n\n    return (<object3D>\n      <resources>\n        <texture\n          url=\"textures/patterns/circuit_pattern.png\"\n          wrapS={THREE.RepeatWrapping}\n          wrapT={THREE.RepeatWrapping}\n          anisotropy={16}\n          resourceId=\"clothTexture\"\n        />\n      </resources>\n      <ambientLight\n        color={Number.parseInt(ambientLightColor, 16)}\n      />\n      <directionalLight\n        color={Number.parseInt(directionalLightColor, 16)}\n        intensity={1.75}\n        position={this.directionalLightPosition}\n        lookAt={this.lightTarget}\n        castShadow\n        shadowMapWidth={1024}\n        shadowMapHeight={1024}\n        shadowCameraLeft={-shadowCameraSize}\n        shadowCameraRight={shadowCameraSize}\n        shadowCameraTop={shadowCameraSize}\n        shadowCameraBottom={-shadowCameraSize}\n        shadowCameraFar={1000}\n      />\n      <mesh\n        castShadow\n        receiveShadow\n      >\n        <ClothGeometry\n          ref={this.props.clothRef}\n          cloth={this.props.cloth}\n        />\n        <meshPhongMaterial\n          alphaTest={0.5}\n          color={0xffffff}\n          specular={0x030303}\n          emissive={0x111111}\n          shininess={10}\n          side={THREE.DoubleSide}\n        >\n          <textureResource\n            resourceId=\"clothTexture\"\n          />\n        </meshPhongMaterial>\n        <shaderMaterial\n          slot=\"customDepthMaterial\"\n          fragmentShader={frag}\n          vertexShader={vert}\n        >\n          <uniforms>\n            <uniform\n              name=\"texture\"\n              type=\"t\"\n            >\n              <textureResource\n                resourceId=\"clothTexture\"\n              />\n            </uniform>\n          </uniforms>\n        </shaderMaterial>\n      </mesh>\n      { /* <arrowHelper\n       direction={this.arrowDirection}\n       origin={this.arrowOrigin}\n       length={this.arrowLength}\n       color={0xff0000}\n       position={this.arrowPosition}\n       /> */ }\n      <mesh\n        position={this.groundPosition}\n        rotation={this.groundRotation}\n        receiveShadow\n      >\n        <planeBufferGeometry\n          width={20000}\n          height={20000}\n        />\n        <meshPhongMaterial\n          color={0xffffff}\n          specular={0x111111}\n        >\n          <texture\n            url=\"textures/terrain/grasslight-big.jpg\"\n            wrapS={THREE.RepeatWrapping}\n            wrapT={THREE.RepeatWrapping}\n            repeat={this.groundRepeat}\n            anisotropy={16}\n          />\n        </meshPhongMaterial>\n      </mesh>\n      <Poles/>\n    </object3D>);\n  }\n}\n\nexport default StaticWorld;\n"
  },
  {
    "path": "src/examples/AnimationCloth/index.js",
    "content": "import jsx from './index.jsx';\n\nmodule.exports = jsx;"
  },
  {
    "path": "src/examples/AnimationCloth/index.jsx",
    "content": "import React from 'react';\nimport * as THREE from 'three';\nimport Stats from 'stats.js';\n\nimport React3 from 'react-three-renderer';\n\nimport ExampleBase from '../ExampleBase';\n\nimport Info from './Info';\n\nimport Cloth from './Cloth';\nimport StaticWorld from './StaticWorld';\nimport Sphere from './Sphere';\n\nimport TrackballControls from '../../ref/trackball';\n\nconst ballSize = 60; // 40\n\nconst GRAVITY = 981 * 1.4; //\nconst gravity = new THREE.Vector3(0, -GRAVITY, 0).multiplyScalar(Cloth.MASS);\n\nconst TIMESTEP = 18 / 1000;\nconst TIMESTEP_SQ = TIMESTEP * TIMESTEP;\n\nconst diff = new THREE.Vector3();\n\n\nfunction satisfyConstrains(p1, p2, distance) {\n  diff.subVectors(p2.position, p1.position);\n  const currentDist = diff.length();\n  if (currentDist === 0) {\n    return;\n  } // prevents division by 0\n  const correction = diff.multiplyScalar(1 - distance / currentDist);\n  const correctionHalf = correction.multiplyScalar(0.5);\n  p1.position.add(correctionHalf);\n  p2.position.sub(correctionHalf);\n}\n\nconst tmpForce = new THREE.Vector3();\n\nclass AnimationCloth extends ExampleBase {\n  constructor(props, context) {\n    super(props, context);\n\n    this.state = {\n      ...this.state,\n      minTimePerFrame: 0,\n      rotate: true,\n      wind: true,\n      sphere: false,\n    };\n\n    const xSegs = 10; //\n    const ySegs = 10; //\n\n    this.cloth = new Cloth(xSegs, ySegs);\n\n    const pinsFormation = [];\n    let pins = [6];\n\n    pinsFormation.push(pins);\n\n    pins = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    pinsFormation.push(pins);\n\n    pins = [0];\n    pinsFormation.push(pins);\n\n    pins = []; // cut the rope ;)\n    pinsFormation.push(pins);\n\n    pins = [0, this.cloth.w]; // classic 2 pins\n    pinsFormation.push(pins);\n\n    pins = pinsFormation[1];\n\n    this.pins = pins;\n    this.pinsFormation = pinsFormation;\n\n    this.fog = new THREE.Fog(0xcce0ff, 500, 10000);\n\n    this.windForce = new THREE.Vector3(0, 0, 0);\n\n    this.state = {\n      ...this.state,\n      ballPosition: new THREE.Vector3(0, -45, 0),\n      cameraPosition: new THREE.Vector3(0, 50, 1500),\n    };\n\n    this.scenePosition = new THREE.Vector3(0, 0, 0);\n  }\n\n  componentDidMount() {\n    const controls = new TrackballControls(\n      this.mainCamera, this.react3);\n    controls.rotateSpeed = 1.0;\n    controls.zoomSpeed = 1.2;\n    controls.panSpeed = 0.8;\n\n    controls.noZoom = false;\n    controls.noPan = false;\n\n    controls.staticMoving = true;\n    controls.dynamicDampingFactor = 0.3;\n\n    controls.addEventListener('change', () => {\n      this.setState({\n        cameraPosition: this.mainCamera.position,\n      });\n    });\n\n    this.controls = controls;\n\n    this.stats = new Stats();\n\n    this.stats.domElement.style.position = 'absolute';\n    this.stats.domElement.style.top = '0px';\n\n    this.container.appendChild(this.stats.domElement);\n  }\n\n  componentWillUnmount() {\n    delete this.stats;\n    this.controls.dispose();\n    delete this.controls;\n  }\n\n  _toggleRotate = () => {\n    this.setState({ rotate: !this.state.rotate });\n  };\n\n  _toggleWind = () => {\n    this.setState({ wind: !this.state.wind });\n  };\n\n  _toggleSphere = () => {\n    this.setState({ sphere: !this.state.sphere });\n  };\n\n  _togglePins = () => {\n    this.pins = this.pinsFormation[~~(Math.random() * this.pinsFormation.length)];\n  };\n\n  _simulate(time) {\n    if (!this.lastTime) {\n      this.lastTime = time;\n      return;\n    }\n\n    let i;\n    let il;\n    let particles;\n    let particle;\n    let constrain;\n\n    const clothGeometry = React3.findTHREEObject(this._clothGeometry);\n\n    const sphere = React3.findTHREEObject(this.sphere);\n\n    // Aerodynamics forces\n    if (this.state.wind) {\n      let face;\n      const faces = clothGeometry.faces;\n      let normal;\n\n      particles = this.cloth.particles;\n\n      for (i = 0, il = faces.length; i < il; i++) {\n        face = faces[i];\n        normal = face.normal;\n\n        tmpForce.copy(normal).normalize().multiplyScalar(normal.dot(this.windForce));\n        particles[face.a].addForce(tmpForce);\n        particles[face.b].addForce(tmpForce);\n        particles[face.c].addForce(tmpForce);\n      }\n    }\n\n    for (particles = this.cloth.particles, i = 0, il = particles.length; i < il; i++) {\n      particle = particles[i];\n      particle.addForce(gravity);\n\n      particle.integrate(TIMESTEP_SQ);\n    }\n\n    // Start Constrains\n\n    const constrains = this.cloth.constrains;\n    il = constrains.length;\n\n    for (i = 0; i < il; i++) {\n      constrain = constrains[i];\n      satisfyConstrains(constrain[0], constrain[1], constrain[2]);\n    }\n\n    const ballPosition = this.state.ballPosition.clone();\n\n    // Ball Constrains\n    ballPosition.z = -Math.sin(Date.now() / 600) * 90; // + 40;\n    ballPosition.x = Math.cos(Date.now() / 400) * 70;\n\n    if (sphere.visible) {\n      for (particles = this.cloth.particles,\n             i = 0,\n             il = particles.length; i < il; i++) {\n        particle = particles[i];\n        const pos = particle.position;\n        diff.subVectors(pos, ballPosition);\n        if (diff.length() < ballSize) {\n          // collided\n          diff.normalize().multiplyScalar(ballSize);\n          pos.copy(ballPosition).add(diff);\n        }\n      }\n    }\n\n    // Floor Constraints\n    for (particles = this.cloth.particles, i = 0, il = particles.length\n      ; i < il; i++) {\n      particle = particles[i];\n      const pos = particle.position;\n      if (pos.y < -250) {\n        pos.y = -250;\n      }\n    }\n\n    // Pin Constrains\n    for (i = 0, il = this.pins.length; i < il; i++) {\n      const xy = this.pins[i];\n      const p = particles[xy];\n      p.position.copy(p.original);\n      p.previous.copy(p.original);\n    }\n\n    this.setState({\n      ballPosition,\n    });\n  }\n\n  _onAnimate = () => {\n    this.controls.update();\n\n    const {\n      minTimePerFrame,\n    } = this.state;\n\n    let time;\n\n    if (minTimePerFrame > 0) {\n      time = Math.round(Date.now() / minTimePerFrame) * minTimePerFrame;\n    } else {\n      time = Date.now();\n    }\n\n    if (time === this.state.time) {\n      return;\n    }\n\n    const windStrength = Math.cos(time / 7000) * 20 + 40;\n    this.windForce.set(\n      Math.sin(time / 2000),\n      Math.cos(time / 3000),\n      Math.sin(time / 1000)).normalize().multiplyScalar(windStrength);\n\n    this._simulate(time);\n\n    const clothGeometry = React3.findTHREEObject(this._clothGeometry);\n\n    // render\n\n    const timer = time * 0.0002;\n\n    const p = this.cloth.particles;\n\n    let il;\n    let i;\n    for (i = 0, il = p.length; i < il; ++i) {\n      clothGeometry.vertices[i].copy(p[i].position);\n    }\n\n    clothGeometry.computeFaceNormals();\n    clothGeometry.computeVertexNormals();\n\n    clothGeometry.normalsNeedUpdate = true;\n    clothGeometry.verticesNeedUpdate = true;\n\n    const newState = {\n      time,\n      spherePosition: this.ballPosition,\n    };\n\n    if (this.state.rotate) {\n      newState.cameraPosition = new THREE.Vector3(\n        Math.cos(timer) * 1500,\n        this.state.cameraPosition.y,\n        Math.sin(timer) * 1500);\n    }\n\n    this.setState(newState);\n    this.stats.update();\n  };\n\n  _clothRef = (ref) => {\n    this._clothGeometry = ref;\n  };\n\n  _onFrameChange = (event) => {\n    this.setState({\n      minTimePerFrame: +event.target.value,\n    });\n  };\n\n  _containerRef = (container) => {\n    this.container = container;\n  };\n\n  _sphereRef = (sphere) => {\n    this.sphere = sphere;\n  };\n\n  _react3Ref = (react3) => {\n    this.react3 = react3;\n  };\n\n  _mainCameraRef = (mainCamera) => {\n    this.mainCamera = mainCamera;\n  };\n\n  render() {\n    const {\n      width,\n      height,\n    } = this.props;\n\n    const {\n      minTimePerFrame,\n    } = this.state;\n\n    return (<div ref={this._containerRef}>\n      <Info\n        toggleRotate={this._toggleRotate}\n        toggleWind={this._toggleWind}\n        toggleSphere={this._toggleSphere}\n        togglePins={this._togglePins}\n        rotating={this.state.rotate}\n        winding={this.state.wind}\n        balling={this.state.sphere}\n        onFrameChange={this._onFrameChange}\n        minTimePerFrame={minTimePerFrame}\n      />\n      <React3\n        canvasRef={this._react3Ref}\n        width={width}\n        height={height}\n        antialias\n        pixelRatio={window.devicePixelRatio}\n        clearColor={this.fog.color}\n        gammaInput\n        gammaOutput\n        shadowMapEnabled\n        shadowMapDebug\n        mainCamera=\"mainCamera\"\n        onAnimate={this._onAnimate}\n      >\n        <scene fog={this.fog}>\n          <perspectiveCamera\n            name=\"mainCamera\"\n            fov={30}\n            aspect={width / height}\n            ref={this._mainCameraRef}\n            position={this.state.cameraPosition}\n            near={1}\n            far={10000}\n            lookAt={this.state.rotate ? this.scenePosition : null}\n          />\n          <StaticWorld\n            clothRef={this._clothRef}\n            cloth={this.cloth}\n          />\n          <Sphere\n            ref={this._sphereRef}\n            visible={this.state.sphere}\n            position={this.state.ballPosition}\n          />\n        </scene>\n      </React3>\n    </div>);\n  }\n}\n\nexport default AnimationCloth;\n"
  },
  {
    "path": "src/examples/AnimationCloth/shaders/depth.frag",
    "content": "uniform sampler2D texture;\nvarying vec2 vUV;\n\nvec4 pack_depth( const in float depth ) {\n  const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\n  const vec4 bit_mask  = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\n  vec4 res = fract( depth * bit_shift );\n  res -= res.xxyz * bit_mask;\n\n  return res;\n}\n\nvoid main() {\n  vec4 pixel = texture2D( texture, vUV );\n\n  if ( pixel.a < 0.5 ) discard;\n\n  gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n}\n"
  },
  {
    "path": "src/examples/AnimationCloth/shaders/depth.vert",
    "content": "varying vec2 vUV;\n\nvoid main() {\n  vUV = 0.75 * uv;\n\n  vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\n  gl_Position = projectionMatrix * mvPosition;\n}\n"
  },
  {
    "path": "src/examples/Benchmark/RotatingCube.js",
    "content": "import React from 'react';\nimport * as THREE from 'three';\n\nimport PropTypes from 'prop-types';\n\nconst meshScale = new THREE.Vector3(1, 1, 1).multiplyScalar(0.5);\n\nclass RotatingCube extends React.Component {\n  static propTypes = {\n    position: PropTypes.instanceOf(THREE.Vector3).isRequired,\n    quaternion: PropTypes.instanceOf(THREE.Quaternion).isRequired,\n  };\n\n  render() {\n    const {\n      position,\n      quaternion,\n    } = this.props;\n\n    return (<mesh\n      position={position}\n      quaternion={quaternion}\n      scale={meshScale}\n\n      castShadow\n    >\n      <geometryResource\n        resourceId=\"cubeGeo\"\n      />\n      <materialResource\n        resourceId=\"cubeMaterial\"\n      />\n    </mesh>);\n  }\n}\n\nexport default RotatingCube;\n"
  },
  {
    "path": "src/examples/Benchmark/RotatingCubes.js",
    "content": "import React from 'react';\nimport React3 from 'react-three-renderer';\nimport * as THREE from 'three';\n\nimport ExampleBase from '../ExampleBase';\n\nimport Stats from 'stats.js';\n\nimport RotatingCube from './RotatingCube';\n\nclass RotatingCubes extends ExampleBase {\n  constructor(props, context) {\n    super(props, context);\n\n    const N = 200;\n\n    this.fog = new THREE.Fog(0x001525, 10, 40);\n\n    const d = 20;\n\n    this.lightPosition = new THREE.Vector3(d, d, d);\n    this.lightTarget = new THREE.Vector3(0, 0, 0);\n    this.groundQuaternion = new THREE.Quaternion()\n      .setFromAxisAngle(new THREE.Vector3(1, 0, 0), -Math.PI / 2);\n    this.cameraPosition = new THREE.Vector3(10, 2, 0);\n    this.cameraQuaternion = new THREE.Quaternion()\n      .setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2);\n\n    const bodies = [];\n    bodies.length = N;\n\n    this.bodies = bodies;\n\n    this._createBodies();\n\n    this.state = {\n      numBodies: N,\n      meshStates: this._getMeshStates(),\n    };\n  }\n\n  _getMeshStates() {\n    return this.bodies.map(({ position, quaternion }) => ({\n      position: new THREE.Vector3().copy(position),\n      quaternion: new THREE.Quaternion().copy(quaternion),\n    }));\n  }\n\n  _onAnimate = () => {\n    this._updatePhysics();\n\n    this._updateGraphics();\n\n    this.stats.update();\n  };\n\n  _updateGraphics() {\n    this.setState({\n      meshStates: this._getMeshStates(),\n    });\n  }\n\n  _updatePhysics() {\n    const time = new Date().getTime();\n    const bodies = this.bodies;\n\n    for (let i = 0; i < bodies.length; ++i) {\n      const body = bodies[i];\n\n      const sinTime = Math.sin(time * body.timeScale);\n\n      body.quaternion.multiply(body.rotationDeltaPerFrame);\n\n      const { movementPerFrame } = body;\n\n      body.position.copy(body.startPosition.clone()\n        .add(movementPerFrame.clone()\n          .multiplyScalar(sinTime)));\n    }\n  }\n\n  componentDidMount() {\n    const {\n      container,\n    } = this.refs;\n\n    this.stats = new Stats();\n\n    this.stats.domElement.style.position = 'absolute';\n    this.stats.domElement.style.top = '0px';\n\n    container.appendChild(this.stats.domElement);\n  }\n\n  componentWillUnmount() {\n    delete this.stats;\n  }\n\n  _createBodies() {\n    const { bodies } = this;\n    const N = bodies.length;\n\n    for (let i = 0; i < N; ++i) {\n      bodies[i] = this._createBody(i);\n    }\n  }\n\n  _createBody() {\n    const position = new THREE.Vector3(\n      -2.5 + Math.random() * 5,\n      0.5 + Math.random() * 5,\n      -2.5 + Math.random() * 5);\n\n    return {\n      position,\n      timeScale: Math.random() * 0.005,\n      startPosition: position.clone(),\n      movementPerFrame: new THREE.Vector3(Math.random(), Math.random(), Math.random()),\n      rotationDeltaPerFrame: new THREE.Quaternion()\n        .setFromEuler(new THREE.Euler(\n          Math.random() * 0.05,\n          Math.random() * 0.05,\n          Math.random() * 0.05)),\n      quaternion: new THREE.Quaternion(),\n    };\n  }\n\n  _onBodiesSelectChange = (event) => {\n    const numBodies = event.target.value;\n\n    this.bodies.length = numBodies;\n    this._createBodies();\n\n    this.setState({\n      numBodies,\n      meshStates: this._getMeshStates(),\n    });\n\n    this._updateGraphics();\n  };\n\n  _getInputBox(title) {\n    const { numBodies } = this.state;\n\n    return (<div\n      style={{\n        position: 'absolute',\n        top: 0,\n        color: 'white',\n        width: '100%',\n        textAlign: 'center',\n        background: 'rgba(1,1,1,0.75)',\n      }}\n    >\n      <div>{title}</div>\n      <label>Bodies: <select\n        value={numBodies}\n        onChange={this._onBodiesSelectChange}\n      >\n        {[10, 50, 100, 200, 300, 500, 1000, 1500, 2000, 2500, 3000]\n          .map(val => <option value={val} key={val}>{val}</option>)}\n      </select>\n      </label>\n    </div>);\n  }\n\n  render() {\n    const {\n      width,\n      height,\n    } = this.props;\n\n    const {\n      meshStates,\n    } = this.state;\n\n    const d = 20;\n\n    const cubeMeshes = meshStates.map(({ position, quaternion }, i) =>\n      (<RotatingCube\n        key={i}\n\n        position={position}\n        quaternion={quaternion}\n\n        bodyIndex={i}\n\n        meshes={this.meshes}\n      />));\n\n    return (<div\n      ref=\"container\"\n    >\n      {this._getInputBox('Rotating Cubes - Through React')}\n      <React3\n        antialias\n        mainCamera=\"camera\"\n        width={width}\n        height={height}\n\n        onAnimate={this._onAnimate}\n\n        clearColor={this.fog.color}\n\n        gammaInput\n        gammaOutput\n        shadowMapEnabled\n      >\n        <resources>\n          <boxGeometry\n            resourceId=\"cubeGeo\"\n\n            width={0.5}\n            height={0.5}\n            depth={0.5}\n\n            widthSegments={10}\n            heightSegments={10}\n          />\n          <meshPhongMaterial\n            resourceId=\"cubeMaterial\"\n\n            color={0x888888}\n          />\n        </resources>\n        <scene\n          ref=\"scene\"\n          fog={this.fog}\n        >\n          <perspectiveCamera\n            name=\"camera\"\n            fov={30}\n            aspect={width / height}\n            near={0.5}\n            far={10000}\n\n            position={this.cameraPosition}\n            quaternion={this.cameraQuaternion}\n\n            ref=\"camera\"\n          />\n          <ambientLight\n            color={0x666666}\n          />\n          <directionalLight\n            color={0xffffff}\n            intensity={1.75}\n\n            castShadow\n\n            shadowMapWidth={1024}\n            shadowMapHeight={1024}\n\n            shadowCameraLeft={-d}\n            shadowCameraRight={d}\n            shadowCameraTop={d}\n            shadowCameraBottom={-d}\n\n            shadowCameraFar={3 * d}\n            shadowCameraNear={d}\n\n            position={this.lightPosition}\n            lookAt={this.lightTarget}\n          />\n          <mesh\n            castShadow\n            receiveShadow\n\n            quaternion={this.groundQuaternion}\n          >\n            <planeBufferGeometry\n              width={100}\n              height={100}\n              widthSegments={1}\n              heightSegments={1}\n            />\n            <meshLambertMaterial\n              color={0x777777}\n            />\n          </mesh>\n          {cubeMeshes}\n        </scene>\n\n      </React3>\n    </div>);\n  }\n}\n\nexport default RotatingCubes;\n"
  },
  {
    "path": "src/examples/Benchmark/RotatingCubesDirectUpdates.js",
    "content": "import React from 'react';\nimport React3 from 'react-three-renderer';\nimport * as THREE from 'three';\n\nimport RotatingCube from './RotatingCube';\nimport RotatingCubes from './RotatingCubes';\n\nclass RotatingCubesDirectUpdates extends RotatingCubes {\n  _getMeshStates() {\n    const { bodies } = this;\n\n    return bodies.map(({ position, quaternion, ref }) => ({\n      position: new THREE.Vector3().copy(position),\n      quaternion: new THREE.Quaternion().copy(quaternion),\n      ref,\n    }));\n  }\n\n  _bodyRef(index, body) {\n    if (body === null) {\n      // dismounted\n      return;\n    }\n\n    this.bodies[index].body = React3.findTHREEObject(body);\n  }\n\n  _updateGraphics() {\n    const { bodies } = this;\n\n    for (let i = 0; i < bodies.length; ++i) {\n      const body = bodies[i];\n\n      if (body.body) {\n        body.body.position.copy(body.position);\n        body.body.quaternion.copy(body.quaternion);\n      }\n    }\n  }\n\n  _createBody(i) {\n    return {\n      ...super._createBody(),\n\n      ref: this._bodyRef.bind(this, i),\n    };\n  }\n\n  render() {\n    const {\n      width,\n      height,\n    } = this.props;\n\n    const {\n      meshStates,\n    } = this.state;\n\n    const d = 20;\n\n    const cubeMeshes = meshStates.map(({ position, quaternion, ref }, i) => (<RotatingCube\n      key={i}\n\n      position={position}\n      quaternion={quaternion}\n\n      ref={ref}\n\n      meshes={this.meshes}\n    />));\n\n    return (<div\n      ref=\"container\"\n    >\n      {this._getInputBox('Rotating Cubes - Direct Updates')}\n      <React3\n        antialias\n        mainCamera=\"camera\"\n        width={width}\n        height={height}\n\n        onAnimate={this._onAnimate}\n\n        clearColor={this.fog.color}\n\n        gammaInput\n        gammaOutput\n        shadowMapEnabled\n      >\n        <resources>\n          <boxGeometry\n            resourceId=\"cubeGeo\"\n\n            width={0.5}\n            height={0.5}\n            depth={0.5}\n\n            widthSegments={10}\n            heightSegments={10}\n          />\n          <meshPhongMaterial\n            resourceId=\"cubeMaterial\"\n\n            color={0x888888}\n          />\n        </resources>\n        <scene\n          ref=\"scene\"\n          fog={this.fog}\n        >\n          <perspectiveCamera\n            name=\"camera\"\n            fov={30}\n            aspect={width / height}\n            near={0.5}\n            far={10000}\n\n            position={this.cameraPosition}\n            quaternion={this.cameraQuaternion}\n\n            ref=\"camera\"\n          />\n          <ambientLight\n            color={0x666666}\n          />\n          <directionalLight\n            color={0xffffff}\n            intensity={1.75}\n\n            castShadow\n\n            shadowMapWidth={1024}\n            shadowMapHeight={1024}\n\n            shadowCameraLeft={-d}\n            shadowCameraRight={d}\n            shadowCameraTop={d}\n            shadowCameraBottom={-d}\n\n            shadowCameraFar={3 * d}\n            shadowCameraNear={d}\n\n            position={this.lightPosition}\n            lookAt={this.lightTarget}\n          />\n          <mesh\n            castShadow\n            receiveShadow\n\n            quaternion={this.groundQuaternion}\n          >\n            <planeBufferGeometry\n              width={100}\n              height={100}\n              widthSegments={1}\n              heightSegments={1}\n            />\n            <meshLambertMaterial\n              color={0x777777}\n            />\n          </mesh>\n          {cubeMeshes}\n        </scene>\n\n      </React3>\n    </div>);\n  }\n}\n\nexport default RotatingCubesDirectUpdates;\n"
  },
  {
    "path": "src/examples/DraggableCubes/AllCubes.js",
    "content": "import React from 'react';\nimport DraggableCube from './DraggableCube';\nimport * as THREE from 'three';\n\nimport PureRenderMixin from 'react/lib/ReactComponentWithPureRenderMixin';\n\nimport PropTypes from 'prop-types';\n\nimport MouseInput from '../inputs/MouseInput';\n\nclass AllCubes extends React.Component {\n  static propTypes = {\n    mouseInput: PropTypes.instanceOf(MouseInput),\n    camera: PropTypes.instanceOf(THREE.PerspectiveCamera),\n\n    onCubesMounted: PropTypes.func.isRequired,\n    onHoverStart: PropTypes.func.isRequired,\n    onHoverEnd: PropTypes.func.isRequired,\n    onDragStart: PropTypes.func.isRequired,\n    onDragEnd: PropTypes.func.isRequired,\n\n    cursor: PropTypes.any,\n  };\n\n  constructor(props, context) {\n    super(props, context);\n\n    const cubePositions = [];\n    cubePositions.length = 200;\n\n    for (let i = 0; i < 200; ++i) {\n      cubePositions[i] = new THREE.Vector3(\n        Math.random() * 1000 - 500,\n        Math.random() * 600 - 300,\n        Math.random() * 800 - 400\n      );\n    }\n\n    const cubes = [];\n    cubes.length = cubePositions.length;\n    this.cubes = cubes;\n\n    this.cubePositions = cubePositions;\n\n    this._hoveredCubes = 0;\n    this._draggingCubes = 0;\n  }\n\n  componentDidMount() {\n    const {\n      onCubesMounted,\n    } = this.props;\n\n    onCubesMounted(this.cubes);\n  }\n\n  shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate;\n\n  _onCubeCreate = (index, cube) => {\n    this.cubes[index] = cube;\n  };\n\n  _onCubeMouseEnter = () => {\n    if (this._hoveredCubes === 0) {\n      const {\n        onHoverStart,\n      } = this.props;\n\n      onHoverStart();\n    }\n\n    this._hoveredCubes++;\n  };\n\n  _onCubeMouseLeave = () => {\n    this._hoveredCubes--;\n\n    if (this._hoveredCubes === 0) {\n      const {\n        onHoverEnd,\n      } = this.props;\n\n      onHoverEnd();\n    }\n  };\n\n  _onCubeDragStart = () => {\n    if (this._draggingCubes === 0) {\n      const {\n        onDragStart,\n      } = this.props;\n\n      onDragStart();\n    }\n\n    this._draggingCubes++;\n  };\n\n  _onCubeDragEnd = () => {\n    this._draggingCubes--;\n\n    if (this._draggingCubes === 0) {\n      const {\n        onDragEnd,\n      } = this.props;\n\n      onDragEnd();\n    }\n  };\n\n\n  render() {\n    const {\n      mouseInput,\n      camera,\n\n      cursor,\n    } = this.props;\n\n    return (<group>\n      {this.cubePositions.map((cubePosition, index) => {\n        const onCreate = this._onCubeCreate.bind(this, index);\n        return (<DraggableCube\n          key={index}\n\n          mouseInput={mouseInput}\n          camera={camera}\n\n          initialPosition={cubePosition}\n          onCreate={onCreate}\n          onMouseEnter={this._onCubeMouseEnter}\n          onMouseLeave={this._onCubeMouseLeave}\n          onDragStart={this._onCubeDragStart}\n          onDragEnd={this._onCubeDragEnd}\n\n          cursor={cursor}\n        />);\n      })}\n    </group>);\n  }\n}\n\nexport default AllCubes;\n"
  },
  {
    "path": "src/examples/DraggableCubes/DraggableCube.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport * as THREE from 'three';\nimport PureRenderMixin from 'react/lib/ReactComponentWithPureRenderMixin';\n\nimport MouseInput from '../inputs/MouseInput';\n\n// shared plane for dragging purposes\n// it's good to share because you can drag only one cube at a time\nconst dragPlane = new THREE.Plane();\n\nconst backVector = new THREE.Vector3(0, 0, -1);\n\nclass DraggableCube extends React.Component {\n  static propTypes = {\n    initialPosition: PropTypes.instanceOf(THREE.Vector3).isRequired,\n\n    mouseInput: PropTypes.instanceOf(MouseInput),\n    camera: PropTypes.instanceOf(THREE.PerspectiveCamera),\n\n    onCreate: PropTypes.func.isRequired,\n\n    onMouseEnter: PropTypes.func.isRequired,\n    onMouseLeave: PropTypes.func.isRequired,\n    onDragStart: PropTypes.func.isRequired,\n    onDragEnd: PropTypes.func.isRequired,\n\n    cursor: PropTypes.any,\n  };\n\n  constructor(props, context) {\n    super(props, context);\n\n    this.rotation = new THREE.Euler(\n      Math.random() * 2 * Math.PI,\n      Math.random() * 2 * Math.PI,\n      Math.random() * 2 * Math.PI\n    );\n\n    this.scale = new THREE.Vector3(\n      Math.random() * 2 + 1,\n      Math.random() * 2 + 1,\n      Math.random() * 2 + 1\n    );\n\n    this.color = new THREE.Color(Math.random() * 0xffffff);\n\n    const hsl = this.color.getHSL();\n\n    hsl.s = Math.min(1, hsl.s * 1.1);\n    hsl.l = Math.min(1, hsl.l * 1.1);\n\n    const { h, s, l } = hsl;\n\n    this.hoverColor = new THREE.Color().setHSL(h, s, l);\n    this.pressedColor = 0xff0000;\n\n    const {\n      initialPosition,\n    } = props;\n\n    this.state = {\n      hovered: false,\n      pressed: false,\n      position: initialPosition,\n    };\n  }\n\n  shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate;\n\n  componentWillUnmount() {\n    document.removeEventListener('mouseup', this._onDocumentMouseUp);\n  }\n\n  _onMouseEnter = () => {\n    this.setState({\n      hovered: true,\n    });\n\n    const { onMouseEnter } = this.props;\n\n    onMouseEnter();\n  };\n\n  _onMouseDown = (event, intersection) => {\n    event.preventDefault();\n    event.stopPropagation();\n\n    const {\n      position,\n    } = this.state;\n\n    const {\n      onDragStart,\n      camera,\n    } = this.props;\n\n    dragPlane.setFromNormalAndCoplanarPoint(backVector.clone()\n      .applyQuaternion(camera.quaternion), intersection.point);\n\n    this._offset = intersection.point.clone().sub(position);\n\n    document.addEventListener('mouseup', this._onDocumentMouseUp);\n    document.addEventListener('mousemove', this._onDocumentMouseMove);\n\n    this.setState({\n      pressed: true,\n    });\n\n    onDragStart();\n  };\n\n  _onDocumentMouseMove = (event) => {\n    event.preventDefault();\n\n    const {\n      mouseInput,\n    } = this.props;\n\n    const ray:THREE.Ray = mouseInput.getCameraRay(new THREE\n      .Vector2(event.clientX, event.clientY));\n\n    const intersection = dragPlane.intersectLine(new THREE.Line3(\n      ray.origin,\n      ray.origin.clone()\n        .add(ray.direction.clone().multiplyScalar(10000))\n    ));\n\n    if (intersection) {\n      this.setState({\n        position: intersection.sub(this._offset),\n      });\n    }\n  };\n\n  _onDocumentMouseUp = (event) => {\n    event.preventDefault();\n\n    document.removeEventListener('mouseup', this._onDocumentMouseUp);\n    document.removeEventListener('mousemove', this._onDocumentMouseMove);\n\n    const {\n      onDragEnd,\n    } = this.props;\n\n    onDragEnd();\n\n    this.setState({\n      pressed: false,\n    });\n  };\n\n  _onMouseLeave = () => {\n    if (this.state.hovered) {\n      this.setState({\n        hovered: false,\n      });\n    }\n\n    const {\n      onMouseLeave,\n    } = this.props;\n\n    onMouseLeave();\n  };\n\n  _ref = (mesh) => {\n    const {\n      onCreate,\n    } = this.props;\n\n    onCreate(mesh);\n  };\n\n  render() {\n    const {\n      rotation,\n      scale,\n    } = this;\n\n    const {\n      cursor: {\n        dragging,\n      },\n    } = this.props;\n\n    const {\n      hovered,\n      pressed,\n      position,\n    } = this.state;\n\n    let color;\n\n    const hoverHighlight = (hovered && !dragging);\n    if (pressed) {\n      color = this.pressedColor;\n    } else if (hoverHighlight) {\n      color = this.hoverColor;\n    } else {\n      color = this.color;\n    }\n\n    return (<group\n      position={position}\n      rotation={rotation}\n      scale={scale}\n    >\n      <mesh\n        castShadow\n        receiveShadow\n\n        onMouseEnter={this._onMouseEnter}\n        onMouseDown={this._onMouseDown}\n        onMouseLeave={this._onMouseLeave}\n\n        ref={this._ref}\n      >\n        <geometryResource\n          resourceId=\"boxGeometry\"\n        />\n        <meshLambertMaterial\n          color={color}\n        />\n      </mesh>\n      {hoverHighlight ? <mesh\n        ignorePointerEvents\n      >\n        <geometryResource\n          resourceId=\"boxGeometry\"\n        />\n        <materialResource\n          resourceId=\"highlightMaterial\"\n        />\n      </mesh> : null}\n    </group>);\n  }\n}\n\nexport default DraggableCube;\n"
  },
  {
    "path": "src/examples/DraggableCubes/index.js",
    "content": "import React from 'react';\n\nimport PureRenderMixin from 'react/lib/ReactComponentWithPureRenderMixin';\n\nimport * as THREE from 'three';\nimport Stats from 'stats.js';\n\nimport React3 from 'react-three-renderer';\n\nimport ExampleBase from '../ExampleBase';\n\nimport TrackballControls from '../../ref/trackball';\n\nimport MouseInput from '../inputs/MouseInput';\n\nimport AllCubes from './AllCubes';\n\nclass DraggableCubes extends ExampleBase {\n  constructor(props, context) {\n    super(props, context);\n\n    this.state = {\n      cameraPosition: new THREE.Vector3(0, 0, 1000),\n      cameraRotation: new THREE.Euler(),\n      mouseInput: null,\n      hovering: false,\n      dragging: false,\n    };\n\n    this._cursor = {\n      hovering: false,\n      dragging: false,\n    };\n\n    this.lightPosition = new THREE.Vector3(0, 500, 2000);\n    this.lightTarget = new THREE.Vector3(0, 0, 0);\n  }\n\n  shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate;\n\n  _onAnimate = () => {\n    this._onAnimateInternal();\n  };\n\n  componentDidMount() {\n    this.stats = new Stats();\n\n    this.stats.domElement.style.position = 'absolute';\n    this.stats.domElement.style.top = '0px';\n\n    const {\n      container,\n      camera,\n    } = this.refs;\n\n    container.appendChild(this.stats.domElement);\n\n    const controls = new TrackballControls(camera);\n\n    controls.rotateSpeed = 1.0;\n    controls.zoomSpeed = 1.2;\n    controls.panSpeed = 0.8;\n    controls.noZoom = false;\n    controls.noPan = false;\n    controls.staticMoving = true;\n    controls.dynamicDampingFactor = 0.3;\n\n    this.controls = controls;\n\n    this.controls.addEventListener('change', this._onTrackballChange);\n  }\n\n  _onCubesMounted = (cubes) => {\n    this.cubes = cubes;\n  };\n\n  _onHoverStart = () => {\n    this.setState({\n      hovering: true,\n    });\n  };\n\n  _onHoverEnd = () => {\n    this.setState({\n      hovering: false,\n    });\n  };\n\n  _onDragStart = () => {\n    this.setState({\n      dragging: true,\n    });\n  };\n\n  _onDragEnd = () => {\n    this.setState({\n      dragging: false,\n    });\n  };\n\n\n  componentDidUpdate(newProps) {\n    const {\n      mouseInput,\n    } = this.refs;\n\n    const {\n      width,\n      height,\n    } = this.props;\n\n    if (width !== newProps.width || height !== newProps.height) {\n      mouseInput.containerResized();\n    }\n  }\n\n  _onTrackballChange = () => {\n    this.setState({\n      cameraPosition: this.refs.camera.position.clone(),\n      cameraRotation: this.refs.camera.rotation.clone(),\n    });\n  };\n\n  componentWillUnmount() {\n    this.controls.removeEventListener('change', this._onTrackballChange);\n\n    this.controls.dispose();\n    delete this.controls;\n\n    delete this.stats;\n  }\n\n  _onAnimateInternal() {\n    const {\n      mouseInput,\n      camera,\n    } = this.refs;\n\n    if (!mouseInput.isReady()) {\n      const {\n        scene,\n        container,\n      } = this.refs;\n\n      mouseInput.ready(scene, container, camera);\n      mouseInput.restrictIntersections(this.cubes);\n      mouseInput.setActive(false);\n    }\n\n    if (this.state.mouseInput !== mouseInput) {\n      this.setState({\n        mouseInput,\n      });\n    }\n\n    if (this.state.camera !== camera) {\n      this.setState({\n        camera,\n      });\n    }\n\n    this.stats.update();\n    this.controls.update();\n  }\n\n  render() {\n    const {\n      width,\n      height,\n    } = this.props;\n\n    const {\n      cameraPosition,\n      cameraRotation,\n\n      mouseInput,\n      camera,\n\n      hovering,\n      dragging,\n    } = this.state;\n\n    const style = {};\n\n    if (dragging) {\n      style.cursor = 'move';\n    } else if (hovering) {\n      style.cursor = 'pointer';\n    }\n\n    this._cursor.hovering = hovering;\n    this._cursor.dragging = dragging;\n\n    return (<div\n      ref=\"container\"\n      style={style}\n    >\n      <React3\n        width={width}\n        height={height}\n        antialias\n        pixelRatio={window.devicePixelRatio}\n        mainCamera=\"mainCamera\"\n        onAnimate={this._onAnimate}\n        sortObjects={false}\n        shadowMapEnabled\n        shadowMapType={THREE.PCFShadowMap}\n        clearColor={0xf0f0f0}\n      >\n        <module\n          ref=\"mouseInput\"\n          descriptor={MouseInput}\n        />\n        <resources>\n          <boxGeometry\n            resourceId=\"boxGeometry\"\n\n            width={40}\n            height={40}\n            depth={40}\n          />\n          <meshBasicMaterial\n            resourceId=\"highlightMaterial\"\n\n            color={0xffff00}\n            wireframe\n          />\n        </resources>\n        <scene ref=\"scene\">\n          <perspectiveCamera\n            fov={70}\n            aspect={width / height}\n            near={1}\n            far={10000}\n            name=\"mainCamera\"\n            ref=\"camera\"\n            position={cameraPosition}\n            rotation={cameraRotation}\n          />\n          <ambientLight\n            color={0x505050}\n          />\n          <spotLight\n            color={0xffffff}\n            intensity={1.5}\n            position={this.lightPosition}\n            lookAt={this.lightTarget}\n\n            castShadow\n            shadowCameraNear={200}\n            shadowCameraFar={10000}\n            shadowCameraFov={50}\n\n            shadowBias={-0.00022}\n\n            shadowMapWidth={2048}\n            shadowMapHeight={2048}\n          />\n          <AllCubes\n            mouseInput={mouseInput}\n            camera={camera}\n\n            onCubesMounted={this._onCubesMounted}\n\n            onHoverStart={this._onHoverStart}\n            onHoverEnd={this._onHoverEnd}\n            onDragStart={this._onDragStart}\n            onDragEnd={this._onDragEnd}\n\n            cursor={this._cursor}\n          />\n        </scene>\n      </React3>\n    </div>);\n  }\n}\n\nexport default DraggableCubes;\n"
  },
  {
    "path": "src/examples/ExampleBase.js",
    "content": "import React from 'react';\n\nimport PropTypes from 'prop-types';\n\nclass ExampleBase extends React.Component {\n  static propTypes = {\n    width: PropTypes.number.isRequired,\n    height: PropTypes.number.isRequired,\n  };\n}\n\nexport default ExampleBase;\n"
  },
  {
    "path": "src/examples/ExampleBrowser.js",
    "content": "import React from 'react';\nimport { NavLink } from 'react-router-dom';\nimport ExampleViewer from './ExampleViewer';\n\nimport SimpleExample from './Simple/index';\nimport ManualRenderingExample from './ManualRendering/index';\nimport ClothExample from './AnimationCloth/index';\nimport GeometriesExample from './Geometries/index';\nimport CameraExample from './WebGLCameraExample/index';\nimport GeometryShapesExample from './GeometryShapes/index';\nimport DraggableCubes from './DraggableCubes/index';\nimport Physics from './Physics/index';\nimport PhysicsMousePick from './Physics/mousePick';\nimport BenchmarkRotatingCubes from './Benchmark/RotatingCubes';\nimport RotatingCubesDirectUpdates from './Benchmark/RotatingCubesDirectUpdates';\n\nconst examples = [\n  {\n    name: 'Simple',\n    component: SimpleExample,\n    url: 'Simple/index',\n    slug: 'webgl_simple',\n  },\n  {\n    name: 'Cloth',\n    component: ClothExample,\n    url: 'AnimationCloth/index',\n    slug: 'webgl_cloth',\n  },\n  {\n    name: 'Camera',\n    component: CameraExample,\n    url: 'WebGLCameraExample/index',\n    slug: 'webgl_camera',\n  },\n  {\n    name: 'Geometries',\n    component: GeometriesExample,\n    url: 'Geometries/index',\n    slug: 'webgl_geometries',\n  },\n  {\n    name: 'Geometry Shapes',\n    component: GeometryShapesExample,\n    url: 'GeometryShapes/index',\n    slug: 'webgl_geometry_shapes',\n  },\n  {\n    name: 'Draggable Cubes',\n    component: DraggableCubes,\n    url: 'DraggableCubes/index',\n    slug: 'webgl_draggable_cubes',\n  },\n  {\n    name: 'Physics',\n    component: Physics,\n    url: 'Physics/index',\n    slug: 'webgl_physics',\n  },\n  {\n    name: 'Physics - MousePick',\n    component: PhysicsMousePick,\n    url: 'Physics/mousePick',\n    slug: 'webgl_physics_mousepick',\n  },\n  {\n    separator: true,\n    name: 'Advanced',\n  },\n  {\n    name: 'Without react-dom',\n    advanced: true,\n    page: 'advanced.html',\n  },\n  {\n    name: 'Manual rendering',\n    component: ManualRenderingExample,\n    url: 'ManualRendering/index',\n    slug: 'advanced_manual_rendering',\n  },\n  {\n    separator: true,\n    name: 'Benchmarks',\n  },\n  {\n    name: 'RotatingCubes - Through React',\n    component: BenchmarkRotatingCubes,\n    url: 'Benchmark/RotatingCubes',\n    slug: 'benchmarks_rotating_cubes_react',\n  },\n  {\n    name: 'RotatingCubes - Direct Updates',\n    component: RotatingCubesDirectUpdates,\n    url: 'Benchmark/RotatingCubesDirectUpdates',\n    slug: 'benchmarks_rotating_cubes_direct',\n  },\n];\n\nconst ExampleBrowser = ({ match }) => {\n  const { params } = match;\n  const activeExample = params.slug && examples.find(example => example.slug === params.slug);\n  return (\n    <div>\n      <div id=\"panel\" className=\"collapsed\">\n        <h1><a href=\"https://github.com/toxicFork/react-three-renderer/\">react-three-renderer</a> / examples</h1>\n        <div id=\"content\">\n          <div>\n            <h2>webgl</h2>\n            {examples.map((example, index) => {\n              if (example.separator) {\n                return (<h2 key={index}>{example.name}</h2>);\n              }\n\n              if (example.advanced) {\n                return (<div key={index}>\n                  <a href={example.page} target=\"blank\">{example.name}</a> (new tab)\n                </div>);\n              }\n\n              return (<NavLink\n                to={`/${example.slug}`}\n                key={index}\n                className=\"link\"\n                activeClassName=\"selected\"\n              >\n                {example.name}\n              </NavLink>);\n            })}\n          </div>\n        </div>\n      </div>\n      <ExampleViewer example={activeExample} />\n    </div>\n  );\n};\n\nExampleBrowser.propTypes = {\n  match: React.PropTypes.object.isRequired,\n};\n\nexport default ExampleBrowser;\n"
  },
  {
    "path": "src/examples/ExampleViewer.js",
    "content": "import React from 'react';\nimport sizeMe from 'react-sizeme';\n\nconst ExampleViewer = ({ example, size }) => {\n  let sourceButton = null;\n  let exampleContent = null;\n\n  if (example) {\n    const {\n      component: ExampleComponent,\n      url,\n    } = example;\n    exampleContent = (<ExampleComponent width={size.width} height={size.height} />);\n    sourceButton = (<div key=\"src\" id=\"button\">\n      <a\n        href={`https://github.com/toxicFork/react-three-renderer-example/blob/master/src/examples/${url}.js`}\n        target=\"_blank\"\n      >\n        View source\n      </a>\n    </div>);\n  }\n\n  return (\n    <div id=\"viewer\">\n      {exampleContent}\n      {sourceButton}\n    </div>\n  );\n};\n\nExampleViewer.propTypes = {\n  example: React.PropTypes.object,\n  size: React.PropTypes.object,\n};\n\nexport default sizeMe({ monitorHeight: true, refreshRate: 200 })(ExampleViewer);\n"
  },
  {
    "path": "src/examples/Geometries/index.js",
    "content": "import React from 'react';\n\nimport * as THREE from 'three';\nimport Stats from 'stats.js';\n\nimport React3 from 'react-three-renderer';\n\nimport ExampleBase from '../ExampleBase';\n\n\nclass Geometries extends ExampleBase {\n  constructor(props, context) {\n    super(props, context);\n\n    this.directionalLightPosition = new THREE.Vector3(0, 1, 0);\n\n    this.objectPositions = [\n      new THREE.Vector3(-400, 0, 200),\n      new THREE.Vector3(-200, 0, 200),\n      new THREE.Vector3(0, 0, 200),\n      new THREE.Vector3(200, 0, 200),\n      new THREE.Vector3(-400, 0, 0),\n      new THREE.Vector3(-200, 0, 0),\n      new THREE.Vector3(0, 0, 0),\n      new THREE.Vector3(200, 0, 0),\n      new THREE.Vector3(400, 0, 0),\n\n      new THREE.Vector3(-400, 0, -200),\n      new THREE.Vector3(-200, 0, -200),\n      new THREE.Vector3(0, 0, -200),\n      new THREE.Vector3(200, 0, -200),\n      new THREE.Vector3(400, 0, -200),\n    ];\n\n    this.lathePoints = [];\n\n    for (let i = 0; i < 50; i++) {\n      this.lathePoints.push(new THREE\n        .Vector2(Math.sin(i * 0.2) * Math.sin(i * 0.1) * 15 + 50, (i - 5) * 2));\n    }\n\n    this.arrowDir = new THREE.Vector3(0, 1, 0);\n    this.arrowOrigin = new THREE.Vector3(0, 0, 0);\n\n    this.scenePosition = new THREE.Vector3(0, 0, 0);\n\n    this.state = {\n      ...this.state,\n      timer: Date.now() * 0.0001,\n    };\n  }\n\n  _onAnimate = () => {\n    this._onAnimateInternal();\n  };\n\n  componentDidMount() {\n    this.stats = new Stats();\n\n    this.stats.domElement.style.position = 'absolute';\n    this.stats.domElement.style.top = '0px';\n\n    this.refs.container.appendChild(this.stats.domElement);\n  }\n\n  componentWillUnmount() {\n    delete this.stats;\n  }\n\n  _onAnimateInternal() {\n    const timer = Date.now() * 0.0001;\n\n    this.setState({\n      timer,\n    });\n\n    this.stats.update();\n  }\n\n  render() {\n    const {\n      width,\n      height,\n    } = this.props;\n\n    const {\n      timer,\n    } = this.state;\n\n    const objectRotation = new THREE.Euler(\n      timer * 5,\n      timer * 2.5,\n      0\n    );\n\n    return (<div ref=\"container\">\n      <React3\n        width={width}\n        height={height}\n        antialias\n        pixelRatio={window.devicePixelRatio}\n        mainCamera=\"mainCamera\"\n        onAnimate={this._onAnimate}\n      >\n        <resources>\n          <texture\n            resourceId=\"texture\"\n            url=\"textures/UV_Grid_Sm.jpg\"\n            wrapS={THREE.RepeatWrapping}\n            wrapT={THREE.RepeatWrapping}\n            anisotropy={16}\n          />\n          <meshLambertMaterial\n            resourceId=\"material\"\n            side={THREE.DoubleSide}\n          >\n            <textureResource\n              resourceId=\"texture\"\n            />\n          </meshLambertMaterial>\n        </resources>\n        <scene>\n          <perspectiveCamera\n            fov={45}\n            aspect={width / height}\n            near={1}\n            far={2000}\n            lookAt={this.scenePosition}\n            name=\"mainCamera\"\n            position={new THREE.Vector3(\n              Math.cos(timer) * 800,\n              400,\n              Math.sin(timer) * 800\n            )}\n          />\n          <ambientLight\n            color={0x404040}\n          />\n          <directionalLight\n            color={0xffffff}\n            position={this.directionalLightPosition}\n            lookAt={this.scenePosition}\n          />\n          <mesh\n            position={this.objectPositions[0]}\n            rotation={objectRotation}\n          >\n            <sphereGeometry\n              radius={75}\n              widthSegments={20}\n              heightSegments={10}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[1]}\n            rotation={objectRotation}\n          >\n            <icosahedronGeometry\n              radius={75}\n              detail={1}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[2]}\n            rotation={objectRotation}\n          >\n            <octahedronGeometry\n              radius={75}\n              detail={2}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[3]}\n            rotation={objectRotation}\n          >\n            <tetrahedronGeometry\n              radius={75}\n              detail={0}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[4]}\n            rotation={objectRotation}\n          >\n            <planeBufferGeometry\n              width={100}\n              height={100}\n              widthSegments={4}\n              heightSegments={4}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[5]}\n            rotation={objectRotation}\n          >\n            <boxGeometry\n              width={100}\n              height={100}\n              depth={100}\n              widthSegments={4}\n              heightSegments={4}\n              depthSegments={4}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[6]}\n            rotation={objectRotation}\n          >\n            <circleGeometry\n              radius={50}\n              segments={20}\n              thetaStart={0}\n              thetaLength={Math.PI * 2}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[7]}\n            rotation={objectRotation}\n          >\n            <ringGeometry\n              innerRadius={10}\n              outerRadius={50}\n              thetaSegments={20}\n              phiSegments={5}\n              thetaStart={0}\n              thetaLength={Math.PI * 2}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[8]}\n            rotation={objectRotation}\n          >\n            <cylinderGeometry\n              radiusTop={25}\n              radiusBottom={75}\n              height={100}\n              radialSegments={40}\n              heightSegments={5}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[9]}\n            rotation={objectRotation}\n          >\n            <latheGeometry\n              points={this.lathePoints}\n              segments={20}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[10]}\n            rotation={objectRotation}\n          >\n            <torusGeometry\n              radius={50}\n              tube={20}\n              radialSegments={20}\n              tubularSegments={20}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <mesh\n            position={this.objectPositions[11]}\n            rotation={objectRotation}\n          >\n            <torusKnotGeometry\n              radius={50}\n              tube={10}\n              radialSegments={50}\n              tubularSegments={20}\n            />\n            <materialResource\n              resourceId=\"material\"\n            />\n          </mesh>\n          <axisHelper\n            position={this.objectPositions[12]}\n            size={50}\n            rotation={objectRotation}\n          />\n          <arrowHelper\n            dir={this.arrowDir}\n            origin={this.arrowOrigin}\n            length={50}\n            position={this.objectPositions[13]}\n            rotation={objectRotation}\n          />\n        </scene>\n      </React3>\n    </div>);\n  }\n}\n\nexport default Geometries;\n"
  },
  {
    "path": "src/examples/GeometryShapes/Rect.js",
    "content": "import React from 'react';\nimport PropTypes from 'react/lib/ReactPropTypes';\n\nfunction Rect(props) {\n  const {\n    width,\n    length,\n    resourceId,\n  } = props;\n\n  return (<shape resourceId={resourceId}>\n    <moveTo\n      x={0}\n      y={0}\n    />\n    <lineTo\n      x={0}\n      y={width}\n    />\n    <lineTo\n      x={length}\n      y={width}\n    />\n    <lineTo\n      x={length}\n      y={0}\n    />\n    <lineTo\n      x={0}\n      y={0}\n    />\n  </shape>);\n}\n\nRect.propTypes = {\n  width: PropTypes.number.isRequired,\n  length: PropTypes.number.isRequired,\n  resourceId: PropTypes.string.isRequired,\n};\n\nexport default Rect;\n"
  },
  {
    "path": "src/examples/GeometryShapes/Resources.js",
    "content": "import React from 'react';\nimport * as THREE from 'three';\n\nimport Rect from './Rect';\n\nclass Resources extends React.Component {\n  shouldComponentUpdate() {\n    return false;\n  }\n\n  render() {\n    this.textureRepeat = new THREE.Vector2(0.008, 0.008);\n\n    const x = 0;\n    const y = 0;\n\n    const sqLength = 80;\n\n    const rectLength = 120;\n    const rectWidth = 40;\n\n    const californiaPts = [];\n\n    californiaPts.push(new THREE.Vector2(610, 320));\n    californiaPts.push(new THREE.Vector2(450, 300));\n    californiaPts.push(new THREE.Vector2(392, 392));\n    californiaPts.push(new THREE.Vector2(266, 438));\n    californiaPts.push(new THREE.Vector2(190, 570));\n    californiaPts.push(new THREE.Vector2(190, 600));\n    californiaPts.push(new THREE.Vector2(160, 620));\n    californiaPts.push(new THREE.Vector2(160, 650));\n    californiaPts.push(new THREE.Vector2(180, 640));\n    californiaPts.push(new THREE.Vector2(165, 680));\n    californiaPts.push(new THREE.Vector2(150, 670));\n    californiaPts.push(new THREE.Vector2(90, 737));\n    californiaPts.push(new THREE.Vector2(80, 795));\n    californiaPts.push(new THREE.Vector2(50, 835));\n    californiaPts.push(new THREE.Vector2(64, 870));\n    californiaPts.push(new THREE.Vector2(60, 945));\n    californiaPts.push(new THREE.Vector2(300, 945));\n    californiaPts.push(new THREE.Vector2(300, 743));\n    californiaPts.push(new THREE.Vector2(600, 473));\n    californiaPts.push(new THREE.Vector2(626, 425));\n    californiaPts.push(new THREE.Vector2(600, 370));\n    californiaPts.push(new THREE.Vector2(610, 320));\n\n    for (let i = 0; i < californiaPts.length; i++) californiaPts[i].multiplyScalar(0.25);\n\n    this.californiaPts = californiaPts;\n\n    return (\n      <resources>\n        <texture\n          resourceId=\"texture\"\n          url=\"textures/UV_Grid_Sm.jpg\"\n          wrapS={THREE.RepeatWrapping}\n          wrapT={THREE.RepeatWrapping}\n          repeat={this.textureRepeat}\n        />\n        <meshBasicMaterial\n          resourceId=\"hoverMaterial\"\n          color={0xff0000}\n          side={THREE.DoubleSide}\n        />\n        <meshPhongMaterial\n          resourceId=\"phongMaterial\"\n          side={THREE.DoubleSide}\n        >\n          <textureResource\n            resourceId=\"texture\"\n          />\n        </meshPhongMaterial>\n        <shape\n          resourceId=\"california\"\n          points={this.californiaPts}\n        />\n        <shape resourceId=\"triangle\">\n          <moveTo\n            x={80}\n            y={20}\n          />\n          <lineTo\n            x={40}\n            y={80}\n          />\n          <lineTo\n            x={120}\n            y={80}\n          />\n          <lineTo\n            x={80}\n            y={20}\n          />\n        </shape>\n        <shape resourceId=\"heart\">\n          <moveTo\n            x={x + 25}\n            y={y + 25}\n          />\n          <bezierCurveTo\n            cp1X={x + 25}\n            cp1Y={y + 25}\n            cp2X={x + 20}\n            cp2Y={y}\n            aX={x}\n            aY={y}\n          />\n          <bezierCurveTo\n            cp1X={x - 30}\n            cp1Y={y}\n            cp2X={x - 30}\n            cp2Y={y + 35}\n            aX={x - 30}\n            aY={y + 35}\n          />\n          <bezierCurveTo\n            cp1X={x - 30}\n            cp1Y={y + 55}\n            cp2X={x - 10}\n            cp2Y={y + 77}\n            aX={x + 25}\n            aY={y + 95}\n          />\n          <bezierCurveTo\n            cp1X={x + 60}\n            cp1Y={y + 77}\n            cp2X={x + 80}\n            cp2Y={y + 55}\n            aX={x + 80}\n            aY={y + 35}\n          />\n          <bezierCurveTo\n            cp1X={ x + 80}\n            cp1Y={y + 35}\n            cp2X={x + 80}\n            cp2Y={y}\n            aX={x + 50}\n            aY={y}\n          />\n          <bezierCurveTo\n            cp1X={x + 35}\n            cp1Y={y}\n            cp2X={x + 25}\n            cp2Y={y + 25}\n            aX={x + 25}\n            aY={y + 25}\n          />\n        </shape>\n        <Rect\n          resourceId=\"square\"\n          width={sqLength}\n          length={sqLength}\n        />\n        <Rect\n          resourceId=\"rect\"\n          width={rectWidth}\n          length={rectLength}\n        />\n        {((function roundedRect(rectX, rectY,\n                                roundedRectWidth, roundedRectHeight,\n                                radius) {\n          return (<shape resourceId=\"roundedRect\">\n            <moveTo\n              x={rectX}\n              y={rectY + radius}\n            />\n            <lineTo\n              x={rectX}\n              y={rectY + roundedRectHeight - radius}\n            />\n            <quadraticCurveTo\n              cpX={rectX}\n              cpY={rectY + roundedRectHeight}\n              x={rectX + radius}\n              y={rectY + roundedRectHeight}\n            />\n            <lineTo\n              x={rectX + roundedRectWidth - radius}\n              y={rectY + roundedRectHeight}\n            />\n            <quadraticCurveTo\n              cpX={rectX + roundedRectWidth}\n              cpY={rectY + roundedRectHeight}\n              x={rectX + roundedRectWidth}\n              y={rectY + roundedRectHeight - radius}\n            />\n            <lineTo\n              x={rectX + roundedRectWidth}\n              y={rectY + radius}\n            />\n            <quadraticCurveTo\n              cpX={rectX + roundedRectWidth}\n              cpY={rectY}\n              x={rectX + roundedRectWidth - radius}\n              y={rectY}\n            />\n            <lineTo\n              x={rectX + radius}\n              y={rectY}\n            />\n            <quadraticCurveTo\n              cpX={rectX}\n              cpY={rectY}\n              x={rectX}\n              y={rectY + radius}\n            />\n          </shape>);\n        })(0, 0, 50, 50, 20))}\n        <shape\n          resourceId=\"track\"\n        >\n          <moveTo\n            x={40}\n            y={40}\n          />\n          <lineTo\n            x={40}\n            y={160}\n          />\n          <absArc\n            x={60}\n            y={160}\n            radius={20}\n            startAngle={Math.PI}\n            endAngle={0}\n            clockwise\n          />\n          <lineTo\n            x={80}\n            y={40}\n          />\n          <absArc\n            x={60}\n            y={40}\n            radius={20}\n            startAngle={2 * Math.PI}\n            endAngle={Math.PI}\n            clockwise\n          />\n        </shape>\n        {((function circleShape() {\n          const circleRadius = 40;\n\n          return (<shape resourceId=\"circle\">\n            <moveTo\n              x={0}\n              y={circleRadius}\n            />\n            <quadraticCurveTo\n              cpX={circleRadius}\n              cpY={circleRadius}\n              x={circleRadius}\n              y={0}\n            />\n            <quadraticCurveTo\n              cpX={circleRadius}\n              cpY={-circleRadius}\n              x={0}\n              y={-circleRadius}\n            />\n            <quadraticCurveTo\n              cpX={-circleRadius}\n              cpY={-circleRadius}\n              x={-circleRadius}\n              y={0}\n            />\n            <quadraticCurveTo\n              cpX={-circleRadius}\n              cpY={circleRadius}\n              x={0}\n              y={circleRadius}\n            />\n          </shape>);\n        })())}\n        <shape resourceId=\"arc\">\n          <moveTo\n            x={50}\n            y={10}\n          />\n          <absArc\n            x={10}\n            y={10}\n            radius={40}\n            startAngle={0}\n            endAngle={Math.PI * 2}\n            clockwise={false}\n          />\n          <hole>\n            <moveTo\n              x={20}\n              y={10}\n            />\n            <absArc\n              x={10}\n              y={10}\n              radius={10}\n              startAngle={0}\n              endAngle={Math.PI * 2}\n              clockwise\n            />\n          </hole>\n        </shape>\n        <shape resourceId=\"fish\">\n          <moveTo\n            x={x}\n            y={y}\n          />\n          <quadraticCurveTo\n            cpX={x + 50}\n            cpY={y - 80}\n            x={x + 90}\n            y={y - 10}\n          />\n          <quadraticCurveTo\n            cpX={x + 100}\n            cpY={y - 10}\n            x={x + 115}\n            y={y - 40}\n          />\n          <quadraticCurveTo\n            cpX={x + 115}\n            cpY={y}\n            x={x + 115}\n            y={y + 40}\n          />\n          <quadraticCurveTo\n            cpX={x + 100}\n            cpY={y + 10}\n            x={x + 90}\n            y={y + 10}\n          />\n          <quadraticCurveTo\n            cpX={x + 50}\n            cpY={y + 80}\n            x={x}\n            y={y}\n          />\n        </shape>\n        <shape resourceId=\"smiley\">\n          <moveTo\n            x={80}\n            y={40}\n          />\n          <absArc\n            x={40}\n            y={40}\n            radius={40}\n            startAngle={0}\n            endAngle={Math.PI * 2}\n            clockwise={false}\n          />\n          <hole key=\"eye1\">\n            <moveTo\n              x={35}\n              y={20}\n            />\n            <absEllipse\n              x={25}\n              y={20}\n              xRadius={10}\n              yRadius={10}\n              startAngle={0}\n              endAngle={Math.PI * 2}\n              clockwise\n            />\n          </hole>\n          <hole key=\"eye2\">\n            <moveTo\n              x={65}\n              y={20}\n            />\n            <absArc\n              x={55}\n              y={20}\n              radius={10}\n              startAngle={0}\n              endAngle={Math.PI * 2}\n              clockwise\n            />\n          </hole>\n          <hole key=\"mouth\">\n            <moveTo\n              x={20}\n              y={40}\n            />\n            <quadraticCurveTo\n              cpX={40}\n              cpY={60}\n              x={60}\n              y={40}\n            />\n            <bezierCurveTo\n              cp1X={70}\n              cp1Y={45}\n              cp2X={70}\n              cp2Y={50}\n              aX={60}\n              aY={60}\n            />\n            <quadraticCurveTo\n              cpX={40}\n              cpY={80}\n              x={20}\n              y={60}\n            />\n            <quadraticCurveTo\n              cpX={5}\n              cpY={50}\n              x={20}\n              y={40}\n            />\n          </hole>\n        </shape>\n        {((function splineShape() {\n          const splinePoints = [];\n          splinePoints.push(new THREE.Vector2(70, 20));\n          splinePoints.push(new THREE.Vector2(80, 90));\n          splinePoints.push(new THREE.Vector2(-30, 70));\n          splinePoints.push(new THREE.Vector2(0, 0));\n\n          return (<shape resourceId=\"spline\">\n            <moveTo\n              x={0}\n              y={0}\n            />\n            <splineThru\n              points={splinePoints}\n            />\n          </shape>);\n        })())}\n      </resources>);\n  }\n}\n\nexport default Resources;\n"
  },
  {
    "path": "src/examples/GeometryShapes/Shape.js",
    "content": "import React from 'react';\nimport * as THREE from 'three';\nimport PropTypes from 'react/lib/ReactPropTypes';\n\nimport PureRenderMixin from 'react/lib/ReactComponentWithPureRenderMixin';\n\nconst extrudeSettings = {\n  amount: 8,\n  bevelEnabled: true,\n  bevelSegments: 2,\n  steps: 2,\n  bevelSize: 1,\n  bevelThickness: 1,\n};\n\nclass Shape extends React.Component {\n  static propTypes = {\n    resourceId: PropTypes.string.isRequired,\n    color: PropTypes.any.isRequired,\n    x: PropTypes.number.isRequired,\n    y: PropTypes.number.isRequired,\n    z: PropTypes.number.isRequired,\n    rx: PropTypes.number.isRequired,\n    ry: PropTypes.number.isRequired,\n    rz: PropTypes.number.isRequired,\n    s: PropTypes.number.isRequired,\n  };\n\n  shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate;\n\n  render() {\n    const {\n      rx,\n      ry,\n      rz,\n      s,\n      resourceId,\n      color,\n      x,\n      y,\n      z,\n      } = this.props;\n\n    const rotation = new THREE.Euler(rx, ry, rz);\n    const scale = new THREE.Vector3(s, s, s);\n\n    return (<group>\n      <mesh\n        // flat shape with texture\n        position={new THREE.Vector3(x, y, z - 175)}\n        rotation={rotation}\n        scale={scale}\n      >\n        <shapeGeometryResource\n          resourceId={resourceId}\n          type=\"shape\"\n        />\n        <materialResource\n          resourceId={'phongMaterial'}\n        />\n      </mesh>\n      <mesh\n        // flat shape\n        position={new THREE.Vector3(x, y, z - 125)}\n        rotation={rotation}\n        scale={scale}\n      >\n        <shapeGeometryResource\n          resourceId={resourceId}\n          type=\"shape\"\n        />\n        <meshPhongMaterial\n          color={color}\n          side={THREE.DoubleSide}\n        />\n      </mesh>\n      <mesh\n        // 3d shape\n        position={new THREE.Vector3(x, y, z - 75)}\n        rotation={rotation}\n        scale={scale}\n      >\n        <extrudeGeometry\n          settings={extrudeSettings}\n        >\n          <shapeResource\n            resourceId={resourceId}\n          />\n        </extrudeGeometry>\n        <meshPhongMaterial\n          color={color}\n        />\n      </mesh>\n      <line\n        // solid line\n        position={new THREE.Vector3(x, y, z - 25)}\n        rotation={rotation}\n        scale={scale}\n      >\n        <shapeGeometryResource\n          resourceId={resourceId}\n          type=\"points\"\n        />\n        <lineBasicMaterial\n          color={color}\n          // wireframe\n        />\n      </line>\n      <points\n        // vertices from real points\n        position={new THREE.Vector3(x, y, z + 25)}\n        rotation={rotation}\n        scale={scale}\n      >\n        <shapeGeometryResource\n          resourceId={resourceId}\n          type=\"points\"\n        />\n        <pointsMaterial\n          color={color}\n          size={4}\n          // wireframe\n        />\n      </points>\n      <line\n        // line from equidistance sampled points\n        position={new THREE.Vector3(x, y, z + 75)}\n        rotation={rotation}\n        scale={scale}\n      >\n        <shapeGeometryResource\n          resourceId={resourceId}\n          type=\"spacedPoints\"\n          divisions={50}\n        />\n        <lineBasicMaterial\n          color={color}\n          linewidth={3}\n          // wireframe\n        />\n      </line>\n      <points\n        // equidistance sampled points\n        position={new THREE.Vector3(x, y, z + 125)}\n        rotation={rotation}\n        scale={scale}\n      >\n        <shapeGeometryResource\n          resourceId={resourceId}\n          type=\"spacedPoints\"\n          divisions={50}\n        />\n        <pointsMaterial\n          color={color}\n          size={4}\n          // wireframe\n        />\n      </points>\n    </group>);\n  }\n}\n\nexport default Shape;\n"
  },
  {
    "path": "src/examples/GeometryShapes/Shapes.js",
    "content": "import React from 'react';\nimport Shape from './Shape';\n\nclass Shapes extends React.Component {\n  shouldComponentUpdate() {\n    return false;\n  }\n\n  render() {\n    return (<group>\n      <Shape\n        resourceId=\"california\"\n        x={-300}\n        y={-100}\n        z={0}\n        color={0xf08000}\n        rx={0}\n        ry={0}\n        rz={0}\n        s={1}\n      />\n      <Shape\n        resourceId=\"triangle\"\n        color={0x8080f0}\n        x={-180}\n        y={0}\n        z={0}\n        rx={0}\n        ry={0}\n        rz={0}\n        s={1}\n      />\n      <Shape\n        resourceId=\"roundedRect\"\n        x={-150}\n        y={150}\n        z={0}\n        color={0x008000}\n        rx={0}\n        ry={0}\n        rz={0}\n        s={1}\n      />\n      <Shape\n        resourceId=\"track\"\n        x={200}\n        y={-100}\n        z={0}\n        color={0x008080}\n        rx={0}\n        ry={0}\n        rz={0}\n        s={1}\n      />\n      <Shape\n        resourceId=\"square\"\n        color={0x0040f0}\n        x={150}\n        y={100}\n        z={0}\n        rx={0}\n        ry={0}\n        rz={0}\n        s={1}\n      />\n      <Shape\n        resourceId=\"heart\"\n        color={0xf00000}\n        x={60}\n        y={100}\n        z={0}\n        rx={0}\n        ry={0}\n        rz={Math.PI}\n        s={1}\n      />\n      <Shape\n        resourceId=\"circle\"\n        color={0x00f000}\n        x={120}\n        y={250}\n        z={0}\n        rx={0}\n        ry={0}\n        rz={0}\n        s={1}\n      />\n      <Shape\n        resourceId=\"fish\"\n        color={0x404040}\n        x={-60}\n        y={200}\n        z={0}\n        rx={0}\n        ry={0}\n        rz={0}\n        s={1}\n      />\n      <Shape\n        resourceId=\"smiley\"\n        x={-200}\n        y={250}\n        z={0}\n        color={0xf000f0}\n        rx={0}\n        ry={0}\n        rz={Math.PI}\n        s={1}\n      />\n      <Shape\n        resourceId=\"arc\"\n        color={0x804000}\n        x={150}\n        y={0}\n        z={0}\n        rx={0}\n        ry={0}\n        rz={0}\n        s={1}\n      />\n      <Shape\n        resourceId=\"spline\"\n        color={0x808080}\n        x={-50}\n        y={-100}\n        z={0}\n        rx={0}\n        ry={0}\n        rz={0}\n        s={1}\n      />\n    </group>);\n  }\n}\n\nexport default Shapes;\n"
  },
  {
    "path": "src/examples/GeometryShapes/index.js",
    "content": "import React from 'react';\n\nimport * as THREE from 'three';\nimport Stats from 'stats.js';\n\nimport React3 from 'react-three-renderer';\n\nimport ExampleBase from '../ExampleBase';\n\nimport Resources from './Resources';\n\nimport Shapes from './Shapes';\n\nclass GeometryShapes extends ExampleBase {\n  constructor(props, context) {\n    super(props, context);\n\n    this.cameraPosition = new THREE.Vector3(0, 150, 500);\n    this.groupPosition = new THREE.Vector3(0, 50, 0);\n\n    this.targetRotationOnMouseDown = 0;\n\n    this.mouseX = 0;\n    this.mouseXOnMouseDown = 0;\n    this.targetRotation = 0;\n\n    this.state = {\n      ...this.state,\n      groupRotation: new THREE.Euler(0, 0, 0),\n    };\n  }\n\n  componentDidMount() {\n    this.stats = new Stats();\n\n    const container = this.refs.container;\n\n    this.stats.domElement.style.position = 'absolute';\n    this.stats.domElement.style.top = '0px';\n\n    container.appendChild(this.stats.domElement);\n\n    container.addEventListener('mousedown', this._onDocumentMouseDown, false);\n    container.addEventListener('touchstart', this._onDocumentTouchStart, false);\n    document.addEventListener('touchmove', this._onDocumentTouchMove, false);\n  }\n\n  componentWillUnmount() {\n    const container = this.refs.container;\n\n    container.removeEventListener('mousedown', this._onDocumentMouseDown, false);\n    container.removeEventListener('touchstart', this._onDocumentTouchStart, false);\n    document.removeEventListener('touchmove', this._onDocumentTouchMove, false);\n    document.removeEventListener('mousemove', this._onDocumentMouseMove, false);\n    document.removeEventListener('mouseup', this._onDocumentMouseUp, false);\n    document.removeEventListener('mouseout', this._onDocumentMouseOut, false);\n\n    delete this.stats;\n  }\n\n  _onDocumentMouseDown = (event) => {\n    event.preventDefault();\n\n    document.addEventListener('mousemove', this._onDocumentMouseMove, false);\n    document.addEventListener('mouseup', this._onDocumentMouseUp, false);\n    document.addEventListener('mouseout', this._onDocumentMouseOut, false);\n\n    const {\n      width,\n    } = this.props;\n\n    const windowHalfX = width / 2;\n\n    this.mouseXOnMouseDown = event.clientX - windowHalfX;\n    this.targetRotationOnMouseDown = this.targetRotation;\n  };\n\n  _onDocumentMouseMove = (event) => {\n    const {\n      width,\n    } = this.props;\n\n    const windowHalfX = width / 2;\n\n    this.mouseX = event.clientX - windowHalfX;\n    this.targetRotation = this.targetRotationOnMouseDown +\n      (this.mouseX - this.mouseXOnMouseDown) * 0.02;\n  };\n\n  _onDocumentMouseUp = () => {\n    document.removeEventListener('mousemove', this._onDocumentMouseMove, false);\n    document.removeEventListener('mouseup', this._onDocumentMouseUp, false);\n    document.removeEventListener('mouseout', this._onDocumentMouseOut, false);\n  };\n\n  _onDocumentMouseOut = () => {\n    document.removeEventListener('mousemove', this._onDocumentMouseMove, false);\n    document.removeEventListener('mouseup', this._onDocumentMouseUp, false);\n    document.removeEventListener('mouseout', this._onDocumentMouseOut, false);\n  };\n\n  _onDocumentTouchStart = (event) => {\n    if (event.touches.length === 1) {\n      event.preventDefault();\n\n      const {\n        width,\n      } = this.props;\n\n      const windowHalfX = width / 2;\n\n      this.mouseXOnMouseDown = event.touches[0].pageX - windowHalfX;\n      this.targetRotationOnMouseDown = this.targetRotation;\n    }\n  };\n\n  _onDocumentTouchMove = (event) => {\n    if (event.touches.length === 1) {\n      event.preventDefault();\n\n      const {\n        width,\n      } = this.props;\n\n      const windowHalfX = width / 2;\n\n      this.mouseX = event.touches[0].pageX - windowHalfX;\n      this.targetRotation = this.targetRotationOnMouseDown +\n        (this.mouseX - this.mouseXOnMouseDown) * 0.05;\n    }\n  };\n\n  _onAnimate = () => {\n    this._onAnimateInternal();\n  };\n\n  _onAnimateInternal() {\n    const groupRotationY = this.state.groupRotation.y;\n\n    if (Math.abs(groupRotationY - this.targetRotation) > 0.0001) {\n      this.setState({\n        groupRotation: new THREE.Euler(0, groupRotationY +\n          (this.targetRotation - groupRotationY) * 0.05, 0),\n      });\n    }\n\n    this.stats.update();\n  }\n\n  render() {\n    const {\n      width,\n      height,\n    } = this.props;\n\n    const {\n      groupRotation,\n    } = this.state;\n\n    return (<div ref=\"container\">\n      <div\n        style={{\n          color: 'black',\n          position: 'absolute',\n          top: '10px',\n          width: '100%',\n          textAlign: 'center',\n        }}\n      >\n        Simple procedurally generated 3D shapes<br/>\n        Drag to spin\n      </div>\n      <React3\n        width={width}\n        height={height}\n        antialias\n        pixelRatio={window.devicePixelRatio}\n        mainCamera=\"mainCamera\"\n        clearColor={0xf0f0f0}\n        onAnimate={this._onAnimate}\n      >\n        <scene ref=\"scene\">\n          <perspectiveCamera\n            name=\"mainCamera\"\n            ref=\"camera\"\n            fov={50}\n            aspect={width / height}\n            near={1}\n            far={1000}\n\n            position={this.cameraPosition}\n          >\n            <pointLight\n              color={0xffffff}\n              intensity={0.8}\n            />\n          </perspectiveCamera>\n          <Resources/>\n          <group\n            position={this.groupPosition}\n            rotation={groupRotation}\n          >\n            <Shapes/>\n          </group>\n        </scene>\n      </React3>\n    </div>);\n  }\n}\n\nexport default GeometryShapes;\n"
  },
  {
    "path": "src/examples/ManualRendering/Info.js",
    "content": "import React from 'react';\n\nimport PropTypes from 'prop-types';\n\nclass Info extends React.Component {\n  static propTypes = {\n    onUpdateColorButtonPress: PropTypes.func.isRequired,\n    onRenderButtonPress: PropTypes.func.isRequired,\n    onManualButtonPress: PropTypes.func.isRequired,\n    forceManual: PropTypes.bool,\n    cubeColor: PropTypes.number.isRequired,\n  };\n\n  constructor(props, context) {\n    super(props, context);\n\n    this.state = {\n      colorButtonPressed: false,\n    };\n  }\n\n  _onColorButtonPress = () => {\n    this.props.onUpdateColorButtonPress();\n\n    this.setState({\n      colorButtonPressed: true,\n    });\n  };\n\n  _onTriggerPress = () => {\n    this.setState({\n      colorButtonPressed: false,\n    });\n\n    this.props.onRenderButtonPress();\n  };\n\n  _manualButtonPress = () => {\n    this.setState({\n      colorButtonPressed: false,\n    });\n\n    this.props.onManualButtonPress();\n  };\n\n  render() {\n    const {\n      forceManual,\n      cubeColor,\n    } = this.props;\n\n    const {\n      colorButtonPressed,\n    } = this.state;\n\n    const triggerButtonStyle = {};\n\n    if (colorButtonPressed && forceManual) {\n      triggerButtonStyle.fontWeight = 'bold';\n    }\n\n    return (<div\n      style={{\n        position: 'absolute',\n        textAlign: 'center',\n        top: 0,\n        width: '100%',\n        padding: 5,\n        color: 'white',\n        zIndex: 100,\n      }}\n    >\n      <h2>Manual rendering</h2>\n      If automatic rendering is off, the canvas will re-render only\n      when you press the \"Trigger render\" button.<br/>\n      This way you can save battery life\n      or have finer controls for rendering.<br/>\n      Check your CPU profiler with automatic rendering on/off :)<br/>\n      <br/>\n      <button onClick={this._onColorButtonPress}>Update cube color state</button>\n      <span\n        style={{\n          width: 15,\n          minHeight: 15,\n          marginLeft: 5,\n          display: 'inline-block',\n          background: `rgb(\n            ${(cubeColor >> 16 & 255)},\n            ${(cubeColor >> 8 & 255)},\n            ${(cubeColor & 255)})`,\n        }}\n      >&nbsp;</span>\n      <br/>\n      <button\n        onClick={this._onTriggerPress}\n        style={triggerButtonStyle}\n        disabled={!forceManual}\n      >{colorButtonPressed && forceManual ? 'TRIGGER RENDER' : 'Trigger render'}\n      </button>\n      <br/>\n      <button onClick={this._manualButtonPress}>\n        Turn automatic rendering {forceManual ? 'ON' : 'OFF'}\n      </button>\n    </div>);\n  }\n}\n\nexport default Info;\n"
  },
  {
    "path": "src/examples/ManualRendering/index.js",
    "content": "import React from 'react';\nimport React3 from 'react-three-renderer';\nimport * as THREE from 'three';\n\nimport ExampleBase from '../ExampleBase';\n\nimport Info from './Info';\n\nclass Manual extends ExampleBase {\n  constructor(props, context) {\n    super(props, context);\n\n    this.cameraPosition = new THREE.Vector3(0, 0, 5);\n\n    this._onManualRenderTriggerCreated = (renderTrigger) => {\n      // assign to variable to be able to reuse the trigger\n      this._renderTrigger = renderTrigger;\n    };\n\n    this.state = {\n      cubeColor: 0x00ff00,\n      forceManual: true,\n    };\n  }\n\n  componentDidMount() {\n    // render one frame to show initial scene\n    this._renderTrigger();\n\n    setTimeout(() => {\n      // this should not be visible!\n      this.setState({\n        cubeColor: 0x0000ff,\n      });\n    }, 20);\n\n    setTimeout(() => {\n      // render again after updating color\n      this.setState({\n        cubeColor: 0xff0000,\n      }, () => {\n        this._renderTrigger();\n      });\n    }, 1000);\n  }\n\n  _onUpdateColorButtonPress = () => {\n    this.setState({\n      cubeColor: Math.floor(Math.random() * 0xffffff),\n    });\n  };\n\n  _onRenderButtonPress = () => {\n    this._renderTrigger();\n  };\n\n  _onManualButtonPress = () => {\n    this.setState({\n      forceManual: !this.state.forceManual,\n    });\n  };\n\n  render() {\n    const {\n      width,\n      height,\n    } = this.props;\n\n    const {\n      forceManual,\n      cubeColor,\n    } = this.state;\n\n    return (<div>\n      <div>\n        <Info\n          onUpdateColorButtonPress={this._onUpdateColorButtonPress}\n          onRenderButtonPress={this._onRenderButtonPress}\n          onManualButtonPress={this._onManualButtonPress}\n          forceManual={forceManual}\n          cubeColor={cubeColor}\n        />\n      </div>\n      <React3\n        width={width}\n        height={height}\n\n        forceManualRender={forceManual}\n        onManualRenderTriggerCreated={this._onManualRenderTriggerCreated}\n\n        mainCamera=\"camera\"\n      >\n        <scene>\n          <perspectiveCamera\n            name=\"camera\"\n            fov={75}\n            aspect={width / height}\n            near={0.1}\n            far={1000}\n\n            position={this.cameraPosition}\n          />\n          <mesh>\n            <boxGeometry\n              width={1}\n              height={1}\n              depth={1}\n            />\n            <meshBasicMaterial\n              color={cubeColor}\n            />\n          </mesh>\n        </scene>\n      </React3></div>);\n  }\n}\n\nexport default Manual;\n"
  },
  {
    "path": "src/examples/Physics/index.js",
    "content": "import React from 'react';\nimport React3 from 'react-three-renderer';\nimport * as THREE from 'three';\nimport CANNON from 'cannon/src/Cannon';\n\nimport Stats from 'stats.js';\n\nimport ExampleBase from '../ExampleBase';\n\nclass Physics extends ExampleBase {\n  constructor(props, context) {\n    super(props, context);\n\n    const world = new CANNON.World();\n    this.world = world;\n    world.gravity.set(0, 0, 0);\n    world.broadphase = new CANNON.NaiveBroadphase();\n    world.solver.iterations = 10;\n    const shape = new CANNON.Box(new CANNON.Vec3(1, 1, 1));\n    const mass = 1;\n    const body = new CANNON.Body({\n      mass,\n    });\n    body.addShape(shape);\n    body.angularVelocity.set(0, 10, 0);\n    body.angularDamping = 0.5;\n    world.addBody(body);\n\n    this._onMouseDown = () => {\n      body.angularVelocity.y += 5;\n    };\n\n    this.cameraPosition = new THREE.Vector3(0, 0, 5);\n\n    const timeStep = 1 / 60;\n\n    const updatePhysics = () => {\n      // Step the physics world\n      world.step(timeStep);\n      // Copy coordinates from Cannon.js to Three.js\n\n      this.setState({\n        // need to call new THREE.* in order to ensure an update goes through\n        meshPosition: new THREE.Vector3().copy(body.position),\n        meshQuaternion: new THREE.Quaternion().copy(body.quaternion),\n      });\n    };\n\n    this._onAnimate = () => {\n      updatePhysics();\n\n      this.stats.update();\n    };\n\n    this.state = {\n      meshPosition: new THREE.Vector3(),\n      meshQuaternion: new THREE.Quaternion(),\n    };\n  }\n\n  componentWillUnmount() {\n    delete this.world;\n\n    delete this.stats;\n  }\n\n  componentDidMount() {\n    const {\n      container,\n      } = this.refs;\n\n    this.stats = new Stats();\n\n    this.stats.domElement.style.position = 'absolute';\n    this.stats.domElement.style.top = '0px';\n\n    container.appendChild(this.stats.domElement);\n  }\n\n  render() {\n    const {\n      width,\n      height,\n      } = this.props;\n\n    const {\n      meshPosition,\n      meshQuaternion,\n      } = this.state;\n\n    return (<div\n      ref=\"container\"\n\n      onMouseDown={this._onMouseDown}\n    ><React3\n      antialias\n      mainCamera=\"camera\"\n      width={width}\n      height={height}\n\n      onAnimate={this._onAnimate}\n    >\n      <scene>\n        <perspectiveCamera\n          name=\"camera\"\n          fov={75}\n          aspect={width / height}\n          near={1}\n          far={100}\n\n          position={this.cameraPosition}\n        />\n        <mesh\n          position={meshPosition}\n          quaternion={meshQuaternion}\n        >\n          <boxGeometry\n            width={2}\n            height={2}\n            depth={2}\n          />\n          <meshBasicMaterial\n            color={0x00ff00}\n            wireframe\n          />\n        </mesh>\n      </scene>\n    </React3>\n    </div>);\n  }\n}\n\nexport default Physics;\n"
  },
  {
    "path": "src/examples/Physics/mousePick/PickableMesh.js",
    "content": "import React from 'react';\nimport * as THREE from 'three';\n\nimport PropTypes from 'prop-types';\n\nclass PickableMesh extends React.Component {\n  static propTypes = {\n    position: PropTypes.instanceOf(THREE.Vector3).isRequired,\n    quaternion: PropTypes.instanceOf(THREE.Quaternion).isRequired,\n    meshes: PropTypes.arrayOf(PropTypes.instanceOf(THREE.Mesh)).isRequired,\n    bodyIndex: PropTypes.number.isRequired,\n\n    onMouseDown: PropTypes.func.isRequired,\n  };\n\n  componentDidMount() {\n    const {\n      mesh,\n    } = this.refs;\n\n    const {\n      bodyIndex,\n      meshes,\n    } = this.props;\n\n    mesh.userData._bodyIndex = bodyIndex;\n\n    meshes.push(mesh);\n  }\n\n  componentWillUnmount() {\n    const {\n      mesh,\n    } = this.refs;\n\n    const {\n      meshes,\n    } = this.props;\n\n    meshes.splice(meshes.indexOf(mesh), 1);\n  }\n\n  _onMouseDown = (event, intersection) => {\n    event.preventDefault();\n\n    this.props.onMouseDown(this.refs.mesh.userData._bodyIndex, intersection);\n  };\n\n  render() {\n    const {\n      position,\n      quaternion,\n    } = this.props;\n\n    return (<mesh\n      position={position}\n      quaternion={quaternion}\n\n      ref=\"mesh\"\n\n      castShadow\n\n      onMouseDown={this._onMouseDown}\n    >\n      <geometryResource\n        resourceId=\"cubeGeo\"\n      />\n      <materialResource\n        resourceId=\"cubeMaterial\"\n      />\n    </mesh>);\n  }\n}\n\nexport default PickableMesh;\n"
  },
  {
    "path": "src/examples/Physics/mousePick.js",
    "content": "import React from 'react';\nimport React3 from 'react-three-renderer';\nimport * as THREE from 'three';\nimport CANNON from 'cannon/src/Cannon';\n\nimport MouseInput from '../inputs/MouseInput';\n\nimport ExampleBase from '../ExampleBase';\n\nimport Stats from 'stats.js';\n\nimport PickableMesh from './mousePick/PickableMesh';\n\nconst backVector = new THREE.Vector3(0, 0, -1);\nconst dragPlane = new THREE.Plane();\n\nclass PhysicsMousePick extends ExampleBase {\n  constructor(props, context) {\n    super(props, context);\n\n    const N = 100;\n\n    this._raycaster = new THREE.Raycaster();\n\n    this.fog = new THREE.Fog(0x001525, 10, 40);\n\n    const d = 20;\n\n    this.lightPosition = new THREE.Vector3(d, d, d);\n    this.lightTarget = new THREE.Vector3(0, 0, 0);\n    this.groundQuaternion = new THREE.Quaternion()\n      .setFromAxisAngle(new THREE.Vector3(1, 0, 0), -Math.PI / 2);\n    this.cameraPosition = new THREE.Vector3(10, 2, 0);\n    this.cameraQuaternion = new THREE.Quaternion()\n      .setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2);\n\n    const world = new CANNON.World();\n\n    const bodies = [];\n    const meshRefs = [];\n\n    let constrainedBody;\n    let pivot;\n\n    const initCannon = () => {\n      world.quatNormalizeSkip = 0;\n      world.quatNormalizeFast = false;\n\n      world.gravity.set(0, -10, 0);\n      world.broadphase = new CANNON.NaiveBroadphase();\n\n      const mass = 5;\n\n      const boxShape = new CANNON.Box(new CANNON.Vec3(0.25, 0.25, 0.25));\n\n      for (let i = 0; i < N; ++i) {\n        const boxBody = new CANNON.Body({\n          mass,\n        });\n\n        boxBody.addShape(boxShape);\n        boxBody.position.set(\n          -2.5 + Math.random() * 5,\n          2.5 + Math.random() * 5,\n          -2.5 + Math.random() * 5);\n        world.addBody(boxBody);\n        bodies.push(boxBody);\n\n        meshRefs.push((mesh) => {\n          if (mesh) {\n            mesh.userData._bodyIndex = i;\n\n            this.meshes.push(mesh);\n          }\n        });\n      }\n\n      const groundShape = new CANNON.Plane();\n      const groundBody = new CANNON.Body({ mass: 0 });\n\n      groundBody.addShape(groundShape);\n      groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);\n\n      // WAIT A MINUTE I CAN CREATE A REACT RENDERER FOR CANNON\n      // patience is a virtue\n      // breathe in breathe out breathe in breathe out\n      // let's finish this one first\n\n      world.addBody(groundBody);\n\n      const shape = new CANNON.Sphere(0.1);\n      const jointBody = new CANNON.Body({ mass: 0 });\n      jointBody.addShape(shape);\n      jointBody.collisionFilterGroup = 0;\n      jointBody.collisionFilterMask = 0;\n\n      world.addBody(jointBody);\n\n      this.jointBody = jointBody;\n    };\n\n    initCannon();\n\n    const timeStep = 1 / 60;\n    const updatePhysics = () => {\n      // Step the physics world\n      world.step(timeStep);\n    };\n\n    const _getMeshStates = () => bodies\n      .map(({ position, quaternion }, bodyIndex) => ({\n        position: new THREE.Vector3().copy(position),\n        quaternion: new THREE.Quaternion().copy(quaternion),\n        ref: meshRefs[bodyIndex],\n      }));\n\n    this._onAnimate = () => {\n      updatePhysics();\n\n      this.setState({\n        meshStates: _getMeshStates(),\n      });\n\n      this.stats.update();\n    };\n\n    this._addMouseConstraint = ({ x, y, z }, bodyIndex) => {\n      // The cannon body constrained by the mouse joint\n      constrainedBody = bodies[bodyIndex];\n      // Vector to the clicked point, relative to the body\n      const v1 = new CANNON.Vec3(x, y, z).vsub(constrainedBody.position);\n      // Apply anti-quaternion to vector to transform it into the local body coordinate system\n      const antiRot = constrainedBody.quaternion.inverse();\n      pivot = antiRot.vmult(v1); // pivot is not in local body coordinates\n      // Move the cannon click marker particle to the click position\n      this.jointBody.position.set(x, y, z);\n      // Create a new constraint\n      // The pivot for the jointBody is zero\n      this.mouseConstraint = new CANNON\n        .PointToPointConstraint(\n        constrainedBody,\n        pivot,\n        this.jointBody,\n        new CANNON.Vec3(0, 0, 0)\n      );\n      // Add the t to world\n      world.addConstraint(this.mouseConstraint);\n\n      this.world = world;\n    };\n\n    this.state = {\n      clickMarkerVisible: false,\n      clickMarkerPosition: new THREE.Vector3(),\n\n      meshStates: _getMeshStates(),\n    };\n\n    this.meshes = [];\n  }\n\n  _setClickMarker(x, y, z) {\n    return {\n      clickMarkerPosition: new THREE.Vector3(x, y, z),\n      clickMarkerVisible: true,\n    };\n  }\n\n  componentDidMount() {\n    const {\n      mouseInput,\n      container,\n    } = this.refs;\n\n    this.stats = new Stats();\n\n    this.stats.domElement.style.position = 'absolute';\n    this.stats.domElement.style.top = '0px';\n\n    container.appendChild(this.stats.domElement);\n\n    if (!mouseInput.isReady()) {\n      const {\n        scene,\n        camera,\n      } = this.refs;\n\n      mouseInput.ready(scene, container, camera);\n      mouseInput.restrictIntersections(this.meshes);\n      mouseInput.setActive(false);\n    }\n  }\n\n  componentDidUpdate(newProps) {\n    const {\n      mouseInput,\n    } = this.refs;\n\n    const {\n      width,\n      height,\n    } = this.props;\n\n    if (width !== newProps.width || height !== newProps.height) {\n      mouseInput.containerResized();\n    }\n  }\n\n  componentWillUnmount() {\n    delete this.world;\n    delete this.stats;\n  }\n\n  _onMeshMouseDown = (bodyIndex, intersection) => {\n    const {\n      camera,\n    } = this.refs;\n\n    const pos = intersection.point;\n\n    this.setState({\n      // Set marker on contact point\n      ...this._setClickMarker(pos.x, pos.y, pos.z),\n    });\n\n    dragPlane.setFromNormalAndCoplanarPoint(backVector.clone()\n      .applyQuaternion(camera.quaternion), pos);\n\n    this._addMouseConstraint(pos, bodyIndex);\n\n    window.addEventListener('mousemove', this._onMouseMove, false);\n    window.addEventListener('mouseup', this._onMouseUp, false);\n  };\n\n  _onMouseUp = () => {\n    window.removeEventListener('mousemove', this._onMouseMove, false);\n    window.removeEventListener('mouseup', this._onMouseUp, false);\n\n    this.setState({\n      clickMarkerVisible: false,\n    });\n\n    this.world.removeConstraint(this.mouseConstraint);\n    this.mouseConstraint = false;\n  };\n\n  _onMouseMove = (event) => {\n    const {\n      mouseInput,\n    } = this.refs;\n\n    const ray:THREE.Ray = mouseInput.getCameraRay(new THREE.Vector2(event.clientX, event.clientY));\n\n    const pos = dragPlane.intersectLine(\n      new THREE.Line3(ray.origin, ray.origin\n        .clone()\n        .add(ray.direction\n          .clone()\n          .multiplyScalar(10000))));\n\n    if (pos) {\n      this.setState({\n        ... this._setClickMarker(pos.x, pos.y, pos.z),\n      });\n\n      // Move the joint body to a new position\n      this.jointBody.position.set(pos.x, pos.y, pos.z);\n      this.mouseConstraint.update();\n    }\n  };\n\n  render() {\n    const {\n      width,\n      height,\n    } = this.props;\n\n    const {\n      clickMarkerVisible,\n      clickMarkerPosition,\n\n      meshStates,\n    } = this.state;\n\n    const d = 20;\n\n    const cubeMeshes = meshStates.map(({ position, quaternion }, i) =>\n      (<PickableMesh\n        key={i}\n\n        position={position}\n        quaternion={quaternion}\n\n        bodyIndex={i}\n\n        meshes={this.meshes}\n\n        onMouseDown={this._onMeshMouseDown}\n      />));\n\n    return (<div\n      ref=\"container\"\n    >\n      <React3\n        antialias\n        mainCamera=\"camera\"\n        width={width}\n        height={height}\n\n        onAnimate={this._onAnimate}\n\n        clearColor={this.fog.color}\n\n        gammaInput\n        gammaOutput\n        shadowMapEnabled\n      >\n        <module\n          ref=\"mouseInput\"\n          descriptor={MouseInput}\n        />\n        <resources>\n          <boxGeometry\n            resourceId=\"cubeGeo\"\n\n            width={0.5}\n            height={0.5}\n            depth={0.5}\n\n            widthSegments={10}\n            heightSegments={10}\n          />\n          <meshPhongMaterial\n            resourceId=\"cubeMaterial\"\n\n            color={0x888888}\n          />\n        </resources>\n        <scene\n          ref=\"scene\"\n          fog={this.fog}\n        >\n          <perspectiveCamera\n            name=\"camera\"\n            fov={30}\n            aspect={width / height}\n            near={0.5}\n            far={10000}\n\n            position={this.cameraPosition}\n            quaternion={this.cameraQuaternion}\n\n            ref=\"camera\"\n          />\n          <ambientLight\n            color={0x666666}\n          />\n          <directionalLight\n            color={0xffffff}\n            intensity={1.75}\n\n            castShadow\n\n            shadowMapWidth={1024}\n            shadowMapHeight={1024}\n\n            shadowCameraLeft={-d}\n            shadowCameraRight={d}\n            shadowCameraTop={d}\n            shadowCameraBottom={-d}\n\n            shadowCameraFar={3 * d}\n            shadowCameraNear={d}\n\n            position={this.lightPosition}\n            lookAt={this.lightTarget}\n          />\n          <mesh\n            castShadow\n            receiveShadow\n\n            quaternion={this.groundQuaternion}\n          >\n            <planeBufferGeometry\n              width={100}\n              height={100}\n              widthSegments={1}\n              heightSegments={1}\n            />\n            <meshLambertMaterial\n              color={0x777777}\n            />\n          </mesh>\n          {cubeMeshes}\n          <mesh // click marker\n            visible={clickMarkerVisible}\n\n            position={clickMarkerPosition}\n          >\n            <sphereGeometry\n              radius={0.2}\n              widthSegments={8}\n              heightSegments={8}\n            />\n            <meshLambertMaterial\n              color={0x772211}\n            />\n          </mesh>\n        </scene>\n\n      </React3>\n    </div>);\n  }\n}\n\nexport default PhysicsMousePick;\n"
  },
  {
    "path": "src/examples/Simple/index.js",
    "content": "import React from 'react';\nimport React3 from 'react-three-renderer';\nimport * as THREE from 'three';\n\nclass Simple extends React.Component {\n  static propTypes = {\n    width: React.PropTypes.number.isRequired,\n    height: React.PropTypes.number.isRequired,\n  };\n\n  constructor(props, context) {\n    super(props, context);\n\n    this.cameraPosition = new THREE.Vector3(0, 0, 5);\n\n    // construct the position vector here, because if we use 'new' within render,\n    // React will think that things have changed when they have not.\n\n    this.state = {\n      cubeRotation: new THREE.Euler(),\n    };\n\n    this._onAnimate = () => {\n      // we will get this callback every frame\n\n      // pretend cubeRotation is immutable.\n      // this helps with updates and pure rendering.\n      // React will be sure that the rotation has now updated.\n      this.setState({\n        cubeRotation: new THREE.Euler(\n          this.state.cubeRotation.x + 0.1,\n          this.state.cubeRotation.y + 0.1,\n          0\n        ),\n      });\n    };\n  }\n\n  render() {\n    const {\n      width,\n      height,\n    } = this.props;\n\n    // or you can use:\n    // width = window.innerWidth\n    // height = window.innerHeight\n\n    return (<React3\n      mainCamera=\"camera\" // this points to the perspectiveCamera below\n      width={width}\n      height={height}\n\n      onAnimate={this._onAnimate}\n    >\n      <scene>\n        <perspectiveCamera\n          name=\"camera\"\n          fov={75}\n          aspect={width / height}\n          near={0.1}\n          far={1000}\n\n          position={this.cameraPosition}\n        />\n        <mesh\n          rotation={this.state.cubeRotation}\n        >\n          <boxGeometry\n            width={1}\n            height={1}\n            depth={1}\n          />\n          <meshBasicMaterial\n            color={0x00ff00}\n          />\n        </mesh>\n      </scene>\n    </React3>);\n  }\n}\n\nexport default Simple;\n"
  },
  {
    "path": "src/examples/WebGLCameraExample/Info.js",
    "content": "import React from 'react';\n\nimport PropTypes from 'prop-types';\n\nclass Info extends React.Component {\n  static propTypes = {\n    pause: PropTypes.func.isRequired,\n    frame: PropTypes.func.isRequired,\n  };\n\n  render() {\n    return (<div\n      style={{\n        position: 'absolute',\n        textAlign: 'center',\n        top: 0,\n        width: '100%',\n        padding: 5,\n        color: 'white',\n        zIndex: 100,\n      }}\n    >\n      <a\n        href=\"http://threejs.org\"\n        style={{\n          color: '#0080ff',\n        }}\n      >three.js</a> - cameras<br/>\n      <b\n        style={{\n          color: 'lightgreen',\n        }}\n      >O</b> orthographic &nbsp;\n      <b\n        style={{\n          color: 'lightgreen',\n        }}\n      >P</b> perspective <br/>\n      <button onClick={this.props.pause}>Pause</button>\n      <button onClick={this.props.frame}>Frame</button>\n    </div>);\n  }\n}\n\nexport default Info;\n"
  },
  {
    "path": "src/examples/WebGLCameraExample/PointCloud.js",
    "content": "import React from 'react';\nimport * as THREE from 'three';\n\nclass PointCloud extends React.Component {\n  constructor(props, context) {\n    super(props, context);\n\n    this.pointCloudVertices = [];\n\n    for (let i = 0; i < 10000; i++) {\n      const vertex = new THREE.Vector3();\n\n      vertex.x = THREE.Math.randFloatSpread(2000);\n      vertex.y = THREE.Math.randFloatSpread(2000);\n      vertex.z = THREE.Math.randFloatSpread(2000);\n\n      this.pointCloudVertices.push(vertex);\n    }\n  }\n\n  shouldComponentUpdate() {\n    return false;\n  }\n\n  render() {\n    return (<points>\n      <geometry vertices={this.pointCloudVertices}/>\n      <pointsMaterial\n        color={0x888888}\n      />\n    </points>);\n  }\n}\n\nexport default PointCloud;\n"
  },
  {
    "path": "src/examples/WebGLCameraExample/index.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport * as THREE from 'three';\nimport ExampleBase from './../ExampleBase';\n\nimport React3 from 'react-three-renderer';\n\nimport Info from './Info';\n\nimport PointCloud from './PointCloud';\n\nimport TrackballControls from '../../ref/trackball';\n\nconst perspectiveCameraName = 'perspectiveCamera';\nconst orthographicCameraName = 'orthographicCamera';\nconst mainCameraName = 'mainCamera';\n\nconst perspectiveCameraRotation = new THREE.Euler(0, Math.PI, 0);\nconst orthographicCameraRotation = new THREE.Euler(0, Math.PI, 0);\n\nconst spherePosition = new THREE.Vector3(0, 0, 150);\n\nclass WebGLCameraExample extends ExampleBase {\n  constructor(props, context) {\n    super(props, context);\n\n    const r = Date.now() * 0.0005;\n\n    this.state = {\n      ... this.state,\n      meshPosition: new THREE.Vector3(Math.cos(r), Math.sin(r), Math.sin(r)).multiplyScalar(700),\n      childPosition: new THREE.Vector3(70 * Math.cos(2 * r), 150, 70 * Math.sin(r)),\n      activeCameraName: perspectiveCameraName,\n      paused: false,\n      mainCameraPosition: new THREE.Vector3(0, 0, 2500),\n    };\n  }\n\n  componentDidMount() {\n    document.addEventListener('keydown', this._onKeyDown, false);\n\n    const controls = new TrackballControls(this.refs.mainCamera,\n      ReactDOM.findDOMNode(this.refs.react3));\n\n    controls.rotateSpeed = 1.0;\n    controls.zoomSpeed = 1.2;\n    controls.panSpeed = 0.8;\n\n    controls.noZoom = false;\n    controls.noPan = false;\n\n    controls.staticMoving = true;\n    controls.dynamicDampingFactor = 0.3;\n\n    controls.addEventListener('change', () => {\n      this.setState({\n        mainCameraPosition: this.refs.mainCamera.position,\n      });\n    });\n\n    this.controls = controls;\n  }\n\n  componentWillUnmount() {\n    document.removeEventListener('keydown', this._onKeyDown, false);\n\n    this.controls.dispose();\n    delete this.controls;\n  }\n\n  _onKeyDown = (event) => {\n    switch (event.keyCode) {\n      default:\n        break;\n      case 79: // O\n        this.setState({\n          activeCameraName: orthographicCameraName,\n        });\n        break;\n      case 80: // P\n        this.setState({\n          activeCameraName: perspectiveCameraName,\n        });\n\n        break;\n    }\n  };\n\n  _onAnimate = () => {\n    this.controls.update();\n\n    if (this.state.paused) {\n      return;\n    }\n\n    const r = Date.now() * 0.0005;\n\n    this.setState({\n      r,\n      meshPosition: new THREE.Vector3(Math.cos(r), Math.sin(r), Math.sin(r)).multiplyScalar(700),\n      childPosition: new THREE.Vector3(70 * Math.cos(2 * r), 150, 70 * Math.sin(r)),\n    });\n  };\n\n  _pause = () => {\n    this.setState({\n      paused: !this.state.paused,\n    });\n  };\n\n  _frame = () => {\n    this.setState({\n      paused: false,\n    }, () => {\n      this._onAnimate();\n      this.setState({\n        paused: true,\n      });\n    });\n  };\n\n  render() {\n    const {\n      width,\n      height,\n    } = this.props;\n\n    const {\n      meshPosition,\n      childPosition,\n      r,\n    } = this.state;\n\n    const aspectRatio = 0.5 * width / height;\n\n    return (<div>\n      <Info\n        pause={this._pause}\n        frame={this._frame}\n      />\n      <React3\n        ref=\"react3\"\n        width={width}\n        height={height}\n        antialias\n        onAnimate={this._onAnimate}\n      >\n        <viewport\n          x={0}\n          y={0}\n          width={width / 2}\n          height={height}\n          cameraName={this.state.activeCameraName}\n        />\n        <viewport\n          x={width / 2}\n          y={0}\n          width={width / 2}\n          height={height}\n          cameraName={mainCameraName}\n        />\n        <scene>\n          <perspectiveCamera\n            ref=\"mainCamera\"\n            name={mainCameraName}\n            fov={50}\n            aspect={aspectRatio}\n            near={1}\n            far={10000}\n            position={this.state.mainCameraPosition}\n          />\n          <object3D\n            lookAt={meshPosition}\n          >\n            <perspectiveCamera\n              name={perspectiveCameraName}\n              fov={35 + 30 * Math.sin(0.5 * r)}\n              aspect={aspectRatio}\n              near={150}\n              far={meshPosition.length()}\n              rotation={perspectiveCameraRotation}\n            />\n            <orthographicCamera\n              name={orthographicCameraName}\n              left={0.5 * width / -2}\n              right={0.5 * width / 2}\n              top={height / 2}\n              bottom={height / -2}\n              near={150}\n              far={meshPosition.length()}\n              rotation={orthographicCameraRotation}\n            />\n            <mesh\n              position={spherePosition}\n            >\n              <sphereGeometry\n                radius={5}\n                widthSegments={16}\n                heightSegments={8}\n              />\n              <meshBasicMaterial\n                color={0x0000ff}\n                wireframe\n              />\n            </mesh>\n          </object3D>\n          <cameraHelper\n            cameraName={this.state.activeCameraName}\n          />\n          <object3D\n            position={meshPosition}\n          >\n            <mesh>\n              <sphereGeometry\n                radius={100}\n                widthSegments={16}\n                heightSegments={8}\n              />\n              <meshBasicMaterial\n                color={0xffffff}\n                wireframe\n              />\n            </mesh>\n            <mesh\n              position={childPosition}\n            >\n              <sphereGeometry\n                radius={50}\n                widthSegments={16}\n                heightSegments={8}\n              />\n              <meshBasicMaterial\n                color={0x00ff00}\n                wireframe\n              />\n            </mesh>\n          </object3D>\n          {\n            <PointCloud/>\n          }\n        </scene>\n      </React3>\n    </div>);\n  }\n}\n\nexport default WebGLCameraExample;\n"
  },
  {
    "path": "src/examples/inputs/MouseInput.js",
    "content": "import React3 from 'react-three-renderer';\nimport * as THREE from 'three';\nimport ReactUpdates from 'react-dom/lib/ReactUpdates';\n\nimport SyntheticMouseEvent from 'react-dom/lib/SyntheticMouseEvent';\n\nimport Module from 'react-three-renderer/lib/Module';\n\nimport PropTypes from 'react/lib/ReactPropTypes';\n\nconst tempVector2 = new THREE.Vector2();\n\nconst listenerCallbackNames = {\n  mousedown: 'onMouseDown',\n  mouseup: 'onMouseUp',\n};\n\nconst mouseEvents = [\n  'onMouseEnter',\n  'onMouseLeave',\n  'onMouseDown',\n  'onMouseUp',\n  'onClick',\n];\n\nconst boolProps = {\n  ignorePointerEvents: false,\n};\n\nclass MouseInput extends Module {\n  constructor() {\n    super();\n\n    this._isReady = false;\n    this._active = true;\n    this._restrictIntersections = false;\n    this._objectsToIntersect = null;\n\n    this._restrictedIntersectionRecursive = false;\n\n    this._patchedDescriptors = [];\n  }\n\n  // noinspection JSUnusedGlobalSymbols\n  setup(react3RendererInstance) {\n    super.setup(react3RendererInstance);\n\n    const Object3DDescriptor = react3RendererInstance.threeElementDescriptors.object3D.constructor;\n\n    Object.values(react3RendererInstance.threeElementDescriptors).forEach(elementDescriptor => {\n      if (elementDescriptor instanceof Object3DDescriptor) {\n        mouseEvents.forEach(eventName => {\n          elementDescriptor.hasEvent(eventName);\n        });\n\n        Object.keys(boolProps).forEach(propName => {\n          elementDescriptor.hasProp(propName, {\n            type: PropTypes.bool,\n            update(threeObject, value, hasProp) {\n              if (hasProp) {\n                threeObject.userData[propName] = value;\n              } else {\n                threeObject.userData[propName] = boolProps[propName];\n              }\n            },\n            default: boolProps[propName],\n          });\n        });\n\n        this._patchedDescriptors.push(elementDescriptor);\n      }\n    });\n  }\n\n  isReady() {\n    return this._isReady;\n  }\n\n  setActive(active) {\n    this._active = active;\n  }\n\n  restrictIntersections(objects, recursive = false) {\n    this._restrictIntersections = true;\n    this._objectsToIntersect = objects;\n\n    this._restrictedIntersectionRecursive = recursive;\n  }\n\n  ready(scene, container, camera) {\n    this._isReady = true;\n\n    this._scene = scene;\n    this._container = container;\n    this._camera = camera;\n\n    this._raycaster = new THREE.Raycaster();\n    this._mouse = new THREE.Vector2();\n\n    this._onMouseMove = (event) => {\n      this._mouse.set(event.clientX, event.clientY);\n\n      if (!this._active) {\n        this._updateEnterLeave();\n      }\n    };\n\n    this._containerRect = this._container.getBoundingClientRect();\n\n    this._hoverObjectMap = {};\n\n    document.addEventListener('mousemove', this._onMouseMove, false);\n\n    this._intersectionsForClick = null;\n\n    this._caughtListenersCleanupFunctions = [];\n\n    Object.keys(listenerCallbackNames).forEach(eventName => {\n      let boundListener;\n\n      const listenerCallbackName = listenerCallbackNames[eventName];\n      switch (eventName) {\n        case 'mousedown':\n          boundListener = this._onMouseDown.bind(this, listenerCallbackName);\n          break;\n        case 'mouseup':\n          boundListener = this._onMouseUp.bind(this, listenerCallbackName);\n          break;\n        default:\n          break;\n      }\n\n      if (boundListener) {\n        container.addEventListener(eventName, boundListener, true);\n\n        this._caughtListenersCleanupFunctions.push(() => {\n          container.removeEventListener(eventName, boundListener, true);\n        });\n      }\n    });\n  }\n\n  _onMouseDown = (callbackName, mouseEvent) => {\n    ReactUpdates.batchedUpdates(() => {\n      const {\n        event,\n        intersections,\n      } = this._intersectAndDispatch(callbackName, mouseEvent);\n\n      if (event.isDefaultPrevented() || event.isPropagationStopped()) {\n        this._intersectionsForClick = null;\n      } else {\n        this._intersectionsForClick = intersections;\n      }\n    });\n  };\n\n  _onMouseUp = (callbackName, mouseEvent) => {\n    ReactUpdates.batchedUpdates(() => {\n      const {\n        event,\n        intersections,\n      } = this._intersectAndDispatch(callbackName, mouseEvent);\n\n      if (!(event.isDefaultPrevented() || event.isPropagationStopped())) {\n        if (this._intersectionsForClick === null) {\n          return;\n        }\n\n        // intersect current intersections with the intersections for click\n        //   call xzibit ASAP we have a good one son\n        //     it wasn't that good\n\n        const intersectionUUIDMap = this._intersectionsForClick.reduce((map, intersection) => {\n          map[intersection.object.uuid] = intersection;\n\n          return map;\n        }, {});\n\n        for (let i = 0; i < intersections.length; ++i) {\n          if (event.isDefaultPrevented() || event.isPropagationStopped()) {\n            return;\n          }\n\n          const intersection = intersections[i];\n\n          const object = intersection.object;\n\n          const uuid = object.uuid;\n\n          if (intersectionUUIDMap[uuid]) {\n            // oh boy oh boy here we go, we got a clicker\n\n            React3.eventDispatcher\n              .dispatchEvent(object, 'onClick',\n                this._createSyntheticMouseEvent('click', event), intersection);\n          }\n        }\n      }\n    });\n\n    this._intersectionsForClick = null;\n  };\n\n  _createSyntheticMouseEvent(eventType, prototype) {\n    return SyntheticMouseEvent.getPooled(null, null,\n      new MouseEvent(eventType, prototype), prototype.target);\n  }\n\n  _intersectAndDispatch(callbackName, mouseEvent) {\n    const event = SyntheticMouseEvent.getPooled(null, null, mouseEvent, mouseEvent.target);\n\n    const intersections = this._getIntersections(tempVector2.set(event.clientX, event.clientY));\n\n    ReactUpdates.batchedUpdates(() => {\n      for (let i = 0; i < intersections.length; ++i) {\n        const intersection = intersections[i];\n\n        if (event.isDefaultPrevented() || event.isPropagationStopped()) {\n          return;\n        }\n\n        const object = intersection.object;\n\n        React3.eventDispatcher.dispatchEvent(object, callbackName, event, intersection);\n      }\n    });\n\n    return {\n      event,\n      intersections,\n    };\n  }\n\n  _getIntersections(mouseCoords) {\n    const relativeMouseCoords = this._getRelativeMouseCoords(mouseCoords);\n\n    this._raycaster.setFromCamera(relativeMouseCoords, this._camera);\n\n    if (this._restrictIntersections) {\n      return this._raycaster.intersectObjects(this._objectsToIntersect,\n        this._restrictedIntersectionRecursive);\n    }\n\n    return this._raycaster.intersectObject(this._scene, true);\n  }\n\n  // noinspection JSUnusedGlobalSymbols\n  /**\n   *\n   * @param {THREE.Vector2} mouseCoords usually an event's clientX and clientY\n   * @returns {THREE.Ray}\n   */\n  getCameraRay(mouseCoords) {\n    const relativeMouseCoords = this._getRelativeMouseCoords(mouseCoords);\n\n    const originalRay = this._raycaster.ray.clone();\n\n    this._raycaster.setFromCamera(relativeMouseCoords, this._camera);\n\n    const resultRay = this._raycaster.ray.clone();\n\n    this._raycaster.ray.copy(originalRay);\n\n    return resultRay;\n  }\n\n  // noinspection JSUnusedGlobalSymbols\n  intersectObject(mouseCoords, object, recursive = false) {\n    const relativeMouseCoords = this._getRelativeMouseCoords(mouseCoords);\n\n    const originalRay = this._raycaster.ray.clone();\n\n    this._raycaster.setFromCamera(relativeMouseCoords, this._camera);\n\n    const intersections = this._raycaster.intersectObject(object, recursive);\n\n    this._raycaster.ray.copy(originalRay);\n\n    return intersections;\n  }\n\n  containerResized() {\n    this._containerRect = this._container.getBoundingClientRect();\n  }\n\n  update() {\n    if (!this._isReady) {\n      return;\n    }\n\n    if (this._active) {\n      this._updateEnterLeave();\n    }\n  }\n\n  _updateEnterLeave() {\n    const intersections = this._getIntersections(this._mouse);\n\n    const hoverMapToUpdate = {\n      ...this._hoverObjectMap,\n    };\n\n    const mouseEnterEvent = this._createSyntheticMouseEvent('mouseEnter', {\n      target: this._container,\n      clientX: this._mouse.x,\n      clientY: this._mouse.y,\n    });\n\n    // find first intersection that does not ignore pointer events\n    for (let depth = 0; depth < intersections.length; ++depth) {\n      const intersection = intersections[depth];\n      const object = intersection.object;\n\n      if (object.userData && object.userData.ignorePointerEvents) {\n        continue;\n      }\n\n      const uuid = object.uuid;\n\n      if (this._hoverObjectMap[uuid]) {\n        delete hoverMapToUpdate[uuid];\n\n        // just update that intersection\n        this._hoverObjectMap[uuid].intersection = intersection;\n      } else {\n        this._hoverObjectMap[uuid] = {\n          object,\n          intersection,\n        };\n\n        if (!(mouseEnterEvent.isDefaultPrevented() || mouseEnterEvent.isPropagationStopped())) {\n          React3.eventDispatcher.dispatchEvent(object, 'onMouseEnter',\n            mouseEnterEvent, intersection, depth);\n        }\n      }\n\n      // we have found the first solid intersection, don't go further\n      break;\n    }\n\n    const mouseLeaveEvent = this._createSyntheticMouseEvent('mouseLeave', {\n      target: this._container,\n      clientX: this._mouse.x,\n      clientY: this._mouse.y,\n    });\n\n    // delete all unseen uuids in hover map\n    const unseenUUIDs = Object.keys(hoverMapToUpdate);\n\n    for (let i = 0; i < unseenUUIDs.length; ++i) {\n      const uuid = unseenUUIDs[i];\n\n      if (!(mouseLeaveEvent.isDefaultPrevented() || mouseLeaveEvent.isPropagationStopped())) {\n        React3.eventDispatcher.dispatchEvent(this._hoverObjectMap[uuid].object,\n          'onMouseLeave', mouseLeaveEvent);\n      }\n\n      delete this._hoverObjectMap[uuid];\n    }\n  }\n\n  _getRelativeMouseCoords(screenMouseCoords) {\n    const containerRect = this._containerRect;\n\n    const relativeMouseCoords = screenMouseCoords.clone()\n      .sub(tempVector2.set(containerRect.left, containerRect.top))\n      .divide(tempVector2.set(containerRect.width, containerRect.height));\n\n    // mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;\n    // mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;\n\n    relativeMouseCoords.x = relativeMouseCoords.x * 2 - 1;\n    relativeMouseCoords.y = -relativeMouseCoords.y * 2 + 1;\n\n    return relativeMouseCoords;\n  }\n\n  // noinspection JSUnusedGlobalSymbols\n  dispose() {\n    document.removeEventListener('mousemove', this._onMouseMove, false);\n\n    this._caughtListenersCleanupFunctions.forEach(cleanupFunction => cleanupFunction());\n    delete this._caughtListenersCleanupFunctions;\n\n    delete this._onMouseMove;\n\n    this._patchedDescriptors.forEach(elementDescriptor => {\n      const allProps = Object.keys(boolProps)\n        .concat(mouseEvents);\n\n      allProps.forEach(propName => {\n        elementDescriptor.removeProp(propName);\n      });\n    });\n  }\n}\n\nexport default MouseInput;\n"
  },
  {
    "path": "src/index.jsx",
    "content": "/* eslint-disable no-undef */\n\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport {\n  HashRouter as Router,\n  Route,\n} from 'react-router-dom';\nimport Perf from 'react-addons-perf';\nimport createHashHistory from 'history/createHashHistory';\n\nimport ExampleBrowser from './examples/ExampleBrowser';\n\nconst customHistory = createHashHistory();\nwindow.Perf = Perf;\n\nReactDOM.render(\n  <Router history={customHistory}>\n    <div>\n      <Route path=\"/:slug?\" component={ExampleBrowser} />\n    </div>\n  </Router>,\n  document.getElementById('content'),\n);\n"
  },
  {
    "path": "src/ref/trackball.js",
    "content": "/* eslint-disable */\n\nimport * as THREE from 'three';\n\n/**\n * @author Eberhard Graether / http://egraether.com/\n * @author Mark Lundin  / http://mark-lundin.com\n * @author Simone Manini / http://daron1337.github.io\n * @author Luca Antiga  / http://lantiga.github.io\n */\n\nclass TrackballControls extends THREE.EventDispatcher {\n  constructor(object, domElement) {\n    super();\n\n    const _this = this;\n    const STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };\n\n    this.object = object;\n    this.domElement = ( domElement !== undefined ) ? domElement : document;\n\n    // API\n\n    this.enabled = true;\n\n    this.screen = { left: 0, top: 0, width: 0, height: 0 };\n\n    this.rotateSpeed = 1.0;\n    this.zoomSpeed = 1.2;\n    this.panSpeed = 0.3;\n\n    this.noRotate = false;\n    this.noZoom = false;\n    this.noPan = false;\n\n    this.staticMoving = false;\n    this.dynamicDampingFactor = 0.2;\n\n    this.minDistance = 0;\n    this.maxDistance = Infinity;\n\n    this.keys = [\n      65/* A */,\n      83/* S */,\n      68/* D */,\n    ];\n\n    // internals\n\n    this.target = new THREE.Vector3();\n\n    const EPS = 0.000001;\n\n    const lastPosition = new THREE.Vector3();\n\n    let _state = STATE.NONE;\n    let _prevState = STATE.NONE;\n\n    const _eye = new THREE.Vector3();\n    const _movePrev = new THREE.Vector2();\n    const _moveCurr = new THREE.Vector2();\n    const _lastAxis = new THREE.Vector3();\n\n    let _lastAngle = 0;\n\n    const _zoomStart = new THREE.Vector2();\n    const _zoomEnd = new THREE.Vector2();\n\n    let _touchZoomDistanceStart = 0;\n    let _touchZoomDistanceEnd = 0;\n    const _panStart = new THREE.Vector2();\n    const _panEnd = new THREE.Vector2();\n\n    // for reset\n\n    this.target0 = this.target.clone();\n    this.position0 = this.object.position.clone();\n    this.up0 = this.object.up.clone();\n\n    // events\n\n    const changeEvent = { type: 'change' };\n    const startEvent = { type: 'start' };\n    const endEvent = { type: 'end' };\n\n    // methods\n\n    this.handleResize = () => {\n      if (this.domElement === document) {\n        this.screen.left = 0;\n        this.screen.top = 0;\n        this.screen.width = window.innerWidth;\n        this.screen.height = window.innerHeight;\n      } else {\n        const box = this.domElement.getBoundingClientRect();\n        // adjustments come from similar code in the jquery offset() function\n        const d = this.domElement.ownerDocument.documentElement;\n        this.screen.left = box.left + window.pageXOffset - d.clientLeft;\n        this.screen.top = box.top + window.pageYOffset - d.clientTop;\n        this.screen.width = box.width;\n        this.screen.height = box.height;\n      }\n    };\n\n    this.handleEvent = (event) => {\n      if (typeof this[event.type] === 'function') {\n        this[event.type](event);\n      }\n    };\n\n    const getMouseOnScreen = ( function wrapper() {\n      const vector = new THREE.Vector2();\n\n      return (pageX, pageY) => {\n        vector.set(\n          ( pageX - _this.screen.left ) / _this.screen.width,\n          ( pageY - _this.screen.top ) / _this.screen.height\n        );\n\n        return vector;\n      };\n    }() );\n\n    const getMouseOnCircle = ( function wrapper() {\n      const vector = new THREE.Vector2();\n\n      return (pageX, pageY) => {\n        vector.set(\n          ( ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / ( _this.screen.width * 0.5 ) ),\n          ( ( _this.screen.height + 2 * ( _this.screen.top - pageY ) ) / _this.screen.width ) // screen.width intentional\n        );\n\n        return vector;\n      };\n    }() );\n\n    this.rotateCamera = ( function wrapper() {\n      const axis = new THREE.Vector3();\n      const quaternion = new THREE.Quaternion();\n      const eyeDirection = new THREE.Vector3();\n      const objectUpDirection = new THREE.Vector3();\n      const objectSidewaysDirection = new THREE.Vector3();\n      const moveDirection = new THREE.Vector3();\n\n      let angle;\n\n      return function rotateCamera() {\n        moveDirection.set(_moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0);\n        angle = moveDirection.length();\n\n        if (angle) {\n          _eye.copy(_this.object.position).sub(_this.target);\n\n          eyeDirection.copy(_eye).normalize();\n          objectUpDirection.copy(_this.object.up).normalize();\n          objectSidewaysDirection.crossVectors(objectUpDirection, eyeDirection).normalize();\n\n          objectUpDirection.setLength(_moveCurr.y - _movePrev.y);\n          objectSidewaysDirection.setLength(_moveCurr.x - _movePrev.x);\n\n          moveDirection.copy(objectUpDirection.add(objectSidewaysDirection));\n\n          axis.crossVectors(moveDirection, _eye).normalize();\n\n          angle *= _this.rotateSpeed;\n          quaternion.setFromAxisAngle(axis, angle);\n\n          _eye.applyQuaternion(quaternion);\n          _this.object.up.applyQuaternion(quaternion);\n\n          _lastAxis.copy(axis);\n          _lastAngle = angle;\n        } else if (!_this.staticMoving && _lastAngle) {\n          _lastAngle *= Math.sqrt(1.0 - _this.dynamicDampingFactor);\n          _eye.copy(_this.object.position).sub(_this.target);\n          quaternion.setFromAxisAngle(_lastAxis, _lastAngle);\n          _eye.applyQuaternion(quaternion);\n          _this.object.up.applyQuaternion(quaternion);\n        }\n\n        _movePrev.copy(_moveCurr);\n      };\n    }() );\n\n    this.zoomCamera = () => {\n      let factor;\n\n      if (_state === STATE.TOUCH_ZOOM_PAN) {\n        factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;\n        _touchZoomDistanceStart = _touchZoomDistanceEnd;\n        _eye.multiplyScalar(factor);\n      } else {\n        factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;\n\n        if (factor !== 1.0 && factor > 0.0) {\n          _eye.multiplyScalar(factor);\n\n          if (_this.staticMoving) {\n            _zoomStart.copy(_zoomEnd);\n          } else {\n            _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;\n          }\n        }\n      }\n    };\n\n    this.panCamera = ( function wrapper() {\n      const mouseChange = new THREE.Vector2();\n      const objectUp = new THREE.Vector3();\n      const pan = new THREE.Vector3();\n\n      return function panCamera() {\n        mouseChange.copy(_panEnd).sub(_panStart);\n\n        if (mouseChange.lengthSq()) {\n          mouseChange.multiplyScalar(_eye.length() * _this.panSpeed);\n\n          pan.copy(_eye).cross(_this.object.up).setLength(mouseChange.x);\n          pan.add(objectUp.copy(_this.object.up).setLength(mouseChange.y));\n\n          _this.object.position.add(pan);\n          _this.target.add(pan);\n\n          if (_this.staticMoving) {\n            _panStart.copy(_panEnd);\n          } else {\n            _panStart.add(mouseChange.subVectors(_panEnd, _panStart).multiplyScalar(_this.dynamicDampingFactor));\n          }\n        }\n      };\n    }() );\n\n    this.checkDistances = () => {\n      if (!_this.noZoom || !_this.noPan) {\n        if (_eye.lengthSq() > _this.maxDistance * _this.maxDistance) {\n          _this.object.position.addVectors(_this.target, _eye.setLength(_this.maxDistance));\n          _zoomStart.copy(_zoomEnd);\n        }\n\n        if (_eye.lengthSq() < _this.minDistance * _this.minDistance) {\n          _this.object.position.addVectors(_this.target, _eye.setLength(_this.minDistance));\n          _zoomStart.copy(_zoomEnd);\n        }\n      }\n    };\n\n    this.update = () => {\n      _eye.subVectors(_this.object.position, _this.target);\n\n      if (!_this.noRotate) {\n        _this.rotateCamera();\n      }\n\n      if (!_this.noZoom) {\n        _this.zoomCamera();\n      }\n\n      if (!_this.noPan) {\n        _this.panCamera();\n      }\n\n      _this.object.position.addVectors(_this.target, _eye);\n\n      _this.checkDistances();\n\n      _this.object.lookAt(_this.target);\n\n      if (lastPosition.distanceToSquared(_this.object.position) > EPS) {\n        _this.dispatchEvent(changeEvent);\n\n        lastPosition.copy(_this.object.position);\n      }\n    };\n\n    this.reset = () => {\n      _state = STATE.NONE;\n      _prevState = STATE.NONE;\n\n      _this.target.copy(_this.target0);\n      _this.object.position.copy(_this.position0);\n      _this.object.up.copy(_this.up0);\n\n      _eye.subVectors(_this.object.position, _this.target);\n\n      _this.object.lookAt(_this.target);\n\n      _this.dispatchEvent(changeEvent);\n\n      lastPosition.copy(_this.object.position);\n    };\n\n    // listeners\n\n    function keydown(event) {\n      if (_this.enabled === false) return;\n\n      window.removeEventListener('keydown', keydown);\n\n      _prevState = _state;\n\n      if (_state !== STATE.NONE) {\n        return;\n      }\n\n      if (event.keyCode === _this.keys[STATE.ROTATE] && !_this.noRotate) {\n        _state = STATE.ROTATE;\n      } else if (event.keyCode === _this.keys[STATE.ZOOM] && !_this.noZoom) {\n        _state = STATE.ZOOM;\n      } else if (event.keyCode === _this.keys[STATE.PAN] && !_this.noPan) {\n        _state = STATE.PAN;\n      }\n    }\n\n    function keyup() {\n      if (_this.enabled === false) return;\n\n      _state = _prevState;\n\n      window.addEventListener('keydown', keydown, false);\n    }\n\n\n    function mousemove(event) {\n      if (_this.enabled === false) return;\n\n      event.preventDefault();\n      event.stopPropagation();\n\n      if (_state === STATE.ROTATE && !_this.noRotate) {\n        _movePrev.copy(_moveCurr);\n        _moveCurr.copy(getMouseOnCircle(event.pageX, event.pageY));\n      } else if (_state === STATE.ZOOM && !_this.noZoom) {\n        _zoomEnd.copy(getMouseOnScreen(event.pageX, event.pageY));\n      } else if (_state === STATE.PAN && !_this.noPan) {\n        _panEnd.copy(getMouseOnScreen(event.pageX, event.pageY));\n      }\n    }\n\n    function mouseup(event) {\n      if (_this.enabled === false) return;\n\n      event.preventDefault();\n      event.stopPropagation();\n\n      _state = STATE.NONE;\n\n      document.removeEventListener('mousemove', mousemove);\n      document.removeEventListener('mouseup', mouseup);\n      _this.dispatchEvent(endEvent);\n    }\n\n    function mousedown(event) {\n      if (_this.enabled === false) return;\n\n      event.preventDefault();\n      event.stopPropagation();\n\n      if (_state === STATE.NONE) {\n        _state = event.button;\n      }\n\n      if (_state === STATE.ROTATE && !_this.noRotate) {\n        _moveCurr.copy(getMouseOnCircle(event.pageX, event.pageY));\n        _movePrev.copy(_moveCurr);\n      } else if (_state === STATE.ZOOM && !_this.noZoom) {\n        _zoomStart.copy(getMouseOnScreen(event.pageX, event.pageY));\n        _zoomEnd.copy(_zoomStart);\n      } else if (_state === STATE.PAN && !_this.noPan) {\n        _panStart.copy(getMouseOnScreen(event.pageX, event.pageY));\n        _panEnd.copy(_panStart);\n      }\n\n      document.addEventListener('mousemove', mousemove, false);\n      document.addEventListener('mouseup', mouseup, false);\n\n      _this.dispatchEvent(startEvent);\n    }\n\n\n    function mousewheel(event) {\n      if (_this.enabled === false) return;\n\n      event.preventDefault();\n      event.stopPropagation();\n\n      let delta = 0;\n\n      if (event.wheelDelta) {\n        // WebKit / Opera / Explorer 9\n\n        delta = event.wheelDelta / 40;\n      } else if (event.detail) {\n        // Firefox\n\n        delta = -event.detail / 3;\n      }\n\n      _zoomStart.y += delta * 0.01;\n      _this.dispatchEvent(startEvent);\n      _this.dispatchEvent(endEvent);\n    }\n\n    function touchstart(event) {\n      if (_this.enabled === false) return;\n\n      switch (event.touches.length) {\n        case 1:\n          _state = STATE.TOUCH_ROTATE;\n          _moveCurr.copy(getMouseOnCircle(event.touches[0].pageX, event.touches[0].pageY));\n          _movePrev.copy(_moveCurr);\n          break;\n\n        case 2:\n          _state = STATE.TOUCH_ZOOM_PAN;\n          const dx = event.touches[0].pageX - event.touches[1].pageX;\n          const dy = event.touches[0].pageY - event.touches[1].pageY;\n          _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt(dx * dx + dy * dy);\n\n          const x = ( event.touches[0].pageX + event.touches[1].pageX ) / 2;\n          const y = ( event.touches[0].pageY + event.touches[1].pageY ) / 2;\n          _panStart.copy(getMouseOnScreen(x, y));\n          _panEnd.copy(_panStart);\n          break;\n\n        default:\n          _state = STATE.NONE;\n\n      }\n      _this.dispatchEvent(startEvent);\n    }\n\n    function touchmove(event) {\n      if (_this.enabled === false) return;\n\n      event.preventDefault();\n      event.stopPropagation();\n\n      switch (event.touches.length) {\n\n        case 1:\n          _movePrev.copy(_moveCurr);\n          _moveCurr.copy(getMouseOnCircle(event.touches[0].pageX, event.touches[0].pageY));\n          break;\n\n        case 2:\n          const dx = event.touches[0].pageX - event.touches[1].pageX;\n          const dy = event.touches[0].pageY - event.touches[1].pageY;\n          _touchZoomDistanceEnd = Math.sqrt(dx * dx + dy * dy);\n\n          const x = ( event.touches[0].pageX + event.touches[1].pageX ) / 2;\n          const y = ( event.touches[0].pageY + event.touches[1].pageY ) / 2;\n          _panEnd.copy(getMouseOnScreen(x, y));\n          break;\n\n        default:\n          _state = STATE.NONE;\n      }\n    }\n\n    function touchend(event) {\n      if (_this.enabled === false) return;\n\n      switch (event.touches.length) {\n        default:\n          // no touches\n          break;\n        case 1:\n          _moveCurr.copy(getMouseOnCircle(event.touches[0].pageX, event.touches[0].pageY));\n          _movePrev.copy(_moveCurr);\n          break;\n\n        case 2:\n          _touchZoomDistanceStart = _touchZoomDistanceEnd = 0;\n\n          const x = ( event.touches[0].pageX + event.touches[1].pageX ) / 2;\n          const y = ( event.touches[0].pageY + event.touches[1].pageY ) / 2;\n          _panEnd.copy(getMouseOnScreen(x, y));\n          _panStart.copy(_panEnd);\n          break;\n\n      }\n\n      _state = STATE.NONE;\n      _this.dispatchEvent(endEvent);\n    }\n\n    function contextmenu(event) {\n      event.preventDefault();\n    }\n\n    this.dispose = () => {\n      this.domElement.removeEventListener('contextmenu', contextmenu, false);\n      this.domElement.removeEventListener('mousedown', mousedown, false);\n      this.domElement.removeEventListener('mousewheel', mousewheel, false);\n      this.domElement.removeEventListener('DOMMouseScroll', mousewheel, false); // firefox\n\n      this.domElement.removeEventListener('touchstart', touchstart, false);\n      this.domElement.removeEventListener('touchend', touchend, false);\n      this.domElement.removeEventListener('touchmove', touchmove, false);\n\n      document.removeEventListener('mousemove', mousemove, false);\n      document.removeEventListener('mouseup', mouseup, false);\n\n      window.removeEventListener('keydown', keydown, false);\n      window.removeEventListener('keyup', keyup, false);\n    };\n\n    this.domElement.addEventListener('contextmenu', contextmenu, false);\n    this.domElement.addEventListener('mousedown', mousedown, false);\n    this.domElement.addEventListener('mousewheel', mousewheel, false);\n    this.domElement.addEventListener('DOMMouseScroll', mousewheel, false); // firefox\n\n    this.domElement.addEventListener('touchstart', touchstart, false);\n    this.domElement.addEventListener('touchend', touchend, false);\n    this.domElement.addEventListener('touchmove', touchmove, false);\n\n    window.addEventListener('keydown', keydown, false);\n    window.addEventListener('keyup', keyup, false);\n\n    this.handleResize();\n\n    // force an update at start\n    this.update();\n  }\n}\n\nexport default TrackballControls;\n\n/* eslint-enable */\n"
  },
  {
    "path": "webpack.config.babel.js",
    "content": "/* eslint-disable import/no-extraneous-dependencies */\n\nimport path from 'path';\nimport webpack from 'webpack';\nimport pluginsWithoutUglify from './config/webpackPluginsWithoutUglify';\n\nimport packageJson from './package.json';\n\nconst outPath = path.join(__dirname, 'pages');\n\nconst plugins = pluginsWithoutUglify.concat([\n  new webpack.optimize.UglifyJsPlugin({\n    compress: {\n      warnings: false,\n    },\n    mangle: true,\n  }),\n]);\n\nconst babelLoaderConfigShared = {\n  test: /\\.jsx?$/,\n  loader: 'babel-loader',\n  query: {\n    ...packageJson.babel,\n    cacheDirectory: true,\n  },\n};\n\nexport default {\n  entry: {\n    app: [\n      './src/index.jsx',\n    ],\n    advanced: [\n      './src/examples/AdvancedExample/index.js',\n    ],\n  },\n  output: {\n    path: outPath,\n    filename: path.join('js', 'bundle-[name].js'),\n  },\n  module: {\n    loaders: [\n      {\n        loader: 'json-loader',\n        test: /\\.json$/,\n      },\n      {\n        exclude: /node_modules/,\n        ...babelLoaderConfigShared,\n      },\n      {\n        include: /react-three-renderer[\\\\/]src/,\n        ...babelLoaderConfigShared,\n      },\n    ],\n  },\n  resolve: {\n    extensions: ['.js', '.jsx'],\n    alias: {\n      // use the source files\n      'react-three-renderer': path.join(\n        __dirname, 'node_modules', 'react-three-renderer', 'src'),\n    },\n  },\n  devServer: {\n    contentBase: path.join(__dirname, 'assets'),\n    // noInfo: true, //  --no-info option\n    hot: true,\n    inline: true,\n    stats: { colors: true },\n  },\n  plugins,\n};\n"
  }
]