Browse Source

Merge remote-tracking branch 'origin/dev' into optimize-buffer-geometry-indices

Garrett Johnson 7 years ago
parent
commit
73dba53db6
100 changed files with 7338 additions and 4770 deletions
  1. 1 1
      .github/ISSUE_TEMPLATE.md
  2. 11 1
      build/three.js
  3. 382 381
      build/three.min.js
  4. 11 1
      build/three.module.js
  5. 3 3
      docs/api/core/Object3D.html
  6. 1 1
      docs/api/loaders/JSONLoader.html
  7. 1 1
      docs/api/objects/Line.html
  8. 1 1
      docs/api/objects/Mesh.html
  9. 1 1
      docs/api/objects/Points.html
  10. 1 1
      docs/api/objects/Sprite.html
  11. 1 0
      docs/api/textures/DataTexture.html
  12. 1 1
      docs/examples/exporters/GLTFExporter.html
  13. 62 0
      docs/examples/exporters/PLYExporter.html
  14. 1 0
      docs/examples/renderers/CSS2DRenderer.html
  15. 3 1
      docs/list.js
  16. 5 5
      docs/manual/introduction/Animation-system.html
  17. 1 1
      docs/manual/introduction/Creating-a-scene.html
  18. 3 3
      docs/manual/introduction/FAQ.html
  19. 3 3
      docs/manual/introduction/Import-via-modules.html
  20. 129 0
      docs/manual/introduction/Loading-3D-models.html
  21. 7 0
      docs/manual/introduction/Useful-links.html
  22. 11 27
      docs/scenes/geometry-browser.html
  23. 150 0
      examples/css2d_label.html
  24. 6 2
      examples/files.js
  25. 9 8
      examples/js/MorphBlendMesh.js
  26. 1 1
      examples/js/animation/CCDIKSolver.js
  27. 8 5
      examples/js/animation/MMDAnimationHelper.js
  28. 14 6
      examples/js/cameras/CinematicCamera.js
  29. 0 149
      examples/js/controls/VRControls.js
  30. 1 1
      examples/js/effects/OutlineEffect.js
  31. 0 533
      examples/js/effects/VREffect.js
  32. 4 0
      examples/js/exporters/GLTFExporter.js
  33. 1 1
      examples/js/exporters/PLYExporter.js
  34. 0 94
      examples/js/exporters/STLBinaryExporter.js
  35. 110 25
      examples/js/exporters/STLExporter.js
  36. 5 0
      examples/js/loaders/DRACOLoader.js
  37. 1 7
      examples/js/loaders/EquiangularToCubeGenerator.js
  38. 25 24
      examples/js/loaders/GLTFLoader.js
  39. 199 131
      examples/js/loaders/MD2Loader.js
  40. 8 7
      examples/js/loaders/MMDLoader.js
  41. 21 69
      examples/js/loaders/TDSLoader.js
  42. 22 48
      examples/js/loaders/VTKLoader.js
  43. 7 2
      examples/js/loaders/XLoader.js
  44. 96 63
      examples/js/modifiers/SimplifyModifier.js
  45. 2 2
      examples/js/objects/Reflector.js
  46. 0 2
      examples/js/objects/ReflectorRTT.js
  47. 1 7
      examples/js/pmrem/PMREMCubeUVPacker.js
  48. 1 7
      examples/js/pmrem/PMREMGenerator.js
  49. 62 0
      examples/js/renderers/CSS2DRenderer.js
  50. 91 26
      examples/js/shaders/BokehShader2.js
  51. 5 2
      examples/js/vr/WebVR.js
  52. 193 0
      examples/misc_exporter_stl.html
  53. 0 1
      examples/webgl_buffergeometry_instancing_lambert.html
  54. 2 2
      examples/webgl_geometry_colors_json.html
  55. 29 23
      examples/webgl_interactive_voxelpainter.html
  56. 1 1
      examples/webgl_loader_json.html
  57. 12 8
      examples/webgl_loader_mmd.html
  58. 8 4
      examples/webgl_loader_mmd_audio.html
  59. 23 18
      examples/webgl_loader_mmd_pose.html
  60. 16 18
      examples/webgl_loader_x.html
  61. 44 88
      examples/webgl_modifier_simplifier.html
  62. 71 13
      examples/webgl_postprocessing_dof2.html
  63. 0 1
      examples/webgl_shaders_tonemapping.html
  64. 2 2
      examples/webvr_cubes.html
  65. 1 1
      examples/webvr_daydream.html
  66. 1 1
      examples/webvr_gearvr.html
  67. 5 8
      examples/webvr_panorama.html
  68. 2 2
      examples/webvr_rollercoaster.html
  69. 2 2
      examples/webvr_sandbox.html
  70. 1 1
      examples/webvr_video.html
  71. 1 1
      examples/webvr_vive.html
  72. 1 1
      examples/webvr_vive_dragging.html
  73. 1 1
      examples/webvr_vive_paint.html
  74. 1 1
      examples/webvr_vive_sculpt.html
  75. 5250 0
      package-lock.json
  76. 13 13
      package.json
  77. 1 1
      src/constants.js
  78. 54 0
      src/geometries/ExtrudeGeometry.js
  79. 30 0
      src/loaders/ObjectLoader.js
  80. 10 0
      src/math/Matrix4.js
  81. 12 2
      src/renderers/WebGLRenderer.js
  82. 0 1
      src/renderers/shaders/ShaderLib/meshlambert_frag.glsl
  83. 0 1
      src/renderers/shaders/ShaderLib/meshlambert_vert.glsl
  84. 0 1
      src/renderers/shaders/ShaderLib/meshphong_frag.glsl
  85. 1 1
      src/renderers/webgl/WebGLAnimation.js
  86. 2 0
      src/renderers/webgl/WebGLUniforms.js
  87. 0 8
      src/renderers/webvr/WebVRManager.js
  88. 57 19
      src/renderers/webvr/WebXRManager.js
  89. 0 3
      utils/exporters/blender/.gitignore
  90. 1 66
      utils/exporters/blender/README.md
  91. 0 1059
      utils/exporters/blender/addons/io_three/__init__.py
  92. 0 398
      utils/exporters/blender/addons/io_three/constants.py
  93. 0 112
      utils/exporters/blender/addons/io_three/dialogs.py
  94. 0 9
      utils/exporters/blender/addons/io_three/exceptions.py
  95. 0 96
      utils/exporters/blender/addons/io_three/exporter/__init__.py
  96. 0 208
      utils/exporters/blender/addons/io_three/exporter/_json.py
  97. 0 77
      utils/exporters/blender/addons/io_three/exporter/api/__init__.py
  98. 0 683
      utils/exporters/blender/addons/io_three/exporter/api/animation.py
  99. 0 130
      utils/exporters/blender/addons/io_three/exporter/api/camera.py
  100. 0 29
      utils/exporters/blender/addons/io_three/exporter/api/constants.py

+ 1 - 1
.github/ISSUE_TEMPLATE.md

@@ -19,7 +19,7 @@ Please also include a live example if possible. You can start from these templat
 ##### Three.js version
 
 - [ ] Dev
-- [ ] r92
+- [ ] r93
 - [ ] ...
 
 ##### Browser

File diff suppressed because it is too large
+ 11 - 1
build/three.js


File diff suppressed because it is too large
+ 382 - 381
build/three.min.js


File diff suppressed because it is too large
+ 11 - 1
build/three.module.js


+ 3 - 3
docs/api/core/Object3D.html

@@ -387,13 +387,13 @@
 		</p>
 
 		<h3>[method:this translateX]( [param:Float distance] )</h3>
-		<p>Translates object along x axis by *distance* units.</p>
+		<p>Translates object along x axis in object space by *distance* units.</p>
 
 		<h3>[method:this translateY]( [param:Float distance] )</h3>
-		<p>Translates object along y axis by *distance* units.</p>
+		<p>Translates object along y axis in object space by *distance* units.</p>
 
 		<h3>[method:this translateZ]( [param:Float distance] )</h3>
-		<p>Translates object along z axis by *distance* units.</p>
+		<p>Translates object along z axis in object space by *distance* units.</p>
 
 		<h3>[method:null traverse]( [param:Function callback] )</h3>
 		<p>

+ 1 - 1
docs/api/loaders/JSONLoader.html

@@ -18,7 +18,7 @@
 		<h2>Example</h2>
 
 		<p>
-		[example:webgl_loader_json_blender WebGL / loader / json / blender]<br />
+		[example:webgl_loader_json WebGL / loader / json]<br />
 		[example:webgl_loader_json_objconverter WebGL / loader / json / objconverter]
 		</p>
 

+ 1 - 1
docs/api/objects/Line.html

@@ -79,7 +79,7 @@
 		Computes an array of distance values which are necessary for [page:LineDashedMaterial]. For each vertex in the geometry, the method calculates the cumulative length from the current point to the very beginning of the line.
 		</p>
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		Get intersections between a casted [page:Ray] and this Line.
 		[page:Raycaster.intersectObject] will call this method.

+ 1 - 1
docs/api/objects/Mesh.html

@@ -92,7 +92,7 @@
 		<h3>[method:Mesh clone]()</h3>
 		<p>Returns a clone of this [name] object and its descendants.</p>
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		Get intersections between a casted ray and this mesh.
 		[page:Raycaster.intersectObject] will call this method.

+ 1 - 1
docs/api/objects/Points.html

@@ -58,7 +58,7 @@
 		<h2>Methods</h2>
 		<p>See the base [page:Object3D] class for common methods.</p>
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		Get intersections between a casted ray and this Points.
 		[page:Raycaster.intersectObject] will call this method.

+ 1 - 1
docs/api/objects/Sprite.html

@@ -76,7 +76,7 @@ scene.add( sprite );
 		Copies the properties of the passed sprite to this one.
 		</p>
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		Get intersections between a casted ray and this sprite.
 		[page:Raycaster.intersectObject] will call this method.

+ 1 - 0
docs/api/textures/DataTexture.html

@@ -57,6 +57,7 @@
 		// used the buffer to create a [name]
 
 		var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
+		texture.needsUpdate = true
 		</code>
 
 		<h2>Properties</h2>

+ 1 - 1
docs/examples/exporters/GLTFExporter.html

@@ -25,7 +25,7 @@
 
 		<code>
 		// Instantiate a exporter
-		var exporter = new THREE.GLTFExporter( defaultOptions );
+		var exporter = new THREE.GLTFExporter();
 
 		// Parse the input and generate the glTF output
 		exporter.parse( scene, function ( gltf ) {

+ 62 - 0
docs/examples/exporters/PLYExporter.html

@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<p class="desc">
+		An exporter for *PLY*.
+		<br /><br />
+		<a href="https://www.khronos.org/gltf">PLY</a> (Polygon or Stanford Triangle Format) is a
+		file format for efficient delivery and loading of simple, static 3D content in a dense format.
+		Both binary and ascii formats are supported. PLY can store vertex positions, colors, normals and
+		uv coordinates. No textures or texture references are saved.
+		</p>
+
+		<h2>Example</h2>
+
+		<code>
+		// Instantiate an exporter
+		var exporter = new THREE.PLYExporter();
+
+		// Parse the input and generate the ply output
+		var data = exporter.parse( scene, options );
+		downloadFile(data);
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+		<p>
+		</p>
+		<p>
+		Creates a new [name].
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null parse]( [param:Object3D input], [param:Object options] )</h3>
+		<p>
+		[page:Object input] — Object3D<br />
+		[page:Options options] — Export options<br />
+		<ul>
+			<li>excludeAttributes - array. Which properties to explicitly exclude from the exported PLY file. Valid values are 'color', 'normal', 'uv', and 'index'. If triangle indices are excluded, then a point cloud is exported. Default is an empty array.</li>
+			<li>binary - bool. Export in binary format, returning an ArrayBuffer. Default is false.</li>
+		</ul>
+		</p>
+		<p>
+		Generates ply file data as string or ArrayBuffer (ascii or binary) output from the input object.
+		If the object is composed of multiple children and geometry, they are merged into a single mesh in the file.
+		</p>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/PLYExporter.js examples/js/exporters/PLYExporter.js]
+	</body>
+</html>

+ 1 - 0
docs/examples/renderers/CSS2DRenderer.html

@@ -33,6 +33,7 @@
 		<h2>Examples</h2>
 
 		<p>
+			[example:css2d_label]<br>
 			[example:webgl_loader_pdb molecules]
 		</p>
 

+ 3 - 1
docs/list.js

