<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 */

THREE.JSONLoader = function ( showStatus ) {

	THREE.Loader.call( this, showStatus );

	this.withCredentials = false;

};

THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype );

THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) {

	var scope = this;

	// todo: unify load API to for easier SceneLoader use

	texturePath = texturePath && ( typeof texturePath === "string" ) ? texturePath : this.extractUrlBase( url );

	this.onLoadStart();
	this.loadAjaxJSON( this, url, callback, texturePath );

};

THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, callbackProgress ) {

	var xhr = new XMLHttpRequest();

	var length = 0;

	xhr.onreadystatechange = function () {

		if ( xhr.readyState === xhr.DONE ) {

			if ( xhr.status === 200 || xhr.status === 0 ) {

				if ( xhr.responseText ) {

					var json = JSON.parse( xhr.responseText );

					if ( json.metadata.type === 'scene' ) {

						console.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' );
						return;

					}

					var result = context.parse( json, texturePath );
					callback( result.geometry, result.materials );

				} else {

					console.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' );

				}

				// in context of more complex asset initialization
				// do not block on single failed file
				// maybe should go even one more level up

				context.onLoadComplete();

			} else {

				console.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' );

			}

		} else if ( xhr.readyState === xhr.LOADING ) {

			if ( callbackProgress ) {

				if ( length === 0 ) {

					length = xhr.getResponseHeader( 'Content-Length' );

				}

				callbackProgress( { total: length, loaded: xhr.responseText.length } );

			}

		} else if ( xhr.readyState === xhr.HEADERS_RECEIVED ) {

			if ( callbackProgress !== undefined ) {

				length = xhr.getResponseHeader( "Content-Length" );

			}

		}

	};

	xhr.open( "GET", url, true );
	xhr.withCredentials = this.withCredentials;
	xhr.send( null );

};

THREE.JSONLoader.prototype.parse = function ( json, texturePath ) {

	var scope = this,
	geometry = new THREE.Geometry(),
	scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;

	parseModel( scale );

	parseSkin();
	parseMorphing( scale );

	geometry.computeCentroids();
	geometry.computeFaceNormals();
	geometry.computeBoundingSphere();

	function parseModel( scale ) {

		function isBitSet( value, position ) {

			return value & ( 1 << position );

		}

		var i, j, fi,

		offset, zLength,

		colorIndex, normalIndex, uvIndex, materialIndex,

		type,
		isQuad,
		hasMaterial,
		hasFaceVertexUv,
		hasFaceNormal, hasFaceVertexNormal,
		hasFaceColor, hasFaceVertexColor,

		vertex, face, faceA, faceB, color, hex, normal,

		uvLayer, uv, u, v,

		faces = json.faces,
		vertices = json.vertices,
		normals = json.normals,
		colors = json.colors,

		nUvLayers = 0;

		if ( json.uvs !== undefined ) {

			// disregard empty arrays

			for ( i = 0; i < json.uvs.length; i++ ) {

				if ( json.uvs[ i ].length ) nUvLayers ++;

			}

			for ( i = 0; i < nUvLayers; i++ ) {

				geometry.faceVertexUvs[ i ] = [];

			}

		}

		offset = 0;
		zLength = vertices.length;

		while ( offset < zLength ) {

			vertex = new THREE.Vector3();

			vertex.x = vertices[ offset ++ ] * scale;
			vertex.y = vertices[ offset ++ ] * scale;
			vertex.z = vertices[ offset ++ ] * scale;

			geometry.vertices.push( vertex );

		}

		offset = 0;
		zLength = faces.length;

		while ( offset < zLength ) {

			type = faces[ offset ++ ];

			isQuad              = isBitSet( type, 0 );
			hasMaterial         = isBitSet( type, 1 );
			hasFaceVertexUv     = isBitSet( type, 3 );
			hasFaceNormal       = isBitSet( type, 4 );
			hasFaceVertexNormal = isBitSet( type, 5 );
			hasFaceColor	    = isBitSet( type, 6 );
			hasFaceVertexColor  = isBitSet( type, 7 );

			// console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);

			if ( isQuad ) {

				faceA = new THREE.Face3();
				faceA.a = faces[ offset ];
				faceA.b = faces[ offset + 1 ];
				faceA.c = faces[ offset + 3 ];

				faceB = new THREE.Face3();
				faceB.a = faces[ offset + 1 ];
				faceB.b = faces[ offset + 2 ];
				faceB.c = faces[ offset + 3 ];

				offset += 4;

				if ( hasMaterial ) {

					materialIndex = faces[ offset ++ ];
					faceA.materialIndex = materialIndex;
					faceB.materialIndex = materialIndex;

				}

				// to get face <=> uv index correspondence

				fi = geometry.faces.length;

				if ( hasFaceVertexUv ) {

					for ( i = 0; i < nUvLayers; i++ ) {

						uvLayer = json.uvs[ i ];

						geometry.faceVertexUvs[ i ][ fi ] = [];
						geometry.faceVertexUvs[ i ][ fi + 1 ] = []

						for ( j = 0; j < 4; j ++ ) {

							uvIndex = faces[ offset ++ ];

							u = uvLayer[ uvIndex * 2 ];
							v = uvLayer[ uvIndex * 2 + 1 ];

							uv = new THREE.Vector2( u, v );

							if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
							if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );

						}

					}

				}

				if ( hasFaceNormal ) {

					normalIndex = faces[ offset ++ ] * 3;

					faceA.normal.set(
						normals[ normalIndex ++ ],
						normals[ normalIndex ++ ],
						normals[ normalIndex ]
					);

					faceB.normal.copy( faceA.normal );

				}

				if ( hasFaceVertexNormal ) {

					for ( i = 0; i < 4; i++ ) {

						normalIndex = faces[ offset ++ ] * 3;

						normal = new THREE.Vector3(
							normals[ normalIndex ++ ],
							normals[ normalIndex ++ ],
							normals[ normalIndex ]
						);

						if ( i !== 2 ) faceA.vertexNormals.push( normal );
						if ( i !== 0 ) faceB.vertexNormals.push( normal );

					}

				}

				if ( hasFaceColor ) {

					colorIndex = faces[ offset ++ ];
					hex = colors[ colorIndex ];

					faceA.color.setHex( hex );
					faceB.color.setHex( hex );

				}

				if ( hasFaceVertexColor ) {

					for ( i = 0; i < 4; i++ ) {

						colorIndex = faces[ offset ++ ];
						hex = colors[ colorIndex ];

						if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) );
						if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) );

					}

				}

				geometry.faces.push( faceA );
				geometry.faces.push( faceB );

			} else {

				face = new THREE.Face3();
				face.a = faces[ offset ++ ];
				face.b = faces[ offset ++ ];
				face.c = faces[ offset ++ ];

				if ( hasMaterial ) {

					materialIndex = faces[ offset ++ ];
					face.materialIndex = materialIndex;

				}

				// to get face <=> uv index correspondence

				fi = geometry.faces.length;

				if ( hasFaceVertexUv ) {

					for ( i = 0; i < nUvLayers; i++ ) {

						uvLayer = json.uvs[ i ];

						geometry.faceVertexUvs[ i ][ fi ] = [];

						for ( j = 0; j < 3; j ++ ) {

							uvIndex = faces[ offset ++ ];

							u = uvLayer[ uvIndex * 2 ];
							v = uvLayer[ uvIndex * 2 + 1 ];

							uv = new THREE.Vector2( u, v );

							geometry.faceVertexUvs[ i ][ fi ].push( uv );

						}

					}

				}

				if ( hasFaceNormal ) {

					normalIndex = faces[ offset ++ ] * 3;

					face.normal.set(
						normals[ normalIndex ++ ],
						normals[ normalIndex ++ ],
						normals[ normalIndex ]
					);

				}

				if ( hasFaceVertexNormal ) {

					for ( i = 0; i < 3; i++ ) {

						normalIndex = faces[ offset ++ ] * 3;

						normal = new THREE.Vector3(
							normals[ normalIndex ++ ],
							normals[ normalIndex ++ ],
							normals[ normalIndex ]
						);

						face.vertexNormals.push( normal );

					}

				}

				if ( hasFaceColor ) {

					colorIndex = faces[ offset ++ ];
					face.color.setHex( colors[ colorIndex ] );

				}

				if ( hasFaceVertexColor ) {

					for ( i = 0; i < 3; i++ ) {

						colorIndex = faces[ offset ++ ];
						face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );

					}

				}

				geometry.faces.push( face );

			}

		}

	};

	function parseSkin() {

		var i, l, x, y, z, w, a, b, c, d;

		if ( json.skinWeights ) {

			for ( i = 0, l = json.skinWeights.length; i < l; i += 2 ) {

				x = json.skinWeights[ i     ];
				y = json.skinWeights[ i + 1 ];
				z = 0;
				w = 0;

				geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );

			}

		}

		if ( json.skinIndices ) {

			for ( i = 0, l = json.skinIndices.length; i < l; i += 2 ) {

				a = json.skinIndices[ i     ];
				b = json.skinIndices[ i + 1 ];
				c = 0;
				d = 0;

				geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );

			}

		}

		geometry.bones = json.bones;
		// could change this to json.animations[0] or remove completely
		geometry.animation = json.animation;
		geometry.animations = json.animations;
	};

	function parseMorphing( scale ) {

		if ( json.morphTargets !== undefined ) {

			var i, l, v, vl, dstVertices, srcVertices;

			for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {

				geometry.morphTargets[ i ] = {};
				geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
				geometry.morphTargets[ i ].vertices = [];

				dstVertices = geometry.morphTargets[ i ].vertices;
				srcVertices = json.morphTargets [ i ].vertices;

				for( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {

					var vertex = new THREE.Vector3();
					vertex.x = srcVertices[ v ] * scale;
					vertex.y = srcVertices[ v + 1 ] * scale;
					vertex.z = srcVertices[ v + 2 ] * scale;

					dstVertices.push( vertex );

				}

			}

		}

		if ( json.morphColors !== undefined ) {

			var i, l, c, cl, dstColors, srcColors, color;

			for ( i = 0, l = json.morphColors.length; i < l; i++ ) {

				geometry.morphColors[ i ] = {};
				geometry.morphColors[ i ].name = json.morphColors[ i ].name;
				geometry.morphColors[ i ].colors = [];

				dstColors = geometry.morphColors[ i ].colors;
				srcColors = json.morphColors [ i ].colors;

				for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {

					color = new THREE.Color( 0xffaa00 );
					color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
					dstColors.push( color );

				}

			}

		}

	};

	if ( json.materials === undefined ) {

		return { geometry: geometry };

	} else {

		var materials = this.initMaterials( json.materials, texturePath );

		if ( this.needsTangents( materials ) ) {

			geometry.computeTangents();

		}

		return { geometry: geometry, materials: materials };

	}

};
<commit_msg>Add error for invalid skinIndices or skinWeights import data lengths. Fixes #4421<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 */

THREE.JSONLoader = function ( showStatus ) {

	THREE.Loader.call( this, showStatus );

	this.withCredentials = false;

};

THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype );

THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) {

	var scope = this;

	// todo: unify load API to for easier SceneLoader use

	texturePath = texturePath && ( typeof texturePath === "string" ) ? texturePath : this.extractUrlBase( url );

	this.onLoadStart();
	this.loadAjaxJSON( this, url, callback, texturePath );

};

THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, callbackProgress ) {

	var xhr = new XMLHttpRequest();

	var length = 0;

	xhr.onreadystatechange = function () {

		if ( xhr.readyState === xhr.DONE ) {

			if ( xhr.status === 200 || xhr.status === 0 ) {

				if ( xhr.responseText ) {

					var json = JSON.parse( xhr.responseText );

					if ( json.metadata.type === 'scene' ) {

						console.error( 'THREE.JSONLoader: "' + url + '" seems to be a Scene. Use THREE.SceneLoader instead.' );
						return;

					}

					var result = context.parse( json, texturePath );
					callback( result.geometry, result.materials );

				} else {

					console.error( 'THREE.JSONLoader: "' + url + '" seems to be unreachable or the file is empty.' );

				}

				// in context of more complex asset initialization
				// do not block on single failed file
				// maybe should go even one more level up

				context.onLoadComplete();

			} else {

				console.error( 'THREE.JSONLoader: Couldn\'t load "' + url + '" (' + xhr.status + ')' );

			}

		} else if ( xhr.readyState === xhr.LOADING ) {

			if ( callbackProgress ) {

				if ( length === 0 ) {

					length = xhr.getResponseHeader( 'Content-Length' );

				}

				callbackProgress( { total: length, loaded: xhr.responseText.length } );

			}

		} else if ( xhr.readyState === xhr.HEADERS_RECEIVED ) {

			if ( callbackProgress !== undefined ) {

				length = xhr.getResponseHeader( "Content-Length" );

			}

		}

	};

	xhr.open( "GET", url, true );
	xhr.withCredentials = this.withCredentials;
	xhr.send( null );

};

THREE.JSONLoader.prototype.parse = function ( json, texturePath ) {

	var scope = this,
	geometry = new THREE.Geometry(),
	scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;

	parseModel( scale );

	parseSkin();
	parseMorphing( scale );

	geometry.computeCentroids();
	geometry.computeFaceNormals();
	geometry.computeBoundingSphere();

	function parseModel( scale ) {

		function isBitSet( value, position ) {

			return value & ( 1 << position );

		}

		var i, j, fi,

		offset, zLength,

		colorIndex, normalIndex, uvIndex, materialIndex,

		type,
		isQuad,
		hasMaterial,
		hasFaceVertexUv,
		hasFaceNormal, hasFaceVertexNormal,
		hasFaceColor, hasFaceVertexColor,

		vertex, face, faceA, faceB, color, hex, normal,

		uvLayer, uv, u, v,

		faces = json.faces,
		vertices = json.vertices,
		normals = json.normals,
		colors = json.colors,

		nUvLayers = 0;

		if ( json.uvs !== undefined ) {

			// disregard empty arrays

			for ( i = 0; i < json.uvs.length; i++ ) {

				if ( json.uvs[ i ].length ) nUvLayers ++;

			}

			for ( i = 0; i < nUvLayers; i++ ) {

				geometry.faceVertexUvs[ i ] = [];

			}

		}

		offset = 0;
		zLength = vertices.length;

		while ( offset < zLength ) {

			vertex = new THREE.Vector3();

			vertex.x = vertices[ offset ++ ] * scale;
			vertex.y = vertices[ offset ++ ] * scale;
			vertex.z = vertices[ offset ++ ] * scale;

			geometry.vertices.push( vertex );

		}

		offset = 0;
		zLength = faces.length;

		while ( offset < zLength ) {

			type = faces[ offset ++ ];

			isQuad              = isBitSet( type, 0 );
			hasMaterial         = isBitSet( type, 1 );
			hasFaceVertexUv     = isBitSet( type, 3 );
			hasFaceNormal       = isBitSet( type, 4 );
			hasFaceVertexNormal = isBitSet( type, 5 );
			hasFaceColor	    = isBitSet( type, 6 );
			hasFaceVertexColor  = isBitSet( type, 7 );

			// console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);

			if ( isQuad ) {

				faceA = new THREE.Face3();
				faceA.a = faces[ offset ];
				faceA.b = faces[ offset + 1 ];
				faceA.c = faces[ offset + 3 ];

				faceB = new THREE.Face3();
				faceB.a = faces[ offset + 1 ];
				faceB.b = faces[ offset + 2 ];
				faceB.c = faces[ offset + 3 ];

				offset += 4;

				if ( hasMaterial ) {

					materialIndex = faces[ offset ++ ];
					faceA.materialIndex = materialIndex;
					faceB.materialIndex = materialIndex;

				}

				// to get face <=> uv index correspondence

				fi = geometry.faces.length;

				if ( hasFaceVertexUv ) {

					for ( i = 0; i < nUvLayers; i++ ) {

						uvLayer = json.uvs[ i ];

						geometry.faceVertexUvs[ i ][ fi ] = [];
						geometry.faceVertexUvs[ i ][ fi + 1 ] = []

						for ( j = 0; j < 4; j ++ ) {

							uvIndex = faces[ offset ++ ];

							u = uvLayer[ uvIndex * 2 ];
							v = uvLayer[ uvIndex * 2 + 1 ];

							uv = new THREE.Vector2( u, v );

							if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv );
							if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv );

						}

					}

				}

				if ( hasFaceNormal ) {

					normalIndex = faces[ offset ++ ] * 3;

					faceA.normal.set(
						normals[ normalIndex ++ ],
						normals[ normalIndex ++ ],
						normals[ normalIndex ]
					);

					faceB.normal.copy( faceA.normal );

				}

				if ( hasFaceVertexNormal ) {

					for ( i = 0; i < 4; i++ ) {

						normalIndex = faces[ offset ++ ] * 3;

						normal = new THREE.Vector3(
							normals[ normalIndex ++ ],
							normals[ normalIndex ++ ],
							normals[ normalIndex ]
						);

						if ( i !== 2 ) faceA.vertexNormals.push( normal );
						if ( i !== 0 ) faceB.vertexNormals.push( normal );

					}

				}

				if ( hasFaceColor ) {

					colorIndex = faces[ offset ++ ];
					hex = colors[ colorIndex ];

					faceA.color.setHex( hex );
					faceB.color.setHex( hex );

				}

				if ( hasFaceVertexColor ) {

					for ( i = 0; i < 4; i++ ) {

						colorIndex = faces[ offset ++ ];
						hex = colors[ colorIndex ];

						if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) );
						if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) );

					}

				}

				geometry.faces.push( faceA );
				geometry.faces.push( faceB );

			} else {

				face = new THREE.Face3();
				face.a = faces[ offset ++ ];
				face.b = faces[ offset ++ ];
				face.c = faces[ offset ++ ];

				if ( hasMaterial ) {

					materialIndex = faces[ offset ++ ];
					face.materialIndex = materialIndex;

				}

				// to get face <=> uv index correspondence

				fi = geometry.faces.length;

				if ( hasFaceVertexUv ) {

					for ( i = 0; i < nUvLayers; i++ ) {

						uvLayer = json.uvs[ i ];

						geometry.faceVertexUvs[ i ][ fi ] = [];

						for ( j = 0; j < 3; j ++ ) {

							uvIndex = faces[ offset ++ ];

							u = uvLayer[ uvIndex * 2 ];
							v = uvLayer[ uvIndex * 2 + 1 ];

							uv = new THREE.Vector2( u, v );

							geometry.faceVertexUvs[ i ][ fi ].push( uv );

						}

					}

				}

				if ( hasFaceNormal ) {

					normalIndex = faces[ offset ++ ] * 3;

					face.normal.set(
						normals[ normalIndex ++ ],
						normals[ normalIndex ++ ],
						normals[ normalIndex ]
					);

				}

				if ( hasFaceVertexNormal ) {

					for ( i = 0; i < 3; i++ ) {

						normalIndex = faces[ offset ++ ] * 3;

						normal = new THREE.Vector3(
							normals[ normalIndex ++ ],
							normals[ normalIndex ++ ],
							normals[ normalIndex ]
						);

						face.vertexNormals.push( normal );

					}

				}

				if ( hasFaceColor ) {

					colorIndex = faces[ offset ++ ];
					face.color.setHex( colors[ colorIndex ] );

				}

				if ( hasFaceVertexColor ) {

					for ( i = 0; i < 3; i++ ) {

						colorIndex = faces[ offset ++ ];
						face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );

					}

				}

				geometry.faces.push( face );

			}

		}

	};

	function parseSkin() {

		var i, l, x, y, z, w, a, b, c, d;

		if ( json.skinWeights ) {

			for ( i = 0, l = json.skinWeights.length; i < l; i += 2 ) {

				x = json.skinWeights[ i     ];
				y = json.skinWeights[ i + 1 ];
				z = 0;
				w = 0;

				geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );

			}

		}

		if ( json.skinIndices ) {

			for ( i = 0, l = json.skinIndices.length; i < l; i += 2 ) {

				a = json.skinIndices[ i     ];
				b = json.skinIndices[ i + 1 ];
				c = 0;
				d = 0;

				geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );

			}

		}

		geometry.bones = json.bones;

    if ( (geometry.bones.length > 0) && (
      (geometry.skinWeights.length != geometry.skinIndices.length) ||
      (geometry.skinWeights.length != geometry.vertices.length) ) ) {
        console.warn('When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' +
          geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.');
    }

		// could change this to json.animations[0] or remove completely
		geometry.animation = json.animation;
		geometry.animations = json.animations;
	};

	function parseMorphing( scale ) {

		if ( json.morphTargets !== undefined ) {

			var i, l, v, vl, dstVertices, srcVertices;

			for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {

				geometry.morphTargets[ i ] = {};
				geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
				geometry.morphTargets[ i ].vertices = [];

				dstVertices = geometry.morphTargets[ i ].vertices;
				srcVertices = json.morphTargets [ i ].vertices;

				for( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {

					var vertex = new THREE.Vector3();
					vertex.x = srcVertices[ v ] * scale;
					vertex.y = srcVertices[ v + 1 ] * scale;
					vertex.z = srcVertices[ v + 2 ] * scale;

					dstVertices.push( vertex );

				}

			}

		}

		if ( json.morphColors !== undefined ) {

			var i, l, c, cl, dstColors, srcColors, color;

			for ( i = 0, l = json.morphColors.length; i < l; i++ ) {

				geometry.morphColors[ i ] = {};
				geometry.morphColors[ i ].name = json.morphColors[ i ].name;
				geometry.morphColors[ i ].colors = [];

				dstColors = geometry.morphColors[ i ].colors;
				srcColors = json.morphColors [ i ].colors;

				for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {

					color = new THREE.Color( 0xffaa00 );
					color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
					dstColors.push( color );

				}

			}

		}

	};

	if ( json.materials === undefined ) {

		return { geometry: geometry };

	} else {

		var materials = this.initMaterials( json.materials, texturePath );

		if ( this.needsTangents( materials ) ) {

			geometry.computeTangents();

		}

		return { geometry: geometry, materials: materials };

	}

};
<|endoftext|>


<commit_before>'use strict';

var Sinon = require('sinon');
var base = process.cwd();

var ConfigurableRecipeRegistry = require(base + '/lib/core/configurable_recipe_registry');

module.exports = function () {
	return {
		flows: new ConfigurableRecipeRegistry({
			parallel: Sinon.spy(),
			series: Sinon.spy()
		}),
		streams: new ConfigurableRecipeRegistry({
			merge: fakeStreamRunner,
			'stream-task': fakeStreamRunner
		}),
		tasks: new ConfigurableRecipeRegistry({
			copy: Sinon.spy(),
			'recipe-task': Sinon.spy()
		})
	};

	function fakeStreamRunner(gulp, config, stream, tasks) {
		tasks.forEach(function (task) {
			task.run(gulp, config, stream, done);
		});
	}

	function done() {
	}
};
<commit_msg>fake stuff: add fake flow-task; remove stream runner<commit_after>'use strict';

var Sinon = require('sinon');
var base = process.cwd();

var ConfigurableRecipeRegistry = require(base + '/lib/core/configurable_recipe_registry');

