<!-- NEW7 — TEST 7 · THE WOVEN CITY · part 144 -->
Mesh} A reference to this batched mesh.
	 */
	setColorAt( instanceId, color ) {

		this.validateInstanceId( instanceId );

		if ( this._colorsTexture === null ) {

			this._initColorsTexture();

		}

		color.toArray( this._colorsTexture.image.data, instanceId * 4 );
		this._colorsTexture.needsUpdate = true;

		return this;

	}

	/**
	 * Returns the color of the defined instance.
	 *
	 * @param {number} instanceId - The ID of an instance to get the color of.
	 * @param {Color|Vector4} color - The target object that is used to store the method's result.
	 * @return {Color|Vector4} The instance's color.  Use a `Vector4` to also retrieve alpha.
	 */
	getColorAt( instanceId, color ) {

		this.validateInstanceId( instanceId );
		if ( this._colorsTexture === null ) {

			if ( color.isVector4 ) {

				return color.set( 1, 1, 1, 1 );

			} else {

				return color.setRGB( 1, 1, 1 );

			}

		} else {

			return color.fromArray( this._colorsTexture.image.data, instanceId * 4 );

		}

	}

	/**
	 * Sets the visibility of the instance.
	 *
	 * @param {number} instanceId - The id of the instance to set the visibility of.
	 * @param {boolean} visible - Whether the instance is visible or not.
	 * @return {BatchedMesh} A reference to this batched mesh.
	 */
	setVisibleAt( instanceId, visible ) {

		this.validateInstanceId( instanceId );

		if ( this._instanceInfo[ instanceId ].visible === visible ) {

			return this;

		}

		this._instanceInfo[ instanceId ].visible = visible;
		this._visibilityChanged = true;

		return this;

	}

	/**
	 * Returns the visibility state of the defined instance.
	 *
	 * @param {number} instanceId - The ID of an instance to get the visibility state of.
	 * @return {boolean} Whether the instance is visible or not.
	 */
	getVisibleAt( instanceId ) {

		this.validateInstanceId( instanceId );

		return this._instanceInfo[ instanceId ].visible;

	}

	/**
	 * Sets the geometry ID of the instance at the given index.
	 *
	 * @param {number} instanceId - The ID of the instance to set the geometry ID of.
	 * @param {number} geometryId - The geometry ID to be use by the instance.
	 * @return {BatchedMesh} A reference to this batched mesh.
	 */
	setGeometryIdAt( instanceId, geometryId ) {

		this.validateInstanceId( instanceId );
		this.validateGeometryId( geometryId );

		this._instanceInfo[ instanceId ].geometryIndex = geometryId;
		this._visibilityChanged = true;

		return this;

	}

	/**
	 * Returns the geometry ID of the defined instance.
	 *
	 * @param {number} instanceId - The ID of an instance to get the geometry ID of.
	 * @return {number} The instance's geometry ID.
	 */
	getGeometryIdAt( instanceId ) {

		this.validateInstanceId( instanceId );

		return this._instanceInfo[ instanceId ].geometryIndex;

	}

	/**
	 * Get the range representing the subset of triangles related to the attached geometry,
	 * indicating the starting offset and count, or `null` if invalid.
	 *
	 * @param {number} geometryId - The id of the geometry to get the range of.
	 * @param {Object} [target] - The target object that is used to store the method's result.
	 * @return {{
	 * 	vertexStart:number,vertexCount:number,reservedVertexCount:number,
	 * 	indexStart:number,indexCount:number,reservedIndexCount:number,
	 * 	start:number,count:number
	 * }} The result object with range data.
	 */
	getGeometryRangeAt( geometryId, target = {} ) {

		this.validateGeometryId( geometryId );

		const geometryInfo = this._geometryInfo[ geometryId ];
		target.vertexStart = geometryInfo.vertexStart;
		target.vertexCount = geometryInfo.vertexCount;
		target.reservedVertexCount = geometryInfo.reservedVertexCount;

		target.indexStart = geometryInfo.indexStart;
		target.indexCount = geometryInfo.indexCount;
		target.reservedIndexCount = geometryInfo.reservedIndexCount;

		target.start = geometryInfo.start;
		target.count = geometryInfo.count;

		return target;

	}

	/**
	 * Resizes the necessary buffers to support the provided number of instances.
	 * If the provided arguments shrink the number of instances but there are not enough
	 * unused Ids at the end of the list then an error is thrown.
	 *
	 * @param {number} maxInstanceCount - The max number of individual instances that can be added and rendered by the batch.
	*/
	setInstanceCount( maxInstanceCount ) {

		// shrink the available instances as much as possible
		const availableInstanceIds = this._availableInstanceIds;
		const instanceInfo = this._instanceInfo;
		availableInstanceIds.sort( ascIdSort );
		while ( availableInstanceIds[ availableInstanceIds.length - 1 ] === instanceInfo.length - 1 ) {

			instanceInfo.pop();
			availableInstanceIds.pop();

		}

		// throw an error if it can't be shrunk to the desired size
		if ( maxInstanceCount < instanceInfo.length ) {

			throw new Error( `THREE.BatchedMesh: Instance ids outside the range ${ maxInstanceCount } are being used. Cannot shrink instance count.` );

		}

		// copy the multi 