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

THREE.Animation = function ( root, data ) {

	this.root = root;
	this.data = THREE.AnimationHandler.init( data );
	this.hierarchy = THREE.AnimationHandler.parse( root );

	this.currentTime = 0;
	this.timeScale = 1;

	this.isPlaying = false;
	this.loop = true;
	this.weight = 0;

	this.interpolationType = THREE.AnimationHandler.LINEAR;

};


THREE.Animation.prototype.keyTypes = [ "pos", "rot", "scl" ];


THREE.Animation.prototype.play = function ( startTime, weight ) {

	this.currentTime = startTime !== undefined ? startTime : 0;
	this.weight = weight !== undefined ? weight: 1;

	this.isPlaying = true;

	this.reset();

	THREE.AnimationHandler.play( this );

};


THREE.Animation.prototype.stop = function() {

	this.isPlaying = false;

	THREE.AnimationHandler.stop( this );

};

THREE.Animation.prototype.reset = function () {

	for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {

		var object = this.hierarchy[ h ];

		if ( object.animationCache === undefined ) {

			object.animationCache = {
				animations: {},
				blending: {
					positionWeight: 0.0,
					quaternionWeight: 0.0,
					scaleWeight: 0.0
				}
			};
		}

		if ( object.animationCache.animations[this.data.name] === undefined ) {

			object.animationCache.animations[this.data.name] = {};
			object.animationCache.animations[this.data.name].prevKey = { pos: 0, rot: 0, scl: 0 };
			object.animationCache.animations[this.data.name].nextKey = { pos: 0, rot: 0, scl: 0 };
			object.animationCache.animations[this.data.name].originalMatrix = object.matrix;

		}

		var animationCache = object.animationCache.animations[this.data.name];

		// Get keys to match our current time

		for ( var t = 0; t < 3; t ++ ) {

			var type = this.keyTypes[ t ];

			var prevKey = this.data.hierarchy[ h ].keys[ 0 ];
			var nextKey = this.getNextKeyWith( type, h, 1 );

			while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) {

				prevKey = nextKey;
				nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 );

			}

			animationCache.prevKey[ type ] = prevKey;
			animationCache.nextKey[ type ] = nextKey;

		}

	}

};

THREE.Animation.prototype.resetBlendWeights = function () {

	for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {

		var object = this.hierarchy[ h ];

		if ( object.animationCache !== undefined ) {

			object.animationCache.blending.positionWeight = 0.0;
			object.animationCache.blending.quaternionWeight = 0.0;
			object.animationCache.blending.scaleWeight = 0.0;

		}

	}

};