module.exports = function () {
	return {
		flows: new ConfigurableRecipeRegistry({
			parallel: Sinon.spy(),
			series: Sinon.spy(),
			'flow-task': Sinon.spy()
		}),
		streams: new ConfigurableRecipeRegistry({
			merge: Sinon.spy(),
			'stream-task': Sinon.spy()
		}),
		tasks: new ConfigurableRecipeRegistry({
			copy: Sinon.spy(),
			'task-task': Sinon.spy()
		})
	};
};
<|endoftext|>


<commit_before>// @flow
import * as Constants from '../../constants/searchv3'
import {last} from 'lodash'
import React, {Component} from 'react'
import {AutosizeInput, Box, Text, Icon, ClickableBox} from '../../common-adapters'
import {globalColors, globalMargins, globalStyles} from '../../styles'
import IconOrAvatar from '../icon-or-avatar'
import {followingStateToStyle} from '../shared'
import {getStyle as getTextStyle} from '../../common-adapters/text'

import type {IconType} from '../../common-adapters/icon'

export type UserDetails = {
  followingState: Constants.FollowingState,
  icon: ?IconType,
  service: Constants.Service,
  username: string,
}

export type UserItemProps = UserDetails & {onRemoveUser: (username: string) => void}

export type Props = {
  placeholder?: string,
  userItems: Array<UserDetails>,
  usernameText: string,
  showAddButton: boolean,
  onChangeText: (usernameText: string) => void,
  onRemoveUser: (username: string) => void,
  onClickAddButton: () => void,
}

class UserItem extends Component<void, UserItemProps, void> {
  _onRemoveUser = () => {
    this.props.onRemoveUser(this.props.username)
  }

  render() {
    const {followingState, icon, service, username} = this.props
    return (
      <Box style={_pillStyle}>
        <IconOrAvatar
          icon={icon}
          service={service}
          username={username}
          avatarSize={16}
          style={{
            fontSize: 16,
            // Add more space to the left of square icons
            marginLeft: service === 'Hacker News' || service === 'Facebook' ? 3 : 0,
          }}
        />
        <Text
          type="BodySemibold"
          style={{
            ...followingStateToStyle(followingState),
            lineHeight: '18px',
            marginLeft: globalMargins.xtiny,
          }}
        >
          {username}
        </Text>
        <Icon
          type="iconfont-close"
          onClick={this._onRemoveUser}
          style={{fontSize: 11, marginLeft: globalMargins.tiny}}
        />
      </Box>
    )
  }
}

class UserInput extends Component<void, Props, void> {
  _textInput: AutosizeInput

  _focusInput = () => {
    this._textInput.focus()
  }

  _onInputKeyDown = ev => {
    if (
      this.props.userItems.length &&
      ev.key === 'Backspace' &&
      ev.target.selectionStart === 0 &&
      ev.target.selectionEnd === 0
    ) {
      this.props.onRemoveUser(last(this.props.userItems).username)
    }
  }

  render() {
    const {
      placeholder,
      userItems,
      usernameText,
      onChangeText,
      showAddButton,
      onClickAddButton,
      onRemoveUser,
    } = this.props

    const inputLeftPadding = userItems.length ? {paddingLeft: globalMargins.xtiny} : null
    return (
      <Box style={{...globalStyles.flexBoxRow, alignItems: 'center', flexWrap: 'wrap'}}>
        {userItems.map(item => <UserItem {...item} onRemoveUser={onRemoveUser} key={item.username} />)}
        <AutosizeInput
          ref={el => {
            this._textInput = el
          }}
          flex={1}
          inputStyle={{..._inputStyle, ...inputLeftPadding}}
          placeholder={placeholder}
          value={usernameText}
          onChange={onChangeText}
          onKeyDown={this._onInputKeyDown}
        />
        {showAddButton &&
          <Icon
            onClick={onClickAddButton}
            type="iconfont-add"
            style={{
              fontSize: 12,
              color: globalColors.blue,
              marginLeft: globalMargins.xtiny,
              cursor: 'pointer',
            }}
          />}
        <ClickableBox style={{flex: 1, cursor: 'text', height: 24}} onClick={this._focusInput} />
      </Box>
    )
  }
}

const _pillStyle = {
  ...globalStyles.flexBoxRow,
  ...globalStyles.flexBoxCenter,
  height: 24,
  paddingLeft: globalMargins.xtiny,
  // 2 pixel fudge to accomodate built-in padding to iconfont-close
  paddingRight: globalMargins.tiny - 2,
  paddingTop: globalMargins.xtiny,
  paddingBottom: globalMargins.xtiny,
  marginRight: globalMargins.xtiny,
  margin: 2,
  borderRadius: 24,
  borderWidth: 1,
  borderStyle: 'solid',
  borderColor: globalColors.black_10,
}

const _inputStyle = {
  ...getTextStyle('Body'),
  flex: 1,
  color: globalColors.black_75,
  border: 'none',
  outline: 'none',
  lineHeight: '22px',
  padding: 0,
}

export default UserInput
<commit_msg>Remove unused lines<commit_after>// @flow
import * as Constants from '../../constants/searchv3'
import {last} from 'lodash'
import React, {Component} from 'react'
import {AutosizeInput, Box, Text, Icon, ClickableBox} from '../../common-adapters'
import {globalColors, globalMargins, globalStyles} from '../../styles'
import IconOrAvatar from '../icon-or-avatar'
import {followingStateToStyle} from '../shared'
import {getStyle as getTextStyle} from '../../common-adapters/text'

import type {IconType} from '../../common-adapters/icon'

export type UserDetails = {
  followingState: Constants.FollowingState,
  icon: ?IconType,
  service: Constants.Service,
  username: string,
}

export type UserItemProps = UserDetails & {onRemoveUser: (username: string) => void}

export type Props = {
  placeholder?: string,
  userItems: Array<UserDetails>,
  usernameText: string,
  showAddButton: boolean,
  onChangeText: (usernameText: string) => void,
  onRemoveUser: (username: string) => void,
  onClickAddButton: () => void,
}

class UserItem extends Component<void, UserItemProps, void> {
  _onRemoveUser = () => {
    this.props.onRemoveUser(this.props.username)
  }

  render() {
    const {followingState, icon, service, username} = this.props
    return (
      <Box style={_pillStyle}>
        <IconOrAvatar
          icon={icon}
          service={service}
          username={username}
          avatarSize={16}
          style={{
            // Add more space to the left of square icons
            marginLeft: service === 'Hacker News' || service === 'Facebook' ? 3 : 0,
          }}
        />
        <Text
          type="BodySemibold"
          style={{
            ...followingStateToStyle(followingState),
            lineHeight: '18px',
            marginLeft: globalMargins.xtiny,
          }}
        >
          {username}
        </Text>
        <Icon
          type="iconfont-close"
          onClick={this._onRemoveUser}
          style={{fontSize: 11, marginLeft: globalMargins.tiny}}
        />
      </Box>
    )
  }
}

class UserInput extends Component<void, Props, void> {
  _textInput: AutosizeInput

  _focusInput = () => {
    this._textInput.focus()
  }

  _onInputKeyDown = ev => {
    if (
      this.props.userItems.length &&
      ev.key === 'Backspace' &&
      ev.target.selectionStart === 0 &&
      ev.target.selectionEnd === 0
    ) {
      this.props.onRemoveUser(last(this.props.userItems).username)
    }
  }

  render() {
    const {
      placeholder,
      userItems,
      usernameText,
      onChangeText,
      showAddButton,
      onClickAddButton,
      onRemoveUser,
    } = this.props

    const inputLeftPadding = userItems.length ? {paddingLeft: globalMargins.xtiny} : null
    return (
      <Box style={{...globalStyles.flexBoxRow, alignItems: 'center', flexWrap: 'wrap'}}>
        {userItems.map(item => <UserItem {...item} onRemoveUser={onRemoveUser} key={item.username} />)}
        <AutosizeInput
          ref={el => {
            this._textInput = el
          }}
          inputStyle={{..._inputStyle, ...inputLeftPadding}}
          placeholder={placeholder}
          value={usernameText}
          onChange={onChangeText}
          onKeyDown={this._onInputKeyDown}
        />
        {showAddButton &&
          <Icon
            onClick={onClickAddButton}
            type="iconfont-add"
            style={{
              fontSize: 12,
              color: globalColors.blue,
              marginLeft: globalMargins.xtiny,
              cursor: 'pointer',
            }}
          />}
        <ClickableBox style={{flex: 1, cursor: 'text', height: 24}} onClick={this._focusInput} />
      </Box>
    )
  }
}

const _pillStyle = {
  ...globalStyles.flexBoxRow,
  ...globalStyles.flexBoxCenter,
  height: 24,
  paddingLeft: globalMargins.xtiny,
  // 2 pixel fudge to accomodate built-in padding to iconfont-close
  paddingRight: globalMargins.tiny - 2,
  paddingTop: globalMargins.xtiny,
  paddingBottom: globalMargins.xtiny,
  marginRight: globalMargins.xtiny,
  margin: 2,
  borderRadius: 24,
  borderWidth: 1,
  borderStyle: 'solid',
  borderColor: globalColors.black_10,
}

const _inputStyle = {
  ...getTextStyle('Body'),
  flex: 1,
  color: globalColors.black_75,
  border: 'none',
  outline: 'none',
  lineHeight: '22px',
  padding: 0,
}

export default UserInput
<|endoftext|>


<commit_before>var assert      = require('assert');
var should      = require('should');
var fs          = require('fs');

describe('nodemailer-sendgrid-transport repo', function() {
  it('should have ./Docker or docker/Docker file', function() {
    assert(fileExists('Docker') || fileExists('docker/Docker'));
  });

  it('should have ./docker-compose.yml or ./docker/docker-compose.yml file', function() {
    assert(fileExists('docker-compose.yml') || fileExists('docker/docker-compose.yml'));
  });

  it('should have ./.env_sample file', function() {
    assert(fileExists('.env_sample'));
  });

  it('should have ./.gitignore file', function() {
    assert(fileExists('.gitignore'));
  });

  it('should have ./.travis.yml file', function() {
    assert(fileExists('.travis.yml'));
  });

  it('should have ./.codeclimate.yml file', function() {
    assert(fileExists('.codeclimate.yml'));
  });

  it('should have ./CHANGELOG.md file', function() {
    assert(fileExists('CHANGELOG.md'));
  });

  it('should have ./CODE_OF_CONDUCT.md file', function() {
    assert(fileExists('CODE_OF_CONDUCT.md'));
  });

  it('should have ./CONTRIBUTING.md file', function() {
    assert(fileExists('CONTRIBUTING.md'));
  });

  it('should have ./.github/ISSUE_TEMPLATE file', function() {
    assert(fileExists('.github/ISSUE_TEMPLATE'));
  });

  it('should have ./LICENSE.md file', function() {
    assert(fileExists('LICENSE.md'));
  });

  it('should have ./.github/PULL_REQUEST_TEMPLATE file', function() {
    assert(fileExists('.github/PULL_REQUEST_TEMPLATE'));
  });

  it('should have ./README.md file', function() {
    assert(fileExists('README.md'));
  });

  it('should have ./TROUBLESHOOTING.md file', function() {
    assert(fileExists('TROUBLESHOOTING.md'));
  });

  it('should have ./USAGE.md file', function() {
    assert(fileExists('USAGE.md'));
  });

  it('should have ./USE_CASES.md file', function() {
    assert(fileExists('USE_CASES.md'));
  });

  function fileExists(filepath) {
    try {
      return fs.statSync(filepath).isFile();
    } catch(e) {
      if (e.code === 'ENOENT') {
        console.log('' + filepath + ' doesn\'t exist.');
        return false;
      }
      throw e;
    }
  }
});
<commit_msg>Update test to reflect current conditions<commit_after>var assert      = require('assert');
var should      = require('should');
var fs          = require('fs');

