text: /*---------------------------------------------------------------------------------------------
   *  Copyright (c) Microsoft Corporation. All rights reserved.
   *  Licensed under the MIT License. See License.txt in the project root for license information.
   *--------------------------------------------------------------------------------------------*/
  'use strict';
  Object.defineProperty(exports, "__esModule", { value: true });
  const es = require("event-stream");
  const debounce = require("debounce");
  const _filter = require("gulp-filter");
  const rename = require("gulp-rename");
  const path = require("path");
  const fs = require("fs");
  const _rimraf = require("rimraf");
  const git = require("./git");
  const VinylFile = require("vinyl");
  const NoCancellationToken = { isCancellationRequested: () => false };
  function incremental(streamProvider, initial, supportsCancellation) {
      const input = es.through();
      const output = es.through();
      let state = 'idle';
      let buffer = Object.create(null);
      const token = !supportsCancellation ? undefined : { isCancellationRequested: () => Object.keys(buffer).length > 0 };
      const run = (input, isCancellable) => {
          state = 'running';
          const stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
          input
              .pipe(stream)
              .pipe(es.through(undefined, () => {
              state = 'idle';
              eventuallyRun();
          }))
              .pipe(output);
      };
      if (initial) {
          run(initial, false);
      }
      const eventuallyRun = debounce(() => {
          const paths = Object.keys(buffer);
          if (paths.length === 0) {
              return;
          }
          const data = paths.map(path => buffer[path]);
          buffer = Object.create(null);
          run(es.readArray(data), true);
      }, 500);
      input.on('data', (f) => {
          buffer[f.path] = f;
          if (state === 'idle') {
              eventuallyRun();
          }
      });
      return es.duplex(input, output);
  }
  exports.incremental = incremental;
  function fixWin32DirectoryPermissions() {
      if (!/win32/.test(process.platform)) {
          return es.through();
      }
      return es.mapSync(f => {
          if (f.stat && f.stat.isDirectory && f.stat.isDirectory()) {
              f.stat.mode = 16877;
          }
          return f;
      });
  }
  exports.fixWin32DirectoryPermissions = fixWin32DirectoryPermissions;
  function setExecutableBit(pattern) {
      const setBit = es.mapSync(f => {
          if (!f.stat) {
              f.stat = { isFile() { return true; } };
          }
          f.stat.mode = /* 100755 */ 33261;
          return f;
      });
      if (!pattern) {
          return setBit;
      }
      const input = es.through();
      const filter = _filter(pattern, { restore: true });
      const output = input
          .pipe(filter)
          .pipe(setBit)
          .pipe(filter.restore);
      return es.duplex(input, output);
  }
  exports.setExecutableBit = setExecutableBit;
  function toFileUri(filePath) {
      const match = filePath.match(/^([a-z])\:(.*)$/i);
      if (match) {
          filePath = '/' + match[1].toUpperCase() + ':' + match[2];
      }
      return 'file://' + filePath.replace(/\\/g, '/');
  }
  exports.toFileUri = toFileUri;
  function skipDirectories() {
      return es.mapSync(f => {
          if (!f.isDirectory()) {
              return f;
          }
      });
  }
  exports.skipDirectories = skipDirectories;
  function cleanNodeModules(rulePath) {
      const rules = fs.readFileSync(rulePath, 'utf8')
          .split(/\r?\n/g)
          .map(line => line.trim())
          .filter(line => line && !/^#/.test(line));
      const excludes = rules.filter(line => !/^!/.test(line)).map(line => `!**/node_modules/${line}`);
      const includes = rules.filter(line => /^!/.test(line)).map(line => `**/node_modules/${line.substr(1)}`);
      const input = es.through();
      const output = es.merge(input.pipe(_filter(['**', ...excludes])), input.pipe(_filter(includes)));
      return es.duplex(input, output);
  }
  exports.cleanNodeModules = cleanNodeModules;
  function loadSourcemaps() {
      const input = es.through();
      const output = input
          .pipe(es.map((f, cb) => {
          if (f.sourceMap) {
              cb(undefined, f);
              return;
          }
          if (!f.contents) {
              cb(new Error('empty file'));
              return;
          }
          const contents = f.contents.toString('utf8');
          const reg = /\/\/# sourceMappingURL=(.*)$/g;
          let lastMatch = null;
          let match = null;
          while (match = reg.exec(contents)) {
              lastMatch = match;
          }
          if (!lastMatch) {
              f.sourceMap = {
                  version: '3',
                  names: [],
                  mappings: '',
                  sources: [f.relative.replace(/\//g, '/')],
                  sourcesContent: [contents]
              };
              cb(undefined, f);
              return;
          }
          f.contents = Buffer.from(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
          fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', (err, contents) => {
              if (err) {
                  return cb(err);
              }
              f.sourceMap = JSON.parse(contents);
              cb(undefined, f);
          });
      }));
      return es.duplex(input, output);
  }
  exports.loadSourcemaps = loadSourcemaps;
  function stripSourceMappingURL() {
      const input = es.through();
      const output = input
          .pipe(es.mapSync(f => {
          const contents = f.contents.toString('utf8');
          f.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
          return f;
      }));
      return es.duplex(input, output);
  }
  exports.stripSourceMappingURL = stripSourceMappingURL;
  function rimraf(dir) {
      let retries = 0;
      const retry = (cb) => {
          _rimraf(dir, { maxBusyTries: 1 }, (err) => {
              if (!err) {
                  return cb();
              }
              if (err.code === 'ENOTEMPTY' && ++retries < 5) {
                  return setTimeout(() => retry(cb), 10);
              }
              return cb(err);
          });
      };
      retry.taskName = `clean-${path.basename(dir).toLowerCase()}`;
      return retry;
  }
  exports.rimraf = rimraf;
  function getVersion(root) {
      let version = process.env['BUILD_SOURCEVERSION'];
      if (!version || !/^[0-9a-f]{40}$/i.test(version)) {
          version = git.getVersion(root);
      }
      return version;
  }
  exports.getVersion = getVersion;
  function rebase(count) {
      return rename(f => {
          const parts = f.dirname ? f.dirname.split(/[\/\\]/) : [];
          f.dirname = parts.slice(count).join(path.sep);
      });
  }
  exports.rebase = rebase;
  function filter(fn) {
      const result = es.through(function (data) {
          if (fn(data)) {
              this.emit('data', data);
          }
          else {
              result.restore.push(data);
          }
      });
      result.restore = es.through();
      return result;
  }
  exports.filter = filter;
  function versionStringToNumber(versionStr) {
      const semverRegex = /(\d+)\.(\d+)\.(\d+)/;
      const match = versionStr.match(semverRegex);
      if (!match) {
          throw new Error('Version string is not properly formatted: ' + versionStr);
      }
      return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10);
  }
  exports.versionStringToNumber = versionStringToNumber;
  