Computing Levenshtein distance to guess a main file.
Based on https://github.com/curist/grunt-bower

@param {String} componentName Component name.
@param {Array} files List of all possible main files.
@return {String}
763350
function guessBestFile(componentName, files) {
			var minDist = 1e13;
			var minDistIndex = -1;

			files.sort(function(a, b) {
				// Reverse order by path length
				return b.length - a.length;
			});

			files.forEach(function(filepath, i) {
				var filename = path.basename(filepath, '.js');
				var dist = _.str.levenshtein(componentName, filename);
				if (dist <= minDist) {
					minDist = dist;
					minDistIndex = i;
				}
			});

			if (minDistIndex !== -1) {
				return files[minDistIndex];
			}
			else {
				return undefined;
			}
		}
1251938
function resolve(name, workdir) {
	workdir = workdir || process.cwd();
	var compName = componentName(name),
		subname = name.substring(compName.length + 1),
		basedir = path.join(componentsHome(workdir), compName),
		bowerJson = require(path.join(basedir, 'bower.json'));

	var mainfile = Array.isArray(bowerJson.main) 
		? bowerJson.main.filter(function(file) { return /\.js$/.test(file); })[0] 
		: bowerJson.main;

	if (subname && subname.length > 0) {
		var subpath = mainfile && path.join(basedir, mainfile, '..', subname);
		if (subpath && (fs.existsSync(subpath) || fs.existsSync(subpath + '.js'))) {
			return path.join(basedir, mainfile, '..', subname);
		} else {
			return path.join(basedir, subname);
		}
	} else {
		if (mainfile) {
			return path.join(basedir, mainfile);
		}	else {
			if (fs.existsSync(path.join(basedir, "index.js"))) {
				return path.join(basedir, "index.js");
			} else {
				return path.join(basedir, compName);
			}
		}
	}
}
1246277
function getRelative(filename) {
    var parsed = chek_1.isString(filename) ? getParsed(filename) : filename;
    return path_1.relative(exports.cwd, path_1.join(parsed.dir, parsed.base || ''));
}
180977
function (fileName) {
            var dir;
            if (currDirRegExp.test(fileName)) {
                dir = frontSlash(location.href);
                if (dir.indexOf('/') !== -1) {
                    dir = dir.split('/');

                    //Pull off protocol and host, just want
                    //to allow paths (other build parts, like
                    //require._isSupportedBuildUrl do not support
                    //full URLs), but a full path from
                    //the root.
                    dir.splice(0, 3);

                    dir.pop();
                    dir = '/' + dir.join('/');
                }

                fileName = dir + fileName.substring(1);
            }

            return fileName;
        }
875601
function ( file ) {
			var resolved;
			var expanded = grunt.file.expand( file )[0];

			if ( !expanded ) {
				resolved = require.resolve( file );

			} else {
				resolved = "./" + expanded;
			}

			return resolved;
		}
1180552
function resolveComponent (file) {
  // make sure relative paths resolved to somewhere inside veui
  let pkg = pkgDir.sync(file)
  if (!pkg || getJSON(path.join(pkg, 'package.json')).name !== 'veui') {
    return null
  }

  // veui/${dir} or veui/src/${dir}
  let dirPath = path.join(pkg, COMPONENTS_DIRNAME) // runtime
  if (!fs.existsSync(dirPath)) {
    dirPath = path.join(pkg, 'src', COMPONENTS_DIRNAME) // dev
    if (!fs.existsSync(dirPath)) {
      return null
    }
  }

  // is VEUI component
  return getComponentName(path.relative(dirPath, file))
}
900858
function getComponentPath (componentName) {
  let entry = COMPONENTS.find(({ name }) => name === componentName)
  if (!entry) {
    return null
  }
  return `veui/${COMPONENTS_DIRNAME}/${entry.path}`
}
1162993
function (fileName) {
            if (!file.exists(fileName)) {
                try {
                    //Try to find the path of the file thanks to node's require resolving.
                    fileName = nodeRequire.resolve(fileName);
                } catch(e) {}
            }
            return frontSlash(path.normalize(frontSlash(fs.realpathSync(fileName))));
        }
