text: /**
   * @license
   * Copyright 2018 Google LLC
   * SPDX-License-Identifier: Apache-2.0
   */
  
  /**
   * @fileoverview Gulp tasks to complete various clean up tasks.
   */
  
  const gulp = require('gulp');
  const path = require('path');
  const through2 = require('through2');
  
  /**
   * Sorts goog.requires in core, blocks and generators.
   */
  function sortRequires() {
    const srcs = ['core/**/**/*.js', 'blocks/*.js', 'generators/**/*.js'];
    const excludes = ['core/requires.js'];
    return gulp.src(srcs, {base: './'})
        .pipe(through2.obj((file, _enc, next) => {
          if (file.isNull() || file.isDirectory()) {
            next(null, file);
            return;
          }
  
          if (file.extname !== '.js' && path.extname(file.history[0]) !== '.js') {
            next(null, file);
            return;
          }
  
          const relPath = path.relative(path.join(file.cwd, file.base), file.path);
          if (excludes.indexOf(relPath) > -1) {
            next(null, file);
            return;
          }
  
          const contents = file.contents.toString();
  
          // Capture requires.
          const re = /goog\.(require|requireType)\('(.*)'\);/gm;
          const requiresList = [];
          const requireTypesList = [];
          let firstIndex;
          let lastIndex;
          while ((match = re.exec(contents)) != null) {
            if (match[1] == 'require') requiresList.push(match[2]);
            if (match[1] == 'requireType') requireTypesList.push(match[2]);
            if (firstIndex == undefined) {
              firstIndex = match.index;
            } else {
              lastIndex = re.lastIndex;
            }
          }
  
          // Sort requires.
          requiresList.sort(
              (a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
          requireTypesList.sort(
              (a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
  
          // Replace in file.
          const requiresSection = requiresList.length ?
              requiresList.map(r => `goog.require('${r}');`).join('\n') + '\n\n' :
              '';
          const requireTypesSection = requireTypesList.length ?
              requireTypesList.map(r => `goog.requireType('${r}');`).join('\n') +
                  '\n\n' :
              '';
          const requires = `${requiresSection}${requireTypesSection}\n`;
  
          if (firstIndex != undefined & lastIndex != undefined) {
            file.contents = Buffer.from(
                contents.substring(0, firstIndex) + requires +
                contents.substring(lastIndex).trimStart());
          }
          next(null, file);
        }))
        .pipe(gulp.dest('./'));
  };
  
  module.exports = {
    sortRequires: sortRequires
  };
  