function iterReplicateBy( iterator, fcn, thisArg ) {
	var value;
	var iter;
	var FLG;
	var t;
	var n;
	var i;
	var j;
	if ( !isIteratorLike( iterator ) ) {
		throw new TypeError( format( 'invalid argument. First argument must be an iterator protocol-compliant object. Value: `%s`.', iterator ) );
	}
	if ( !isFunction( fcn ) ) {
		throw new TypeError( format( 'invalid argument. Second argument must be a function. Value: `%s`.', fcn ) );
	}
	t = -1; // total iteration index
	i = -1; // replicate counter
	j = -1; // source iteration index
	n = 0;  // number of replicates

	// Create an iterator protocol-compliant object:
	iter = {};
	setReadOnly( iter, 'next', next );
	setReadOnly( iter, 'return', end );

	// If an environment supports `Symbol.iterator` and a provided iterator is iterable, make the iterator iterable:
	if ( iteratorSymbol && isFunction( iterator[ iteratorSymbol ] ) ) {
		setReadOnly( iter, iteratorSymbol, factory );
	}
	return iter;

	/**
	* Returns an iterator protocol-compliant object containing the next iterated value.
	*
	* @private
	* @throws {TypeError} callback function must return an integer
	* @returns {Object} iterator protocol-compliant object
	*/
	function next() {
		var v;
		if ( FLG ) {
			return {
				'done': true
			};
		}
		while ( true ) {
			t += 1;
			i += 1;
			if ( i >= n ) {
				v = iterator.next();
				if ( v.done ) {
					FLG = true;
					return v;
				}
				value = v.value; // cache value
				j += 1;
				n = fcn.call( thisArg, value, j, t );
				if ( !isInteger( n ) ) {
					throw new TypeError( format( 'invalid return value. Callback function must return an integer. Value: `%s`.', n ) );
				}
				i = 0; // reset the counter
				if ( n > 0 ) {
					// Return the newly cached value...
					break;
				}
			} else {
				// Return the cached value...
				break;
			}
		}
		return {
			'value': value,
			'done': false
		};
	}

	/**
	* Finishes an iterator.
	*
	* @private
	* @param {*} [value] - value to return
	* @returns {Object} iterator protocol-compliant object
	*/
	function end( value ) {
		FLG = true;
		if ( arguments.length ) {
			return {
				'value': value,
				'done': true
			};
		}
		return {
			'done': true
		};
	}

	/**
	* Returns a new iterator.
	*
	* @private
	* @returns {Iterator} iterator
	*/
	function factory() {
		return iterReplicateBy( iterator[ iteratorSymbol ](), fcn, thisArg );
	}
}
Returns an iterator which replicates each iterated value according to a provided function.

@param {Iterator} iterator - input iterator
@param {Function} fcn - function which specifies how many times to replicate an iterated value
@param {*} [thisArg] - callback function execution context
@throws {TypeError} first argument must be an iterator protocol-compliant object
@throws {TypeError} second argument must be a function
@returns {Iterator} iterator

@example
var array2iterator = require( '@stdlib/array/to-iterator' );

function fcn( v, i ) {
    return i + 1;
}

var src = array2iterator( [ 1, 2, 3, 4 ] );
var iter = iterReplicateBy( src, fcn );

var v = iter.next().value;
// returns 1

v = iter.next().value;
// returns 2

v = iter.next().value;
// returns 2

v = iter.next().value;
// returns 3

v = iter.next().value;
// returns 3

v = iter.next().value;
// returns 3