<commit_before>// ID or URL of the Hosted Web App plugin - THIS SETTING WILL NEED TO BE UPDATED IF THE PLUGIN IS RELOCATED
var pluginIdOrUrl = require('ManifoldCordova'); //'https://github.com/manifoldjs/ManifoldCordova.git';

var manifestTools = require('./manifestTools'),
    path = require('path'),
    url = require('url'),
    exec = require('child_process').exec,
    fs = require('fs'),
    log = require('loglevel'),
    downloader = require('./projectBuilder/downloader'),
    Q = require('q'),
    mkdirp = require('mkdirp'),
    fileUtils = require('./common/fileUtils');

var mapToCordovaPlatform = function (platform) {
  if (platform.toUpperCase() === 'WINDOWSUNIVERSAL') {
    return 'windows';
  } else {
    return platform;
  }
};

var createPlatformShortcut = function (projectPath, platform, callback) {
  var srcpath = path.resolve(projectPath, 'cordova', 'platforms', mapToCordovaPlatform(platform));
  var dstpath = path.resolve(projectPath, platform);
  fs.symlink(srcpath, dstpath, 'junction', function (err) {
    if (callback) {
      callback(err);
    }
  });
};

var createChromeApp = function (w3cManifestInfo, generatedAppDir) {
  log.info('Generating the Chrome application...');

  var task = Q.defer();

  manifestTools.convertTo(w3cManifestInfo, 'chromeOS', function (err, chromeManifestInfo) {

    if (err) {
      log.error(err.message);
      return task.reject(new Error('The Chrome project could not be created successfully.'));
    }

    // if the platform dir doesn't exist, create it
    var platformDir = path.join(generatedAppDir, 'chrome');
    mkdirp(platformDir, function (err) {
      function createDownloaderImageCallback(downloadTask, icons, size) {
        return function (err, data) {
          if (err) {
            log.warn('WARNING: Failed to download icon file: ' + icons[size] + ' (' + err.message + ')');
            log.debug(err);
          } else {
            var localPath = path.basename(data.path);
            icons[size] = localPath;
          }

          downloadTask.resolve();
        };
      }

      if (err && err.code !== 'EEXIST') {
        log.error(err.message);
        return task.reject(new Error('The Chrome project could not be created successfully.'));
      }

      // download icons to the app's folder
      var pendingDownloads = [];
      log.info('Downloading Chrome icons...');
      var icons = chromeManifestInfo.content.icons;
      for (var size in icons) {
        var downloadTask = new Q.defer();
        pendingDownloads.push(downloadTask.promise);
        var iconUrl = url.resolve(w3cManifestInfo.content.start_url, icons[size]);
        downloader.downloadImage(iconUrl, platformDir, createDownloaderImageCallback(downloadTask, icons, size));
      }

      // copy the manifest file to the app folder
      Q.allSettled(pendingDownloads)
        .done(function () {
        log.info('Copying the Chrome manifest to the app folder...');
        var manifestFilePath = path.join(platformDir, 'manifest.json');
        manifestTools.writeToFile(chromeManifestInfo, manifestFilePath, function (err) {
          if (err) {
            log.error('ERROR: Failed to copy the manifest to the Chrome platform folder.');
            log.debug(err);
            return task.reject(new Error('The Chrome project could not be created successfully.'));
          }

          return task.resolve();
        });
      });
    });
  });

  return task.promise;
};

var createFirefoxApp = function (w3cManifestInfo, generatedAppDir) {
  log.info('Generating the Firefox application...');

  var task = Q.defer();

  manifestTools.convertTo(w3cManifestInfo, 'firefox', function (err, firefoxManifestInfo) {
    if (err) {
      log.error(err.message);
      return task.reject(new Error('The Firefox project could not be created successfully.'));
    }

    // if the platform dir doesn't exist, create it
    var platformDir = path.join(generatedAppDir, 'firefox');
    mkdirp(platformDir, function (err) {
      if (err && err.code !== 'EEXIST') {
        log.error(err.message);
        return task.reject(new Error('The Firefox project could not be created successfully.'));
      }

      // copy the manifest file to the app folder
      log.info('Copying the Firefox manifest to the app folder...');
      var manifestFilePath = path.join(platformDir, 'manifest.webapp');
      manifestTools.writeToFile(firefoxManifestInfo, manifestFilePath, function (err) {
        if (err) {
          log.error('ERROR: Failed to copy the manifest to the Firefox platform folder.');
          log.debug(err);
          return task.reject(new Error('The Firefox project could not be created successfully.'));
        }

        return task.resolve();
      });
    });
  });

  return task.promise;
};

var createWindowsApp = function (w3cManifestInfo, generatedAppDir) {
  log.info('Generating the Windows application...');

  var task = Q.defer();

  manifestTools.convertTo(w3cManifestInfo, 'windows10', function (err, windowsManifestInfo) {
    if (err) {
      log.error(err.message);
      return task.reject(new Error('The Windows project could not be created successfully.'));
    }

    // if the platform dir doesn't exist, create it
    var platformDir = path.join(generatedAppDir, 'windows');
    mkdirp(platformDir, function (err) {
      if (err && err.code !== 'EEXIST') {
        log.error(err.message);
        return task.reject(new Error('The Windows project could not be created successfully.'));
      }

      // download icons to the app's folder
      var pendingDownloads = [];
      log.info('Downloading Windows icons...');
      var icons = windowsManifestInfo.content.icons;

      function downloadIcon(size) {
        var downloadTask = new Q.defer();
        pendingDownloads.push(downloadTask.promise);
        var iconUrl = url.resolve(w3cManifestInfo.content.start_url, icons[size]);
        downloader.downloadImage(iconUrl, platformDir, function (err, data) {
          if (err) {
            log.warn('WARNING: Failed to download icon file: ' + icons[size] + ' (' + err.message + ')');
            log.debug(err);
          } else {
            var localPath = path.basename(data.path);
            windowsManifestInfo.content.rawData = windowsManifestInfo.content.rawData.replace(new RegExp(icons[size], 'g'), localPath);
          }

          downloadTask.resolve();
        });
      }

      for (var size in icons) {
        downloadIcon(size);
      }

      // copy the manifest file to the app folder
      Q.allSettled(pendingDownloads)
        .done(function () {
        log.info('Copying the Windows manifest to the app folder...');
        var manifestFilePath = path.join(platformDir, 'appxmanifest.xml');
        fs.writeFile(manifestFilePath, windowsManifestInfo.content.rawData, function (err) {
          if (err) {
            log.error('ERROR: Failed to copy the manifest to the Windows platform folder.');
            log.debug(err);
            return task.reject(new Error('The Windows project could not be created successfully.'));
          }

          return task.resolve();
        });
      });
    });
  });

  return task.promise;
};

var applyPlatformsFix = function (platform, platformDir, callback) {
  if (platform === 'android') {
    log.info('Applying fix for Android...');

    var assetsBasePath = path.join(__dirname, 'projectBuilder', 'assets', 'android');
    var targetBasePath = path.join(platformDir, 'platforms', 'android');

    var fixedBuildGradleFilePath = path.join(assetsBasePath, 'build.gradle');
    var buildGradleFilePath = path.join(targetBasePath, 'build.gradle');

    fileUtils.copyFile(fixedBuildGradleFilePath, buildGradleFilePath, function(err) {
      if (err) {
        return callback(err);
      }

      var settingsGradleFilePath = path.join(assetsBasePath, 'settings.gradle');
      var targetSettingsGradleFilePath = path.join(targetBasePath, 'settings.gradle');

      fileUtils.copyFile(settingsGradleFilePath, targetSettingsGradleFilePath, callback);
    });
  } else {
    callback();
  }
};

