function accumulator( x ) {
		var v;
		var k;
		if ( arguments.length === 0 ) {
			if ( N === 0 ) {
				return null;
			}
			return ( max+min ) / 2.0;
		}
		// Update the index for managing the circular buffer:
		i = (i+1) % W;

		if ( x === 0.0 ) {
			x = 0.0; // normalizes +-0
		}
		// Case: incoming value is NaN...
		if ( isnan( x ) ) {
			N = W; // explicitly set to avoid `N < W` branch
			min = x;
			max = x;
		}
		// Case: initial window...
		else if ( N < W ) {
			N += 1;
			if ( x < min ) {
				min = x;
			}
			if ( x > max ) {
				max = x;
			}
		}
		// Case: outgoing value is the current minimum or maximum and the new value is either greater than the minimum or less than the maximum, and, thus, we need to find new accumulated values among the current buffer values...
		else if (
			( buf[ i ] === min && x > min ) ||
			( buf[ i ] === max && x < max ) ||
			isnan( buf[ i ] )
		) {
			min = x;
			max = x;
			for ( k = 0; k < W; k++ ) {
				if ( k !== i ) {
					v = buf[ k ];
					if ( isnan( v ) ) {
						min = v;
						max = v;
						break; // no need to continue searching
					}
					if ( v < min ) {
						min = v;
					}
					if ( v > max ) {
						max = v;
					}
				}
			}
		}
		// Case: incoming value is less than current minimum value...
		else if ( x < min ) {
			min = x;
		}
		// Case: incoming value is greater than current maximum value...
		else if ( x > max ) {
			max = x;
		}
		// Case: updating existing window; however, the minimum and maximum values do not change so nothing to do but update our buffer...
		buf[ i ] = x;

		return ( max+min ) / 2.0;
	}
If provided a value, the accumulator function returns an updated mid-range. If not provided a value, the accumulator function returns the current mid-range.

@private
@param {number} [x] - input value
@returns {(number|null)} mid-range or null