<!-- NEW4 — TEST 4 · THE QUILT · part 146 -->
lableGeometryIds = source._availableGeometryIds.slice();

		this._nextIndexStart = source._nextIndexStart;
		this._nextVertexStart = source._nextVertexStart;
		this._geometryCount = source._geometryCount;

		this._maxInstanceCount = source._maxInstanceCount;
		this._maxVertexCount = source._maxVertexCount;
		this._maxIndexCount = source._maxIndexCount;

		this._geometryInitialized = source._geometryInitialized;
		this._multiDrawCounts = source._multiDrawCounts.slice();
		this._multiDrawStarts = source._multiDrawStarts.slice();
		this._multiDrawBytesPerElement = source._multiDrawBytesPerElement;

		this._indirectTexture = source._indirectTexture.clone();
		this._indirectTexture.image.data = this._indirectTexture.image.data.slice();

		this._matricesTexture = source._matricesTexture.clone();
		this._matricesTexture.image.data = this._matricesTexture.image.data.slice();

		if ( this._colorsTexture !== null ) {

			this._colorsTexture = source._colorsTexture.clone();
			this._colorsTexture.image.data = this._colorsTexture.image.data.slice();

		}

		return this;

	}

	/**
	 * Frees the GPU-related resources allocated by this instance. Call this
	 * method whenever this instance is no longer used in your app.
	 */
	dispose() {

		super.dispose();

		// Assuming the geometry is not shared with other meshes
		this.geometry.dispose();

		this._matricesTexture.dispose();
		this._matricesTexture = null;

		this._indirectTexture.dispose();
		this._indirectTexture = null;

		if ( this._colorsTexture !== null ) {

			this._colorsTexture.dispose();
			this._colorsTexture = null;

		}

	}

	onBeforeRender( renderer, scene, camera, geometry, material/*, _group*/ ) {

		// if visibility has not changed and frustum culling and object sorting is not required
		// then skip iterating over all items
		if ( ! this._visibilityChanged && ! this.perObjectFrustumCulled && ! this.sortObjects ) {

			return;

		}

		// the indexed version of the multi draw function requires specifying the start
		// offset in bytes.
		const index = geometry.getIndex();
		let bytesPerElement = index === null ? 1 : index.array.BYTES_PER_ELEMENT;


		// the "wireframe" attribute implicitly creates a line attribute in the renderer, which is double
		// the vertices to draw (3 lines per triangle) so we multiply the draw counts / starts and make
		// assumptions about the index buffer byte size.
		let multiDrawMultiplier = 1;
		if ( material.wireframe ) {

			multiDrawMultiplier = 2;
			bytesPerElement = geometry.attributes.position.count > 65535 ? 4 : 2;

		}

		const instanceInfo = this._instanceInfo;
		const multiDrawStarts = this._multiDrawStarts;
		const multiDrawCounts = this._multiDrawCounts;
		const geometryInfoList = this._geometryInfo;
		const perObjectFrustumCulled = this.perObjectFrustumCulled;
		const indirectTexture = this._indirectTexture;
		const indirectArray = indirectTexture.image.data;

		const frustum = camera.isArrayCamera ? _frustumArray : _frustum;
		// prepare the frustum in the local frame
		if ( perObjectFrustumCulled ) {

			if ( camera.isArrayCamera ) {

				frustum.setFromArrayCamera( camera );

			} else {

				_matrix$1
					.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse )
					.multiply( this.matrixWorld );

				frustum.setFromProjectionMatrix(
					_matrix$1,
					camera.coordinateSystem,
					camera.reversedDepth
				);

			}

		}

		let multiDrawCount = 0;
		if ( this.sortObjects ) {

			// get the camera position in the local frame
			_matrix$1.copy( this.matrixWorld ).invert();
			_vector$5.setFromMatrixPosition( camera.matrixWorld ).applyMatrix4( _matrix$1 );
			_forward$1.set( 0, 0, -1 ).transformDirection( camera.matrixWorld ).transformDirection( _matrix$1 );

			for ( let i = 0, l = instanceInfo.length; i < l; i ++ ) {

				if ( instanceInfo[ i ].visible && instanceInfo[ i ].active ) {

					const geometryId = instanceInfo[ i ].geometryIndex;

					// get the bounds in world space
					this.getMatrixAt( i, _matrix$1 );
					this.getBoundingSphereAt( geometryId, _sphere$2 ).applyMatrix4( _matrix$1 );

					// determine whether the batched geometry is within the frustum
					let culled = false;
					if ( perObjectFrustumCulled ) {

						culled = ! frustum.intersectsSphere( _sphere$2 );

					}

					if ( ! culled ) {

						// get the distance from camera used for sorting
						const geometryInfo = geometryInfoList[ geometryId ];
						const z = _temp.subVectors( _sphere$2.center, _vector$5 ).dot( _forward$1 );
						_renderList.push( geometryInfo.start, geometryInfo.count, z, i );

					}

				}

			}

			// Sort the draw ranges and prep for rendering
			const list = _renderList.list;
			const customSort = this.customSort;
			if ( customSort === null ) {

				list.sort( material.transparent ? sortTransparent : sortOpaque );

			} else {

				customSort.call( this, list, camera );

			}

			for ( let i = 0, l = list.length; i < l; i ++ ) {

				co