var createCordovaApp = function (w3cManifestInfo, generatedAppDir, platforms, build) {
  log.info('Generating the Cordova application...');

  var task = Q.defer();

  // path to cordova shell command
  var cordovaPath = path.resolve(__dirname, '..', 'node_modules', 'cordova', 'bin', 'cordova');

  // go to the directory where the app will be created
  process.chdir(generatedAppDir);

  // generate a reverse-domain-style package name from the manifest's start_url
  var packageName = '';
  url.parse(w3cManifestInfo.content.start_url)
            .hostname
            .replace(/-/g, '')
            .split('.')
            .map(function (segment) {
    packageName = segment + (packageName ? '.' : '') + packageName;
  });

  // create the Cordova project
  log.info('Creating the Cordova project...');
  var cmdLine = cordovaPath + ' create cordova ' + packageName + ' ' + w3cManifestInfo.content.short_name;
  log.debug('    ' + cmdLine);
  exec(cmdLine, function (err, stdout, stderr) {

    log.debug(stdout);
    if (err) {
      log.error('ERROR: Failed to create the Cordova application.');
      log.debug(err);
      return task.reject(new Error('The Cordova project could not be created successfully.\n' + err.message));
    } else if (stderr.length) {
      log.error(stderr.trim());
    }

    // copy the manifest file to the app folder
    log.info('Copying the W3C manifest to the app folder...');
    var platformDir = path.join(generatedAppDir, 'cordova');
    var manifestFilePath = path.join(platformDir, 'manifest.json');
    manifestTools.writeToFile(w3cManifestInfo, manifestFilePath, function (err) {

      log.debug(stdout);
      if (err) {
        log.error('ERROR: Failed to copy the manifest to the app folder.');
        log.debug(err);
        return task.reject(new Error('The Cordova project could not be created successfully.'));
      }

      // set generated app's directory as current
      process.chdir(platformDir);

      // add the Hosted Web App plugin
      log.info('Adding the Hosted Web App plugin to the Cordova project...');
      cmdLine = cordovaPath + ' plugin add ' + pluginIdOrUrl;
      log.debug('    ' + cmdLine);
      exec(cmdLine, function (err, stdout, stderr) {

        log.debug(stdout);
        if (err) {
          log.error('ERROR: Failed to add the Hosted Web App plugin to the Cordova project.');
          log.debug(err);
          return task.reject(new Error('The Cordova project could not be created successfully.'));
        } else if (stderr.length) {
          log.error(stderr.trim());
        }

        // process all the specified platforms
        var pendingTasks = [];
        platforms.forEach(function (platform) {
          log.info('Adding Cordova platform: ' + platform + '...');

          var platformTask = new Q.defer();
          pendingTasks.push(platformTask.promise);
          cmdLine = cordovaPath + ' platform add ' + mapToCordovaPlatform(platform);
          log.debug('    ' + cmdLine);
          exec(cmdLine, function (err, stdout, stderr) {

            log.debug(stdout);
            if (err) {
              log.warn('WARNING: Failed to add ' + platform + ' platform.');
              log.debug(err);
              return platformTask.reject(err);
            } else if (stderr.length) {
              log.error(stderr.trim());
            }

            applyPlatformsFix(platform, platformDir, function(err) {
              if (err) {
                log.warn('WARNING: Failed to apply platform fix: ' + platform + '.');
                log.debug(err);
                return platformTask.reject(err);
              } else if (stderr.length) {
                log.error(stderr.trim());
              }

              // set module directory as current (so that the generated folder can be deleted)
              var rootPath = path.join(__dirname, '..');
              process.chdir(rootPath);

              log.info('Creating shortcut for platform: ' + platform + '...');
              createPlatformShortcut(generatedAppDir, platform, function (err) {

                log.debug(stdout);
                if (err) {
                  log.warn('WARNING: Failed to create shortcut for platform: ' + platform + '.');
                  log.debug(err);
                }

                // build the platform-specific projects
                if (build) {
                  log.info('Building Cordova platform: ' + platform + '...');
                  cmdLine = cordovaPath + ' build ' + mapToCordovaPlatform(platform);
                  log.debug('    ' + cmdLine);
                  exec(cmdLine, function (err, stdout, stderr) {

                    log.debug(stdout);
                    if (err) {
                      log.warn('WARNING: Failed to build platform: ' + platform + '.');
                      log.debug(err);
                      return platformTask.reject(err);
                    } else if (stderr.length) {
                      log.error(stderr.trim());
                    }

                    platformTask.resolve();
                  });
                } else {
                  platformTask.resolve();
                }
              });
            });
          });
        });

        Q.allSettled(pendingTasks)
          .done(function (results) {
          if (results.some(function (platformTask) { return platformTask.state !== 'fulfilled'; })) {
            return task.reject(new Error('One or more tasks failed while generating the Cordova application.'));
          } else {
            return task.resolve();
          }
        });
      });
    });
  });

  return task.promise;
};

var createApps = function (w3cManifestInfo, rootDir, platforms, build, callback) {

  // determine the path where the Cordova app will be created
  var appName = w3cManifestInfo.content.short_name;
  var generatedAppDir = path.join(rootDir, appName);

  // create app directory
  mkdirp(generatedAppDir, function (err) {
    if (err && err.code !== 'EEXIST') {
      return callback(err);
    }

    // process all requested platforms
    var pendingTasks = [];
    var cordovaPlatforms = [];
    platforms.forEach(function (el) {
      var platform = el.toUpperCase();
      if (platform === 'CHROME') {
        pendingTasks.push(createChromeApp(w3cManifestInfo, generatedAppDir));
      } else if (platform === 'FIREFOX') {
        pendingTasks.push(createFirefoxApp(w3cManifestInfo, generatedAppDir));
      } else if (platform === 'WINDOWS') {
        pendingTasks.push(createWindowsApp(w3cManifestInfo, generatedAppDir));
      } else if (platform === 'WINDOWSUNIVERSAL' || platform === 'IOS' || platform === 'ANDROID') {
        // all these platforms are handled by Cordova
        cordovaPlatforms.push(el);
      } else {
        return callback(new Error('Unknown platform \'' + el + '\' specified.'));
      }
    });

    // generate Cordova project
    if (cordovaPlatforms.length) {
      pendingTasks.push(createCordovaApp(w3cManifestInfo, generatedAppDir, cordovaPlatforms, build));
    }

    Q.allSettled(pendingTasks)
    .done(function (results) {
      var err;
      results.forEach(function (task) {
        if (task.state !== 'fulfilled') {
          log.error('WARNING: ' + task.reason.message);
          if (!err) {
            err = new Error('One or more errors occurred when generating the application.');
          }
        }
      });

      if (callback) {
        callback(err);
      }
    });
  });
};

module.exports = {
  createApps: createApps,
  createChromeApp: createChromeApp,
  createFirefoxApp: createFirefoxApp,
  createWindowsApp: createWindowsApp,
  createCordovaApp: createCordovaApp,
};
<commit_msg>Minor improvement in logic used to change the working directory folder<commit_after>// ID or URL of the Hosted Web App plugin - THIS SETTING WILL NEED TO BE UPDATED IF THE PLUGIN IS RELOCATED
var pluginIdOrUrl = require('ManifoldCordova'); //'https://github.com/manifoldjs/ManifoldCordova.git';

var manifestTools = require('./manifestTools'),
    path = require('path'),
    url = require('url'),
    exec = require('child_process').exec,
    fs = require('fs'),
    log = require('loglevel'),
    downloader = require('./projectBuilder/downloader'),
    Q = require('q'),
    mkdirp = require('mkdirp'),
    fileUtils = require('./common/fileUtils');

var originalPath = process.cwd();

var mapToCordovaPlatform = function (platform) {
  if (platform.toUpperCase() === 'WINDOWSUNIVERSAL') {
    return 'windows';
  } else {
    return platform;
  }
};

var createPlatformShortcut = function (projectPath, platform, callback) {
  var srcpath = path.resolve(projectPath, 'cordova', 'platforms', mapToCordovaPlatform(platform));
  var dstpath = path.resolve(projectPath, platform);
  fs.symlink(srcpath, dstpath, 'junction', function (err) {
    if (callback) {
      callback(err);
    }
  });
};

var createChromeApp = function (w3cManifestInfo, generatedAppDir) {
  log.info('Generating the Chrome application...');

  var task = Q.defer();

  manifestTools.convertTo(w3cManifestInfo, 'chromeOS', function (err, chromeManifestInfo) {

    if (err) {
      log.error(err.message);
      return task.reject(new Error('The Chrome project could not be created successfully.'));
    }

    // if the platform dir doesn't exist, create it
    var platformDir = path.join(generatedAppDir, 'chrome');
    mkdirp(platformDir, function (err) {
      function createDownloaderImageCallback(downloadTask, icons, size) {
        return function (err, data) {
          if (err) {
            log.warn('WARNING: Failed to download icon file: ' + icons[size] + ' (' + err.message + ')');
            log.debug(err);
          } else {
            var localPath = path.basename(data.path);
            icons[size] = localPath;
          }

          downloadTask.resolve();
        };
      }

      if (err && err.code !== 'EEXIST') {
        log.error(err.message);
        return task.reject(new Error('The Chrome project could not be created successfully.'));
      }

      // download icons to the app's folder
      var pendingDownloads = [];
      log.info('Downloading Chrome icons...');
      var icons = chromeManifestInfo.content.icons;
      for (var size in icons) {
        var downloadTask = new Q.defer();
        pendingDownloads.push(downloadTask.promise);
        var iconUrl = url.resolve(w3cManifestInfo.content.start_url, icons[size]);
        downloader.downloadImage(iconUrl, platformDir, createDownloaderImageCallback(downloadTask, icons, size));
      }

      // copy the manifest file to the app folder
      Q.allSettled(pendingDownloads)
        .done(function () {
        log.info('Copying the Chrome manifest to the app folder...');
        var manifestFilePath = path.join(platformDir, 'manifest.json');
        manifestTools.writeToFile(chromeManifestInfo, manifestFilePath, function (err) {
          if (err) {
            log.error('ERROR: Failed to copy the manifest to the Chrome platform folder.');
            log.debug(err);
            return task.reject(new Error('The Chrome project could not be created successfully.'));
          }

          return task.resolve();
        });
      });
    });
  });

  return task.promise;
};

var createFirefoxApp = function (w3cManifestInfo, generatedAppDir) {
  log.info('Generating the Firefox application...');

  var task = Q.defer();

  manifestTools.convertTo(w3cManifestInfo, 'firefox', function (err, firefoxManifestInfo) {
    if (err) {
      log.error(err.message);
      return task.reject(new Error('The Firefox project could not be created successfully.'));
    }

    // if the platform dir doesn't exist, create it
    var platformDir = path.join(generatedAppDir, 'firefox');
    mkdirp(platformDir, function (err) {
      if (err && err.code !== 'EEXIST') {
        log.error(err.message);
        return task.reject(new Error('The Firefox project could not be created successfully.'));
      }

      // copy the manifest file to the app folder
      log.info('Copying the Firefox manifest to the app folder...');
      var manifestFilePath = path.join(platformDir, 'manifest.webapp');
      manifestTools.writeToFile(firefoxManifestInfo, manifestFilePath, function (err) {
        if (err) {
          log.error('ERROR: Failed to copy the manifest to the Firefox platform folder.');
          log.debug(err);
          return task.reject(new Error('The Firefox project could not be created successfully.'));
        }

        return task.resolve();
      });
    });
  });

  return task.promise;
};