@@ -10,6 +10,7 @@ var list = {
 			"How to run things locally": "manual/introduction/How-to-run-things-locally",
 			"Drawing Lines": "manual/introduction/Drawing-lines",
 			"Creating Text": "manual/introduction/Creating-text",
+			"Loading 3D Models": "manual/introduction/Loading-3D-models",
 			"Migration Guide": "manual/introduction/Migration-guide",
 			"Code Style Guide": "manual/introduction/Code-style-guide",
 			"FAQ": "manual/introduction/FAQ",
@@ -373,7 +374,8 @@ var list = {
 		},
 
 		"Exporters": {
-			"GLTFExporter": "examples/exporters/GLTFExporter"
+			"GLTFExporter": "examples/exporters/GLTFExporter",
+			"PLYExporter": "examples/exporters/PLYExporter"
 		},
 
 		"Plugins": {

+ 5 - 5
docs/manual/introduction/Animation-system.html

@@ -35,11 +35,11 @@
 		<p class="desc">
 
 			If you have successfully imported an animated 3D object (it doesn't matter if it has
-			bones or morph targets or both) - for example exporting it from Blender with the
-			[link:https://github.com/mrdoob/three.js/tree/master/utils/exporters/blender/addons/io_three Blender exporter] and
-			loading it into a three.js scene using [page:JSONLoader] -, one of the geometry's
-			properties of the loaded mesh should be an array named "animations", containing the
-			[page:AnimationClip AnimationClips] for this model (see a list of possible loaders below).<br /><br />
+			bones or morph targets or both)  for example exporting it from Blender with the
+			[link:https://github.com/KhronosGroup/glTF-Blender-Exporter glTF Blender exporter] and
+			loading it into a three.js scene using [page:GLTFLoader] — one of the response fields
+			should be an array named "animations", containing the [page:AnimationClip AnimationClips]
+			for this model (see a list of possible loaders below).<br /><br />
 
 			Each *AnimationClip* usually holds the data for a certain activity of the object. If the
 			mesh is a character, for example, there may be one AnimationClip for a walkcycle, a second

+ 1 - 1
docs/manual/introduction/Creating-a-scene.html

@@ -14,7 +14,7 @@
 
 		<h2>Before we start</h2>
 
-		<p>Before you can use three.js, you need somewhere to display it. Save the following HTML to a file on your computer, along with a copy of <a href="http://threejs.org/build/three.js">three.js</a> in the js/ directory, and open it in your browser.</p>
+		<p>Before you can use three.js, you need somewhere to display it. Save the following HTML to a file on your computer, along with a copy of [link:https://threejs.org/build/three.js three.js] in the js/ directory, and open it in your browser.</p>
 
 		<code>
 		&lt;!DOCTYPE html&gt;

+ 3 - 3
docs/manual/introduction/FAQ.html

@@ -16,7 +16,7 @@
 				The recommended format for importing and exporting assets is glTF (GL Transmission Format). Because glTF is focused on runtime asset delivery, it is compact to transmit and fast to load.
 			</p>
 			<p>
-				three.js provides loaders for many other popular formats like FBX, Collada or OBJ as well. Nevertheless, you should always try to establish a glTF based workflow in your projects first.
+				three.js provides loaders for many other popular formats like FBX, Collada or OBJ as well. Nevertheless, you should always try to establish a glTF based workflow in your projects first. For more information, see [link:#manual/introduction/Loading-3D-models loading 3D models].
 			</p>
 		</div>
 
@@ -26,9 +26,9 @@
 
 				<p>These tags control viewport size and scale for mobile browsers (where page content may be rendered at different size than visible viewport).</p>
 
-				<p><a href="https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html">Safari: Using the Viewport</a></p>
+				<p>[link:https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html Safari: Using the Viewport]</p>
 
-				<p><a href="https://developer.mozilla.org/en/Mobile/Viewport_meta_tag">MDN: Using the viewport meta tag</a></p>
+				<p>[link:https://developer.mozilla.org/en/Mobile/Viewport_meta_tag MDN: Using the viewport meta tag]</p>
 		</div>
 
 		<h2>How can scene scale be preserved on resize?</h2>

+ 3 - 3
docs/manual/introduction/Import-via-modules.html

@@ -23,11 +23,11 @@
 
 		<h2>Installation via npm</h2>
 
-		<p>Three.js is published as an npm module, see: <a href="https://www.npmjs.com/package/three" target="_blank">npm</a>. This means all you need to do to include three.js into your project is run "npm install three"</p>
+		<p>Three.js is published as an npm module, see: [link:https://www.npmjs.com/package/three npm]. This means all you need to do to include three.js into your project is run "npm install three"</p>
 
 		<h2>Importing the module</h2>
 
-		<p>Assuming that you're bundling your files with a tool such as <a href="https://webpack.github.io/" target="_blank">Webpack</a> or <a href="https://github.com/substack/node-browserify" target="_blank">Browserify</a>, which allow you to "require('modules') in the browser by bundling up all of your dependencies."</p>
+		<p>Assuming that you're bundling your files with a tool such as [link:https://webpack.github.io/ Webpack] or [link:https://github.com/substack/node-browserify Browserify], which allow you to "require('modules') in the browser by bundling up all of your dependencies."</p>
 
 		<p>
 			You should now be able to import the module into your source files and continue to use it as per normal.
@@ -41,7 +41,7 @@
 		</code>
 
 		<p>
-			You're also able to leverage <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import" target="_blank">ES6 import syntax</a>:
+			You're also able to leverage [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import ES6 import syntax]:
 		</p>
 
 		<code>

+ 129 - 0
docs/manual/introduction/Loading-3D-models.html

@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="utf-8">
+  <base href="../../" />
+  <script src="list.js"></script>
+  <script src="page.js"></script>
+  <link type="text/css" rel="stylesheet" href="page.css" />
+</head>
+
+<body>
+  <h1>[name]</h1>
+  <br />
+
+  <p>
+    3D models are available in hundreds of file formats, each with different
+    purposes, assorted features, and varying complexity. Although
+    <a href="https://github.com/mrdoob/three.js/tree/dev/examples/js/loaders">
+    three.js provides many loaders</a>, choosing the right format and
+    workflow will save time and frustration later on. Some formats are
+    difficult to work with, inefficient for realtime experiences, or simply not
+    fully supported at this time.
+  </p>
+
+  <p>
+    This guide provides a workflow recommended for most users, and suggestions
+    for what to try if things don't go as expected.
+  </p>
+
+  <h2>Before we start</h2>
+
+  <p>
+    If you're new to running a local server, begin with
+    [link:#manual/introduction/How-to-run-things-locally how to run things locally]
+    first. Many common errors viewing 3D models can be avoided by hosting files
+    correctly.
+  </p>
+
+  <h2>Recommended workflow</h2>
+
+  <p>
+    Where possible, we recommend using glTF (GL Transmission Format). Both
+    <small>.GLB</small> and <small>.GLTF</small> versions of the format are
+    well supported. Because glTF is focused on runtime asset delivery, it is
+    compact to transmit and fast to load. Features include meshes, materials,
+    textures, skins, skeletons, morph targets, animations, lights, and
+    cameras.
+  </p>
+
+  <p>
+    Public-domain glTF files are available on sites like
+    <a href="https://sketchfab.com/models?features=downloadable&sort_by=-likeCount&type=models">
+    Sketchfab</a>, or various tools include glTF export:
+  </p>
+
+  <ul>
+    <li><a href="https://github.com/KhronosGroup/glTF-Blender-Exporter">glTF-Blender-Exporter</a> by the Khronos Group</li>
+    <li><a href="https://github.com/KhronosGroup/COLLADA2GLTF">COLLADA2GLTF</a> by the Khronos Group</li>
+    <li><a href="https://github.com/facebookincubator/FBX2glTF">FBX2GLTF</a> by Facebook</li>
+    <li><a href="https://github.com/AnalyticalGraphicsInc/obj2gltf">OBJ2GLTF</a> by Analytical Graphics Inc</li>
+    <li><a href="https://www.allegorithmic.com/products/substance-painter">Substance Painter</a> by Allegorithmic</li>
+    <li><a href="https://www.foundry.com/products/modo">Modo</a> by Foundry</li>
+    <li><a href="https://www.marmoset.co/toolbag/">Toolbag</a> by Marmoset</li>
+    <li>&hellip;and <a href="https://github.com/khronosgroup/gltf#gltf-tools">many more</a></li>
+  </ul>
+
+  <p>
+    If your preferred tools do not support glTF, consider requesting glTF
+    export from the authors, or posting on
+    <a href="https://github.com/KhronosGroup/glTF/issues/1051">the glTF roadmap thread</a>.
+  </p>
+
+  <p>
+    When glTF is not an option, popular formats such as FBX, OBJ, or COLLADA
+    are also available and regularly maintained.
+  </p>
+
+  <h2>Troubleshooting</h2>
+
+  <p>
+    You've spent hours modeling an artisanal masterpiece, you load it into
+    the webpage, and — oh no! 😭 It's distorted, miscolored, or missing entirely.
+    Start with these troubleshooting steps:
+  </p>
+
+  <ol>
+    <li>
+      Check the JavaScript console for errors, and make sure you've used an
+      <em>onError</em> callback when calling <em>.load()</em> to log the result.
+    </li>
+    <li>
+      View the model in another application. For glTF, drag-and-drop viewers
+      are available for
+      <a href="https://gltf-viewer.donmccurdy.com/">three.js</a> and
+      <a href="http://sandbox.babylonjs.com/">babylon.js</a>. If the model
+      appears correctly in one or more applications,
+      <a href="https://github.com/mrdoob/three.js/issues/new">file a bug against three.js</a>.
+      If the model cannot be shown in any application, we strongly encourage
+      filing a bug with the application used to create the model.
+    </li>
+    <li>
+      Try scaling the model up or down by a factor of 1000. Many models are
+      scaled differently, and large models may not appear if the camera is
+      inside the model.
+    </li>
+    <li>
+      Look for failed texture requests in the network tab, like
+      <em>C:\\Path\To\Model\texture.jpg</em>. Use paths relative to your
+      model instead, such as <em>images/texture.jpg</em> — this may require
+      editing the model file in a text editor.
+    </li>
+  </ol>
+
+  <h2>Asking for help</h2>
+
+  <p>
+    If you've gone through the troubleshooting process above and your model
+    still isn't working, the right approach to asking for help will get you to
+    a solution faster. Post a question on the
+    <a href="https://discourse.threejs.org/">three.js forum</a> and, whenever possible,
+    include your model (or a simpler model with the same problem) in any formats
+    you have available. Include enough information for someone else to reproduce
+    the issue quickly — ideally, a live demo.
+  </p>
+
+</body>
+
+</html>

+ 7 - 0
docs/manual/introduction/Useful-links.html

@@ -126,6 +126,13 @@
 			[link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js].
 		</li>
 	 </ul>
+		
+	<h2>WebGL References</h2>
+	 <ul>
+		 <li>
+			[link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf] - Reference of all WebGL and GLSL keywords, terminology, syntex and definations.
+		 </li>
+	 </ul>
 
 	 <h2>Old Links</h2>
 	 <p>

+ 11 - 27
docs/scenes/geometry-browser.html

@@ -72,36 +72,20 @@
 			scene.add( lights[ 1 ] );
 			scene.add( lights[ 2 ] );
 
-			var mesh = new THREE.Object3D();
+			var group = new THREE.Group();
 
-			mesh.add( new THREE.LineSegments(
+			var geometry = new THREE.BufferGeometry();
+			geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( [], 3 ) );
 
-				new THREE.Geometry(),
+			var lineMaterial = new THREE.LineBasicMaterial( { color: 0xffffff, transparent: true, opacity: 0.5 } );
+			var meshMaterial = new THREE.MeshPhongMaterial( { color: 0x156289, emissive: 0x072534, side: THREE.DoubleSide, flatShading: true } );
 
-				new THREE.LineBasicMaterial( {
-					color: 0xffffff,
-					transparent: true,
-					opacity: 0.5
-				} )
+			group.add( new THREE.LineSegments( geometry, lineMaterial ) );
+			group.add( new THREE.Mesh( geometry, meshMaterial ) );
 
-			) );
+			var options = chooseFromHash( group );
 
-			mesh.add( new THREE.Mesh(
-
-				new THREE.Geometry(),
-
-				new THREE.MeshPhongMaterial( {
-					color: 0x156289,
-					emissive: 0x072534,
-					side: THREE.DoubleSide,
-					flatShading: true
-				} )
-
-			) );
-
-			var options = chooseFromHash( mesh );
-
-			scene.add( mesh );
+			scene.add( group );
 
 			var prevFog = false;
 
@@ -111,8 +95,8 @@
 
 				if ( ! options.fixed ) {
 
-					mesh.rotation.x += 0.005;
-					mesh.rotation.y += 0.005;
+					group.rotation.x += 0.005;
+					group.rotation.y += 0.005;
 
 				}
 

+ 150 - 0
examples/css2d_label.html

@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<title>three.js css2d - label</title>
+		<style>
+			body {
+				background-color: #000;
+				margin: 0;
+				overflow: hidden;
+			}
+			#info {
+				position: absolute;
+				top: 0px;
+				width: 100%;
+				color: #FFF;
+				padding: 5px;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
+				z-index: 1;
+			}
+
+			.label{
+				color: #FFF;
+				font-family: sans-serif;
+				padding: 2px;
+				background: rgba( 0, 0, 0, .6 );
+			}
+
+			a {
+				color: #000000;
+			}
+
+		</style>
+	</head>
+	<body>
+		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - three.js css2d - label</div>
+
+		<script src="../build/three.js"></script>
+
+		<script src="js/controls/OrbitControls.js"></script>
+
+		<script src="js/renderers/CSS2DRenderer.js"></script>
+
+		<script>
+
+			var camera, scene, renderer, labelRenderer;
+			var controls;
+			var clock = new THREE.Clock();
+			var textureLoader = new THREE.TextureLoader();
+
+			var earth, moon;
+
+			init();
+			animate();
+
+			function init() {
+
+				var EARTH_RADIUS = 1;
+				var MOON_RADIUS = 0.27;
+
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.set( 10, 5, 20 );
+
+				controls = new THREE.OrbitControls( camera );
+
+				scene = new THREE.Scene();
+
+				scene2 = new THREE.Scene();
+
+				dirLight = new THREE.DirectionalLight( 0xffffff );
+				dirLight.position.set( 0, 0, 1 );
+				scene.add( dirLight );
+
+				var axesHelper = new THREE.AxesHelper( 5 );
+				scene.add( axesHelper );
+
+				//
+
+				var earthGeometry = new THREE.SphereBufferGeometry( EARTH_RADIUS, 16, 16 );
+				var earthMaterial = new THREE.MeshPhongMaterial( {
+					specular: 0x333333,
+					shininess: 5,
+					map: textureLoader.load( 'textures/planets/earth_atmos_2048.jpg' ),
+					specularMap: textureLoader.load( 'textures/planets/earth_specular_2048.jpg' ),
+					normalMap: textureLoader.load( 'textures/planets/earth_normal_2048.jpg' ),
+					normalScale: new THREE.Vector2( 0.85, 0.85 )
+				} );
+				earth = new THREE.Mesh( earthGeometry, earthMaterial );
+				scene.add( earth );
+
+				var moonGeometry = new THREE.SphereBufferGeometry( MOON_RADIUS, 16, 16 );
+				var moonMaterial = new THREE.MeshPhongMaterial( {
+					shininess: 5,
+					map: textureLoader.load( 'textures/planets/moon_1024.jpg' )
+				} );
+				moon = new THREE.Mesh( moonGeometry, moonMaterial );
+				scene.add( moon );
+
+				//
+
+				var earthDiv = document.createElement( 'div' );
+				earthDiv.className = 'label';
+				earthDiv.textContent = 'Earth';
+				earthDiv.style.marginTop = '-1em';
+				var earthLabel = new THREE.CSS2DObject( earthDiv );
+				earthLabel.position.set( 0, EARTH_RADIUS, 0 );
+				earth.add( earthLabel );
+
+				var moonDiv = document.createElement( 'div' );
+				moonDiv.className = 'label';
+				moonDiv.textContent = 'Moon';
+				moonDiv.style.marginTop = '-1em';
+				var moonLabel = new THREE.CSS2DObject( moonDiv );
+				moonLabel.position.set( 0, MOON_RADIUS, 0 );
+				moon.add( moonLabel );
+
+				//
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				labelRenderer = new THREE.CSS2DRenderer();
+				labelRenderer.setSize( window.innerWidth, window.innerHeight );
+				labelRenderer.domElement.style.position = 'absolute';
+				labelRenderer.domElement.style.top = 0;
+				document.body.appendChild( labelRenderer.domElement );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				var elapsed = clock.getElapsedTime();
+
+				moon.position.set( Math.sin( elapsed ) * 5, 0, Math.cos( elapsed ) * 5 );
+
+				renderer.render( scene, camera );
+				labelRenderer.render( scene, camera );
+
+			}
+
+		</script>
+	</body>
+</html>

+ 6 - 2
examples/files.js

@@ -22,7 +22,7 @@ var files = {
 		"webgl_geometries",
 		"webgl_geometries_parametric",
 		"webgl_geometry_colors",
-		"webgl_geometry_colors_blender",
+		"webgl_geometry_colors_json",
 		"webgl_geometry_colors_lookuptable",
 		"webgl_geometry_convex",
 		"webgl_geometry_cube",
@@ -93,7 +93,7 @@ var files = {
 		"webgl_loader_gltf",
 		"webgl_loader_gltf_extensions",
 		"webgl_loader_imagebitmap",
-		"webgl_loader_json_blender",
+		"webgl_loader_json",
 		"webgl_loader_json_claraio",
 		"webgl_loader_json_objconverter",
 		"webgl_loader_kmz",
@@ -342,6 +342,7 @@ var files = {
 		"misc_controls_transform",
 		"misc_exporter_gltf",
 		"misc_exporter_obj",
+		"misc_exporter_stl",
 		"misc_fps",
 		"misc_lights_test",
 		"misc_lookat",
@@ -359,6 +360,9 @@ var files = {
 		"css3d_sprites",
 		"css3d_youtube"
 	],
+	"css2d": [
+		"css2d_label"
+	],
 	"canvas": [
 		"canvas_ascii_effect",
 		"canvas_camera_orthographic",

+ 9 - 8
examples/js/MorphBlendMesh.js

@@ -12,9 +12,9 @@ THREE.MorphBlendMesh = function ( geometry, material ) {
 	// prepare default animation
 	// (all frames played together in 1 second)
 
-	var numFrames = this.geometry.morphTargets.length;
+	var numFrames = Object.keys( this.morphTargetDictionary ).length;
 
-	var name = "__default";
+	var name = '__default';
 
 	var startFrame = 0;
 	var endFrame = numFrames - 1;
@@ -24,7 +24,7 @@ THREE.MorphBlendMesh = function ( geometry, material ) {
 	this.createAnimation( name, startFrame, endFrame, fps );
 	this.setAnimationWeight( name, 1 );
 
-}
+};
 
 THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), {
 
@@ -61,18 +61,17 @@ THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.protot
 
 	},
 
-		autoCreateAnimations: function ( fps ) {
+	autoCreateAnimations: function ( fps ) {
 
 		var pattern = /([a-z]+)_?(\d+)/i;
 
 		var firstAnimation, frameRanges = {};
 
-		var geometry = this.geometry;
+		var i = 0;
 
-		for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
+		for ( var key in this.morphTargetDictionary ) {
 
-			var morph = geometry.morphTargets[ i ];
-			var chunks = morph.name.match( pattern );
+			var chunks = key.match( pattern );
 
 			if ( chunks && chunks.length > 1 ) {
 
@@ -89,6 +88,8 @@ THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.protot
 
 			}
 
+			i ++;
+
 		}
 
 		for ( var name in frameRanges ) {

+ 1 - 1
examples/js/animation/CCDIKSolver.js

@@ -203,7 +203,7 @@ THREE.CCDIKSolver = ( function () {
 		 */
 		createHelper: function () {
 
-			return new CCDIKHelper( this.mesh, this.mesh.geometry.iks );
+			return new CCDIKHelper( this.mesh, this.mesh.geometry.userData.MMD.iks );
 
 		},
 

+ 8 - 5
examples/js/animation/MMDAnimationHelper.js

@@ -275,7 +275,7 @@ THREE.MMDAnimationHelper = ( function () {
 		 */
 		createGrantSolver: function ( mesh ) {
 
-			return new GrantSolver( mesh, mesh.geometry.grants );
+			return new GrantSolver( mesh, mesh.geometry.userData.MMD.grants );
 
 		},
 
@@ -581,8 +581,8 @@ THREE.MMDAnimationHelper = ( function () {
 
 		_optimizeIK: function ( mesh, physicsEnabled ) {
 
-			var iks = mesh.geometry.iks;
-			var bones = mesh.geometry.bones;
+			var iks = mesh.geometry.userData.MMD.iks;
+			var bones = mesh.geometry.userData.MMD.bones;
 
 			for ( var i = 0, il = iks.length; i < il; i ++ ) {
 
@@ -619,7 +619,7 @@ THREE.MMDAnimationHelper = ( function () {
 
 			}
 
-			return new THREE.CCDIKSolver( mesh, mesh.geometry.iks );
+			return new THREE.CCDIKSolver( mesh, mesh.geometry.userData.MMD.iks );
 
 		},
 
@@ -632,7 +632,10 @@ THREE.MMDAnimationHelper = ( function () {
 			}
 
 			return new THREE.MMDPhysics(
-				mesh, mesh.geometry.rigidBodies, mesh.geometry.constraints, params );
+				mesh,
+				mesh.geometry.userData.MMD.rigidBodies,
+				mesh.geometry.userData.MMD.constraints,
+				params );
 
 		},
 

+ 14 - 6
examples/js/cameras/CinematicCamera.js

@@ -5,20 +5,28 @@
  * @author kaypiKun
  */
 
-THREE.CinematicCamera = function( fov, aspect, near, far ) {
+THREE.CinematicCamera = function ( fov, aspect, near, far ) {
 
 	THREE.PerspectiveCamera.call( this, fov, aspect, near, far );
 
-	this.type = "CinematicCamera";
+	this.type = 'CinematicCamera';
 
-	this.postprocessing = { enabled	: true };
+	this.postprocessing = { enabled: true };
 	this.shaderSettings = {
 		rings: 3,
 		samples: 4
 	};
 
-	this.material_depth = new THREE.MeshDepthMaterial();
-	this.material_depth.depthPacking = THREE.RGBADepthPacking;
+	var depthShader = THREE.BokehDepthShader;
+
+	this.materialDepth = new THREE.ShaderMaterial( {
+		uniforms: depthShader.uniforms,
+		vertexShader: depthShader.vertexShader,
+		fragmentShader: depthShader.fragmentShader
+	} );
+
+	this.materialDepth.uniforms[ 'mNear' ].value = near;
+	this.materialDepth.uniforms[ 'mFar' ].value = far;
 
 	// In case of cinematicCamera, having a default lens set is important
 	this.setLens();
@@ -178,7 +186,7 @@ THREE.CinematicCamera.prototype.renderCinematic = function ( scene, renderer ) {
 
 		// Render depth into texture
 
-		scene.overrideMaterial = this.material_depth;
+		scene.overrideMaterial = this.materialDepth;
 		renderer.render( scene, camera, this.postprocessing.rtTextureDepth, true );
 
 		// Render bokeh composite

+ 0 - 149
examples/js/controls/VRControls.js

@@ -1,149 +0,0 @@
-/**
- * @author dmarcos / https://github.com/dmarcos
- * @author mrdoob / http://mrdoob.com
- */
-
-THREE.VRControls = function ( object, onError ) {
-
-	var scope = this;
-
-	var vrDisplay, vrDisplays;
-
-	var standingMatrix = new THREE.Matrix4();
-
-	var frameData = null;
-
-	if ( 'VRFrameData' in window ) {
-
-		frameData = new VRFrameData();
-
-	}
-
-	function gotVRDisplays( displays ) {
-
-		vrDisplays = displays;
-
-		if ( displays.length > 0 ) {
-
-			vrDisplay = displays[ 0 ];
-
-		} else {
-
-			if ( onError ) onError( 'VR input not available.' );
-
-		}
-
-	}
-
-	if ( navigator.getVRDisplays ) {
-
-		navigator.getVRDisplays().then( gotVRDisplays ).catch( function () {
-
-			console.warn( 'THREE.VRControls: Unable to get VR Displays' );
-
-		} );
-
-	}
-
-	// the Rift SDK returns the position in meters
-	// this scale factor allows the user to define how meters
-	// are converted to scene units.
-
-	this.scale = 1;
-
-	// If true will use "standing space" coordinate system where y=0 is the
-	// floor and x=0, z=0 is the center of the room.
-	this.standing = false;
-
-	// Distance from the users eyes to the floor in meters. Used when
-	// standing=true but the VRDisplay doesn't provide stageParameters.
-	this.userHeight = 1.6;
-
-	this.getVRDisplay = function () {
-
-		return vrDisplay;
-
-	};
-
-	this.setVRDisplay = function ( value ) {
-
-		vrDisplay = value;
-
-	};
-
-	this.getVRDisplays = function () {
-
-		console.warn( 'THREE.VRControls: getVRDisplays() is being deprecated.' );
-		return vrDisplays;
-
-	};
-
-	this.getStandingMatrix = function () {
-
-		return standingMatrix;
-
-	};
-
-	this.update = function () {
-
-		if ( vrDisplay ) {
-
-			var pose;
-
-			if ( vrDisplay.getFrameData ) {
-
-				vrDisplay.getFrameData( frameData );
-				pose = frameData.pose;
-
-			} else if ( vrDisplay.getPose ) {
-
-				pose = vrDisplay.getPose();
-
-			}
-
-			if ( pose.orientation !== null ) {
-
-				object.quaternion.fromArray( pose.orientation );
-
-			}
-
-			if ( pose.position !== null ) {
-
-				object.position.fromArray( pose.position );
-
-			} else {
-
-				object.position.set( 0, 0, 0 );
-
-			}
-
-			if ( this.standing ) {
-
-				if ( vrDisplay.stageParameters ) {
-
-					object.updateMatrix();
-
-					standingMatrix.fromArray( vrDisplay.stageParameters.sittingToStandingTransform );
-					object.applyMatrix( standingMatrix );
-
-				} else {
-
-					object.position.setY( object.position.y + this.userHeight );
-
-				}
-
-			}
-
-			object.position.multiplyScalar( scope.scale );
-
-		}
-
-	};
-
-	this.dispose = function () {
-
-		vrDisplay = null;
-
-	};
-
-};

+ 1 - 1
examples/js/effects/OutlineEffect.js

@@ -448,7 +448,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 	 * The following property copies and wrapper methods enable
 	 * THREE.OutlineEffect to be called from other *Effect, like
 	 *
-	 * effect = new THREE.VREffect( new THREE.OutlineEffect( renderer ) );
+	 * effect = new THREE.StereoEffect( new THREE.OutlineEffect( renderer ) );
 	 *
 	 * function render () {
 	 *

+ 0 - 533
examples/js/effects/VREffect.js

@@ -1,533 +0,0 @@
-/**
- * @author dmarcos / https://github.com/dmarcos
- * @author mrdoob / http://mrdoob.com
- *
- * WebVR Spec: http://mozvr.github.io/webvr-spec/webvr.html
- *
- * Firefox: http://mozvr.com/downloads/
- * Chromium: https://webvr.info/get-chrome
- */
-
-THREE.VREffect = function ( renderer, onError ) {
-
-	var vrDisplay, vrDisplays;
-	var eyeTranslationL = new THREE.Vector3();
-	var eyeTranslationR = new THREE.Vector3();
-	var renderRectL, renderRectR;
-	var headMatrix = new THREE.Matrix4();
-	var eyeMatrixL = new THREE.Matrix4();
-	var eyeMatrixR = new THREE.Matrix4();
-
-	var frameData = null;
-
-	if ( 'VRFrameData' in window ) {
-
-		frameData = new window.VRFrameData();
-
-	}
-
-	function gotVRDisplays( displays ) {
-
-		vrDisplays = displays;
-
-		if ( displays.length > 0 ) {
-
-			vrDisplay = displays[ 0 ];
-
-		} else {
-
-			if ( onError ) onError( 'HMD not available' );
-
-		}
-
-	}
-
-	if ( navigator.getVRDisplays ) {
-
-		navigator.getVRDisplays().then( gotVRDisplays ).catch( function () {
-
-			console.warn( 'THREE.VREffect: Unable to get VR Displays' );
-
-		} );
-
-	}
-
-	//
-
-	this.isPresenting = false;
-
-	var scope = this;
-
-	var rendererSize = renderer.getSize();
-	var rendererUpdateStyle = false;
-	var rendererPixelRatio = renderer.getPixelRatio();
-
-	this.getVRDisplay = function () {
-
-		return vrDisplay;
-
-	};
-
-	this.setVRDisplay = function ( value ) {
-
-		vrDisplay = value;
-
-	};
-
-	this.getVRDisplays = function () {
-
-		console.warn( 'THREE.VREffect: getVRDisplays() is being deprecated.' );
-		return vrDisplays;
-
-	};
-
-	this.setSize = function ( width, height, updateStyle ) {
-
-		rendererSize = { width: width, height: height };
-		rendererUpdateStyle = updateStyle;
-
-		if ( scope.isPresenting ) {
-
-			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
-			renderer.setPixelRatio( 1 );
-			renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false );
-
-		} else {
-
-			renderer.setPixelRatio( rendererPixelRatio );
-			renderer.setSize( width, height, updateStyle );
-
-		}
-
-	};
-
-	// VR presentation
-
-	var canvas = renderer.domElement;
-	var defaultLeftBounds = [ 0.0, 0.0, 0.5, 1.0 ];
-	var defaultRightBounds = [ 0.5, 0.0, 0.5, 1.0 ];
-
-	function onVRDisplayPresentChange() {
-
-		var wasPresenting = scope.isPresenting;
-		scope.isPresenting = vrDisplay !== undefined && vrDisplay.isPresenting;
-
-		if ( scope.isPresenting ) {
-
-			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
-			var eyeWidth = eyeParamsL.renderWidth;
-			var eyeHeight = eyeParamsL.renderHeight;
-
-			if ( ! wasPresenting ) {
-
-				rendererPixelRatio = renderer.getPixelRatio();
-				rendererSize = renderer.getSize();
-
-				renderer.setPixelRatio( 1 );
-				renderer.setSize( eyeWidth * 2, eyeHeight, false );
-
-			}
-
-		} else if ( wasPresenting ) {
-
-			renderer.setPixelRatio( rendererPixelRatio );
-			renderer.setSize( rendererSize.width, rendererSize.height, rendererUpdateStyle );
-
-		}
-
-	}
-
-	window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
-
-	this.setFullScreen = function ( boolean ) {
-
-		return new Promise( function ( resolve, reject ) {
-
-			if ( vrDisplay === undefined ) {
-
-				reject( new Error( 'No VR hardware found.' ) );
-				return;
-
-			}
-
-			if ( scope.isPresenting === boolean ) {
-
-				resolve();
-				return;
-
-			}
-
-			if ( boolean ) {
-
-				resolve( vrDisplay.requestPresent( [ { source: canvas } ] ) );
-
-			} else {
-
-				resolve( vrDisplay.exitPresent() );
-
-			}
-
-		} );
-
-	};
-
-	this.requestPresent = function () {
-
-		return this.setFullScreen( true );
-
-	};
-
-	this.exitPresent = function () {
-
-		return this.setFullScreen( false );
-
-	};
-
-	this.requestAnimationFrame = function ( f ) {
-
-		if ( vrDisplay !== undefined ) {
-
-			return vrDisplay.requestAnimationFrame( f );
-
-		} else {
-
-			return window.requestAnimationFrame( f );
-
-		}
-
-	};
-
-	this.cancelAnimationFrame = function ( h ) {
-
-		if ( vrDisplay !== undefined ) {
-
-			vrDisplay.cancelAnimationFrame( h );
-
-		} else {
-
-			window.cancelAnimationFrame( h );
-
-		}
-
-	};
-
-	this.submitFrame = function () {
-
-		if ( vrDisplay !== undefined && scope.isPresenting ) {
-
-			vrDisplay.submitFrame();
-
-		}
-
-	};
-
-	this.autoSubmitFrame = true;
-
-	// render
-
-	var cameraL = new THREE.PerspectiveCamera();
-	cameraL.layers.enable( 1 );
-
-	var cameraR = new THREE.PerspectiveCamera();
-	cameraR.layers.enable( 2 );
-
-	this.render = function ( scene, camera, renderTarget, forceClear ) {
-
-		if ( vrDisplay && scope.isPresenting ) {
-
-			var autoUpdate = scene.autoUpdate;
-
-			if ( autoUpdate ) {
-
-				scene.updateMatrixWorld();
-				scene.autoUpdate = false;
-
-			}
-
-			if ( Array.isArray( scene ) ) {
-
-				console.warn( 'THREE.VREffect.render() no longer supports arrays. Use object.layers instead.' );
-				scene = scene[ 0 ];
-
-			}
-
-			// When rendering we don't care what the recommended size is, only what the actual size
-			// of the backbuffer is.
-			var size = renderer.getSize();
-			var layers = vrDisplay.getLayers();
-			var leftBounds;
-			var rightBounds;
-
-			if ( layers.length ) {
-
-				var layer = layers[ 0 ];
-
-				leftBounds = layer.leftBounds !== null && layer.leftBounds.length === 4 ? layer.leftBounds : defaultLeftBounds;
-				rightBounds = layer.rightBounds !== null && layer.rightBounds.length === 4 ? layer.rightBounds : defaultRightBounds;
-
-			} else {
-
-				leftBounds = defaultLeftBounds;
-				rightBounds = defaultRightBounds;
-
-			}
-
-			renderRectL = {
-				x: Math.round( size.width * leftBounds[ 0 ] ),
-				y: Math.round( size.height * leftBounds[ 1 ] ),
-				width: Math.round( size.width * leftBounds[ 2 ] ),
-				height: Math.round( size.height * leftBounds[ 3 ] )
-			};
-			renderRectR = {
-				x: Math.round( size.width * rightBounds[ 0 ] ),
-				y: Math.round( size.height * rightBounds[ 1 ] ),
-				width: Math.round( size.width * rightBounds[ 2 ] ),
-				height: Math.round( size.height * rightBounds[ 3 ] )
-			};
-
-			if ( renderTarget ) {
-
-				renderer.setRenderTarget( renderTarget );
-				renderTarget.scissorTest = true;
-
-			} else {
-
-				renderer.setRenderTarget( null );
-				renderer.setScissorTest( true );
-
-			}
-
-			if ( renderer.autoClear || forceClear ) renderer.clear();
-
-			if ( camera.parent === null ) camera.updateMatrixWorld();
-
-			camera.matrixWorld.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
-
-			cameraR.position.copy( cameraL.position );
-			cameraR.quaternion.copy( cameraL.quaternion );
-			cameraR.scale.copy( cameraL.scale );
-
-			if ( vrDisplay.getFrameData ) {
-
-				vrDisplay.depthNear = camera.near;
-				vrDisplay.depthFar = camera.far;
-
-				vrDisplay.getFrameData( frameData );
-
-				cameraL.projectionMatrix.elements = frameData.leftProjectionMatrix;
-				cameraR.projectionMatrix.elements = frameData.rightProjectionMatrix;
-
-				getEyeMatrices( frameData );
-
-				cameraL.updateMatrix();
-				cameraL.matrix.multiply( eyeMatrixL );
-				cameraL.matrix.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
-
-				cameraR.updateMatrix();
-				cameraR.matrix.multiply( eyeMatrixR );
-				cameraR.matrix.decompose( cameraR.position, cameraR.quaternion, cameraR.scale );
-
-			} else {
-
-				var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
-				var eyeParamsR = vrDisplay.getEyeParameters( 'right' );
-
-				cameraL.projectionMatrix = fovToProjection( eyeParamsL.fieldOfView, true, camera.near, camera.far );
-				cameraR.projectionMatrix = fovToProjection( eyeParamsR.fieldOfView, true, camera.near, camera.far );
-
-				eyeTranslationL.fromArray( eyeParamsL.offset );
-				eyeTranslationR.fromArray( eyeParamsR.offset );
-
-				cameraL.translateOnAxis( eyeTranslationL, cameraL.scale.x );
-				cameraR.translateOnAxis( eyeTranslationR, cameraR.scale.x );
-
-			}
-
-			// render left eye
-			if ( renderTarget ) {
-
-				renderTarget.viewport.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-				renderTarget.scissor.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-
-			} else {
-
-				renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-				renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-
-			}
-			renderer.render( scene, cameraL, renderTarget, forceClear );
-
-			// render right eye
-			if ( renderTarget ) {
-
-				renderTarget.viewport.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-				renderTarget.scissor.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-
-			} else {
-
-				renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-				renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-
-			}
-			renderer.render( scene, cameraR, renderTarget, forceClear );
-
-			if ( renderTarget ) {
-
-				renderTarget.viewport.set( 0, 0, size.width, size.height );
-				renderTarget.scissor.set( 0, 0, size.width, size.height );
-				renderTarget.scissorTest = false;
-				renderer.setRenderTarget( null );
-
-			} else {
-
-				renderer.setViewport( 0, 0, size.width, size.height );
-				renderer.setScissorTest( false );
-
-			}
-
-			if ( autoUpdate ) {
-
-				scene.autoUpdate = true;
-
-			}
-
-			if ( scope.autoSubmitFrame ) {
-
-				scope.submitFrame();
-
-			}
-
-			return;
-
-		}
-
-		// Regular render mode if not HMD
-
-		renderer.render( scene, camera, renderTarget, forceClear );
-
-	};
-
-	this.dispose = function () {
-
-		window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
-
-	};
-
-	//
-
-	var poseOrientation = new THREE.Quaternion();
-	var posePosition = new THREE.Vector3();
-
-	// Compute model matrices of the eyes with respect to the head.
-	function getEyeMatrices( frameData ) {
-
-		// Compute the matrix for the position of the head based on the pose
-		if ( frameData.pose.orientation ) {
-
-			poseOrientation.fromArray( frameData.pose.orientation );
-			headMatrix.makeRotationFromQuaternion( poseOrientation );
-
-		}	else {
-
-			headMatrix.identity();
-
-		}
-
-		if ( frameData.pose.position ) {
-
-			posePosition.fromArray( frameData.pose.position );
-			headMatrix.setPosition( posePosition );
-
-		}
-
-		// The view matrix transforms vertices from sitting space to eye space. As such, the view matrix can be thought of as a product of two matrices:
-		// headToEyeMatrix * sittingToHeadMatrix
-
-		// The headMatrix that we've calculated above is the model matrix of the head in sitting space, which is the inverse of sittingToHeadMatrix.
-		// So when we multiply the view matrix with headMatrix, we're left with headToEyeMatrix:
-		// viewMatrix * headMatrix = headToEyeMatrix * sittingToHeadMatrix * headMatrix = headToEyeMatrix
-
-		eyeMatrixL.fromArray( frameData.leftViewMatrix );
-		eyeMatrixL.multiply( headMatrix );
-		eyeMatrixR.fromArray( frameData.rightViewMatrix );
-		eyeMatrixR.multiply( headMatrix );
-
-		// The eye's model matrix in head space is the inverse of headToEyeMatrix we calculated above.
-
-		eyeMatrixL.getInverse( eyeMatrixL );
-		eyeMatrixR.getInverse( eyeMatrixR );
-
-	}
-
-	function fovToNDCScaleOffset( fov ) {
-
-		var pxscale = 2.0 / ( fov.leftTan + fov.rightTan );
-		var pxoffset = ( fov.leftTan - fov.rightTan ) * pxscale * 0.5;
-		var pyscale = 2.0 / ( fov.upTan + fov.downTan );
-		var pyoffset = ( fov.upTan - fov.downTan ) * pyscale * 0.5;
-		return { scale: [ pxscale, pyscale ], offset: [ pxoffset, pyoffset ] };
-
-	}
-
-	function fovPortToProjection( fov, rightHanded, zNear, zFar ) {
-
-		rightHanded = rightHanded === undefined ? true : rightHanded;
-		zNear = zNear === undefined ? 0.01 : zNear;
-		zFar = zFar === undefined ? 10000.0 : zFar;
-
-		var handednessScale = rightHanded ? - 1.0 : 1.0;
-
-		// start with an identity matrix
-		var mobj = new THREE.Matrix4();
-		var m = mobj.elements;
-
-		// and with scale/offset info for normalized device coords
-		var scaleAndOffset = fovToNDCScaleOffset( fov );
-
-		// X result, map clip edges to [-w,+w]
-		m[ 0 * 4 + 0 ] = scaleAndOffset.scale[ 0 ];
-		m[ 0 * 4 + 1 ] = 0.0;
-		m[ 0 * 4 + 2 ] = scaleAndOffset.offset[ 0 ] * handednessScale;
-		m[ 0 * 4 + 3 ] = 0.0;
-
-		// Y result, map clip edges to [-w,+w]
-		// Y offset is negated because this proj matrix transforms from world coords with Y=up,
-		// but the NDC scaling has Y=down (thanks D3D?)
-		m[ 1 * 4 + 0 ] = 0.0;
-		m[ 1 * 4 + 1 ] = scaleAndOffset.scale[ 1 ];
-		m[ 1 * 4 + 2 ] = - scaleAndOffset.offset[ 1 ] * handednessScale;
-		m[ 1 * 4 + 3 ] = 0.0;
-
-		// Z result (up to the app)
-		m[ 2 * 4 + 0 ] = 0.0;
-		m[ 2 * 4 + 1 ] = 0.0;
-		m[ 2 * 4 + 2 ] = zFar / ( zNear - zFar ) * - handednessScale;
-		m[ 2 * 4 + 3 ] = ( zFar * zNear ) / ( zNear - zFar );
-
-		// W result (= Z in)
-		m[ 3 * 4 + 0 ] = 0.0;
-		m[ 3 * 4 + 1 ] = 0.0;
-		m[ 3 * 4 + 2 ] = handednessScale;
-		m[ 3 * 4 + 3 ] = 0.0;
-
-		mobj.transpose();
-		return mobj;
-
-	}
-
-	function fovToProjection( fov, rightHanded, zNear, zFar ) {
-
-		var DEG2RAD = Math.PI / 180.0;
-
-		var fovPort = {
-			upTan: Math.tan( fov.upDegrees * DEG2RAD ),
-			downTan: Math.tan( fov.downDegrees * DEG2RAD ),
-			leftTan: Math.tan( fov.leftDegrees * DEG2RAD ),
-			rightTan: Math.tan( fov.rightDegrees * DEG2RAD )
-		};
-
-		return fovPortToProjection( fovPort, rightHanded, zNear, zFar );
-
-	}
-
-};

+ 4 - 0
examples/js/exporters/GLTFExporter.js

@@ -1182,6 +1182,8 @@ THREE.GLTFExporter.prototype = {
 
 			}
 
+			var extras = ( Object.keys( geometry.userData ).length > 0 ) ? serializeUserData( geometry ) : undefined;
+
 			var forceIndices = options.forceIndices;
 			var isMultiMaterial = Array.isArray( mesh.material );
 
@@ -1223,6 +1225,8 @@ THREE.GLTFExporter.prototype = {
 					attributes: attributes,
 				};
 
+				if ( extras ) primitive.extras = extras;
+
 				if ( targets.length > 0 ) primitive.targets = targets;
 
 				if ( geometry.index !== null ) {

+ 1 - 1
examples/js/exporters/PLYExporter.js

@@ -6,7 +6,7 @@
  *  var exporter = new THREE.PLYExporter();
  *
  *  // second argument is a list of options
- *  var data = exporter.parse(mesh, { binar: true, excludeAttributes: [ 'color' ] });
+ *  var data = exporter.parse( mesh, { binary: true, excludeAttributes: [ 'color' ] } );
  *
  * Format Definition:
  *  http://paulbourke.net/dataformats/ply/

+ 0 - 94
examples/js/exporters/STLBinaryExporter.js

@@ -1,94 +0,0 @@
-/**
- * @author kovacsv / http://kovacsv.hu/
- * @author mrdoob / http://mrdoob.com/
- * @author mudcube / http://mudcu.be/
- */
-
-THREE.STLBinaryExporter = function () {};
-
-THREE.STLBinaryExporter.prototype = {
-
-	constructor: THREE.STLBinaryExporter,
-
-	parse: ( function () {
-
-		var vector = new THREE.Vector3();
-		var normalMatrixWorld = new THREE.Matrix3();
-
-		return function parse( scene ) {
-
-			// We collect objects first, as we may need to convert from BufferGeometry to Geometry
-			var objects = [];
-			var triangles = 0;
-			scene.traverse( function ( object ) {
-
-				if ( ! ( object instanceof THREE.Mesh ) ) return;
-
-				var geometry = object.geometry;
-				if ( geometry instanceof THREE.BufferGeometry ) {
-
-					geometry = new THREE.Geometry().fromBufferGeometry( geometry );
-
-				}
-
-				if ( ! ( geometry instanceof THREE.Geometry ) ) return;
-				triangles += geometry.faces.length;
-
-				objects.push( {
-
-					geometry: geometry,
-					matrix: object.matrixWorld
-
-				} );
-
-			} );
-
-			var offset = 80; // skip header
-			var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
-			var arrayBuffer = new ArrayBuffer( bufferLength );
-			var output = new DataView( arrayBuffer );
-			output.setUint32( offset, triangles, true ); offset += 4;
-
-			// Traversing our collected objects
-			objects.forEach( function ( object ) {
-
-				var vertices = object.geometry.vertices;
-				var faces = object.geometry.faces;
-
-				normalMatrixWorld.getNormalMatrix( object.matrix );
-
-				for ( var i = 0, l = faces.length; i < l; i ++ ) {
-
-					var face = faces[ i ];
-
-					vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
-
-					output.setFloat32( offset, vector.x, true ); offset += 4; // normal
-					output.setFloat32( offset, vector.y, true ); offset += 4;
-					output.setFloat32( offset, vector.z, true ); offset += 4;
-
-					var indices = [ face.a, face.b, face.c ];
-
-					for ( var j = 0; j < 3; j ++ ) {
-
-						vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( object.matrix );
-
-						output.setFloat32( offset, vector.x, true ); offset += 4; // vertices
-						output.setFloat32( offset, vector.y, true ); offset += 4;
-						output.setFloat32( offset, vector.z, true ); offset += 4;
-
-					}
-
-					output.setUint16( offset, 0, true ); offset += 2; // attribute byte count
-
-				}
-
-			} );
-
-			return output;
-
-		};
-
-	}() )
-
-};

+ 110 - 25
examples/js/exporters/STLExporter.js

@@ -1,6 +1,15 @@
 /**
  * @author kovacsv / http://kovacsv.hu/
  * @author mrdoob / http://mrdoob.com/
+ * @author mudcube / http://mudcu.be/
+ * @author Mugen87 / https://github.com/Mugen87
+ *
+ * Usage:
+ *  var exporter = new THREE.STLExporter();
+ *
+ *  // second argument is a list of options
+ *  var data = exporter.parse( mesh, { binary: true } );
+ *
  */
 
 THREE.STLExporter = function () {};
@@ -14,65 +23,141 @@ THREE.STLExporter.prototype = {
 		var vector = new THREE.Vector3();
 		var normalMatrixWorld = new THREE.Matrix3();
 
-		return function parse( scene ) {
+		return function parse( scene, options ) {
 
-			var output = '';
+			if ( options === undefined ) options = {};
 
-			output += 'solid exported\n';
+			var binary = options.binary !== undefined ? options.binary : false;
+
+			//
+
+			var objects = [];
+			var triangles = 0;
 
 			scene.traverse( function ( object ) {
 
-				if ( object instanceof THREE.Mesh ) {
+				if ( object.isMesh ) {
 
 					var geometry = object.geometry;
-					var matrixWorld = object.matrixWorld;
 
-					if ( geometry instanceof THREE.BufferGeometry ) {
+					if ( geometry.isBufferGeometry ) {
 
 						geometry = new THREE.Geometry().fromBufferGeometry( geometry );
 
 					}
 
-					if ( geometry instanceof THREE.Geometry ) {
+					if ( geometry.isGeometry ) {
 
-						var vertices = geometry.vertices;
-						var faces = geometry.faces;
+						triangles += geometry.faces.length;
 
-						normalMatrixWorld.getNormalMatrix( matrixWorld );
+						objects.push( {
 
-						for ( var i = 0, l = faces.length; i < l; i ++ ) {
+							geometry: geometry,
+							matrixWorld: object.matrixWorld
 
-							var face = faces[ i ];
+						} );
 
-							vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+					}
 
-							output += '\tfacet normal ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
-							output += '\t\touter loop\n';
+				}
 
-							var indices = [ face.a, face.b, face.c ];
+			} );
 
-							for ( var j = 0; j < 3; j ++ ) {
+			if ( binary ) {
+
+				var offset = 80; // skip header
+				var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
+				var arrayBuffer = new ArrayBuffer( bufferLength );
+				var output = new DataView( arrayBuffer );
+				output.setUint32( offset, triangles, true ); offset += 4;
+
+				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+
+					var object = objects[ i ];
+
+					var vertices = object.geometry.vertices;
+					var faces = object.geometry.faces;
+					var matrixWorld = object.matrixWorld;
 
-								vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( matrixWorld );
+					normalMatrixWorld.getNormalMatrix( matrixWorld );
 
-								output += '\t\t\tvertex ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+					for ( var j = 0, jl = faces.length; j < jl; j ++ ) {
 
-							}
+						var face = faces[ j ];
 
-							output += '\t\tendloop\n';
-							output += '\tendfacet\n';
+						vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+
+						output.setFloat32( offset, vector.x, true ); offset += 4; // normal
+						output.setFloat32( offset, vector.y, true ); offset += 4;
+						output.setFloat32( offset, vector.z, true ); offset += 4;
+
+						var indices = [ face.a, face.b, face.c ];
+
+						for ( var k = 0; k < 3; k ++ ) {
+
+							vector.copy( vertices[ indices[ k ] ] ).applyMatrix4( matrixWorld );
+
+							output.setFloat32( offset, vector.x, true ); offset += 4; // vertices
+							output.setFloat32( offset, vector.y, true ); offset += 4;
+							output.setFloat32( offset, vector.z, true ); offset += 4;
 
 						}
 
+						output.setUint16( offset, 0, true ); offset += 2; // attribute byte count
+
 					}
 
 				}
 
-			} );
+				return output;
+
+			} else {
+
+				var output = '';
+
+				output += 'solid exported\n';
+
+				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+
+					var object = objects[ i ];
+
+					var vertices = object.geometry.vertices;
+					var faces = object.geometry.faces;
+					var matrixWorld = object.matrixWorld;
+
+					normalMatrixWorld.getNormalMatrix( matrixWorld );
+
+					for ( var j = 0, jl = faces.length; j < jl; j ++ ) {
+
+						var face = faces[ j ];
+
+						vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+
+						output += '\tfacet normal ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+						output += '\t\touter loop\n';
+
+						var indices = [ face.a, face.b, face.c ];
+
+						for ( var k = 0; k < 3; k ++ ) {
+
+							vector.copy( vertices[ indices[ k ] ] ).applyMatrix4( matrixWorld );
+
+							output += '\t\t\tvertex ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+
+						}
+
+						output += '\t\tendloop\n';
+						output += '\tendfacet\n';
+
+					}
+
+				}
+
+				output += 'endsolid exported\n';
 
-			output += 'endsolid exported\n';
+				return output;
 
-			return output;
+			}
 
 		};
 

+ 5 - 0
examples/js/loaders/DRACOLoader.js

@@ -52,14 +52,17 @@ THREE.DRACOLoader.prototype = {
 
     setPath: function(value) {
         this.path = value;
+        return this;
     },
 
     setCrossOrigin: function(value) {
         this.crossOrigin = value;
+        return this;
     },
 
     setVerbosity: function(level) {
         this.verbosity = level;
+        return this;
     },
 
     /**
@@ -70,6 +73,7 @@ THREE.DRACOLoader.prototype = {
      */
     setDrawMode: function(drawMode) {
         this.drawMode = drawMode;
+        return this;
     },
 
     /**
@@ -84,6 +88,7 @@ THREE.DRACOLoader.prototype = {
           skipDequantization = skip;
         this.getAttributeOptions(attributeName).skipDequantization =
             skipDequantization;
+        return this;
     },
 
     /**

+ 1 - 7
examples/js/loaders/EquiangularToCubeGenerator.js

@@ -95,13 +95,7 @@ THREE.EquiangularToCubeGenerator.prototype = {
 					gl_FragColor = vec4( color, 1.0 );\n\
 				}",
 
-			blending: THREE.CustomBlending,
-			premultipliedAlpha: false,
-			blendSrc: THREE.OneFactor,
-			blendDst: THREE.ZeroFactor,
-			blendSrcAlpha: THREE.OneFactor,
-			blendDstAlpha: THREE.ZeroFactor,
-			blendEquation: THREE.AddEquation
+			blending: THREE.NoBlending
 
 		} );
 

+ 25 - 24
examples/js/loaders/GLTFLoader.js

@@ -246,9 +246,9 @@ THREE.GLTFLoader = ( function () {
 	/**
 	 * DDS Texture Extension
 	 *
-	 * Specification: 
+	 * Specification:
 	 * https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_texture_dds
-	 * 
+	 *
 	 */
 	function GLTFTextureDDSExtension() {
 
@@ -455,7 +455,7 @@ THREE.GLTFLoader = ( function () {
 	 *
 	 * Specification: https://github.com/KhronosGroup/glTF/pull/874
 	 */
-	function GLTFDracoMeshCompressionExtension ( json, dracoLoader ) {
+	function GLTFDracoMeshCompressionExtension( json, dracoLoader ) {
 
 		if ( ! dracoLoader ) {
 
@@ -481,7 +481,7 @@ THREE.GLTFLoader = ( function () {
 
 		for ( var attributeName in gltfAttributeMap ) {
 
-			if ( !( attributeName in ATTRIBUTES ) ) continue;
+			if ( ! ( attributeName in ATTRIBUTES ) ) continue;
 
 			threeAttributeMap[ ATTRIBUTES[ attributeName ] ] = gltfAttributeMap[ attributeName ];
 
@@ -494,7 +494,7 @@ THREE.GLTFLoader = ( function () {
 				var accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];
 				var componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
 
-				attributeTypeMap[ ATTRIBUTES[ attributeName ] ]  = componentType;
+				attributeTypeMap[ ATTRIBUTES[ attributeName ] ] = componentType;
 				attributeNormalizedMap[ ATTRIBUTES[ attributeName ] ] = accessorDef.normalized === true;
 
 			}
@@ -934,7 +934,7 @@ THREE.GLTFLoader = ( function () {
 
 		THREE.Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
 
-	};
+	}
 
 	GLTFCubicSplineInterpolant.prototype = Object.create( THREE.Interpolant.prototype );
 	GLTFCubicSplineInterpolant.prototype.constructor = GLTFCubicSplineInterpolant;
@@ -966,10 +966,10 @@ THREE.GLTFLoader = ( function () {
 		//   [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
 		for ( var i = 0; i !== stride; i ++ ) {
 
-			var p0 = values[ offset0 + i + stride ];        // splineVertex_k
-			var m0 = values[ offset0 + i + stride2 ] * td;  // outTangent_k * (t_k+1 - t_k)
-			var p1 = values[ offset1 + i + stride ];        // splineVertex_k+1
-			var m1 = values[ offset1 + i ] * td;            // inTangent_k+1 * (t_k+1 - t_k)
+			var p0 = values[ offset0 + i + stride ]; // splineVertex_k
+			var m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k)
+			var p1 = values[ offset1 + i + stride ]; // splineVertex_k+1
+			var m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k)
 
 			result[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;
 
@@ -1123,7 +1123,7 @@ THREE.GLTFLoader = ( function () {
 		WEIGHT: 'skinWeight', // deprecated
 		JOINTS_0: 'skinIndex',
 		JOINT: 'skinIndex' // deprecated
-	}
+	};
 
 	var PATH_PROPERTIES = {
 		scale: 'scale',
@@ -1214,7 +1214,7 @@ THREE.GLTFLoader = ( function () {
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
 	 *
-	 * @param {THREE.Geometry} geometry
+	 * @param {THREE.BufferGeometry} geometry
 	 * @param {Array<GLTF.Target>} targets
 	 * @param {Array<THREE.BufferAttribute>} accessors
 	 */
@@ -1533,7 +1533,7 @@ THREE.GLTFLoader = ( function () {
 		// BufferGeometry caching
 		this.primitiveCache = [];
 		this.multiplePrimitivesCache = [];
-		this.multiPassGeometryCache = []
+		this.multiPassGeometryCache = [];
 
 		this.textureLoader = new THREE.TextureLoader( this.options.manager );
 		this.textureLoader.setCrossOrigin( this.options.crossOrigin );
@@ -2178,7 +2178,7 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
-		if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
+		if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {
 
 			pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) );
 
@@ -2192,7 +2192,7 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
-		if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
+		if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {
 
 			pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) );
 
@@ -2204,13 +2204,13 @@ THREE.GLTFLoader = ( function () {
 
 		}
 
-		if ( materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial) {
+		if ( materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial ) {
 
 			materialParams.emissive = new THREE.Color().fromArray( materialDef.emissiveFactor );
 
 		}
 
-		if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
+		if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {
 
 			pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) );
 
@@ -2240,9 +2240,10 @@ THREE.GLTFLoader = ( function () {
 
 			}
 
-			// emissiveTexture and baseColorTexture use sRGB encoding.
+			// baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding.
 			if ( material.map ) material.map.encoding = THREE.sRGBEncoding;
 			if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding;
+			if ( material.specularMap ) material.specularMap.encoding = THREE.sRGBEncoding;
 
 			if ( materialDef.extras ) material.userData = materialDef.extras;
 
@@ -2269,7 +2270,7 @@ THREE.GLTFLoader = ( function () {
 			var bufferAttribute = accessors[ attributes[ gltfAttributeName ] ];
 
 			// Skip attributes already provided by e.g. Draco extension.
-			if ( !threeAttributeName ) continue;
+			if ( ! threeAttributeName ) continue;
 			if ( threeAttributeName in geometry.attributes ) continue;
 
 			geometry.addAttribute( threeAttributeName, bufferAttribute );
@@ -2507,7 +2508,7 @@ THREE.GLTFLoader = ( function () {
 
 					var mesh;
 
-					var material = isMultiMaterial ? originalMaterials : originalMaterials[ i ]
+					var material = isMultiMaterial ? originalMaterials : originalMaterials[ i ];
 
 					if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||
 						primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||
@@ -2591,7 +2592,7 @@ THREE.GLTFLoader = ( function () {
 								THREE.Material.prototype.copy.call( pointsMaterial, material );
 								pointsMaterial.color.copy( material.color );
 								pointsMaterial.map = material.map;
-								pointsMaterial.lights = false;  // PointsMaterial doesn't support lights yet
+								pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
 
 								scope.cache.add( cacheKey, pointsMaterial );
 
@@ -2610,7 +2611,7 @@ THREE.GLTFLoader = ( function () {
 								lineMaterial = new THREE.LineBasicMaterial();
 								THREE.Material.prototype.copy.call( lineMaterial, material );
 								lineMaterial.color.copy( material.color );
-								lineMaterial.lights = false;  // LineBasicMaterial doesn't support lights yet
+								lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet
 
 								scope.cache.add( cacheKey, lineMaterial );
 
@@ -2637,8 +2638,8 @@ THREE.GLTFLoader = ( function () {
 							if ( ! cachedMaterial ) {
 
 								cachedMaterial = material.isGLTFSpecularGlossinessMaterial
-										? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
-										: material.clone();
+									? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
+									: material.clone();
 
 								if ( useSkinning ) cachedMaterial.skinning = true;
 								if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors;

+ 199 - 131
examples/js/loaders/MD2Loader.js

@@ -28,88 +28,88 @@ THREE.MD2Loader.prototype = {
 
 	parse: ( function () {
 
-		var normals = [
-			[ -0.525731,  0.000000,  0.850651 ], [ -0.442863,  0.238856,  0.864188 ],
-			[ -0.295242,  0.000000,  0.955423 ], [ -0.309017,  0.500000,  0.809017 ],
-			[ -0.162460,  0.262866,  0.951056 ], [  0.000000,  0.000000,  1.000000 ],
-			[  0.000000,  0.850651,  0.525731 ], [ -0.147621,  0.716567,  0.681718 ],
-			[  0.147621,  0.716567,  0.681718 ], [  0.000000,  0.525731,  0.850651 ],
-			[  0.309017,  0.500000,  0.809017 ], [  0.525731,  0.000000,  0.850651 ],
-			[  0.295242,  0.000000,  0.955423 ], [  0.442863,  0.238856,  0.864188 ],
-			[  0.162460,  0.262866,  0.951056 ], [ -0.681718,  0.147621,  0.716567 ],
-			[ -0.809017,  0.309017,  0.500000 ], [ -0.587785,  0.425325,  0.688191 ],
-			[ -0.850651,  0.525731,  0.000000 ], [ -0.864188,  0.442863,  0.238856 ],
-			[ -0.716567,  0.681718,  0.147621 ], [ -0.688191,  0.587785,  0.425325 ],
-			[ -0.500000,  0.809017,  0.309017 ], [ -0.238856,  0.864188,  0.442863 ],
-			[ -0.425325,  0.688191,  0.587785 ], [ -0.716567,  0.681718, -0.147621 ],
-			[ -0.500000,  0.809017, -0.309017 ], [ -0.525731,  0.850651,  0.000000 ],
-			[  0.000000,  0.850651, -0.525731 ], [ -0.238856,  0.864188, -0.442863 ],
-			[  0.000000,  0.955423, -0.295242 ], [ -0.262866,  0.951056, -0.162460 ],
-			[  0.000000,  1.000000,  0.000000 ], [  0.000000,  0.955423,  0.295242 ],
-			[ -0.262866,  0.951056,  0.162460 ], [  0.238856,  0.864188,  0.442863 ],
-			[  0.262866,  0.951056,  0.162460 ], [  0.500000,  0.809017,  0.309017 ],
-			[  0.238856,  0.864188, -0.442863 ], [  0.262866,  0.951056, -0.162460 ],
-			[  0.500000,  0.809017, -0.309017 ], [  0.850651,  0.525731,  0.000000 ],
-			[  0.716567,  0.681718,  0.147621 ], [  0.716567,  0.681718, -0.147621 ],
-			[  0.525731,  0.850651,  0.000000 ], [  0.425325,  0.688191,  0.587785 ],
-			[  0.864188,  0.442863,  0.238856 ], [  0.688191,  0.587785,  0.425325 ],
-			[  0.809017,  0.309017,  0.500000 ], [  0.681718,  0.147621,  0.716567 ],
-			[  0.587785,  0.425325,  0.688191 ], [  0.955423,  0.295242,  0.000000 ],
-			[  1.000000,  0.000000,  0.000000 ], [  0.951056,  0.162460,  0.262866 ],
-			[  0.850651, -0.525731,  0.000000 ], [  0.955423, -0.295242,  0.000000 ],
-			[  0.864188, -0.442863,  0.238856 ], [  0.951056, -0.162460,  0.262866 ],
-			[  0.809017, -0.309017,  0.500000 ], [  0.681718, -0.147621,  0.716567 ],
-			[  0.850651,  0.000000,  0.525731 ], [  0.864188,  0.442863, -0.238856 ],
-			[  0.809017,  0.309017, -0.500000 ], [  0.951056,  0.162460, -0.262866 ],
-			[  0.525731,  0.000000, -0.850651 ], [  0.681718,  0.147621, -0.716567 ],
-			[  0.681718, -0.147621, -0.716567 ], [  0.850651,  0.000000, -0.525731 ],
-			[  0.809017, -0.309017, -0.500000 ], [  0.864188, -0.442863, -0.238856 ],
-			[  0.951056, -0.162460, -0.262866 ], [  0.147621,  0.716567, -0.681718 ],
-			[  0.309017,  0.500000, -0.809017 ], [  0.425325,  0.688191, -0.587785 ],
-			[  0.442863,  0.238856, -0.864188 ], [  0.587785,  0.425325, -0.688191 ],
-			[  0.688191,  0.587785, -0.425325 ], [ -0.147621,  0.716567, -0.681718 ],
-			[ -0.309017,  0.500000, -0.809017 ], [  0.000000,  0.525731, -0.850651 ],
-			[ -0.525731,  0.000000, -0.850651 ], [ -0.442863,  0.238856, -0.864188 ],
-			[ -0.295242,  0.000000, -0.955423 ], [ -0.162460,  0.262866, -0.951056 ],
-			[  0.000000,  0.000000, -1.000000 ], [  0.295242,  0.000000, -0.955423 ],
-			[  0.162460,  0.262866, -0.951056 ], [ -0.442863, -0.238856, -0.864188 ],
-			[ -0.309017, -0.500000, -0.809017 ], [ -0.162460, -0.262866, -0.951056 ],
-			[  0.000000, -0.850651, -0.525731 ], [ -0.147621, -0.716567, -0.681718 ],
-			[  0.147621, -0.716567, -0.681718 ], [  0.000000, -0.525731, -0.850651 ],
-			[  0.309017, -0.500000, -0.809017 ], [  0.442863, -0.238856, -0.864188 ],
-			[  0.162460, -0.262866, -0.951056 ], [  0.238856, -0.864188, -0.442863 ],
-			[  0.500000, -0.809017, -0.309017 ], [  0.425325, -0.688191, -0.587785 ],
-			[  0.716567, -0.681718, -0.147621 ], [  0.688191, -0.587785, -0.425325 ],
-			[  0.587785, -0.425325, -0.688191 ], [  0.000000, -0.955423, -0.295242 ],
-			[  0.000000, -1.000000,  0.000000 ], [  0.262866, -0.951056, -0.162460 ],
-			[  0.000000, -0.850651,  0.525731 ], [  0.000000, -0.955423,  0.295242 ],
-			[  0.238856, -0.864188,  0.442863 ], [  0.262866, -0.951056,  0.162460 ],
-			[  0.500000, -0.809017,  0.309017 ], [  0.716567, -0.681718,  0.147621 ],
-			[  0.525731, -0.850651,  0.000000 ], [ -0.238856, -0.864188, -0.442863 ],
-			[ -0.500000, -0.809017, -0.309017 ], [ -0.262866, -0.951056, -0.162460 ],
-			[ -0.850651, -0.525731,  0.000000 ], [ -0.716567, -0.681718, -0.147621 ],
-			[ -0.716567, -0.681718,  0.147621 ], [ -0.525731, -0.850651,  0.000000 ],
-			[ -0.500000, -0.809017,  0.309017 ], [ -0.238856, -0.864188,  0.442863 ],
-			[ -0.262866, -0.951056,  0.162460 ], [ -0.864188, -0.442863,  0.238856 ],
-			[ -0.809017, -0.309017,  0.500000 ], [ -0.688191, -0.587785,  0.425325 ],
-			[ -0.681718, -0.147621,  0.716567 ], [ -0.442863, -0.238856,  0.864188 ],
-			[ -0.587785, -0.425325,  0.688191 ], [ -0.309017, -0.500000,  0.809017 ],
-			[ -0.147621, -0.716567,  0.681718 ], [ -0.425325, -0.688191,  0.587785 ],
-			[ -0.162460, -0.262866,  0.951056 ], [  0.442863, -0.238856,  0.864188 ],
-			[  0.162460, -0.262866,  0.951056 ], [  0.309017, -0.500000,  0.809017 ],
-			[  0.147621, -0.716567,  0.681718 ], [  0.000000, -0.525731,  0.850651 ],
-			[  0.425325, -0.688191,  0.587785 ], [  0.587785, -0.425325,  0.688191 ],
-			[  0.688191, -0.587785,  0.425325 ], [ -0.955423,  0.295242,  0.000000 ],
-			[ -0.951056,  0.162460,  0.262866 ], [ -1.000000,  0.000000,  0.000000 ],
-			[ -0.850651,  0.000000,  0.525731 ], [ -0.955423, -0.295242,  0.000000 ],
-			[ -0.951056, -0.162460,  0.262866 ], [ -0.864188,  0.442863, -0.238856 ],
-			[ -0.951056,  0.162460, -0.262866 ], [ -0.809017,  0.309017, -0.500000 ],
-			[ -0.864188, -0.442863, -0.238856 ], [ -0.951056, -0.162460, -0.262866 ],
-			[ -0.809017, -0.309017, -0.500000 ], [ -0.681718,  0.147621, -0.716567 ],
-			[ -0.681718, -0.147621, -0.716567 ], [ -0.850651,  0.000000, -0.525731 ],
-			[ -0.688191,  0.587785, -0.425325 ], [ -0.587785,  0.425325, -0.688191 ],
-			[ -0.425325,  0.688191, -0.587785 ], [ -0.425325, -0.688191, -0.587785 ],
-			[ -0.587785, -0.425325, -0.688191 ], [ -0.688191, -0.587785, -0.425325 ]
+		var normalData = [
+			[ - 0.525731, 0.000000, 0.850651 ], [ - 0.442863, 0.238856, 0.864188 ],
+			[ - 0.295242, 0.000000, 0.955423 ], [ - 0.309017, 0.500000, 0.809017 ],
+			[ - 0.162460, 0.262866, 0.951056 ], [ 0.000000, 0.000000, 1.000000 ],
+			[ 0.000000, 0.850651, 0.525731 ], [ - 0.147621, 0.716567, 0.681718 ],
+			[ 0.147621, 0.716567, 0.681718 ], [ 0.000000, 0.525731, 0.850651 ],
+			[ 0.309017, 0.500000, 0.809017 ], [ 0.525731, 0.000000, 0.850651 ],
+			[ 0.295242, 0.000000, 0.955423 ], [ 0.442863, 0.238856, 0.864188 ],
+			[ 0.162460, 0.262866, 0.951056 ], [ - 0.681718, 0.147621, 0.716567 ],
+			[ - 0.809017, 0.309017, 0.500000 ], [ - 0.587785, 0.425325, 0.688191 ],
+			[ - 0.850651, 0.525731, 0.000000 ], [ - 0.864188, 0.442863, 0.238856 ],
+			[ - 0.716567, 0.681718, 0.147621 ], [ - 0.688191, 0.587785, 0.425325 ],
+			[ - 0.500000, 0.809017, 0.309017 ], [ - 0.238856, 0.864188, 0.442863 ],
+			[ - 0.425325, 0.688191, 0.587785 ], [ - 0.716567, 0.681718, - 0.147621 ],
+			[ - 0.500000, 0.809017, - 0.309017 ], [ - 0.525731, 0.850651, 0.000000 ],
+			[ 0.000000, 0.850651, - 0.525731 ], [ - 0.238856, 0.864188, - 0.442863 ],
+			[ 0.000000, 0.955423, - 0.295242 ], [ - 0.262866, 0.951056, - 0.162460 ],
+			[ 0.000000, 1.000000, 0.000000 ], [ 0.000000, 0.955423, 0.295242 ],
+			[ - 0.262866, 0.951056, 0.162460 ], [ 0.238856, 0.864188, 0.442863 ],
+			[ 0.262866, 0.951056, 0.162460 ], [ 0.500000, 0.809017, 0.309017 ],
+			[ 0.238856, 0.864188, - 0.442863 ], [ 0.262866, 0.951056, - 0.162460 ],
+			[ 0.500000, 0.809017, - 0.309017 ], [ 0.850651, 0.525731, 0.000000 ],
+			[ 0.716567, 0.681718, 0.147621 ], [ 0.716567, 0.681718, - 0.147621 ],
+			[ 0.525731, 0.850651, 0.000000 ], [ 0.425325, 0.688191, 0.587785 ],
+			[ 0.864188, 0.442863, 0.238856 ], [ 0.688191, 0.587785, 0.425325 ],
+			[ 0.809017, 0.309017, 0.500000 ], [ 0.681718, 0.147621, 0.716567 ],
+			[ 0.587785, 0.425325, 0.688191 ], [ 0.955423, 0.295242, 0.000000 ],
+			[ 1.000000, 0.000000, 0.000000 ], [ 0.951056, 0.162460, 0.262866 ],
+			[ 0.850651, - 0.525731, 0.000000 ], [ 0.955423, - 0.295242, 0.000000 ],
+			[ 0.864188, - 0.442863, 0.238856 ], [ 0.951056, - 0.162460, 0.262866 ],
+			[ 0.809017, - 0.309017, 0.500000 ], [ 0.681718, - 0.147621, 0.716567 ],
+			[ 0.850651, 0.000000, 0.525731 ], [ 0.864188, 0.442863, - 0.238856 ],
+			[ 0.809017, 0.309017, - 0.500000 ], [ 0.951056, 0.162460, - 0.262866 ],
+			[ 0.525731, 0.000000, - 0.850651 ], [ 0.681718, 0.147621, - 0.716567 ],
+			[ 0.681718, - 0.147621, - 0.716567 ], [ 0.850651, 0.000000, - 0.525731 ],
+			[ 0.809017, - 0.309017, - 0.500000 ], [ 0.864188, - 0.442863, - 0.238856 ],
+			[ 0.951056, - 0.162460, - 0.262866 ], [ 0.147621, 0.716567, - 0.681718 ],
+			[ 0.309017, 0.500000, - 0.809017 ], [ 0.425325, 0.688191, - 0.587785 ],
+			[ 0.442863, 0.238856, - 0.864188 ], [ 0.587785, 0.425325, - 0.688191 ],
+			[ 0.688191, 0.587785, - 0.425325 ], [ - 0.147621, 0.716567, - 0.681718 ],
+			[ - 0.309017, 0.500000, - 0.809017 ], [ 0.000000, 0.525731, - 0.850651 ],
+			[ - 0.525731, 0.000000, - 0.850651 ], [ - 0.442863, 0.238856, - 0.864188 ],
+			[ - 0.295242, 0.000000, - 0.955423 ], [ - 0.162460, 0.262866, - 0.951056 ],
+			[ 0.000000, 0.000000, - 1.000000 ], [ 0.295242, 0.000000, - 0.955423 ],
+			[ 0.162460, 0.262866, - 0.951056 ], [ - 0.442863, - 0.238856, - 0.864188 ],
+			[ - 0.309017, - 0.500000, - 0.809017 ], [ - 0.162460, - 0.262866, - 0.951056 ],
+			[ 0.000000, - 0.850651, - 0.525731 ], [ - 0.147621, - 0.716567, - 0.681718 ],
+			[ 0.147621, - 0.716567, - 0.681718 ], [ 0.000000, - 0.525731, - 0.850651 ],
+			[ 0.309017, - 0.500000, - 0.809017 ], [ 0.442863, - 0.238856, - 0.864188 ],
+			[ 0.162460, - 0.262866, - 0.951056 ], [ 0.238856, - 0.864188, - 0.442863 ],
+			[ 0.500000, - 0.809017, - 0.309017 ], [ 0.425325, - 0.688191, - 0.587785 ],
+			[ 0.716567, - 0.681718, - 0.147621 ], [ 0.688191, - 0.587785, - 0.425325 ],
+			[ 0.587785, - 0.425325, - 0.688191 ], [ 0.000000, - 0.955423, - 0.295242 ],
+			[ 0.000000, - 1.000000, 0.000000 ], [ 0.262866, - 0.951056, - 0.162460 ],
+			[ 0.000000, - 0.850651, 0.525731 ], [ 0.000000, - 0.955423, 0.295242 ],
+			[ 0.238856, - 0.864188, 0.442863 ], [ 0.262866, - 0.951056, 0.162460 ],
+			[ 0.500000, - 0.809017, 0.309017 ], [ 0.716567, - 0.681718, 0.147621 ],
+			[ 0.525731, - 0.850651, 0.000000 ], [ - 0.238856, - 0.864188, - 0.442863 ],
+			[ - 0.500000, - 0.809017, - 0.309017 ], [ - 0.262866, - 0.951056, - 0.162460 ],
+			[ - 0.850651, - 0.525731, 0.000000 ], [ - 0.716567, - 0.681718, - 0.147621 ],
+			[ - 0.716567, - 0.681718, 0.147621 ], [ - 0.525731, - 0.850651, 0.000000 ],
+			[ - 0.500000, - 0.809017, 0.309017 ], [ - 0.238856, - 0.864188, 0.442863 ],
+			[ - 0.262866, - 0.951056, 0.162460 ], [ - 0.864188, - 0.442863, 0.238856 ],
+			[ - 0.809017, - 0.309017, 0.500000 ], [ - 0.688191, - 0.587785, 0.425325 ],
+			[ - 0.681718, - 0.147621, 0.716567 ], [ - 0.442863, - 0.238856, 0.864188 ],
+			[ - 0.587785, - 0.425325, 0.688191 ], [ - 0.309017, - 0.500000, 0.809017 ],
+			[ - 0.147621, - 0.716567, 0.681718 ], [ - 0.425325, - 0.688191, 0.587785 ],
+			[ - 0.162460, - 0.262866, 0.951056 ], [ 0.442863, - 0.238856, 0.864188 ],
+			[ 0.162460, - 0.262866, 0.951056 ], [ 0.309017, - 0.500000, 0.809017 ],
+			[ 0.147621, - 0.716567, 0.681718 ], [ 0.000000, - 0.525731, 0.850651 ],
+			[ 0.425325, - 0.688191, 0.587785 ], [ 0.587785, - 0.425325, 0.688191 ],
+			[ 0.688191, - 0.587785, 0.425325 ], [ - 0.955423, 0.295242, 0.000000 ],
+			[ - 0.951056, 0.162460, 0.262866 ], [ - 1.000000, 0.000000, 0.000000 ],
+			[ - 0.850651, 0.000000, 0.525731 ], [ - 0.955423, - 0.295242, 0.000000 ],
+			[ - 0.951056, - 0.162460, 0.262866 ], [ - 0.864188, 0.442863, - 0.238856 ],
+			[ - 0.951056, 0.162460, - 0.262866 ], [ - 0.809017, 0.309017, - 0.500000 ],
+			[ - 0.864188, - 0.442863, - 0.238856 ], [ - 0.951056, - 0.162460, - 0.262866 ],
+			[ - 0.809017, - 0.309017, - 0.500000 ], [ - 0.681718, 0.147621, - 0.716567 ],
+			[ - 0.681718, - 0.147621, - 0.716567 ], [ - 0.850651, 0.000000, - 0.525731 ],
+			[ - 0.688191, 0.587785, - 0.425325 ], [ - 0.587785, 0.425325, - 0.688191 ],
+			[ - 0.425325, 0.688191, - 0.587785 ], [ - 0.425325, - 0.688191, - 0.587785 ],
+			[ - 0.587785, - 0.425325, - 0.688191 ], [ - 0.688191, - 0.587785, - 0.425325 ]
 		];
 
 		return function ( buffer ) {
@@ -151,11 +151,11 @@ THREE.MD2Loader.prototype = {
 
 			//
 
-			var geometry = new THREE.Geometry();
+			var geometry = new THREE.BufferGeometry();
 
 			// uvs
 
-			var uvs = [];
+			var uvsTemp = [];
 			var offset = header.offset_st;
 
 			for ( var i = 0, l = header.num_st; i < l; i ++ ) {
@@ -163,7 +163,7 @@ THREE.MD2Loader.prototype = {
 				var u = data.getInt16( offset + 0, true );
 				var v = data.getInt16( offset + 2, true );
 
-				uvs.push( new THREE.Vector2( u / header.skinwidth, 1 - ( v / header.skinheight ) ) );
+				uvsTemp.push( u / header.skinwidth, 1 - ( v / header.skinheight ) );
 
 				offset += 4;
 
@@ -171,21 +171,24 @@ THREE.MD2Loader.prototype = {
 
 			// triangles
 
-			var offset = header.offset_tris;
+			offset = header.offset_tris;
 
-			for ( var i = 0, l = header.num_tris; i < l; i ++ ) {
+			var vertexIndices = [];
+			var uvIndices = [];
 
-				var a = data.getUint16( offset + 0, true );
-				var b = data.getUint16( offset + 2, true );
-				var c = data.getUint16( offset + 4, true );
+			for ( var i = 0, l = header.num_tris; i < l; i ++ ) {
 
-				geometry.faces.push( new THREE.Face3( a, b, c ) );
+				vertexIndices.push(
+					data.getUint16( offset + 0, true ),
+					data.getUint16( offset + 2, true ),
+					data.getUint16( offset + 4, true )
+				);
 
-				geometry.faceVertexUvs[ 0 ].push( [
-					uvs[ data.getUint16( offset + 6, true ) ],
-					uvs[ data.getUint16( offset + 8, true ) ],
-					uvs[ data.getUint16( offset + 10, true ) ]
-				] );
+				uvIndices.push(
+					data.getUint16( offset + 6, true ),
+					data.getUint16( offset + 8, true ),
+					data.getUint16( offset + 10, true )
+				);
 
 				offset += 12;
 
@@ -197,7 +200,9 @@ THREE.MD2Loader.prototype = {
 			var scale = new THREE.Vector3();
 			var string = [];
 
-			var offset = header.offset_frames;
+			var frames = [];
+
+			offset = header.offset_frames;
 
 			for ( var i = 0, l = header.num_frames; i < l; i ++ ) {
 
@@ -237,68 +242,131 @@ THREE.MD2Loader.prototype = {
 					var x = data.getUint8( offset ++, true );
 					var y = data.getUint8( offset ++, true );
 					var z = data.getUint8( offset ++, true );
-					var n = normals[ data.getUint8( offset ++, true ) ];
-
-					var vertex = new THREE.Vector3(
-						x * scale.x + translation.x,
-						z * scale.z + translation.z,
-						y * scale.y + translation.y
-					);
+					var n = normalData[ data.getUint8( offset ++, true ) ];
 
-					var normal = new THREE.Vector3( n[ 0 ], n[ 2 ], n[ 1 ] );
+					x = x * scale.x + translation.x;
+					y = y * scale.y + translation.y;
+					z = z * scale.z + translation.z;
 
-					frame.vertices.push( vertex );
-					frame.normals.push( normal );
+					frame.vertices.push( x, z, y ); // convert to Y-up
+					frame.normals.push( n[ 0 ], n[ 2 ], n[ 1 ] ); // convert to Y-up
 
 				}
 
-				geometry.morphTargets.push( frame );
+				frames.push( frame );
 
 			}
 
-			// Static
+			// static
+
+			var positions = [];
+			var normals = [];
+			var uvs = [];
+
+			var verticesTemp = frames[ 0 ].vertices;
+			var normalsTemp = frames[ 0 ].normals;
+
+			for ( var i = 0, l = vertexIndices.length; i < l; i ++ ) {
+
+				var vertexIndex = vertexIndices[ i ];
+				var stride = vertexIndex * 3;
+
+				//
+
+				var x = verticesTemp[ stride ];
+				var y = verticesTemp[ stride + 1 ];
+				var z = verticesTemp[ stride + 2 ];
 
-			geometry.vertices = geometry.morphTargets[ 0 ].vertices;
+				positions.push( x, y, z );
 
-			var morphTarget = geometry.morphTargets[ 0 ];
+				//
 
-			for ( var j = 0, jl = geometry.faces.length; j < jl; j ++ ) {
+				var nx = normalsTemp[ stride ];
+				var ny = normalsTemp[ stride + 1 ];
+				var nz = normalsTemp[ stride + 2 ];
 
-				var face = geometry.faces[ j ];
+				normals.push( nx, ny, nz );
 
-				face.vertexNormals = [
-					morphTarget.normals[ face.a ],
-					morphTarget.normals[ face.b ],
-					morphTarget.normals[ face.c ]
-				];
+				//
+
+				var uvIndex = uvIndices[ i ];
+				stride = uvIndex * 2;
+
+				var u = uvsTemp[ stride ];
+				var v = uvsTemp[ stride + 1 ];
+
+				uvs.push( u, v );
 
 			}
 
+			geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
+			geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
+			geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
+
+			// animation
 
-			// Convert to geometry.morphNormals
+			var morphPositions = [];
+			var morphNormals = [];
 
-			for ( var i = 0, l = geometry.morphTargets.length; i < l; i ++ ) {
+			for ( var i = 0, l = frames.length; i < l; i ++ ) {
 
-				var morphTarget = geometry.morphTargets[ i ];
-				var vertexNormals = [];
+				var frame = frames[ i ];
+				var attributeName = frame.name;
 
-				for ( var j = 0, jl = geometry.faces.length; j < jl; j ++ ) {
+				if ( frame.vertices.length > 0 ) {
 
-					var face = geometry.faces[ j ];
+					var positions = [];
 
-					vertexNormals.push( {
-						a: morphTarget.normals[ face.a ],
-						b: morphTarget.normals[ face.b ],
-						c: morphTarget.normals[ face.c ]
-					} );
+					for ( var j = 0, jl = vertexIndices.length; j < jl; j ++ ) {
+
+						var vertexIndex = vertexIndices[ j ];
+						var stride = vertexIndex * 3;
+
+						var x = frame.vertices[ stride ];
+						var y = frame.vertices[ stride + 1 ];
+						var z = frame.vertices[ stride + 2 ];
+
+						positions.push( x, y, z );
+
+					}
+
+					var positionAttribute = new THREE.Float32BufferAttribute( positions, 3 );
+					positionAttribute.name = attributeName;
+
+					morphPositions.push( positionAttribute );
 
 				}
 
-				geometry.morphNormals.push( { vertexNormals: vertexNormals } );
+				if ( frame.normals.length > 0 ) {
+
+					var normals = [];
+
+					for ( var j = 0, jl = vertexIndices.length; j < jl; j ++ ) {
+
+						var vertexIndex = vertexIndices[ j ];
+						var stride = vertexIndex * 3;
+
+						var nx = frame.normals[ stride ];
+						var ny = frame.normals[ stride + 1 ];
+						var nz = frame.normals[ stride + 2 ];
+
+						normals.push( nx, ny, nz );
+
+					}
+
+					var normalAttribute = new THREE.Float32BufferAttribute( normals, 3 );
+					normalAttribute.name = attributeName;
+
+					morphNormals.push( normalAttribute );
+
+				}
 
 			}
 
-			geometry.animations = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
+			geometry.morphAttributes.position = morphPositions;
+			geometry.morphAttributes.normal = morphNormals;
+
+			geometry.animations = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( frames, 10 );
 
 			console.timeEnd( 'MD2Loader' );
 

+ 8 - 7
examples/js/loaders/MMDLoader.js

@@ -841,13 +841,14 @@ THREE.MMDLoader = ( function () {
 			geometry.morphTargets = morphTargets;
 			geometry.morphAttributes.position = morphPositions;
 
-			geometry.iks = iks;
-			geometry.grants = grants;
-
-			geometry.rigidBodies = rigidBodies;
-			geometry.constraints = constraints;
-
-			geometry.mmdFormat = data.metadata.format;
+			geometry.userData.MMD = {
+				bones: bones,
+				iks: iks,
+				grants: grants,
+				rigidBodies: rigidBodies,
+				constraints: constraints,
+				format: data.metadata.format
+			};
 
 			geometry.computeBoundingSphere();
 

+ 21 - 69
examples/js/loaders/TDSLoader.js

@@ -1,5 +1,5 @@
 /*
- * Autodesk 3DS threee.js file loader, based on lib3ds.
+ * Autodesk 3DS three.js file loader, based on lib3ds.
  *
  * Loads geometry with uv and materials basic properties with texture support.
  *
@@ -321,20 +321,9 @@ THREE.TDSLoader.prototype = {
 		var chunk = this.readChunk( data );
 		var next = this.nextChunk( data, chunk );
 
-		var useBufferGeometry = false;
-		var geometry = null;
+		var geometry = new THREE.BufferGeometry();
 		var uvs = [];
 
-		if ( useBufferGeometry ) {
-
-			geometry = new THREE.BufferGeometry();
-
-		}	else {
-
-			geometry = new THREE.Geometry();
-
-		}
-
 		var material = new THREE.MeshPhongMaterial();
 		var mesh = new THREE.Mesh( geometry, material );
 		mesh.name = 'mesh';
@@ -349,29 +338,18 @@ THREE.TDSLoader.prototype = {
 
 				//BufferGeometry
 
-				if ( useBufferGeometry )	{
-
-					var vertices = [];
-					for ( var i = 0; i < points; i ++ )		{
-
-						vertices.push( this.readFloat( data ) );
-						vertices.push( this.readFloat( data ) );
-						vertices.push( this.readFloat( data ) );
-
-					}
-
-					geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
-
-				} else	{ //Geometry
+				var vertices = [];
 
-					for ( var i = 0; i < points; i ++ )		{
+				for ( var i = 0; i < points; i ++ )		{
 
-						geometry.vertices.push( new THREE.Vector3( this.readFloat( data ), this.readFloat( data ), this.readFloat( data ) ) );
-
-					}
+					vertices.push( this.readFloat( data ) );
+					vertices.push( this.readFloat( data ) );
+					vertices.push( this.readFloat( data ) );
 
 				}
 
+				geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
+
 			} else if ( next === FACE_ARRAY ) {
 
 				this.resetPosition( data );
@@ -385,27 +363,17 @@ THREE.TDSLoader.prototype = {
 
 				//BufferGeometry
 
-				if ( useBufferGeometry )	{
-
-					var uvs = [];
-					for ( var i = 0; i < texels; i ++ )		{
-
-						uvs.push( this.readFloat( data ) );
-						uvs.push( this.readFloat( data ) );
-
-					}
-					geometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( uvs ), 2 ) );
+				var uvs = [];
 
-				} else { //Geometry
+				for ( var i = 0; i < texels; i ++ )		{
 
-					uvs = [];
-					for ( var i = 0; i < texels; i ++ )		{
+					uvs.push( this.readFloat( data ) );
+					uvs.push( this.readFloat( data ) );
 
-						uvs.push( new THREE.Vector2( this.readFloat( data ), this.readFloat( data ) ) );
+				}
 
-					}
+				geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
 
-				}
 
 			} else if ( next === MESH_MATRIX ) {
 
@@ -464,27 +432,7 @@ THREE.TDSLoader.prototype = {
 
 		this.endChunk( chunk );
 
-		if ( ! useBufferGeometry ) {
-
-			//geometry.faceVertexUvs[0][faceIndex][vertexIndex]
-
-			if ( uvs.length > 0 ) {
-
-				var faceUV = [];
-
-				for ( var i = 0; i < geometry.faces.length; i ++ ) {
-
-					faceUV.push( [ uvs[ geometry.faces[ i ].a ], uvs[ geometry.faces[ i ].b ], uvs[ geometry.faces[ i ].c ] ] );
-
-				}
-
-				geometry.faceVertexUvs[ 0 ] = faceUV;
-
-			}
-
-			geometry.computeVertexNormals();
-
-		}
+		geometry.computeVertexNormals();
 
 		return mesh;
 
@@ -504,14 +452,18 @@ THREE.TDSLoader.prototype = {
 
 		this.debugMessage( '   Faces: ' + faces );
 
+		var index = [];
+
 		for ( var i = 0; i < faces; ++ i ) {
 
-			mesh.geometry.faces.push( new THREE.Face3( this.readWord( data ), this.readWord( data ), this.readWord( data ) ) );
+			index.push( this.readWord( data ), this.readWord( data ), this.readWord( data ) );
 
 			var visibility = this.readWord( data );
 
 		}
 
+		mesh.geometry.setIndex( index );
+
 		//The rest of the FACE_ARRAY chunk is subchunks
 
 		while ( this.position < chunk.end ) {

+ 22 - 48
examples/js/loaders/VTKLoader.js

@@ -250,77 +250,51 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 			}
 
-			var geometry;
-			var stagger = 'point';
+			var geometry = new THREE.BufferGeometry();
+			geometry.setIndex( indices );
+			geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
 
-			if ( colors.length === indices.length ) {
+			if ( normals.length === positions.length ) {
 
-				stagger = 'cell';
+				geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
 
 			}
 
-			if ( stagger === 'point' ) {
+			if ( colors.length !== indices.length ) {
 
-				// Nodal. Use BufferGeometry
-				geometry = new THREE.BufferGeometry();
-				geometry.setIndex( new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );
-				geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( positions ), 3 ) );
+				// stagger
 
 				if ( colors.length === positions.length ) {
 
-					geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
-
-				}
-
-				if ( normals.length === positions.length ) {
-
-					geometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
+					geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
 
 				}
 
 			} else {
 
-				// Cell centered colors. The only way to attach a solid color to each triangle
-				// is to use Geometry, which is less efficient than BufferGeometry
-				geometry = new THREE.Geometry();
-
-				var numTriangles = indices.length / 3;
-				var numPoints = positions.length / 3;
-				var face;
-				var ia, ib, ic;
-				var x, y, z;
-				var r, g, b;
+				// cell
 
-				for ( var j = 0; j < numPoints; ++ j ) {
+				geometry = geometry.toNonIndexed();
+				var numTriangles = geometry.attributes.position.count / 3;
 
-					x = positions[ 3 * j + 0 ];
-					y = positions[ 3 * j + 1 ];
-					z = positions[ 3 * j + 2 ];
-					geometry.vertices.push( new THREE.Vector3( x, y, z ) );
+				if ( colors.length === ( numTriangles * 3 ) ) {
 
-				}
-
-				for ( var i = 0; i < numTriangles; ++ i ) {
-
-					ia = indices[ 3 * i + 0 ];
-					ib = indices[ 3 * i + 1 ];
-					ic = indices[ 3 * i + 2 ];
-					geometry.faces.push( new THREE.Face3( ia, ib, ic ) );
+					var newColors = [];
 
-				}
-
-				if ( colors.length === numTriangles * 3 ) {
+					for ( var i = 0; i < numTriangles; i ++ ) {
 
-					for ( var i = 0; i < numTriangles; ++ i ) {
+						var r = colors[ 3 * i + 0 ];
+						var g = colors[ 3 * i + 1 ];
+						var b = colors[ 3 * i + 2 ];
 
-						face = geometry.faces[ i ];
-						r = colors[ 3 * i + 0 ];
-						g = colors[ 3 * i + 1 ];
-						b = colors[ 3 * i + 2 ];
-						face.color = new THREE.Color().setRGB( r, g, b );
+						newColors.push( r, g, b );
+						newColors.push( r, g, b );
+						newColors.push( r, g, b );
 
 					}
 
+					geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( newColors, 3 ) );
+
 				}
 
 			}

+ 7 - 2
examples/js/loaders/XLoader.js

@@ -1,3 +1,8 @@
+/**
+ * @author adrs2002 / https://github.com/adrs2002
+ */
+
+
 ( function ( global, factory ) {
 
 	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
@@ -203,13 +208,13 @@
 
 	var XLoader = function () {
 
-		function XLoader( manager, texloader ) {
+		function XLoader( manager ) {
 
 			classCallCheck( this, XLoader );
 
 			this.debug = false;
 			this.manager = manager !== undefined ? manager : new THREE.DefaultLoadingManager();
-			this.texloader = texloader !== undefined ? texloader : new THREE.TextureLoader();
+			this.texloader = new THREE.TextureLoader( this.manager );
 			this.url = "";
 			this.baseDir = "";
 			this._putMatLength = 0;

+ 96 - 63
examples/js/modifiers/SimplifyModifier.js

@@ -8,24 +8,22 @@
  *    - http://www.melax.com/polychop/
  */
 
-THREE.SimplifyModifier = function() {
+THREE.SimplifyModifier = function () {};
 
-};
-
-(function() {
+( function () {
 
 	var cb = new THREE.Vector3(), ab = new THREE.Vector3();
 
 	function pushIfUnique( array, object ) {
 
-		if ( array.indexOf( object ) === -1 ) array.push( object );
+		if ( array.indexOf( object ) === - 1 ) array.push( object );
 
 	}
 
 	function removeFromArray( array, object ) {
 
 		var k = array.indexOf( object );
-		if ( k > -1 ) array.splice( k, 1 );
+		if ( k > - 1 ) array.splice( k, 1 );
 
 	}
 
@@ -38,14 +36,14 @@ THREE.SimplifyModifier = function() {
 		var curvature = 0;
 
 		var sideFaces = [];
-		var i, uFaces = u.faces, il = u.faces.length, face, sideFace;
+		var i, il = u.faces.length, face, sideFace;
 
 		// find the "sides" triangles that are on the edge uv
-		for ( i = 0 ; i < il; i ++ ) {
+		for ( i = 0; i < il; i ++ ) {
 
 			face = u.faces[ i ];
 
-			if ( face.hasVertex(v) ) {
+			if ( face.hasVertex( v ) ) {
 
 				sideFaces.push( face );
 
@@ -55,20 +53,22 @@ THREE.SimplifyModifier = function() {
 
 		// use the triangle facing most away from the sides
 		// to determine our curvature term
-		for ( i = 0 ; i < il; i ++ ) {
+		for ( i = 0; i < il; i ++ ) {
 
 			var minCurvature = 1;
 			face = u.faces[ i ];
 
-			for( var j = 0; j < sideFaces.length; j ++ ) {
+			for ( var j = 0; j < sideFaces.length; j ++ ) {
 
 				sideFace = sideFaces[ j ];
 				// use dot product of face normals.
 				var dotProd = face.normal.dot( sideFace.normal );
-				minCurvature = Math.min( minCurvature, ( 1.001 - dotProd ) / 2);
+				minCurvature = Math.min( minCurvature, ( 1.001 - dotProd ) / 2 );
+
 			}
 
 			curvature = Math.max( curvature, minCurvature );
+
 		}
 
 		// crude approach in attempt to preserve borders
@@ -79,6 +79,7 @@ THREE.SimplifyModifier = function() {
 			// we add some arbitrary cost for borders,
 			// borders += 10;
 			curvature = 1;
+
 		}
 
 		var amt = edgelength * curvature + borders;
@@ -88,6 +89,7 @@ THREE.SimplifyModifier = function() {
 	}
 
 	function computeEdgeCostAtVertex( v ) {
+
 		// compute the edge collapse cost for all edges that start
 		// from vertex v.  Since we are only interested in reducing
 		// the object by selecting the min cost edge at each step, we
@@ -113,12 +115,14 @@ THREE.SimplifyModifier = function() {
 
 			var collapseCost = computeEdgeCollapseCost( v, v.neighbors[ i ] );
 
-			if ( !v.collapseNeighbor ) {
+			if ( ! v.collapseNeighbor ) {
+
 				v.collapseNeighbor = v.neighbors[ i ];
 				v.collapseCost = collapseCost;
 				v.minCost = collapseCost;
 				v.totalCost = 0;
 				v.costCount = 0;
+
 			}
 
 			v.costCount ++;
@@ -166,13 +170,16 @@ THREE.SimplifyModifier = function() {
 		var vs = [ this.v1, this.v2, this.v3 ];
 		var v1, v2;
 
-		for( var i = 0 ; i < 3 ; i ++ ) {
+		for ( var i = 0; i < 3; i ++ ) {
+
 			v1 = vs[ i ];
-			v2 = vs[( i+1) % 3 ];
+			v2 = vs[ ( i + 1 ) % 3 ];
+
+			if ( ! v1 || ! v2 ) continue;
 
-			if( !v1 || !v2 ) continue;
 			v1.removeIfNonNeighbor( v2 );
 			v2.removeIfNonNeighbor( v1 );
+
 		}
 
 	}
@@ -181,7 +188,7 @@ THREE.SimplifyModifier = function() {
 
 		// Collapse the edge uv by moving vertex u onto v
 
-		if ( !v ) {
+		if ( ! v ) {
 
 			// u is a vertex all by itself so just delete it..
 			removeVertex( u, vertices );
@@ -192,7 +199,7 @@ THREE.SimplifyModifier = function() {
 		var i;
 		var tmpVertices = [];
 
-		for( i = 0 ; i < u.neighbors.length; i ++ ) {
+		for ( i = 0; i < u.neighbors.length; i ++ ) {
 
 			tmpVertices.push( u.neighbors[ i ] );
 
@@ -200,7 +207,7 @@ THREE.SimplifyModifier = function() {
 
 
 		// delete triangles on edge uv:
-		for( i = u.faces.length - 1; i >= 0; i -- ) {
+		for ( i = u.faces.length - 1; i >= 0; i -- ) {
 
 			if ( u.faces[ i ].hasVertex( v ) ) {
 
@@ -211,9 +218,9 @@ THREE.SimplifyModifier = function() {
 		}
 
 		// update remaining triangles to have v instead of u
-		for( i = u.faces.length -1 ; i >= 0; i -- ) {
+		for ( i = u.faces.length - 1; i >= 0; i -- ) {
 
-			u.faces[i].replaceVertex( u, v );
+			u.faces[ i ].replaceVertex( u, v );
 
 		}
 
@@ -221,7 +228,7 @@ THREE.SimplifyModifier = function() {
 		removeVertex( u, vertices );
 
 		// recompute the edge collapse costs in neighborhood
-		for( i = 0; i < tmpVertices.length; i ++ ) {
+		for ( i = 0; i < tmpVertices.length; i ++ ) {
 
 			computeEdgeCostAtVertex( tmpVertices[ i ] );
 
@@ -237,13 +244,14 @@ THREE.SimplifyModifier = function() {
 
 		var least = vertices[ 0 ];
 
-		for (var i = 0; i < vertices.length; i ++ ) {
+		for ( var i = 0; i < vertices.length; i ++ ) {
 
 			if ( vertices[ i ].collapseCost < least.collapseCost ) {
 
 				least = vertices[ i ];
 
 			}
+
 		}
 
 		return least;
@@ -253,6 +261,7 @@ THREE.SimplifyModifier = function() {
 	// we use a triangle class to represent structure of face slightly differently
 
 	function Triangle( v1, v2, v3, a, b, c ) {
+
 		this.a = a;
 		this.b = b;
 		this.c = c;
@@ -280,7 +289,7 @@ THREE.SimplifyModifier = function() {
 
 	}
 
-	Triangle.prototype.computeNormal = function() {
+	Triangle.prototype.computeNormal = function () {
 
 		var vA = this.v1.position;
 		var vB = this.v2.position;
@@ -294,13 +303,13 @@ THREE.SimplifyModifier = function() {
 
 	};
 
-	Triangle.prototype.hasVertex = function( v ) {
+	Triangle.prototype.hasVertex = function ( v ) {
 
 		return v === this.v1 || v === this.v2 || v === this.v3;
 
 	};
 
-	Triangle.prototype.replaceVertex = function( oldv, newv ) {
+	Triangle.prototype.replaceVertex = function ( oldv, newv ) {
 
 		if ( oldv === this.v1 ) this.v1 = newv;
 		else if ( oldv === this.v2 ) this.v2 = newv;
@@ -347,17 +356,19 @@ THREE.SimplifyModifier = function() {
 
 	}
 
-	Vertex.prototype.addUniqueNeighbor = function( vertex ) {
-		pushIfUnique(this.neighbors, vertex);
+	Vertex.prototype.addUniqueNeighbor = function ( vertex ) {
+
+		pushIfUnique( this.neighbors, vertex );
+
 	};
 
-	Vertex.prototype.removeIfNonNeighbor = function( n ) {
+	Vertex.prototype.removeIfNonNeighbor = function ( n ) {
 
 		var neighbors = this.neighbors;
 		var faces = this.faces;
 
 		var offset = neighbors.indexOf( n );
-		if ( offset === -1 ) return;
+		if ( offset === - 1 ) return;
 		for ( var i = 0; i < faces.length; i ++ ) {
 
 			if ( faces[ i ].hasVertex( n ) ) return;
@@ -365,13 +376,15 @@ THREE.SimplifyModifier = function() {
 		}
 
 		neighbors.splice( offset, 1 );
+
 	};
 
-	THREE.SimplifyModifier.prototype.modify = function( geometry, count ) {
+	THREE.SimplifyModifier.prototype.modify = function ( geometry, count ) {
+
+		if ( geometry.isBufferGeometry ) {
 
-		if ( geometry instanceof THREE.BufferGeometry && !geometry.vertices && !geometry.faces ) {
-			console.log('converting BufferGeometry to Geometry');
 			geometry = new THREE.Geometry().fromBufferGeometry( geometry );
+
 		}
 
 		geometry.mergeVertices();
@@ -379,83 +392,103 @@ THREE.SimplifyModifier = function() {
 		var oldVertices = geometry.vertices; // Three Position
 		var oldFaces = geometry.faces; // Three Face
 
-		var newGeometry = new THREE.Geometry();
-
 		// conversion
-		var vertices = new Array( oldVertices.length ); // Simplify Custom Vertex Struct
-		var faces = new Array( oldFaces.length ); // Simplify Custom Traignle Struct
+		var vertices = [];
+		var faces = [];
 
-		var i, il, face;
+		var i, il;
 
 		//
 		// put data of original geometry in different data structures
 		//
 
 		// add vertices
+
 		for ( i = 0, il = oldVertices.length; i < il; i ++ ) {
 
-			vertices[ i ] = new Vertex( oldVertices[ i ], i );
+			var vertex = new Vertex( oldVertices[ i ], i );
+			vertices.push( vertex );
 
 		}
 
 		// add faces
+
 		for ( i = 0, il = oldFaces.length; i < il; i ++ ) {
 
-			face = oldFaces[ i ];
-			faces[ i ] = new Triangle( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ], face.a, face.b, face.c );
+			var face = oldFaces[ i ];
+
+			var a = face.a;
+			var b = face.b;
+			var c = face.c;
+
+			var triangle = new Triangle( vertices[ a ], vertices[ b ], vertices[ c ], a, b, c );
+			faces.push( triangle );
 
 		}
 
 		// compute all edge collapse costs
+
 		for ( i = 0, il = vertices.length; i < il; i ++ ) {
 
 			computeEdgeCostAtVertex( vertices[ i ] );
 
 		}
 
-		var permutation = new Array( vertices.length );
-		var map = new Array( vertices.length );
-
 		var nextVertex;
 
 		var z = count;
 
-		// console.time('z')
-		// console.profile('zz');
+		while ( z -- ) {
 
-		while( z-- ) {
 			nextVertex = minimumCostEdge( vertices );
-			if (!nextVertex) {
-				console.log('no next vertex');
+
+			if ( ! nextVertex ) {
+
+				console.log( 'THREE.SimplifyModifier: No next vertex' );
 				break;
+
 			}
+
 			collapse( vertices, faces, nextVertex, nextVertex.collapseNeighbor );
+
 		}
 
-		// console.profileEnd('zz');
-		// console.timeEnd('z')
+		//
+
+		var simplifiedGeometry = new THREE.BufferGeometry();
+		var position = [];
+		var index = [];
 
-		// TODO convert to buffer geometry.
-		var newGeo = new THREE.Geometry();
+		//
 
 		for ( i = 0; i < vertices.length; i ++ ) {
 
-			var v = vertices[ i ];
-			newGeo.vertices.push( v.position )
+			var vertex = vertices[ i ].position;
+			position.push( vertex.x, vertex.y, vertex.z );
 
 		}
 
+		//
+
 		for ( i = 0; i < faces.length; i ++ ) {
 
-			var tri = faces[ i ];
-			newGeo.faces.push( new THREE.Face3(
-				vertices.indexOf(tri.v1),
-				vertices.indexOf(tri.v2),
-				vertices.indexOf(tri.v3)
-			) )
+			var face = faces[ i ];
+
+			var a = vertices.indexOf( face.v1 );
+			var b = vertices.indexOf( face.v2 );
+			var c = vertices.indexOf( face.v3 );
+
+			index.push( a, b, c );
 
 		}
 
-		return newGeo;
+		//
+
+		simplifiedGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) );
+		simplifiedGeometry.setIndex( index );
+
+		return simplifiedGeometry;
+
 	};
-})();
+
+} )();

+ 2 - 2
examples/js/objects/Reflector.js

@@ -55,8 +55,7 @@ THREE.Reflector = function ( geometry, options ) {
 	var material = new THREE.ShaderMaterial( {
 		uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
 		fragmentShader: shader.fragmentShader,
-		vertexShader: shader.vertexShader,
-
+		vertexShader: shader.vertexShader
 	} );
 
 	material.uniforms.tDiffuse.value = renderTarget.texture;
@@ -64,6 +63,7 @@ THREE.Reflector = function ( geometry, options ) {
 	material.uniforms.textureMatrix.value = textureMatrix;
 
 	this.material = material;
+	this.renderOrder = - Infinity; // render first
 
 	this.onBeforeRender = function ( renderer, scene, camera ) {
 

+ 0 - 2
examples/js/objects/ReflectorRTT.js

@@ -4,8 +4,6 @@ THREE.ReflectorRTT = function ( geometry, options ) {
 
 	this.geometry.setDrawRange( 0, 0 ); // avoid rendering geometry
 
-	this.renderOrder = -Infinity; // render RTT first
-
 };
 
 THREE.ReflectorRTT.prototype = Object.create( THREE.Reflector.prototype );

+ 1 - 7
examples/js/pmrem/PMREMCubeUVPacker.js

@@ -178,13 +178,7 @@ THREE.PMREMCubeUVPacker.prototype = {
 					gl_FragColor = linearToOutputTexel( color );\
 				}",
 
-			blending: THREE.CustomBlending,
-			premultipliedAlpha: false,
-			blendSrc: THREE.OneFactor,
-			blendDst: THREE.ZeroFactor,
-			blendSrcAlpha: THREE.OneFactor,
-			blendDstAlpha: THREE.ZeroFactor,
-			blendEquation: THREE.AddEquation
+			blending: THREE.NoBlending
 
 		} );
 

+ 1 - 7
examples/js/pmrem/PMREMGenerator.js

@@ -259,13 +259,7 @@ THREE.PMREMGenerator.prototype = {
 					gl_FragColor = linearToOutputTexel( vec4( rgbColor, 1.0 ) );\n\
 				}",
 
-			blending: THREE.CustomBlending,
-			premultipliedAlpha: false,
-			blendSrc: THREE.OneFactor,
-			blendDst: THREE.ZeroFactor,
-			blendSrcAlpha: THREE.OneFactor,
-			blendDstAlpha: THREE.ZeroFactor,
-			blendEquation: THREE.AddEquation
+			blending: THREE.NoBlending
 
 		} );
 

+ 62 - 0
examples/js/renderers/CSS2DRenderer.js

@@ -37,6 +37,10 @@ THREE.CSS2DRenderer = function () {
 	var viewMatrix = new THREE.Matrix4();
 	var viewProjectionMatrix = new THREE.Matrix4();
 
+	var cache = {
+		objects: new WeakMap()
+	};
+
 	var domElement = document.createElement( 'div' );
 	domElement.style.overflow = 'hidden';
 
@@ -79,6 +83,12 @@ THREE.CSS2DRenderer = function () {
 			element.style.oTransform = style;
 			element.style.transform = style;
 
+			var objectData = {
+				distanceToCameraSquared: getDistanceToSquared( camera, object )
+			};
+
+			cache.objects.set( object, objectData );
+
 			if ( element.parentNode !== domElement ) {
 
 				domElement.appendChild( element );
@@ -95,6 +105,57 @@ THREE.CSS2DRenderer = function () {
 
 	};
 
+	var getDistanceToSquared = function () {
+
+		var a = new THREE.Vector3();
+		var b = new THREE.Vector3();
+
+		return function ( object1, object2 ) {
+
+			a.setFromMatrixPosition( object1.matrixWorld );
+			b.setFromMatrixPosition( object2.matrixWorld );
+
+			return a.distanceToSquared( b );
+
+		};
+
+	}();
+
+	var filterAndFlatten = function ( scene ) {
+
+		var result = [];
+
+		scene.traverse( function ( object ) {
+
+			if ( object instanceof THREE.CSS2DObject ) result.push( object );
+
+		} );
+
+		return result;
+
+	};
+
+	var zOrder = function ( scene ) {
+
+		var sorted = filterAndFlatten( scene ).sort( function ( a, b ) {
+
+			var distanceA = cache.objects.get( a ).distanceToCameraSquared;
+			var distanceB = cache.objects.get( b ).distanceToCameraSquared;
+
+			return distanceA - distanceB;
+
+		} );
+
+		var zMax = sorted.length;
+
+		for ( var i = 0, l = sorted.length; i < l; i ++ ) {
+
+			sorted[ i ].element.style.zIndex = zMax - i;
+
+		}
+
+	};
+
 	this.render = function ( scene, camera ) {
 
 		scene.updateMatrixWorld();
@@ -105,6 +166,7 @@ THREE.CSS2DRenderer = function () {
 		viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );
 
 		renderObject( scene, camera );
+		zOrder( scene );
 
 	};
 

+ 91 - 26
examples/js/shaders/BokehShader2.js

@@ -26,7 +26,9 @@ THREE.BokehShader = {
 
 		"maxblur":  { value: 1.0 },
 
+		"showFocus":   { value: 0 },
 		"manualdof":   { value: 0 },
+		"vignetting":   { value: 0 },
 		"depthblur":   { value: 0 },
 
 		"threshold":  { value: 0.5 },
@@ -75,6 +77,7 @@ THREE.BokehShader = {
 		"uniform float focalDepth;  //focal distance value in meters, but you may use autofocus option below",
 		"uniform float focalLength; //focal length in mm",
 		"uniform float fstop; //f-stop value",
+		"uniform bool showFocus; //show debug focus point and focal range (red = focal point, green = focal range)",
 
 		"/*",
 		"make sure that these two values are the same for your camera, otherwise distances will be wrong.",
@@ -99,6 +102,12 @@ THREE.BokehShader = {
 
 		"float CoC = 0.03; //circle of confusion size in mm (35mm film = 0.03mm)",
 
+		"uniform bool vignetting; // use optical lens vignetting",
+
+		"float vignout = 1.3; // vignetting outer border",
+		"float vignin = 0.0; // vignetting inner border",
+		"float vignfade = 22.0; // f-stops till vignete fades",
+
 		"uniform bool shaderFocus;",
 		"// disable if you use external focalDepth value",
 
@@ -133,22 +142,6 @@ THREE.BokehShader = {
 
 		"//------------------------------------------",
 
-		"float getDepth( const in vec2 screenPosition ) {",
-		"	#if DEPTH_PACKING == 1",
-		"	return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );",
-		"	#else",
-		"	return texture2D( tDepth, screenPosition ).x;",
-		"	#endif",
-		"}",
-
-		"float getViewZ( const in float depth ) {",
-		"	#if PERSPECTIVE_CAMERA == 1",
-		"	return perspectiveDepthToViewZ( depth, znear, zfar );",
-		"	#else",
-		"	return orthographicDepthToViewZ( depth, znear, zfar );",
-		"	#endif",
-		"}",
-
 		"float penta(vec2 coords) {",
 			"//pentagonal shape",
 			"float scale = float(rings) - 1.3;",
@@ -210,7 +203,7 @@ THREE.BokehShader = {
 
 
 			"for( int i=0; i<9; i++ ) {",
-				"float tmp = getDepth( coords + offset[ i ] );",
+				"float tmp = texture2D(tDepth, coords + offset[i]).r;",
 				"d += tmp * kernel[i];",
 			"}",
 
@@ -234,6 +227,28 @@ THREE.BokehShader = {
 			"return col+mix(vec3(0.0),col,thresh*blur);",
 		"}",
 
+		"vec3 debugFocus(vec3 col, float blur, float depth) {",
+			"float edge = 0.002*depth; //distance based edge smoothing",
+			"float m = clamp(smoothstep(0.0,edge,blur),0.0,1.0);",
+			"float e = clamp(smoothstep(1.0-edge,1.0,blur),0.0,1.0);",
+
+			"col = mix(col,vec3(1.0,0.5,0.0),(1.0-m)*0.6);",
+			"col = mix(col,vec3(0.0,0.5,1.0),((1.0-e)-(1.0-m))*0.2);",
+
+			"return col;",
+		"}",
+
+		"float linearize(float depth) {",
+			"return -zfar * znear / (depth * (zfar - znear) - zfar);",
+		"}",
+
+
+		"float vignette() {",
+			"float dist = distance(vUv.xy, vec2(0.5,0.5));",
+			"dist = smoothstep(vignout+(fstop/vignfade), vignin+(fstop/vignfade), dist);",
+			"return clamp(dist,0.0,1.0);",
+		"}",
+
 		"float gather(float i, float j, int ringsamples, inout vec3 col, float w, float h, float blur) {",
 			"float rings2 = float(rings);",
 			"float step = PI*2.0 / float(ringsamples);",
@@ -250,20 +265,20 @@ THREE.BokehShader = {
 		"void main() {",
 			"//scene depth calculation",
 
-			"float depth = getViewZ( getDepth( vUv.xy ) );",
+			"float depth = linearize(texture2D(tDepth,vUv.xy).x);",
 
 			"// Blur depth?",
-			"if (depthblur) {",
-				"depth = getViewZ(bdepth(vUv.xy));",
+			"if ( depthblur ) {",
+				"depth = linearize(bdepth(vUv.xy));",
 			"}",
 
 			"//focal plane calculation",
 
-			"float fDepth = - focalDepth;", // viewZ is negative
+			"float fDepth = focalDepth;",
 
 			"if (shaderFocus) {",
 
-				"fDepth = getViewZ( getDepth( focusCoords ) );",
+				"fDepth = linearize(texture2D(tDepth,focusCoords).x);",
 
 			"}",
 
@@ -272,14 +287,14 @@ THREE.BokehShader = {
 			"float blur = 0.0;",
 
 			"if (manualdof) {",
-				"float a = depth - fDepth; // Focal plane",
+				"float a = depth-fDepth; // Focal plane",
 				"float b = (a-fdofstart)/fdofdist; // Far DoF",
 				"float c = (-a-ndofstart)/ndofdist; // Near Dof",
 				"blur = (a>0.0) ? b : c;",
 			"} else {",
-				"float f = focalLength;",
-				"float d = fDepth;",
-				"float o = depth;",
+				"float f = focalLength; // focal length in mm",
+				"float d = fDepth*1000.0; // focal plane in mm",
+				"float o = depth*1000.0; // depth in mm",
 
 				"float a = (o*f)/(o-f);",
 				"float b = (d*f)/(d-f);",
@@ -325,6 +340,14 @@ THREE.BokehShader = {
 				"col /= s; //divide by sample count",
 			"}",
 
+			"if (showFocus) {",
+				"col = debugFocus(col, blur, depth);",
+			"}",
+
+			"if (vignetting) {",
+				"col *= vignette();",
+			"}",
+
 			"gl_FragColor.rgb = col;",
 			"gl_FragColor.a = 1.0;",
 		"} "
@@ -332,3 +355,45 @@ THREE.BokehShader = {
 	].join( "\n" )
 
 };
+
+THREE.BokehDepthShader = {
+
+	uniforms: {
+
+		"mNear": { value: 1.0 },
+		"mFar": { value: 1000.0 },
+
+	},
+
+	vertexShader: [
+
+		"varying float vViewZDepth;",
+
+		"void main() {",
+
+		"	#include <begin_vertex>",
+		"	#include <project_vertex>",
+
+		"	vViewZDepth = - mvPosition.z;",
+
+		"}"
+
+	].join( "\n" ),
+
+	fragmentShader: [
+
+		"uniform float mNear;",
+		"uniform float mFar;",
+
+		"varying float vViewZDepth;",
+
+		"void main() {",
+
+		"	float color = 1.0 - smoothstep( mNear, mFar, vViewZDepth );",
+		"	gl_FragColor = vec4( vec3( color ), 1.0 );",
+
+		"} "
+
+	].join( "\n" )
+
+};

+ 5 - 2
examples/js/vr/WebVR.js

@@ -7,7 +7,7 @@
 
 var WEBVR = {
 
-	createButton: function ( renderer ) {
+	createButton: function ( renderer, options ) {
 
 		function showEnterVR( device ) {
 
@@ -38,9 +38,12 @@ var WEBVR = {
 
 			function onSessionStarted( session ) {
 
+				if ( options === undefined ) options = {};
+				if ( options.frameOfReferenceType === undefined ) options.frameOfReferenceType = 'stage';
+
 				session.addEventListener( 'end', onSessionEnded );
 
-				renderer.vr.setSession( session );
+				renderer.vr.setSession( session, options );
 				button.textContent = 'EXIT XR';
 
 				currentSession = session;

+ 193 - 0
examples/misc_exporter_stl.html

@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - exporter - stl</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				font-family: Monospace;
+				background-color: #000;
+				color: #fff;
+				margin: 0px;
+				overflow: hidden;
+			}
+			#info {
+				color: #fff;
+				position: absolute;
+				top: 10px;
+				width: 100%;
+				text-align: center;
+				display:block;
+			}
+			#info a {
+				color: #046;
+				font-weight: bold;
+			}
+		</style>
+	</head>
+	<body>
+		<div id="info">
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - exporter - stl
+		</div>
+
+		<script src="../build/three.js"></script>
+		<script src="js/controls/OrbitControls.js"></script>
+		<script src="js/exporters/STLExporter.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var scene, camera, renderer, exporter;
+
+			init();
+			animate();
+
+			function init() {
+
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.set( 200, 100, 200 );
+
+				scene = new THREE.Scene();
+				scene.background = new THREE.Color( 0xa0a0a0 );
+				scene.fog = new THREE.Fog( 0xa0a0a0, 200, 1000 );
+
+				exporter = new THREE.STLExporter();
+
+				//
+
+				var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
+				hemiLight.position.set( 0, 200, 0 );
+				scene.add( hemiLight );
+
+				var directionalLight = new THREE.DirectionalLight( 0xffffff );
+				directionalLight.position.set( 0, 200, 100 );
+				directionalLight.castShadow = true;
+				directionalLight.shadow.camera.top = 180;
+				directionalLight.shadow.camera.bottom = - 100;
+				directionalLight.shadow.camera.left = - 120;
+				directionalLight.shadow.camera.right = 120;
+				scene.add( directionalLight );
+
+				// ground
+
+				var ground = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
+				ground.rotation.x = - Math.PI / 2;
+				ground.receiveShadow = true;
+				scene.add( ground );
+
+				var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
+				grid.material.opacity = 0.2;
+				grid.material.transparent = true;
+				scene.add( grid );
+
+				// export mesh
+
+				var geometry = new THREE.BoxBufferGeometry( 50, 50, 50 );
+				var material = new THREE.MeshPhongMaterial( { color: 0x00ff00 } );
+
+				mesh = new THREE.Mesh( geometry, material );
+				mesh.castShadow = true;
+				mesh.position.y = 25;
+				scene.add( mesh );
+
+				//
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.shadowMap.enabled = true;
+				document.body.appendChild( renderer.domElement );
+
+				//
+
+				var controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.target.set( 0, 25, 0 );
+				controls.update();
+
+				//
+
+				var params = {
+					ASCII: function() {
+						exportASCII();
+					},
+					Binary: function() {
+						exportBinary();
+					}
+				}
+
+				var gui = new dat.GUI();
+				var folder = gui.addFolder( 'Export' );
+
+				folder.add( params, 'ASCII' );
+				folder.add( params, 'Binary' );
+				folder.open();
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+				renderer.render( scene, camera );
+
+			}
+
+			function exportASCII() {
+
+				var result = exporter.parse( mesh );
+				saveString( result, 'box.stl' );
+
+			}
+
+			function exportBinary() {
+
+				var result = exporter.parse( mesh, { binary: true } );
+				saveArrayBuffer( result, 'box.stl' );
+
+			}
+
+			var link = document.createElement( 'a' );
+			link.style.display = 'none';
+			document.body.appendChild( link );
+
+			function save( blob, filename ) {
+
+				link.href = URL.createObjectURL( blob );
+				link.download = filename;
+				link.click();
+
+			}
+
+			function saveString( text, filename ) {
+
+				save( new Blob( [ text ], { type: 'text/plain' } ), filename );
+
+			}
+
+			function saveArrayBuffer( buffer, filename ) {
+
+				save( new Blob( [ buffer ], { type: 'application/octet-stream' } ), filename );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 0 - 1
examples/webgl_buffergeometry_instancing_lambert.html

@@ -144,7 +144,6 @@
 				#include <envmap_pars_vertex>
 				#include <bsdfs>
 				#include <lights_pars_begin>
-				#include <lights_pars_maps>
 				#include <color_pars_vertex>
 				#include <fog_pars_vertex>
 				#include <morphtarget_pars_vertex>

+ 2 - 2
examples/webgl_geometry_colors_blender.html → examples/webgl_geometry_colors_json.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<title>three.js webgl - io blender - vertex colors</title>
+		<title>three.js webgl - json - vertex colors</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
@@ -32,7 +32,7 @@
 	<body>
 
 		<div id="container"></div>
-		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - io blender - vertex colors</div>
+		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - json - vertex colors</div>
 
 		<script src="../build/three.js"></script>
 

+ 29 - 23
examples/webgl_interactive_voxelpainter.html

@@ -6,17 +6,35 @@
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
 			body {
-				font-family: Monospace;
-				background-color: #f0f0f0;
-				margin: 0px;
-				overflow: hidden;
+				background:#777;
+				padding:0;
+				margin:0;
+				font-weight: bold;
+				overflow:hidden;
 			}
 
-			#oldie { background-color: #ddd !important }
+			#info {
+				position: absolute;
+				top: 0px;
+				width: 100%;
+				padding: 5px;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+			}
+
+			a {
+				color: #ff0000;
+			}
 		</style>
 	</head>
 	<body>
 
+		<div id="info">
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - voxel painter - webgl<br>
+			<strong>click</strong>: add voxel, <strong>shift + click</strong>: remove voxel
+		</div>
+
 		<script src="../build/three.js"></script>
 
 		<script src="js/Detector.js"></script>
@@ -25,7 +43,6 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
-			var container;
 			var camera, scene, renderer;
 			var plane, cube;
 			var mouse, raycaster, isShiftDown = false;
@@ -40,17 +57,6 @@
 
 			function init() {
 
-				container = document.createElement( 'div' );
-				document.body.appendChild( container );
-
-				var info = document.createElement( 'div' );
-				info.style.position = 'absolute';
-				info.style.top = '10px';
-				info.style.width = '100%';
-				info.style.textAlign = 'center';
-				info.innerHTML = '<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - voxel painter - webgl<br><strong>click</strong>: add voxel, <strong>shift + click</strong>: remove voxel';
-				container.appendChild( info );
-
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
 				camera.position.set( 500, 800, 1300 );
 				camera.lookAt( new THREE.Vector3() );
@@ -60,15 +66,15 @@
 
 				// roll-over helpers
 
-				var rollOverGeo = new THREE.BoxGeometry( 50, 50, 50 );
+				var rollOverGeo = new THREE.BoxBufferGeometry( 50, 50, 50 );
 				rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } );
 				rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
 				scene.add( rollOverMesh );
 
 				// cubes
 
-				cubeGeo = new THREE.BoxGeometry( 50, 50, 50 );
-				cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xfeb74c, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" ) } );
+				cubeGeo = new THREE.BoxBufferGeometry( 50, 50, 50 );
+				cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xfeb74c, map: new THREE.TextureLoader().load( 'textures/square-outline-textured.png' ) } );
 
 				// grid
 
@@ -88,7 +94,7 @@
 
 				objects.push( plane );
 
-				// Lights
+				// lights
 
 				var ambientLight = new THREE.AmbientLight( 0x606060 );
 				scene.add( ambientLight );
@@ -100,7 +106,7 @@
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
+				document.body.appendChild( renderer.domElement );
 
 				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 				document.addEventListener( 'mousedown', onDocumentMouseDown, false );
@@ -163,7 +169,7 @@
 
 					if ( isShiftDown ) {
 
-						if ( intersect.object != plane ) {
+						if ( intersect.object !== plane ) {
 
 							scene.remove( intersect.object );
 

+ 1 - 1
examples/webgl_loader_json_blender.html → examples/webgl_loader_json.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<title>three.js webgl - blender -json</title>
+		<title>three.js webgl - loader -json</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>

+ 12 - 8
examples/webgl_loader_mmd.html

@@ -82,14 +82,14 @@
 				scene.background = new THREE.Color( 0xffffff );
 
 				var gridHelper = new THREE.PolarGridHelper( 30, 10 );
-				gridHelper.position.y = -10;
+				gridHelper.position.y = - 10;
 				scene.add( gridHelper );
 
 				var ambient = new THREE.AmbientLight( 0x666666 );
 				scene.add( ambient );
 
 				var directionalLight = new THREE.DirectionalLight( 0x887766 );
-				directionalLight.position.set( -1, 1, 1 ).normalize();
+				directionalLight.position.set( - 1, 1, 1 ).normalize();
 				scene.add( directionalLight );
 
 				//
@@ -108,14 +108,18 @@
 
 				// model
 
-				var onProgress = function ( xhr ) {
+				function onProgress( xhr ) {
+
 					if ( xhr.lengthComputable ) {
+
 						var percentComplete = xhr.loaded / xhr.total * 100;
-						console.log( Math.round(percentComplete, 2) + '% downloaded' );
+						console.log( Math.round( percentComplete, 2 ) + '% downloaded' );
+
 					}
+
 				};
 
-				var onError = function ( xhr ) {
+				function onError( xhr ) {
 				};
 
 				var modelFile = 'models/mmd/miku/miku_v2.pmd';
@@ -130,7 +134,7 @@
 				loader.loadWithAnimation( modelFile, vmdFiles, function ( mmd ) {
 
 					mesh = mmd.mesh;
-					mesh.position.y = -10;
+					mesh.position.y = - 10;
 					scene.add( mesh );
 
 					helper.add( mesh, {
@@ -157,7 +161,7 @@
 				var phongMaterials;
 				var originalMaterials;
 
-				function makePhongMaterials ( materials ) {
+				function makePhongMaterials( materials ) {
 
 					var array = [];
 
@@ -175,7 +179,7 @@
 
 				}
 
-				function initGui () {
+				function initGui() {
 
 					var api = {
 						'animation': true,

+ 8 - 4
examples/webgl_loader_mmd_audio.html

@@ -87,7 +87,7 @@
 				scene.add( ambient );
 
 				var directionalLight = new THREE.DirectionalLight( 0x887766 );
-				directionalLight.position.set( -1, 1, 1 ).normalize();
+				directionalLight.position.set( - 1, 1, 1 ).normalize();
 				scene.add( directionalLight );
 
 				//
@@ -101,14 +101,18 @@
 
 				// model
 
-				var onProgress = function ( xhr ) {
+				function onProgress( xhr ) {
+
 					if ( xhr.lengthComputable ) {
+
 						var percentComplete = xhr.loaded / xhr.total * 100;
-						console.log( Math.round(percentComplete, 2) + '% downloaded' );
+						console.log( Math.round( percentComplete, 2 ) + '% downloaded' );
+
 					}
+
 				};
 
-				var onError = function ( xhr ) {
+				function onError( xhr ) {
 				};
 
 				var modelFile = 'models/mmd/miku/miku_v2.pmd';

+ 23 - 18
examples/webgl_loader_mmd_pose.html

@@ -80,7 +80,7 @@
 				scene.add( ambient );
 
 				var directionalLight = new THREE.DirectionalLight( 0x887766 );
-				directionalLight.position.set( -1, 1, 1 ).normalize();
+				directionalLight.position.set( - 1, 1, 1 ).normalize();
 				scene.add( directionalLight );
 
 				//
@@ -94,14 +94,18 @@
 
 				// model
 
-				var onProgress = function ( xhr ) {
+				function onProgress( xhr ) {
+
 					if ( xhr.lengthComputable ) {
+
 						var percentComplete = xhr.loaded / xhr.total * 100;
-						console.log( Math.round(percentComplete, 2) + '% downloaded' );
+						console.log( Math.round( percentComplete, 2 ) + '% downloaded' );
+
 					}
+
 				};
 
-				var onError = function ( xhr ) {
+				function onError( xhr ) {
 				};
 
 				var modelFile = 'models/mmd/miku/miku_v2.pmd';
@@ -126,13 +130,13 @@
 				loader.load( modelFile, function ( object ) {
 
 					mesh = object;
-					mesh.position.y = -10;
+					mesh.position.y = - 10;
 
 					scene.add( mesh );
 
 					var vpdIndex = 0;
 
-					function loadVpd () {
+					function loadVpd() {
 
 						var vpdFile = vpdFiles[ vpdIndex ];
 
@@ -140,7 +144,7 @@
 
 							vpds.push( vpd );
 
-							vpdIndex++;
+							vpdIndex ++;
 
 							if ( vpdIndex < vpdFiles.length ) {
 
@@ -155,6 +159,7 @@
 						}, onProgress, onError );
 
 					}
+
 					loadVpd();
 
 				}, onProgress, onError );
@@ -163,7 +168,7 @@
 
 				window.addEventListener( 'resize', onWindowResize, false );
 
-				function initGui () {
+				function initGui() {
 
 					var gui = new dat.GUI();
 
@@ -175,13 +180,13 @@
 					var poses = gui.addFolder( 'Poses' );
 					var morphs = gui.addFolder( 'Morphs' );
 
-					function getBaseName ( s ) {
+					function getBaseName( s ) {
 
 						return s.slice( s.lastIndexOf( '/' ) + 1 );
 
 					}
 
-					function initControls () {
+					function initControls() {
 
 						for ( var key in dictionary ) {
 
@@ -189,7 +194,7 @@
 
 						}
 
-						controls.pose = -1;
+						controls.pose = - 1;
 
 						for ( var i = 0; i < vpdFiles.length; i++ ) {
 
@@ -199,7 +204,7 @@
 
 					}
 
-					function initKeys () {
+					function initKeys() {
 
 						for ( var key in dictionary ) {
 
@@ -209,9 +214,9 @@
 
 					}
 
-					function initPoses () {
+					function initPoses() {
 
-						var files = { default: -1 };
+						var files = { default: - 1 };
 
 						for ( var i = 0; i < vpdFiles.length; i++ ) {
 
@@ -223,7 +228,7 @@
 
 					}
 
-					function initMorphs () {
+					function initMorphs() {
 
 						for ( var key in dictionary ) {
 
@@ -233,7 +238,7 @@
 
 					}
 
-					function onChangeMorph () {
+					function onChangeMorph() {
 
 						for ( var i = 0; i < keys.length; i++ ) {
 
@@ -245,11 +250,11 @@
 
 					}
 
-					function onChangePose () {
+					function onChangePose() {
 
 						var index = parseInt( controls.pose );
 
-						if ( index === -1 ) {
+						if ( index === - 1 ) {
 
 							mesh.pose();
 

+ 16 - 18
examples/webgl_loader_x.html

@@ -23,22 +23,22 @@
         a {
             color: #ff0000
         }
-        
-        #info2 { 
-            color: #fff; 
-            background-color: #000; 
-            position: absolute; 
-            top: 3em; 
-            right : 0px; 
-            width: 10em; 
-            z-index: 200; 
-            display: block;  
+
+        #info2 {
+            color: #fff;
+            background-color: #000;
+            position: absolute;
+            top: 3em;
+            right : 0px;
+            width: 10em;
+            z-index: 200;
+            display: block;
         }
-    
-        td { 
+
+        td {
             padding: 0.5em;
         }
-        
+
     </style>
 </head>
 <body>
@@ -71,7 +71,7 @@
 	<script src='js/Detector.js'></script>
 	<script src='js/libs/stats.min.js'></script>
 	<script src='js/libs/dat.gui.min.js'></script>
-    
+
     <script>
 
         if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
@@ -81,7 +81,6 @@
         var clock = new THREE.Clock();
         var mixers = [];
         var manager = null;
-        var Texloader = null;
 
         var skeletonHelper = null;
         var animates = [];
@@ -156,8 +155,7 @@
 
             };
 
-            Texloader = new THREE.TextureLoader();
-            var loader = new THREE.XLoader( manager, Texloader );
+            var loader = new THREE.XLoader( manager );
 
             actions[ 0 ] = {};
 
@@ -244,7 +242,7 @@
 
             } else {
 
-                var loader2 = new THREE.XLoader( manager, Texloader );
+                var loader2 = new THREE.XLoader( manager );
                 loader2.load( [ 'models/xfile/' + animeName + '.x', { putPos: false, putScl: false } ], function () {
 
                     // !! important!

+ 44 - 88
examples/webgl_modifier_simplifier.html

@@ -7,10 +7,13 @@
 		<style>
 			body {
 				font-family: Monospace;
-				background-color: #f0f0f0;
+				color: #fff;
 				margin: 0px;
 				overflow: hidden;
 			}
+			a {
+				color: #ffffff;
+			}
 		</style>
 	</head>
 	<body>
@@ -18,127 +21,80 @@
 		<script src="../build/three.js"></script>
 		<script src="js/controls/OrbitControls.js"></script>
 		<script src="js/modifiers/SimplifyModifier.js"></script>
-		<script src="js/libs/stats.min.js"></script>
 
 		<script>
 
-			var container, stats;
-
-			var camera, controls, scene, renderer;
-
-			var boxGeometry = new THREE.BoxGeometry( 80, 80, 80, 4, 4, 4 );
-			var torusGeometry = new THREE.TorusGeometry( 50, 25, 8, 8, Math.PI * 2 );
-			var sphereGeometry = new THREE.SphereGeometry( 50, 15, 15 );
-			var planeGeometry = new THREE.PlaneGeometry( 100, 100, 6, 6 );
-
-			var modifer = new THREE.SimplifyModifier();
-			var meshes = [];
-			var count = 0;
-
-			var wireframeMaterial = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, transparent: true } );
+			var renderer, scene, camera;
 
 			init();
-			animate();
-
-
-			function addStuff( geometry ) {
-
-				count ++;
-
-				var mesh, wireframe;
-
-				var material = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } );
-
-				var simplified = modifer.modify( geometry, geometry.vertices.length * 0.5 | 0 );
-
-				mesh = new THREE.Mesh( simplified, material );
-				wireframe = new THREE.Mesh( simplified, wireframeMaterial );
-				mesh.add( wireframe );
-				mesh.position.x = - 200;
-				mesh.position.y = count * 150 - 300;
-
-				scene.add( mesh );
-				meshes.push( mesh );
-
-				mesh = new THREE.Mesh( geometry, material );
-				wireframe = new THREE.Mesh( geometry, wireframeMaterial );
-				mesh.add( wireframe );
-				mesh.position.x = 200;
-				mesh.position.y = count * 150 - 300;
-
-				scene.add( mesh );
-				meshes.push ( mesh );
-
-			}
 
 			function init() {
 
-				container = document.createElement( 'div' );
-				document.body.appendChild( container );
-
 				var info = document.createElement( 'div' );
 				info.style.position = 'absolute';
 				info.style.top = '10px';
 				info.style.width = '100%';
 				info.style.textAlign = 'center';
-				info.innerHTML = '50% Vertex Reduction using SimplifyModifier';
-				container.appendChild( info );
+				info.innerHTML = '<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - Vertex Reduction using SimplifyModifier';
+				document.body.appendChild( info );
 
-				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
-				camera.position.z = 500;
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
 
 				scene = new THREE.Scene();
-				scene.background = new THREE.Color( 0xf0f0f0 );
 
-				var light = new THREE.PointLight( 0xffffff, 1.5 );
-				light.position.set( 1000, 1000, 2000 );
-				scene.add( light );
+				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.z = 15;
 
-				addStuff( planeGeometry );
-				addStuff( boxGeometry );
-				addStuff( sphereGeometry );
-				addStuff( torusGeometry );
+				var controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.addEventListener( 'change', render ); // use if there is no animation loop
+				controls.enablePan = false;
+				controls.enableZoom = false;
 
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
+				scene.add( new THREE.AmbientLight( 0xffffff, 0.2 ) );
 
-				stats = new Stats();
-				container.appendChild( stats.dom );
+				var light = new THREE.PointLight( 0xffffff, 0.7 );
+				camera.add( light );
+				scene.add( camera );
 
-				//
+				new THREE.JSONLoader().load( "models/json/leeperrysmith/LeePerrySmith.json", function ( geometry ) {
 
-				controls = new THREE.OrbitControls( camera, renderer.domElement );
+					var material = new THREE.MeshPhongMaterial( { color: 0xAEAED5, shininess: 1 } );
 
-				window.addEventListener( 'resize', onWindowResize, false );
+					var mesh = new THREE.Mesh( geometry, material );
+					mesh.position.x = - 3;
+					mesh.rotation.y = Math.PI / 2;
+					scene.add( mesh );
 
-			}
+					var modifer = new THREE.SimplifyModifier();
 
-			function onWindowResize() {
+					var simplified = modifer.modify( geometry, Math.floor( geometry.vertices.length * 0.9375 ) ); // number of vertices to remove
 
-				camera.aspect = window.innerWidth / window.innerHeight;
-				camera.updateProjectionMatrix();
+					var material = new THREE.MeshPhongMaterial( { color: 0xAEAED5, shininess: 1, flatShading: true } );
 
-				renderer.setSize( window.innerWidth, window.innerHeight );
+					var mesh = new THREE.Mesh( simplified, material );
+					mesh.position.x = 3;
+					mesh.rotation.y = - Math.PI / 2;
+					scene.add( mesh );
 
-			}
+					render();
 
-			//
+				} );
 
-			function animate() {
+				window.addEventListener( 'resize', onWindowResize, false );
 
-				meshes.forEach( function( m ) {
-					m.rotation.x += 0.01;
-					m.rotation.y += 0.01;
-					m.rotation.z += 0.01;
-				} );
+			}
+
+			function onWindowResize() {
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
-				requestAnimationFrame( animate );
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
 
-				stats.begin();
 				render();
-				stats.end();
 
 			}
 

+ 71 - 13
examples/webgl_postprocessing_dof2.html

@@ -96,9 +96,16 @@ Use WEBGL Depth buffer support?
 				renderer.autoClear = false;
 				container.appendChild( renderer.domElement );
 
-				materialDepth = new THREE.MeshDepthMaterial();
-				materialDepth.depthPacking = THREE.RGBADepthPacking;
-				materialDepth.blending = THREE.NoBlending;
+				var depthShader = THREE.BokehDepthShader;
+
+				materialDepth = new THREE.ShaderMaterial( {
+					uniforms: depthShader.uniforms,
+					vertexShader: depthShader.vertexShader,
+					fragmentShader: depthShader.fragmentShader
+				} );
+
+				materialDepth.uniforms[ 'mNear' ].value = camera.near;
+				materialDepth.uniforms[ 'mFar' ].value = camera.far;
 
 				// skybox
 
@@ -110,7 +117,21 @@ Use WEBGL Depth buffer support?
 				var textureCube = new THREE.CubeTextureLoader().load( urls );
 				textureCube.format = THREE.RGBFormat;
 
-				scene.background = textureCube;
+				var shader = THREE.ShaderLib[ 'cube' ];
+				shader.uniforms[ 'tCube' ].value = textureCube;
+
+				material = new THREE.ShaderMaterial( {
+
+					fragmentShader: shader.fragmentShader,
+					vertexShader: shader.vertexShader,
+					uniforms: shader.uniforms,
+					depthWrite: false,
+					side: THREE.BackSide
+
+				} );
+
+				mesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 1000, 1000, 1000 ), material );
+				scene.add( mesh );
 
 				// plane particles
 
@@ -226,11 +247,13 @@ Use WEBGL Depth buffer support?
 					jsDepthCalculation: true,
 					shaderFocus: false,
 
-					fstop: 10,
+					fstop: 2.2,
 					maxblur: 1.0,
 
+					showFocus: false,
 					focalDepth: 2.8,
 					manualdof: false,
+					vignetting: false,
 					depthblur: false,
 
 					threshold: 0.5,
@@ -272,10 +295,13 @@ Use WEBGL Depth buffer support?
 				gui.add( effectController, 'shaderFocus' ).onChange( matChanger );
 				gui.add( effectController, 'focalDepth', 0.0, 200.0 ).listen().onChange( matChanger );
 
-				gui.add( effectController, 'fstop', 1, 50, 0.1 ).onChange( matChanger );
+				gui.add( effectController, 'fstop', 0.1, 22, 0.001 ).onChange( matChanger );
 				gui.add( effectController, 'maxblur', 0.0, 5.0, 0.025 ).onChange( matChanger );
 
+				gui.add( effectController, 'showFocus' ).onChange( matChanger );
 				gui.add( effectController, 'manualdof' ).onChange( matChanger );
+				gui.add( effectController, 'vignetting' ).onChange( matChanger );
+
 				gui.add( effectController, 'depthblur' ).onChange( matChanger );
 
 				gui.add( effectController, 'threshold', 0, 1, 0.001 ).onChange( matChanger );
@@ -284,8 +310,11 @@ Use WEBGL Depth buffer support?
 				gui.add( effectController, 'fringe', 0, 5, 0.001 ).onChange( matChanger );
 
 				gui.add( effectController, 'focalLength', 16, 80, 0.001 ).onChange( matChanger );
+
 				gui.add( effectController, 'noise' ).onChange( matChanger );
+
 				gui.add( effectController, 'dithering', 0, 0.001, 0.0001 ).onChange( matChanger );
+
 				gui.add( effectController, 'pentagon' ).onChange( matChanger );
 
 				gui.add( shaderSettings, 'rings', 1, 8).step(1).onChange( shaderUpdate );
@@ -369,9 +398,7 @@ Use WEBGL Depth buffer support?
 					fragmentShader: bokeh_shader.fragmentShader,
 					defines: {
 						RINGS: shaderSettings.rings,
-						SAMPLES: shaderSettings.samples,
-						DEPTH_PACKING: 1, // RGBADepth
-						PERSPECTIVE_CAMERA: 1
+						SAMPLES: shaderSettings.samples
 					}
 
 				} );
@@ -399,6 +426,28 @@ Use WEBGL Depth buffer support?
 
 			}
 
+			function linearize( depth ) {
+
+				var zfar = camera.far;
+				var znear = camera.near;
+				return - zfar * znear / ( depth * ( zfar - znear ) - zfar );
+
+			}
+
+
+			function smoothstep( near, far, depth ) {
+
+				var x = saturate( ( depth - near ) / ( far - near ) );
+				return x * x * ( 3 - 2 * x );
+
+			}
+
+			function saturate( x ) {
+
+				return Math.max( 0, Math.min( 1, x ) );
+
+			}
+
 			function render() {
 
 				var time = Date.now() * 0.00015;
@@ -417,13 +466,22 @@ Use WEBGL Depth buffer support?
 
 					var intersects = raycaster.intersectObjects( scene.children, true );
 
-					var targetDistance = ( intersects.length > 0 ) ? intersects[ 0 ].distance : 1000;
 
-					distance += ( targetDistance - distance ) * 0.05;
+					if ( intersects.length > 0 ) {
+
+						var targetDistance = intersects[ 0 ].distance;
+
+						distance += (targetDistance - distance) * 0.03;
+
+						var sdistance = smoothstep(camera.near, camera.far, distance);
 
-					postprocessing.bokeh_uniforms[ 'focalDepth' ].value = distance;
+						var ldistance = linearize(1 -  sdistance);
 
-					effectController[ 'focalDepth' ] = distance;
+						postprocessing.bokeh_uniforms[ 'focalDepth' ].value = ldistance;
+
+						effectController['focalDepth'] = ldistance;
+
+					}
 
 				}
 

+ 0 - 1
examples/webgl_shaders_tonemapping.html

@@ -161,7 +161,6 @@
 						THREE.ShaderChunk[ "common" ],
 						THREE.ShaderChunk[ "bsdfs" ],
 						THREE.ShaderChunk[ "lights_pars_begin" ],
-						THREE.ShaderChunk[ "lights_pars_maps" ],
 						THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
 
 						"void main() {",

+ 2 - 2
examples/webvr_cubes.html

@@ -5,7 +5,7 @@
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-06-19 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-06-19" content="Alxt96tYGgIr9l6EXU0eeI360zcmzOY6Kuo3kcTfBGIRDOQbgFIZKRQ1joExQ74WZr1einsE+cUMHgSclNHCQQ4AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUyOTM5NzgyOH0="> 
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-06-19" content="Alxt96tYGgIr9l6EXU0eeI360zcmzOY6Kuo3kcTfBGIRDOQbgFIZKRQ1joExQ74WZr1einsE+cUMHgSclNHCQQ4AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUyOTM5NzgyOH0=">
 		<!-- Origin Trial Token, feature = WebXR Device API, origin = https://threejs.org, expires = 2018-06-15 -->
 		<meta http-equiv="origin-trial" data-feature="WebXR Device API" data-expires="2018-06-15" content="AtJH9g6nn0B87bnjJt+9m1joZXEYDmLSlRvtMr5qJD52hMcm3S86S7jg5I7y2I5cgQglE0rzsXzti5DECQLb8QkAAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZSIsImV4cGlyeSI6MTUyOTA4NDY2OH0=">
 		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-06-15 -->
@@ -180,7 +180,7 @@
 
 			function animate() {
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 			}
 

+ 1 - 1
examples/webvr_daydream.html

@@ -140,7 +140,7 @@
 
 			function animate() {
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 			}
 

+ 1 - 1
examples/webvr_gearvr.html

@@ -165,7 +165,7 @@
 
 			function animate() {
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 			}
 

+ 5 - 8
examples/webvr_panorama.html

@@ -43,7 +43,7 @@
 			renderer.vr.userHeight = 0; // TOFIX
 			document.body.appendChild( renderer.domElement );
 
-			document.body.appendChild( WEBVR.createButton( renderer ) );
+			document.body.appendChild( WEBVR.createButton( renderer, { frameOfReferenceType: 'headModel' } ) );
 
 			//
 
@@ -95,9 +95,8 @@
 
 			}
 
-			var imageObj = new Image();
-
-			imageObj.onload = function() {
+			var loader = new THREE.ImageLoader();
+			loader.load( atlasImgUrl, function ( imageObj ) {
 
 				var canvas, context;
 				var tileWidth = imageObj.height;
@@ -114,9 +113,7 @@
 
 				}
 
-			};
-
-			imageObj.src = atlasImgUrl;
+			} );
 
 			return textures;
 
@@ -133,7 +130,7 @@
 
 		function animate() {
 
-			renderer.animate( render );
+			renderer.setAnimationLoop( render );
 
 		}
 

+ 2 - 2
examples/webvr_rollercoaster.html

@@ -40,7 +40,7 @@
 			renderer.vr.userHeight = 0; // TOFIX
 			document.body.appendChild( renderer.domElement );
 
-			document.body.appendChild( WEBVR.createButton( renderer ) );
+			document.body.appendChild( WEBVR.createButton( renderer, { frameOfReferenceType: 'eyeLevel' } ) );
 
 			//
 
@@ -247,7 +247,7 @@
 
 			}
 
-			renderer.animate( render );
+			renderer.setAnimationLoop( render );
 
 		</script>
 

+ 2 - 2
examples/webvr_sandbox.html

@@ -125,7 +125,7 @@
 				//
 
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setClearColor( 0x000000 );
+				renderer.autoClear = false;
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.shadowMap.enabled = true;
@@ -151,7 +151,7 @@
 
 			function animate() {
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 			}
 

+ 1 - 1
examples/webvr_video.html

@@ -159,7 +159,7 @@
 
 			function animate() {
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 			}
 

+ 1 - 1
examples/webvr_vive.html

@@ -204,7 +204,7 @@
 
 			function animate() {
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 			}
 

+ 1 - 1
examples/webvr_vive_dragging.html

@@ -293,7 +293,7 @@
 
 			function animate() {
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 			}
 

+ 1 - 1
examples/webvr_vive_paint.html

@@ -417,7 +417,7 @@
 
 			function animate() {
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 			}
 

+ 1 - 1
examples/webvr_vive_sculpt.html

@@ -216,7 +216,7 @@
 
 			function animate() {
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 			}
 

+ 5250 - 0
package-lock.json

@@ -0,0 +1,5250 @@
+{
+  "name": "three",
+  "version": "0.92.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@types/estree": {
+      "version": "0.0.39",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+      "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "8.10.17",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.17.tgz",
+      "integrity": "sha1-1IzxDw3G3PWfgn9aP8ekpgBDGNM=",
+      "dev": true
+    },
+    "@zeit/schemas": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-1.1.2.tgz",
+      "integrity": "sha512-1KCchM412X/6h1b5XAU3CUe2Teu7duHa6ECkQVa27PmD4UWzciB3oAlElDv4uqAKJFfwprG1eeqwjtmGIQcJcg==",
+      "dev": true
+    },
+    "acorn": {
+      "version": "5.5.3",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
+      "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==",
+      "dev": true
+    },
+    "acorn-jsx": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+      "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+      "dev": true,
+      "requires": {
+        "acorn": "3.3.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+          "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+          "dev": true
+        }
+      }
+    },
+    "ajv": {
+      "version": "5.5.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+      "dev": true,
+      "requires": {
+        "co": "4.6.0",
+        "fast-deep-equal": "1.0.0",
+        "fast-json-stable-stringify": "2.0.0",
+        "json-schema-traverse": "0.3.1"
+      }
+    },
+    "ajv-keywords": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
+      "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
+      "dev": true
+    },
+    "ansi-escapes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+      "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+      "dev": true
+    },
+    "anymatch": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+      "integrity": "sha1-VT3Lj5HjyImEXf26NMd3IbkLnXo=",
+      "dev": true,
+      "requires": {
+        "micromatch": "2.3.11",
+        "normalize-path": "2.1.1"
+      }
+    },
+    "arg": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz",
+      "integrity": "sha1-wG5/9pqwWzpKA+vgQH+sTLpldUU=",
+      "dev": true
+    },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "1.0.3"
+      }
+    },
+    "arr-diff": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+      "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "1.1.0"
+      }
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-find-index": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+      "dev": true
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "1.0.3"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+      "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "asn1": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+      "dev": true
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "async-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
+      "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
+      "dev": true
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
+      "integrity": "sha1-1NDpudv8p3vwjusKikcVUP454ok=",
+      "dev": true
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "esutils": "2.0.2",
+        "js-tokens": "3.0.2"
+      }
+    },
+    "balanced-match": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+      "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "1.0.1",
+        "class-utils": "0.3.6",
+        "component-emitter": "1.2.1",
+        "define-property": "1.0.0",
+        "isobject": "3.0.1",
+        "mixin-deep": "1.3.1",
+        "pascalcase": "0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "1.0.2"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+      "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "tweetnacl": "0.14.5"
+      }
+    },
+    "binary-extensions": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.9.0.tgz",
+      "integrity": "sha1-ZlBsFs5vTWkopbPNajPKQelB43s=",
+      "dev": true
+    },
+    "brace-expansion": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz",
+      "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=",
+      "dev": true,
+      "requires": {
+        "balanced-match": "0.4.2",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+      "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+      "dev": true,
+      "requires": {
+        "expand-range": "1.8.2",
+        "preserve": "0.2.0",
+        "repeat-element": "1.1.2"
+      }
+    },
+    "buffer-from": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz",
+      "integrity": "sha1-h/yqOimDWOCt5uRCz86EB0DRrQQ=",
+      "dev": true
+    },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "dev": true
+    },
+    "bytes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+      "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+      "dev": true
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "collection-visit": "1.0.0",
+        "component-emitter": "1.2.1",
+        "get-value": "2.0.6",
+        "has-value": "1.0.0",
+        "isobject": "3.0.1",
+        "set-value": "2.0.0",
+        "to-object-path": "0.3.0",
+        "union-value": "1.0.0",
+        "unset-value": "1.0.0"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "caller-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+      "dev": true,
+      "requires": {
+        "callsites": "0.2.0"
+      }
+    },
+    "callsites": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+      "dev": true
+    },
+    "camelcase": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+      "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+      "dev": true
+    },
+    "camelcase-keys": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+      "dev": true,
+      "requires": {
+        "camelcase": "2.1.1",
+        "map-obj": "1.0.1"
+      }
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "2.2.1",
+        "escape-string-regexp": "1.0.5",
+        "has-ansi": "2.0.0",
+        "strip-ansi": "3.0.1",
+        "supports-color": "2.0.0"
+      }
+    },
+    "chardet": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+      "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
+      "dev": true
+    },
+    "chokidar": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+      "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+      "dev": true,
+      "requires": {
+        "anymatch": "1.3.2",
+        "async-each": "1.0.1",
+        "fsevents": "1.2.4",
+        "glob-parent": "2.0.0",
+        "inherits": "2.0.3",
+        "is-binary-path": "1.0.1",
+        "is-glob": "2.0.1",
+        "path-is-absolute": "1.0.1",
+        "readdirp": "2.1.0"
+      }
+    },
+    "circular-json": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+      "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+      "dev": true
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "3.1.0",
+        "define-property": "0.2.5",
+        "isobject": "3.0.1",
+        "static-extend": "0.1.2"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "2.0.0"
+      }
+    },
+    "cli-width": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+      "dev": true
+    },
+    "clone": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
+      "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=",
+      "dev": true
+    },
+    "clone-buffer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+      "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
+      "dev": true
+    },
+    "clone-stats": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+      "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+      "dev": true
+    },
+    "cloneable-readable": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz",
+      "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "process-nextick-args": "2.0.0",
+        "readable-stream": "2.3.6"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "2.0.0",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.1.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+      "dev": true
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "1.0.0",
+        "object-visit": "1.0.1"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
+      "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "combined-stream": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+      "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz",
+      "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+      "dev": true
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "1.1.0",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.6",
+        "typedarray": "0.0.6"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "2.0.0",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.1.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "concurrently": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.5.1.tgz",
+      "integrity": "sha1-7otgAYu+hrAt8T5SSUU8bs7NJSE=",
+      "dev": true,
+      "requires": {
+        "chalk": "0.5.1",
+        "commander": "2.6.0",
+        "date-fns": "1.29.0",
+        "lodash": "4.17.4",
+        "rx": "2.3.24",
+        "spawn-command": "0.0.2-1",
+        "supports-color": "3.2.3",
+        "tree-kill": "1.2.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
+          "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
+          "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
+          "dev": true
+        },
+        "chalk": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
+          "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "1.1.0",
+            "escape-string-regexp": "1.0.5",
+            "has-ansi": "0.1.0",
+            "strip-ansi": "0.3.0",
+            "supports-color": "0.2.0"
+          },
+          "dependencies": {
+            "supports-color": {
+              "version": "0.2.0",
+              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
+              "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
+              "dev": true
+            }
+          }
+        },
+        "has-ansi": {
+          "version": "0.1.0",
+          "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
+          "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "0.2.1"
+          }
+        },
+        "has-flag": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.4",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+          "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
+          "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "0.2.1"
+          }
+        },
+        "supports-color": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "dev": true,
+          "requires": {
+            "has-flag": "1.0.0"
+          }
+        }
+      }
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "cross-spawn": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+      "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+      "dev": true,
+      "requires": {
+        "lru-cache": "4.1.3",
+        "shebang-command": "1.2.0",
+        "which": "1.3.1"
+      }
+    },
+    "currently-unhandled": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+      "dev": true,
+      "requires": {
+        "array-find-index": "1.0.2"
+      }
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0"
+      }
+    },
+    "date-fns": {
+      "version": "1.29.0",
+      "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz",
+      "integrity": "sha1-EuYJzcuTUScxHQTTMzTilgoqVOY=",
+      "dev": true
+    },
+    "debug": {
+      "version": "2.6.8",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+      "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+      "dev": true,
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "deep-extend": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+      "integrity": "sha1-xPp8lUBKF6nD6Mp+FTcxK3NjMKw=",
+      "dev": true
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "1.0.2",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "del": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+      "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+      "dev": true,
+      "requires": {
+        "globby": "5.0.0",
+        "is-path-cwd": "1.0.0",
+        "is-path-in-cwd": "1.0.1",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "rimraf": "2.5.4"
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "detect-file": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+      "dev": true
+    },
+    "doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "requires": {
+        "esutils": "2.0.2"
+      }
+    },
+    "ecc-jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "jsbn": "0.1.1"
+      }
+    },
+    "electron": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/electron/-/electron-2.0.2.tgz",
+      "integrity": "sha1-t34F+DQZzF7JIaLSHzW1Xkv8PWg=",
+      "dev": true,
+      "requires": {
+        "@types/node": "8.10.17",
+        "electron-download": "3.3.0",
+        "extract-zip": "1.6.7"
+      }
+    },
+    "electron-download": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-3.3.0.tgz",
+      "integrity": "sha1-LP1U1pZsAZxNSa1l++Zcyc3vaMg=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.8",
+        "fs-extra": "0.30.0",
+        "home-path": "1.0.6",
+        "minimist": "1.2.0",
+        "nugget": "2.0.1",
+        "path-exists": "2.1.0",
+        "rc": "1.2.8",
+        "semver": "5.4.1",
+        "sumchecker": "1.3.1"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "ensure-posix-path": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.0.2.tgz",
+      "integrity": "sha1-pls+QtC3HPxYXrd0+ZQ8jZuRsMI=",
+      "dev": true
+    },
+    "error-ex": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+      "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "0.2.1"
+      }
+    },
+    "es6-promise": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
+      "integrity": "sha1-3EIhwrFlGHYL2MOaUtjzVvwA7Sk=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "eslint": {
+      "version": "4.19.1",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
+      "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "babel-code-frame": "6.26.0",
+        "chalk": "2.4.1",
+        "concat-stream": "1.6.2",
+        "cross-spawn": "5.1.0",
+        "debug": "3.1.0",
+        "doctrine": "2.1.0",
+        "eslint-scope": "3.7.1",
+        "eslint-visitor-keys": "1.0.0",
+        "espree": "3.5.4",
+        "esquery": "1.0.1",
+        "esutils": "2.0.2",
+        "file-entry-cache": "2.0.0",
+        "functional-red-black-tree": "1.0.1",
+        "glob": "7.1.2",
+        "globals": "11.5.0",
+        "ignore": "3.3.8",
+        "imurmurhash": "0.1.4",
+        "inquirer": "3.3.0",
+        "is-resolvable": "1.1.0",
+        "js-yaml": "3.11.0",
+        "json-stable-stringify-without-jsonify": "1.0.1",
+        "levn": "0.3.0",
+        "lodash": "4.17.10",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "natural-compare": "1.4.0",
+        "optionator": "0.8.2",
+        "path-is-inside": "1.0.2",
+        "pluralize": "7.0.0",
+        "progress": "2.0.0",
+        "regexpp": "1.1.0",
+        "require-uncached": "1.0.3",
+        "semver": "5.4.1",
+        "strip-ansi": "4.0.0",
+        "strip-json-comments": "2.0.1",
+        "table": "4.0.2",
+        "text-table": "0.2.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "eslint-config-mdcs": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/eslint-config-mdcs/-/eslint-config-mdcs-4.2.3.tgz",
+      "integrity": "sha512-pSiX8roIR7KVZeKBrzQUiRAr2jxLn0H8WUHHCgq2TdoVGSLk/GRNeB78WG1IZnTwENgtSgDtMXq7/UVDBXls+Q==",
+      "dev": true
+    },
+    "eslint-scope": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
+      "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
+      "dev": true,
+      "requires": {
+        "esrecurse": "4.2.1",
+        "estraverse": "4.2.0"
+      }
+    },
+    "eslint-visitor-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+      "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+      "dev": true
+    },
+    "espree": {
+      "version": "3.5.4",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+      "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
+      "dev": true,
+      "requires": {
+        "acorn": "5.5.3",
+        "acorn-jsx": "3.0.1"
+      }
+    },
+    "esprima": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+      "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+      "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "estraverse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+      "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+      "dev": true
+    },
+    "estree-walker": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.3.1.tgz",
+      "integrity": "sha1-5rGlHPcpJSTnI3wxLl/mZgwc4ao=",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+      "dev": true
+    },
+    "exists-stat": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/exists-stat/-/exists-stat-1.0.0.tgz",
+      "integrity": "sha1-BmDjUlouidnkRhKUQMJy7foktSk=",
+      "dev": true
+    },
+    "expand-brackets": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+      "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+      "dev": true,
+      "requires": {
+        "is-posix-bracket": "0.1.1"
+      }
+    },
+    "expand-range": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+      "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+      "dev": true,
+      "requires": {
+        "fill-range": "2.2.3"
+      }
+    },
+    "expand-tilde": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "1.0.1"
+      }
+    },
+    "extend": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+      "dev": true
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "1.0.0",
+        "is-extendable": "1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+      "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
+      "dev": true,
+      "requires": {
+        "chardet": "0.4.2",
+        "iconv-lite": "0.4.23",
+        "tmp": "0.0.33"
+      }
+    },
+    "extglob": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+      "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "extract-zip": {
+      "version": "1.6.7",
+      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
+      "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
+      "dev": true,
+      "requires": {
+        "concat-stream": "1.6.2",
+        "debug": "2.6.9",
+        "mkdirp": "0.5.1",
+        "yauzl": "2.4.1"
+      },
+      "dependencies": {
+        "concat-stream": {
+          "version": "1.6.2",
+          "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+          "integrity": "sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ=",
+          "dev": true,
+          "requires": {
+            "buffer-from": "1.1.0",
+            "inherits": "2.0.3",
+            "readable-stream": "2.3.6",
+            "typedarray": "0.0.6"
+          }
+        },
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+          "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "2.0.0",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.1.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+      "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
+      "dev": true
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+      "dev": true
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "fast-url-parser": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz",
+      "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.4.1"
+      }
+    },
+    "fd-slicer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+      "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+      "dev": true,
+      "requires": {
+        "pend": "1.2.0"
+      }
+    },
+    "figures": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+      "dev": true,
+      "requires": {
+        "flat-cache": "1.3.0",
+        "object-assign": "4.1.1"
+      }
+    },
+    "filename-regex": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+      "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
+      "dev": true
+    },
+    "fill-range": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
+      "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
+      "dev": true,
+      "requires": {
+        "is-number": "2.1.0",
+        "isobject": "2.1.0",
+        "randomatic": "1.1.7",
+        "repeat-element": "1.1.2",
+        "repeat-string": "1.6.1"
+      }
+    },
+    "find-up": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+      "dev": true,
+      "requires": {
+        "path-exists": "2.1.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "findup-sync": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+      "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
+      "dev": true,
+      "requires": {
+        "detect-file": "1.0.0",
+        "is-glob": "3.1.0",
+        "micromatch": "3.1.10",
+        "resolve-dir": "1.0.1"
+      },
+      "dependencies": {
+        "arr-diff": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+          "dev": true
+        },
+        "braces": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "1.1.0",
+            "array-unique": "0.3.2",
+            "extend-shallow": "2.0.1",
+            "fill-range": "4.0.0",
+            "isobject": "3.0.1",
+            "repeat-element": "1.1.2",
+            "snapdragon": "0.8.2",
+            "snapdragon-node": "2.1.1",
+            "split-string": "3.1.0",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "expand-brackets": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+          "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+          "dev": true,
+          "requires": {
+            "debug": "2.6.8",
+            "define-property": "0.2.5",
+            "extend-shallow": "2.0.1",
+            "posix-character-classes": "0.1.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "0.2.5",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+              "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "0.1.6"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            },
+            "is-accessor-descriptor": {
+              "version": "0.1.6",
+              "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+              "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+              "dev": true,
+              "requires": {
+                "kind-of": "3.2.2"
+              },
+              "dependencies": {
+                "kind-of": {
+                  "version": "3.2.2",
+                  "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+                  "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+                  "dev": true,
+                  "requires": {
+                    "is-buffer": "1.1.5"
+                  }
+                }
+              }
+            },
+            "is-data-descriptor": {
+              "version": "0.1.4",
+              "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+              "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+              "dev": true,
+              "requires": {
+                "kind-of": "3.2.2"
+              },
+              "dependencies": {
+                "kind-of": {
+                  "version": "3.2.2",
+                  "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+                  "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+                  "dev": true,
+                  "requires": {
+                    "is-buffer": "1.1.5"
+                  }
+                }
+              }
+            },
+            "is-descriptor": {
+              "version": "0.1.6",
+              "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+              "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+              "dev": true,
+              "requires": {
+                "is-accessor-descriptor": "0.1.6",
+                "is-data-descriptor": "0.1.4",
+                "kind-of": "5.1.0"
+              }
+            },
+            "kind-of": {
+              "version": "5.1.0",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+              "dev": true
+            }
+          }
+        },
+        "extglob": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+          "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+          "dev": true,
+          "requires": {
+            "array-unique": "0.3.2",
+            "define-property": "1.0.0",
+            "expand-brackets": "2.1.4",
+            "extend-shallow": "2.0.1",
+            "fragment-cache": "0.2.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+              "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "1.0.2"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "fill-range": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "2.0.1",
+            "is-number": "3.0.0",
+            "repeat-string": "1.6.1",
+            "to-regex-range": "2.1.1"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-extglob": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+          "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+          "dev": true
+        },
+        "is-glob": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+          "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "2.1.1"
+          }
+        },
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "3.1.10",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+          "dev": true,
+          "requires": {
+            "arr-diff": "4.0.0",
+            "array-unique": "0.3.2",
+            "braces": "2.3.2",
+            "define-property": "2.0.2",
+            "extend-shallow": "3.0.2",
+            "extglob": "2.0.4",
+            "fragment-cache": "0.2.1",
+            "kind-of": "6.0.2",
+            "nanomatch": "1.2.9",
+            "object.pick": "1.3.0",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          }
+        }
+      }
+    },
+    "flat-cache": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+      "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+      "dev": true,
+      "requires": {
+        "circular-json": "0.3.3",
+        "del": "2.2.2",
+        "graceful-fs": "4.1.11",
+        "write": "0.2.1"
+      }
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "for-own": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+      "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+      "dev": true,
+      "requires": {
+        "for-in": "1.0.2"
+      }
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "form-data": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+      "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+      "dev": true,
+      "requires": {
+        "asynckit": "0.4.0",
+        "combined-stream": "1.0.6",
+        "mime-types": "2.1.18"
+      }
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "0.2.2"
+      }
+    },
+    "fs-extra": {
+      "version": "0.30.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "jsonfile": "2.4.0",
+        "klaw": "1.3.1",
+        "path-is-absolute": "1.0.1",
+        "rimraf": "2.5.4"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
+      "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nan": "2.10.0",
+        "node-pre-gyp": "0.10.0"
+      },
+      "dependencies": {
+        "abbrev": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "ansi-regex": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "aproba": {
+          "version": "1.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "are-we-there-yet": {
+          "version": "1.1.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "delegates": "1.0.0",
+            "readable-stream": "2.3.6"
+          }
+        },
+        "balanced-match": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.11",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "balanced-match": "1.0.0",
+            "concat-map": "0.0.1"
+          }
+        },
+        "chownr": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "code-point-at": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "concat-map": {
+          "version": "0.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "console-control-strings": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "core-util-is": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "debug": {
+          "version": "2.6.9",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "deep-extend": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "delegates": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "detect-libc": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "fs-minipass": {
+          "version": "1.2.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minipass": "2.2.4"
+          }
+        },
+        "fs.realpath": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "gauge": {
+          "version": "2.7.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aproba": "1.2.0",
+            "console-control-strings": "1.1.0",
+            "has-unicode": "2.0.1",
+            "object-assign": "4.1.1",
+            "signal-exit": "3.0.2",
+            "string-width": "1.0.2",
+            "strip-ansi": "3.0.1",
+            "wide-align": "1.1.2"
+          }
+        },
+        "glob": {
+          "version": "7.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "has-unicode": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "iconv-lite": {
+          "version": "0.4.21",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safer-buffer": "2.1.2"
+          }
+        },
+        "ignore-walk": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minimatch": "3.0.4"
+          }
+        },
+        "inflight": {
+          "version": "1.0.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "once": "1.4.0",
+            "wrappy": "1.0.2"
+          }
+        },
+        "inherits": {
+          "version": "2.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "ini": {
+          "version": "1.3.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.11"
+          }
+        },
+        "minimist": {
+          "version": "0.0.8",
+          "bundled": true,
+          "dev": true
+        },
+        "minipass": {
+          "version": "2.2.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1",
+            "yallist": "3.0.2"
+          }
+        },
+        "minizlib": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minipass": "2.2.4"
+          }
+        },
+        "mkdirp": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "minimist": "0.0.8"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "needle": {
+          "version": "2.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "debug": "2.6.9",
+            "iconv-lite": "0.4.21",
+            "sax": "1.2.4"
+          }
+        },
+        "node-pre-gyp": {
+          "version": "0.10.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "detect-libc": "1.0.3",
+            "mkdirp": "0.5.1",
+            "needle": "2.2.0",
+            "nopt": "4.0.1",
+            "npm-packlist": "1.1.10",
+            "npmlog": "4.1.2",
+            "rc": "1.2.7",
+            "rimraf": "2.6.2",
+            "semver": "5.5.0",
+            "tar": "4.4.1"
+          }
+        },
+        "nopt": {
+          "version": "4.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "abbrev": "1.1.1",
+            "osenv": "0.1.5"
+          }
+        },
+        "npm-bundled": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "npm-packlist": {
+          "version": "1.1.10",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ignore-walk": "3.0.1",
+            "npm-bundled": "1.0.3"
+          }
+        },
+        "npmlog": {
+          "version": "4.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "are-we-there-yet": "1.1.4",
+            "console-control-strings": "1.1.0",
+            "gauge": "2.7.4",
+            "set-blocking": "2.0.0"
+          }
+        },
+        "number-is-nan": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "object-assign": {
+          "version": "4.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "once": {
+          "version": "1.4.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "wrappy": "1.0.2"
+          }
+        },
+        "os-homedir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "os-tmpdir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "osenv": {
+          "version": "0.1.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "os-homedir": "1.0.2",
+            "os-tmpdir": "1.0.2"
+          }
+        },
+        "path-is-absolute": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "rc": {
+          "version": "1.2.7",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "deep-extend": "0.5.1",
+            "ini": "1.3.5",
+            "minimist": "1.2.0",
+            "strip-json-comments": "2.0.1"
+          },
+          "dependencies": {
+            "minimist": {
+              "version": "1.2.0",
+              "bundled": true,
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "2.0.0",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.1.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "rimraf": {
+          "version": "2.6.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "glob": "7.1.2"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "safer-buffer": {
+          "version": "2.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "sax": {
+          "version": "1.2.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "semver": {
+          "version": "5.5.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "set-blocking": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "signal-exit": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ansi-regex": "2.1.1"
+          }
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "tar": {
+          "version": "4.4.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "chownr": "1.0.1",
+            "fs-minipass": "1.2.5",
+            "minipass": "2.2.4",
+            "minizlib": "1.1.0",
+            "mkdirp": "0.5.1",
+            "safe-buffer": "5.1.1",
+            "yallist": "3.0.2"
+          }
+        },
+        "util-deprecate": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "wide-align": {
+          "version": "1.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "string-width": "1.0.2"
+          }
+        },
+        "wrappy": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "yallist": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true
+        }
+      }
+    },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
+    "get-stdin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+      "dev": true
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+      "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "1.0.0",
+        "inflight": "1.0.6",
+        "inherits": "2.0.3",
+        "minimatch": "3.0.4",
+        "once": "1.4.0",
+        "path-is-absolute": "1.0.1"
+      }
+    },
+    "glob-base": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+      "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+      "dev": true,
+      "requires": {
+        "glob-parent": "2.0.0",
+        "is-glob": "2.0.1"
+      }
+    },
+    "glob-parent": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+      "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+      "dev": true,
+      "requires": {
+        "is-glob": "2.0.1"
+      }
+    },
+    "glob-slash": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/glob-slash/-/glob-slash-1.0.0.tgz",
+      "integrity": "sha1-/lLvpDMjP3Si/mTHq7m8hIICq5U=",
+      "dev": true
+    },
+    "glob-slasher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/glob-slasher/-/glob-slasher-1.0.1.tgz",
+      "integrity": "sha1-dHoOW7IiZC7hDT4FRD4QlJPLD44=",
+      "dev": true,
+      "requires": {
+        "glob-slash": "1.0.0",
+        "lodash.isobject": "2.4.1",
+        "toxic": "1.0.0"
+      }
+    },
+    "global-modules": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+      "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+      "dev": true,
+      "requires": {
+        "global-prefix": "1.0.2",
+        "is-windows": "1.0.2",
+        "resolve-dir": "1.0.1"
+      }
+    },
+    "global-prefix": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+      "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "2.0.2",
+        "homedir-polyfill": "1.0.1",
+        "ini": "1.3.4",
+        "is-windows": "1.0.2",
+        "which": "1.3.1"
+      }
+    },
+    "globals": {
+      "version": "11.5.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz",
+      "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==",
+      "dev": true
+    },
+    "globby": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+      "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+      "dev": true,
+      "requires": {
+        "array-union": "1.0.2",
+        "arrify": "1.0.1",
+        "glob": "7.1.2",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "google-closure-compiler": {
+      "version": "20180506.0.0",
+      "resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20180506.0.0.tgz",
+      "integrity": "sha1-9ZzDTb+Mmk9I+6Prss8JjSXjRas=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "vinyl": "2.1.0",
+        "vinyl-sourcemaps-apply": "0.2.1"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.1.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+      "dev": true
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true
+    },
+    "har-validator": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+      "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "har-schema": "2.0.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "5.5.2",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+          "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+          "dev": true,
+          "requires": {
+            "co": "4.6.0",
+            "fast-deep-equal": "1.0.0",
+            "fast-json-stable-stringify": "2.0.0",
+            "json-schema-traverse": "0.3.1"
+          }
+        }
+      }
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "2.0.6",
+        "has-values": "1.0.0",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "kind-of": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.5"
+          }
+        }
+      }
+    },
+    "home-path": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.6.tgz",
+      "integrity": "sha1-1UncJGU4in+GZyQsWzFYjSmvKfw=",
+      "dev": true
+    },
+    "homedir-polyfill": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
+      "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
+      "dev": true,
+      "requires": {
+        "parse-passwd": "1.0.0"
+      }
+    },
+    "hosted-git-info": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz",
+      "integrity": "sha1-IyNbKasjDFdqqw1PE/wEawsDgiI=",
+      "dev": true
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "jsprim": "1.4.1",
+        "sshpk": "1.14.1"
+      }
+    },
+    "iconv-lite": {
+      "version": "0.4.23",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+      "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": "2.1.2"
+      }
+    },
+    "ignore": {
+      "version": "3.3.8",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz",
+      "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==",
+      "dev": true
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "indent-string": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+      "dev": true,
+      "requires": {
+        "repeating": "2.0.1"
+      }
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "1.4.0",
+        "wrappy": "1.0.2"
+      }
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true
+    },
+    "ini": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+      "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
+      "dev": true
+    },
+    "inquirer": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+      "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "3.1.0",
+        "chalk": "2.4.1",
+        "cli-cursor": "2.1.0",
+        "cli-width": "2.2.0",
+        "external-editor": "2.2.0",
+        "figures": "2.0.0",
+        "lodash": "4.17.10",
+        "mute-stream": "0.0.7",
+        "run-async": "2.3.0",
+        "rx-lite": "4.0.8",
+        "rx-lite-aggregates": "4.0.8",
+        "string-width": "2.1.1",
+        "strip-ansi": "4.0.0",
+        "through": "2.3.8"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "2.0.0",
+            "strip-ansi": "4.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+      "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "1.9.0"
+      }
+    },
+    "is-buffer": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+      "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
+      "dev": true
+    },
+    "is-builtin-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+      "dev": true,
+      "requires": {
+        "builtin-modules": "1.1.1"
+      }
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "0.1.6",
+        "is-data-descriptor": "0.1.4",
+        "kind-of": "5.1.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-dotfile": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+      "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
+      "dev": true
+    },
+    "is-equal-shallow": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+      "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+      "dev": true,
+      "requires": {
+        "is-primitive": "2.0.0"
+      }
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+      "dev": true
+    },
+    "is-finite": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+      "dev": true,
+      "requires": {
+        "number-is-nan": "1.0.1"
+      }
+    },
+    "is-fullwidth-code-point": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+      "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+      "dev": true,
+      "requires": {
+        "number-is-nan": "1.0.1"
+      }
+    },
+    "is-glob": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "is-number": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+      "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "is-odd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
+      "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
+      "dev": true,
+      "requires": {
+        "is-number": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+          "dev": true
+        }
+      }
+    },
+    "is-path-cwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+      "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+      "dev": true
+    },
+    "is-path-in-cwd": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
+      "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "1.0.1"
+      }
+    },
+    "is-path-inside": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+      "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "1.0.2"
+      }
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "is-posix-bracket": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+      "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
+      "dev": true
+    },
+    "is-primitive": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+      "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
+      "dev": true
+    },
+    "is-promise": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+      "dev": true
+    },
+    "is-resolvable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+      "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+      "dev": true
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "dev": true
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isobject": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+      "dev": true,
+      "requires": {
+        "isarray": "1.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        }
+      }
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "js-reporters": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/js-reporters/-/js-reporters-1.2.1.tgz",
+      "integrity": "sha1-+IxgjjJKM3OpW8xFrTBeXJecRZs=",
+      "dev": true
+    },
+    "js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+      "dev": true
+    },
+    "js-yaml": {
+      "version": "3.11.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
+      "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
+      "dev": true,
+      "requires": {
+        "argparse": "1.0.10",
+        "esprima": "4.0.0"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true,
+      "optional": true
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "json-schema-traverse": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+      "dev": true
+    },
+    "json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+      "dev": true
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "dev": true
+    },
+    "jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      }
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "requires": {
+        "is-buffer": "1.1.5"
+      }
+    },
+    "klaw": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+      "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      }
+    },
+    "levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2"
+      }
+    },
+    "load-json-file": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "parse-json": "2.2.0",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "strip-bom": "2.0.0"
+      }
+    },
+    "lodash": {
+      "version": "4.17.10",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
+      "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+      "dev": true
+    },
+    "lodash._objecttypes": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz",
+      "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=",
+      "dev": true
+    },
+    "lodash.isobject": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
+      "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
+      "dev": true,
+      "requires": {
+        "lodash._objecttypes": "2.4.1"
+      }
+    },
+    "loud-rejection": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+      "dev": true,
+      "requires": {
+        "currently-unhandled": "0.4.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "lru-cache": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
+      "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
+      "dev": true,
+      "requires": {
+        "pseudomap": "1.0.2",
+        "yallist": "2.1.2"
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "1.0.1"
+      }
+    },
+    "matcher-collection": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.0.5.tgz",
+      "integrity": "sha512-nUCmzKipcJEwYsBVAFh5P+d7JBuhJaW1xs85Hara9xuMLqtCVUrW6DSC0JVIkluxEH2W45nPBM/wjHtBXa/tYA==",
+      "dev": true,
+      "requires": {
+        "minimatch": "3.0.4"
+      }
+    },
+    "meow": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+      "dev": true,
+      "requires": {
+        "camelcase-keys": "2.1.0",
+        "decamelize": "1.2.0",
+        "loud-rejection": "1.6.0",
+        "map-obj": "1.0.1",
+        "minimist": "1.2.0",
+        "normalize-package-data": "2.4.0",
+        "object-assign": "4.1.1",
+        "read-pkg-up": "1.0.1",
+        "redent": "1.0.0",
+        "trim-newlines": "1.0.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "micromatch": {
+      "version": "2.3.11",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+      "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+      "dev": true,
+      "requires": {
+        "arr-diff": "2.0.0",
+        "array-unique": "0.2.1",
+        "braces": "1.8.5",
+        "expand-brackets": "0.1.5",
+        "extglob": "0.3.2",
+        "filename-regex": "2.0.1",
+        "is-extglob": "1.0.0",
+        "is-glob": "2.0.1",
+        "kind-of": "3.2.2",
+        "normalize-path": "2.1.1",
+        "object.omit": "2.0.1",
+        "parse-glob": "3.0.4",
+        "regex-cache": "0.4.3"
+      }
+    },
+    "mime": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
+      "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.33.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+      "integrity": "sha1-o0kgUKXLm2NFBUHjnZeI0icng9s=",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.18",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+      "integrity": "sha1-bzI/YKg9ERRvgx/xH9ZuL+VQO7g=",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.33.0"
+      }
+    },
+    "mimic-fn": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+      "dev": true
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
+      "requires": {
+        "brace-expansion": "1.1.11"
+      },
+      "dependencies": {
+        "balanced-match": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.11",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "1.0.0",
+            "concat-map": "0.0.1"
+          }
+        }
+      }
+    },
+    "minimist": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+      "dev": true
+    },
+    "mixin-deep": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+      "dev": true,
+      "requires": {
+        "for-in": "1.0.2",
+        "is-extendable": "1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "2.0.4"
+          }
+        }
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "dev": true,
+      "requires": {
+        "minimist": "0.0.8"
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "mute-stream": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+      "dev": true
+    },
+    "nan": {
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
+      "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
+      "dev": true,
+      "optional": true
+    },
+    "nanomatch": {
+      "version": "1.2.9",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
+      "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "4.0.0",
+        "array-unique": "0.3.2",
+        "define-property": "2.0.2",
+        "extend-shallow": "3.0.2",
+        "fragment-cache": "0.2.1",
+        "is-odd": "2.0.0",
+        "is-windows": "1.0.2",
+        "kind-of": "6.0.2",
+        "object.pick": "1.3.0",
+        "regex-not": "1.0.2",
+        "snapdragon": "0.8.2",
+        "to-regex": "3.0.2"
+      },
+      "dependencies": {
+        "arr-diff": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "natural-compare": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "dev": true
+    },
+    "normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=",
+      "dev": true,
+      "requires": {
+        "hosted-git-info": "2.6.0",
+        "is-builtin-module": "1.0.0",
+        "semver": "5.4.1",
+        "validate-npm-package-license": "3.0.3"
+      }
+    },
+    "normalize-path": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+      "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+      "dev": true,
+      "requires": {
+        "remove-trailing-separator": "1.0.2"
+      }
+    },
+    "nugget": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz",
+      "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.8",
+        "minimist": "1.2.0",
+        "pretty-bytes": "1.0.4",
+        "progress-stream": "1.2.0",
+        "request": "2.87.0",
+        "single-line-log": "1.1.2",
+        "throttleit": "0.0.2"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+      "dev": true
+    },
+    "oauth-sign": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+      "dev": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
+    },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "0.1.1",
+        "define-property": "0.2.5",
+        "kind-of": "3.2.2"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        }
+      }
+    },
+    "object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "object.omit": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+      "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+      "dev": true,
+      "requires": {
+        "for-own": "0.1.5",
+        "is-extendable": "0.1.1"
+      }
+    },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "requires": {
+        "wrappy": "1.0.2"
+      }
+    },
+    "onetime": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "1.2.0"
+      }
+    },
+    "optionator": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+      "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+      "dev": true,
+      "requires": {
+        "deep-is": "0.1.3",
+        "fast-levenshtein": "2.0.6",
+        "levn": "0.3.0",
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2",
+        "wordwrap": "1.0.0"
+      }
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true
+    },
+    "parse-glob": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+      "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+      "dev": true,
+      "requires": {
+        "glob-base": "0.3.0",
+        "is-dotfile": "1.0.3",
+        "is-extglob": "1.0.0",
+        "is-glob": "2.0.1"
+      }
+    },
+    "parse-json": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+      "dev": true,
+      "requires": {
+        "error-ex": "1.3.1"
+      }
+    },
+    "parse-passwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+      "dev": true
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
+    "path-exists": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+      "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+      "dev": true,
+      "requires": {
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
+    },
+    "path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+      "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+      "dev": true
+    },
+    "path-to-regexp": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz",
+      "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==",
+      "dev": true
+    },
+    "path-type": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "pend": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+      "dev": true
+    },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+      "dev": true
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "dev": true,
+      "requires": {
+        "pinkie": "2.0.4"
+      }
+    },
+    "pluralize": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+      "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
+      "dev": true
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
+    },
+    "prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "dev": true
+    },
+    "preserve": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+      "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
+      "dev": true
+    },
+    "pretty-bytes": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
+      "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "4.0.1",
+        "meow": "3.7.0"
+      }
+    },
+    "process-nextick-args": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+      "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+      "dev": true
+    },
+    "progress": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+      "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
+      "dev": true
+    },
+    "progress-stream": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz",
+      "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=",
+      "dev": true,
+      "requires": {
+        "speedometer": "0.1.4",
+        "through2": "0.2.3"
+      }
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "punycode": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+      "dev": true
+    },
+    "qs": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+      "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=",
+      "dev": true
+    },
+    "qunit": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.6.1.tgz",
+      "integrity": "sha512-AaILHe41G+fVC8h5wrp8U31iM2tRxLAVwH1tICtDkRbC1HDgJBjjYq0SMCZE8K3Z16MiZq3vhNhLu18KeDtS6Q==",
+      "dev": true,
+      "requires": {
+        "chokidar": "1.7.0",
+        "commander": "2.12.2",
+        "exists-stat": "1.0.0",
+        "findup-sync": "2.0.0",
+        "js-reporters": "1.2.1",
+        "resolve": "1.5.0",
+        "walk-sync": "0.3.2"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.12.2",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
+          "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
+          "dev": true
+        }
+      }
+    },
+    "randomatic": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
+      "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "kind-of": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.5"
+          }
+        }
+      }
+    },
+    "rc": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+      "integrity": "sha1-zZJL9SAKB1uDwYjNa54hG3/A0+0=",
+      "dev": true,
+      "requires": {
+        "deep-extend": "0.6.0",
+        "ini": "1.3.4",
+        "minimist": "1.2.0",
+        "strip-json-comments": "2.0.1"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+          "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+          "dev": true
+        }
+      }
+    },
+    "read-pkg": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+      "dev": true,
+      "requires": {
+        "load-json-file": "1.1.0",
+        "normalize-package-data": "2.4.0",
+        "path-type": "1.1.0"
+      }
+    },
+    "read-pkg-up": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+      "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+      "dev": true,
+      "requires": {
+        "find-up": "1.1.2",
+        "read-pkg": "1.1.0"
+      }
+    },
+    "readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "requires": {
+        "core-util-is": "1.0.2",
+        "inherits": "2.0.3",
+        "isarray": "0.0.1",
+        "string_decoder": "0.10.31"
+      }
+    },
+    "readdirp": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+      "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "minimatch": "3.0.4",
+        "readable-stream": "2.3.3",
+        "set-immediate-shim": "1.0.1"
+      },
+      "dependencies": {
+        "balanced-match": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.8",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+          "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+          "dev": true,
+          "requires": {
+            "balanced-match": "1.0.0",
+            "concat-map": "0.0.1"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+          "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.8"
+          }
+        },
+        "readable-stream": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+          "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "1.0.7",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.0.3",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+          "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "redent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+      "dev": true,
+      "requires": {
+        "indent-string": "2.1.0",
+        "strip-indent": "1.0.1"
+      }
+    },
+    "regex-cache": {
+      "version": "0.4.3",
+      "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz",
+      "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=",
+      "dev": true,
+      "requires": {
+        "is-equal-shallow": "0.1.3",
+        "is-primitive": "2.0.0"
+      }
+    },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "3.0.2",
+        "safe-regex": "1.1.0"
+      }
+    },
+    "regexpp": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
+      "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==",
+      "dev": true
+    },
+    "registry-auth-token": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
+      "integrity": "sha1-hR/UkDjuy1hpERFa+EUmDuyYPyA=",
+      "dev": true,
+      "requires": {
+        "rc": "1.2.8",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "registry-url": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
+      "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
+      "dev": true,
+      "requires": {
+        "rc": "1.2.8"
+      }
+    },
+    "remove-trailing-separator": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz",
+      "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=",
+      "dev": true
+    },
+    "repeat-element": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+      "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true
+    },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "dev": true,
+      "requires": {
+        "is-finite": "1.0.2"
+      }
+    },
+    "replace-ext": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+      "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+      "dev": true
+    },
+    "request": {
+      "version": "2.87.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
+      "integrity": "sha1-MvACNc0I1IK00NaNuTqCnA7VdW4=",
+      "dev": true,
+      "requires": {
+        "aws-sign2": "0.7.0",
+        "aws4": "1.7.0",
+        "caseless": "0.12.0",
+        "combined-stream": "1.0.6",
+        "extend": "3.0.1",
+        "forever-agent": "0.6.1",
+        "form-data": "2.3.2",
+        "har-validator": "5.0.3",
+        "http-signature": "1.2.0",
+        "is-typedarray": "1.0.0",
+        "isstream": "0.1.2",
+        "json-stringify-safe": "5.0.1",
+        "mime-types": "2.1.18",
+        "oauth-sign": "0.8.2",
+        "performance-now": "2.1.0",
+        "qs": "6.5.2",
+        "safe-buffer": "5.1.1",
+        "tough-cookie": "2.3.4",
+        "tunnel-agent": "0.6.0",
+        "uuid": "3.2.1"
+      },
+      "dependencies": {
+        "uuid": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
+          "integrity": "sha1-EsUou51Y0LkmXZovbw/ovhf/HxQ=",
+          "dev": true
+        }
+      }
+    },
+    "require-relative": {
+      "version": "0.8.7",
+      "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz",
+      "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=",
+      "dev": true
+    },
+    "require-uncached": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+      "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+      "dev": true,
+      "requires": {
+        "caller-path": "0.1.0",
+        "resolve-from": "1.0.1"
+      }
+    },
+    "resolve": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
+      "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
+      "dev": true,
+      "requires": {
+        "path-parse": "1.0.5"
+      }
+    },
+    "resolve-dir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+      "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "2.0.2",
+        "global-modules": "1.0.0"
+      }
+    },
+    "resolve-from": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+      "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "restore-cursor": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+      "dev": true,
+      "requires": {
+        "onetime": "2.0.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
+    "rimraf": {
+      "version": "2.5.4",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz",
+      "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=",
+      "dev": true,
+      "requires": {
+        "glob": "7.1.1"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.1",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
+          "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.3",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.3",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
+          "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.6"
+          }
+        }
+      }
+    },
+    "rollup": {
+      "version": "0.59.4",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.59.4.tgz",
+      "integrity": "sha512-ISiMqq/aJa+57QxX2MRcvLESHdJ7wSavmr6U1euMr+6UgFe6KM+3QANrYy8LQofwhTC1I7BcAdlLnDiaODs1BA==",
+      "dev": true,
+      "requires": {
+        "@types/estree": "0.0.39",
+        "@types/node": "8.10.17"
+      }
+    },
+    "rollup-pluginutils": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz",
+      "integrity": "sha1-fslbNXP2VDpGpkYb2afFRFJdD8A=",
+      "dev": true,
+      "requires": {
+        "estree-walker": "0.3.1",
+        "micromatch": "2.3.11"
+      }
+    },
+    "rollup-watch": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/rollup-watch/-/rollup-watch-4.3.1.tgz",
+      "integrity": "sha1-WqHq6reHrd82iQXRArOdb8XOSos=",
+      "dev": true,
+      "requires": {
+        "chokidar": "1.7.0",
+        "require-relative": "0.8.7",
+        "rollup-pluginutils": "2.0.1"
+      }
+    },
+    "run-async": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+      "dev": true,
+      "requires": {
+        "is-promise": "2.1.0"
+      }
+    },
+    "rx": {
+      "version": "2.3.24",
+      "resolved": "https://registry.npmjs.org/rx/-/rx-2.3.24.tgz",
+      "integrity": "sha1-FPlQpCF9fjXapxu8vljv9o6ksrc=",
+      "dev": true
+    },
+    "rx-lite": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+      "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
+      "dev": true
+    },
+    "rx-lite-aggregates": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
+      "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+      "dev": true,
+      "requires": {
+        "rx-lite": "4.0.8"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+      "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=",
+      "dev": true
+    },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "0.1.15"
+      }
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "semver": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+      "integrity": "sha1-4FnAnYVx8FQII3M0M1BdOi8AsY4=",
+      "dev": true
+    },
+    "serve": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/serve/-/serve-7.1.2.tgz",
+      "integrity": "sha512-j4FUohDvyssavjkE3xJiTPZ2jKxseCT+C/LTgcCBYILouvNEBwbEWpR33sxQNMivWsuNgaNpwcLagNPP8VNuiw==",
+      "dev": true,
+      "requires": {
+        "@zeit/schemas": "1.1.2",
+        "ajv": "6.5.0",
+        "arg": "2.0.0",
+        "chalk": "2.4.1",
+        "serve-handler": "2.3.13",
+        "update-check": "1.5.2"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.5.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz",
+          "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "2.0.1",
+            "fast-json-stable-stringify": "2.0.0",
+            "json-schema-traverse": "0.3.1",
+            "uri-js": "4.2.2"
+          }
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "fast-deep-equal": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+          "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "serve-handler": {
+      "version": "2.3.13",
+      "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-2.3.13.tgz",
+      "integrity": "sha512-qQTg8i5X8YTtzOdMHEedC2Xr50ptXWVrIt22QWIpKgO0pZXZsFYbPB00yoLc02U4xv/3X884/wZD5q9dr+RfcQ==",
+      "dev": true,
+      "requires": {
+        "bytes": "3.0.0",
+        "fast-url-parser": "1.1.3",
+        "glob-slasher": "1.0.1",
+        "mime": "2.3.1",
+        "minimatch": "3.0.4",
+        "path-to-regexp": "2.2.1"
+      },
+      "dependencies": {
+        "balanced-match": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.11",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "1.0.0",
+            "concat-map": "0.0.1"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.11"
+          }
+        }
+      }
+    },
+    "set-immediate-shim": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+      "dev": true
+    },
+    "set-value": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "2.0.1",
+        "is-extendable": "0.1.1",
+        "is-plain-object": "2.0.4",
+        "split-string": "3.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        }
+      }
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "signal-exit": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "dev": true
+    },
+    "single-line-log": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz",
+      "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=",
+      "dev": true,
+      "requires": {
+        "string-width": "1.0.2"
+      }
+    },
+    "slice-ansi": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
+      "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+      "dev": true,
+      "requires": {
+        "is-fullwidth-code-point": "2.0.0"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "base": "0.11.2",
+        "debug": "2.6.8",
+        "define-property": "0.2.5",
+        "extend-shallow": "2.0.1",
+        "map-cache": "0.2.2",
+        "source-map": "0.5.6",
+        "source-map-resolve": "0.5.2",
+        "use": "3.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "1.0.0",
+        "isobject": "3.0.1",
+        "snapdragon-util": "3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "1.0.2"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "source-map": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
+      "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
+      "dev": true
+    },
+    "source-map-resolve": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+      "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+      "dev": true,
+      "requires": {
+        "atob": "2.1.1",
+        "decode-uri-component": "0.2.0",
+        "resolve-url": "0.2.1",
+        "source-map-url": "0.4.0",
+        "urix": "0.1.0"
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "spawn-command": {
+      "version": "0.0.2-1",
+      "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
+      "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
+      "integrity": "sha1-BaW01xU6GVvJLDxCW2nzsqlSTII=",
+      "dev": true,
+      "requires": {
+        "spdx-expression-parse": "3.0.0",
+        "spdx-license-ids": "3.0.0"
+      }
+    },
+    "spdx-exceptions": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
+      "integrity": "sha1-LHrmEFbHFKW5ubKyr30xHvXHj+k=",
+      "dev": true
+    },
+    "spdx-expression-parse": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+      "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=",
+      "dev": true,
+      "requires": {
+        "spdx-exceptions": "2.1.0",
+        "spdx-license-ids": "3.0.0"
+      }
+    },
+    "spdx-license-ids": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
+      "integrity": "sha1-enzShHDMbToc/m1miG9rxDDTrIc=",
+      "dev": true
+    },
+    "speedometer": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz",
+      "integrity": "sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0=",
+      "dev": true
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "3.0.2"
+      }
+    },
+    "sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
+    "sshpk": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
+      "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
+      "dev": true,
+      "requires": {
+        "asn1": "0.2.3",
+        "assert-plus": "1.0.0",
+        "bcrypt-pbkdf": "1.0.1",
+        "dashdash": "1.14.1",
+        "ecc-jsbn": "0.1.1",
+        "getpass": "0.1.7",
+        "jsbn": "0.1.1",
+        "tweetnacl": "0.14.5"
+      }
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "0.2.5",
+        "object-copy": "0.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        }
+      }
+    },
+    "string-width": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+      "dev": true,
+      "requires": {
+        "code-point-at": "1.1.0",
+        "is-fullwidth-code-point": "1.0.0",
+        "strip-ansi": "3.0.1"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "2.1.1"
+          }
+        }
+      }
+    },
+    "string_decoder": {
+      "version": "0.10.31",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+      "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+      "dev": true
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "dev": true,
+      "requires": {
+        "is-utf8": "0.2.1"
+      }
+    },
+    "strip-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "4.0.1"
+      }
+    },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true
+    },
+    "sumchecker": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-1.3.1.tgz",
+      "integrity": "sha1-ebs7RFbdBPGOvbwNcDodHa7FEF0=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.8",
+        "es6-promise": "4.2.4"
+      }
+    },
+    "supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+      "dev": true
+    },
+    "table": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
+      "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "ajv-keywords": "2.1.1",
+        "chalk": "2.4.1",
+        "lodash": "4.17.10",
+        "slice-ansi": "1.0.0",
+        "string-width": "2.1.1"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "2.0.0",
+            "strip-ansi": "4.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true
+    },
+    "throttleit": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
+      "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=",
+      "dev": true
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "through2": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
+      "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "1.1.14",
+        "xtend": "2.1.2"
+      }
+    },
+    "tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "requires": {
+        "os-tmpdir": "1.0.2"
+      }
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "2.0.2",
+        "extend-shallow": "3.0.2",
+        "regex-not": "1.0.2",
+        "safe-regex": "1.1.0"
+      }
+    },
+    "to-regex-range": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "repeat-string": "1.6.1"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          }
+        }
+      }
+    },
+    "tough-cookie": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
+      "integrity": "sha1-7GDO44rGdQY//JelwYlwV47oNlU=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.4.1"
+      }
+    },
+    "toxic": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/toxic/-/toxic-1.0.0.tgz",
+      "integrity": "sha1-8RVNi2rCGHWslDqfdAjfLf4WTqI=",
+      "dev": true,
+      "requires": {
+        "lodash": "2.4.2"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
+          "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
+          "dev": true
+        }
+      }
+    },
+    "tree-kill": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz",
+      "integrity": "sha1-WEZ4Yje0I5AU8F2xVrZDIS1MbzY=",
+      "dev": true
+    },
+    "trim-newlines": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+      "dev": true
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true,
+      "optional": true
+    },
+    "type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "1.1.2"
+      }
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "uglify-js": {
+      "version": "3.3.28",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.28.tgz",
+      "integrity": "sha512-68Rc/aA6cswiaQ5SrE979UJcXX+ADA1z33/ZsPd+fbAiVdjZ16OXdbtGO+rJUUBgK6qdf3SOPhQf3K/ybF5Miw==",
+      "dev": true,
+      "requires": {
+        "commander": "2.15.1",
+        "source-map": "0.6.1"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.15.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+          "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "union-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+      "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+      "dev": true,
+      "requires": {
+        "arr-union": "3.1.0",
+        "get-value": "2.0.6",
+        "is-extendable": "0.1.1",
+        "set-value": "0.4.3"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        },
+        "set-value": {
+          "version": "0.4.3",
+          "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+          "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "2.0.1",
+            "is-extendable": "0.1.1",
+            "is-plain-object": "2.0.4",
+            "to-object-path": "0.3.0"
+          }
+        }
+      }
+    },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "0.3.1",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "2.0.6",
+            "has-values": "0.1.4",
+            "isobject": "2.1.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "update-check": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz",
+      "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==",
+      "dev": true,
+      "requires": {
+        "registry-auth-token": "3.3.2",
+        "registry-url": "3.1.0"
+      }
+    },
+    "uri-js": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+      "dev": true,
+      "requires": {
+        "punycode": "2.1.1"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+          "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+          "dev": true
+        }
+      }
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "use": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz",
+      "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==",
+      "dev": true,
+      "requires": {
+        "kind-of": "6.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
+      "integrity": "sha1-gWQ7y+8b3+zUYjeT3EZIlIupgzg=",
+      "dev": true,
+      "requires": {
+        "spdx-correct": "3.0.0",
+        "spdx-expression-parse": "3.0.0"
+      }
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "1.3.0"
+      }
+    },
+    "vinyl": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz",
+      "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=",
+      "dev": true,
+      "requires": {
+        "clone": "2.1.1",
+        "clone-buffer": "1.0.0",
+        "clone-stats": "1.0.0",
+        "cloneable-readable": "1.1.2",
+        "remove-trailing-separator": "1.0.2",
+        "replace-ext": "1.0.0"
+      }
+    },
+    "vinyl-sourcemaps-apply": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
+      "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.6"
+      }
+    },
+    "walk-sync": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-0.3.2.tgz",
+      "integrity": "sha512-FMB5VqpLqOCcqrzA9okZFc0wq0Qbmdm396qJxvQZhDpyu0W95G9JCmp74tx7iyYnyOcBtUuKJsgIKAqjozvmmQ==",
+      "dev": true,
+      "requires": {
+        "ensure-posix-path": "1.0.2",
+        "matcher-collection": "1.0.5"
+      }
+    },
+    "which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "requires": {
+        "isexe": "2.0.0"
+      }
+    },
+    "wordwrap": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+      "dev": true
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "write": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+      "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+      "dev": true,
+      "requires": {
+        "mkdirp": "0.5.1"
+      }
+    },
+    "xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "requires": {
+        "object-keys": "0.4.0"
+      }
+    },
+    "yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+      "dev": true
+    },
+    "yauzl": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+      "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+      "dev": true,
+      "requires": {
+        "fd-slicer": "1.0.1"
+      }
+    }
+  }
+}

