function searchForKeywords(classNamesAndProbs, filePaths, targetWords) {
   // Filter through the output class names and probilities to look for
  // matches.
  const foundItems = [];
  for (let i = 0; i < classNamesAndProbs.length; ++i) {
    const namesAndProbs = classNamesAndProbs[i];
    let matchWord = null;
    for (const nameAndProb of namesAndProbs) {
      const classTokens = nameAndProb.className.toLowerCase().trim()
          .replace(/[,\/]/g, ' ')
          .split(' ').filter(x => x.length > 0);
      for (const word of targetWords) {
        if (classTokens.indexOf(word) !== -1) {
          matchWord = word;
          break;
        }
      }
      if (matchWord != null) {
        break;
      }
    }
    if (matchWord != null) {
      foundItems.push({
        filePath: filePaths[i],
        matchWord,
        topClasses: namesAndProbs,
      });
    }
  }
  return foundItems;
}
Search for target words in an array of class names and corresponding
probabilities.

This search is necessary because the class names output by the
TensorFlow.js model are not isolated English words, instead they long
phrases such as "tiger shark, Galeocerdo cuvieri". We need to break
these labels into words and match them against the target words
provided by the app's user (e.g., "shark").

@param {Array<{className: string, prob: number}>} classNamesAndProbs
  An array of `N` classification results, each of which is an object
  mapping a class name (`className`) to a probability score (`prob`).
@param {string[]} The file paths of the image files. Must have the
  same length as `classNamesAndProbs`.
@param {string[]} targetWords An array of target words to search for
  in the results.
@returns {Array<{filePath: string, matchWord: string, topClasses: string}>}
  All matches to the target words.