var createWindowsApp = function (w3cManifestInfo, generatedAppDir) {
  log.info('Generating the Windows application...');

  var task = Q.defer();

  manifestTools.convertTo(w3cManifestInfo, 'windows10', function (err, windowsManifestInfo) {
    if (err) {
      log.error(err.message);
      return task.reject(new Error('The Windows project could not be created successfully.'));
    }

    // if the platform dir doesn't exist, create it
    var platformDir = path.join(generatedAppDir, 'windows');
    mkdirp(platformDir, function (err) {
      if (err && err.code !== 'EEXIST') {
        log.error(err.message);
        return task.reject(new Error('The Windows project could not be created successfully.'));
      }

      // download icons to the app's folder
      var pendingDownloads = [];
      log.info('Downloading Windows icons...');
      var icons = windowsManifestInfo.content.icons;

      function downloadIcon(size) {
        var downloadTask = new Q.defer();
        pendingDownloads.push(downloadTask.promise);
        var iconUrl = url.resolve(w3cManifestInfo.content.start_url, icons[size]);
        downloader.downloadImage(iconUrl, platformDir, function (err, data) {
          if (err) {
            log.warn('WARNING: Failed to download icon file: ' + icons[size] + ' (' + err.message + ')');
            log.debug(err);
          } else {
            var localPath = path.basename(data.path);
            windowsManifestInfo.content.rawData = windowsManifestInfo.content.rawData.replace(new RegExp(icons[size], 'g'), localPath);
          }

          downloadTask.resolve();
        });
      }

      for (var size in icons) {
        downloadIcon(size);
      }

      // copy the manifest file to the app folder
      Q.allSettled(pendingDownloads)
        .done(function () {
        log.info('Copying the Windows manifest to the app folder...');
        var manifestFilePath = path.join(platformDir, 'appxmanifest.xml');
        fs.writeFile(manifestFilePath, windowsManifestInfo.content.rawData, function (err) {
          if (err) {
            log.error('ERROR: Failed to copy the manifest to the Windows platform folder.');
            log.debug(err);
            return task.reject(new Error('The Windows project could not be created successfully.'));
          }

          return task.resolve();
        });
      });
    });
  });

  return task.promise;
};

var applyPlatformsFix = function (platform, platformDir, callback) {
  if (platform === 'android') {
    log.info('Applying fix for Android...');

    var assetsBasePath = path.join(__dirname, 'projectBuilder', 'assets', 'android');
    var targetBasePath = path.join(platformDir, 'platforms', 'android');

    var fixedBuildGradleFilePath = path.join(assetsBasePath, 'build.gradle');
    var buildGradleFilePath = path.join(targetBasePath, 'build.gradle');

    fileUtils.copyFile(fixedBuildGradleFilePath, buildGradleFilePath, function(err) {
      if (err) {
        return callback(err);
      }

      var settingsGradleFilePath = path.join(assetsBasePath, 'settings.gradle');
      var targetSettingsGradleFilePath = path.join(targetBasePath, 'settings.gradle');

      fileUtils.copyFile(settingsGradleFilePath, targetSettingsGradleFilePath, callback);
    });
  } else {
    callback();
  }
};

var createCordovaApp = function (w3cManifestInfo, generatedAppDir, platforms, build) {
  log.info('Generating the Cordova application...');

  var task = Q.defer();

  // path to cordova shell command
  var cordovaPath = path.resolve(__dirname, '..', 'node_modules', 'cordova', 'bin', 'cordova');

  // go to the directory where the app will be created
  process.chdir(generatedAppDir);

  // generate a reverse-domain-style package name from the manifest's start_url
  var packageName = '';
  url.parse(w3cManifestInfo.content.start_url)
            .hostname
            .replace(/-/g, '')
            .split('.')
            .map(function (segment) {
    packageName = segment + (packageName ? '.' : '') + packageName;
  });

  // create the Cordova project
  log.info('Creating the Cordova project...');
  var cmdLine = cordovaPath + ' create cordova ' + packageName + ' ' + w3cManifestInfo.content.short_name;
  log.debug('    ' + cmdLine);
  exec(cmdLine, function (err, stdout, stderr) {

    log.debug(stdout);
    if (err) {
      log.error('ERROR: Failed to create the Cordova application.');
      log.debug(err);
      return task.reject(new Error('The Cordova project could not be created successfully.\n' + err.message));
    } else if (stderr.length) {
      log.error(stderr.trim());
    }

    // copy the manifest file to the app folder
    log.info('Copying the W3C manifest to the app folder...');
    var platformDir = path.join(generatedAppDir, 'cordova');
    var manifestFilePath = path.join(platformDir, 'manifest.json');
    manifestTools.writeToFile(w3cManifestInfo, manifestFilePath, function (err) {

      log.debug(stdout);
      if (err) {
        log.error('ERROR: Failed to copy the manifest to the app folder.');
        log.debug(err);
        return task.reject(new Error('The Cordova project could not be created successfully.'));
      }

      // set generated app's directory as current
      process.chdir(platformDir);

      // add the Hosted Web App plugin
      log.info('Adding the Hosted Web App plugin to the Cordova project...');
      cmdLine = cordovaPath + ' plugin add ' + pluginIdOrUrl;
      log.debug('    ' + cmdLine);
      exec(cmdLine, function (err, stdout, stderr) {

        log.debug(stdout);
        if (err) {
          log.error('ERROR: Failed to add the Hosted Web App plugin to the Cordova project.');
          log.debug(err);
          return task.reject(new Error('The Cordova project could not be created successfully.'));
        } else if (stderr.length) {
          log.error(stderr.trim());
        }

        // process all the specified platforms
        var pendingTasks = [];
        platforms.forEach(function (platform) {
          log.info('Adding Cordova platform: ' + platform + '...');

          var platformTask = new Q.defer();
          pendingTasks.push(platformTask.promise);
          cmdLine = cordovaPath + ' platform add ' + mapToCordovaPlatform(platform);
          log.debug('    ' + cmdLine);
          exec(cmdLine, function (err, stdout, stderr) {

            log.debug(stdout);
            if (err) {
              log.warn('WARNING: Failed to add ' + platform + ' platform.');
              log.debug(err);
              return platformTask.reject(err);
            } else if (stderr.length) {
              log.error(stderr.trim());
            }

            applyPlatformsFix(platform, platformDir, function(err) {
              if (err) {
                log.warn('WARNING: Failed to apply platform fix: ' + platform + '.');
                log.debug(err);
                return platformTask.reject(err);
              } else if (stderr.length) {
                log.error(stderr.trim());
              }

              // set original working directory as current (so that the generated folder can be deleted)
              process.chdir(originalPath);

              log.info('Creating shortcut for platform: ' + platform + '...');
              createPlatformShortcut(generatedAppDir, platform, function (err) {

                log.debug(stdout);
                if (err) {
                  log.warn('WARNING: Failed to create shortcut for platform: ' + platform + '.');
                  log.debug(err);
                }

                // build the platform-specific projects
                if (build) {
                  log.info('Building Cordova platform: ' + platform + '...');
                  cmdLine = cordovaPath + ' build ' + mapToCordovaPlatform(platform);
                  log.debug('    ' + cmdLine);
                  exec(cmdLine, function (err, stdout, stderr) {

                    log.debug(stdout);
                    if (err) {
                      log.warn('WARNING: Failed to build platform: ' + platform + '.');
                      log.debug(err);
                      return platformTask.reject(err);
                    } else if (stderr.length) {
                      log.error(stderr.trim());
                    }

                    platformTask.resolve();
                  });
                } else {
                  platformTask.resolve();
                }
              });
            });
          });
        });

        Q.allSettled(pendingTasks)
          .done(function (results) {
          if (results.some(function (platformTask) { return platformTask.state !== 'fulfilled'; })) {
            return task.reject(new Error('One or more tasks failed while generating the Cordova application.'));
          } else {
            return task.resolve();
          }
        });
      });
    });
  });

  return task.promise;
};

var createApps = function (w3cManifestInfo, rootDir, platforms, build, callback) {

  // determine the path where the Cordova app will be created
  var appName = w3cManifestInfo.content.short_name;
  var generatedAppDir = path.join(rootDir, appName);

  // create app directory
  mkdirp(generatedAppDir, function (err) {
    if (err && err.code !== 'EEXIST') {
      return callback(err);
    }

    // process all requested platforms
    var pendingTasks = [];
    var cordovaPlatforms = [];
    platforms.forEach(function (el) {
      var platform = el.toUpperCase();
      if (platform === 'CHROME') {
        pendingTasks.push(createChromeApp(w3cManifestInfo, generatedAppDir));
      } else if (platform === 'FIREFOX') {
        pendingTasks.push(createFirefoxApp(w3cManifestInfo, generatedAppDir));
      } else if (platform === 'WINDOWS') {
        pendingTasks.push(createWindowsApp(w3cManifestInfo, generatedAppDir));
      } else if (platform === 'WINDOWSUNIVERSAL' || platform === 'IOS' || platform === 'ANDROID') {
        // all these platforms are handled by Cordova
        cordovaPlatforms.push(el);
      } else {
        return callback(new Error('Unknown platform \'' + el + '\' specified.'));
      }
    });

    // generate Cordova project
    if (cordovaPlatforms.length) {
      pendingTasks.push(createCordovaApp(w3cManifestInfo, generatedAppDir, cordovaPlatforms, build));
    }

    Q.allSettled(pendingTasks)
    .done(function (results) {
      var err;
      results.forEach(function (task) {
        if (task.state !== 'fulfilled') {
          log.error('WARNING: ' + task.reason.message);
          if (!err) {
            err = new Error('One or more errors occurred when generating the application.');
          }
        }
      });

      if (callback) {
        callback(err);
      }
    });
  });
};