+ 13 - 13
package.json

@@ -1,6 +1,6 @@
 {
   "name": "three",
-  "version": "0.92.0",
+  "version": "0.93.0",
   "description": "JavaScript 3D library",
   "main": "build/three.js",
   "repository": "mrdoob/three.js",
@@ -31,8 +31,8 @@
     "build-test": "rollup -c test/rollup.unit.config.js",
     "build-uglify": "rollup -c && uglifyjs build/three.js -cm --preamble \"// threejs.org/license\" > build/three.min.js",
     "build-closure": "rollup -c && java -jar node_modules/google-closure-compiler/compiler.jar --warning_level=VERBOSE --jscomp_off=globalThis --jscomp_off=checkTypes --externs utils/build/externs.js --language_in=ECMASCRIPT5_STRICT --js build/three.js --js_output_file build/three.min.js",
-    "dev": "concurrently --names \"ROLLUP,HTTP\" -c \"bgBlue.bold,bgGreen.bold\" \"rollup -c -w -m inline\" \"serve --port 8080\"",
-    "dev-test": "concurrently --names \"ROLLUP,ROLLUPTEST,HTTP\" -c \"bgBlue.bold,bgRed.bold,bgGreen.bold\" \"rollup -c -w -m inline\" \"rollup -c test/rollup.unit.config.js -w -m inline\" \"serve --port 8080\"",
+    "dev": "concurrently --names \"ROLLUP,HTTP\" -c \"bgBlue.bold,bgGreen.bold\" \"rollup -c -w -m inline\" \"serve --listen 8080\"",
+    "dev-test": "concurrently --names \"ROLLUP,ROLLUPTEST,HTTP\" -c \"bgBlue.bold,bgRed.bold,bgGreen.bold\" \"rollup -c -w -m inline\" \"rollup -c test/rollup.unit.config.js -w -m inline\" \"serve --listen 8080\"",
     "start": "npm run dev",
     "lint": "eslint src",
     "test": "npm run build-test && qunit test/unit/three.source.unit.js",
@@ -52,15 +52,15 @@
   },
   "homepage": "https://threejs.org/",
   "devDependencies": {
-    "concurrently": "^3.5.0",
-    "electron": "~1.8.4",
-    "eslint": "^4.1.1",
-    "eslint-config-mdcs": "^4.2.2",
-    "google-closure-compiler": "20180204.0.0",
-    "qunit": "^2.5.1",
-    "rollup": "^0.57.1",
-    "rollup-watch": "^4.0.0",
-    "serve": "~6.5.3",
-    "uglify-js": "^3.0.23"
+    "concurrently": "^3.5.1",
+    "electron": "^2.0.2",
+    "eslint": "^4.19.1",
+    "eslint-config-mdcs": "^4.2.3",
+    "google-closure-compiler": "20180506.0.0",
+    "qunit": "^2.6.1",
+    "rollup": "^0.59.4",
+    "rollup-watch": "^4.3.1",
+    "serve": "^7.1.2",
+    "uglify-js": "^3.3.28"
   }
 }