THREE.Animation.prototype.update = (function(){

	var points = [];
	var target = new THREE.Vector3();
	var newVector = new THREE.Vector3();
	var newQuat = new THREE.Quaternion();

	// Catmull-Rom spline

	var interpolateCatmullRom = function ( points, scale ) {

		var c = [], v3 = [],
		point, intPoint, weight, w2, w3,
		pa, pb, pc, pd;

		point = ( points.length - 1 ) * scale;
		intPoint = Math.floor( point );
		weight = point - intPoint;

		c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
		c[ 1 ] = intPoint;
		c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1;
		c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2;

		pa = points[ c[ 0 ] ];
		pb = points[ c[ 1 ] ];
		pc = points[ c[ 2 ] ];
		pd = points[ c[ 3 ] ];

		w2 = weight * weight;
		w3 = weight * w2;

		v3[ 0 ] = interpolate( pa[ 0 ], pb[ 0 ], pc[ 0 ], pd[ 0 ], weight, w2, w3 );
		v3[ 1 ] = interpolate( pa[ 1 ], pb[ 1 ], pc[ 1 ], pd[ 1 ], weight, w2, w3 );
		v3[ 2 ] = interpolate( pa[ 2 ], pb[ 2 ], pc[ 2 ], pd[ 2 ], weight, w2, w3 );

		return v3;

	};

	var interpolate = function ( p0, p1, p2, p3, t, t2, t3 ) {

		var v0 = ( p2 - p0 ) * 0.5,
			v1 = ( p3 - p1 ) * 0.5;

		return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;

	};

	return function ( delta ) {

		if ( this.isPlaying === false ) return;

		this.currentTime += delta * this.timeScale;

		if ( this.weight === 0 )
			return;

		//

		var duration = this.data.length;

		if ( this.currentTime > duration || this.currentTime < 0 ) {

			if ( this.loop ) {

				this.currentTime %= duration;

				if ( this.currentTime < 0 )
					this.currentTime += duration;

				this.reset();

			} else {

				this.stop();
				return;
<commit_msg>Animation.js - Don't return before rendering the last frame<commit_after>/**
 * @author <NAME> / http://gomo.se/
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 */

THREE.Animation = function ( root, data ) {

	this.root = root;
	this.data = THREE.AnimationHandler.init( data );
	this.hierarchy = THREE.AnimationHandler.parse( root );

	this.currentTime = 0;
	this.timeScale = 1;

	this.isPlaying = false;
	this.loop = true;
	this.weight = 0;

	this.interpolationType = THREE.AnimationHandler.LINEAR;

};


THREE.Animation.prototype.keyTypes = [ "pos", "rot", "scl" ];


THREE.Animation.prototype.play = function ( startTime, weight ) {

	this.currentTime = startTime !== undefined ? startTime : 0;
	this.weight = weight !== undefined ? weight: 1;

	this.isPlaying = true;

	this.reset();

	THREE.AnimationHandler.play( this );

};


THREE.Animation.prototype.stop = function() {

	this.isPlaying = false;

	THREE.AnimationHandler.stop( this );

};

THREE.Animation.prototype.reset = function () {

	for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {

		var object = this.hierarchy[ h ];

		if ( object.animationCache === undefined ) {

			object.animationCache = {
				animations: {},
				blending: {
					positionWeight: 0.0,
					quaternionWeight: 0.0,
					scaleWeight: 0.0
				}
			};
		}

		if ( object.animationCache.animations[this.data.name] === undefined ) {

			object.animationCache.animations[this.data.name] = {};
			object.animationCache.animations[this.data.name].prevKey = { pos: 0, rot: 0, scl: 0 };
			object.animationCache.animations[this.data.name].nextKey = { pos: 0, rot: 0, scl: 0 };
			object.animationCache.animations[this.data.name].originalMatrix = object.matrix;

		}

		var animationCache = object.animationCache.animations[this.data.name];

		// Get keys to match our current time

		for ( var t = 0; t < 3; t ++ ) {

			var type = this.keyTypes[ t ];

			var prevKey = this.data.hierarchy[ h ].keys[ 0 ];
			var nextKey = this.getNextKeyWith( type, h, 1 );

			while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) {

				prevKey = nextKey;
				nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 );

			}

			animationCache.prevKey[ type ] = prevKey;
			animationCache.nextKey[ type ] = nextKey;

		}

	}

};

THREE.Animation.prototype.resetBlendWeights = function () {

	for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {

		var object = this.hierarchy[ h ];

		if ( object.animationCache !== undefined ) {

			object.animationCache.blending.positionWeight = 0.0;
			object.animationCache.blending.quaternionWeight = 0.0;
			object.animationCache.blending.scaleWeight = 0.0;

		}

	}

};

THREE.Animation.prototype.update = (function(){

	var points = [];
	var target = new THREE.Vector3();
	var newVector = new THREE.Vector3();
	var newQuat = new THREE.Quaternion();

	// Catmull-Rom spline

	var interpolateCatmullRom = function ( points, scale ) {

		var c = [], v3 = [],
		point, intPoint, weight, w2, w3,
		pa, pb, pc, pd;

		point = ( points.length - 1 ) * scale;
		intPoint = Math.floor( point );
		weight = point - intPoint;

		c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
		c[ 1 ] = intPoint;
		c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1;
		c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2;

		pa = points[ c[ 0 ] ];
		pb = points[ c[ 1 ] ];
		pc = points[ c[ 2 ] ];
		pd = points[ c[ 3 ] ];

		w2 = weight * weight;
		w3 = weight * w2;

		v3[ 0 ] = interpolate( pa[ 0 ], pb[ 0 ], pc[ 0 ], pd[ 0 ], weight, w2, w3 );
		v3[ 1 ] = interpolate( pa[ 1 ], pb[ 1 ], pc[ 1 ], pd[ 1 ], weight, w2, w3 );
		v3[ 2 ] = interpolate( pa[ 2 ], pb[ 2 ], pc[ 2 ], pd[ 2 ], weight, w2, w3 );

		return v3;

	};

	var interpolate = function ( p0, p1, p2, p3, t, t2, t3 ) {

		var v0 = ( p2 - p0 ) * 0.5,
			v1 = ( p3 - p1 ) * 0.5;

		return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;

	};

	return function ( delta ) {

		if ( this.isPlaying === false ) return;

		this.currentTime += delta * this.timeScale;

		if ( this.weight === 0 )
			return;

		//

		var duration = this.data.length;

		if ( this.currentTime > duration || this.currentTime < 0 ) {

			if ( this.loop ) {

				this.currentTime %= duration;

				if ( this.currentTime < 0 )
					this.currentTime += duration;

				this.reset();

			} else {

				this.stop();

{'fraction_non_alphanumeric': 0.16044353926227653, 'fraction_numerical': 0.02534510070151618, 'mean_word_length': 2.800085984522786, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2743385', 'n_tokens_mistral': 3696, 'n_tokens_neox': 3171, 'n_words': 794}