module.exports = {
  createApps: createApps,
  createChromeApp: createChromeApp,
  createFirefoxApp: createFirefoxApp,
  createWindowsApp: createWindowsApp,
  createCordovaApp: createCordovaApp,
};
<|endoftext|>


<commit_before>/*
 * Copyright 2014-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'find/app/model/find-base-collection',
    'underscore'
], function(FindBaseCollection, _) {

    return FindBaseCollection.extend({
        url: '../api/public/search/find-related-concepts',

        parse: function(response) {
            return _.reject(response, function (model) {
                // A negative cluster indicates that the associated documents did not fall into a cluster
                return model.cluster < 0;
            });
        },

        /**
         * Get the text for entities in the cluster with the given id.
         * @param {Number} clusterId
         * @return {String[]}
         */
        getClusterEntities: function(clusterId) {
            return this.chain()
                .filter(function(model) {
                    return model.get('cluster') === clusterId;
                })
                .map(function(model) {
                    return model.get('text');
                })
                .value();
        }
    });

});
<commit_msg>[FIND-22] returning only 10 related concepts per cluster [rev:matthew.gordon2]<commit_after>/*
 * Copyright 2014-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'find/app/model/find-base-collection',
    'underscore'
], function(FindBaseCollection, _) {

    return FindBaseCollection.extend({
        url: '../api/public/search/find-related-concepts',

        parse: function(response) {
            var allModels = _.reject(response, function (model) {
                // A negative cluster indicates that the associated documents did not fall into a cluster
                return model.cluster < 0;
            });

            var groupedModelsByCluster = _.groupBy(allModels, function(obj){
                return obj.cluster;
            });

            //returns an array of arrays of first 11 models
            var filteredModelsInClusters = _.map(groupedModelsByCluster, function(array) {
                return _.first(array, 10);
            });

            return _.flatten(filteredModelsInClusters);
        },

        /**
         * Get the text for entities in the cluster with the given id.
         * @param {Number} clusterId
         * @return {String[]}
         */
        getClusterEntities: function(clusterId) {
            return this.chain()
                .filter(function(model) {
                    return model.get('cluster') === clusterId;
                })
                .map(function(model) {
                    return model.get('text');
                })
                .value();
        }
    });

});
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var SourceEntry = (function() {
  'use strict';

  /**
   * A SourceEntry gathers all log entries with the same source.
   *
   * @constructor
   */
  function SourceEntry(logEntry, maxPreviousSourceId) {
    this.maxPreviousSourceId_ = maxPreviousSourceId;
    this.entries_ = [];
    this.description_ = '';

    // Set to true on most net errors.
    this.isError_ = false;

    // If the first entry is a BEGIN_PHASE, set to false.
    // Set to true when an END_PHASE matching the first entry is encountered.
    this.isInactive_ = true;

    if (logEntry.phase == EventPhase.PHASE_BEGIN)
      this.isInactive_ = false;

    this.update(logEntry);
  }

  SourceEntry.prototype = {
    update: function(logEntry) {
      // Only the last event should have the same type first event,
      if (!this.isInactive_ && logEntry.phase == EventPhase.PHASE_END &&
          logEntry.type == this.entries_[0].type) {
        this.isInactive_ = true;
      }

      // If we have a net error code, update |this.isError_| if appropriate.
      if (logEntry.params) {
        var netErrorCode = logEntry.params.net_error;
        // Skip both cases where netErrorCode is undefined, and cases where it
        // is 0, indicating no actual error occurred.
        if (netErrorCode) {
          // Ignore error code caused by not finding an entry in the cache.
          if (logEntry.type != EventType.HTTP_CACHE_OPEN_ENTRY ||
              netErrorCode != NetError.ERR_FAILED) {
            this.isError_ = true;
          }
        }
      }

      var prevStartEntry = this.getStartEntry_();
      this.entries_.push(logEntry);
      var curStartEntry = this.getStartEntry_();

      // If we just got the first entry for this source.
      if (prevStartEntry != curStartEntry)
        this.updateDescription_();
    },

    updateDescription_: function() {
      var e = this.getStartEntry_();
      this.description_ = '';
      if (!e)
        return;

      if (e.source.type == EventSourceType.NONE) {
        // NONE is what we use for global events that aren't actually grouped
        // by a "source ID", so we will just stringize the event's type.
        this.description_ = EventTypeNames[e.type];
        return;
      }

      if (e.params == undefined) {
        return;
      }

      switch (e.source.type) {
        case EventSourceType.URL_REQUEST:
        case EventSourceType.HTTP_STREAM_JOB:
        case EventSourceType.HTTP_STREAM_JOB_CONTROLLER:
        case EventSourceType.BIDIRECTIONAL_STREAM:
          this.description_ = e.params.url;
          break;
        case EventSourceType.TRANSPORT_CONNECT_JOB:
        case EventSourceType.SSL_CONNECT_JOB:
        case EventSourceType.SOCKS_CONNECT_JOB:
        case EventSourceType.HTTP_PROXY_CONNECT_JOB:
        case EventSourceType.WEB_SOCKET_TRANSPORT_CONNECT_JOB:
          this.description_ = e.params.group_name;
          break;
        case EventSourceType.HOST_RESOLVER_IMPL_JOB:
        case EventSourceType.HOST_RESOLVER_IMPL_PROC_TASK:
          this.description_ = e.params.host;
          break;
        case EventSourceType.DISK_CACHE_ENTRY:
        case EventSourceType.MEMORY_CACHE_ENTRY:
          this.description_ = e.params.key;
          break;
        case EventSourceType.QUIC_SESSION:
          if (e.params.host != undefined)
            this.description_ = e.params.host;
          break;
        case EventSourceType.HTTP2_SESSION:
          if (e.params.host)
            this.description_ = e.params.host + ' (' + e.params.proxy + ')';
          break;
        case EventSourceType.HTTP_PIPELINED_CONNECTION:
          if (e.params.host_and_port)
            this.description_ = e.params.host_and_port;
          break;
        case EventSourceType.SOCKET:
        case EventSourceType.PROXY_CLIENT_SOCKET:
          // Use description of parent source, if any.
          if (e.params.source_dependency != undefined) {
            var parentId = e.params.source_dependency.id;
            this.description_ =
                SourceTracker.getInstance().getDescription(parentId);
          }
          break;
        case EventSourceType.UDP_SOCKET:
          if (e.params.address != undefined) {
            this.description_ = e.params.address;
            // If the parent of |this| is a HOST_RESOLVER_IMPL_JOB, use
            // '<DNS Server IP> [<host we're resolving>]'.
            if (this.entries_[0].type == EventType.SOCKET_ALIVE &&
                this.entries_[0].params &&
                this.entries_[0].params.source_dependency != undefined) {
              var parentId = this.entries_[0].params.source_dependency.id;
              var parent = SourceTracker.getInstance().getSourceEntry(parentId);
              if (parent &&
                  parent.getSourceType() ==
                      EventSourceType.HOST_RESOLVER_IMPL_JOB &&
                  parent.getDescription().length > 0) {
                this.description_ += ' [' + parent.getDescription() + ']';
              }
            }
          }
          break;
        case EventSourceType.ASYNC_HOST_RESOLVER_REQUEST:
        case EventSourceType.DNS_TRANSACTION:
          this.description_ = e.params.hostname;
          break;
        case EventSourceType.DOWNLOAD:
          switch (e.type) {
            case EventType.DOWNLOAD_FILE_RENAMED:
              this.description_ = e.params.new_filename;
              break;
            case EventType.DOWNLOAD_FILE_OPENED:
              this.description_ = e.params.file_name;
              break;
            case EventType.DOWNLOAD_ITEM_ACTIVE:
              this.description_ = e.params.file_name;
              break;
          }
          break;
      }

      if (this.description_ == undefined)
        this.description_ = '';
    },

    /**
     * Returns a description for this source log stream, which will be displayed
     * in the list view. Most often this is a URL that identifies the request,
     * or a hostname for a connect job, etc...
     */
    getDescription: function() {
      return this.description_;
    },

    /**
     * Returns the starting entry for this source. Conceptually this is the
     * first entry that was logged to this source. However, we skip over the
     * TYPE_REQUEST_ALIVE entries without parameters which wrap
     * TYPE_URL_REQUEST_START_JOB entries.  (TYPE_REQUEST_ALIVE may or may not
     * have parameters depending on what version of Chromium they were
     * generated from.)
     */
    getStartEntry_: function() {
      if (this.entries_.length < 1)
        return undefined;
      if (this.entries_[0].source.type == EventSourceType.FILESTREAM) {
        var e = this.findLogEntryByType_(EventType.FILE_STREAM_OPEN);
        if (e != undefined)
          return e;
      }
      if (this.entries_[0].source.type == EventSourceType.DOWNLOAD) {
        // If any rename occurred, use the last name
        e = this.findLastLogEntryStartByType_(EventType.DOWNLOAD_FILE_RENAMED);
        if (e != undefined)
          return e;
        // Otherwise, if the file was opened, use that name
        e = this.findLogEntryByType_(EventType.DOWNLOAD_FILE_OPENED);
        if (e != undefined)
          return e;
        // History items are never opened, so use the activation info
        e = this.findLogEntryByType_(EventType.DOWNLOAD_ITEM_ACTIVE);
        if (e != undefined)
          return e;
      }
      if (this.entries_.length >= 2) {
        if (this.entries_[1].type == EventType.UDP_CONNECT)
          return this.entries_[1];
        if (this.entries_[1].type == EventType.IPV6_PROBE_RUNNING)
          return this.entries_[1];
      }
      return this.entries_[0];
    },

    /**
     * Returns the first entry with the specified type, or undefined if not
     * found.
     */
    findLogEntryByType_: function(type) {
      for (var i = 0; i < this.entries_.length; ++i) {
        if (this.entries_[i].type == type) {
          return this.entries_[i];
        }
      }
      return undefined;
    },

    /**
     * Returns the beginning of the last entry with the specified type, or
     * undefined if not found.
     */
    findLastLogEntryStartByType_: function(type) {
      for (var i = this.entries_.length - 1; i >= 0; --i) {
        if (this.entries_[i].type == type) {
          if (this.entries_[i].phase != EventPhase.PHASE_END)
            return this.entries_[i];
        }
      }
      return undefined;
    },

    getLogEntries: function() {
      return this.entries_;
    },

    getSourceTypeString: function() {
      return EventSourceTypeNames[this.entries_[0].source.type];
    },

    getSourceType: function() {
      return this.entries_[0].source.type;
    },

    getSourceId: function() {
      return this.entries_[0].source.id;
    },

    /**
     * Returns the largest source ID seen before this object was received.
     * Used only for sorting SourceEntries without a source by source ID.
     */
    getMaxPreviousEntrySourceId: function() {
      return this.maxPreviousSourceId_;
    },

    isInactive: function() {
      return this.isInactive_;
    },

    isError: function() {
      return this.isError_;
    },

    /**
     * Returns time ticks of first event.
     */
    getStartTicks: function() {
      return this.entries_[0].time;
    },

    /**
     * Returns time of last event if inactive.  Returns current time otherwise.
     * Returned time is a "time ticks" value.
     */
    getEndTicks: function() {
      if (!this.isInactive_)
        return timeutil.getCurrentTimeTicks();
      return this.entries_[this.entries_.length - 1].time;
    },

    /**
     * Returns the time between the first and last events with a matching
     * source ID.  If source is still active, uses the current time for the
     * last event.
     */
    getDuration: function() {
      var startTime = this.getStartTicks();
      var endTime = this.getEndTicks();
      return endTime - startTime;
    },

    /**
     * Prints descriptive text about |entries_| to a new node added to the end
     * of |parent|.
     */
    printAsText: function(parent) {
      var tablePrinter = this.createTablePrinter();

      // Format the table for fixed-width text.
      tablePrinter.toText(0, parent);
    },

    /**
     * Creates a table printer for the SourceEntry.
     */
    createTablePrinter: function() {
      return createLogEntryTablePrinter(
          this.entries_,
          SourceTracker.getInstance().getUseRelativeTimes() ?
              timeutil.getBaseTime() :
              0,
          Constants.clientInfo.numericDate);
    },
  };

  return SourceEntry;
})();