588197
function updateServicesJS(newFileName) {

  console.log(" 🔰  updating: ".cyan + "components.js".white);

  if (process.cwd().includes('client/app/services') === false) {
    process.chdir(`./client/app/services`);
  }

  if (process.cwd().includes(`client/app/services/${newFileName}`) === true) {
    process.chdir('..');
  }

  componentsArray = [];
  genArr = [];


  // sync with updates
  fs.readdir(process.cwd(), function (err, items) {
    genArr = items;
    generateDirectArray(genArr);
  });


  function generateDirectArray(items) {
    for (var i = 0; i < items.length; i++) {
      if (isDirectory(items[i])) {
      } else {
        componentsArray.push(items[i]);
      }
    }
    importStringGenerator();
  }

  function isDirectory(inputString) {
    var str = inputString;
    var patt = new RegExp("[.]");
    var res = patt.test(str);
    return res;
  }

  function importStringGenerator() {

    genString = "";
    for (var i = 0; i < componentsArray.length; i++) {
      genString = genString + `import ${componentsArray[i]}Service from './${componentsArray[i]}/${componentsArray[i]}';\r`
    }

    listString = "";
    for (var i = 0; i < componentsArray.length; i++) {

      // check if last in list in order to not include comma
      if (i === (componentsArray.length - 1)) {
        listString = listString + `  .service('${componentsArray[i]}Service', ${componentsArray[i]}Service);` + `\r`
      } else {
        listString = listString + `  .service('${componentsArray[i]}Service', ${componentsArray[i]}Service)` + `\r`
      }
    }


    fs.writeFile("services.js", `import angular from 'angular';
${genString}

const ServicesModule = angular.module('app.services', [])
${listString}

export default ServicesModule;`, function (err) {
      if (err) {
        return console.log(` ❌  failed to update due to error:  ${err}`);
      }
      console.log(" 🔰  updated: ".cyan + "services.js".white);
    });
  }
}
678848
function includedFile(fileName) {
            var relativePath = fileName.substring(appDir.length + 1);
            var result = false;
            for (var i = 0; i < onlyIncludeList.length; i++) {
                var prefix = onlyIncludeList[i];
                if (relativePath.indexOf(prefix) === 0) {
                    result = true;
                    break;
                }
            }
            return result;
        }
346576
function getComponent (name) {
    // get component
    var component = global().components[name]
    // throw error if note defined
    this.assert(defined(component), 103, `${name} component not defined`)
    // return component
    return component
}
452261
function getCommonPathBase( paths ) {

		var list = [];
		var minLength = 999999999;

		var commonPath = "";

		//break up paths into parts
		paths.forEach( function( file ) {

			//normalize path seperators
			file = file.replace( pathSepRegExp, path.sep );

			//get resolved path parts for file directory
			if ( file.charAt(0) === path.sep ){
				file = file.substr(1);
			}
			//console.log("   "+file);
			//console.log("   "+path.dirname( file ));
			var dirname = path.dirname( file );
			var parts = dirname === "." ? [] : dirname.split( path.sep );
			list.push( parts );

			//save minimum path length for next step
			minLength = Math.min( minLength, parts.length );

		} );

		var listLength = list.length;

		grunt.verbose.writeln( JSON.stringify( list, undefined, "   ") );
		//check for common parts
		if ( listLength > 1 ) {
			var common = true;
			var index = -1;

			//iterate parts up to minLength
			for ( var i = 0; i < minLength; i++ ) {

				for ( var j = 1; j < listLength; j++ ) {
					if ( list[ j ][ i ] !== list[ j - 1 ][ i ] ) {
						common = false;
						break;
					}
				}

				if ( !common ) {
					index = i;
					break;
				}
			}
			//catch case where all paths are common
			if ( index < 0 ){
				index = minLength;
			}

			//build new paths array
			//for ( var n=0; n<listLength; n++ ) {
			//	newPaths.push( path.join( list[n].slice( index ) ) );
			//}

			commonPath = list[0].slice( 0, index ).join( path.sep );

		}
		else if ( listLength === 1 ) {
			commonPath = list[0].join( path.sep );
		}

		return commonPath;

	}