describe('sendgrid-nodejs repo', function() {
  /*
  it('should have ./Docker or docker/Docker file', function() {
    assert(fileExists('Docker') || fileExists('docker/Docker'));
  });

  it('should have ./docker-compose.yml or ./docker/docker-compose.yml file', function() {
    assert(fileExists('docker-compose.yml') || fileExists('docker/docker-compose.yml'));
  });
  */

  it('should have ./.env_sample file', function() {
    assert(fileExists('.env_sample'));
  });

  it('should have ./.gitignore file', function() {
    assert(fileExists('.gitignore'));
  });

  it('should have ./.travis.yml file', function() {
    assert(fileExists('.travis.yml'));
  });

  it('should have ./.codeclimate.yml file', function() {
    assert(fileExists('.codeclimate.yml'));
  });

  it('should have ./CHANGELOG.md file', function() {
    assert(fileExists('CHANGELOG.md'));
  });

  it('should have ./CODE_OF_CONDUCT.md file', function() {
    assert(fileExists('CODE_OF_CONDUCT.md'));
  });

  it('should have ./CONTRIBUTING.md file', function() {
    assert(fileExists('CONTRIBUTING.md'));
  });

  it('should have ./.github/ISSUE_TEMPLATE file', function() {
    assert(fileExists('.github/ISSUE_TEMPLATE'));
  });

  it('should have ./LICENSE.md file', function() {
    assert(fileExists('LICENSE.md'));
  });

  it('should have ./.github/PULL_REQUEST_TEMPLATE file', function() {
    assert(fileExists('.github/PULL_REQUEST_TEMPLATE'));
  });

  it('should have ./README.md file', function() {
    assert(fileExists('README.md'));
  });

  it('should have ./TROUBLESHOOTING.md file', function() {
    assert(fileExists('TROUBLESHOOTING.md'));
  });

  it('should have ./USAGE.md file', function() {
    assert(fileExists('USAGE.md'));
  });

  /*
  it('should have ./USE_CASES.md file', function() {
    assert(fileExists('USE_CASES.md'));
  });
  */

  function fileExists(filepath) {
    try {
      return fs.statSync(filepath).isFile();
    } catch(e) {
      if (e.code === 'ENOENT') {
        console.log('' + filepath + ' doesn\'t exist.');
        return false;
      }
      throw e;
    }
  }
});
<|endoftext|>


<commit_before>/**
 * # Alias
 * Copyright(c) 2015 Stefano Balietti
 * MIT Licensed
 *
 * `nodeGame` aliasing module
 */
(function(exports, node) {

    "use strict";

    // ## Global scope

    var J = node.JSUS;

    var NGC = node.NodeGameClient;

    /**
     * ### node.alias
     *
     * Creates event listeners aliases
     *
     * This method creates a new property to the `node.on` object named
     * after the alias. The alias can be used as a shortcut to register
     * to new listeners on the given events.
     *
     *
     * ```javascript
     *   // The node.on.data alias example with modifier function
     *   // only DATA msg with the right label will be fired.
     *   this.alias('data', ['in.say.DATA', 'in.set.DATA'], function(text, cb) {
     *       return function(msg) {
     *           if (msg.text === text) cb.call(that.game, msg);
     *           else return false;
     *       };
     *   });
     *
     *  node.on.data('myLabel', function(){ ... };
     *  node.once.data('myLabel', function(){ ... };
     * ```
     *
     * @param {string} alias The name of alias
     * @param {string|array} events The event/s under which the listeners
     *   will be registered
     * @param {function} modifier Optional. A function that makes a closure
     *   around its own input parameters, and returns a function that will
     *   actually be invoked when the aliased event is fired. It should return
     *   FALSE if it does not executes the user callback.
     */
    NGC.prototype.alias = function(alias, events, modifier) {
        var that;
        if ('string' !== typeof alias) {
            throw new TypeError('node.alias: alias must be string. Found: ' +
                                alias);
        }
        if ('string' === typeof events) {
            events = [events];
        }
        if (!J.isArray(events)) {
            throw new TypeError('node.alias: events must be array or string. ' +
                                'Found: ' + events);
        }
        if (modifier && 'function' !== typeof modifier) {
            throw new TypeError(
                'node.alias: modifier must be function or undefined. Found: ' +
                    modifier);
        }

        that = this;

        this.on[alias] = function(func) {
            var i, len, args;

            // If set, we use the callback returned by the modifier.
            // Otherwise, we assume the first parameter is the callback.
            if (modifier) {
                args = [];
                i = -1, len = arguments.length;
                for ( ; ++i < len ; ) {
                    args[i] = arguments[i];
                }
                func = modifier.apply(that.game, args);
            }

            J.each(events, function(event) {
                that.on(event, function() {
                    func.apply(that.game, arguments);
                });
            });

        };
        this.once[alias] = function(func) {
            var i, len, args;

            // If set, we use the callback returned by the modifier.
            // Otherwise, we assume the first parameter is the callback.
            if (modifier) {
                args = [];
                i = -1, len = arguments.length;
                for ( ; ++i < len ; ) {
                    args[i] = arguments[i];
                }
                func = modifier.apply(that.game, args);
            }

            J.each(events, function(event) {
                // We redo the once method manually because otherwise
                // the first call to once will remove all once listeners
                // defined with this alias. Normal one calls the listener
                // that wraps the modifier which may or may not execute the
                // user-defined function. We introduce that if the modifier
                // return false, it means the user-defined function was not
                // executed and therefore it should not be removed.
                function g() {
                    var i, len, args, toRemove;
                    args = [];
                    i = -1, len = arguments.length;
                    for ( ; ++i < len ; ) {
                        args[i] = arguments[i];
                    }
                    toRemove = func.apply(that.game, args);
                    // If a modifier returns false it has not executed the
                    // user-defined listener, so we should not remove it.
                    if (!modifier || toRemove !== false) that.off(event, g);
                }
                that.on(event, g);
            });
        };

        // attachAlias(this, 'on', events, modifier, alias);
        // attachAlias(this, 'once', events, modifier, alias);

        // this.on[alias] = function(func) {
        //     var i, len, args;
        //     args = [];
        //     i = -1, len = arguments.length;
        //     for ( ; ++i < len ; ) {
        //         args[i] = arguments[i];
        //     }
        //     // If set, we use the callback returned by the modifier.
        //     // Otherwise, we assume the first parameter is the callback.
        //     if (modifier) func = modifier.apply(that.game, args);
        //
        //     // Optimized.
        //     if (eventsLen < 3) {
        //         that.on(event[0], function() {
        //             func.apply(that.game, args);
        //         });
        //         if (eventsLen === 2) {
        //             that.on(event[1], function() {
        //                 func.apply(that.game, args);
        //             });
        //         }
        //     }
        //     else {
        //         for ( ; ++i < len ; ) {
        //             that.on(event[i], function() {
        //                 func.apply(that.game, args);
        //             });
        //         }
        //     }
        // };

        // TODO: remove code duplication?
        // this.once[alias] = function(func) {
        //     var i, len, args;
        //     args = [];
        //     i = -1, len = arguments.length;
        //     for ( ; ++i < len ; ) {
        //         args[i] = arguments[i];
        //     }
        //     // If set, we use the callback returned by the modifier.
        //     // Otherwise, we assume the first parameter is the callback.
        //     if (modifier) func = modifier.apply(that.game, args);
        //
        //     // Optimized.
        //     if (eventsLen < 3) {
        //         that.once(event[0], function() {
        //             func.apply(that.game, args);
        //         });
        //         if (eventsLen === 2) {
        //             that.once(event[1], function() {
        //                 func.apply(that.game, args);
        //             });
        //         }
        //     }
        //     else {
        //         for ( ; ++i < len ; ) {
        //             that.once(event[i], function() {
        //                 func.apply(that.game, args);
        //             });
        //         }
        //     }
        // };

    };

    // function attachAlias(that, method, events, modifier, alias) {
    //     var eventsLen = events.length;
    //     that[method][alias] = function(func) {
    //         var i, len, args;
    //         // Cloning arguments array.
    //         i = -1;
    //         len = arguments.length;
    //         args = new Array(len);
    //         for ( ; ++i < len ; ) {
    //             args[i] = arguments[i];
    //         }
    //         // If set, we use the callback returned by the modifier.
    //         // Otherwise, we assume the first parameter is the callback.
    //         if (modifier) func = modifier.apply(that.game, args);
    //
    //         // Optimized.
    //         if (eventsLen < 3) {
    //             that[method](events[0], function() {
    //                 func.apply(that.game, arguments);
    //             });
    //             if (eventsLen === 2) {
    //                 that[method](events[1], function() {
    //                     func.apply(that.game, arguments);
    //                 });
    //             }
    //         }
    //         else {
    //             for ( ; ++i < len ; ) {
    //                 that[method](events[i], function() {
    //                     func.apply(that.game, arguments);
    //                 });
    //             }
    //         }
    //     };
    // }

    // function attachAlias(that, method, events, modifier, alias) {
    //     var eventsLen = events.length;
    //     that[method][alias] = function(func) {
    //         var i;
    //         // Cloning arguments array.
    //         // i = -1;
    //         // len = arguments.length;
    //         // args = new Array(len);
    //         // for ( ; ++i < len ; ) {
    //         //     args[i] = arguments[i];
    //         // }
    //         // If set, we use the callback returned by the modifier.
    //         // Otherwise, we assume the first parameter is the callback.
    //         // if (modifier) func = modifier.apply(that.game, args);
    //
    //         // Optimized.
    //
    //         that[method](events[0], function() {
    //             if (modifier) {
    //                 func = modifier.apply(that.game, arguments);
    //                 if (!func) return;
    //             }
    //             func.apply(that.game, arguments);
    //         });
    //         if (eventsLen === 2) {
    //             that[method](events[1], function() {
    //                 if (modifier) {
    //                     func = modifier.apply(that.game, arguments);
    //                     if (!func) return;
    //                 }
    //                 func.apply(that.game, arguments);
    //             });
    //         }
    //         else {
    //             i = 0;
    //             for ( ; ++i < eventsLen ; ) {
    //                 that[method](events[i], function() {
    //                     if (modifier) {
    //                         func = modifier.apply(that.game, arguments);
    //                         if (!func) return;
    //                     }
    //                     func.apply(that.game, arguments);
    //                 });
    //             }
    //         }
    //     };
    // }
})(
    'undefined' != typeof node ? node : module.exports,
    'undefined' != typeof node ? node : module.parent.exports
);
<commit_msg>minor<commit_after>/**
 * # Alias
 * Copyright(c) 2015 Stefano Balietti
 * MIT Licensed
 *
 * `nodeGame` aliasing module
 */