<commit_msg>Fix eslint errors in source_entry.js<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

class SourceEntry {
  /**
   * A SourceEntry gathers all log entries with the same source.
   *
   * @constructor
   */
  constructor(logEntry, maxPreviousSourceId) {
    this.maxPreviousSourceId_ = maxPreviousSourceId;
    this.entries_ = [];
    this.description_ = '';

    // Set to true on most net errors.
    this.isError_ = false;

    // If the first entry is a BEGIN_PHASE, set to false.
    // Set to true when an END_PHASE matching the first entry is encountered.
    this.isInactive_ = true;

    if (logEntry.phase === EventPhase.PHASE_BEGIN) {
      this.isInactive_ = false;
    }

    this.update(logEntry);
  }

  update(logEntry) {
    // Only the last event should have the same type first event,
    if (!this.isInactive_ && logEntry.phase === EventPhase.PHASE_END &&
        logEntry.type === this.entries_[0].type) {
      this.isInactive_ = true;
    }

    // If we have a net error code, update |this.isError_| if appropriate.
    if (logEntry.params) {
      const netErrorCode = logEntry.params.net_error;
      // Skip both cases where netErrorCode is undefined, and cases where it
      // is 0, indicating no actual error occurred.
      if (netErrorCode) {
        // Ignore error code caused by not finding an entry in the cache.
        if (logEntry.type !== EventType.HTTP_CACHE_OPEN_ENTRY ||
            netErrorCode !== NetError.ERR_FAILED) {
          this.isError_ = true;
        }
      }
    }

    const prevStartEntry = this.getStartEntry_();
    this.entries_.push(logEntry);
    const curStartEntry = this.getStartEntry_();

    // If we just got the first entry for this source.
    if (prevStartEntry !== curStartEntry) {
      this.updateDescription_();
    }
  }

  updateDescription_() {
    const e = this.getStartEntry_();
    this.description_ = '';
    if (!e) {
      return;
    }

    if (e.source.type === EventSourceType.NONE) {
      // NONE is what we use for global events that aren't actually grouped
      // by a "source ID", so we will just stringize the event's type.
      this.description_ = EventTypeNames[e.type];
      return;
    }

    if (e.params === undefined) {
      return;
    }

    switch (e.source.type) {
      case EventSourceType.URL_REQUEST:
      case EventSourceType.HTTP_STREAM_JOB:
      case EventSourceType.HTTP_STREAM_JOB_CONTROLLER:
      case EventSourceType.BIDIRECTIONAL_STREAM:
        this.description_ = e.params.url;
        break;
      case EventSourceType.TRANSPORT_CONNECT_JOB:
      case EventSourceType.SSL_CONNECT_JOB:
      case EventSourceType.SOCKS_CONNECT_JOB:
      case EventSourceType.HTTP_PROXY_CONNECT_JOB:
      case EventSourceType.WEB_SOCKET_TRANSPORT_CONNECT_JOB:
        this.description_ = e.params.group_name;
        break;
      case EventSourceType.HOST_RESOLVER_IMPL_JOB:
      case EventSourceType.HOST_RESOLVER_IMPL_PROC_TASK:
        this.description_ = e.params.host;
        break;
      case EventSourceType.DISK_CACHE_ENTRY:
      case EventSourceType.MEMORY_CACHE_ENTRY:
        this.description_ = e.params.key;
        break;
      case EventSourceType.QUIC_SESSION:
        if (e.params.host !== undefined) {
          this.description_ = e.params.host;
        }
        break;
      case EventSourceType.HTTP2_SESSION:
        if (e.params.host) {
          this.description_ = e.params.host + ' (' + e.params.proxy + ')';
        }
        break;
      case EventSourceType.HTTP_PIPELINED_CONNECTION:
        if (e.params.host_and_port) {
          this.description_ = e.params.host_and_port;
        }
        break;
      case EventSourceType.SOCKET:
      case EventSourceType.PROXY_CLIENT_SOCKET:
        // Use description of parent source, if any.
        if (e.params.source_dependency !== undefined) {
          const parentId = e.params.source_dependency.id;
          this.description_ =
              SourceTracker.getInstance().getDescription(parentId);
        }
        break;
      case EventSourceType.UDP_SOCKET:
        if (e.params.address !== undefined) {
          this.description_ = e.params.address;
          // If the parent of |this| is a HOST_RESOLVER_IMPL_JOB, use
          // '<DNS Server IP> [<host we're resolving>]'.
          if (this.entries_[0].type === EventType.SOCKET_ALIVE &&
              this.entries_[0].params &&
              this.entries_[0].params.source_dependency !== undefined) {
            const parentId = this.entries_[0].params.source_dependency.id;
            const parent = SourceTracker.getInstance().getSourceEntry(parentId);
            if (parent &&
                parent.getSourceType() ===
                    EventSourceType.HOST_RESOLVER_IMPL_JOB &&
                parent.getDescription().length > 0) {
              this.description_ += ' [' + parent.getDescription() + ']';
            }
          }
        }
        break;
      case EventSourceType.ASYNC_HOST_RESOLVER_REQUEST:
      case EventSourceType.DNS_TRANSACTION:
        this.description_ = e.params.hostname;
        break;
      case EventSourceType.DOWNLOAD:
        switch (e.type) {
          case EventType.DOWNLOAD_FILE_RENAMED:
            this.description_ = e.params.new_filename;
            break;
          case EventType.DOWNLOAD_FILE_OPENED:
            this.description_ = e.params.file_name;
            break;
          case EventType.DOWNLOAD_ITEM_ACTIVE:
            this.description_ = e.params.file_name;
            break;
        }
        break;
    }

    if (this.description_ === undefined) {
      this.description_ = '';
    }
  }

  /**
   * Returns a description for this source log stream, which will be displayed
   * in the list view. Most often this is a URL that identifies the request,
   * or a hostname for a connect job, etc...
   */
  getDescription() {
    return this.description_;
  }

