src/stringProcessing/specialCharacterMappings.js
function replaceTurkishIs( text ) {
	// Get indices of all occurrences of İ, I, i, or ı.
	const indicesOfAllIs = getIndicesOfCharacter( text, "İ" ).concat(
		getIndicesOfCharacter( text, "I" ),
		getIndicesOfCharacter( text, "i" ),
		getIndicesOfCharacter( text, "ı" )
	);
	indicesOfAllIs.sort();

	// If there are no Is return the text
	if ( indicesOfAllIs.length === 0 ) {
		return [ text ];
	}
	const indicesOfIsInWordBeginnings = arraysOverlap( getIndicesOfWords( text ), indicesOfAllIs );

	const results = [];

	// First round of creating combinations: assign which indices will be replaced by İ
	const combinationsDottedI = combinations( indicesOfIsInWordBeginnings );

	combinationsDottedI.forEach( function( oneCombinationDottedI ) {
		// If the combination is full array, just add it to results immediately without going through the rest of iterations.
		if ( oneCombinationDottedI === indicesOfIsInWordBeginnings ) {
			results.push( [ oneCombinationDottedI, [], [], [] ] );
		} else {
			const indicesNotDottedI = arraysDifference( indicesOfIsInWordBeginnings, oneCombinationDottedI );

			// Second round of creating combinations: assign which indices will be replaced by I
			const combinationsDotlessI = combinations( indicesNotDottedI );
			combinationsDotlessI.forEach( function( oneCombinationDotlessI ) {
				// If the combination is full array, just add it to results immediately without going through the rest of iterations.
				if ( oneCombinationDotlessI === indicesNotDottedI ) {
					results.push( [ oneCombinationDottedI, oneCombinationDotlessI, [], [] ] );
				} else {
					const indicesSmalli = arraysDifference( indicesNotDottedI, oneCombinationDotlessI );

					// Third round of creating combinations: assign which indices will be replaced by i
					const combinationsDottedi = combinations( indicesSmalli );

					combinationsDottedi.forEach( function( oneCombinationDottedi ) {
						// If the combination is full array, just add it to results immediately without going through the rest of iterations.
						if ( oneCombinationDottedi === indicesSmalli ) {
							results.push( [ oneCombinationDottedI, oneCombinationDotlessI, oneCombinationDottedi, [] ] );
						} else {
							const oneCombinationDotlessi = arraysDifference( indicesSmalli, oneCombinationDottedi );

							results.push( [ oneCombinationDottedI, oneCombinationDotlessI, oneCombinationDottedi, oneCombinationDotlessi ] );
						}
					} );
				}
			} );
		}
	} );

	const textAlternations = [];

	results.forEach( function( result ) {
		const toDottedI = replaceCharactersByIndex( text, result[ 0 ], "İ" );
		const toDotlessI = replaceCharactersByIndex( toDottedI, result[ 1 ], "I" );
		const toDottedi = replaceCharactersByIndex( toDotlessI, result[ 2 ], "i" );
		const toDotlessi = replaceCharactersByIndex( toDottedi, result[ 3 ], "ı" );
		textAlternations.push( toDotlessi );
	} );

	return textAlternations;
}
function replaceTurkishIs( text ) {
	// Get indices of all occurrences of İ, I, i, or ı.
	const indicesOfAllIs = getIndicesOfCharacter( text, "İ" ).concat(
		getIndicesOfCharacter( text, "I" ),
		getIndicesOfCharacter( text, "i" ),
		getIndicesOfCharacter( text, "ı" )
	);
	indicesOfAllIs.sort();

	// If there are no Is return the text
	if ( indicesOfAllIs.length === 0 ) {
		return [ text ];
	}
	const indicesOfIsInWordBeginnings = arraysOverlap( getIndicesOfWords( text ), indicesOfAllIs );

	const results = [];

	// First round of creating combinations: assign which indices will be replaced by İ
	const combinationsDottedI = combinations( indicesOfIsInWordBeginnings );

	combinationsDottedI.forEach( function( oneCombinationDottedI ) {
		// If the combination is full array, just add it to results immediately without going through the rest of iterations.
		if ( oneCombinationDottedI === indicesOfIsInWordBeginnings ) {
			results.push( [ oneCombinationDottedI, [], [], [] ] );
		} else {
			const indicesNotDottedI = arraysDifference( indicesOfIsInWordBeginnings, oneCombinationDottedI );

			// Second round of creating combinations: assign which indices will be replaced by I
			const combinationsDotlessI = combinations( indicesNotDottedI );
			combinationsDotlessI.forEach( function( oneCombinationDotlessI ) {
				// If the combination is full array, just add it to results immediately without going through the rest of iterations.
				if ( oneCombinationDotlessI === indicesNotDottedI ) {
					results.push( [ oneCombinationDottedI, oneCombinationDotlessI, [], [] ] );
				} else {
					const indicesSmalli = arraysDifference( indicesNotDottedI, oneCombinationDotlessI );

					// Third round of creating combinations: assign which indices will be replaced by i
					const combinationsDottedi = combinations( indicesSmalli );

					combinationsDottedi.forEach( function( oneCombinationDottedi ) {
						// If the combination is full array, just add it to results immediately without going through the rest of iterations.
						if ( oneCombinationDottedi === indicesSmalli ) {
							results.push( [ oneCombinationDottedI, oneCombinationDotlessI, oneCombinationDottedi, [] ] );
						} else {
							const oneCombinationDotlessi = arraysDifference( indicesSmalli, oneCombinationDottedi );

							results.push( [ oneCombinationDottedI, oneCombinationDotlessI, oneCombinationDottedi, oneCombinationDotlessi ] );
						}
					} );
				}
			} );
		}
	} );

	const textAlternations = [];

	results.forEach( function( result ) {
		const toDottedI = replaceCharactersByIndex( text, result[ 0 ], "İ" );
		const toDotlessI = replaceCharactersByIndex( toDottedI, result[ 1 ], "I" );
		const toDottedi = replaceCharactersByIndex( toDotlessI, result[ 2 ], "i" );
		const toDotlessi = replaceCharactersByIndex( toDottedi, result[ 3 ], "ı" );
		textAlternations.push( toDotlessi );
	} );

	return textAlternations;
}
Generates upper and lower case for Turkish strings that contain characters İ or ı, which appear to not be processed correctly by regexes.

@param {string} text The text to build possible upper and lower case alternatives.

@returns {Array} An array of strings that contains all possible upper and lower case alternatives of the original string