(function(exports, node) {

    "use strict";

    // ## Global scope

    var J = node.JSUS;

    var NGC = node.NodeGameClient;

    /**
     * ### node.alias
     *
     * Creates event listeners aliases
     *
     * This method creates a new property to the `node.on` object named
     * after the alias. The alias can be used as a shortcut to register
     * to new listeners on the given events.
     *
     * Note: aliases cannot return values to the emit call.
     * TODO: node.on aliases could do it without problem, node.once aliases
     * have the problem that the return value is currently used to detect
     * whether the modifier function actually executed the user callback.
     *
     * ```javascript
     *   // The node.on.data alias example with modifier function
     *   // only DATA msg with the right label will be fired.
     *   this.alias('data', ['in.say.DATA', 'in.set.DATA'], function(text, cb) {
     *       return function(msg) {
     *           if (msg.text === text) cb.call(that.game, msg);
     *           else return false;
     *       };
     *   });
     *
     *  node.on.data('myLabel', function() { ... };
     *  node.once.data('myLabel', function() { ... };
     * ```
     *
     * @param {string} alias The name of alias
     * @param {string|array} events The event/s under which the listeners
     *   will be registered
     * @param {function} modifier Optional. A function that makes a closure
     *   around its own input parameters, and returns a function that will
     *   actually be invoked when the aliased event is fired. It should return
     *   FALSE if it does not executes the user callback.
     */
    NGC.prototype.alias = function(alias, events, modifier) {
        var that;
        if ('string' !== typeof alias) {
            throw new TypeError('node.alias: alias must be string. Found: ' +
                                alias);
        }
        if ('string' === typeof events) {
            events = [events];
        }
        if (!J.isArray(events)) {
            throw new TypeError('node.alias: events must be array or string. ' +
                                'Found: ' + events);
        }
        if (modifier && 'function' !== typeof modifier) {
            throw new TypeError(
                'node.alias: modifier must be function or undefined. Found: ' +
                    modifier);
        }

        that = this;

        this.on[alias] = function(func) {
            var i, len, args;

            // If set, we use the callback returned by the modifier.
            // Otherwise, we assume the first parameter is the callback.
            if (modifier) {
                args = [];
                i = -1, len = arguments.length;
                for ( ; ++i < len ; ) {
                    args[i] = arguments[i];
                }
                func = modifier.apply(that.game, args);
            }

            J.each(events, function(event) {
                that.on(event, function() {
                    func.apply(that.game, arguments);
                });
            });

        };
        this.once[alias] = function(func) {
            var i, len, args;

            // If set, we use the callback returned by the modifier.
            // Otherwise, we assume the first parameter is the callback.
            if (modifier) {
                args = [];
                i = -1, len = arguments.length;
                for ( ; ++i < len ; ) {
                    args[i] = arguments[i];
                }
                func = modifier.apply(that.game, args);
            }

            J.each(events, function(event) {
                // We redo the once method manually because otherwise
                // the first call to once will remove all once listeners
                // defined with this alias. Normal one calls the listener
                // that wraps the modifier which may or may not execute the
                // user-defined function. We introduce that if the modifier
                // return false, it means the user-defined function was not
                // executed and therefore it should not be removed.
                function g() {
                    var i, len, args, toRemove;
                    args = [];
                    i = -1, len = arguments.length;
                    for ( ; ++i < len ; ) {
                        args[i] = arguments[i];
                    }
                    toRemove = func.apply(that.game, args);
                    // If a modifier returns false it has not executed the
                    // user-defined listener, so we should not remove it.
                    if (!modifier || toRemove !== false) that.off(event, g);
                }
                that.on(event, g);
            });
        };

        // attachAlias(this, 'on', events, modifier, alias);
        // attachAlias(this, 'once', events, modifier, alias);

        // this.on[alias] = function(func) {
        //     var i, len, args;
        //     args = [];
        //     i = -1, len = arguments.length;
        //     for ( ; ++i < len ; ) {
        //         args[i] = arguments[i];
        //     }
        //     // If set, we use the callback returned by the modifier.
        //     // Otherwise, we assume the first parameter is the callback.
        //     if (modifier) func = modifier.apply(that.game, args);
        //
        //     // Optimized.
        //     if (eventsLen < 3) {
        //         that.on(event[0], function() {
        //             func.apply(that.game, args);
        //         });
        //         if (eventsLen === 2) {
        //             that.on(event[1], function() {
        //                 func.apply(that.game, args);
        //             });
        //         }
        //     }
        //     else {
        //         for ( ; ++i < len ; ) {
        //             that.on(event[i], function() {
        //                 func.apply(that.game, args);
        //             });
        //         }
        //     }
        // };

        // TODO: remove code duplication?
        // this.once[alias] = function(func) {
        //     var i, len, args;
        //     args = [];
        //     i = -1, len = arguments.length;
        //     for ( ; ++i < len ; ) {
        //         args[i] = arguments[i];
        //     }
        //     // If set, we use the callback returned by the modifier.
        //     // Otherwise, we assume the first parameter is the callback.
        //     if (modifier) func = modifier.apply(that.game, args);
        //
        //     // Optimized.
        //     if (eventsLen < 3) {
        //         that.once(event[0], function() {
        //             func.apply(that.game, args);
        //         });
        //         if (eventsLen === 2) {
        //             that.once(event[1], function() {
        //                 func.apply(that.game, args);
        //             });
        //         }
        //     }
        //     else {
        //         for ( ; ++i < len ; ) {
        //             that.once(event[i], function() {
        //                 func.apply(that.game, args);
        //             });
        //         }
        //     }
        // };

    };

    // function attachAlias(that, method, events, modifier, alias) {
    //     var eventsLen = events.length;
    //     that[method][alias] = function(func) {
    //         var i, len, args;
    //         // Cloning arguments array.
    //         i = -1;
    //         len = arguments.length;
    //         args = new Array(len);
    //         for ( ; ++i < len ; ) {
    //             args[i] = arguments[i];
    //         }
    //         // If set, we use the callback returned by the modifier.
    //         // Otherwise, we assume the first parameter is the callback.
    //         if (modifier) func = modifier.apply(that.game, args);
    //
    //         // Optimized.
    //         if (eventsLen < 3) {
    //             that[method](events[0], function() {
    //                 func.apply(that.game, arguments);
    //             });
    //             if (eventsLen === 2) {
    //                 that[method](events[1], function() {
    //                     func.apply(that.game, arguments);
    //                 });
    //             }
    //         }
    //         else {
    //             for ( ; ++i < len ; ) {
    //                 that[method](events[i], function() {
    //                     func.apply(that.game, arguments);
    //                 });
    //             }
    //         }
    //     };
    // }

    // function attachAlias(that, method, events, modifier, alias) {
    //     var eventsLen = events.length;
    //     that[method][alias] = function(func) {
    //         var i;
    //         // Cloning arguments array.
    //         // i = -1;
    //         // len = arguments.length;
    //         // args = new Array(len);
    //         // for ( ; ++i < len ; ) {
    //         //     args[i] = arguments[i];
    //         // }
    //         // If set, we use the callback returned by the modifier.
    //         // Otherwise, we assume the first parameter is the callback.
    //         // if (modifier) func = modifier.apply(that.game, args);
    //
    //         // Optimized.
    //
    //         that[method](events[0], function() {
    //             if (modifier) {
    //                 func = modifier.apply(that.game, arguments);
    //                 if (!func) return;
    //             }
    //             func.apply(that.game, arguments);
    //         });
    //         if (eventsLen === 2) {
    //             that[method](events[1], function() {
    //                 if (modifier) {
    //                     func = modifier.apply(that.game, arguments);
    //                     if (!func) return;
    //                 }
    //                 func.apply(that.game, arguments);
    //             });
    //         }
    //         else {
    //             i = 0;
    //             for ( ; ++i < eventsLen ; ) {
    //                 that[method](events[i], function() {
    //                     if (modifier) {
    //                         func = modifier.apply(that.game, arguments);
    //                         if (!func) return;
    //                     }
    //                     func.apply(that.game, arguments);
    //                 });
    //             }
    //         }
    //     };
    // }
})(
    'undefined' != typeof node ? node : module.exports,
    'undefined' != typeof node ? node : module.parent.exports
);
<|endoftext|>


<commit_before>'use strict';

angular.module('ui.dashboard', ['ui.bootstrap', 'ui.sortable']);

angular.module('ui.dashboard')
  .directive('dashboard', function () {
    return {
      restrict: 'A',
      templateUrl: 'template/dashboard.html',
      scope: true,
      controller: function ($scope) {
        $scope.sortableOptions = {
          stop: function () {
            //TODO store active widgets in local storage on add/remove/reorder
            //var titles = _.map($scope.widgets, function (widget) {
            //  return widget.title;
            //});
            //console.log(titles);
          }
        };
      },
      link: function (scope, element, attrs) {
        scope.options = scope.$eval(attrs.dashboard);

        var count = 1;

        scope.addWidget = function (widgetDef) {
          var widget = {
            title: 'Widget ' + count++,
            name: widgetDef.name,
            attrs: widgetDef.attrs,
            style: widgetDef.style
          };

          if (widgetDef.template) {
            widget.template = widgetDef.template;
          } else {
            var directive = widgetDef.directive ? widgetDef.directive : widgetDef.name;
            widget.directive = directive;
          }

          scope.widgets.push(widget);
        };

        scope.removeWidget = function (widget) {
          scope.widgets.splice(_.indexOf(scope.widgets, widget), 1);
        };

        scope.clear = function () {
          scope.widgets = [];
        };

        scope.widgets = [];
        _.each(scope.options.defaultWidgets, function (widgetDef) {
          scope.addWidget(widgetDef);
        });

        scope.addWidgetInternal = function (event, widgetDef) {
          event.preventDefault();
          scope.addWidget(widgetDef);
        };

        // allow adding widgets externally
        scope.options.addWidget = scope.addWidget;
      }
    };
  })
  .directive('widget', ['$compile', function ($compile) {
    function findWidgetPlaceholder(element) {
      // widget placeholder is the first (and only) child of .widget-content
      return angular.element(element.find('.widget-content').children()[0]);
    }

    return {
      link: function (scope, element) {
        var elm = findWidgetPlaceholder(element);
        var widget = scope.widget;

        if (widget.template) {
          elm.replaceWith(widget.template);
          elm = findWidgetPlaceholder(element);
        } else {
          elm.attr(widget.directive, '');

          if (widget.attrs) {
            _.each(widget.attrs, function (value, attr) {
              elm.attr(attr, value);
            });
          }
        }

        $compile(elm)(scope);
      }
    };
  }]);<commit_msg>made sortable handle the widget header region only<commit_after>'use strict';

angular.module('ui.dashboard', ['ui.bootstrap', 'ui.sortable']);

angular.module('ui.dashboard')
  .directive('dashboard', function () {
    return {
      restrict: 'A',
      templateUrl: 'template/dashboard.html',
      scope: true,
      controller: function ($scope) {
        $scope.sortableOptions = {
          stop: function () {
            //TODO store active widgets in local storage on add/remove/reorder
            //var titles = _.map($scope.widgets, function (widget) {
            //  return widget.title;
            //});
            //console.log(titles);
          },
          handle: '.widget-header'
        };
      },
      link: function (scope, element, attrs) {
        scope.options = scope.$eval(attrs.dashboard);

        var count = 1;

        scope.addWidget = function (widgetDef) {
          var widget = {
            title: 'Widget ' + count++,
            name: widgetDef.name,
            attrs: widgetDef.attrs,
            style: widgetDef.style
          };

          if (widgetDef.template) {
            widget.template = widgetDef.template;
          } else {
            var directive = widgetDef.directive ? widgetDef.directive : widgetDef.name;
            widget.directive = directive;
          }

          scope.widgets.push(widget);
        };

        scope.removeWidget = function (widget) {
          scope.widgets.splice(_.indexOf(scope.widgets, widget), 1);
        };

        scope.clear = function () {
          scope.widgets = [];
        };

        scope.widgets = [];
        _.each(scope.options.defaultWidgets, function (widgetDef) {
          scope.addWidget(widgetDef);
        });

        scope.addWidgetInternal = function (event, widgetDef) {
          event.preventDefault();
          scope.addWidget(widgetDef);
        };

        // allow adding widgets externally
        scope.options.addWidget = scope.addWidget;
      }
    };
  })
  .directive('widget', ['$compile', function ($compile) {
    function findWidgetPlaceholder(element) {
      // widget placeholder is the first (and only) child of .widget-content
      return angular.element(element.find('.widget-content').children()[0]);
    }

    return {
      link: function (scope, element) {
        var elm = findWidgetPlaceholder(element);
        var widget = scope.widget;

        if (widget.template) {
          elm.replaceWith(widget.template);
          elm = findWidgetPlaceholder(element);
        } else {
          elm.attr(widget.directive, '');

          if (widget.attrs) {
            _.each(widget.attrs, function (value, attr) {
              elm.attr(attr, value);
            });
          }
        }

        $compile(elm)(scope);
      }
    };
  }]);<|endoftext|>


