<!-- NEW4 — TEST 4 · THE QUILT · part 221 -->
 );

		this.setInterpolation( interpolation || this.DefaultInterpolation );

	}

	/**
	 * Converts the keyframe track to JSON.
	 *
	 * @static
	 * @param {KeyframeTrack} track - The keyframe track to serialize.
	 * @return {Object} The serialized keyframe track as JSON.
	 */
	static toJSON( track ) {

		const trackType = track.constructor;

		let json;

		// derived classes can define a static toJSON method
		if ( trackType.toJSON !== this.toJSON ) {

			json = trackType.toJSON( track );

		} else {

			// by default, we assume the data can be serialized as-is
			json = {

				'name': track.name,
				'times': convertArray( track.times, Array ),
				'values': convertArray( track.values, Array )

			};

			const interpolation = track.getInterpolation();

			if ( interpolation !== track.DefaultInterpolation ) {

				json.interpolation = interpolation;

			}

			if ( hasTangents( track.settings ) ) {

				json.settings = {
					inTangents: convertArray( track.settings.inTangents, Array ),
					outTangents: convertArray( track.settings.outTangents, Array )
				};

			}

		}

		json.type = track.ValueTypeName; // mandatory

		return json;

	}

	/**
	 * Factory method for creating a new discrete interpolant.
	 *
	 * @static
	 * @param {TypedArray} [result] - The result buffer.
	 * @return {DiscreteInterpolant} The new interpolant.
	 */
	InterpolantFactoryMethodDiscrete( result ) {

		return new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result );

	}

	/**
	 * Factory method for creating a new linear interpolant.
	 *
	 * @static
	 * @param {TypedArray} [result] - The result buffer.
	 * @return {LinearInterpolant} The new interpolant.
	 */
	InterpolantFactoryMethodLinear( result ) {

		return new LinearInterpolant( this.times, this.values, this.getValueSize(), result );

	}

	/**
	 * Factory method for creating a new smooth interpolant.
	 *
	 * @static
	 * @param {TypedArray} [result] - The result buffer.
	 * @return {CubicInterpolant} The new interpolant.
	 */
	InterpolantFactoryMethodSmooth( result ) {

		return new CubicInterpolant( this.times, this.values, this.getValueSize(), result );

	}

	/**
	 * Factory method for creating a new Bezier interpolant.
	 *
	 * The Bezier interpolant requires tangent data to be set via the `settings` property
	 * on the track before creating the interpolant. The settings should contain:
	 * - `inTangents`: Float32Array with [time, value] pairs per keyframe per component
	 * - `outTangents`: Float32Array with [time, value] pairs per keyframe per component
	 *
	 * @static
	 * @param {TypedArray} [result] - The result buffer.
	 * @return {BezierInterpolant} The new interpolant.
	 */
	InterpolantFactoryMethodBezier( result ) {

		const interpolant = new BezierInterpolant( this.times, this.values, this.getValueSize(), result );

		if ( this.settings ) {

			interpolant.inTangents = this.settings.inTangents;
			interpolant.outTangents = this.settings.outTangents;

		}

		return interpolant;

	}

	/**
	 * Defines the interpolation factor method for this keyframe track.
	 *
	 * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth|InterpolateBezier)} interpolation - The interpolation type.
	 * @return {KeyframeTrack} A reference to this keyframe track.
	 */
	setInterpolation( interpolation ) {

		let factoryMethod;

		switch ( interpolation ) {

			case InterpolateDiscrete:

				factoryMethod = this.InterpolantFactoryMethodDiscrete;

				break;

			case InterpolateLinear:

				factoryMethod = this.InterpolantFactoryMethodLinear;

				break;

			case InterpolateSmooth:

				factoryMethod = this.InterpolantFactoryMethodSmooth;

				break;

			case InterpolateBezier:

				factoryMethod = this.InterpolantFactoryMethodBezier;

				break;

		}

		if ( factoryMethod === undefined ) {

			const message = 'unsupported interpolation for ' +
				this.ValueTypeName + ' keyframe track named ' + this.name;

			if ( this.createInterpolant === undefined ) {

				// fall back to default, unless the default itself is messed up
				if ( interpolation !== this.DefaultInterpolation ) {

					this.setInterpolation( this.DefaultInterpolation );

				} else {

					throw new Error( message ); // fatal, in this case

				}

			}

			warn( 'KeyframeTrack:', message );
			return this;

		}

		this.createInterpolant = factoryMethod;

		return this;

	}

	/**
	 * Returns the current interpolation type.
	 *
	 * @return {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth|InterpolateBezier)} The interpolation type.
	 */
	getInterpolation() {

		switch ( this.createInterpolant ) {

			case this.InterpolantFactoryMethodDiscrete:

				return InterpolateDiscrete;

			case this.InterpolantFactoryMethodLinear:

				return InterpolateLinear;

			case this.InterpolantFactoryMethodSmooth:

				return InterpolateSmooth;

			case this.InterpolantFactoryMethodBezier:

				return InterpolateBezier;

		}

	}

	/**
	 * Returns the value size.
	