+ 1 - 1
src/constants.js

@@ -1,4 +1,4 @@
-export var REVISION = '93dev';
+export var REVISION = '94dev';
 export var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 export var CullFaceNone = 0;
 export var CullFaceBack = 1;

+ 54 - 0
src/geometries/ExtrudeGeometry.js

@@ -49,6 +49,17 @@ function ExtrudeGeometry( shapes, options ) {
 ExtrudeGeometry.prototype = Object.create( Geometry.prototype );
 ExtrudeGeometry.prototype.constructor = ExtrudeGeometry;
 
+ExtrudeGeometry.prototype.toJSON = function () {
+
+	var data = Geometry.prototype.toJSON.call( this );
+
+	var shapes = this.parameters.shapes;
+	var options = this.parameters.options;
+
+	return toJSON( shapes, options, data );
+
+};
+
 // ExtrudeBufferGeometry
 
 function ExtrudeBufferGeometry( shapes, options ) {
@@ -717,6 +728,19 @@ function ExtrudeBufferGeometry( shapes, options ) {
 ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
 ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry;
 
+ExtrudeBufferGeometry.prototype.toJSON = function () {
+
+	var data = BufferGeometry.prototype.toJSON.call( this );
+
+	var shapes = this.parameters.shapes;
+	var options = this.parameters.options;
+
+	return toJSON( shapes, options, data );
+
+};
+
+//
+
 var WorldUVGenerator = {
 
 	generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {
@@ -774,5 +798,35 @@ var WorldUVGenerator = {
 	}
 };
 
+function toJSON( shapes, options, data ) {
+
+	//
+
+	data.shapes = [];
+
+	if ( Array.isArray( shapes ) ) {
+
+		for ( var i = 0, l = shapes.length; i < l; i ++ ) {
+
+			var shape = shapes[ i ];
+
+			data.shapes.push( shape.uuid );
+
+		}
+
+	} else {
+
+		data.shapes.push( shapes.uuid );
+
+	}
+
+	//
+
+	if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON();
+
+	return data;
+
+}
+
 
 export { ExtrudeGeometry, ExtrudeBufferGeometry };

+ 30 - 0
src/loaders/ObjectLoader.js

@@ -51,6 +51,7 @@ import { BufferGeometryLoader } from './BufferGeometryLoader.js';
 import { JSONLoader } from './JSONLoader.js';
 import { FileLoader } from './FileLoader.js';
 import * as Geometries from '../geometries/Geometries.js';
+import * as Curves from '../extras/curves/Curves.js';
 
 /**
  * @author mrdoob / http://mrdoob.com/
@@ -377,6 +378,35 @@ Object.assign( ObjectLoader.prototype, {
 
 						break;
 
+
+					case 'ExtrudeGeometry':
+					case 'ExtrudeBufferGeometry':
+
+						var geometryShapes = [];
+
+						for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) {
+
+							var shape = shapes[ data.shapes[ j ] ];
+
+							geometryShapes.push( shape );
+
+						}
+
+						var extrudePath = data.options.extrudePath;
+
+						if ( extrudePath !== undefined ) {
+
+							data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath );
+
+						}
+
+						geometry = new Geometries[ data.type ](
+							geometryShapes,
+							data.options
+						);
+
+						break;
+
 					case 'BufferGeometry':
 
 						geometry = bufferGeometryLoader.parse( data );

+ 10 - 0
src/math/Matrix4.js

@@ -125,6 +125,8 @@ Object.assign( Matrix4.prototype, {
 
 		return function extractRotation( m ) {
 
+			// this method does not support reflection matrices
+
 			var te = this.elements;
 			var me = m.elements;
 
@@ -135,14 +137,22 @@ Object.assign( Matrix4.prototype, {
 			te[ 0 ] = me[ 0 ] * scaleX;
 			te[ 1 ] = me[ 1 ] * scaleX;
 			te[ 2 ] = me[ 2 ] * scaleX;
+			te[ 3 ] = 0;
 
 			te[ 4 ] = me[ 4 ] * scaleY;
 			te[ 5 ] = me[ 5 ] * scaleY;
 			te[ 6 ] = me[ 6 ] * scaleY;
+			te[ 7 ] = 0;
 
 			te[ 8 ] = me[ 8 ] * scaleZ;
 			te[ 9 ] = me[ 9 ] * scaleZ;
 			te[ 10 ] = me[ 10 ] * scaleZ;
+			te[ 11 ] = 0;
+
+			te[ 12 ] = 0;
+			te[ 13 ] = 0;
+			te[ 14 ] = 0;
+			te[ 15 ] = 1;
 
 			return this;
 

+ 12 - 2
src/renderers/WebGLRenderer.js

@@ -123,6 +123,8 @@ function WebGLRenderer( parameters ) {
 
 		// internal state cache
 
+		_framebuffer = null,
+
 		_currentRenderTarget = null,
 		_currentFramebuffer = null,
 		_currentMaterialId = - 1,
@@ -290,7 +292,7 @@ function WebGLRenderer( parameters ) {
 
 	// vr
 
-	var vr = ( 'xr' in navigator ) ? new WebXRManager( _gl ) : new WebVRManager( _this );
+	var vr = ( 'xr' in navigator ) ? new WebXRManager( _this ) : new WebVRManager( _this );
 
 	this.vr = vr;
 
@@ -2396,6 +2398,14 @@ function WebGLRenderer( parameters ) {
 
 	}() );
 
+	//
+
+	this.setFramebuffer = function ( value ) {
+
+		_framebuffer = value;
+
+	};
+
 	this.getRenderTarget = function () {
 
 		return _currentRenderTarget;
@@ -2412,7 +2422,7 @@ function WebGLRenderer( parameters ) {
 
 		}
 
-		var framebuffer = null;
+		var framebuffer = _framebuffer;
 		var isCube = false;
 
 		if ( renderTarget ) {

+ 0 - 1
src/renderers/shaders/ShaderLib/meshlambert_frag.glsl

@@ -24,7 +24,6 @@ varying vec3 vLightFront;
 #include <envmap_pars_fragment>
 #include <bsdfs>
 #include <lights_pars_begin>
-#include <lights_pars_maps>
 #include <fog_pars_fragment>
 #include <shadowmap_pars_fragment>
 #include <shadowmask_pars_fragment>

+ 0 - 1
src/renderers/shaders/ShaderLib/meshlambert_vert.glsl

@@ -14,7 +14,6 @@ varying vec3 vLightFront;
 #include <envmap_pars_vertex>
 #include <bsdfs>
 #include <lights_pars_begin>
-#include <lights_pars_maps>
 #include <color_pars_vertex>
 #include <fog_pars_vertex>
 #include <morphtarget_pars_vertex>

+ 0 - 1
src/renderers/shaders/ShaderLib/meshphong_frag.glsl

@@ -22,7 +22,6 @@ uniform float opacity;
 #include <fog_pars_fragment>
 #include <bsdfs>
 #include <lights_pars_begin>
-#include <lights_pars_maps>
 #include <lights_phong_pars_fragment>
 #include <shadowmap_pars_fragment>
 #include <bumpmap_pars_fragment>

+ 1 - 1
src/renderers/webgl/WebGLAnimation.js

@@ -49,7 +49,7 @@ function WebGLAnimation() {
 
 		}
 
-	}
+	};
 
 }
 

+ 2 - 0
src/renderers/webgl/WebGLUniforms.js

@@ -1,5 +1,7 @@
 /**
  * @author tschw
+ * @author Mugen87 / https://github.com/Mugen87
+ * @author mrdoob / http://mrdoob.com/
  *
  * Uniforms of a program.
  * Those form a tree structure with a special top-level container for the root,

+ 0 - 8
src/renderers/webvr/WebVRManager.js

@@ -261,14 +261,6 @@ function WebVRManager( renderer ) {
 
 	};
 
-	// DEPRECATED
-
-	this.requestAnimationFrame = function ( callback ) {
-
-		// device.requestAnimationFrame( callback );
-
-	};
-
 }
 
 export { WebVRManager };

+ 57 - 19
src/renderers/webvr/WebXRManager.js

@@ -2,23 +2,19 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-import { Matrix4 } from '../../math/Matrix4.js';
 import { Vector4 } from '../../math/Vector4.js';
-import { Vector3 } from '../../math/Vector3.js';
-import { Quaternion } from '../../math/Quaternion.js';
 import { ArrayCamera } from '../../cameras/ArrayCamera.js';
 import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
 import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
 
-function WebXRManager( gl ) {
+function WebXRManager( renderer ) {
 
-	var scope = this;
+	var gl = renderer.context;
 
 	var device = null;
 	var session = null;
 
 	var frameOfRef = null;
-	var isExclusive = false;
 
 	var pose = null;
 
@@ -62,7 +58,7 @@ function WebXRManager( gl ) {
 
 	//
 
-	this.setSession = function ( value ) {
+	this.setSession = function ( value, options ) {
 
 		session = value;
 
@@ -70,16 +66,17 @@ function WebXRManager( gl ) {
 
 			session.addEventListener( 'end', function () {
 
-				gl.bindFramebuffer( gl.FRAMEBUFFER, null );
+				renderer.setFramebuffer( null );
 				animation.stop();
 
 			} );
 
 			session.baseLayer = new XRWebGLLayer( session, gl );
-			session.requestFrameOfReference( 'stage' ).then( function ( value ) {
+			session.requestFrameOfReference( options.frameOfReferenceType ).then( function ( value ) {
 
 				frameOfRef = value;
-				isExclusive = session.exclusive;
+
+				renderer.setFramebuffer( session.baseLayer.framebuffer );
 
 				animation.setContext( session );
 				animation.start();
@@ -90,9 +87,56 @@ function WebXRManager( gl ) {
 
 	};
 
+	function updateCamera( camera, parent ) {
+
+		if ( parent === null ) {
+
+			camera.matrixWorld.copy( camera.matrix );
+
+		} else {
+
+			camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix );
+
+		}
+
+		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
+
+	}
+
 	this.getCamera = function ( camera ) {
 
-		return isPresenting() ? cameraVR : camera;
+		if ( isPresenting() ) {
+
+			var parent = camera.parent;
+			var cameras = cameraVR.cameras;
+
+			// apply camera.parent to cameraVR
+
+			updateCamera( cameraVR, parent );
+
+			for ( var i = 0; i < cameras.length; i ++ ) {
+
+				updateCamera( cameras[ i ], parent );
+
+			}
+
+			// update camera and its children
+
+			camera.matrixWorld.copy( cameraVR.matrixWorld );
+
+			var children = camera.children;
+
+			for ( var i = 0, l = children.length; i < l; i ++ ) {
+
+				children[ i ].updateMatrixWorld( true );
+
+			}
+
+			return cameraVR;
+
+		}
+
+		return camera;
 
 	};
 
@@ -116,15 +160,13 @@ function WebXRManager( gl ) {
 			var viewMatrix = pose.getViewMatrix( view );
 
 			var camera = cameraVR.cameras[ i ];
+			camera.matrix.fromArray( viewMatrix ).getInverse( camera.matrix );
 			camera.projectionMatrix.fromArray( view.projectionMatrix );
-			camera.matrixWorldInverse.fromArray( viewMatrix );
-			camera.matrixWorld.getInverse( camera.matrixWorldInverse );
 			camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
 
 			if ( i === 0 ) {
 
-				cameraVR.matrixWorld.copy( camera.matrixWorld );
-				cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse );
+				cameraVR.matrix.copy( camera.matrix );
 
 				// HACK (mrdoob)
 				// https://github.com/w3c/webvr/issues/203
@@ -135,8 +177,6 @@ function WebXRManager( gl ) {
 
 		}
 
-		gl.bindFramebuffer( gl.FRAMEBUFFER, session.baseLayer.framebuffer );
-
 		if ( onAnimationFrameCallback ) onAnimationFrameCallback();
 
 	}
@@ -159,8 +199,6 @@ function WebXRManager( gl ) {
 
 	};
 
-	this.requestAnimationFrame = function () {};
-
 	this.submitFrame = function () {};
 
 }

+ 0 - 3
utils/exporters/blender/.gitignore

@@ -1,3 +0,0 @@
-tests/review
-__pycache__/
-tmp/

+ 1 - 66
utils/exporters/blender/README.md

@@ -1,68 +1,3 @@
 # Three.js Blender Export
 
-Exports Three.js' ASCII JSON format.
-
-## IMPORTANT
-
-The exporter (r69 and earlier) has been completely replaced. Please ensure you have removed the io_three_mesh addon from your Blender addons directory before installing the current addon (io_three).
-
-## Installation
-
-
-Recommended Blender version **>= 2.73.0**
-
-Copy the io_three folder to the scripts/addons folder. If it doesn't exist, create it. The full path is OS-dependent (see below).
-
-Once that is done, you need to activate the plugin. Open Blender preferences, look for
-Addons, search for `three`, enable the checkbox next to the `Import-Export: Three.js Format` entry.
-
-Goto Usage.
-
-### Windows
-
-Should look like this:
-
-    C:\Program Files\Blender Foundation\Blender\2.7X\scripts\addons
-    
-OR (for 2.6)
-    
-    C:\Users\USERNAME\AppData\Roaming\Blender Foundation\Blender\2.6X\scripts\addons
-
-### OSX
-
-In your user's library for user installed Blender addons:
-
-    /Users/(myuser)/Library/Application Support/Blender/2.7X/scripts/addons
-    
-OR (for 2.79)
-    
-    /Applications/Blender/blender.app/Contents/Resources/2.79/scripts/addons
-
-### Linux
-
-By default, this should look like:
-
-    /home/USERNAME/.config/blender/2.6X/scripts/addons
-
-For Ubuntu users who installed Blender 2.68 via apt-get, this is the location:
-
-    /usr/lib/blender/scripts/addons
-
-For Ubuntu users who installed Blender 2.7x via apt-get, this is the location:
-
-    /usr/share/blender/scripts/addons
-
-
-## Usage
-
-Activate the Import-Export addon under "User Preferences" > "Addons" and then use the regular Export menu within Blender, select `Three.js (json)`.
-
-
-## Enabling msgpack
-
-To enable msgpack compression copy the msgpack to scripts/modules.
-
-
-## Importer
-
-Currently there is no import functionality available.
+> **NOTICE:** The Blender exporter for the Three.js JSON format has been removed, to focus on better support for other workflows. For recommended alternatives, see [Loading 3D Models](https://threejs.org/docs/#manual/introduction/loading-3d-models). The Three.js JSON format is still fully supported for use with [Object3D.toJSON](https://threejs.org/docs/#api/core/Object3D.toJSON), the [Editor](https://threejs.org/editor/), [THREE.ObjectLoader](https://threejs.org/docs/#api/loaders/ObjectLoader), [THREE.JSONLoader](https://threejs.org/docs/#api/loaders/JSONLoader), and [converters](https://github.com/mrdoob/three.js/tree/dev/utils/converters).

+ 0 - 1059
utils/exporters/blender/addons/io_three/__init__.py

@@ -1,1059 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-import os
-import json
-import logging
-
-import bpy
-from bpy_extras.io_utils import ExportHelper
-from bpy.props import (
-    EnumProperty,
-    BoolProperty,
-    FloatProperty,
-    IntProperty,
-    StringProperty
-)
-
-from . import constants
-
-logging.basicConfig(
-    format='%(levelname)s:THREE:%(message)s',
-    level=logging.DEBUG)
-
-bl_info = {
-    'name': "Three.js Format",
-    'author': "repsac, mrdoob, yomotsu, mpk, jpweeks, rkusa, tschw, jackcaron, bhouston",
-    'version': (1, 5, 0),
-    'blender': (2, 74, 0),
-    'location': "File > Export",
-    'description': "Export Three.js formatted JSON files.",
-    'warning': "Importer not included.",
-    'wiki_url': "https://github.com/mrdoob/three.js/tree/"\
-        "master/utils/exporters/blender",
-    'tracker_url':  "https://github.com/mrdoob/three.js/issues",
-    'category': 'Import-Export'
-}
-
-
-def _geometry_types():
-    """The valid geometry types that are supported by Three.js
-
-    :return: list of tuples
-
-    """
-    keys = (constants.GLOBAL,
-            constants.GEOMETRY,
-            constants.BUFFER_GEOMETRY)
-    types = []
-    for key in keys:
-        types.append((key, key.title(), key))
-
-    return types
-
-bpy.types.Mesh.THREE_geometry_type = EnumProperty(
-    name="Geometry type",
-    description="Geometry type",
-    items=_geometry_types(),
-    default=constants.GLOBAL)
-
-class ThreeMesh(bpy.types.Panel):
-    """Creates custom properties on a mesh node"""
-
-    bl_label = 'THREE'
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-    bl_context = 'data'
-
-    def draw(self, context):
-        """
-
-        :param context:
-
-        """
-        row = self.layout.row()
-        if context.mesh:
-            row.prop(context.mesh,
-                     'THREE_geometry_type',
-                     text="Type")
-
-def _blending_types(index):
-    """Supported blending types for Three.js
-
-    :param index:
-    :type index: int
-    :returns: tuple if types (str, str, str)
-
-    """
-    types = (constants.BLENDING_TYPES.NONE,
-             constants.BLENDING_TYPES.NORMAL,
-             constants.BLENDING_TYPES.ADDITIVE,
-             constants.BLENDING_TYPES.SUBTRACTIVE,
-             constants.BLENDING_TYPES.MULTIPLY,
-             constants.BLENDING_TYPES.CUSTOM)
-    return (types[index], types[index], types[index])
-
-bpy.types.Material.THREE_blending_type = EnumProperty(
-    name="Blending type",
-    description="Blending type",
-    items=[_blending_types(x) for x in range(6)],
-    default=constants.BLENDING_TYPES.NORMAL)
-
-bpy.types.Material.THREE_depth_write = BoolProperty(default=True)
-bpy.types.Material.THREE_depth_test = BoolProperty(default=True)
-bpy.types.Material.THREE_double_sided = BoolProperty(default=False)
-
-class ThreeMaterial(bpy.types.Panel):
-    """Adds custom properties to the Materials of an object"""
-
-    bl_label = 'THREE'
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-    bl_context = 'material'
-
-    def draw(self, context):
-        """
-
-        :param context:
-
-        """
-        layout = self.layout
-        mat = context.material
-
-        if mat is not None:
-            row = layout.row()
-            row.label(text="Selected material: %s" % mat.name)
-
-            row = layout.row()
-            row.prop(mat, 'THREE_blending_type',
-                     text="Blending type")
-
-            row = layout.row()
-            row.prop(mat, 'THREE_depth_write',
-                     text="Enable depth writing")
-
-            row = layout.row()
-            row.prop(mat, 'THREE_depth_test',
-                     text="Enable depth testing")
-
-            row = layout.row()
-            row.prop(mat, 'THREE_double_sided',
-                     text="Double-sided")
-
-def _mag_filters(index):
-    """Three.js mag filters
-
-    :param index:
-    :type index: int
-    :returns: tuple with the filter values
-
-    """
-    types = (constants.LINEAR_FILTERS.LINEAR,
-             constants.NEAREST_FILTERS.NEAREST)
-    return (types[index], types[index], types[index])
-
-bpy.types.Texture.THREE_mag_filter = EnumProperty(
-    name="Mag Filter",
-    items=[_mag_filters(x) for x in range(2)],
-    default=constants.LINEAR_FILTERS.LINEAR)
-
-def _min_filters(index):
-    """Three.js min filters
-
-    :param index:
-    :type index: int
-    :returns: tuple with the filter values
-
-    """
-    types = (constants.LINEAR_FILTERS.LINEAR,
-             constants.LINEAR_FILTERS.MIP_MAP_NEAREST,
-             constants.LINEAR_FILTERS.MIP_MAP_LINEAR,
-             constants.NEAREST_FILTERS.NEAREST,
-             constants.NEAREST_FILTERS.MIP_MAP_NEAREST,
-             constants.NEAREST_FILTERS.MIP_MAP_LINEAR)
-    return (types[index], types[index], types[index])
-
-bpy.types.Texture.THREE_min_filter = EnumProperty(
-    name="Min Filter",
-    items=[_min_filters(x) for x in range(6)],
-    default=constants.LINEAR_FILTERS.MIP_MAP_LINEAR)
-
-def _mapping(index):
-    """Three.js texture mappings types
-
-    :param index:
-    :type index: int
-    :returns: tuple with the mapping values
-
-    """
-    types = (constants.MAPPING_TYPES.UV,
-             constants.MAPPING_TYPES.CUBE_REFLECTION,
-             constants.MAPPING_TYPES.CUBE_REFRACTION,
-             constants.MAPPING_TYPES.SPHERICAL_REFLECTION)
-    return (types[index], types[index], types[index])
-
-bpy.types.Texture.THREE_mapping = EnumProperty(
-    name="Mapping",
-    items=[_mapping(x) for x in range(4)],
-    default=constants.MAPPING_TYPES.UV)
-
-class ThreeTexture(bpy.types.Panel):
-    """Adds custom properties to a texture"""
-    bl_label = 'THREE'
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-    bl_context = 'texture'
-
-    #@TODO: possible to make cycles compatible?
-    def draw(self, context):
-        """
-
-        :param context:
-
-        """
-        layout = self.layout
-        tex = context.texture
-
-        if tex is not None:
-            row = layout.row()
-            row.prop(tex, 'THREE_mapping', text="Mapping")
-
-            row = layout.row()
-            row.prop(tex, 'THREE_mag_filter', text="Mag Filter")
-
-            row = layout.row()
-            row.prop(tex, 'THREE_min_filter', text="Min Filter")
-
-bpy.types.Object.THREE_export = bpy.props.BoolProperty(default=True)
-
-class ThreeObject(bpy.types.Panel):
-    """Adds custom properties to an object"""
-    bl_label = 'THREE'
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-    bl_context = 'object'
-
-    def draw(self, context):
-        """
-
-        :param context:
-
-        """
-        layout = self.layout
-        obj = context.object
-
-        row = layout.row()
-        row.prop(obj, 'THREE_export', text='Export')
-
-class ThreeExportSettings(bpy.types.Operator):
-    """Save the current export settings (gets saved in .blend)"""
-    bl_label = "Save Settings"
-    bl_idname = "scene.three_export_settings_set"
-
-    def execute(self, context):
-        cycles = context.scene.cycles
-        cycles.use_samples_final = True
-
-        context.scene[constants.EXPORT_SETTINGS_KEY] = set_settings(context.active_operator.properties)
-
-        self.report({"INFO"}, "Three Export Settings Saved")
-
-        return {"FINISHED"}
-
-def restore_export_settings(properties, settings):
-    """Restore the settings
-
-    :param properties:
-
-    """
-
-    ## Geometry {
-    properties.option_vertices = settings.get(
-        constants.VERTICES,
-        constants.EXPORT_OPTIONS[constants.VERTICES])
-
-    properties.option_faces = settings.get(
-        constants.FACES,
-        constants.EXPORT_OPTIONS[constants.FACES])
-    properties.option_normals = settings.get(
-        constants.NORMALS,
-        constants.EXPORT_OPTIONS[constants.NORMALS])
-
-    properties.option_skinning = settings.get(
-        constants.SKINNING,
-        constants.EXPORT_OPTIONS[constants.SKINNING])
-
-    properties.option_bones = settings.get(
-        constants.BONES,
-        constants.EXPORT_OPTIONS[constants.BONES])
-
-    properties.option_influences = settings.get(
-        constants.INFLUENCES_PER_VERTEX,
-        constants.EXPORT_OPTIONS[constants.INFLUENCES_PER_VERTEX])
-
-    properties.option_apply_modifiers = settings.get(
-        constants.APPLY_MODIFIERS,
-        constants.EXPORT_OPTIONS[constants.APPLY_MODIFIERS])
-
-    properties.option_extra_vgroups = settings.get(
-        constants.EXTRA_VGROUPS,
-        constants.EXPORT_OPTIONS[constants.EXTRA_VGROUPS])
-
-    properties.option_geometry_type = settings.get(
-        constants.GEOMETRY_TYPE,
-        constants.EXPORT_OPTIONS[constants.GEOMETRY_TYPE])
-
-    properties.option_index_type = settings.get(
-        constants.INDEX_TYPE,
-        constants.EXPORT_OPTIONS[constants.INDEX_TYPE])
-    ## }
-
-    ## Materials {
-    properties.option_materials = settings.get(
-        constants.MATERIALS,
-        constants.EXPORT_OPTIONS[constants.MATERIALS])
-
-    properties.option_uv_coords = settings.get(
-        constants.UVS,
-        constants.EXPORT_OPTIONS[constants.UVS])
-
-    properties.option_face_materials = settings.get(
-        constants.FACE_MATERIALS,
-        constants.EXPORT_OPTIONS[constants.FACE_MATERIALS])
-
-    properties.option_maps = settings.get(
-        constants.MAPS,
-        constants.EXPORT_OPTIONS[constants.MAPS])
-
-    properties.option_colors = settings.get(
-        constants.COLORS,
-        constants.EXPORT_OPTIONS[constants.COLORS])
-
-    properties.option_mix_colors = settings.get(
-        constants.MIX_COLORS,
-        constants.EXPORT_OPTIONS[constants.MIX_COLORS])
-    ## }
-
-    ## Settings {
-    properties.option_scale = settings.get(
-        constants.SCALE,
-        constants.EXPORT_OPTIONS[constants.SCALE])
-
-    properties.option_round_off = settings.get(
-        constants.ENABLE_PRECISION,
-        constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION])
-
-    properties.option_round_value = settings.get(
-        constants.PRECISION,
-        constants.EXPORT_OPTIONS[constants.PRECISION])
-
-    properties.option_custom_properties = settings.get(
-        constants.CUSTOM_PROPERTIES,
-        constants.EXPORT_OPTIONS[constants.CUSTOM_PROPERTIES])
-
-    properties.option_logging = settings.get(
-        constants.LOGGING,
-        constants.EXPORT_OPTIONS[constants.LOGGING])
-
-    properties.option_compression = settings.get(
-        constants.COMPRESSION,
-        constants.NONE)
-
-    properties.option_indent = settings.get(
-        constants.INDENT,
-        constants.EXPORT_OPTIONS[constants.INDENT])
-
-    properties.option_export_textures = settings.get(
-        constants.EXPORT_TEXTURES,
-        constants.EXPORT_OPTIONS[constants.EXPORT_TEXTURES])
-
-    properties.option_embed_textures = settings.get(
-        constants.EMBED_TEXTURES,
-        constants.EXPORT_OPTIONS[constants.EMBED_TEXTURES])
-
-    properties.option_texture_folder = settings.get(
-        constants.TEXTURE_FOLDER,
-        constants.EXPORT_OPTIONS[constants.TEXTURE_FOLDER])
-
-    properties.option_embed_animation = settings.get(
-        constants.EMBED_ANIMATION,
-        constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION])
-    ## }
-
-    ## Scene {
-    properties.option_export_scene = settings.get(
-        constants.SCENE,
-        constants.EXPORT_OPTIONS[constants.SCENE])
-
-    #properties.option_embed_geometry = settings.get(
-    #    constants.EMBED_GEOMETRY,
-    #    constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY])
-
-    properties.option_lights = settings.get(
-        constants.LIGHTS,
-        constants.EXPORT_OPTIONS[constants.LIGHTS])
-
-    properties.option_cameras = settings.get(
-        constants.CAMERAS,
-        constants.EXPORT_OPTIONS[constants.CAMERAS])
-
-    properties.option_hierarchy = settings.get(
-        constants.HIERARCHY,
-        constants.EXPORT_OPTIONS[constants.HIERARCHY])
-    ## }
-
-    ## Animation {
-    properties.option_animation_morph = settings.get(
-        constants.MORPH_TARGETS,
-        constants.EXPORT_OPTIONS[constants.MORPH_TARGETS])
-
-    properties.option_blend_shape = settings.get(
-        constants.BLEND_SHAPES,
-        constants.EXPORT_OPTIONS[constants.BLEND_SHAPES])
-
-    properties.option_animation_skeletal = settings.get(
-        constants.ANIMATION,
-        constants.EXPORT_OPTIONS[constants.ANIMATION])
-
-    properties.option_keyframes = settings.get(
-        constants.KEYFRAMES,
-        constants.EXPORT_OPTIONS[constants.KEYFRAMES])
-
-    properties.option_bake_keyframes = settings.get(
-        constants.BAKE_KEYFRAMES,
-        constants.EXPORT_OPTIONS[constants.BAKE_KEYFRAMES])
-
-    properties.option_frame_step = settings.get(
-        constants.FRAME_STEP,
-        constants.EXPORT_OPTIONS[constants.FRAME_STEP])
-
-    properties.option_frame_index_as_time = settings.get(
-        constants.FRAME_INDEX_AS_TIME,
-        constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME])
-    ## }
-
-def set_settings(properties):
-    """Set the export settings to the correct keys.
-
-    :param properties:
-    :returns: settings
-    :rtype: dict
-
-    """
-    settings = {
-        constants.VERTICES: properties.option_vertices,
-        constants.FACES: properties.option_faces,
-        constants.NORMALS: properties.option_normals,
-        constants.SKINNING: properties.option_skinning,
-        constants.BONES: properties.option_bones,
-        constants.EXTRA_VGROUPS: properties.option_extra_vgroups,
-        constants.APPLY_MODIFIERS: properties.option_apply_modifiers,
-        constants.GEOMETRY_TYPE: properties.option_geometry_type,
-        constants.INDEX_TYPE: properties.option_index_type,
-
-        constants.MATERIALS: properties.option_materials,
-        constants.UVS: properties.option_uv_coords,
-        constants.FACE_MATERIALS: properties.option_face_materials,
-        constants.MAPS: properties.option_maps,
-        constants.COLORS: properties.option_colors,
-        constants.MIX_COLORS: properties.option_mix_colors,
-
-        constants.SCALE: properties.option_scale,
-        constants.ENABLE_PRECISION: properties.option_round_off,
-        constants.PRECISION: properties.option_round_value,
-        constants.CUSTOM_PROPERTIES: properties.option_custom_properties,
-        constants.LOGGING: properties.option_logging,
-        constants.COMPRESSION: properties.option_compression,
-        constants.INDENT: properties.option_indent,
-        constants.EXPORT_TEXTURES: properties.option_export_textures,
-        constants.EMBED_TEXTURES: properties.option_embed_textures,
-        constants.TEXTURE_FOLDER: properties.option_texture_folder,
-
-        constants.SCENE: properties.option_export_scene,
-        #constants.EMBED_GEOMETRY: properties.option_embed_geometry,
-        constants.EMBED_ANIMATION: properties.option_embed_animation,
-        constants.LIGHTS: properties.option_lights,
-        constants.CAMERAS: properties.option_cameras,
-        constants.HIERARCHY: properties.option_hierarchy,
-
-        constants.MORPH_TARGETS: properties.option_animation_morph,
-        constants.BLEND_SHAPES: properties.option_blend_shape,
-        constants.ANIMATION: properties.option_animation_skeletal,
-        constants.KEYFRAMES: properties.option_keyframes,
-        constants.BAKE_KEYFRAMES: properties.option_bake_keyframes,
-        constants.FRAME_STEP: properties.option_frame_step,
-        constants.FRAME_INDEX_AS_TIME: properties.option_frame_index_as_time,
-        constants.INFLUENCES_PER_VERTEX: properties.option_influences
-    }
-
-    return settings
-
-
-def compression_types():
-    """Supported compression formats
-
-    :rtype: tuple
-
-    """
-    types = [(constants.NONE, constants.NONE, constants.NONE)]
-
-    try:
-        import msgpack
-        types.append((constants.MSGPACK, constants.MSGPACK,
-                      constants.MSGPACK))
-    except ImportError:
-        pass
-
-    return types
-
-
-def animation_options():
-    """The supported skeletal animation types
-
-    :returns: list of tuples
-
-    """
-    anim = [
-        (constants.OFF, constants.OFF.title(), constants.OFF),
-        (constants.POSE, constants.POSE.title(), constants.POSE),
-        (constants.REST, constants.REST.title(), constants.REST)
-    ]
-
-    return anim
-
-def resolve_conflicts(self, context):
-    if(not self.option_export_textures):
-        self.option_embed_textures = False;
-
-class ExportThree(bpy.types.Operator, ExportHelper):
-    """Class that handles the export properties"""
-
-    bl_idname = 'export.three'
-    bl_label = 'Export THREE'
-    bl_options = {'PRESET'}
-
-    filename_ext = constants.EXTENSION
-
-    option_vertices = BoolProperty(
-        name="Vertices",
-        description="Export vertices",
-        default=constants.EXPORT_OPTIONS[constants.VERTICES])
-
-    option_faces = BoolProperty(
-        name="Faces",
-        description="Export faces (Geometry only)",
-        default=constants.EXPORT_OPTIONS[constants.FACES])
-
-    option_normals = BoolProperty(
-        name="Normals",
-        description="Export normals",
-        default=constants.EXPORT_OPTIONS[constants.NORMALS])
-
-    option_colors = BoolProperty(
-        name="Vertex Colors",
-        description="Export vertex colors",
-        default=constants.EXPORT_OPTIONS[constants.COLORS])
-
-    option_mix_colors = BoolProperty(
-        name="Mix Colors",
-        description="Mix material and vertex colors",
-        default=constants.EXPORT_OPTIONS[constants.MIX_COLORS])
-
-    option_uv_coords = BoolProperty(
-        name="UVs",
-        description="Export texture coordinates",
-        default=constants.EXPORT_OPTIONS[constants.UVS])
-
-    option_materials = BoolProperty(
-        name="Materials",
-        description="Export materials",
-        default=constants.EXPORT_OPTIONS[constants.MATERIALS])
-
-    option_face_materials = BoolProperty(
-        name="Face Materials",
-        description="Face mapping materials (Geometry only)",
-        default=constants.EXPORT_OPTIONS[constants.FACE_MATERIALS])
-
-    option_maps = BoolProperty(
-        name="Textures",
-        description="Include texture maps",
-        default=constants.EXPORT_OPTIONS[constants.MAPS])
-
-    option_skinning = BoolProperty(
-        name="Skinning",
-        description="Export skin data",
-        default=constants.EXPORT_OPTIONS[constants.SKINNING])
-
-    option_bones = BoolProperty(
-        name="Bones",
-        description="Export bones",
-        default=constants.EXPORT_OPTIONS[constants.BONES])
-
-    option_extra_vgroups = StringProperty(
-        name="Extra Vertex Groups",
-        description="Non-skinning vertex groups to export (comma-separated, w/ star wildcard, BufferGeometry only).",
-        default=constants.EXPORT_OPTIONS[constants.EXTRA_VGROUPS])
-
-    option_apply_modifiers = BoolProperty(
-        name="Apply Modifiers",
-        description="Apply Modifiers to mesh objects",
-        default=constants.EXPORT_OPTIONS[constants.APPLY_MODIFIERS]
-    )
-
-    index_buffer_types = [
-        (constants.NONE,) * 3,
-        (constants.UINT_16,) * 3,
-        (constants.UINT_32,) * 3]
-
-    option_index_type = EnumProperty(
-        name="Index Buffer",
-        description="Index buffer type that will be used for BufferGeometry objects.",
-        items=index_buffer_types,
-        default=constants.EXPORT_OPTIONS[constants.INDEX_TYPE])
-
-    option_scale = FloatProperty(
-        name="Scale",
-        description="Scale vertices",
-        min=0.01,
-        max=1000.0,
-        soft_min=0.01,
-        soft_max=1000.0,
-        default=constants.EXPORT_OPTIONS[constants.SCALE])
-
-    option_round_off = BoolProperty(
-        name="Enable Precision",
-        description="Round off floating point values",
-        default=constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION])
-
-    option_round_value = IntProperty(
-        name="",
-        min=0,
-        max=16,
-        description="Floating point precision",
-        default=constants.EXPORT_OPTIONS[constants.PRECISION])
-
-    option_custom_properties = BoolProperty(
-        name="Custom Properties",
-        description="Export custom properties as userData",
-        default=False)
-
-    logging_types = [
-        (constants.DISABLED, constants.DISABLED, constants.DISABLED),
-        (constants.DEBUG, constants.DEBUG, constants.DEBUG),
-        (constants.INFO, constants.INFO, constants.INFO),
-        (constants.WARNING, constants.WARNING, constants.WARNING),
-        (constants.ERROR, constants.ERROR, constants.ERROR),
-        (constants.CRITICAL, constants.CRITICAL, constants.CRITICAL)]
-
-    option_logging = EnumProperty(
-        name="",
-        description="Logging verbosity level",
-        items=logging_types,
-        default=constants.DISABLED)
-
-    option_geometry_type = EnumProperty(
-        name="Type",
-        description="Geometry type",
-        items=_geometry_types()[1:],
-        default=constants.EXPORT_OPTIONS[constants.GEOMETRY_TYPE])
-
-    option_export_scene = BoolProperty(
-        name="Scene",
-        description="Export scene",
-        default=constants.EXPORT_OPTIONS[constants.SCENE])
-
-    #@TODO: removing this option since the ObjectLoader doesn't have
-    #       support for handling external geometry data
-    #option_embed_geometry = BoolProperty(
-    #    name="Embed geometry",
-    #    description="Embed geometry",
-    #    default=constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY])
-
-    option_embed_animation = BoolProperty(
-        name="Embed animation",
-        description="Embed animation data with the geometry data",
-        default=constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION])
-
-    option_export_textures = BoolProperty(
-        name="Export textures",
-        description="Export textures",
-        default=constants.EXPORT_OPTIONS[constants.EXPORT_TEXTURES],
-        update=resolve_conflicts)
-
-    option_embed_textures = BoolProperty(
-        name="Embed textures",
-        description="Embed base64 textures in .json",
-        default=constants.EXPORT_OPTIONS[constants.EMBED_TEXTURES])
-
-    option_texture_folder = StringProperty(
-        name="Texture folder",
-        description="add this folder to textures path",
-        default=constants.EXPORT_OPTIONS[constants.TEXTURE_FOLDER])
-
-    option_lights = BoolProperty(
-        name="Lights",
-        description="Export default scene lights",
-        default=False)
-
-    option_cameras = BoolProperty(
-        name="Cameras",
-        description="Export default scene cameras",
-        default=False)
-
-    option_hierarchy = BoolProperty(
-        name="Hierarchy",
-        description="Export object hierarchy",
-        default=False)
-
-    option_animation_morph = BoolProperty(
-        name="Morph animation",
-        description="Export animation (morphs)",
-        default=constants.EXPORT_OPTIONS[constants.MORPH_TARGETS])
-
-    option_blend_shape = BoolProperty(
-        name="Blend Shape animation",
-        description="Export Blend Shapes",
-        default=constants.EXPORT_OPTIONS[constants.BLEND_SHAPES])
-
-    option_animation_skeletal = EnumProperty(
-        name="",
-        description="Export animation (skeletal)",
-        items=animation_options(),
-        default=constants.OFF)
-
-    option_keyframes = BoolProperty(
-        name="Keyframe animation",
-        description="Export animation (keyframes)",
-        default=constants.EXPORT_OPTIONS[constants.KEYFRAMES])
-
-    option_bake_keyframes = BoolProperty(
-        name="Bake keyframe animation",
-        description="Bake keyframe animation each frame step",
-        default=constants.EXPORT_OPTIONS[constants.BAKE_KEYFRAMES])
-
-    option_frame_index_as_time = BoolProperty(
-        name="Frame index as time",
-        description="Use (original) frame index as frame time",
-        default=constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME])
-
-    option_frame_step = IntProperty(
-        name="Frame step",
-        description="Animation frame step",
-        min=1,
-        max=1000,
-        soft_min=1,
-        soft_max=1000,
-        default=1)
-
-    option_indent = BoolProperty(
-        name="Indent JSON",
-        description="Disable this to reduce the file size",
-        default=constants.EXPORT_OPTIONS[constants.INDENT])
-
-    option_compression = EnumProperty(
-        name="",
-        description="Compression options",
-        items=compression_types(),
-        default=constants.NONE)
-
-    option_influences = IntProperty(
-        name="Influences",
-        description="Maximum number of bone influences",
-        min=1,
-        max=4,
-        default=2)
-
-    def invoke(self, context, event):
-        
-        settings = context.scene.get(constants.EXPORT_SETTINGS_KEY)
-        if settings:
-            try:
-                restore_export_settings(self.properties, settings)
-            except AttributeError as e:
-                logging.error("Loading export settings failed:")
-                logging.exception(e)
-                logging.debug("Removed corrupted settings")
-
-                del context.scene[constants.EXPORT_SETTINGS_KEY]
-
-        return ExportHelper.invoke(self, context, event)
-
-    @classmethod
-    def poll(cls, context):
-        """
-
-        :param context:
-
-        """
-        return context.active_object is not None
-
-    def execute(self, context):
-        """
-
-        :param context:
-
-        """
-
-        if not self.properties.filepath:
-            raise Exception("filename not set")
-
-        settings = set_settings(self.properties)
-        settings['addon_version'] = bl_info['version']
-
-        filepath = self.filepath
-        if settings[constants.COMPRESSION] == constants.MSGPACK:
-            filepath = "%s%s" % (filepath[:-4], constants.PACK)
-
-        from io_three import exporter
-        if settings[constants.SCENE]:
-            exporter.export_scene(filepath, settings)
-        else:
-            exporter.export_geometry(filepath, settings)
-
-        return {'FINISHED'}
-
-    def draw(self, context):
-        """
-
-        :param context:
-
-        """
-
-        using_geometry = self.option_geometry_type == constants.GEOMETRY
-
-        layout = self.layout
-
-        ## Scene {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="SCENE", icon="SCENE_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_export_scene')
-        row.prop(self.properties, 'option_materials')
-
-        #row = box.row()
-        #row.prop(self.properties, 'option_embed_geometry')
-
-        row = box.row()
-        row.prop(self.properties, 'option_lights')
-        row.prop(self.properties, 'option_cameras')
-
-        row = box.row()
-        row.prop(self.properties, 'option_hierarchy')
-        ## }
-
-        layout.separator()
-
-        ## Geometry {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="GEOMETRY", icon="MESH_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_geometry_type')
-
-        row = box.row()
-        row.prop(self.properties, 'option_index_type')
-
-        row = box.row()
-        row.prop(self.properties, 'option_vertices')
-        col = row.column()
-        col.prop(self.properties, 'option_faces')
-        col.enabled = using_geometry
-
-        row = box.row()
-        row.prop(self.properties, 'option_normals')
-        row.prop(self.properties, 'option_uv_coords')
-
-        row = box.row()
-        row.prop(self.properties, 'option_apply_modifiers')
-
-        row = box.row()
-        row.prop(self.properties, 'option_extra_vgroups')
-        row.enabled = not using_geometry
-        ## }
-
-        layout.separator()
-
-        ## Materials {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-        row.label(text="MATERIAL", icon="MATERIAL_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_colors')
-        row.prop(self.properties, 'option_mix_colors')
-
-        row = box.row()
-        row.prop(self.properties, 'option_face_materials')
-        row.enabled = using_geometry
-        ## }
-
-        layout.separator()
-
-        ## Textures {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="TEXTURE", icon="TEXTURE_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_maps')
-        row.prop(self.properties, 'option_export_textures')
-
-        row = box.row()
-        row.prop(self.properties, 'option_embed_textures')
-        row.enabled = self.properties.option_export_textures
-
-        row = box.row()
-        row.prop(self.properties, 'option_texture_folder')
-        ## }
-
-        layout.separator()
-
-        ## Armature {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="ARMATURE", icon="ARMATURE_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_bones')
-        row.prop(self.properties, 'option_skinning')
-        ## }
-
-        layout.separator()
-
-        ## Animation {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="ANIMATION", icon="POSE_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_animation_morph')
-        row.prop(self.properties, 'option_blend_shape')
-
-        row = box.row()
-        row.label(text="Skeletal animations:")
-        row.prop(self.properties, 'option_animation_skeletal')
-
-        row = box.row()
-        row.prop(self.properties, 'option_keyframes')
-
-        row = box.row()
-        row.prop(self.properties, 'option_bake_keyframes')
-
-        row = box.row()
-        row.prop(self.properties, 'option_influences')
-
-        row = box.row()
-        row.prop(self.properties, 'option_frame_step')
-
-        row = box.row()
-        row.prop(self.properties, 'option_frame_index_as_time')
-
-        row = box.row()
-        row.prop(self.properties, 'option_embed_animation')
-        ## }
-
-        layout.separator()
-
-        ## Settings {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="SETTINGS", icon="SETTINGS")
-
-        row = box.row()
-        row.prop(self.properties, 'option_scale')
-
-        row = box.row()
-        row.prop(self.properties, 'option_round_off')
-        row.prop(self.properties, 'option_round_value')
-
-        row = box.row()
-        row.prop(self.properties, 'option_custom_properties')
-
-        row = box.row()
-        row.prop(self.properties, 'option_indent')
-
-        row = box.row()
-        row.label(text="Logging verbosity:")
-        row.prop(self.properties, 'option_logging')
-
-        row = box.row()
-        row.label(text="File compression format:")
-        row.prop(self.properties, 'option_compression')
-        ## }
-
-        ## Operators {
-        has_settings = context.scene.get(constants.EXPORT_SETTINGS_KEY, False)
-        row = layout.row()
-        row.operator(
-            ThreeExportSettings.bl_idname,
-            ThreeExportSettings.bl_label,
-            icon="%s" % "PINNED" if has_settings else "UNPINNED")
-        ## }
-
-
-
-def menu_func_export(self, context):
-    """
-
-    :param self:
-    :param context:
-
-    """
-    default_path = bpy.data.filepath.replace('.blend', constants.EXTENSION)
-    text = "Three.js (%s)" % constants.EXTENSION
-    operator = self.layout.operator(ExportThree.bl_idname, text=text)
-    operator.filepath = default_path
-
-
-def register():
-    """Registers the addon (Blender boilerplate)"""
-    bpy.utils.register_module(__name__)
-    bpy.types.INFO_MT_file_export.append(menu_func_export)
-
-
-def unregister():
-    """Unregisters the addon (Blender boilerplate)"""
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_file_export.remove(menu_func_export)
-
-
-if __name__ == '__main__':
-    register()

+ 0 - 398
utils/exporters/blender/addons/io_three/constants.py

@@ -1,398 +0,0 @@
-'''
-All constant data used in the package should be defined here.
-'''
-
-from collections import OrderedDict as BASE_DICT
-
-BLENDING_TYPES = type('Blending', (), {
-    'NONE': 'NoBlending',
-    'NORMAL': 'NormalBlending',
-    'ADDITIVE': 'AdditiveBlending',
-    'SUBTRACTIVE': 'SubtractiveBlending',
-    'MULTIPLY': 'MultiplyBlending',
-    'CUSTOM': 'CustomBlending'
-})
-
-BLENDING_CONSTANTS = type('BlendingConstant', (), {
-    'NoBlending':0,
-    'NormalBlending':1,
-    'AdditiveBlending':2,
-    'SubtractiveBlending':3,
-    'MultiplyBlending':4,
-    'CustomBlending':5
-})
-
-NEAREST_FILTERS = type('NearestFilters', (), {
-    'NEAREST': 'NearestFilter',
-    'MIP_MAP_NEAREST': 'NearestMipMapNearestFilter',
-    'MIP_MAP_LINEAR': 'NearestMipMapLinearFilter'
-})
-
-LINEAR_FILTERS = type('LinearFilters', (), {
-    'LINEAR': 'LinearFilter',
-    'MIP_MAP_NEAREST': 'LinearMipMapNearestFilter',
-    'MIP_MAP_LINEAR': 'LinearMipMapLinearFilter'
-})
-
-MAPPING_TYPES = type('Mapping', (), {
-    'UV': 'UVMapping',
-    'CUBE_REFLECTION': 'CubeReflectionMapping',
-    'CUBE_REFRACTION': 'CubeRefractionMapping',
-    'SPHERICAL_REFLECTION': 'SphericalReflectionMapping'
-})
-
-NUMERIC = {
-    'UVMapping': 300,
-    'CubeReflectionMapping': 301,
-    'CubeRefractionMapping': 302,
-    'EquirectangularReflectionMapping': 303,
-    'EquirectangularRefractionMapping': 304,
-    'SphericalReflectionMapping': 305,
-
-    'RepeatWrapping': 1000,
-    'repeat': 1000,
-    'ClampToEdgeWrapping': 1001,
-    'MirroredRepeatWrapping': 1002,
-
-    'NearestFilter': 1003,
-    'NearestMipMapNearestFilter': 1004,
-    'NearestMipMapLinearFilter': 1005,
-    'LinearFilter': 1006,
-    'LinearMipMapNearestFilter': 1007,
-    'LinearMipMapLinearFilter': 1008
-}
-JSON = 'json'
-EXTENSION = '.%s' % JSON
-INDENT = 'indent'
-
-
-MATERIALS = 'materials'
-SCENE = 'scene'
-VERTICES = 'vertices'
-FACES = 'faces'
-NORMALS = 'normals'
-BONES = 'bones'
-UVS = 'uvs'
-APPLY_MODIFIERS = 'applyModifiers'
-COLORS = 'colors'
-MIX_COLORS = 'mixColors'
-EXTRA_VGROUPS = 'extraVertexGroups'
-INDEX = 'index'
-DRAW_CALLS = 'drawcalls'
-DC_START = 'start'
-DC_COUNT = 'count'
-DC_INDEX = 'index'
-
-GROUPS = 'groups'
-
-SCALE = 'scale'
-COMPRESSION = 'compression'
-MAPS = 'maps'
-FRAME_STEP = 'frameStep'
-FRAME_INDEX_AS_TIME = 'frameIndexAsTime'
-ANIMATION = 'animations'
-CLIPS="clips"
-KEYFRAMES = 'tracks'
-BAKE_KEYFRAMES = 'bake_tracks'
-MORPH_TARGETS = 'morphTargets'
-MORPH_TARGETS_ANIM = 'morphTargetsAnimation'
-BLEND_SHAPES = 'blendShapes'
-POSE = 'pose'
-REST = 'rest'
-SKIN_INDICES = 'skinIndices'
-SKIN_WEIGHTS = 'skinWeights'
-LOGGING = 'logging'
-CAMERAS = 'cameras'
-LIGHTS = 'lights'
-HIERARCHY = 'hierarchy'
-FACE_MATERIALS = 'faceMaterials'
-SKINNING = 'skinning'
-EXPORT_TEXTURES = 'exportTextures'
-EMBED_TEXTURES = 'embedTextures'
-TEXTURE_FOLDER = 'textureFolder'
-ENABLE_PRECISION = 'enablePrecision'
-PRECISION = 'precision'
-DEFAULT_PRECISION = 6
-CUSTOM_PROPERTIES = 'customProperties'
-EMBED_GEOMETRY = 'embedGeometry'
-EMBED_ANIMATION = 'embedAnimation'
-OFF = 'off'
-
-GLOBAL = 'global'
-BUFFER_GEOMETRY = 'BufferGeometry'
-GEOMETRY = 'geometry'
-GEOMETRY_TYPE = 'geometryType'
-INDEX_TYPE = 'indexType'
-
-CRITICAL = 'critical'
-ERROR = 'error'
-WARNING = 'warning'
-INFO = 'info'
-DEBUG = 'debug'
-DISABLED = 'disabled'
-
-NONE = 'None'
-MSGPACK = 'msgpack'
-
-PACK = 'pack'
-
-FLOAT_32 = 'Float32Array'
-UINT_16 = 'Uint16Array'
-UINT_32 = 'Uint32Array'
-
-INFLUENCES_PER_VERTEX = 'influencesPerVertex'
-
-EXPORT_OPTIONS = {
-    FACES: True,
-    VERTICES: True,
-    NORMALS: True,
-    UVS: True,
-    APPLY_MODIFIERS: True,
-    COLORS: False,
-    EXTRA_VGROUPS: '',
-    INDEX_TYPE: UINT_16,
-    MATERIALS: False,
-    FACE_MATERIALS: False,
-    SCALE: 1,
-    FRAME_STEP: 1,
-    FRAME_INDEX_AS_TIME: False,
-    SCENE: False,
-    MIX_COLORS: False,
-    COMPRESSION: None,
-    MAPS: False,
-    ANIMATION: OFF,
-    KEYFRAMES: False,
-    BAKE_KEYFRAMES: False,
-    BONES: False,
-    SKINNING: False,
-    MORPH_TARGETS: False,
-    BLEND_SHAPES: False,
-    CAMERAS: False,
-    LIGHTS: False,
-    HIERARCHY: False,
-    EXPORT_TEXTURES: True,
-    EMBED_TEXTURES: False,
-    TEXTURE_FOLDER: '',
-    LOGGING: DEBUG,
-    ENABLE_PRECISION: False,
-    PRECISION: DEFAULT_PRECISION,
-    CUSTOM_PROPERTIES: False,
-    EMBED_GEOMETRY: True,
-    EMBED_ANIMATION: True,
-    GEOMETRY_TYPE: BUFFER_GEOMETRY,
-    INFLUENCES_PER_VERTEX: 2,
-    INDENT: True
-}
-
-
-FORMAT_VERSION = 4.4
-VERSION = 'version'
-THREE = 'io_three'
-GENERATOR = 'generator'
-SOURCE_FILE = 'sourceFile'
-VALID_DATA_TYPES = (str, int, float, bool, list, tuple, dict)
-
-JSON = 'json'
-GZIP = 'gzip'
-
-EXTENSIONS = {
-    JSON: '.json',
-    MSGPACK: '.pack',
-    GZIP: '.gz'
-}
-
-METADATA = 'metadata'
-GEOMETRIES = 'geometries'
-IMAGES = 'images'
-TEXTURE = 'texture'
-TEXTURES = 'textures'
-
-USER_DATA = 'userData'
-DATA = 'data'
-TYPE = 'type'
-
-MATERIAL = 'material'
-OBJECT = 'object'
-PERSPECTIVE_CAMERA = 'PerspectiveCamera'
-ORTHOGRAPHIC_CAMERA = 'OrthographicCamera'
-AMBIENT_LIGHT = 'AmbientLight'
-DIRECTIONAL_LIGHT = 'DirectionalLight'
-POINT_LIGHT = 'PointLight'
-SPOT_LIGHT = 'SpotLight'
-# TODO (abelnation): confirm this is correct area light string for exporter
-RECT_AREA_LIGHT = 'RectAreaLight'
-HEMISPHERE_LIGHT = 'HemisphereLight'
-# TODO: RectAreaLight support
-MESH = 'Mesh'
-EMPTY = 'Empty'
-SPRITE = 'Sprite'
-
-DEFAULT_METADATA = {
-    VERSION: FORMAT_VERSION,
-    TYPE: OBJECT.title(),
-    GENERATOR: THREE
-}
-
-UUID = 'uuid'
-
-MATRIX = 'matrix'
-POSITION = 'position'
-QUATERNION = 'quaternion'
-ROTATION = 'rotation'
-SCALE = 'scale'
-
-UV = 'uv'
-UV2 = 'uv2'
-ATTRIBUTES = 'attributes'
-NORMAL = 'normal'
-ITEM_SIZE = 'itemSize'
-ARRAY = 'array'
-
-VISIBLE = 'visible'
-CAST_SHADOW = 'castShadow'
-RECEIVE_SHADOW = 'receiveShadow'
-QUAD = 'quad'
-
-MASK = {
-    QUAD: 0,
-    MATERIALS: 1,
-    UVS: 3,
-    NORMALS: 5,
-    COLORS: 7
-}
-
-
-CHILDREN = 'children'
-
-URL = 'url'
-WRAP = 'wrap'
-REPEAT = 'repeat'
-WRAPPING = type('Wrapping', (), {
-    'REPEAT': 'repeat',
-    'CLAMP': 'clamp',
-    'MIRROR': 'mirror'
-})
-ANISOTROPY = 'anisotropy'
-MAG_FILTER = 'magFilter'
-MIN_FILTER = 'minFilter'
-MAPPING = 'mapping'
-
-IMAGE = 'image'
-
-NAME = 'name'
-PARENT = 'parent'
-LENGTH = 'length'
-FPS = 'fps'
-HIERARCHY = 'hierarchy'
-POS = 'pos'
-ROTQ = 'rotq'
-ROT = 'rot'
-SCL = 'scl'
-TIME = 'time'
-KEYS = 'keys'
-
-COLOR = 'color'
-EMISSIVE = 'emissive'
-SPECULAR = 'specular'
-SPECULAR_COEF = 'specularCoef'
-SHININESS = 'shininess'
-SIDE = 'side'
-OPACITY = 'opacity'
-TRANSPARENT = 'transparent'
-WIREFRAME = 'wireframe'
-BLENDING = 'blending'
-VERTEX_COLORS = 'vertexColors'
-DEPTH_WRITE = 'depthWrite'
-DEPTH_TEST = 'depthTest'
-
-MAP = 'map'
-SPECULAR_MAP = 'specularMap'
-LIGHT_MAP = 'lightMap'
-BUMP_MAP = 'bumpMap'
-BUMP_SCALE = 'bumpScale'
-NORMAL_MAP = 'normalMap'
-NORMAL_SCALE = 'normalScale'
-
-#@TODO ENV_MAP, REFLECTIVITY, REFRACTION_RATIO, COMBINE
-
-MAP_DIFFUSE = 'mapDiffuse'
-MAP_DIFFUSE_REPEAT = 'mapDiffuseRepeat'
-MAP_DIFFUSE_WRAP = 'mapDiffuseWrap'
-MAP_DIFFUSE_ANISOTROPY = 'mapDiffuseAnisotropy'
-
-MAP_SPECULAR = 'mapSpecular'
-MAP_SPECULAR_REPEAT = 'mapSpecularRepeat'
-MAP_SPECULAR_WRAP = 'mapSpecularWrap'
-MAP_SPECULAR_ANISOTROPY = 'mapSpecularAnisotropy'
-
-MAP_LIGHT = 'mapLight'
-MAP_LIGHT_REPEAT = 'mapLightRepeat'
-MAP_LIGHT_WRAP = 'mapLightWrap'
-MAP_LIGHT_ANISOTROPY = 'mapLightAnisotropy'
-
-MAP_NORMAL = 'mapNormal'
-MAP_NORMAL_FACTOR = 'mapNormalFactor'
-MAP_NORMAL_REPEAT = 'mapNormalRepeat'
-MAP_NORMAL_WRAP = 'mapNormalWrap'
-MAP_NORMAL_ANISOTROPY = 'mapNormalAnisotropy'
-
-MAP_BUMP = 'mapBump'
-MAP_BUMP_REPEAT = 'mapBumpRepeat'
-MAP_BUMP_WRAP = 'mapBumpWrap'
-MAP_BUMP_ANISOTROPY = 'mapBumpAnisotropy'
-MAP_BUMP_SCALE = 'mapBumpScale'
-
-NORMAL_BLENDING = 0
-
-VERTEX_COLORS_ON = 2
-VERTEX_COLORS_OFF = 0
-
-SIDE_DOUBLE = 2
-
-THREE_BASIC = 'MeshBasicMaterial'
-THREE_LAMBERT = 'MeshLambertMaterial'
-THREE_PHONG = 'MeshPhongMaterial'
-
-INTENSITY = 'intensity'
-DISTANCE = 'distance'
-ANGLE = 'angle'
-DECAY = 'decayExponent'
-
-FOV = 'fov'
-ASPECT = 'aspect'
-NEAR = 'near'
-FAR = 'far'
-
-LEFT = 'left'
-RIGHT = 'right'
-TOP = 'top'
-BOTTOM = 'bottom'
-
-SHADING = 'shading'
-COLOR_DIFFUSE = 'colorDiffuse'
-COLOR_EMISSIVE = 'colorEmissive'
-COLOR_SPECULAR = 'colorSpecular'
-DBG_NAME = 'DbgName'
-DBG_COLOR = 'DbgColor'
-DBG_INDEX = 'DbgIndex'
-EMIT = 'emit'
-
-PHONG = 'phong'
-LAMBERT = 'lambert'
-BASIC = 'basic'
-
-NORMAL_BLENDING = 'NormalBlending'
-
-DBG_COLORS = (0xeeeeee, 0xee0000, 0x00ee00, 0x0000ee,
-              0xeeee00, 0x00eeee, 0xee00ee)
-
-DOUBLE_SIDED = 'doubleSided'
-
-EXPORT_SETTINGS_KEY = 'threeExportSettings'
-
-# flips vectors
-
-XZ_Y = "XZ_Y"
-X_ZY = "X_ZY"
-XYZ = "XYZ"
-_XY_Z = "_XY_Z"

+ 0 - 112
utils/exporters/blender/addons/io_three/dialogs.py

@@ -1,112 +0,0 @@
-from bpy import context
-
-CONTEXT = {
-    0: {
-        'title': "Error Message",
-        'icon': 'CANCEL'
-    },
-    1: {
-        'title': "Warning Message",
-        'icon': 'ERROR' # I prefer this icon for warnings
-    },
-    2: {
-        'title': "Message",
-        'icon': 'NONE'
-    },
-    3: {
-        'title': "Question",
-        'icon': 'QUESTION'
-    }
-}
-
-
-def error(message, title="", wrap=40):
-    """Creates an error dialog.
-
-    :param message: text of the message body
-    :param title: text to append to the title
-                  (Default value = "")
-    :param wrap: line width (Default value = 40)
-
-    """
-    _draw(message, title, wrap, 0)
-
-
-def warning(message, title="", wrap=40):
-    """Creates an error dialog.
-
-    :param message: text of the message body
-    :param title: text to append to the title
-                  (Default value = "")
-    :param wrap: line width (Default value = 40)
-
-    """
-    _draw(message, title, wrap, 1)
-
-
-
-def info(message, title="", wrap=40):
-    """Creates an error dialog.
-
-    :param message: text of the message body
-    :param title: text to append to the title
-                  (Default value = "")
-    :param wrap: line width (Default value = 40)
-
-    """
-    _draw(message, title, wrap, 2)
-
-
-
-def question(message, title="", wrap=40):
-    """Creates an error dialog.
-
-    :param message: text of the message body
-    :param title: text to append to the title
-                  (Default value = "")
-    :param wrap: line width (Default value = 40)
-
-    """
-    _draw(message, title, wrap, 3)
-
-
-
-# Great idea borrowed from
-# http://community.cgcookie.com/t/code-snippet-easy-error-messages/203
-def _draw(message, title, wrap, key):
-    """
-
-    :type message: str
-    :type title: str
-    :type wrap: int
-    :type key: int
-
-    """
-    lines = []
-    if wrap > 0:
-        while len(message) > wrap:
-            i = message.rfind(' ', 0, wrap)
-            if i == -1:
-                lines += [message[:wrap]]
-                message = message[wrap:]
-            else:
-                lines += [message[:i]]
-                message = message[i+1:]
-    if message:
-        lines += [message]
-
-    def draw(self, *args):
-        """
-
-        :param self:
-        :param *args:
-
-        """
-        for line in lines:
-            self.layout.label(line)
-
-    title = "%s: %s" % (title, CONTEXT[key]['title'])
-    icon = CONTEXT[key]['icon']
-
-    context.window_manager.popup_menu(
-        draw, title=title.strip(), icon=icon)

+ 0 - 9
utils/exporters/blender/addons/io_three/exceptions.py

@@ -1,9 +0,0 @@
-class ThreeError(Exception): pass
-class UnimplementedFeatureError(ThreeError): pass
-class ThreeValueError(ThreeError): pass
-class UnsupportedObjectType(ThreeError): pass
-class GeometryError(ThreeError): pass
-class MaterialError(ThreeError): pass
-class SelectionError(ThreeError): pass
-class NGonError(ThreeError): pass
-class BufferGeometryError(ThreeError): pass

+ 0 - 96
utils/exporters/blender/addons/io_three/exporter/__init__.py

@@ -1,96 +0,0 @@
-import os
-import sys
-import traceback
-from .. import constants, logger, exceptions, dialogs
-from . import scene, geometry, api, base_classes
-
-
-def _error_handler(func):
-    
-    def inner(filepath, options, *args, **kwargs):
-        level = options.get(constants.LOGGING, constants.DISABLED)
-        version = options.get('addon_version')
-        if level != constants.DISABLED:
-            logger.init('io_three.export.log', level=level)
-        if version is not None:
-            logger.debug("Addon Version %s", version)
-        api.init()
-        
-        try:
-            func(filepath, options, *args, **kwargs)
-        except:
-            info = sys.exc_info()
-            trace = traceback.format_exception(
-                info[0], info[1], info[2].tb_next)
-            trace = ''.join(trace)
-            logger.error(trace)
-            
-            print('Error recorded to %s' % logger.LOG_FILE)
-
-            raise
-        else:
-            print('Log: %s' % logger.LOG_FILE)
-
-    return inner
-
-
-@_error_handler
-def export_scene(filepath, options):
-    selected = []
-
-    # during scene exports unselect everything. this is needed for
-    # applying modifiers, if it is necessary
-    # record the selected nodes so that selection is restored later
-    for obj in api.selected_objects():
-        api.object.unselect(obj)
-        selected.append(obj)
-    active = api.active_object()
-
-    try:
-        scene_ = scene.Scene(filepath, options=options)
-        scene_.parse()
-        scene_.write()
-    except:
-        _restore_selection(selected, active)
-        raise
-        
-    _restore_selection(selected, active)
-
-
-@_error_handler
-def export_geometry(filepath, options, node=None):
-    msg = ""
-    exception = None
-    if node is None:
-        node = api.active_object()
-        if node is None:
-            msg = "Nothing selected"
-            logger.error(msg)
-            exception = exceptions.SelectionError
-        if node.type != 'MESH':
-            msg = "%s is not a valid mesh object" % node.name
-            logger.error(msg)
-            exception = exceptions.GeometryError
-    
-        if exception is not None:
-            if api.batch_mode():
-                raise exception(msg)
-            else:
-                dialogs.error(msg)
-                return
-
-    mesh = api.object.mesh(node, options)
-    parent = base_classes.BaseScene(filepath, options)
-    geo = geometry.Geometry(mesh, parent)
-    geo.parse()
-    geo.write()
-    
-    if not options.get(constants.EMBED_ANIMATION, True):
-        geo.write_animation(os.path.dirname(filepath))
-
-
-def _restore_selection(objects, active):
-    for obj in objects:
-        api.object.select(obj)
-
-    api.set_active_object(active)

+ 0 - 208
utils/exporters/blender/addons/io_three/exporter/_json.py

@@ -1,208 +0,0 @@
-import json
-from .. import constants
-
-ROUND = constants.DEFAULT_PRECISION
-
-## THREE override function
-def _json_floatstr(o):
-    if ROUND is not None:
-        o = round(o, ROUND)
-        
-    return '%g' % o
-
-
-def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
-        _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
-        ## HACK: hand-optimized bytecode; turn globals into locals
-        ValueError=ValueError,
-        dict=dict,
-        float=float,
-        id=id,
-        int=int,
-        isinstance=isinstance,
-        list=list,
-        str=str,
-        tuple=tuple,
-    ):
-    '''
-    Overwrite json.encoder for Python 2.7 and above to not
-    assign each index of a list or tuple to its own row as
-    this is completely asinine behaviour 
-    '''
-
-    ## @THREE
-    # Override the function
-    _floatstr = _json_floatstr
-
-    if _indent is not None and not isinstance(_indent, str):
-        _indent = ' ' * _indent
-
-    def _iterencode_list(lst, _current_indent_level):
-        if not lst:
-            yield '[]'
-            return
-        if markers is not None:
-            markerid = id(lst)
-            if markerid in markers:
-                raise ValueError("Circular reference detected")
-            markers[markerid] = lst
-        buf = '['
-        ## @THREEJS
-        # -  block the moronic functionality that puts each
-        #    index on its own line causing insane row counts
-        #if _indent is not None:
-        #    _current_indent_level += 1
-        #    newline_indent = '\n' + _indent * _current_indent_level
-        #    separator = _item_separator + newline_indent
-        #    buf += newline_indent
-        #else:
-        newline_indent = None
-        separator = _item_separator
-        first = True
-        for value in lst:
-            if first:
-                first = False
-            else:
-                buf = separator
-            if isinstance(value, str):
-                yield buf + _encoder(value)
-            elif value is None:
-                yield buf + 'null'
-            elif value is True:
-                yield buf + 'true'
-            elif value is False:
-                yield buf + 'false'
-            elif isinstance(value, int):
-                yield buf + str(value)
-            elif isinstance(value, float):
-                yield buf + _floatstr(value)
-            else:
-                yield buf
-                if isinstance(value, (list, tuple)):
-                    chunks = _iterencode_list(value, _current_indent_level)
-                elif isinstance(value, dict):
-                    chunks = _iterencode_dict(value, _current_indent_level)
-                else:
-                    chunks = _iterencode(value, _current_indent_level)
-                for chunk in chunks:
-                    yield chunk
-        if newline_indent is not None:
-            _current_indent_level -= 1
-            yield '\n' + _indent * _current_indent_level
-        yield ']'
-        if markers is not None:
-            del markers[markerid]
-
-    def _iterencode_dict(dct, _current_indent_level):
-        if not dct:
-            yield '{}'
-            return
-        if markers is not None:
-            markerid = id(dct)
-            if markerid in markers:
-                raise ValueError("Circular reference detected")
-            markers[markerid] = dct
-        yield '{'
-        if _indent is not None:
-            _current_indent_level += 1
-            newline_indent = '\n' + _indent * _current_indent_level
-            item_separator = _item_separator + newline_indent
-            yield newline_indent
-        else:
-            newline_indent = None
-            item_separator = _item_separator
-        first = True
-        if _sort_keys:
-            items = sorted(dct.items(), key=lambda kv: kv[0])
-        else:
-            items = dct.items()
-        for key, value in items:
-            if isinstance(key, str):
-                pass
-            # JavaScript is weakly typed for these, so it makes sense to
-            # also allow them.  Many encoders seem to do something like this.
-            elif isinstance(key, float):
-                key = _floatstr(key)
-            elif key is True:
-                key = 'true'
-            elif key is False:
-                key = 'false'
-            elif key is None:
-                key = 'null'
-            elif isinstance(key, int):
-                key = str(key)
-            elif _skipkeys:
-                continue
-            else:
-                raise TypeError("key " + repr(key) + " is not a string")
-            if first:
-                first = False
-            else:
-                yield item_separator
-            yield _encoder(key)
-            yield _key_separator
-            if isinstance(value, str):
-                yield _encoder(value)
-            elif value is None:
-                yield 'null'
-            elif value is True:
-                yield 'true'
-            elif value is False:
-                yield 'false'
-            elif isinstance(value, int):
-                yield str(value)
-            elif isinstance(value, float):
-                yield _floatstr(value)
-            else:
-                if isinstance(value, (list, tuple)):
-                    chunks = _iterencode_list(value, _current_indent_level)
-                elif isinstance(value, dict):
-                    chunks = _iterencode_dict(value, _current_indent_level)
-                else:
-                    chunks = _iterencode(value, _current_indent_level)
-                for chunk in chunks:
-                    yield chunk
-        if newline_indent is not None:
-            _current_indent_level -= 1
-            yield '\n' + _indent * _current_indent_level
-        yield '}'
-        if markers is not None:
-            del markers[markerid]
-
-    def _iterencode(o, _current_indent_level):
-        if isinstance(o, str):
-            yield _encoder(o)
-        elif o is None:
-            yield 'null'
-        elif o is True:
-            yield 'true'
-        elif o is False:
-            yield 'false'
-        elif isinstance(o, int):
-            yield str(o)
-        elif isinstance(o, float):
-            yield _floatstr(o)
-        elif isinstance(o, (list, tuple)):
-            for chunk in _iterencode_list(o, _current_indent_level):
-                yield chunk
-        elif isinstance(o, dict):
-            for chunk in _iterencode_dict(o, _current_indent_level):
-                yield chunk
-        else:
-            if markers is not None:
-                markerid = id(o)
-                if markerid in markers:
-                    raise ValueError("Circular reference detected")
-                markers[markerid] = o
-            o = _default(o)
-            for chunk in _iterencode(o, _current_indent_level):
-                yield chunk
-            if markers is not None:
-                del markers[markerid]
-    return _iterencode
-
-
-# override the encoder
-json.encoder._make_iterencode = _make_iterencode 
-
-

+ 0 - 77
utils/exporters/blender/addons/io_three/exporter/api/__init__.py

@@ -1,77 +0,0 @@
-import os
-import bpy
-from . import object as object_, mesh, material, camera, light
-from .. import logger
-
-
-def active_object():
-    """
-
-    :return: The actively selected object
-
-    """
-    return bpy.context.scene.objects.active
-
-
-def batch_mode():
-    """
-
-    :return: Whether or not the session is interactive
-    :rtype: bool
-
-    """
-    return bpy.context.area is None
-
-
-def data(node):
-    """
-
-    :param node: name of an object node
-    :returns: the data block of the node
-
-    """
-    try:
-        return bpy.data.objects[node].data
-    except KeyError:
-        pass
-
-
-def init():
-    """Initializing the api module. Required first step before
-    initializing the actual export process.
-    """
-    logger.debug("Initializing API")
-    object_.clear_mesh_map()
-
-
-def selected_objects(valid_types=None):
-    """Selected objects.
-
-    :param valid_types: Filter for valid types (Default value = None)
-
-    """
-    logger.debug("api.selected_objects(%s)", valid_types)
-    for node in bpy.context.selected_objects:
-        if valid_types is None:
-            yield node.name
-        elif valid_types is not None and node.type in valid_types:
-            yield node.name
-
-
-def set_active_object(obj):
-    """Set the object as active in the scene
-
-    :param obj:
-
-    """
-    logger.debug("api.set_active_object(%s)", obj)
-    bpy.context.scene.objects.active = obj
-
-
-def scene_name():
-    """
-
-    :return: name of the current scene
-
-    """
-    return os.path.basename(bpy.data.filepath)

+ 0 - 683
utils/exporters/blender/addons/io_three/exporter/api/animation.py

@@ -1,683 +0,0 @@
-"""
-Module for handling the parsing of skeletal animation data.
-updated on 2/07/2016: bones scaling support (@uthor verteAzur [email protected])
-"""
-
-import math
-import mathutils
-from bpy import data, context, ops
-from .. import constants, logger
-
-def pose_animation(armature, options):
-    """Query armature animation using pose bones
-
-    :param armature:
-    :param options:
-    :returns: list dictionaries containing animationdata
-    :rtype: [{}, {}, ...]
-
-    """
-    logger.debug("animation.pose_animation(%s)", armature)
-    func = _parse_pose_action
-    return _parse_action(func, armature, options)
-
-
-def rest_animation(armature, options):
-    """Query armature animation (REST position)
-
-    :param armature:
-    :param options:
-    :returns: list dictionaries containing animationdata
-    :rtype: [{}, {}, ...]
-
-    """
-    logger.debug("animation.rest_animation(%s)", armature)
-    func = _parse_rest_action
-    return _parse_action(func, armature, options)
-
-
-def _parse_action(func, armature, options):
-    """
-
-    :param func:
-    :param armature:
-    :param options:
-
-    """
-    animations = []
-    logger.info("Parsing %d actions", len(data.actions))
-    for action in data.actions:
-        logger.info("Parsing action %s", action.name)
-        animation = func(action, armature, options)
-        animations.append(animation)
-    return animations
-
-
-def _parse_rest_action(action, armature, options):
-    """
-
-    :param action:
-    :param armature:
-    :param options:
-
-    """
-    end_frame = action.frame_range[1]
-    start_frame = action.frame_range[0]
-    frame_length = end_frame - start_frame
-    rot = armature.matrix_world.decompose()[1]
-    rotation_matrix = rot.to_matrix()
-    hierarchy = []
-    parent_index = -1
-    frame_step = options.get(constants.FRAME_STEP, 1)
-    fps = context.scene.render.fps
-
-    start = int(start_frame)
-    end = int(end_frame / frame_step) + 1
-
-    for bone in armature.data.bones:
-        # I believe this was meant to skip control bones, may
-        # not be useful. needs more testing
-        if bone.use_deform is False:
-            logger.info("Skipping animation data for bone %s", bone.name)
-            continue
-
-        logger.info("Parsing animation data for bone %s", bone.name)
-
-        keys = []
-        for frame in range(start, end):
-            computed_frame = frame * frame_step
-            pos, pchange = _position(bone, computed_frame,
-                                     action, armature.matrix_world)
-            rot, rchange = _rotation(bone, computed_frame,
-                                     action, rotation_matrix)
-            rot = _normalize_quaternion(rot)
-
-            sca, schange = _scale(bone, computed_frame,
-                                     action, armature.matrix_world)
-
-            pos_x, pos_y, pos_z = pos.x, pos.z, -pos.y
-            rot_x, rot_y, rot_z, rot_w = rot.x, rot.z, -rot.y, rot.w
-            sca_x, sca_y, sca_z = sca.x, sca.z, sca.y
-
-            if frame == start_frame:
-
-                time = (frame * frame_step - start_frame) / fps
-                
-                keyframe = {
-                    constants.TIME: time,
-                    constants.POS: [pos_x, pos_y, pos_z],
-                    constants.ROT: [rot_x, rot_y, rot_z, rot_w],
-                    constants.SCL: [sca_x, sca_y, sca_z]
-                }
-                keys.append(keyframe)
-
-            # END-FRAME: needs pos, rot and scl attributes
-            # with animation length (required frame)
-
-            elif frame == end_frame / frame_step:
-
-                time = frame_length / fps
-                keyframe = {
-                    constants.TIME: time,
-                    constants.POS: [pos_x, pos_y, pos_z],
-                    constants.ROT: [rot_x, rot_y, rot_z, rot_w],
-                    constants.SCL: [sca_x, sca_y, sca_z]
-                }
-                keys.append(keyframe)
-
-            # MIDDLE-FRAME: needs only one of the attributes,
-            # can be an empty frame (optional frame)
-
-            elif pchange is True or rchange is True or schange is True:
-
-                time = (frame * frame_step - start_frame) / fps
-
-                if pchange is True and rchange is True:
-                    keyframe = {
-                        constants.TIME: time,
-                        constants.POS: [pos_x, pos_y, pos_z],
-                        constants.ROT: [rot_x, rot_y, rot_z, rot_w],
-                        constants.SCL: [sca_x, sca_y, sca_z]
-                    }
-                elif pchange is True:
-                    keyframe = {
-                        constants.TIME: time,
-                        constants.POS: [pos_x, pos_y, pos_z]
-                    }
-                elif rchange is True:
-                    keyframe = {
-                        constants.TIME: time,
-                        constants.ROT: [rot_x, rot_y, rot_z, rot_w]
-                    }
-                elif schange is True:
-                    keyframe = {
-                        constants.TIME: time,
-                        constants.SCL: [sca_x, sca_y, sca_z]
-                    }
-
-                keys.append(keyframe)
-
-        hierarchy.append({
-            constants.KEYS: keys,
-            constants.PARENT: parent_index
-        })
-        parent_index += 1
-
-    animation = {
-        constants.HIERARCHY: hierarchy,
-        constants.LENGTH: frame_length / fps,
-        constants.FPS: fps,
-        constants.NAME: action.name
-    }
-
-    return animation
-
-
-def _parse_pose_action(action, armature, options):
-    """
-
-    :param action:
-    :param armature:
-    :param options:
-
-    """
-    try:
-        current_context = context.area.type
-    except AttributeError:
-        for window in context.window_manager.windows:
-            screen = window.screen
-            for area in screen.areas:
-                if area.type != 'VIEW_3D':
-                    continue
-
-                override = {
-                    'window': window,
-                    'screen': screen,
-                    'area': area
-                }
-                ops.screen.screen_full_area(override)
-                break
-        current_context = context.area.type
-
-    context.scene.objects.active = armature
-    context.area.type = 'DOPESHEET_EDITOR'
-    context.space_data.mode = 'ACTION'
-    context.area.spaces.active.action = action
-
-    armature_matrix = armature.matrix_world
-    fps = context.scene.render.fps
-
-    end_frame = action.frame_range[1]
-    start_frame = action.frame_range[0]
-    frame_length = end_frame - start_frame
-
-    frame_step = options.get(constants.FRAME_STEP, 1)
-    used_frames = int(frame_length / frame_step) + 1
-
-    keys = []
-    channels_location = []
-    channels_rotation = []
-    channels_scale = []
-
-    for pose_bone in armature.pose.bones:
-        logger.info("Processing channels for %s",
-                    pose_bone.bone.name)
-        keys.append([])
-        channels_location.append(
-            _find_channels(action,
-                           pose_bone.bone,
-                           'location'))
-        channels_rotation.append(
-            _find_channels(action,
-                           pose_bone.bone,
-                           'rotation_quaternion'))
-        channels_rotation.append(
-            _find_channels(action,
-                           pose_bone.bone,
-                           'rotation_euler'))
-        channels_scale.append(
-            _find_channels(action,
-                           pose_bone.bone,
-                           'scale'))
-
-    frame_step = options[constants.FRAME_STEP]
-    frame_index_as_time = options[constants.FRAME_INDEX_AS_TIME]
-    for frame_index in range(0, used_frames):
-        if frame_index == used_frames - 1:
-            frame = end_frame
-        else:
-            frame = start_frame + frame_index * frame_step
-
-        logger.info("Processing frame %d", frame)
-
-        time = frame - start_frame
-        if frame_index_as_time is False:
-            time = time / fps
-
-        context.scene.frame_set(frame)
-
-        bone_index = 0
-
-        def has_keyframe_at(channels, frame):
-            """
-
-            :param channels:
-            :param frame:
-
-            """
-            def find_keyframe_at(channel, frame):
-                """
-
-                :param channel:
-                :param frame:
-
-                """
-                for keyframe in channel.keyframe_points:
-                    if keyframe.co[0] == frame:
-                        return keyframe
-                return None
-
-            for channel in channels:
-                if not find_keyframe_at(channel, frame) is None:
-                    return True
-            return False
-
-        for pose_bone in armature.pose.bones:
-
-            logger.info("Processing bone %s", pose_bone.bone.name)
-            if pose_bone.parent is None:
-                bone_matrix = armature_matrix * pose_bone.matrix
-            else:
-                parent_matrix = armature_matrix * pose_bone.parent.matrix
-                bone_matrix = armature_matrix * pose_bone.matrix
-                bone_matrix = parent_matrix.inverted() * bone_matrix
-
-            pos, rot, scl = bone_matrix.decompose()
-            rot = _normalize_quaternion(rot)
-
-            pchange = True or has_keyframe_at(
-                channels_location[bone_index], frame)
-            rchange = True or has_keyframe_at(
-                channels_rotation[bone_index], frame)
-            schange = True or has_keyframe_at(
-                channels_scale[bone_index], frame)
-
-            pos = (pos.x, pos.z, -pos.y)
-            rot = (rot.x, rot.z, -rot.y, rot.w)
-            scl = (scl.x, scl.z, scl.y)
-
-            keyframe = {constants.TIME: time}
-            if frame == start_frame or frame == end_frame:
-                keyframe.update({
-                    constants.POS: pos,
-                    constants.ROT: rot,
-                    constants.SCL: scl
-                })
-            elif any([pchange, rchange, schange]):
-                if pchange is True:
-                    keyframe[constants.POS] = pos
-                if rchange is True:
-                    keyframe[constants.ROT] = rot
-                if schange is True:
-                    keyframe[constants.SCL] = scl
-
-            if len(keyframe.keys()) > 1:
-                logger.info("Recording keyframe data for %s %s",
-                            pose_bone.bone.name, str(keyframe))
-                keys[bone_index].append(keyframe)
-            else:
-                logger.info("No anim data to record for %s",
-                            pose_bone.bone.name)
-
-            bone_index += 1
-
-    hierarchy = []
-    bone_index = 0
-    for pose_bone in armature.pose.bones:
-        hierarchy.append({
-            constants.PARENT: bone_index - 1,
-            constants.KEYS: keys[bone_index]
-        })
-        bone_index += 1
-
-    if frame_index_as_time is False:
-        frame_length = frame_length / fps
-
-    context.scene.frame_set(start_frame)
-    context.area.type = current_context
-
-    animation = {
-        constants.HIERARCHY: hierarchy,
-        constants.LENGTH: frame_length,
-        constants.FPS: fps,
-        constants.NAME: action.name
-    }
-
-    return animation
-
-
-def _find_channels(action, bone, channel_type):
-    """
-
-    :param action:
-    :param bone:
-    :param channel_type:
-
-    """
-    result = []
-
-    if len(action.groups):
-
-        group_index = -1
-        for index, group in enumerate(action.groups):
-            if group.name == bone.name:
-                group_index = index
-                # @TODO: break?
-
-        if group_index > -1:
-            for channel in action.groups[group_index].channels:
-                if channel_type in channel.data_path:
-                    result.append(channel)
-
-    else:
-        bone_label = '"%s"' % bone.name
-        for channel in action.fcurves:
-            data_path = [bone_label in channel.data_path,
-                         channel_type in channel.data_path]
-            if all(data_path):
-                result.append(channel)
-
-    return result
-
-
-def _position(bone, frame, action, armature_matrix):
-    """
-
-    :param bone:
-    :param frame:
-    :param action:
-    :param armature_matrix:
-
-    """
-
-    position = mathutils.Vector((0, 0, 0))
-    change = False
-
-    ngroups = len(action.groups)
-
-    if ngroups > 0:
-
-        index = 0
-
-        for i in range(ngroups):
-            if action.groups[i].name == bone.name:
-                index = i
-
-        for channel in action.groups[index].channels:
-            if "location" in channel.data_path:
-                has_changed = _handle_position_channel(
-                    channel, frame, position)
-                change = change or has_changed
-
-    else:
-
-        bone_label = '"%s"' % bone.name
-
-        for channel in action.fcurves:
-            data_path = channel.data_path
-            if bone_label in data_path and "location" in data_path:
-                has_changed = _handle_position_channel(
-                    channel, frame, position)
-                change = change or has_changed
-
-    position = position * bone.matrix_local.inverted()
-
-    if bone.parent is None:
-
-        position.x += bone.head.x
-        position.y += bone.head.y
-        position.z += bone.head.z
-
-    else:
-
-        parent = bone.parent
-
-        parent_matrix = parent.matrix_local.inverted()
-        diff = parent.tail_local - parent.head_local
-
-        position.x += (bone.head * parent_matrix).x + diff.x
-        position.y += (bone.head * parent_matrix).y + diff.y
-        position.z += (bone.head * parent_matrix).z + diff.z
-
-    return armature_matrix*position, change
-
-
-def _rotation(bone, frame, action, armature_matrix):
-    """
-
-    :param bone:
-    :param frame:
-    :param action:
-    :param armature_matrix:
-
-    """
-
-    # TODO: calculate rotation also from rotation_euler channels
-
-    rotation = mathutils.Vector((0, 0, 0, 1))
-
-    change = False
-
-    ngroups = len(action.groups)
-
-    # animation grouped by bones
-
-    if ngroups > 0:
-
-        index = -1
-
-        for i in range(ngroups):
-            if action.groups[i].name == bone.name:
-                index = i
-
-        if index > -1:
-            for channel in action.groups[index].channels:
-                if "quaternion" in channel.data_path:
-                    has_changed = _handle_rotation_channel(
-                        channel, frame, rotation)
-                    change = change or has_changed
-
-    # animation in raw fcurves
-
-    else:
-
-        bone_label = '"%s"' % bone.name
-
-        for channel in action.fcurves:
-            data_path = channel.data_path
-            if bone_label in data_path and "quaternion" in data_path:
-                has_changed = _handle_rotation_channel(
-                    channel, frame, rotation)
-                change = change or has_changed
-
-    rot3 = rotation.to_3d()
-    rotation.xyz = rot3 * bone.matrix_local.inverted()
-    rotation.xyz = armature_matrix * rotation.xyz
-
-    return rotation, change
-
-def _scale(bone, frame, action, armature_matrix):
-    """
-
-    :param bone:
-    :param frame:
-    :param action:
-    :param armature_matrix:
-
-    """
-    scale = mathutils.Vector((1.0, 1.0, 1.0))
-
-    change = False
-
-    ngroups = len(action.groups)
-
-    # animation grouped by bones
-	
-    if ngroups > 0:
-
-        index = -1
-
-        for i in range(ngroups):
-            if action.groups[i].name == bone.name:
-		
-                print(action.groups[i].name)
-
-                index = i
-
-        if index > -1:
-            for channel in action.groups[index].channels:
- 
-                if "scale" in channel.data_path:
-                    has_changed = _handle_scale_channel(
-                        channel, frame, scale)
-                    change = change or has_changed
-                    
-    # animation in raw fcurves
-
-    else:
-
-        bone_label = '"%s"' % bone.name
-	
-        for channel in action.fcurves:
-            data_path = channel.data_path
-            if bone_label in data_path and "scale" in data_path:
-                has_changed = _handle_scale_channel(
-                    channel, frame, scale)
-                change = change or has_changed
-    	
-   
-    #scale.xyz = armature_matrix * scale.xyz
-
-    return scale, change
-
-
-def _handle_rotation_channel(channel, frame, rotation):
-    """
-
-    :param channel:
-    :param frame:
-    :param rotation:
-
-    """
-
-    change = False
-
-    if channel.array_index in [0, 1, 2, 3]:
-
-        for keyframe in channel.keyframe_points:
-            if keyframe.co[0] == frame:
-                change = True
-
-        value = channel.evaluate(frame)
-
-        if channel.array_index == 1:
-            rotation.x = value
-
-        elif channel.array_index == 2:
-            rotation.y = value
-
-        elif channel.array_index == 3:
-            rotation.z = value
-
-        elif channel.array_index == 0:
-            rotation.w = value
-
-    return change
-
-
-def _handle_position_channel(channel, frame, position):
-    """
-
-    :param channel:
-    :param frame:
-    :param position:
-
-    """
-
-    change = False
-
-    if channel.array_index in [0, 1, 2]:
-        for keyframe in channel.keyframe_points:
-            if keyframe.co[0] == frame:
-                change = True
-
-        value = channel.evaluate(frame)
-
-        if channel.array_index == 0:
-            position.x = value
-
-        if channel.array_index == 1:
-            position.y = value
-
-        if channel.array_index == 2:
-            position.z = value
-
-    return change
-
-def _handle_scale_channel(channel, frame, scale):
-    """
-
-    :param channel:
-    :param frame:
-    :param position:
-
-    """
-    change = False
-
-    if channel.array_index in [0, 1, 2]:
-        for keyframe in channel.keyframe_points:
-            if keyframe.co[0] == frame:
-                change = True
-       
-        value = channel.evaluate(frame)
-      
-        if channel.array_index == 0:
-            scale.x = value
-
-        if channel.array_index == 1:
-            scale.y = value
-
-        if channel.array_index == 2:
-            scale.z = value
-
-    return change
-
-
-def _quaternion_length(quat):
-    """Calculate the length of a quaternion
-
-    :param quat: Blender quaternion object
-    :rtype: float
-
-    """
-    return math.sqrt(quat.x * quat.x + quat.y * quat.y +
-                     quat.z * quat.z + quat.w * quat.w)
-
-
-def _normalize_quaternion(quat):
-    """Normalize a quaternion
-
-    :param quat: Blender quaternion object
-    :returns: generic quaternion enum object with normalized values
-    :rtype: object
-
-    """
-    enum = type('Enum', (), {'x': 0, 'y': 0, 'z': 0, 'w': 1})
-    length = _quaternion_length(quat)
-    if length is not 0:
-        length = 1 / length
-        enum.x = quat.x * length
-        enum.y = quat.y * length
-        enum.z = quat.z * length
-        enum.w = quat.w * length
-    return enum

+ 0 - 130
utils/exporters/blender/addons/io_three/exporter/api/camera.py

@@ -1,130 +0,0 @@
-import math
-from bpy import data, types, context
-from .. import logger
-
-
-def _camera(func):
-    """
-
-    :param func:
-
-    """
-
-    def inner(name, *args, **kwargs):
-        """
-
-        :param name:
-        :param *args:
-        :param **kwargs:
-
-        """
-
-        if isinstance(name, types.Camera):
-            camera = name
-        else:
-            camera = data.cameras[name]
-
-        return func(camera, *args, **kwargs)
-
-    return inner
-
-
-@_camera
-def aspect(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.aspect(%s)", camera)
-    render = context.scene.render
-    return render.resolution_x/render.resolution_y
-
-
-@_camera
-def bottom(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.bottom(%s)", camera)
-    return -(camera.angle_y * camera.ortho_scale)
-
-
-@_camera
-def far(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.far(%s)", camera)
-    return camera.clip_end
-
-
-@_camera
-def fov(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.fov(%s)", camera)
-    fov_in_radians = camera.angle
-    aspect_ratio = aspect(camera)
-    if aspect_ratio > 1:
-        fov_in_radians = 2 * math.atan(math.tan(fov_in_radians / 2) / aspect_ratio)
-    return math.degrees(fov_in_radians)
-
-
-@_camera
-def left(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.left(%s)", camera)
-    return -(camera.angle_x * camera.ortho_scale)
-
-
-@_camera
-def near(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.near(%s)", camera)
-    return camera.clip_start
-
-
-@_camera
-def right(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.right(%s)", camera)
-    return camera.angle_x * camera.ortho_scale
-
-
-@_camera
-def top(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.top(%s)", camera)
-    return camera.angle_y * camera.ortho_scale

+ 0 - 29
utils/exporters/blender/addons/io_three/exporter/api/constants.py

@@ -1,29 +0,0 @@
-MESH = 'MESH'
-LAMP = 'LAMP'
-EMPTY = 'EMPTY'
-ARMATURE = 'ARMATURE'
-
-SPOT = 'SPOT'
-POINT = 'POINT'
-SUN = 'SUN'
-HEMI = 'HEMI'
-AREA = 'AREA'
-
-NO_SHADOW = 'NOSHADOW'
-
-CAMERA = 'CAMERA'
-PERSP = 'PERSP'
-ORTHO = 'ORTHO'
-
-RENDER = 'RENDER'
-
-ZYX = 'ZYX'
-
-MULTIPLY = 'MULTIPLY'
-
-WIRE = 'WIRE'
-IMAGE = 'IMAGE'
-
-MAG_FILTER = 'LinearFilter'
-MIN_FILTER = 'LinearMipMapLinearFilter'
-MAPPING = 'UVMapping'

Some files were not shown because too many files changed in this diff