<commit_before>/* global d3 */
var hsl = require('hsl-to-rgb-for-reals')

function flameGraph () {
  var w = 960 // graph width
  var h = 1024 // graph height
  var c = 18 // cell height
  var selection = null // selection
  var transitionDuration = 500
  var transitionEase = 'cubic-in-out' // tooltip offset
  var sort = true
  var langs = false
  var tiers = false
  var filterNeeded = true
  var filterTypes = []
  var allSamples
  var labelRx = /^LazyCompile:|Function:|Script:/
  var optRx = /^\w+:(\s+)?\*/
  var notOptRx = /^\w+:(\s+)?~/

  function label (d) {
    if (d.dummy) return ''
    var optInfo = d.optimized && '—opt\'d—' ||
      d.notOptimized && '—not opt\'d—' || ''

    var onStack = d.name ? d3.round(100 * (d.value / allSamples), 1) + '% on stack' : ''
    var top = stackTop(d)
    var topOfStack = d.name ? (top
      ? d3.round(100 * (top / allSamples), 2) + '% stack top'
      : '') : ''

    if (onStack && topOfStack) { onStack += ', ' }

    var name = d.name.replace(labelRx, '') +
      '' + ' ' + optInfo + ' ' + onStack + ' ' + topOfStack + ''

    return name
  }

  function stackTop (d) {
    if (!d.children) return d.top
    var top = d.top

    d.children
      .forEach(function (child) {
        if (
            !child.children ||
            child.children.filter(function (c) { return c.hide }).length
        ) {
          if (child.hide) {
            top += stackTop(child)
          }
        }
      })

    return top
  }

  function titleLabel (d) {
    var top = stackTop(d)
    return d.name + '\n' + (top
      ? 'Top of Stack:' + d3.round(100 * (top / allSamples), 1) + '% ' +
      '(' + top + ' of ' + allSamples + ' samples)\n'
      : '') +
    'On Stack:' + d3.round(100 * (d.value / allSamples), 1) + '% ' +
    '(' + d.value + ' of ' + allSamples + ' samples)'
  }

  function langtier (name) {
    // todo: C deps
    if (!/.js/.test(name)) {
      switch (true) {
        case /^Builtin:|^Stub:|v8::|^(.+)IC:|^Handler:/
          .test(name): return {type: 'v8', lang: 'c'}
        case /^RegExp:/
          .test(name): return {type: 'regexp', lang: 'c'}
        case /apply$|call$|Arguments$/
          .test(name): return {type: 'nativeJS', lang: 'js'}
        case /\.$/.test(name): return {type: 'core', lang: 'js'}
        default: return {type: 'nativeC', lang: 'c'}
      }
      return
    }

    switch (true) {
      case / native /.test(name): return {type: 'nativeJS', lang: 'js'}
      case (name.indexOf('/') === -1 || /internal\//.test(name) && !/ \//.test(name)): return {type: 'core', lang: 'js'}
      case !/node_modules/.test(name): return {type: 'app', lang: 'js'}
      default: return {type: 'deps', lang: 'js'}
    }
  }

  var colors = {
    v8: {h: 67, s: 81, l: 65},
    regexp: {h: 310, s: 86, l: 18},
    nativeC: {h: 0, s: 50, l: 50},
    nativeJS: {h: 122, s: 50, l: 45},
    core: {h: 23, s: 66, l: 45},
    deps: {h: 244, s: 50, l: 65},
    app: {h: 200, s: 50, l: 45}
  }
  colors.def = colors.core
  colors.js = colors.core
  colors.c = colors.deps

  var diffScale = d3.scale.linear().range([0, 0.2])

  function colorHash (d, perc) {
    if (!d.name) {
      return perc ? 'rgb(127, 127, 127)' : 'rgba(0, 0, 0, 0)'
    }

    perc = perc || 1
    var type = d.type || 'def'
    var lang = d.lang || 'js'

    var key

    if (!langs && !tiers) key = colors.def

    if (langs) key = colors[lang]
    if (tiers) key = colors[type]

    var h = key.h
    var s = key.s
    var l = key.l
    var top = stackTop(d)
    var vector = ((top / allSamples) * 100) + 1
    s *= vector
    l += (vector * 2)

    s /= 100
    l /= 100

    s *= perc
    l *= perc

    var a = 0.8
    if (l > .8) {
      a += diffScale(l - 0.8)
      l = .8
    }

    var rgb = hsl(h, s, l)

    return 'rgba(' + rgb + ', ' + a + ')'
  }

  function filter (data) {
    if (!filterNeeded) return
    if (data.children && (data.children.length > 0)) {
      data.children.forEach(filter)
      data.children.forEach(function (child) {
        if (~filterTypes.indexOf(child.type) || ~filterTypes.indexOf(child.lang)) {
          child.hide = true
        } else {
          child.hide = false
        }
      })
    }
  }

  function augment (data) {
    // Augment partitioning layout with "dummy" nodes so that internal nodes'
    // values dictate their width. Annoying, but seems to be least painful
    // option.  https://github.com/mbostock/d3/pull/574
    if (data.children && (data.children.length > 0)) {
      data.children.forEach(augment)
      var childValues = 0
      data.children.forEach(function (child) {
        var lt = langtier(child.name)
        child.type = lt.type
        child.lang = lt.lang

        if (optRx.test(child.name)) {
          child.optimized = true
        }
        if (notOptRx.test(child.name)) {
          child.notOptimized = true
        }

        childValues += child.value
      })
      if (childValues < data.value) {
        data.children.push(
          {
            name: '',
            value: data.value - childValues,
            top: 0,
            dummy: true
          }
        )
      }
    }
  }

  function hide (d) {
    if (!d.original) {
      d.original = d.value
    }
    d.value = 0
    if (d.children) {
      d.children.forEach(hide)
    }
  }

  function show (d) {
    d.fade = false
    if (d.original) {
      d.value = d.original
    }
    if (d.children) {
      d.children.forEach(show)
    }
  }

  function getSiblings (d) {
    var siblings = []
    if (d.parent) {
      var me = d.parent.children.indexOf(d)
      siblings = d.parent.children.slice(0)
      siblings.splice(me, 1)
    }
    return siblings
  }

  function hideSiblings (d) {
    var siblings = getSiblings(d)
    siblings.forEach(function (s) {
      hide(s)
    })
    if (d.parent) {
      hideSiblings(d.parent)
    }
  }

  function fadeAncestors (d) {
    if (d.parent) {
      d.parent.fade = true
      fadeAncestors(d.parent)
    }
  }

  function zoom (d) {
    hideSiblings(d)
    show(d)
    fadeAncestors(d)
    update()
  }

  function searchTree (d, term, color) {
    var re = new RegExp(term)
    var label = d.name

    if (d.children) {
      d.children.forEach(function (child) {
        searchTree(child, term, color)
      })
    }
    if (d.hide) { return }
    if (label.match(re)) {
      d.highlight = color || true
    } else {
      if (typeof d.highlight === 'boolean') {
        d.highlight = false
      }
    }
  }

  function clear (d, color) {
    if (color && d.highlight === color) {
      d.highlight = false
    }
    if (!color) { d.highlight = false }
    if (d.children) {
      d.children.forEach(function (child) {
        clear(child, color)
      })
    }
  }

  function doSort (a, b) {
    if (typeof sort === 'function') {
      return sort(a, b)
    } else if (sort) {
      return d3.ascending(a.name, b.name)
    } else {
      return 0
    }
  }

  var partition = d3.layout.partition()
    .sort(doSort)
    .value(function (d) { return d.v || d.value })
    .children(function (d) { return d.c || d.children })

  function translate (d) {
    var x = d3.scale.linear().range([0, w])
    var parent = d.parent
    var depthOffset = parent && parent.hide ? 1 : 0
    while (parent && (parent = parent.parent)) {
      if (parent.hide) depthOffset += 1
    }
    var depth = d.depth - depthOffset
    return 'translate(' + x(d.x) + ',' + (h - (depth * c) - c) + ')'
  }

  function update () {
    selection
      .each(function (data) {
        filter(data)

        var nodes = partition(data)
        var kx = w / data.dx
        var svg = d3.select(this).select('svg')
        var g = svg.selectAll('g').data(nodes)

        svg.on('click', function (d) {
          if (d3.event.path[0] === this) {
            zoom(d)
          }
        })

        g.transition()
          .duration(transitionDuration)
          .ease(transitionEase)
          .attr('transform', translate)

        g.select('rect').transition()
          .duration(transitionDuration)
          .ease(transitionEase)
          .attr('width', function (d) { return d.dx * kx })

        var node = g.enter()
          .append('svg:g')
          .attr('transform', translate)

        node
          .append('svg:rect')
          .attr('width', function (d) { return d.dx * kx })

        node.append('svg:title')

        node.append('foreignObject')
          .append('xhtml:div')

        node.attr('width', function (d) { return d.dx * kx })
          .attr('height', function (d) { return c })
          .attr('name', function (d) { return d.name })
          .attr('class', function (d) { return d.fade ? 'frame fade' : 'frame' })

        g.select('rect')
          .attr('height', function (d) { return d.hide ? 0 : c })
          .style('cursor', 'pointer')
          .style('stroke', function (d) {
            return colorHash(d, 1.1)
          })
          .attr('fill', function (d) {
            var highlightColor = '#E600E6'

            if (typeof d.highlight === 'string') {
              highlightColor = d.highlight
            }
            return d.highlight ? highlightColor : colorHash(d)
          })
          .style('visibility', function (d) { return d.dummy ? 'hidden' : 'visible' })

        g.select('title')
          .text(titleLabel)

        g.select('foreignObject')
          .transition()
          .duration(transitionDuration)
          .ease(transitionEase)
          .attr('width', function (d) { return d.dx * kx })

        g.select('foreignObject')
          .style('overflow', 'hidden')
          .attr('height', function (d) { return d.hide ? 0 : c })
          .select('div')
          .style('display', function (d) { return (d.dx * kx < 35) || d.dummy ? 'none' : 'block' })
          .style('pointer-events', 'none')
          .style('white-space', 'nowrap')
          .style('text-overflow', 'ellipsis')
          .style('overflow', 'hidden')
          .style('font-size', '12px')
          .style('font-family', 'Verdana')
          .style('margin-left', '4px')
          .style('margin-right', '4px')
          .style('line-height', '1.5')
          .style('padding', '0')
          .style('font-weight', '400')
          .style('color', '#000')
          .style('text-align', 'left')
          .html(label)

        g.on('click', zoom)

        var hidden = g.filter(function (d) { return d.hide })
        hidden.forEach(function (d) {
          hide(d)
        })

        g.exit().remove()
      })
  }

  function chart (s) {
    selection = s

    if (!arguments.length) return chart

    selection.each(function (data) {
      allSamples = data.value

      d3.select(this)
        .append('svg:svg')
        .attr('width', w)
        .attr('height', h)
        .attr('class', 'partition d3-flame-graph')

      augment(data)
      filter(data)
      // "creative" fix for node ordering when partition is called for the first time
      partition(data)

      // first draw
      update()
    })
  }

  chart.height = function (_) {
    if (!arguments.length) { return h }
    h = _
    return chart
  }

  chart.width = function (_) {
    if (!arguments.length) { return w }
    w = _
    return chart
  }

  chart.cellHeight = function (_) {
    if (!arguments.length) { return c }
    c = _
    return chart
  }

  chart.transitionDuration = function (_) {
    if (!arguments.length) { return transitionDuration }
    transitionDuration = _
    return chart
  }

  chart.transitionEase = function (_) {
    if (!arguments.length) { return transitionEase }
    transitionEase = _
    return chart
  }

  chart.sort = function (_) {
    if (!arguments.length) { return sort }
    sort = _
    return chart
  }

  chart.langs = function (_) {
    if (_ === true) tiers = false
    langs = _
    if (selection) update()
    return chart
  }

  chart.tiers = function (_) {
    if (_ === true) langs = false
    tiers = _
    if (selection) update()
    return chart
  }

  chart.search = function (term, color) {
    selection.each(function (data) {
      searchTree(data, term, color)
      update()
    })
  }

  chart.clear = function (color) {
    selection.each(function (data) {
      clear(data, color)
      update()
    })
  }

  chart.typeHide = function (type) {
    if (!~filterTypes.indexOf(type)) {
      filterTypes.push(type)
      filterNeeded = true
      if (selection) update()
    }
  }

  chart.typeShow = function (type) {
    var ix = filterTypes.indexOf(type)
    if (!~ix) return
    filterTypes.splice(ix, 1)
    filterNeeded = true
    if (selection) update()
  }

  chart.colors = colors

  return chart
}

module.exports = flameGraph
<commit_msg>Hide BytecodeHandler within V8 tab.<commit_after>/* global d3 */
var hsl = require('hsl-to-rgb-for-reals')

function flameGraph () {
  var w = 960 // graph width
  var h = 1024 // graph height
  var c = 18 // cell height
  var selection = null // selection
  var transitionDuration = 500
  var transitionEase = 'cubic-in-out' // tooltip offset
  var sort = true
  var langs = false
  var tiers = false
  var filterNeeded = true
  var filterTypes = []
  var allSamples
  var labelRx = /^LazyCompile:|Function:|Script:/
  var optRx = /^\w+:(\s+)?\*/
  var notOptRx = /^\w+:(\s+)?~/

  function label (d) {
    if (d.dummy) return ''
    var optInfo = d.optimized && '—opt\'d—' ||
      d.notOptimized && '—not opt\'d—' || ''

    var onStack = d.name ? d3.round(100 * (d.value / allSamples), 1) + '% on stack' : ''
    var top = stackTop(d)
    var topOfStack = d.name ? (top
      ? d3.round(100 * (top / allSamples), 2) + '% stack top'
      : '') : ''

    if (onStack && topOfStack) { onStack += ', ' }

    var name = d.name.replace(labelRx, '') +
      '' + ' ' + optInfo + ' ' + onStack + ' ' + topOfStack + ''

    return name
  }

  function stackTop (d) {
    if (!d.children) return d.top
    var top = d.top

    d.children
      .forEach(function (child) {
        if (
            !child.children ||
            child.children.filter(function (c) { return c.hide }).length
        ) {
          if (child.hide) {
            top += stackTop(child)
          }
        }
      })

    return top
  }

  function titleLabel (d) {
    var top = stackTop(d)
    return d.name + '\n' + (top
      ? 'Top of Stack:' + d3.round(100 * (top / allSamples), 1) + '% ' +
      '(' + top + ' of ' + allSamples + ' samples)\n'
      : '') +
    'On Stack:' + d3.round(100 * (d.value / allSamples), 1) + '% ' +
    '(' + d.value + ' of ' + allSamples + ' samples)'
  }

  function langtier (name) {
    // todo: C deps
    if (!/.js/.test(name)) {
      switch (true) {
        case /^Builtin:|^Stub:|v8::|^(.+)IC:|^.*Handler:/
          .test(name): return {type: 'v8', lang: 'c'}
        case /^RegExp:/
          .test(name): return {type: 'regexp', lang: 'c'}
        case /apply$|call$|Arguments$/
          .test(name): return {type: 'nativeJS', lang: 'js'}
        case /\.$/.test(name): return {type: 'core', lang: 'js'}
        default: return {type: 'nativeC', lang: 'c'}
      }
      return
    }

    switch (true) {
      case / native /.test(name): return {type: 'nativeJS', lang: 'js'}
      case (name.indexOf('/') === -1 || /internal\//.test(name) && !/ \//.test(name)): return {type: 'core', lang: 'js'}
      case !/node_modules/.test(name): return {type: 'app', lang: 'js'}
      default: return {type: 'deps', lang: 'js'}
    }
  }

  var colors = {
    v8: {h: 67, s: 81, l: 65},
    regexp: {h: 310, s: 86, l: 18},
    nativeC: {h: 0, s: 50, l: 50},
    nativeJS: {h: 122, s: 50, l: 45},
    core: {h: 23, s: 66, l: 45},
    deps: {h: 244, s: 50, l: 65},
    app: {h: 200, s: 50, l: 45}
  }
  colors.def = colors.core
  colors.js = colors.core
  colors.c = colors.deps

  var diffScale = d3.scale.linear().range([0, 0.2])

  function colorHash (d, perc) {
    if (!d.name) {
      return perc ? 'rgb(127, 127, 127)' : 'rgba(0, 0, 0, 0)'
    }

    perc = perc || 1
    var type = d.type || 'def'
    var lang = d.lang || 'js'

    var key

    if (!langs && !tiers) key = colors.def

    if (langs) key = colors[lang]
    if (tiers) key = colors[type]

    var h = key.h
    var s = key.s
    var l = key.l
    var top = stackTop(d)
    var vector = ((top / allSamples) * 100) + 1
    s *= vector
    l += (vector * 2)

    s /= 100
    l /= 100

    s *= perc
    l *= perc

    var a = 0.8
    if (l > .8) {
      a += diffScale(l - 0.8)
      l = .8
    }

    var rgb = hsl(h, s, l)

    return 'rgba(' + rgb + ', ' + a + ')'
  }

  function filter (data) {
    if (!filterNeeded) return
    if (data.children && (data.children.length > 0)) {
      data.children.forEach(filter)
      data.children.forEach(function (child) {
        if (~filterTypes.indexOf(child.type) || ~filterTypes.indexOf(child.lang)) {
          child.hide = true
        } else {
          child.hide = false
        }
      })
    }
  }

  function augment (data) {
    // Augment partitioning layout with "dummy" nodes so that internal nodes'
    // values dictate their width. Annoying, but seems to be least painful
    // option.  https://github.com/mbostock/d3/pull/574
    if (data.children && (data.children.length > 0)) {
      data.children.forEach(augment)
      var childValues = 0
      data.children.forEach(function (child) {
        var lt = langtier(child.name)
        child.type = lt.type
        child.lang = lt.lang

        if (optRx.test(child.name)) {
          child.optimized = true
        }
        if (notOptRx.test(child.name)) {
          child.notOptimized = true
        }

        childValues += child.value
      })
      if (childValues < data.value) {
        data.children.push(
          {
            name: '',
            value: data.value - childValues,
            top: 0,
            dummy: true
          }
        )
      }
    }
  }

  function hide (d) {
    if (!d.original) {
      d.original = d.value
    }
    d.value = 0
    if (d.children) {
      d.children.forEach(hide)
    }
  }

  function show (d) {
    d.fade = false
    if (d.original) {
      d.value = d.original
    }
    if (d.children) {
      d.children.forEach(show)
    }
  }

  function getSiblings (d) {
    var siblings = []
    if (d.parent) {
      var me = d.parent.children.indexOf(d)
      siblings = d.parent.children.slice(0)
      siblings.splice(me, 1)
    }
    return siblings
  }

  function hideSiblings (d) {
    var siblings = getSiblings(d)
    siblings.forEach(function (s) {
      hide(s)
    })
    if (d.parent) {
      hideSiblings(d.parent)
    }
  }

  function fadeAncestors (d) {
    if (d.parent) {
      d.parent.fade = true
      fadeAncestors(d.parent)
    }
  }

  function zoom (d) {
    hideSiblings(d)
    show(d)
    fadeAncestors(d)
    update()
  }

  function searchTree (d, term, color) {
    var re = new RegExp(term)
    var label = d.name

    if (d.children) {
      d.children.forEach(function (child) {
        searchTree(child, term, color)
      })
    }
    if (d.hide) { return }
    if (label.match(re)) {
      d.highlight = color || true
    } else {
      if (typeof d.highlight === 'boolean') {
        d.highlight = false
      }
    }
  }

  function clear (d, color) {
    if (color && d.highlight === color) {
      d.highlight = false
    }
    if (!color) { d.highlight = false }
    if (d.children) {
      d.children.forEach(function (child) {
        clear(child, color)
      })
    }
  }

  function doSort (a, b) {
    if (typeof sort === 'function') {
      return sort(a, b)
    } else if (sort) {
      return d3.ascending(a.name, b.name)
    } else {
      return 0
    }
  }

  var partition = d3.layout.partition()
    .sort(doSort)
    .value(function (d) { return d.v || d.value })
    .children(function (d) { return d.c || d.children })

  function translate (d) {
    var x = d3.scale.linear().range([0, w])
    var parent = d.parent
    var depthOffset = parent && parent.hide ? 1 : 0
    while (parent && (parent = parent.parent)) {
      if (parent.hide) depthOffset += 1
    }
    var depth = d.depth - depthOffset
    return 'translate(' + x(d.x) + ',' + (h - (depth * c) - c) + ')'
  }

  function update () {
    selection
      .each(function (data) {
        filter(data)

        var nodes = partition(data)
        var kx = w / data.dx
        var svg = d3.select(this).select('svg')
        var g = svg.selectAll('g').data(nodes)

        svg.on('click', function (d) {
          if (d3.event.path[0] === this) {
            zoom(d)
          }
        })

        g.transition()
          .duration(transitionDuration)
          .ease(transitionEase)
          .attr('transform', translate)

        g.select('rect').transition()
          .duration(transitionDuration)
          .ease(transitionEase)
          .attr('width', function (d) { return d.dx * kx })

        var node = g.enter()
          .append('svg:g')
          .attr('transform', translate)

        node
          .append('svg:rect')
          .attr('width', function (d) { return d.dx * kx })

        node.append('svg:title')

        node.append('foreignObject')
          .append('xhtml:div')

        node.attr('width', function (d) { return d.dx * kx })
          .attr('height', function (d) { return c })
          .attr('name', function (d) { return d.name })
          .attr('class', function (d) { return d.fade ? 'frame fade' : 'frame' })

        g.select('rect')
          .attr('height', function (d) { return d.hide ? 0 : c })
          .style('cursor', 'pointer')
          .style('stroke', function (d) {
            return colorHash(d, 1.1)
          })
          .attr('fill', function (d) {
            var highlightColor = '#E600E6'

            if (typeof d.highlight === 'string') {
              highlightColor = d.highlight
            }
            return d.highlight ? highlightColor : colorHash(d)
          })
          .style('visibility', function (d) { return d.dummy ? 'hidden' : 'visible' })

        g.select('title')
          .text(titleLabel)

        g.select('foreignObject')
          .transition()
          .duration(transitionDuration)
          .ease(transitionEase)
          .attr('width', function (d) { return d.dx * kx })

        g.select('foreignObject')
          .style('overflow', 'hidden')
          .attr('height', function (d) { return d.hide ? 0 : c })
          .select('div')
          .style('display', function (d) { return (d.dx * kx < 35) || d.dummy ? 'none' : 'block' })
          .style('pointer-events', 'none')
          .style('white-space', 'nowrap')
          .style('text-overflow', 'ellipsis')
          .style('overflow', 'hidden')
          .style('font-size', '12px')
          .style('font-family', 'Verdana')
          .style('margin-left', '4px')
          .style('margin-right', '4px')
          .style('line-height', '1.5')
          .style('padding', '0')
          .style('font-weight', '400')
          .style('color', '#000')
          .style('text-align', 'left')
          .html(label)

        g.on('click', zoom)

        var hidden = g.filter(function (d) { return d.hide })
        hidden.forEach(function (d) {
          hide(d)
        })

        g.exit().remove()
      })
  }

  function chart (s) {
    selection = s

    if (!arguments.length) return chart

    selection.each(function (data) {
      allSamples = data.value

      d3.select(this)
        .append('svg:svg')
        .attr('width', w)
        .attr('height', h)
        .attr('class', 'partition d3-flame-graph')

      augment(data)
      filter(data)
      // "creative" fix for node ordering when partition is called for the first time
      partition(data)

      // first draw
      update()
    })
  }

  chart.height = function (_) {
    if (!arguments.length) { return h }
    h = _
    return chart
  }

  chart.width = function (_) {
    if (!arguments.length) { return w }
    w = _
    return chart
  }

  chart.cellHeight = function (_) {
    if (!arguments.length) { return c }
    c = _
    return chart
  }

  chart.transitionDuration = function (_) {
    if (!arguments.length) { return transitionDuration }
    transitionDuration = _
    return chart
  }

  chart.transitionEase = function (_) {
    if (!arguments.length) { return transitionEase }
    transitionEase = _
    return chart
  }

  chart.sort = function (_) {
    if (!arguments.length) { return sort }
    sort = _
    return chart
  }

  chart.langs = function (_) {
    if (_ === true) tiers = false
    langs = _
    if (selection) update()
    return chart
  }

  chart.tiers = function (_) {
    if (_ === true) langs = false
    tiers = _
    if (selection) update()
    return chart
  }

  chart.search = function (term, color) {
    selection.each(function (data) {
      searchTree(data, term, color)
      update()
    })
  }

  chart.clear = function (color) {
    selection.each(function (data) {
      clear(data, color)
      update()
    })
  }

  chart.typeHide = function (type) {
    if (!~filterTypes.indexOf(type)) {
      filterTypes.push(type)
      filterNeeded = true
      if (selection) update()
    }
  }

  chart.typeShow = function (type) {
    var ix = filterTypes.indexOf(type)
    if (!~ix) return
    filterTypes.splice(ix, 1)
    filterNeeded = true
    if (selection) update()
  }

  chart.colors = colors

  return chart
}

module.exports = flameGraph
<|endoftext|>


<commit_before>var fs = require("fs")
var dirname = require("../config").dirname
var rimraf = require("rimraf")

module.exports = function (cb) {
  cb = typeof cb === "function" ? cb : false
  rimraf.sync(dirname.src)
  rimraf.sync(dirname.npm)
  var lstat
  try {
    lstat = fs.lstatSync(dirname.current.npm)
    if (lstat.isSymbolicLink()) fs.unlinkSync(dirname.current.npm)
    lstat = fs.lstatSync(dirname.current.bin)
    if (lstat.isSymbolicLink()) fs.unlinkSync(dirname.current.bin)
  } catch (Exception) {}
  if (cb) {
    cb(null)
  } else {
    console.log("\nDone")
  }
}
<commit_msg>clean: remove old current symlink<commit_after>var fs = require("fs")
var dirname = require("../config").dirname
var rimraf = require("rimraf")

module.exports = function (cb) {
  cb = typeof cb === "function" ? cb : false
  rimraf.sync(dirname.src)
  rimraf.sync(dirname.npm)
  var lstat
  try {
    lstat = fs.lstatSync(dirname.current.dir)
    if (lstat.isSymbolicLink()) fs.unlinkSync(dirname.current.dir)
    lstat = fs.lstatSync(dirname.current.npm)
    if (lstat.isSymbolicLink()) fs.unlinkSync(dirname.current.npm)
    lstat = fs.lstatSync(dirname.current.bin)
    if (lstat.isSymbolicLink()) fs.unlinkSync(dirname.current.bin)
  } catch (Exception) {}
  if (cb) {
    cb(null)
  } else {
    console.log("\nDone")
  }
}
<|endoftext|>


<commit_before>$(document).ready(function(){
  var on = false;
  var start = false;
  var strict = false;
  var score = 1;
  var count = 0;
  var glowButtonClickable = false;
  var clickCount = 0;
  var glowButtons = [], clickedButtons = [];
  var timeout;

  var audio = document.getElementById("audio");

  $(".onOff").click(function(){
    if(!on){
      $(".strict").removeClass("unclickable");
      $(".start").removeClass("unclickable");
      on = true;
      $(this).text("off");
      $(".count").text("Welcome !!!");
      $(".display > h5").css({'padding-top': "0"});
    }
    else{
      clearGame();
      on = false;
      $(this).text("On");
      $(".display > h5").css({'padding-top': "30rem"});
      $(".count").text("");
      $(".score").text("");
      $(".strict").text("strict");
      strict = false;
      $(".start").text("start");
      start = false;
      $(".strict").addClass("unclickable");
      $(".start").addClass("unclickable");
      pattern = [];
    }
  });

  $(".start").click(function(){
    if(on){
      if(!start){
        updateScore();
        $(this).text("Stop");
        $(".strict").addClass("unclickable");
        start = true;
        setTimeout(function(){startGame();},1200);
      }
      else{
        clearGame();
        updateScore();
        $(".strict").removeClass("unclickable");
        $(this).text("Start");
        start = false;
        $(".strict").text("strict");
        strict = false;
      }
    }
  });

  $(".strict").click(function(){
    if(!strict && !start && on){
      $(this).text("Easy");
      strict = true;
    }
    else if(strict && !start && on){
      $(this).text("Strict");
      strict = false;
      pattern = [];
    }
  });

  function startGame(){
    var no =  (Math.floor(Math.random()* 10 + 1) % 4) + 1 ;
    glowButtons.push( String(no) );
    glow();
  }

  function glow(){
      var str = ".button" + glowButtons[count];
      audio.play();
      $(str).addClass("glow").delay(1000).queue(function(){
        count++;
        $(this).removeClass("glow").dequeue();
        if(count < glowButtons.length){
          setTimeout(function(){
              glow();
          },900);
        }
        else{
          count = 0;
          glowButtonClickable = true;
        }
      });
  }

  $(".button").click(function(){
    if(glowButtonClickable){
      clickCount++;
      clickedButtons.push($(this).attr('data-pos'));
      var no = String($(this).attr('data-pos'));
      audio.play();
      if(clickedButtons[clickCount-1] !== glowButtons[clickCount-1]){
        showStatus();
        if(strict)
          clearGame();
        else
          giveAnotherChance();
        return;
      }
      if(clickedButtons.length === glowButtons.length){
        glowButtonClickable = false;
        clickCount = 0;
        clickedButtons = [];
        score++;
        updateScore();
        if(score !== 2){
          timeout = setTimeout(function(){
            startGame();
          }, 1500);
        }
        else
          showVictory();
      }
    }
  });

  function clearGame(){
    glowButtonClickable = false;
    clickCount = 0;
    score = 1;
    count = 0;
    glowButtons = [];
    clickedButtons = [];
    $(".start").text("start");
    start = false;
    updateScore()
  }

  function giveAnotherChance(){
    glowButtonClickable = false;
    clickCount = 0;
    clickedButtons = [];
    setTimeout(function(){
      glow();
    },1500);
  }

  function showStatus(){
    $(".count").text("!!!!!!!!!").css({color:"red"});
    $(".score").text("");
    setTimeout(function(){
      $(".count").text("Count : ").css({color:"#EEE"});
      $(".score").text(score);
    },1200);
  }

  function updateScore(){

    $(".count").text("Count : ").css({color:"#EEE"});
    $(".score").text(score);

  }

  function showVictory(){
      $(".score").text("");
      $(".count").text("You Win !!!").css({color:"#69b669"});
      setTimeout(function(){clearGame();}, 2000);
  }
});
<commit_msg>simon game final commit!<commit_after>$(document).ready(function(){
  var on = false;
  var start = false;
  var strict = false;
  var score = 1;
  var count = 0;
  var glowButtonClickable = false;
  var clickCount = 0;
  var glowButtons = [], clickedButtons = [];
  var timeout;

  var audio = document.getElementById("audio");

  $(".onOff").click(function(){
    if(!on){
      $(".strict").removeClass("unclickable");
      $(".start").removeClass("unclickable");
      on = true;
      $(this).text("off");
      $(".count").text("Welcome !!!");
      $(".display > h5").css({'padding-top': "0"});
    }
    else{
      clearGame();
      on = false;
      $(this).text("On");
      $(".display > h5").css({'padding-top': "30rem"});
      $(".count").text("");
      $(".score").text("");
      $(".strict").text("strict");
      strict = false;
      $(".start").text("start");
      start = false;
      $(".strict").addClass("unclickable");
      $(".start").addClass("unclickable");
      pattern = [];
    }
  });

  $(".start").click(function(){
    if(on){
      if(!start){
        updateScore();
        $(this).text("Stop");
        $(".strict").addClass("unclickable");
        start = true;
        setTimeout(function(){startGame();},1200);
      }
      else{
        clearGame();
        updateScore();
        $(".strict").removeClass("unclickable");
        $(this).text("Start");
        start = false;
        $(".strict").text("strict");
        strict = false;
      }
    }
  });

  $(".strict").click(function(){
    if(!strict && !start && on){
      $(this).text("Easy");
      strict = true;
    }
    else if(strict && !start && on){
      $(this).text("Strict");
      strict = false;
      pattern = [];
    }
  });

  function startGame(){
    var no =  (Math.floor(Math.random()* 10 + 1) % 4) + 1 ;
    glowButtons.push( String(no) );
    glow();
  }

  function glow(){
      var str = ".button" + glowButtons[count];
      audio.play();
      $(str).addClass("glow").delay(1000).queue(function(){
        count++;
        $(this).removeClass("glow").dequeue();
        if(count < glowButtons.length){
          setTimeout(function(){
              glow();
          },900);
        }
        else{
          count = 0;
          glowButtonClickable = true;
        }
      });
  }

  $(".button").click(function(){
    if(glowButtonClickable){
      clickCount++;
      clickedButtons.push($(this).attr('data-pos'));
      var no = String($(this).attr('data-pos'));
      audio.play();
      if(clickedButtons[clickCount-1] !== glowButtons[clickCount-1]){
        showStatus();
        if(strict)
          clearGame();
        else
          giveAnotherChance();
        return;
      }
      if(clickedButtons.length === glowButtons.length){
        glowButtonClickable = false;
        clickCount = 0;
        clickedButtons = [];
        score++;
        updateScore();
        if(score !== 21){
          timeout = setTimeout(function(){
            startGame();
          }, 1500);
        }
        else
          showVictory();
      }
    }
  });

  function clearGame(){
    glowButtonClickable = false;
    clickCount = 0;
    score = 1;
    count = 0;
    glowButtons = [];
    clickedButtons = [];
    $(".start").text("start");
    start = false;
    updateScore()
  }

  function giveAnotherChance(){
    glowButtonClickable = false;
    clickCount = 0;
    clickedButtons = [];
    setTimeout(function(){
      glow();
    },1500);
  }

  function showStatus(){
    $(".count").text("!!!!!!!!!").css({color:"red"});
    $(".score").text("");
    setTimeout(function(){
      $(".count").text("Count : ").css({color:"#EEE"});
      $(".score").text(score);
    },1200);
  }

  function updateScore(){

    $(".count").text("Count : ").css({color:"#EEE"});
    $(".score").text(score);

  }

  function showVictory(){
      $(".score").text("");
      $(".count").text("You Win !!!").css({color:"#69b669"});
      setTimeout(function(){clearGame();}, 2000);
  }
});
<|endoftext|>