  /**
   * Returns the starting entry for this source. Conceptually this is the
   * first entry that was logged to this source. However, we skip over the
   * TYPE_REQUEST_ALIVE entries without parameters which wrap
   * TYPE_URL_REQUEST_START_JOB entries.  (TYPE_REQUEST_ALIVE may or may not
   * have parameters depending on what version of Chromium they were
   * generated from.)
   */
  getStartEntry_() {
    if (this.entries_.length < 1) {
      return undefined;
    }
    if (this.entries_[0].source.type === EventSourceType.FILESTREAM) {
      const e = this.findLogEntryByType_(EventType.FILE_STREAM_OPEN);
      if (e !== undefined) {
        return e;
      }
    }
    if (this.entries_[0].source.type === EventSourceType.DOWNLOAD) {
      // If any rename occurred, use the last name
      e = this.findLastLogEntryStartByType_(EventType.DOWNLOAD_FILE_RENAMED);
      if (e !== undefined) {
        return e;
      }
      // Otherwise, if the file was opened, use that name
      e = this.findLogEntryByType_(EventType.DOWNLOAD_FILE_OPENED);
      if (e !== undefined) {
        return e;
      }
      // History items are never opened, so use the activation info
      e = this.findLogEntryByType_(EventType.DOWNLOAD_ITEM_ACTIVE);
      if (e !== undefined) {
        return e;
      }
    }
    if (this.entries_.length >= 2) {
      if (this.entries_[1].type === EventType.UDP_CONNECT) {
        return this.entries_[1];
      }
      if (this.entries_[1].type === EventType.IPV6_PROBE_RUNNING) {
        return this.entries_[1];
      }
    }
    return this.entries_[0];
  }

  /**
   * Returns the first entry with the specified type, or undefined if not
   * found.
   */
  findLogEntryByType_(type) {
    for (let i = 0; i < this.entries_.length; ++i) {
      if (this.entries_[i].type === type) {
        return this.entries_[i];
      }
    }
    return undefined;
  }

  /**
   * Returns the beginning of the last entry with the specified type, or
   * undefined if not found.
   */
  findLastLogEntryStartByType_(type) {
    for (let i = this.entries_.length - 1; i >= 0; --i) {
      if (this.entries_[i].type === type) {
        if (this.entries_[i].phase !== EventPhase.PHASE_END) {
          return this.entries_[i];
        }
      }
    }
    return undefined;
  }

  getLogEntries() {
    return this.entries_;
  }

  getSourceTypeString() {
    return EventSourceTypeNames[this.entries_[0].source.type];
  }

  getSourceType() {
    return this.entries_[0].source.type;
  }

  getSourceId() {
    return this.entries_[0].source.id;
  }

  /**
   * Returns the largest source ID seen before this object was received.
   * Used only for sorting SourceEntries without a source by source ID.
   */
  getMaxPreviousEntrySourceId() {
    return this.maxPreviousSourceId_;
  }

  isInactive() {
    return this.isInactive_;
  }

  isError() {
    return this.isError_;
  }

  /**
   * Returns time ticks of first event.
   */
  getStartTicks() {
    return this.entries_[0].time;
  }

  /**
   * Returns time of last event if inactive.  Returns current time otherwise.
   * Returned time is a "time ticks" value.
   */
  getEndTicks() {
    if (!this.isInactive_) {
      return timeutil.getCurrentTimeTicks();
    }
    return this.entries_[this.entries_.length - 1].time;
  }

  /**
   * Returns the time between the first and last events with a matching
   * source ID.  If source is still active, uses the current time for the
   * last event.
   */
  getDuration() {
    const startTime = this.getStartTicks();
    const endTime = this.getEndTicks();
    return endTime - startTime;
  }

  /**
   * Prints descriptive text about |entries_| to a new node added to the end
   * of |parent|.
   */
  printAsText(parent) {
    const tablePrinter = this.createTablePrinter();

    // Format the table for fixed-width text.
    tablePrinter.toText(0, parent);
  }

  /**
   * Creates a table printer for the SourceEntry.
   */
  createTablePrinter() {
    return createLogEntryTablePrinter(
        this.entries_,
        SourceTracker.getInstance().getUseRelativeTimes() ?
          timeutil.getBaseTime() :
          0,
        Constants.clientInfo.numericDate);
  }
}

<|endoftext|>


<commit_before>/* global process */
/**
 * `path` type prompt
 */

var _ = require("lodash");
var util = require("util");
var chalk = require("chalk");
var Base = require('inquirer/lib/prompts/base');
var utils = require("inquirer/lib/utils/utils");
var Separator = require("inquirer/lib/objects/separator");
var observe = require("inquirer/lib/utils/events");

var path = require('path');
var fs = require('fs');

/**
 * Module exports
 */

module.exports = Prompt;

/**
 * Constructor
 */

function Prompt() {
  Base.apply( this, arguments );

  // cwd being a String
  if (this.opt.cwd && !_.isString(this.opt.cwd) ) {
    this.throwParamError("cwd");
  }

  this.opt.cwd = path.resolve(this.opt.cwd || '.');

  this.optionsLines = [];
  this.lines = [];

  return this;
}
util.inherits( Prompt, Base );

/**
 * Start the Inquiry session
 * @param  {Function} cb      Callback when prompt is done
 * @return {this}
 */

Prompt.prototype._run = function( cb ) {
  this.done = cb;

  // Save user answer and update prompt to show selected option.
  var events = observe(this.rl);
  this.lineObs = events.line.forEach( this.onSubmit.bind(this) );
  this.keypressObs = events.keypress.forEach( this.onKeypress.bind(this) );

  // Init the prompt
  this.render();

  return this;
};

/**
 * Render the prompt to screen
 * @return {Prompt} self
 */

Prompt.prototype.render = function() {

  // Render question
  var message = this.getQuestion();

  if ( this.status === "answered" ) {
    message += chalk.cyan( this.selected.name ) + "\n";
  }

  utils.writeMessage( this, message );

  return this;
};

/**
 * When user press `enter` key
 */

Prompt.prototype.onSubmit = function( input ) {
  if ( input == null || input === "" ) {
    //Error or cwd?
    input = this.rawDefault;
  }

  var selected = input;

  if ( selected != null ) {
    this.status = "answered";
    this.selected = selected;

    // Re-render prompt
    this.down().clean(2).render();

    this.lineObs.dispose();
    this.keypressObs.dispose();
    this.done( this.selected.value );
    return;
  }

  // Input is invalid
  this
    .error("Please enter a valid command")
    .clean()
    .render();
};

function getDirContenList (dirPath) {
  return fs.readdirSync(dirPath).map(
    function (elem) {
      var stats = fs.lstatSync(path.join(dirPath, elem));
      if ( !stats.isFile() ) {
        return elem + '/';
      }
      return elem;
    }
  );
}

function getMaxLength (list) {
  return Math.max.apply(null, list.map(function (elem) {
    return elem.length;
  }));
}

function getLines (list) {
  var maxLength = getMaxLength(list) + 2; //It is only to add an extra space
  var maxColumns = Math.floor(process.stdout.columns/maxLength);
  var maxRows = Math.ceil(list.length/maxColumns);

  var lines = new Array(maxRows);
  for (var i = 0; i < maxRows; i++) {
    lines[i] = [];
  }

  list.forEach(function (elem, index) {
    lines[index % maxRows].push(elem + Array(maxLength - elem.length).join(' '));
  });

  return lines.map(function (elem) {
    return elem.join(' ');
  });
}

/**
 * When user press a key
 */

Prompt.prototype.onKeypress = function( input ) {
  this.selectedKey = this.rl.line;
  this.cacheCursorPos();

  //Verify the the user is in the same directory
  var currentDir = path.dirname(path.join(this.opt.cwd, this.rl.line));
  if (currentDir !== this.currentDir) {
    this.currentDir = currentDir;
  }

  if ( input.key.name === "tab" ) {
    if ( this.tabPress ) {
      this.tabPressed = false;
    } else {
      this.tabPressed = true;
      this.list = getDirContenList(currentDir);
//      console.log(this);
    }
  }

  //Clean previous
  this
    .down(this.optionsLines.length)
    .clean(this.optionsLines.length);

  if (this.tabPressed) {
    //Filter the current list
    this.optionsLines = getLines(this.list);
//    console.log(this.optionsLines);
  }

  if (this.optionsLines.length) {
    this
      .down()
      .write(this.optionsLines.join('\n'))
      .up(this.optionsLines.length)
      .clean();
  }

  this.render();

  this.write(this.rl.line).restoreCursorPos();
};

<commit_msg>I managed to synchronize the cursor<commit_after>/* global process */
/**
 * `path` type prompt
 */

var _ = require("lodash");
var util = require("util");
var chalk = require("chalk");
var Base = require('inquirer/lib/prompts/base');
var utils = require("inquirer/lib/utils/utils");
var Separator = require("inquirer/lib/objects/separator");
var observe = require("inquirer/lib/utils/events");

var path = require('path');
var fs = require('fs');

/**
 * Module exports
 */

module.exports = Prompt;

/**
 * Constructor
 */

function Prompt() {
  Base.apply( this, arguments );

  // cwd being a String
  if (this.opt.cwd && !_.isString(this.opt.cwd) ) {
    this.throwParamError("cwd");
  }

  this.opt.cwd = path.resolve(this.opt.cwd || '.');

  this.optionsLines = [];
  this.lines = [];
  this.selectedKey

  return this;
}
util.inherits( Prompt, Base );