311699
function getComponentsWithExamples(root) {
    const componentsPath = `${__dirname}/../${root}/components`;
    return fs.readdirSync(componentsPath).map(component => ({
        name: component,
        sources: [`${componentsPath}/${component}`, `${componentsPath}/${component}/examples`]
    })).filter(isDirectory).map(obj => obj.name);
}
737933
function getComponents() {
	var results = [];

	if (extensions && extensions.hasOwnProperty('components')) {
		var sourceArray = extensions.components;

		for (index = 0; index < sourceArray.length; ++index) {
		    results.push(sourceArray[index]);
		}
	}

	return results;
}
218508
function(props) {
        var files = {};
        // Include all template files by default.
        helpers.expand({filter: 'isFile', dot: true}, [pathPrefix + '**']).forEach(function(obj) {
          // Get the source filepath relative to the template root.
          var src = obj.rel.slice(pathPrefix.length);
          // Get the destination filepath.
          var dest = init.renames[src];
          // Create a property for this file, but use src if dest evaulates
          // to false
          var processed = (dest) ? grunt.template.process(dest, {data: props, delimiters: 'init'}) : false;
          processed = (processed === 'false' || processed === '') ? false : processed;
          files[(processed) ? processed : src] = obj.rel;
        });
        // Exclude files with a value of false in rename.json.
        var exclusions = Object.keys(init.renames).filter(function(key) {
          var processed = (init.renames[key]) ? 
            grunt.template.process(init.renames[key], {data: props, delimiters: 'init'}) : false;
          processed = (processed === 'false' || processed === '') ? false : processed;
          return (processed === false);
        }).map(function(key) {
          return pathPrefix + key;
        });
        // Exclude all exclusion files by deleting them from the files object.
        if (exclusions.length > 0) {
          helpers.expand({filter: 'isFile', dot: true}, exclusions).forEach(function(obj) {
            // Get the source filepath relative to the template root.
            var src = obj.rel.slice(pathPrefix.length);
            // And remove that file from the files list.
            delete files[src];
          });
        }
        return files;
      }
458497
function updateComponentsJS(newFileName) {

  console.log(" 🔰  updating: ".cyan + "components.js".white);

  if (process.cwd().includes('client/app/components') === false) {
    process.chdir(`./client/app/components`);
  }

  componentsArray = [];
  genArr = [];


  // sync app.component with updates
  fs.readdir(process.cwd(), function (err, items) {
    genArr = items;
    generateDirectArray(genArr);
  });


  function generateDirectArray(items) {
    for (var i = 0; i < items.length; i++) {
      if (isDirectory(items[i])) {
      } else {
        componentsArray.push(items[i]);
      }
    }
    importStringGenerator();
  }

  function isDirectory(inputString) {
    var str = inputString;
    var patt = new RegExp("[.]");
    var res = patt.test(str);
    return res;
  }

  String.prototype.capitalizeFirstLetter = function () {
    return this.charAt(0).toUpperCase() + this.slice(1);
  }

  function importStringGenerator() {
    if (typeof newFileName != 'undefined') {
      componentsArray.push(`${newFileName}`);
    }

    genString = "";
    for (var i = 0; i < componentsArray.length; i++) {
      genString = genString + `    import ${componentsArray[i].capitalizeFirstLetter()}Module from './${componentsArray[i]}/${componentsArray[i]}.module';\r`
    }
    listString = "";
    for (var i = 0; i < componentsArray.length; i++) {

      // check if last in list in order to not include comma
      if (i === (componentsArray.length - 1)) {
        listString = listString + `     ${componentsArray[i].capitalizeFirstLetter()}Module` + `.name \r`
      } else {
        listString = listString + `     ${componentsArray[i].capitalizeFirstLetter()}Module` + '.name, \r'
      }

    }


    fs.writeFile("components.js", `import angular from 'angular';
${genString}

const ComponentsModule = angular.module('app.components',[
  ${listString}
]);

export default ComponentsModule;

  `, function (err) {
      if (err) {
        return console.log(` ❌  failed to update due to error:  ${err}`);
      }
      console.log(" 🔰  updated: ".cyan + "components.js".white);
    });
  }
}
306835
function getProjectName(componentPath, optionsName){
		if (typeof optionsName == 'string') return optionsName;
		var projectName;
		for (var prj in optionsName){
			if(~componentPath.indexOf(optionsName[prj])) projectName = prj;
		}
		if (!projectName) grunt.fail.warn('Missing name in options for component with path: ' + componentPath);
		return projectName;
	}