<!-- NEW7 — TEST 7 · THE WOVEN CITY · part 105 -->
ray = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] );

		const ib = new this.constructor( array, this.stride );
		ib.setUsage( this.usage );

		return ib;

	}

	/**
	 * Sets the given callback function that is executed after the Renderer has transferred
	 * the array data to the GPU. Can be used to perform clean-up operations after
	 * the upload when data are not needed anymore on the CPU side.
	 *
	 * @param {Function} callback - The `onUpload()` callback.
	 * @return {InterleavedBuffer} A reference to this instance.
	 */
	onUpload( callback ) {

		this.onUploadCallback = callback;

		return this;

	}

	/**
	 * Serializes the interleaved buffer into JSON.
	 *
	 * @param {Object} [data] - An optional value holding meta information about the serialization.
	 * @return {Object} A JSON object representing the serialized interleaved buffer.
	 */
	toJSON( data ) {

		if ( data.arrayBuffers === undefined ) {

			data.arrayBuffers = {};

		}

		// generate UUID for array buffer if necessary

		if ( this.array.buffer._uuid === undefined ) {

			this.array.buffer._uuid = generateUUID();

		}

		if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {

			data.arrayBuffers[ this.array.buffer._uuid ] = Array.from( new Uint32Array( this.array.buffer ) );

		}

		//

		const json = {
			uuid: this.uuid,
			buffer: this.array.buffer._uuid,
			type: this.array.constructor.name,
			stride: this.stride
		};

		json.usage = this.usage;

		return json;

	}

}

const _vector$8 = /*@__PURE__*/ new Vector3();

/**
 * An alternative version of a buffer attribute with interleaved data. Interleaved
 * attributes share a common interleaved data storage ({@link InterleavedBuffer}) and refer with
 * different offsets into the buffer.
 */
class InterleavedBufferAttribute {

	/**
	 * Constructs a new interleaved buffer attribute.
	 *
	 * @param {InterleavedBuffer} interleavedBuffer - The buffer holding the interleaved data.
	 * @param {number} itemSize - The item size.
	 * @param {number} offset - The attribute offset into the buffer.
	 * @param {boolean} [normalized=false] - Whether the data are normalized or not.
	 */
	constructor( interleavedBuffer, itemSize, offset, normalized = false ) {

		/**
		 * This flag can be used for type testing.
		 *
		 * @type {boolean}
		 * @readonly
		 * @default true
		 */
		this.isInterleavedBufferAttribute = true;

		/**
		 * The name of the buffer attribute.
		 *
		 * @type {string}
		 */
		this.name = '';

		/**
		 * The buffer holding the interleaved data.
		 *
		 * @type {InterleavedBuffer}
		 */
		this.data = interleavedBuffer;

		/**
		 * The item size, see {@link BufferAttribute#itemSize}.
		 *
		 * @type {number}
		 */
		this.itemSize = itemSize;

		/**
		 * The attribute offset into the buffer.
		 *
		 * @type {number}
		 */
		this.offset = offset;

		/**
		 * Whether the data are normalized or not, see {@link BufferAttribute#normalized}
		 *
		 * @type {InterleavedBuffer}
		 */
		this.normalized = normalized;

	}

	/**
	 * The item count of this buffer attribute.
	 *
	 * @type {number}
	 * @readonly
	 */
	get count() {

		return this.data.count;

	}

	/**
	 * The array holding the interleaved buffer attribute data.
	 *
	 * @type {TypedArray}
	 */
	get array() {

		return this.data.array;

	}

	/**
	 * Flag to indicate that this attribute has changed and should be re-sent to
	 * the GPU. Set this to `true` when you modify the value of the array.
	 *
	 * @type {number}
	 * @default false
	 * @param {boolean} value
	 */
	set needsUpdate( value ) {

		this.data.needsUpdate = value;

	}

	/**
	 * Applies the given 4x4 matrix to the given attribute. Only works with
	 * item size `3`.
	 *
	 * @param {Matrix4} m - The matrix to apply.
	 * @return {InterleavedBufferAttribute} A reference to this instance.
	 */
	applyMatrix4( m ) {

		for ( let i = 0, l = this.data.count; i < l; i ++ ) {

			_vector$8.fromBufferAttribute( this, i );

			_vector$8.applyMatrix4( m );

			this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z );

		}

		return this;

	}

	/**
	 * Applies the given 3x3 normal matrix to the given attribute. Only works with
	 * item size `3`.
	 *
	 * @param {Matrix3} m - The normal matrix to apply.
	 * @return {InterleavedBufferAttribute} A reference to this instance.
	 */
	applyNormalMatrix( m ) {

		for ( let i = 0, l = this.count; i < l; i ++ ) {

			_vector$8.fromBufferAttribute( this, i );

			_vector$8.applyNormalMatrix( m );

			this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z );

		}

		return this;

	}

	/**
	 * Applies the given 4x4 matrix to the given attribute. Only works with
	 * item size `3` and with direction vectors.
	 *
	 * @param {Matrix4} m - The matrix to apply.
	 * @return {InterleavedBufferAttribute} A reference to this instance.
	 */
	transformDirection( m ) {

		for ( let i = 0, l = this.count; i < l; i ++ ) {

			_vector$8.fromBufferAttribute( this, i );

			_vector$8