/**
 * Start the Inquiry session
 * @param  {Function} cb      Callback when prompt is done
 * @return {this}
 */

Prompt.prototype._run = function( cb ) {
  this.done = cb;

  // Save user answer and update prompt to show selected option.
  var events = observe(this.rl);
  this.lineObs = events.line.forEach( this.onSubmit.bind(this) );
  this.keypressObs = events.keypress.forEach( this.onKeypress.bind(this) );

  // Init the prompt
  this.render();

  return this;
};

/**
 * Render the prompt to screen
 * @return {Prompt} self
 */

Prompt.prototype.render = function() {

  // Render question
  var message = this.getQuestion();

  if ( this.status === "answered" ) {
    message += chalk.cyan( this.selected.name ) + "\n";
  }

  utils.writeMessage( this, message );

  return this;
};

/**
 * When user press `enter` key
 */

Prompt.prototype.onSubmit = function( input ) {
  if ( input == null || input === "" ) {
    //Error or cwd?
    input = this.rawDefault;
  }

  var selected = input;

  if ( selected != null ) {
    this.status = "answered";
    this.selected = selected;

    // Re-render prompt
    this.down().clean(2).render();

    this.lineObs.dispose();
    this.keypressObs.dispose();
    this.done( this.selected.value );
    return;
  }

  // Input is invalid
  this
    .error("Please enter a valid command")
    .clean()
    .render();
};

function getDirContenList (dirPath) {
  return fs.readdirSync(dirPath).map(
    function (elem) {
      var stats = fs.lstatSync(path.join(dirPath, elem));
      if ( !stats.isFile() ) {
        return elem + '/';
      }
      return elem;
    }
  );
}

function getMaxLength (list) {
  return Math.max.apply(null, list.map(function (elem) {
    return elem.length;
  }));
}

function getLines (list) {
  var maxLength = getMaxLength(list) + 2; //It is only to add an extra space
  var maxColumns = Math.floor(process.stdout.columns/maxLength);
  var maxRows = Math.ceil(list.length/maxColumns);

  var lines = new Array(maxRows);
  for (var i = 0; i < maxRows; i++) {
    lines[i] = [];
  }

  list.forEach(function (elem, index) {
    lines[index % maxRows].push(elem + Array(maxLength - elem.length).join(' '));
  });

  return lines.map(function (elem) {
    return elem.join(' ');
  });
}

/**
 * When user press a key
 */

Prompt.prototype.onKeypress = function( input ) {
  this.selectedKey = this.rl.line;
  //this.cacheCursorPos();

  //Verify the the user is in the same directory
  var currentDir = path.dirname(path.join(this.opt.cwd, this.rl.line));
  if (currentDir !== this.currentDir) {
    this.currentDir = currentDir;
  }

  if ( input.key.name === "tab" ) {
    if ( this.tabPress ) {
      this.tabPressed = false;
    } else {
      this.tabPressed = true;
      this.list = getDirContenList(currentDir);
//      console.log(this);
    }
    this.rl.line = 'lala';
    //this.rl._refreshLine();
    this.rl.cursor = 4;
    //console.dir(this.rl);
  }

  //Clean previous
/*  this
    .down(this.optionsLines.length)
    .clean(this.optionsLines.length);

  if (this.tabPressed) {
    //Filter the current list
    this.optionsLines = getLines(this.list);
//    console.log(this.optionsLines);
  }

  if (this.optionsLines.length) {
    this
      .down()
      .write(this.optionsLines.join('\n'))
      .up(this.optionsLines.length)
      .clean();
  }*/

  this.clean();
  this.render();

  //this.write(this.rl.line).restoreCursorPos();

  //var newLength = this.selectedKey.length - this.rl.line.length;
  this.write(this.rl.line).restoreCursorPos();//.rl._refreshLine() ;//.moveCursor(this.rl.output, 0, newLength);
};

<|endoftext|>


<commit_before>function CrudAction(settings) {
  var MongoClient = require('mongodb').MongoClient;
  var ObjectId = require('mongodb').ObjectID;
  var assert = require('assert');
  this.settings = settings;
  this.collection = settings.collection;
  this.url = settings.url;

  this.insertDocument = function(doc) {
    console.log(">>>>>>>>>"+typeof(this.collection));
    var insertDocument = function(db, callback) {
      db.collection("feedings").insertOne(doc, function(err, result) {
        assert.equal(err, null);
        console.log('+1 ' + doc.datetime);
        callback();
      });
    };

    MongoClient.connect(this.url, function(err, db) {
      assert.equal(null, err);
      insertDocument(db, function() {
        db.close();
      })
    })
  }
  this.read = function() {  }
  this.update = function() {  }
  this.delete = function() {  }

  return this;
}

module.exports = CrudAction;
<commit_msg>Fixed so much stuff<commit_after>function CrudAction(settings) {
  var MongoClient = require('mongodb').MongoClient;
  var ObjectId = require('mongodb').ObjectID;
  var assert = require('assert');
  this.settings = settings;
  this.collection = settings.collection;
  this.url = settings.url;

  this.insertDocument = function(doc) {
    var collection = this.collection
    var insertDocument = function(db, callback) {
      db.collection(collection).insertOne(
        doc,
        function(err, result) {
          assert.equal(err, null);
          console.log('+1 ' + doc.datetime);
          callback();
        });
    };

    MongoClient.connect(this.url, function(err, db) {
      assert.equal(null, err);
      insertDocument(db, function() {
        db.close();
      });
    });
  };

  this.read = function() {};
  this.update = function() {};
  this.delete = function() {};

  return this;
}

module.exports = CrudAction;
<|endoftext|>


<commit_before>/**
 * Zeta Ret XeltoSS Examples
 * ProtoSS mode of inline.morph.XeltoSS.js
 * Access attributes: Public, Private, Protected, Internal, Namespace, etc.
 * Extended design template, CRUD-compliant AccessAttribute class in namespace
 * Requires: protoss.all
 **/

/**
 * AccessAttribute Prototype
 */
Object.prototype.getAccessAttribute = function(namespace, accessor, methods, iidLength) {
	var reference = this,
		scope = {},
		nsa = namespace + '.' + accessor,
		AccessAttribute, m, method;
	if (!iidLength) iidLength = 13;

	reference.namespace(
		nsa,
		class AccessAttribute {
			static access(target, method, args) {
				return AccessAttribute.prototype[method].apply(target, args);
			}
			constructor() {
				throw Error('[Access Attribute] can not be an instance.');
			}
			create() {
				var o = this;
				var iid = o.instanceId;
				if (!iid) {
					iid = o.constructor.packagename + '::' + o.constructor.name + '#' + o.rndstr(iidLength);
					o.instanceId = iid;
				}
				scope[iid] = {
					scope: o,
					data: {}
				};
			}
			read(name) {
				var o = this;
				return scope[o.instanceId].data[name];
			}
			update(name, value) {
				var o = this;
				scope[o.instanceId].data[name] = value;
			}
			destroy() {
				var o = this;
				if (scope[o.instanceId].scope !== o) return false;
				return delete scope[o.instanceId];
			}
		}
	);
	AccessAttribute = reference.usens(nsa).AccessAttribute;
	AccessAttribute.accessor = accessor;
	delete AccessAttribute.packagename;
	delete AccessAttribute.packobj;
	if (methods) {
		for (m in methods) {
			method = methods[m];
			if (method && method.constructor === Function) {
				method.AccessAttribute = AccessAttribute;
				AccessAttribute.prototype[m] = method;
				Object.defineProperty(AccessAttribute.prototype, m, {
					enumerable: false
				});
			}
		}
	}

	return AccessAttribute;
};
Object.defineProperty(Object.prototype, 'getAccessAttribute', {
	enumerable: false
});

/**
 * Program package design
 */
