function flattenArray( arr, options ) {
	var opts;
	var err;
	var out;
	if ( !isArrayLikeObject( arr ) ) {
		throw new TypeError( format( 'invalid argument. First argument must be an array-like object. Value: `%s`.', arr ) );
	}
	opts = {
		'copy': defaults.copy,
		'depth': defaults.depth
	};
	if ( arguments.length > 1 ) {
		err = validate( opts, options );
		if ( err ) {
			throw err;
		}
	}
	if ( opts.depth === 0 ) {
		out = arr;
	} else {
		out = recurse( [], arr, opts.depth );
	}
	if ( opts.copy ) {
		return copy( out );
	}
	return out;
}
Flattens an array.

@param {ArrayLikeObject} arr - input array
@param {Options} [options] - function options
@param {NonNegativeInteger} [options.depth] - maximum depth to flatten
@param {boolean} [options.copy=false] - boolean indicating whether to deep copy array elements
@throws {TypeError} first argument must be an array-like object
@throws {TypeError} options argument must be an object
@throws {TypeError} must provide valid options
@returns {Array} flattened array

@example
var arr = [ 1, [2, [3, [4, [ 5 ], 6], 7], 8], 9 ];

var out = flattenArray( arr );
// returns [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]