(function() {
	var reference = {};

	(function(reference) {
		var ProtectB = reference.getAccessAttribute('B', 'protected'),
			PrivateB = reference.getAccessAttribute('B', 'private'),
			CustomNS = reference.getAccessAttribute('https://zetaret.com/projects/protoss/', 'custom_ns', {
				outputMessage: function() {
					return arguments.callee.AccessAttribute.prototype.read.call(this, 'message');
				}
			});
		reference = null;
		window.package('classes.set').internal(
			class B {
				constructor() {
					ProtectB.prototype.create.call(this);
					PrivateB.prototype.create.call(this);
					ProtectB.prototype.update.call(this, 'myvar', 3);
					PrivateB.prototype.update.call(this, 'privatevar', 1);
				}
				calculateWithSecret(multiplier) {
					return multiplier * PrivateB.prototype.read.call(this, 'privatevar');
				}
				destroy() {
					ProtectB.prototype.destroy.call(this);
					PrivateB.prototype.destroy.call(this);
				}
			}
		);
	})(reference);

	(function(reference) {
		var ProtectB = reference.usens('B.protected').AccessAttribute;
		reference = null;
		window.package('classes.set.depth').internal(
			class A extends classes.set.B {
				constructor() {
					super();
					ProtectB.prototype.update.call(this, 'myvar', 5);
				}
				calculateWithSecret(multiplier) {
					return multiplier * ProtectB.prototype.read.call(this, 'myvar');
				}
			}
		);
	})(reference);

	(function(reference) {
		var ProtectB = reference.usens('B.protected').AccessAttribute,
			Internal = reference.getAccessAttribute('classes.set.intersect', 'internal');
		reference = null;
		window.package('classes.set.intersect').internal(
			class C extends classes.set.B {
				constructor() {
					super();
					Internal.prototype.create.call(this);
					Internal.prototype.update.call(this, 'intercept', 0);
				}
				calculateWithSecret(multiplier) {
					return multiplier * ProtectB.prototype.read.call(this, 'myvar') + 1 + Internal.prototype.read.call(this, 'intercept');
				}
				destroy() {
					super.destroy();
					Internal.prototype.destroy.call(this);
				}
			}
		);
	})(reference);

	(function(reference) {
		var ProtectB = reference.usens('B.protected').AccessAttribute,
			Internal = reference.usens('classes.set.intersect.internal').AccessAttribute,
			CustomNS = reference.usens('https://zetaret.com/projects/protoss/.custom_ns').AccessAttribute;
		reference = null;
		window.package('classes.set.intersect').internal(
			class D extends classes.set.B {
				constructor() {
					super();
					Internal.prototype.create.call(this);
					Internal.prototype.update.call(this, 'intercept', 11);
					CustomNS.prototype.create.call(this);
					CustomNS.prototype.update.call(this, 'message', 'Hello Earth.');
				}
				calculateWithSecret(multiplier) {
					return multiplier * ProtectB.prototype.read.call(this, 'myvar') + Internal.prototype.read.call(this, 'intercept');
				}
				outputFromCustomNS() {
					return CustomNS.access(this, 'outputMessage');
				}
				destroy() {
					super.destroy();
					Internal.prototype.destroy.call(this);
					CustomNS.prototype.destroy.call(this);
				}
			}
		);
	})(reference);

	reference = null;
})();

/**
 * Instance and Console
 */
var instA = new classes.set.depth.A();
console.log(instA.calculateWithSecret(6));
instA.destroy();
var instB = new classes.set.B();
console.log(instB.calculateWithSecret(7));
instB.destroy();
var instC = new classes.set.intersect.C();
console.log(instC.calculateWithSecret(8));
instC.destroy();
var instD = new classes.set.intersect.D();
console.log(instD.calculateWithSecret(8));
console.log(instD.outputFromCustomNS());
instD.destroy();
<commit_msg>Update inline.morph.XeltoSS.access.attributes.js<commit_after>/**
 * Zeta Ret XeltoSS Examples
 * ProtoSS mode of inline.morph.XeltoSS.js
 * Access attributes: Public, Private, Protected, Internal, Namespace, etc.
 * Extended design template, CRUD-compliant AccessAttribute class in namespace
 * Requires: protoss.all
 **/

/**
 * AccessAttribute Prototype
 */
Object.prototype.getAccessAttribute = function(namespace, accessor, methods, iidLength) {
	var reference = this,
		scope = {},
		nsa = namespace + '.' + accessor,
		AccessAttribute, m, method;
	if (!iidLength) iidLength = 13;

	reference.namespace(
		nsa,
		class AccessAttribute {
			static access(target, method, args) {
				var iid = target.instanceId;
				if (!scope[iid]) throw Error('Unauthorized access of scope.');
				else if (scope[iid].scope !== target) throw Error('Illegal access of foreign scope.');
				return AccessAttribute.prototype[method].apply(target, args);
			}
			static verify(target) {
				var iid = target.instanceId;
				if (!scope[iid] || scope[iid].scope !== target) return false;
				return true;
			}
			constructor() {
				throw Error('[Access Attribute] can not be an instance.');
			}
			create() {
				var o = this;
				var iid = o.instanceId;
				if (!iid) {
					iid = o.constructor.packagename + '::' + o.constructor.name + '#' + o.rndstr(iidLength);
					if (scope[iid]) throw Error('Unauthorized override of scope.');
					o.instanceId = iid;
				} else if (scope[iid] && scope[iid].scope !== o) throw Error('Illegal access of foreign scope.');
				scope[iid] = {
					scope: o,
					data: {}
				};
			}
			read(name) {
				var o = this,
					iid = o.instanceId;
				if (!scope[iid]) throw Error('Unauthorized read of scope.');
				else if (scope[iid].scope !== o) throw Error('Illegal access of foreign scope.');
				return scope[iid].data[name];
			}
			update(name, value) {
				var o = this,
					iid = o.instanceId;
				if (!scope[iid]) throw Error('Unauthorized update of scope.');
				else if (scope[iid].scope !== o) throw Error('Illegal access of foreign scope.');
				scope[iid].data[name] = value;
			}
			destroy() {
				var o = this,
					iid = o.instanceId;
				if (!scope[iid]) throw Error('Unauthorized destroy of scope.');
				else if (scope[iid].scope !== o) return false;
				return delete scope[iid];
			}
		}
	);
	AccessAttribute = reference.usens(nsa).AccessAttribute;
	AccessAttribute.accessor = accessor;
	delete AccessAttribute.packagename;
	delete AccessAttribute.packobj;
	if (methods) {
		for (m in methods) {
			method = methods[m];
			if (method && method.constructor === Function) {
				method.AccessAttribute = AccessAttribute;
				AccessAttribute.prototype[m] = method;
				Object.defineProperty(AccessAttribute.prototype, m, {
					enumerable: false
				});
			}
		}
	}

	return AccessAttribute;
};
Object.defineProperty(Object.prototype, 'getAccessAttribute', {
	enumerable: false
});

/**
 * Program package design
 * IDE defines names of access attribute variable, i.e. [ProtectB, Internal, CustomNS].
 * Compilator computes random names on each compilation.
 */
(function() {
	var reference = {};

	(function(reference) {
		var ProtectB = reference.getAccessAttribute('B', 'protected'),
			PrivateB = reference.getAccessAttribute('B', 'private'),
			CustomNS = reference.getAccessAttribute('https://zetaret.com/projects/protoss/', 'custom_ns', {
				outputMessage: function() {
					return arguments.callee.AccessAttribute.prototype.read.call(this, 'message');
				}
			});
		reference = null;
		window.package('classes.set').internal(
			class B {
				constructor() {
					ProtectB.prototype.create.call(this);
					PrivateB.prototype.create.call(this);
					ProtectB.prototype.update.call(this, 'myvar', 3);
					PrivateB.prototype.update.call(this, 'privatevar', 1);
				}
				calculateWithSecret(multiplier) {
					return multiplier * PrivateB.prototype.read.call(this, 'privatevar');
				}
				destroy() {
					ProtectB.prototype.destroy.call(this);
					PrivateB.prototype.destroy.call(this);
				}
			}
		);
	})(reference);

	(function(reference) {
		var ProtectB = reference.usens('B.protected').AccessAttribute;
		reference = null;
		window.package('classes.set.depth').internal(
			class A extends classes.set.B {
				constructor() {
					super();
					ProtectB.prototype.update.call(this, 'myvar', 5);
				}
				calculateWithSecret(multiplier) {
					return multiplier * ProtectB.prototype.read.call(this, 'myvar');
				}
			}
		);
	})(reference);

	(function(reference) {
		var ProtectB = reference.usens('B.protected').AccessAttribute,
			Internal = reference.getAccessAttribute('classes.set.intersect', 'internal');
		reference = null;
		window.package('classes.set.intersect').internal(
			class C extends classes.set.B {
				constructor() {
					super();
					Internal.prototype.create.call(this);
					Internal.prototype.update.call(this, 'intercept', 0);
				}
				calculateWithSecret(multiplier) {
					return multiplier * ProtectB.prototype.read.call(this, 'myvar') + 1 + Internal.prototype.read.call(this, 'intercept');
				}
				destroy() {
					super.destroy();
					Internal.prototype.destroy.call(this);
				}
			}
		);
	})(reference);

	(function(reference) {
		var ProtectB = reference.usens('B.protected').AccessAttribute,
			Internal = reference.usens('classes.set.intersect.internal').AccessAttribute,
			CustomNS = reference.usens('https://zetaret.com/projects/protoss/.custom_ns').AccessAttribute;
		reference = null;
		window.package('classes.set.intersect').internal(
			class D extends classes.set.B {
				constructor() {
					super();
					Internal.prototype.create.call(this);
					Internal.prototype.update.call(this, 'intercept', 11);
					CustomNS.prototype.create.call(this);
					CustomNS.prototype.update.call(this, 'message', 'Hello Earth.');
				}
				calculateWithSecret(multiplier) {
					return multiplier * ProtectB.prototype.read.call(this, 'myvar') + Internal.prototype.read.call(this, 'intercept');
				}
				outputFromCustomNS() {
					return CustomNS.access(this, 'outputMessage');
				}
				destroy() {
					super.destroy();
					Internal.prototype.destroy.call(this);
					CustomNS.prototype.destroy.call(this);
				}
			}
		);
	})(reference);

	reference = null;
})();

/**
 * Instance and Console
 */
var instA = new classes.set.depth.A();
console.log(instA.calculateWithSecret(6));
instA.destroy();
var instB = new classes.set.B();
console.log(instB.calculateWithSecret(7));
instB.destroy();
var instC = new classes.set.intersect.C();
console.log(instC.calculateWithSecret(8));
instC.destroy();
var instD = new classes.set.intersect.D();
console.log(instD.calculateWithSecret(8));
console.log(instD.outputFromCustomNS());
instD.destroy();
<|endoftext|>