<commit_before>'use strict';

angular.module('emission.survey.external.launch', ['emission.services',
                    'emission.plugin.logger',
                    'emission.stats.clientstats'])

.factory('SurveyLaunch', function($http, $window, $ionicPopup, $rootScope,
    CommHelper, Logger) {

    var surveylaunch = {};
    var replace_uuid= function(iab, elementSelector, scriptFile) {
        return Promise.all([$http.get(scriptFile),
                     CommHelper.getUser()])
          .then(function([scriptText, userProfile]) {
            // alert("finished loading script");
            Logger.log(scriptText.data);
            var uuid = userProfile.user_id['$uuid']
            // I tried to use http://stackoverflow.com/posts/23387583/revisions
            // for the idea on how to invoke the function in the script
            // file, but the callback function was never invoked. So I edit the
            // script file directly and insert the userId.
            Logger.log("inserting user id into survey. userId = "+ uuid
                        +" element selector = "+elementSelector);
            var codeTemplate = scriptText.data;
            var codeString = codeTemplate.replace("SCRIPT_REPLACE_VALUE", uuid)
                                .replace("SCRIPT_REPLACE_ELEMENT_SEL", elementSelector);
            Logger.log(codeString);
            return iab.executeScript({ code: codeString });
          });
    };

    var replace_time = function(iab, tsElementId, fmtTimeElementId, ts, label) {
        // we don't need to get the user because we have the timestamp right here
        return Promise.all([$http.get("js/survey/time_insert.js")])
          .then(function([scriptText]) {
            // alert("finished loading script");
            Logger.log(scriptText.data);
            // I tried to use http://stackoverflow.com/posts/23387583/revisions
            // for the idea on how to invoke the function in the script
            // file, but the callback function was never invoked. So I edit the
            // script file directly and insert the userId.
            Logger.log("inserting ts into survey. ts = "+ ts
                        +" element id = "+tsElementId
                        +" fmtTime"+moment.unix(ts).format()
                        +" element id = "+fmtTimeElementId);
            var codeTemplate = scriptText.data;
            var tsCodeString = codeTemplate.replace("SCRIPT_REPLACE_VALUE", ts)
                                .replace("SCRIPT_REPLACE_ELEMENT_ID", tsElementId)
                                .replace(/LABEL/g, label+"Ts");
            Logger.log("After ts replace" + tsCodeString);
            $cordovaInAppBrowser.executeScript({ code: tsCodeString });
            var fmtTimeCodeString = codeTemplate.replace("SCRIPT_REPLACE_VALUE", moment.unix(ts).format())
                                .replace("SCRIPT_REPLACE_ELEMENT_ID", fmtTimeElementId)
                                .replace(/LABEL/g, label+"FmtTime");
            Logger.log("After fmtTimeCode replace" + tsCodeString);
            iab.executeScript({ code: fmtTimeCodeString });
          });
    };

    // BEGIN: startSurveyForCompletedTrip

    // Put the launch in one place so that
    surveylaunch.options = "location=yes,clearcache=no,toolbar=yes,hideurlbar=yes";
    /*
    surveylaunch.options = {
        location: window.cordova.platformId == 'ios'? 'no' : 'yes',
        clearcache: 'no',
        toolbar: 'yes',
        hideurlbar: 'yes'
    };
    */

    surveylaunch.startSurveyForCompletedTrip = function (url, uuidElementId,
                                                         startTsElementId,
                                                         endTsElementId,
                                                         startFmtTimeElementId,
                                                         endFmtTimeElementId,
                                                         startTs,
                                                         endTs) {
      // THIS LINE FOR inAppBrowser
      let iab = $window.cordova.InAppBrowser.open(url, '_blank', surveylaunch.options);

      iab.addEventListener("loadstop", function(event) {
        console.log("successfully opened page with result "+JSON.stringify(event));
        // success
        Promise.all([replace_uuid(iab, uuidElementId, "js/survey/uuid_insert.js"),
                     replace_time(iab, startTsElementId, startFmtTimeElementId, startTs, "Start"),
                     replace_time(iab, endTsElementId, endFmtTimeElementId, endTs, "End")])
        .catch(function(error) { // catch for all promises
          $ionicPopup.alert({"template": "Relaunching survey - while replacing uuid, got error "+ JSON.stringify(error)})
          .then(function() {
            surveylaunch.startSurvey(url, uuidElementId,
                startTsElementId, endTsElementId,
                startFmtTimeElementId, endTsElementId,
                startTs, endTs);
          });
        });
      })

      iab.addEventListener('loaderror', function(event) {
            Logger.displayError("Unable to launch survey", JSON.stringify(event));
      });

      iab.addEventListener('loadstart', function(event) {
        console.log("started loading, event = "+JSON.stringify(event));
        /*
        if (event.url == 'https://bic2cal.eecs.berkeley.edu/') {
            $cordovaInAppBrowser.close();
        }
        */
      });
      iab.addEventListener('exit', function(event) {
        console.log("exiting, event = "+JSON.stringify(event));
        // we could potentially restore the close-on-bic2cal functionality above
        // if we unregistered here
      });
    }
    // END: startSurveyForCompletedTrip

    var startSurveyCommon = function (url, elementSelector, elementSelScriptFile) {
      // THIS LINE FOR inAppBrowser
      let iab = $window.cordova.InAppBrowser.open(url, '_blank', surveylaunch.options);
      iab.addEventListener("loadstop", function(event) {
        console.log("successfully opened page with result "+JSON.stringify(event));
        // success
        replace_uuid(iab, elementSelector, elementSelScriptFile)
        .catch(function(error) {
          iab.close();
          $ionicPopup.alert({"template": "Relaunching survey - while replacing uuid, got error "+ error})
          .then(function() {
            startSurveyCommon(url,elementSelector, elementSelScriptFile);
          });
        });
      });

      iab.addEventListener('loaderror', function(event) {
        Logger.displayError("Unable to launch survey", event);
      });

      iab.addEventListener("loadstart", function(event) {
        console.log("started loading, event = "+JSON.stringify(event));
        /*
        if (event.url == 'https://bic2cal.eecs.berkeley.edu/') {
            $cordovaInAppBrowser.close();
        }
        */
      });

      iab.addEventListener('exit', function(event) {
        console.log("exiting, event = "+JSON.stringify(event));
        // we could potentially restore the close-on-bic2cal functionality above
        // if we unregistered here
      });
    };

    surveylaunch.startSurveyWithID = function (url, uuidElementId) {
        startSurveyCommon(url, uuidElementId, "js/survey/uuid_insert_id.js");
    }

    surveylaunch.startSurveyWithXPath = function (url, elementXPath) {
        startSurveyCommon(url, elementXPath, "js/survey/uuid_insert_xpath.js");
    }

    /**
     * startSurveyPrefilled start the survey and prefill the UUID field.
     * @param {string} url survey url
     * @param {{
     *  uuidSearchParam: string
     *  returnURLSearchParam: string
     *  returnURL: string
     *  autoCloseURL: string
     * }} [opts] options
     */
    surveylaunch.startSurveyPrefilled = function (url, opts = {}) {
      opts = Object.assign({
        uuidSearchParam: 'uuid',
        returnURLSearchParam: 'return_url',
        returnURL: '',
        autoCloseURL: undefined,
      }, opts);
      return CommHelper.getUser().then(function(userProfile) {
        // alert("finished loading script");
        let uuid = userProfile.user_id['$uuid']
        Logger.log("inserting user id into survey. userId = "+ uuid
                      +" base url = "+url);
        const urlObj = new URL(url);
        urlObj.searchParams.append(opts.returnURLSearchParam, encodeURIComponent(opts.returnURL));
        urlObj.searchParams.append(opts.uuidSearchParam, uuid);
        const modifiedURL = urlObj.toString();
        Logger.log("modified URL = "+modifiedURL);
        let iab = $window.cordova.InAppBrowser.open(modifiedURL, '_blank', surveylaunch.options);
        iab.addEventListener('loaderror', function(event) {
          Logger.displayError("Unable to launch survey", event);
          return Promise.reject();
        });
        if (opts.autoCloseURL) {
          return new Promise((resolve, reject) => {
            const autoClose = function(event) {
              console.log("started loading, event = " + JSON.stringify(event));
              if (opts.autoCloseURL.includes(event.url)) {
                iab.removeEventListener('loadstart', autoClose);
                iab.close();
                return resolve();
              }
            };
            iab.addEventListener('loadstart', autoClose);
          });
        }
        return Promise.resolve();
      });
    }

    surveylaunch.init = function() {
      $rootScope.$on('cloud:push:notification', function(event, data) {
        ClientStats.addEvent(ClientStats.getStatKeys().NOTIFICATION_OPEN).then(
            function() {
                console.log("Added "+ClientStats.getStatKeys().NOTIFICATION_OPEN+" event. Data = " JSON.stringify(data));
              });
        Logger.log("data = "+JSON.stringify(data));
        if (angular.isDefined(data.additionalData) &&
            angular.isDefined(data.additionalData.payload) &&
            angular.isDefined(data.additionalData.payload.alert_type) &&
            data.additionalData.payload.alert_type == "survey") {
            var survey_spec = data.additionalData.payload.spec;
            if (angular.isDefined(survey_spec) &&
                angular.isDefined(survey_spec.url)) {
                if (angular.isDefined(survey_spec.uuidElementId)) {
                  surveylaunch.startSurveyWithID(survey_spec.url, survey_spec.uuidElementId);
                } else if (angular.isDefined(survey_spec.uuidXPath)) {
                  surveylaunch.startSurveyWithXPath(survey_spec.url, survey_spec.uuidXPath);
                } else if (angular.isDefined(survey_spec.uuidSearchParam)) {
                  surveylaunch.startSurveyPrefilled(survey_spec.url, {
                    uuidSearchParam: survey_spec.uuidSearchParam
                  });
                } else {
                    $ionicPopup.alert("survey was not specified correctly. spec is "+JSON.stringify(survey_spec));
                }
            } else {
                $ionicPopup.alert("survey was not specified correctly. spec is "+JSON.stringify(survey_spec));
            }
        }
      });
    };

    surveylaunch.init();
    return surveylaunch;
});
<commit_msg>Fix formatting error from previous commit<commit_after>'use strict';

angular.module('emission.survey.external.launch', ['emission.services',
                    'emission.plugin.logger',
                    'emission.stats.clientstats'])

.factory('SurveyLaunch', function($http, $window, $ionicPopup, $rootScope,
    CommHelper, Logger) {

    var surveylaunch = {};
    var replace_uuid= function(iab, elementSelector, scriptFile) {
        return Promise.all([$http.get(scriptFile),
                     CommHelper.getUser()])
          .then(function([scriptText, userProfile]) {
            // alert("finished loading script");
            Logger.log(scriptText.data);
            var uuid = userProfile.user_id['$uuid']
            // I tried to use http://stackoverflow.com/posts/23387583/revisions
            // for the idea on how to invoke the function in the script
            // file, but the callback function was never invoked. So I edit the
            // script file directly and insert the userId.
            Logger.log("inserting user id into survey. userId = "+ uuid
                        +" element selector = "+elementSelector);
            var codeTemplate = scriptText.data;
            var codeString = codeTemplate.replace("SCRIPT_REPLACE_VALUE", uuid)
                                .replace("SCRIPT_REPLACE_ELEMENT_SEL", elementSelector);
            Logger.log(codeString);
            return iab.executeScript({ code: codeString });
          });
    };

    var replace_time = function(iab, tsElementId, fmtTimeElementId, ts, label) {
        // we don't need to get the user because we have the timestamp right here
        return Promise.all([$http.get("js/survey/time_insert.js")])
          .then(function([scriptText]) {
            // alert("finished loading script");
            Logger.log(scriptText.data);
            // I tried to use http://stackoverflow.com/posts/23387583/revisions
            // for the idea on how to invoke the function in the script
            // file, but the callback function was never invoked. So I edit the
            // script file directly and insert the userId.
            Logger.log("inserting ts into survey. ts = "+ ts
                        +" element id = "+tsElementId
                        +" fmtTime"+moment.unix(ts).format()
                        +" element id = "+fmtTimeElementId);
            var codeTemplate = scriptText.data;
            var tsCodeString = codeTemplate.replace("SCRIPT_REPLACE_VALUE", ts)
                                .replace("SCRIPT_REPLACE_ELEMENT_ID", tsElementId)
                                .replace(/LABEL/g, label+"Ts");
            Logger.log("After ts replace" + tsCodeString);
            $cordovaInAppBrowser.executeScript({ code: tsCodeString });
            var fmtTimeCodeString = codeTemplate.replace("SCRIPT_REPLACE_VALUE", moment.unix(ts).format())
                                .replace("SCRIPT_REPLACE_ELEMENT_ID", fmtTimeElementId)
                                .replace(/LABEL/g, label+"FmtTime");
            Logger.log("After fmtTimeCode replace" + tsCodeString);
            iab.executeScript({ code: fmtTimeCodeString });
          });
    };

    // BEGIN: startSurveyForCompletedTrip

    // Put the launch in one place so that
    surveylaunch.options = "location=yes,clearcache=no,toolbar=yes,hideurlbar=yes";
    /*
    surveylaunch.options = {
        location: window.cordova.platformId == 'ios'? 'no' : 'yes',
        clearcache: 'no',
        toolbar: 'yes',
        hideurlbar: 'yes'
    };
    */

    surveylaunch.startSurveyForCompletedTrip = function (url, uuidElementId,
                                                         startTsElementId,
                                                         endTsElementId,
                                                         startFmtTimeElementId,
                                                         endFmtTimeElementId,
                                                         startTs,
                                                         endTs) {
      // THIS LINE FOR inAppBrowser
      let iab = $window.cordova.InAppBrowser.open(url, '_blank', surveylaunch.options);

      iab.addEventListener("loadstop", function(event) {
        console.log("successfully opened page with result "+JSON.stringify(event));
        // success
        Promise.all([replace_uuid(iab, uuidElementId, "js/survey/uuid_insert.js"),
                     replace_time(iab, startTsElementId, startFmtTimeElementId, startTs, "Start"),
                     replace_time(iab, endTsElementId, endFmtTimeElementId, endTs, "End")])
        .catch(function(error) { // catch for all promises
          $ionicPopup.alert({"template": "Relaunching survey - while replacing uuid, got error "+ JSON.stringify(error)})
          .then(function() {
            surveylaunch.startSurvey(url, uuidElementId,
                startTsElementId, endTsElementId,
                startFmtTimeElementId, endTsElementId,
                startTs, endTs);
          });
        });
      })

      iab.addEventListener('loaderror', function(event) {
            Logger.displayError("Unable to launch survey", JSON.stringify(event));
      });

      iab.addEventListener('loadstart', function(event) {
        console.log("started loading, event = "+JSON.stringify(event));
        /*
        if (event.url == 'https://bic2cal.eecs.berkeley.edu/') {
            $cordovaInAppBrowser.close();
        }
        */
      });
      iab.addEventListener('exit', function(event) {
        console.log("exiting, event = "+JSON.stringify(event));
        // we could potentially restore the close-on-bic2cal functionality above
        // if we unregistered here
      });
    }
    // END: startSurveyForCompletedTrip

    var startSurveyCommon = function (url, elementSelector, elementSelScriptFile) {
      // THIS LINE FOR inAppBrowser
      let iab = $window.cordova.InAppBrowser.open(url, '_blank', surveylaunch.options);
      iab.addEventListener("loadstop", function(event) {
        console.log("successfully opened page with result "+JSON.stringify(event));
        // success
        replace_uuid(iab, elementSelector, elementSelScriptFile)
        .catch(function(error) {
          iab.close();
          $ionicPopup.alert({"template": "Relaunching survey - while replacing uuid, got error "+ error})
          .then(function() {
            startSurveyCommon(url,elementSelector, elementSelScriptFile);
          });
        });
      });

      iab.addEventListener('loaderror', function(event) {
        Logger.displayError("Unable to launch survey", event);
      });

      iab.addEventListener("loadstart", function(event) {
        console.log("started loading, event = "+JSON.stringify(event));
        /*
        if (event.url == 'https://bic2cal.eecs.berkeley.edu/') {
            $cordovaInAppBrowser.close();
        }
        */
      });

      iab.addEventListener('exit', function(event) {
        console.log("exiting, event = "+JSON.stringify(event));
        // we could potentially restore the close-on-bic2cal functionality above
        // if we unregistered here
      });
    };

    surveylaunch.startSurveyWithID = function (url, uuidElementId) {
        startSurveyCommon(url, uuidElementId, "js/survey/uuid_insert_id.js");
    }

    surveylaunch.startSurveyWithXPath = function (url, elementXPath) {
        startSurveyCommon(url, elementXPath, "js/survey/uuid_insert_xpath.js");
    }

    /**
     * startSurveyPrefilled start the survey and prefill the UUID field.
     * @param {string} url survey url
     * @param {{
     *  uuidSearchParam: string
     *  returnURLSearchParam: string
     *  returnURL: string
     *  autoCloseURL: string
     * }} [opts] options
     */
    surveylaunch.startSurveyPrefilled = function (url, opts = {}) {
      opts = Object.assign({
        uuidSearchParam: 'uuid',
        returnURLSearchParam: 'return_url',
        returnURL: '',
        autoCloseURL: undefined,
      }, opts);
      return CommHelper.getUser().then(function(userProfile) {
        // alert("finished loading script");
        let uuid = userProfile.user_id['$uuid']
        Logger.log("inserting user id into survey. userId = "+ uuid
                      +" base url = "+url);
        const urlObj = new URL(url);
        urlObj.searchParams.append(opts.returnURLSearchParam, encodeURIComponent(opts.returnURL));
        urlObj.searchParams.append(opts.uuidSearchParam, uuid);
        const modifiedURL = urlObj.toString();
        Logger.log("modified URL = "+modifiedURL);
        let iab = $window.cordova.InAppBrowser.open(modifiedURL, '_blank', surveylaunch.options);
        iab.addEventListener('loaderror', function(event) {
          Logger.displayError("Unable to launch survey", event);
          return Promise.reject();
        });
        if (opts.autoCloseURL) {
          return new Promise((resolve, reject) => {
            const autoClose = function(event) {
              console.log("started loading, event = " + JSON.stringify(event));
              if (opts.autoCloseURL.includes(event.url)) {
                iab.removeEventListener('loadstart', autoClose);
                iab.close();
                return resolve();
              }
            };
            iab.addEventListener('loadstart', autoClose);
          });
        }
        return Promise.resolve();
      });
    }

    surveylaunch.init = function() {
      $rootScope.$on('cloud:push:notification', function(event, data) {
        ClientStats.addEvent(ClientStats.getStatKeys().NOTIFICATION_OPEN).then(
            function() {
                console.log("Added "+ClientStats.getStatKeys().NOTIFICATION_OPEN+" event. Data = " + JSON.stringify(data));
              });
        Logger.log("data = "+JSON.stringify(data));
        if (angular.isDefined(data.additionalData) &&
            angular.isDefined(data.additionalData.payload) &&
            angular.isDefined(data.additionalData.payload.alert_type) &&
            data.additionalData.payload.alert_type == "survey") {
            var survey_spec = data.additionalData.payload.spec;
            if (angular.isDefined(survey_spec) &&
                angular.isDefined(survey_spec.url)) {
                if (angular.isDefined(survey_spec.uuidElementId)) {
                  surveylaunch.startSurveyWithID(survey_spec.url, survey_spec.uuidElementId);
                } else if (angular.isDefined(survey_spec.uuidXPath)) {
                  surveylaunch.startSurveyWithXPath(survey_spec.url, survey_spec.uuidXPath);
                } else if (angular.isDefined(survey_spec.uuidSearchParam)) {
                  surveylaunch.startSurveyPrefilled(survey_spec.url, {
                    uuidSearchParam: survey_spec.uuidSearchParam
                  });
                } else {
                    $ionicPopup.alert("survey was not specified correctly. spec is "+JSON.stringify(survey_spec));
                }
            } else {
                $ionicPopup.alert("survey was not specified correctly. spec is "+JSON.stringify(survey_spec));
            }
        }
      });
    };

    surveylaunch.init();
    return surveylaunch;
});
<|endoftext|>


<commit_before>'use strict';

var fs           = require('fs'),
    _path        = require('path'),
    _            = require('lodash'),
    async        = require('async'),
    checksum     = require('checksum'),
    tools        = require('../tools'),
    constants    = require('../constants'),
    log          = require('debug')('imdone-mixins:repo-fs-store'),
    File         = require('../file'),
    Config       = require('../config'),
    languages    = require('../languages'),
    isBinaryFile = require('isbinaryfile'),
    dir          = require('node-dir');

module.exports = mixin;

var CONFIG_DIR  = constants.CONFIG_DIR,
    CONFIG_FILE = constants.CONFIG_FILE,
    NO_CONTENT  = constants.ERRORS.NO_CONTENT,
    ASYNC_LIMIT = constants.ASYNC_LIMIT;

function getRegExp(s) {
  var re;
  try {
    re = new RegExp(s);
  } catch(e) {}
  return re;
}

function mixin(repo, fs) {
  fs = fs || require('fs');

  repo.init = function(cb) {
    log("Initializing repo:", repo.path);
    cb = tools.cb(cb);
    repo.initializing = true;
    fs.stat(repo.path, function(err, stat) {
      if (err || !stat.isDirectory()) {
        var error = new Error("Path must be an existing directory on the file system");
        repo.emit('error', error);
        repo.initializing = false;
        return cb(error);
      }

      repo.loadConfig(function(err, config) {
        if (err) {
          repo.emit('error', err);
          repo.initializing = false;
          return cb(err);
        }
        repo.emit('config.loaded');
        repo.saveConfig();
        repo.initPlugins();
        repo.createListeners();
        repo.readFiles(function(err, files) {
          repo.initializing = false;
          if (err && repo.destroyed) return cb(err);
          repo.initialized = true;
          repo.emit('initialized', {ok:true});
          if (err) repo.emit('error', err);
          cb(err, files);
        });

      });
    });
  };

  repo.loadIgnore = function() {
    repo.globs = [];
    var ignoreFile = _path.join(repo.path, constants.IGNORE_FILE);
    if (!fs.existsSync(ignoreFile)) return;
    repo.setIgnores(fs.readFileSync(ignoreFile).toString());
  };

  repo.fileStats = function(cb) {
    log("Getting file stats for repo:", repo.path);
    cb = tools.cb(cb);
    fs.stat(repo.path, function(err, stat) {
      if (err || !stat.isDirectory()) return cb(new Error("Path must be an existing directory on the file system"));
      repo.loadConfig(function(err, config) {
        if (err) return cb(err);
        repo.config = config;
        dir.files(repo.path, function (err, files) {
          if (err) return cb(err);
          var goodFiles = files.filter(function(file) {
            return !repo.shouldExclude(repo.getRelativePath(file));
          });
          cb(null, goodFiles);
        });
        // DONE: Just count the files and check if shouldExclude +performance id:22
      });
    });
  };

  repo.fileOK = function(file, includeDirs, cb) {
    if (File.isFile(file)) file = file.path;
    if (_.isFunction(includeDirs)) {
      cb = includeDirs;
      includeDirs = false;
    }
    cb = tools.cb(cb);
    if (this.shouldExclude(file)) return cb(null, false); // stack-2 repo-fs-store.js:105:42
    var fullPath = repo.getFullPath(file);
    fs.stat(fullPath, function(err, stat) {
      if (err) return cb(err);
      if ( /\.\.(\/|\\)/.test(file) || (!includeDirs && stat.isDirectory())) return cb(null, false);
      if (stat.isFile()) {
        isBinaryFile(fullPath, function(err, result) {
          if (err || result) return cb(null, false);
          cb(null, stat);
        });
      } else if (includeDirs && stat.isDirectory()) {
        cb(null, stat);
      } else cb(null, false);
    });
  };

  repo.saveConfig = function(cb) {
    repo.savingConfig = true;
    cb = tools.cb(cb);
    var _cb = function(err, resp) {
      repo.savingConfig = false;
      cb(err, resp);
    };
    var dir = repo.getFullPath(CONFIG_DIR);
    var file = repo.getFullPath(CONFIG_FILE);
    fs.exists(dir, function(exists) {
      var json = JSON.stringify(repo.getConfig(), null, 2);
      if (exists) {
        fs.writeFile(file, json, _cb);
      } else {
        fs.mkdir(dir, function(err) {
          if (err) return _cb(err);
          fs.writeFile(file, json, _cb);
        });
      }
    });
  };

  function newConfig(loadedConfig) {
    var baseConfig = _.cloneDeep(constants.DEFAULT_CONFIG);
    repo.config = new Config(_.assign({}, baseConfig, repo.config, loadedConfig))
    var _languages = _.cloneDeep(languages);
    repo.languages = (repo.config.languages) ? _.assign(_languages, repo.config.languages) : _languages;
    return repo.config;
  }

  repo.loadConfig = function(cb) {
    // TODO: If a config is bad move it to config.json.bak and save a new one with defaults +enhancement +standup +chore gh:2 id:10
    cb = tools.cb(cb);
    repo.loadIgnore();
    var file = repo.getFullPath(CONFIG_FILE);
    fs.exists(file, function(exists) {
      if (exists) {
        fs.readFile(file, function(err, data) {
          if (err) return cb(err);
          var configLike = {};
          try {
            configLike = JSON.parse(data.toString());
          } catch (e) {/* noop */}
          cb(null, newConfig(configLike));
        });
      } else {
        cb(null, newConfig({}));
      }
    });
  };

  var _deleteTasks = repo.deleteTasks;
  repo.deleteTasks = function(tasks, cb) {
      _deleteTasks.call(repo, tasks, false, function(err) {
        if (err) return cb(err);
        repo.saveModifiedFiles(function(err, files) {
          repo.emit('tasks.updated', tasks);
        });
      });
  };

  repo.writeFile = function(file, emitFileUpdate, cb) {
    if (_.isFunction(emitFileUpdate)) {
      cb = emitFileUpdate;
      emitFileUpdate = false;
    }
    cb = tools.cb(cb);
    if (!File.isFile(file)) return cb(new Error(constants.ERRORS.NOT_A_FILE));
    var filePath = repo.getFullPath(file);

    if (!/\.\.(\/|\\)/.test(file.path)) {
      // If dir does not exist create it
      var dirName = _path.dirname(filePath);

      var write = function() {
        if (!file.content) return cb(NO_CONTENT);
        var oldChecksum = file.checksum;
        file.checksum = checksum(file.content);
        fs.writeFile(filePath, file.content, 'utf8', function(err) {
          if (err) {
            file.checksum = oldChecksum;
            return cb([new Error("Unable to write file:" + filePath), err]);
          }

          fs.stat(filePath, function(err, stats) {
            if (err) return cb([new Error("Unable to stat file:" + filePath), err]);

            file.setModifiedTime(stats.mtime);
            file.modified = false;
            repo.extractTasks(file, function(err, file) {

              if (err) return cb(new Error("Unable to extract tasks for file:" + filePath));
              repo.addFile(file, function(err) {
                if (err) return cb(new Error("Unable to add file:" + filePath));
                if (emitFileUpdate) repo.emit('file.saved', file);
                cb(null, file);
              });
            });
          });
        });
      };

      fs.exists(dirName, function(exists) {
        if (exists) return write();

        tools.mkdirp(fs, dirName, function(err) {
          if (err) return cb(err);
          else write();
        });
      });
      //log("file:%s", JSON.stringify(file, null, 5));

    } else return cb(new Error("Unable to write file:" + file.path), file);
  };

  repo.getFilesInPath = function(includeDirs, cb) {
    cb = tools.cb(cb);
    dir.files(repo.path, function(err, allPaths) {
      if (err) return cb(err);
      allPaths = allPaths.filter(function(file) {
        return !repo.shouldExclude(repo.getRelativePath(file));
      });
      var files = [], processed = 0;
      log('allPaths=', allPaths);
      if (allPaths.length === 0) return cb(null, []);
      async.eachLimit(allPaths, ASYNC_LIMIT, function(path, _cb) {
        if (!path) return _cb();
        path = repo.getRelativePath(path);
        repo.fileOK(path, includeDirs, function(err, stat) { // stack-3 repo-fs-store.js:250:14
          processed++;
          if (err) return _cb(err);
          repo.emit("file.processed", {
            file: path,
            ok: (stat !== false),
            total: allPaths.length,
            processed: processed+1,
            repoId: repo.getId()
          });

          if (stat) {
            log("%s is ok %j", path, stat);
            var file = new File({repoId: repo.getId(), filePath: path, modifiedTime: stat.mtime, languages: repo.languages});
            file.isDir = stat.isDirectory();
            files.push(file);
          }
          log('err=%j', err, null);
          log('stat=%j', stat, null);
          log('processed=%d allPaths.length=%d', processed, allPaths.length);
          _cb(); // stack-1 repo-fs-store.js:270:11
        });

      }, function(err) {
        cb(err, _.sortBy(files, "path"));
      });
    });
  };

  repo.getFileTree = function(path, cb) {
    var out = {};
    var waitCount = 0;

    if (_.isFunction(path)) {
      cb = path;
      path = repo.path;
    }

    cb = tools.cb(cb);

    var getFileTree = function(path, _out, cb) {
      log("Path:", path);

      waitCount++;
      dir.files(path, function(err, files) {
        if (err) return cb(err);
        waitCount--;

        files = files.filter(function(file) {
          return !repo.shouldExclude(repo.getRelativePath(file));
        });
        _.each(files, function(file) {
          var fullPath = _path.join(path, file);
          var relPath = repo.getRelativePath(fullPath);
          waitCount++;
          repo.fileOK(relPath, true, function(err, stats) {
            if (err) return cb(err);
            waitCount--;
            if (!stats) return;
            var this_out = { name: _path.basename(file), path: relPath };
            if (stats.isDirectory()) {
              if(!_out.dirs) _out.dirs = [];
              _out.dirs.push(this_out);
              getFileTree(fullPath, this_out, cb);
            } else {
              if(!_out.files) _out.files = [];
              _out.files.push(this_out);
            }
            if (waitCount === 0) cb(null, out);
          });
        });

        if (waitCount === 0) cb(null, out);
      });
    };

    getFileTree(path, out, cb);

  };

  repo.readFileContent = function(file, cb) {
    cb = tools.cb(cb);
    if (!File.isFile(file)) return cb(new Error(constants.ERRORS.NOT_A_FILE));
    var filePath = repo.getFullPath(file);

    fs.stat(filePath, function(err, stats) {
      if (err) return cb([new Error("Unable to stat file:" + filePath), err]);
      fs.readFile(filePath, 'utf8', function(err, data) {
        if (err) return cb([new Error("Unable to read file:" + filePath), err]);
        file.setContent(data).setModifiedTime(stats.mtime);
        cb(null, file);
      });
    });
  };

  repo.deleteFile = function(path, cb) {
    cb = tools.cb(cb);
    var file = repo.getFile(path);
    if (!_.isUndefined(file)) {
      fs.unlink(repo.getFullPath(file), function (err) {
        if (err) return cb("Unable to delete:" + path + " : " + err.toString());
        repo.removeFile(file);
        cb(null, file);
      });
    } else cb("Unable to delete:" + path);
  };

  return repo;
}
<commit_msg>Fix lint<commit_after>'use strict';

var fs           = require('fs'),
    _path        = require('path'),
    _            = require('lodash'),
    async        = require('async'),
    checksum     = require('checksum'),
    tools        = require('../tools'),
    constants    = require('../constants'),
    log          = require('debug')('imdone-mixins:repo-fs-store'),
    File         = require('../file'),
    Config       = require('../config'),
    languages    = require('../languages'),
    isBinaryFile = require('isbinaryfile'),
    dir          = require('node-dir');

module.exports = mixin;

var CONFIG_DIR  = constants.CONFIG_DIR,
    CONFIG_FILE = constants.CONFIG_FILE,
    NO_CONTENT  = constants.ERRORS.NO_CONTENT,
    ASYNC_LIMIT = constants.ASYNC_LIMIT;

function getRegExp(s) {
  var re;
  try {
    re = new RegExp(s);
  } catch(e) {}
  return re;
}

function mixin(repo, fs) {
  fs = fs || require('fs');

  repo.init = function(cb) {
    log("Initializing repo:", repo.path);
    cb = tools.cb(cb);
    repo.initializing = true;
    fs.stat(repo.path, function(err, stat) {
      if (err || !stat.isDirectory()) {
        var error = new Error("Path must be an existing directory on the file system");
        repo.emit('error', error);
        repo.initializing = false;
        return cb(error);
      }

      repo.loadConfig(function(err, config) {
        if (err) {
          repo.emit('error', err);
          repo.initializing = false;
          return cb(err);
        }
        repo.emit('config.loaded');
        repo.saveConfig();
        repo.initPlugins();
        repo.createListeners();
        repo.readFiles(function(err, files) {
          repo.initializing = false;
          if (err && repo.destroyed) return cb(err);
          repo.initialized = true;
          repo.emit('initialized', {ok:true});
          if (err) repo.emit('error', err);
          cb(err, files);
        });

      });
    });
  };

  repo.loadIgnore = function() {
    repo.globs = [];
    var ignoreFile = _path.join(repo.path, constants.IGNORE_FILE);
    if (!fs.existsSync(ignoreFile)) return;
    repo.setIgnores(fs.readFileSync(ignoreFile).toString());
  };

  repo.fileStats = function(cb) {
    log("Getting file stats for repo:", repo.path);
    cb = tools.cb(cb);
    fs.stat(repo.path, function(err, stat) {
      if (err || !stat.isDirectory()) return cb(new Error("Path must be an existing directory on the file system"));
      repo.loadConfig(function(err, config) {
        if (err) return cb(err);
        repo.config = config;
        dir.files(repo.path, function (err, files) {
          if (err) return cb(err);
          var goodFiles = files.filter(function(file) {
            return !repo.shouldExclude(repo.getRelativePath(file));
          });
          cb(null, goodFiles);
        });
        // DONE: Just count the files and check if shouldExclude +performance id:22
      });
    });
  };

  repo.fileOK = function(file, includeDirs, cb) {
    if (File.isFile(file)) file = file.path;
    if (_.isFunction(includeDirs)) {
      cb = includeDirs;
      includeDirs = false;
    }
    cb = tools.cb(cb);
    if (this.shouldExclude(file)) return cb(null, false); // stack-2 repo-fs-store.js:105:42
    var fullPath = repo.getFullPath(file);
    fs.stat(fullPath, function(err, stat) {
      if (err) return cb(err);
      if ( /\.\.(\/|\\)/.test(file) || (!includeDirs && stat.isDirectory())) return cb(null, false);
      if (stat.isFile()) {
        isBinaryFile(fullPath, function(err, result) {
          if (err || result) return cb(null, false);
          cb(null, stat);
        });
      } else if (includeDirs && stat.isDirectory()) {
        cb(null, stat);
      } else cb(null, false);
    });
  };

  repo.saveConfig = function(cb) {
    repo.savingConfig = true;
    cb = tools.cb(cb);
    var _cb = function(err, resp) {
      repo.savingConfig = false;
      cb(err, resp);
    };
    var dir = repo.getFullPath(CONFIG_DIR);
    var file = repo.getFullPath(CONFIG_FILE);
    fs.exists(dir, function(exists) {
      var json = JSON.stringify(repo.getConfig(), null, 2);
      if (exists) {
        fs.writeFile(file, json, _cb);
      } else {
        fs.mkdir(dir, function(err) {
          if (err) return _cb(err);
          fs.writeFile(file, json, _cb);
        });
      }
    });
  };

  function newConfig(loadedConfig) {
    var baseConfig = _.cloneDeep(constants.DEFAULT_CONFIG);
    repo.config = new Config(_.assign({}, baseConfig, repo.config, loadedConfig));
    var _languages = _.cloneDeep(languages);
    repo.languages = (repo.config.languages) ? _.assign(_languages, repo.config.languages) : _languages;
    return repo.config;
  }

  repo.loadConfig = function(cb) {
    // TODO: If a config is bad move it to config.json.bak and save a new one with defaults +enhancement +standup +chore gh:2 id:10
    cb = tools.cb(cb);
    repo.loadIgnore();
    var file = repo.getFullPath(CONFIG_FILE);
    fs.exists(file, function(exists) {
      if (exists) {
        fs.readFile(file, function(err, data) {
          if (err) return cb(err);
          var configLike = {};
          try {
            configLike = JSON.parse(data.toString());
          } catch (e) {/* noop */}
          cb(null, newConfig(configLike));
        });
      } else {
        cb(null, newConfig({}));
      }
    });
  };

  var _deleteTasks = repo.deleteTasks;
  repo.deleteTasks = function(tasks, cb) {
      _deleteTasks.call(repo, tasks, false, function(err) {
        if (err) return cb(err);
        repo.saveModifiedFiles(function(err, files) {
          repo.emit('tasks.updated', tasks);
        });
      });
  };

  repo.writeFile = function(file, emitFileUpdate, cb) {
    if (_.isFunction(emitFileUpdate)) {
      cb = emitFileUpdate;
      emitFileUpdate = false;
    }
    cb = tools.cb(cb);
    if (!File.isFile(file)) return cb(new Error(constants.ERRORS.NOT_A_FILE));
    var filePath = repo.getFullPath(file);

    if (!/\.\.(\/|\\)/.test(file.path)) {
      // If dir does not exist create it
      var dirName = _path.dirname(filePath);

      var write = function() {
        if (!file.content) return cb(NO_CONTENT);
        var oldChecksum = file.checksum;
        file.checksum = checksum(file.content);
        fs.writeFile(filePath, file.content, 'utf8', function(err) {
          if (err) {
            file.checksum = oldChecksum;
            return cb([new Error("Unable to write file:" + filePath), err]);
          }

          fs.stat(filePath, function(err, stats) {
            if (err) return cb([new Error("Unable to stat file:" + filePath), err]);

            file.setModifiedTime(stats.mtime);
            file.modified = false;
            repo.extractTasks(file, function(err, file) {

              if (err) return cb(new Error("Unable to extract tasks for file:" + filePath));
              repo.addFile(file, function(err) {
                if (err) return cb(new Error("Unable to add file:" + filePath));
                if (emitFileUpdate) repo.emit('file.saved', file);
                cb(null, file);
              });
            });
          });
        });
      };

      fs.exists(dirName, function(exists) {
        if (exists) return write();

        tools.mkdirp(fs, dirName, function(err) {
          if (err) return cb(err);
          else write();
        });
      });
      //log("file:%s", JSON.stringify(file, null, 5));

    } else return cb(new Error("Unable to write file:" + file.path), file);
  };

  repo.getFilesInPath = function(includeDirs, cb) {
    cb = tools.cb(cb);
    dir.files(repo.path, function(err, allPaths) {
      if (err) return cb(err);
      allPaths = allPaths.filter(function(file) {
        return !repo.shouldExclude(repo.getRelativePath(file));
      });
      var files = [], processed = 0;
      log('allPaths=', allPaths);
      if (allPaths.length === 0) return cb(null, []);
      async.eachLimit(allPaths, ASYNC_LIMIT, function(path, _cb) {
        if (!path) return _cb();
        path = repo.getRelativePath(path);
        repo.fileOK(path, includeDirs, function(err, stat) { // stack-3 repo-fs-store.js:250:14
          processed++;
          if (err) return _cb(err);
          repo.emit("file.processed", {
            file: path,
            ok: (stat !== false),
            total: allPaths.length,
            processed: processed+1,
            repoId: repo.getId()
          });

          if (stat) {
            log("%s is ok %j", path, stat);
            var file = new File({repoId: repo.getId(), filePath: path, modifiedTime: stat.mtime, languages: repo.languages});
            file.isDir = stat.isDirectory();
            files.push(file);
          }
          log('err=%j', err, null);
          log('stat=%j', stat, null);
          log('processed=%d allPaths.length=%d', processed, allPaths.length);
          _cb(); // stack-1 repo-fs-store.js:270:11
        });

      }, function(err) {
        cb(err, _.sortBy(files, "path"));
      });
    });
  };

  repo.getFileTree = function(path, cb) {
    var out = {};
    var waitCount = 0;

    if (_.isFunction(path)) {
      cb = path;
      path = repo.path;
    }

    cb = tools.cb(cb);

    var getFileTree = function(path, _out, cb) {
      log("Path:", path);

      waitCount++;
      dir.files(path, function(err, files) {
        if (err) return cb(err);
        waitCount--;

        files = files.filter(function(file) {
          return !repo.shouldExclude(repo.getRelativePath(file));
        });
        _.each(files, function(file) {
          var fullPath = _path.join(path, file);
          var relPath = repo.getRelativePath(fullPath);
          waitCount++;
          repo.fileOK(relPath, true, function(err, stats) {
            if (err) return cb(err);
            waitCount--;
            if (!stats) return;
            var this_out = { name: _path.basename(file), path: relPath };
            if (stats.isDirectory()) {
              if(!_out.dirs) _out.dirs = [];
              _out.dirs.push(this_out);
              getFileTree(fullPath, this_out, cb);
            } else {
              if(!_out.files) _out.files = [];
              _out.files.push(this_out);
            }
            if (waitCount === 0) cb(null, out);
          });
        });

        if (waitCount === 0) cb(null, out);
      });
    };

    getFileTree(path, out, cb);

  };

  repo.readFileContent = function(file, cb) {
    cb = tools.cb(cb);
    if (!File.isFile(file)) return cb(new Error(constants.ERRORS.NOT_A_FILE));
    var filePath = repo.getFullPath(file);

    fs.stat(filePath, function(err, stats) {
      if (err) return cb([new Error("Unable to stat file:" + filePath), err]);
      fs.readFile(filePath, 'utf8', function(err, data) {
        if (err) return cb([new Error("Unable to read file:" + filePath), err]);
        file.setContent(data).setModifiedTime(stats.mtime);
        cb(null, file);
      });
    });
  };

  repo.deleteFile = function(path, cb) {
    cb = tools.cb(cb);
    var file = repo.getFile(path);
    if (!_.isUndefined(file)) {
      fs.unlink(repo.getFullPath(file), function (err) {
        if (err) return cb("Unable to delete:" + path + " : " + err.toString());
        repo.removeFile(file);
        cb(null, file);
      });
    } else cb("Unable to delete:" + path);
  };

  return repo;
}
<|endoftext|>


<commit_before>const os = require('os')

const host = os.hostname().toLowerCase()
const rxrc = 'node_modules/@rxrc'

const targetRoot = '/'

const ioType = 'linux'
const pkgType = 'pacman'

const defaults = {
  dmode: '0755',
  fmode: '0644',
  user: 'root',
  group: 'root'
}

const unlinks = []

const directories = [{
  src: `${rxrc}/systemd-units/system/user@.service.d`,
  dst: 'etc/systemd/system/user@.service.d'
}]

const files = [{
  src: `etc/mkinitcpio.${host}.conf`,
  dst: `etc/mkinitcpio.conf`,
  pkgs: ['mkinitcpio']
}, {
  src: 'etc/locale.gen'
}, {
  src: 'etc/locale.conf'
}, {
  src: 'etc/sysctl.d/99-sysctl.conf'
}, {
  src: `${rxrc}/archrc-private/etc/fstab.${host}`,
  dst: `etc/fstab`
}, {
  src: `${rxrc}/archrc-private/refind/refind.conf`,
  dst: 'boot/efi/EFI/refind/refind.conf',
  hosts: ['Sleipnir']
}, {
  src: `${rxrc}/archrc-private/refind/refind_linux.${host}.conf`,
  dst: 'boot/refind_linux.conf',
  hosts: ['Sleipnir']
}, {
  src: `${rxrc}/archrc-private/loader/loader.conf`,
  dst: 'boot/efi/loader/loader.conf',
  hosts: ['Frigg']
}, {
  src: `${rxrc}/archrc-private/loader/entries/arch.conf`,
  dst: `boot/efi/loader/entries/arch.${host}.conf`,
  hosts: ['Frigg']
}, {
  src: `etc/default/grub`,
  pkgs: ['grub'],
  hosts: ['Frigg']
}, {
  src: `etc/default/grub.${host}`,
  dst: `etc/default/grub`,
  pkgs: ['grub'],
  hosts: ['Gungnir']
}, {
  src: `${rxrc}/systemd-units/system/efistub-update@.path`,
  dst: 'etc/systemd/system/efistub-update@.path',
  pkgs: ['efibootmgr']
}, {
  src: `${rxrc}/systemd-units/system/efistub-update@.service`,
  dst: 'etc/systemd/system/efistub-update@.service',
  pkgs: ['efibootmgr']
}, {
  src: `${rxrc}/systemd-units/system/efistub-ucode-update@.path`,
  dst: 'etc/systemd/system/efistub-ucode-update@.path',
  pkgs: ['efibootmgr', 'intel-ucode']
}, {
  src: `${rxrc}/systemd-units/system/efistub-ucode-update@.service`,
  dst: 'etc/systemd/system/efistub-ucode-update@.service',
  pkgs: ['efibootmgr', 'intel-ucode']
}, {
  src: `${rxrc}/systemd-units/system/refind-update.path`,
  dst: 'etc/systemd/system/refind-update.path',
  pkgs: ['refind-efi']
}, {
  src: `${rxrc}/systemd-units/system/refind-update.service`,
  dst: 'etc/systemd/system/refind-update.service'
}, {
  src: `${rxrc}/systemd-units/system/netctl-auto-resume@.service`,
  dst: 'etc/systemd/system/netctl-auto-resume@.service'
}, {
  src: 'etc/pacman.conf',
  pkgs: ['pacman']
}, {
  src: 'etc/nftables.conf',
  pkgs: ['nftables']
}, {
  src: 'etc/sudoers',
  fmode: '0440',
  pkgs: ['sudo']
}, {
  src: 'etc/ssh/sshd_config',
  pkgs: ['openssh']
}, {
  src: `etc/systemd/network/wired.${host}.network`,
  hosts: ['Mimir', 'Sleipnir']
}, {
  src: 'etc/systemd/journald.conf.d/size.conf',
  hosts: ['Gungnir']
}, {
  src: 'etc/udev/rules.d/99-lowbat.rules',
  hosts: ['Gungnir']
}, {
  src: 'etc/modules-load.d/virtualbox.conf',
  pkgs: ['virtualbox']
}, {
  src: 'etc/modprobe.d/alsa-base.conf',
  pkgs: ['linux-samus4']
}, {
  src: `etc/X11/xorg.conf.d/10-monitor.${host}.conf`,
  hosts: ['Mimir']
}, {
  src: 'etc/X11/xorg.conf.d/15-dpms.conf'
}, {
  src: 'etc/X11/xorg.conf.d/20-intel.conf',
  pkgs: ['xf86-video-intel'],
  hosts: ['Frigg']
}, {
  src: `etc/X11/xorg.conf.d/20-intel.${host}.conf`,
  dst: 'etc/X11/xorg.conf.d/20-intel.conf',
  pkgs: ['xf86-video-intel'],
  hosts: ['Gungnir']
}, {
  src: 'etc/X11/xorg.conf.d/10-keyboard.conf',
  pkgs: ['xkeyboard-config-chromebook']
}, {
  src: 'etc/X11/xorg.conf.d/50-synaptics.conf',
  pkgs: ['xf86-input-synaptics'],
  hosts: ['Gungnir']
}, {
  src: 'etc/X11/xorg.conf.d/50-mtrack.conf',
  pkgs: ['xf86-input-mtrack-git'],
  hosts: ['Frigg']
}, {
  src: `${rxrc}/systemd-units/logind.conf.d/acpi.conf`,
  dst: 'etc/systemd/logind.conf.d/acpi.conf'
}, {
  src: `${rxrc}/systemd-units/coredump.conf.d/disable.conf`,
  dst: 'etc/systemd/coredump.conf.d/disable.conf'
}, {
  src: 'etc/systemd/system/chromeos-kbd_backlight.service',
  pkgs: ['linux-samus4']
}, {
  src: `${rxrc}/systemd-units/system/numlock.service`,
  dst: 'etc/systemd/system/numlock.service'
}, {
  src: `${rxrc}/systemd-units/system/xscreensaver-lock@.service`,
  dst: 'etc/systemd/system/xscreensaver-lock@.service',
  pkgs: ['xscreensaver-arch-logo']
}, {
  src: 'etc/lightdm/lightdm.conf',
  pkgs: ['lightdm']
}, {
  src: 'etc/lightdm/lightdm-gtk-greeter.conf',
  pkgs: ['lightdm-gtk-greeter']
}, {
  src: `${rxrc}/archrc-private/etc/samba/smb.${host}.conf`,
  dst: 'etc/samba/smb.conf',
  pkgs: ['samba']
}, {
  src: `${rxrc}/archrc-private/etc/samba/users.${host}.map`,
  dst: 'etc/samba/users.map',
  pkgs: ['samba']
}, {
  src: `${rxrc}/archrc-private/etc/nginx/nginx.${host}.conf`,
  dst: 'etc/nginx/nginx.conf',
  pkgs: ['nginx']
}, {
  src: `node_modules/@razor-x/archutil/bin/archutil`,
  dst: 'usr/local/bin/archutil',
  fmode: '0755'
}, {
  src: 'archutil.yml',
  dst: 'usr/local/etc/archutil.yml'
}, {
  src: 'usr/local/bin/xcleanup',
  fmode: '0755',
  pkgs: ['lightdm']
}, {
  src: 'usr/local/bin/touchpad-toggle',
  fmode: '0755',
  pkgs: ['xf86-input-synaptics']
}, {
  src: 'usr/local/bin/chromeos-kbd_backlight',
  fmode: '0755',
  pkgs: ['linux-samus4']
}, {
  src: 'usr/local/bin/chromeos-sound-output-toggle',
  fmode: '0755',
  pkgs: ['linux-samus4']
}]

const symlinks = []

module.exports = {
  unlinks,
  directories,
  files,
  symlinks,
  targetRoot,
  ioType,
  pkgType,
  defaults
}
<commit_msg>Use ' over ` in manifest<commit_after>const os = require('os')

const host = os.hostname().toLowerCase()
const rxrc = 'node_modules/@rxrc'

const targetRoot = '/'

const ioType = 'linux'
const pkgType = 'pacman'

const defaults = {
  dmode: '0755',
  fmode: '0644',
  user: 'root',
  group: 'root'
}

const unlinks = []

const directories = [{
  src: `${rxrc}/systemd-units/system/user@.service.d`,
  dst: 'etc/systemd/system/user@.service.d'
}]

const files = [{
  src: `etc/mkinitcpio.${host}.conf`,
  dst: 'etc/mkinitcpio.conf',
  pkgs: ['mkinitcpio']
}, {
  src: 'etc/locale.gen'
}, {
  src: 'etc/locale.conf'
}, {
  src: 'etc/sysctl.d/99-sysctl.conf'
}, {
  src: `${rxrc}/archrc-private/etc/fstab.${host}`,
  dst: 'etc/fstab'
}, {
  src: `${rxrc}/archrc-private/refind/refind.conf`,
  dst: 'boot/efi/EFI/refind/refind.conf',
  hosts: ['Sleipnir']
}, {
  src: `${rxrc}/archrc-private/refind/refind_linux.${host}.conf`,
  dst: 'boot/refind_linux.conf',
  hosts: ['Sleipnir']
}, {
  src: `${rxrc}/archrc-private/loader/loader.conf`,
  dst: 'boot/efi/loader/loader.conf',
  hosts: ['Frigg']
}, {
  src: `${rxrc}/archrc-private/loader/entries/arch.conf`,
  dst: `boot/efi/loader/entries/arch.${host}.conf`,
  hosts: ['Frigg']
}, {
  src: 'etc/default/grub',
  pkgs: ['grub'],
  hosts: ['Frigg']
}, {
  src: `etc/default/grub.${host}`,
  dst: 'etc/default/grub',
  pkgs: ['grub'],
  hosts: ['Gungnir']
}, {
  src: `${rxrc}/systemd-units/system/efistub-update@.path`,
  dst: 'etc/systemd/system/efistub-update@.path',
  pkgs: ['efibootmgr']
}, {
  src: `${rxrc}/systemd-units/system/efistub-update@.service`,
  dst: 'etc/systemd/system/efistub-update@.service',
  pkgs: ['efibootmgr']
}, {
  src: `${rxrc}/systemd-units/system/efistub-ucode-update@.path`,
  dst: 'etc/systemd/system/efistub-ucode-update@.path',
  pkgs: ['efibootmgr', 'intel-ucode']
}, {
  src: `${rxrc}/systemd-units/system/efistub-ucode-update@.service`,
  dst: 'etc/systemd/system/efistub-ucode-update@.service',
  pkgs: ['efibootmgr', 'intel-ucode']
}, {
  src: `${rxrc}/systemd-units/system/refind-update.path`,
  dst: 'etc/systemd/system/refind-update.path',
  pkgs: ['refind-efi']
}, {
  src: `${rxrc}/systemd-units/system/refind-update.service`,
  dst: 'etc/systemd/system/refind-update.service'
}, {
  src: `${rxrc}/systemd-units/system/netctl-auto-resume@.service`,
  dst: 'etc/systemd/system/netctl-auto-resume@.service'
}, {
  src: 'etc/pacman.conf',
  pkgs: ['pacman']
}, {
  src: 'etc/nftables.conf',
  pkgs: ['nftables']
}, {
  src: 'etc/sudoers',
  fmode: '0440',
  pkgs: ['sudo']
}, {
  src: 'etc/ssh/sshd_config',
  pkgs: ['openssh']
}, {
  src: `etc/systemd/network/wired.${host}.network`,
  hosts: ['Mimir', 'Sleipnir']
}, {
  src: 'etc/systemd/journald.conf.d/size.conf',
  hosts: ['Gungnir']
}, {
  src: 'etc/udev/rules.d/99-lowbat.rules',
  hosts: ['Gungnir']
}, {
  src: 'etc/modules-load.d/virtualbox.conf',
  pkgs: ['virtualbox']
}, {
  src: 'etc/modprobe.d/alsa-base.conf',
  pkgs: ['linux-samus4']
}, {
  src: `etc/X11/xorg.conf.d/10-monitor.${host}.conf`,
  dst: 'etc/X11/xorg.conf.d/10-monitor.conf',
  hosts: ['Mimir']
}, {
  src: 'etc/X11/xorg.conf.d/15-dpms.conf'
}, {
  src: 'etc/X11/xorg.conf.d/20-intel.conf',
  pkgs: ['xf86-video-intel'],
  hosts: ['Frigg']
}, {
  src: `etc/X11/xorg.conf.d/20-intel.${host}.conf`,
  dst: 'etc/X11/xorg.conf.d/20-intel.conf',
  pkgs: ['xf86-video-intel'],
  hosts: ['Gungnir']
}, {
  src: 'etc/X11/xorg.conf.d/10-keyboard.conf',
  pkgs: ['xkeyboard-config-chromebook']
}, {
  src: 'etc/X11/xorg.conf.d/50-synaptics.conf',
  pkgs: ['xf86-input-synaptics'],
  hosts: ['Gungnir']
}, {
  src: 'etc/X11/xorg.conf.d/50-mtrack.conf',
  pkgs: ['xf86-input-mtrack-git'],
  hosts: ['Frigg']
}, {
  src: `${rxrc}/systemd-units/logind.conf.d/acpi.conf`,
  dst: 'etc/systemd/logind.conf.d/acpi.conf'
}, {
  src: `${rxrc}/systemd-units/coredump.conf.d/disable.conf`,
  dst: 'etc/systemd/coredump.conf.d/disable.conf'
}, {
  src: 'etc/systemd/system/chromeos-kbd_backlight.service',
  pkgs: ['linux-samus4']
}, {
  src: `${rxrc}/systemd-units/system/numlock.service`,
  dst: 'etc/systemd/system/numlock.service'
}, {
  src: `${rxrc}/systemd-units/system/xscreensaver-lock@.service`,
  dst: 'etc/systemd/system/xscreensaver-lock@.service',
  pkgs: ['xscreensaver-arch-logo']
}, {
  src: 'etc/lightdm/lightdm.conf',
  pkgs: ['lightdm']
}, {
  src: 'etc/lightdm/lightdm-gtk-greeter.conf',
  pkgs: ['lightdm-gtk-greeter']
}, {
  src: `${rxrc}/archrc-private/etc/samba/smb.${host}.conf`,
  dst: 'etc/samba/smb.conf',
  pkgs: ['samba']
}, {
  src: `${rxrc}/archrc-private/etc/samba/users.${host}.map`,
  dst: 'etc/samba/users.map',
  pkgs: ['samba']
}, {
  src: `${rxrc}/archrc-private/etc/nginx/nginx.${host}.conf`,
  dst: 'etc/nginx/nginx.conf',
  pkgs: ['nginx']
}, {
  src: 'node_modules/@razor-x/archutil/bin/archutil',
  dst: 'usr/local/bin/archutil',
  fmode: '0755'
}, {
  src: 'archutil.yml',
  dst: 'usr/local/etc/archutil.yml'
}, {
  src: 'usr/local/bin/xcleanup',
  fmode: '0755',
  pkgs: ['lightdm']
}, {
  src: 'usr/local/bin/touchpad-toggle',
  fmode: '0755',
  pkgs: ['xf86-input-synaptics']
}, {
  src: 'usr/local/bin/chromeos-kbd_backlight',
  fmode: '0755',
  pkgs: ['linux-samus4']
}, {
  src: 'usr/local/bin/chromeos-sound-output-toggle',
  fmode: '0755',
  pkgs: ['linux-samus4']
}]

const symlinks = []

module.exports = {
  unlinks,
  directories,
  files,
  symlinks,
  targetRoot,
  ioType,
  pkgType,
  defaults
}
<|endoftext|>


<commit_before><commit_msg>fix(www): remove unnecessary quotation mark (#15709)<commit_after><|endoftext|>


<commit_before>var base = process.cwd().replace(/\\/g,"/")+"/client/Engine/Input",
    CreateKeyBoard = require(base+"/Keyboard/Keyboard"),
    CreateMouse = require(base+"/Mouse/Mouse");

module.exports = function(){
  var _environments = {
    default:{

    }
  },
  _mouse = CreateMouse(),
  _keyboard = CreateKeyBoard(),
  _environment = 'default',
  _onBindingUpdateEvents = {"*":[]},
  _itb = 0,
  _nameb = "*",
  _bindingUpdateEvent = function(e){
    /* e = name(String), added(object info), removed(String), environment(String) */

    /* Global listener */
    _nameb = "*";
    for(_itb=0;_itb<_onBindingUpdateEvents[_nameb].length;_itb++){
      if(typeof _onBindingUpdateEvents[_nameb][x] === 'function'){
        _onBindingUpdateEvents[_nameb][x](e);
      }
    }

    /* added name listener */
    _nameb = e.name;
    if(_onBindingUpdateEvents[_nameb] !== undefined){
      for(_itb=0;_itb<_onBindingUpdateEvents[_nameb].length;_itb++){
        if(typeof _onBindingUpdateEvents[_nameb][x] === 'function'){
          _onBindingUpdateEvents[_nameb][x](e);
        }
      }
    }

    /* removed name listener */
    _nameb = e.removed;
    if(_onBindingUpdateEvents[_nameb] !== undefined){
      for(_itb=0;_itb<_onBindingUpdateEvents[_nameb].length;_itb++){
        if(typeof _onBindingUpdateEvents[_nameb][x] === 'function'){
          _onBindingUpdateEvents[_nameb][x](e);
        }
      }
    }

  },
  _inputEvent = function(e){
    /* e = type(String), code(Int), key(String), shift(Bool), ctrl(Bool), alt(Bool), moveX(Int), moveY(Int) */
  }

  function Inputs(){
    Inputs.toggleListening('mouse',true);
    Inputs.toggleListening('keyboard',true);
  }

  Inputs.addBindingUpdateListener = function(name,func){
    if(typeof name === 'function'){
      _onBindingUpdateEvents["*"].push(name);
    }
    else if(typeof name === 'string'){
      if(_onBindingUpdateEvents[name] === undefined){
        _onBindingUpdateEvents[name] = [];
      }
      _onBindingUpdateEvents[name].push(func);
    }
    return Inputs;
  }

  Inputs.removeBindingUpdateListener = function(name,func){
    if(typeof name === 'function'){
      func = name;
      name = "*";
    }
    if(typeof name === 'string' && _onBindingUpdateEvents[name] !== undefined){
      loop:for(var x=0;x<_onBindingUpdateEvents[name].length;x++){
        if(func.toString() === _onBindingUpdateEvents[name][x].toString()){
          _onBindingUpdateEvents[name].splice(x,1);
        }
      }
    }
    return Inputs
  }

  Inputs.toggleListening = function(type,toggle){
    if(typeof type === 'string'){
      switch(type){
        case 'mouse':
          if(toggle){
            _mouseToggle = !toggle;
          }
          _mouse.removeMouseListener(_inputEvent);
          if(!_mouseToggle){
            _mouse.addMouseListener(_inputEvent).call();
          }
          _mouseToggle = !_mouseToggle;
        break;
        case 'keyboard':
          if(toggle){
            _keyboardToggle = !toggle;
          }
          _keyboard.removeKeyListener(_inputEvent);
          if(!_keyboardToggle){
            _keyboard.addKeyListener(_inputEvent).call();
          }
          _keyboardToggle = !_keyboardToggle;
        break;
      }
    }
    return Inputs;
  }

  Inputs.environment = function(v){
    if(v === undefined){
      return _environment;
    }
    _environment = (typeof v === 'string' && _environments[v] ? v : _environment);
    return Inputs;
  }

  Inputs.addEnvironment = function(v){
    if(typeof v === 'string' && !_environments[v]){
      _environments[v] = {};
    }
    return Inputs;
  }

  Inputs.removeEnvironment = function(v){
    if(typeof v === 'string' && v !== 'default'){
      _environments[v] = null;
    }
    return Inputs;
  }

  Inputs.addBinding = function(environment,name,type,key,func,shift,ctrl,alt){

    /* Overload for environment */
    var __environment = (typeof func === 'function' ? environment : 'default'),
        __name = (typeof func === 'function' ? name : environment),
        __type = (typeof func === 'function' ? type : name),
        __key = (typeof func === 'function' ? key : type),
        __func = (typeof func === 'function' ? func : key),
        __shift = (typeof func === 'function' ? shift : func),
        __ctrl = (typeof func === 'function' ? ctrl : shift),
        __alt = (typeof func === 'function' ? alt : ctrl),
        __readable,
        __bindings = {},
        __bindingKeys = [],
        __bindingKey = {},
        __removal = "";

    __readable = (__shift ? "Shift ": "")+(__ctrl ? "Ctrl " : "")+(__alt ? "Alt " : "")+__type;
    if(_environments[__environment]){
      __bindings = _environments[__environment];

      /* Overwrite Existing if There */
      __bindingKeys = Object.keys(__bindings);
      loop:for(var x=0;x<__bindingKeys.length;x++){
        __bindingKey = __bindings[__bindingKeys[x]];

        if(__bindingKey.key === __key && __bindingKey.type === __type && __bindingKey.shift === !!__shift && __bindingKey.ctrl === !!__ctrl && __bindingKey.alt === !!__alt){
          __bindings[__bindingKeys[x]] = null;
          __removal = __bindingKeys[x];
          break loop;
        }
      }
      __bindings[__name] = {readable:__readable,key:__key,type:__type,func:__func,shift:!!__shift,ctrl:!!__ctrl,alt:!!__alt};
      _bindingUpdateEvent({name:__name,added:__bindings[__name],removed:__removal,environment:__environment});
    }
    return Inputs;
  }

  Inputs.removeBinding = function(environment,name){
    var __environment = (name === undefined ? 'default' : environment),
        __name = (name === undefined ? environment : name);

    if(_environments[__environment]){
      _environments[__environment][__name] = null;
      _bindingUpdateEvent({added:undefined,removed:__name,environment:__environment});
    }
    return Inputs;
  }

  return Inputs;
}
<commit_msg>update and finish Input Section of Engine<commit_after>var base = process.cwd().replace(/\\/g,"/")+"/client/Engine/Input",
    CreateKeyBoard = require(base+"/Keyboard/Keyboard"),
    CreateMouse = require(base+"/Mouse/Mouse");

module.exports = function(){
  var _environments = {
        default:{

        }
      },
      _mouse = CreateMouse(),
      _keyboard = CreateKeyBoard(),
      _environment = 'default',
      _onBindingUpdateEvents = {"*":[]},
      _itb = 0,
      _nameb = "*",
      _bindingUpdateEvent = function(e){
        /* e = name(String), added(object info), removed(String), environment(String) */

        /* Global listener */
        _nameb = "*";
        for(_itb=0;_itb<_onBindingUpdateEvents[_nameb].length;_itb++){
          if(typeof _onBindingUpdateEvents[_nameb][x] === 'function'){
            _onBindingUpdateEvents[_nameb][x](e);
          }
        }

        /* added name listener */
        _nameb = e.name;
        if(_onBindingUpdateEvents[_nameb] !== undefined){
          for(_itb=0;_itb<_onBindingUpdateEvents[_nameb].length;_itb++){
            if(typeof _onBindingUpdateEvents[_nameb][x] === 'function'){
              _onBindingUpdateEvents[_nameb][x](e);
            }
          }
        }

        /* removed name listener */
        _nameb = e.removed;
        if(_onBindingUpdateEvents[_nameb] !== undefined){
          for(_itb=0;_itb<_onBindingUpdateEvents[_nameb].length;_itb++){
            if(typeof _onBindingUpdateEvents[_nameb][x] === 'function'){
              _onBindingUpdateEvents[_nameb][x](e);
            }
          }
        }

      },
      _itI = 0,
      _keyList = [],
      _inputEvent = function(e){
        /* e = type(String), code(Int), key(String), shift(Bool), ctrl(Bool), alt(Bool), moveX(Int), moveY(Int) */
        _keyList = _environments[_environment][e.key];
        if(_keyList){
          loop:for(_itI=0;_itI<_keyList.length;_itI++){
            if(_keyList[_itI].type === type && _keyList[_itI].shift === e.shift && _keyList[_itI].ctrl === e.ctrl && _keyList[_itI].alt === e.alt){
              e.name = _keyList[_itI].name;
              e.readable = _keyList[_itI].readable;
              _keyList[_itI].func(e);
              break loop;
            }
          }
        }
      }

  function Inputs(){
    Inputs.toggleListening('mouse',true);
    Inputs.toggleListening('keyboard',true);
  }

  Inputs.addBindingUpdateListener = function(name,func){
    if(typeof name === 'function'){
      _onBindingUpdateEvents["*"].push(name);
    }
    else if(typeof name === 'string'){
      if(_onBindingUpdateEvents[name] === undefined){
        _onBindingUpdateEvents[name] = [];
      }
      _onBindingUpdateEvents[name].push(func);
    }
    return Inputs;
  }

  Inputs.removeBindingUpdateListener = function(name,func){
    if(typeof name === 'function'){
      func = name;
      name = "*";
    }
    if(typeof name === 'string' && _onBindingUpdateEvents[name] !== undefined){
      loop:for(var x=0;x<_onBindingUpdateEvents[name].length;x++){
        if(func.toString() === _onBindingUpdateEvents[name][x].toString()){
          _onBindingUpdateEvents[name].splice(x,1);
        }
      }
    }
    return Inputs
  }

  Inputs.toggleListening = function(type,toggle){
    if(typeof type === 'string'){
      switch(type){
        case 'mouse':
          if(toggle){
            _mouseToggle = !toggle;
          }
          _mouse.removeMouseListener(_inputEvent);
          if(!_mouseToggle){
            _mouse.addMouseListener(_inputEvent).call();
          }
          _mouseToggle = !_mouseToggle;
        break;
        case 'keyboard':
          if(toggle){
            _keyboardToggle = !toggle;
          }
          _keyboard.removeKeyListener(_inputEvent);
          if(!_keyboardToggle){
            _keyboard.addKeyListener(_inputEvent).call();
          }
          _keyboardToggle = !_keyboardToggle;
        break;
      }
    }
    return Inputs;
  }

  Inputs.environment = function(v){
    if(v === undefined){
      return _environment;
    }
    _environment = (typeof v === 'string' && _environments[v] ? v : _environment);
    return Inputs;
  }

  Inputs.addEnvironment = function(v){
    if(typeof v === 'string' && !_environments[v]){
      _environments[v] = {};
    }
    return Inputs;
  }

  Inputs.removeEnvironment = function(v){
    if(typeof v === 'string' && v !== 'default'){
      _environments[v] = null;
    }
    return Inputs;
  }

  Inputs.addBinding = function(environment,name,type,key,func,shift,ctrl,alt){

    /* Overload for environment */
    var __environment = (typeof func === 'function' ? environment : 'default'),
        __name = (typeof func === 'function' ? name : environment),
        __type = (typeof func === 'function' ? type : name),
        __key = (typeof func === 'function' ? key : type),
        __func = (typeof func === 'function' ? func : key),
        __shift = (typeof func === 'function' ? shift : func),
        __ctrl = (typeof func === 'function' ? ctrl : shift),
        __alt = (typeof func === 'function' ? alt : ctrl),
        __readable,
        __bindings = {},
        __bindingKeys = [],
        __bindingKey = {},
        __removal = "",
        __added = {},
        __found = false;

    __readable = (__shift ? "Shift ": "")+(__ctrl ? "Ctrl " : "")+(__alt ? "Alt " : "")+__key;
    if(_environments[__environment]){
      __bindings = _environments[__environment];

      /* Overwrite Existing if There */
      __bindingKeys = __bindings[__key];
      loop:for(var x=0;x<__bindingKeys.length;x++){
        __bindingKey = __bindingKeys[x];
        if(__bindingKey.type === __type && __bindingKey.shift === !!__shift && __bindingKey.ctrl === !!__ctrl && __bindingKey.alt === !!__alt){
          __removal = __bindingKey.name;
          __bindingKey.name = __name;
          __bindingKey.func = __func;
          __added = __bindingKey;
          __found = true;
          break loop;
        }
      }
      if(!__found){
        __bindingKeys.push({readable:__readable,name:__name,type:__type,func:__func,shift:!!__shift,ctrl:!!__ctrl,alt:!!__alt});
        __added = __bindingKeys[(__bindingKeys.length-1)];
      }
      _bindingUpdateEvent({key:__key,name:__name,added:__added,removed:__removal,environment:__environment});
    }
    return Inputs;
  }

  Inputs.removeBinding = function(environment,name){
    var __environment = (name === undefined ? 'default' : environment),
        __name = (name === undefined ? environment : name),
        __keys = [],
        __key = {},
        __k = "";

    if(_environments[__environment]){
      __keys = Object.keys(_environments[__environment]);
      loop:for(var x=0;x<__keys.length;x++){
        __k = __keys[x];
        __key = _environments[__environment][__keys[x]];
        for(var i=0;i<__key.length;i++){
          if(__key[i].name === __name){
            __key.splice(i,1);
            break loop;
          }
        }
      }
      _bindingUpdateEvent({added:undefined,key:__k,name:__name,removed:__name,environment:__environment});
    }
    return Inputs;
  }

  return Inputs;
}
<|endoftext|>


<commit_before>'use strict'

const Context = require('coworkers/lib/context.js')
const defaults = require('101/defaults')
const sinon = require('sinon')
require('sinon-as-promised')

const mockChannelFactory = require('./mock-channel-factory.js')
const mockConnectionFactory = require('./mock-connection-factory.js')

module.exports = mockContextFactory

function mockContextFactory (app, queueName, message) {
  defaults(app, {
    connection: mockConnectionFactory(),
    consumerChannel: mockChannelFactory(true),
    publisherChannel: mockChannelFactory()
  })

  const context = new Context(app, queueName, message)
  sinon.spy(context, 'publish')
  sinon.spy(context, 'sendToQueue')
  sinon.stub(context, 'request')
  sinon.stub(context, 'reply')
  sinon.stub(context, 'checkQueue')
  sinon.stub(context, 'checkReplyQueue')

  return context
}
<commit_msg>default stubs for rpc methods<commit_after>'use strict'

const Context = require('coworkers/lib/context.js')
const defaults = require('101/defaults')
const sinon = require('sinon')
require('sinon-as-promised')

const mockChannelFactory = require('./mock-channel-factory.js')
const mockConnectionFactory = require('./mock-connection-factory.js')

module.exports = mockContextFactory

function mockContextFactory (app, queueName, message) {
  defaults(app, {
    connection: mockConnectionFactory(),
    consumerChannel: mockChannelFactory(true),
    publisherChannel: mockChannelFactory()
  })

  const context = new Context(app, queueName, message)
  sinon.spy(context, 'publish')
  sinon.spy(context, 'sendToQueue')
  sinon.stub(context, 'request').resolves()
  sinon.stub(context, 'reply')
  sinon.stub(context, 'checkQueue').resolves()
  sinon.stub(context, 'checkReplyQueue').resolves()

  return context
}
<|endoftext|>


<commit_before>function stripHtmlTags(html)
{
    //console.log("Stripping out HTML tags from " + html);
    var tmp = document.createElement("DIV");
    tmp.innerHTML = html;
    return tmp.textContent || tmp.innerText || "";
}

// When the Specific Issue Data changes, parse it if it's formatted as a Burp issue)
// and save the results to the DB.
function parseBurpIssueAndSave(){

    // If the note is Burp-formatted, parse it
    var notes = $("#INotes").val();
    var lines = notes.split('\n');
    var issue="", evidence="", urls="", newNotes="", sev=-1, sevText="";
    var urlSection=false;
    for (var i in lines){
        var t = lines[i].split(':');

        // Capture the Issue Name
        if (lines[i].startsWith('Issue:')){
            issue = t[1].trim();
        }

        // Capture the Issue Name
        if (lines[i].startsWith('Severity:')){
            sevText = t[1].trim();
            sev = getSevVal(sevText);
        }

        // Capture the URL list
        else if (lines[i].startsWith('URL(s):')){
            urlSection = true;
        }

        else if (urlSection){
            var url = lines[i];
            if ((url !== undefined) && (url.length > 0)){
                url = url.replace(/^ - /, "");
                urls += url + "\n";
            }
            else
                urlSection = false;
        }

        // Capture the evidence
        else if (lines[i].startsWith('Evidence:')){
            evidence = t[1].trim();
        }

        // Remove the empty lines with "~" from Burp Clipboarder and
        // keep other unmodified lines.
        else{
            newNotes += lines[i].replace(/^~$/, "") + "\n";
        }
    }

    // Push the captured data to the UI and DB
    if ((issue !== undefined) && (issue.length > 0)){
        saveIssueDataFromUI("#TIssueName", issue);
        $("#TIssueName").val(issue);
    }
    if ((evidence !== undefined) && (evidence.length > 0)){
        // Decode the Base64 value
        evidence = decodeURIComponent(Array.prototype.map.call(atob(evidence), function(c) {
                return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
            }).join('')).trim();
        saveIssueDataFromUI("#IEvidence", evidence);
        $("#IEvidence").val(evidence);
    }
    if ((urls !== undefined) && (urls.length > 0)){
        saveIssueDataFromUI("#IURIs", urls);
        $("#IURIs").val(urls);
    }
    if (sev >= 0){
        saveIssueDataFromUI("#IPriority", sev);
        $("#IPriority").val(sev);
    }

    // Save the note after removing "~", stripping HTML tags and collapsing
    // multiple spaces (from Burp Clipboarder extension).
    if (newNotes.length > 0){
        newNotes = stripHtmlTags(newNotes).replace(/ +/g, " ").trim();
        saveIssueDataFromUI("#INotes", newNotes);
        $("#INotes").val(newNotes);
    }

    // Update titles so that mouse-over information matches the content
    $("#IURIs").attr("title", $("#IURIs").val());
    $("#IEvidence").attr("title", $("#IEvidence").val());
    $("#INotes").attr("title", $("#INotes").val());
}

function getSevVal(sevStr) {
    var sev = -1;
    switch (sevStr) {
        case 'Information'    :
            sev = 0;
            break;
        case 'Low'      :
            sev = 1;
            break;
        case 'Medium'     :
            sev = 2;
            break;
        case 'High'     :
            sev = 3;
            break;
        default         :
            sev = -1;
    }
    return sev;
}<commit_msg>Minor update<commit_after>function stripHtmlTags(html)
{
    //console.log("Stripping out HTML tags from " + html);
    var tmp = document.createElement("DIV");
    tmp.innerHTML = html;
    return tmp.textContent || tmp.innerText || "";
}

// When the Specific Issue Data changes, parse it if it's formatted as a Burp issue)
// and save the results to the DB.
function parseBurpIssueAndSave(){

    // If the note is Burp-formatted, parse it
    var notes = $("#INotes").val();
    var lines = notes.split('\n');
    var issue="", evidence="", urls="", newNotes="", sev=-1, sevText="";
    var urlSection=false;
    for (var i in lines){
        var t = lines[i].split(':');

        // Capture the Issue Name
        if (lines[i].startsWith('Issue:')){
            issue = t[1].trim();
        }

        // Capture the Issue Name
        if (lines[i].startsWith('Severity:')){
            sevText = t[1].trim();
            sev = getSevVal(sevText);
        }

        // Capture the URL list
        else if (lines[i].startsWith('URL(s):')){
            urlSection = true;
        }

        else if (urlSection){
            var url = lines[i];
            if ((url !== undefined) && (url.length > 0)){
                url = url.replace(/^ - /, "");
                urls += url + "\n";
            }
            else
                urlSection = false;
        }

        // Capture the evidence
        else if (lines[i].startsWith('Evidence:')){
            evidence = t[1].trim();
        }

        // Remove the empty lines with "~" from Burp Clipboarder and
        // keep other unmodified lines.
        else{
            newNotes += lines[i].replace(/^~$/, "") + "\n";
        }
    }

    // Push the captured data to the UI and DB
    if ((issue !== undefined) && (issue.length > 0)){
        saveIssueDataFromUI("#TIssueName", issue);
        $("#TIssueName").val(issue);
    }
    if ((evidence !== undefined) && (evidence.length > 0)){
        // Decode the Base64 value
        evidence = decodeURIComponent(Array.prototype.map.call(atob(evidence), function(c) {
                return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
            }).join('')).trim();
        saveIssueDataFromUI("#IEvidence", evidence);
        $("#IEvidence").val(evidence);
    }
    if ((urls !== undefined) && (urls.length > 0)){
        saveIssueDataFromUI("#IURIs", urls);
        $("#IURIs").val(urls);
    }
    if (sev >= 0){
        saveIssueDataFromUI("#IPriority", sev);
        $("#IPriority").val(sev);
        saveIssueDataFromUI("#TSeverity", sev);
        $("#TSeverity").val(sev);
    }

    // Save the note after removing "~", stripping HTML tags and collapsing
    // multiple spaces (from Burp Clipboarder extension).
    if (newNotes.length > 0){
        newNotes = stripHtmlTags(newNotes).replace(/ +/g, " ").trim();
        saveIssueDataFromUI("#INotes", newNotes);
        $("#INotes").val(newNotes);
    }

    // Update titles so that mouse-over information matches the content
    $("#IURIs").attr("title", $("#IURIs").val());
    $("#IEvidence").attr("title", $("#IEvidence").val());
    $("#INotes").attr("title", $("#INotes").val());
}

function getSevVal(sevStr) {
    var sev = -1;
    switch (sevStr) {
        case 'Information'    :
            sev = 0;
            break;
        case 'Low'      :
            sev = 1;
            break;
        case 'Medium'     :
            sev = 2;
            break;
        case 'High'     :
            sev = 3;
            break;
        default         :
            sev = -1;
    }
    return sev;
}<|endoftext|>


<commit_before>var events = require("events")
var http   = require("http")
var url    = require("url")

function Server(opts) {
  events.EventEmitter.call(this)

  this.clients = {}
  this.responses = {}

  this.Client = function(){ Client.call(this) }
  this.Client.prototype = new Client
  this.Client.prototype.server = this

  if (!opts) opts = {}

  this.setHost(opts.host)
  this.attachWs(opts.ws)
  this.attachHttp(opts.http, opts.port)
}

Server.prototype = new events.EventEmitter

Server.prototype.ws = null
Server.prototype.http = null
Server.prototype.host = "*.localhost.browserver.org"

Server.prototype.setHost = function(host) {
  if (host) this.host = host

  if (this.host.split("*").length != 2) {
    throw new Error("Specified host must have one and only one `*`.")
  }

  var hostPattern = this.host
    .replace(/\./g, "\\.")
    .replace(/\*/g, "([a-zA-Z0-9-]+)")

  this.hostPattern = new RegExp("^" + hostPattern + "$")

  return this
}

Server.prototype.attachWs = function(server) {
  this.ws = server

  if (!this.ws) throw new Error("No WebSocket server specified.")

  this.ws.on("connection", this.handleConnection.bind(this))

  return this
}

Server.prototype.attachHttp = function(server, port) {
  this.http = server

  if (!this.http) {
    if (!port) port = "෴".charCodeAt()

    this.http = http.createServer().listen(port)
    this.http.on("request", function(req, res) {
      this.handleError(501, res)
    }.bind(this))
  }

  this.http.emit = function(event, req, res) {
    event == "request"
      ? this.handleRequest(req, res)
      : http.Server.prototype.emit.apply(this.http, arguments)
  }.bind(this)

  return this
}

Server.prototype.handleConnection = function(socket) {
  var client = new this.Client().attachSocket(socket)

  this.clients[client.id] = client

  this.emit("connection", client)
}

Server.prototype.handleRequest = function(req, res) {
  var host = req.headers.host
  var hostname = host && host.split(":")[0]
  var match = hostname && hostname.match(this.hostPattern)
  var id = match && match[1]
  var emit = http.Server.prototype.emit

  if (!id) return emit.call(this.http, "request", req, res)

  var client = this.clients[id]

  if (!client) return this.handleError(504, res) // destroy connection instead?

  req.body = ""
  req.setEncoding("utf8")
  req.on("data", function(chunk){ req.body += chunk })
  req.on("end", client.handleRequest.bind(client, req, res))
}

Server.prototype.handleError = function(code, res) {
  if (!code) code = 500

  var reason = http.STATUS_CODES[code] + "\n"

  res.writeHead(code, {
    "Content-Type": "text/plain",
    "Content-Length": Buffer.byteLength(reason)
  })

  res.end(reason)
}

function Client() {
  this.id = Client.id()
  this.responses = {}
}

Client.id = function() {
  return Math.random().toString(36).slice(2)
}

Client.prototype = new events.EventEmitter

Client.prototype.attachSocket = function(socket) {
  socket.on("message", this.handleMessage.bind(this))
  socket.on("close", this.handleClose.bind(this))

  this.socket = socket

  return this
}

Client.prototype.handleClose = function(){}

Client.prototype.handleMessage = function(data) {
  var self = this

  try { data = JSON.parse(data) }
  catch (error) { return this.emit("error", error) }

  if (data.statusCode) {
    data.headers["Content-Length"] = Buffer.byteLength(data.body)

    var id = data.headers["x-brow-req-id"]
    delete data.headers["x-brow-req-id"]

    var res = this.responses[id]

    res.writeHead(data.statusCode, data.headers)
    res.end(data.body)

    delete this.responses[id]
  }

  else if (data.method) {
    data.path = data.url
    delete data.path

    data.host = data.headers.host
    delete data.headers.host

    var id = data.headers["x-brow-req-id"]
    delete data.headers["x-brow-req-id"]

    var req = http.request(data, function(res) {
      var body = ""

      res.headers["x-brow-req-id"] = id
      res.setEncoding("utf8")
      res.on("data", function(data){ body += data })
      res.on("end", function() {
        self.socket.send(JSON.stringify({
          statusCode: res.statusCode,
          headers: res.headers,
          body: body || undefined
        }))
      })
    })

    if (data.body) req.write(data.body)

    req.end()
  }

  else {
    // invalid type
  }
}

Client.prototype.handleRequest = function(req, res) {
  var id = Math.random().toString(36).slice(2)

  req.headers["x-brow-req-id"] = id
  delete req.headers.host
  this.responses[id] = res

  var payload = JSON.stringify({
    method: req.method,
    headers: req.headers,
    url: req.url,
    body: req.body || undefined
  })

  this.socket.send(payload)
}

exports.Server = Server
exports.Client = Client
<commit_msg>delete closed clients<commit_after>var events = require("events")
var http   = require("http")
var url    = require("url")

function Server(opts) {
  events.EventEmitter.call(this)

  this.clients = {}
  this.responses = {}

  this.Client = function(){ Client.call(this) }
  this.Client.prototype = new Client
  this.Client.prototype.server = this

  if (!opts) opts = {}

  this.setHost(opts.host)
  this.attachWs(opts.ws)
  this.attachHttp(opts.http, opts.port)
}

Server.prototype = new events.EventEmitter

Server.prototype.ws = null
Server.prototype.http = null
Server.prototype.host = "*.vcap.me"

Server.prototype.setHost = function(host) {
  if (host) this.host = host

  if (this.host.split("*").length != 2) {
    throw new Error("Specified host must have one and only one `*`.")
  }

  var hostPattern = this.host
    .replace(/\./g, "\\.")
    .replace(/\*/g, "([a-zA-Z0-9-]+)")

  this.hostPattern = new RegExp("^" + hostPattern + "$")

  return this
}

Server.prototype.attachWs = function(server) {
  this.ws = server

  if (!this.ws) throw new Error("No WebSocket server specified.")

  this.ws.on("connection", this.handleConnection.bind(this))

  return this
}

Server.prototype.attachHttp = function(server, port) {
  this.http = server

  if (!this.http) {
    if (!port) port = "෴".charCodeAt()

    this.http = http.createServer().listen(port)
    this.http.on("request", function(req, res) {
      this.handleError(501, res)
    }.bind(this))
  }

  this.http.emit = function(event, req, res) {
    event == "request"
      ? this.handleRequest(req, res)
      : http.Server.prototype.emit.apply(this.http, arguments)
  }.bind(this)

  return this
}

Server.prototype.handleConnection = function(socket) {
  var client = new this.Client().attachSocket(socket)

  this.clients[client.id] = client

  this.emit("connection", client)
}

Server.prototype.handleRequest = function(req, res) {
  var host = req.headers.host
  var hostname = host && host.split(":")[0]
  var match = hostname && hostname.match(this.hostPattern)
  var id = match && match[1]
  var emit = http.Server.prototype.emit

  if (!id) return emit.call(this.http, "request", req, res)

  var client = this.clients[id]

  if (!client) return this.handleError(504, res) // destroy connection instead?

  req.body = ""
  req.setEncoding("utf8")
  req.on("data", function(chunk){ req.body += chunk })
  req.on("end", client.handleRequest.bind(client, req, res))
}

Server.prototype.handleError = function(code, res) {
  if (!code) code = 500

  var reason = http.STATUS_CODES[code] + "\n"

  res.writeHead(code, {
    "Content-Type": "text/plain",
    "Content-Length": Buffer.byteLength(reason)
  })

  res.end(reason)
}

function Client() {
  this.id = Client.id()
  this.responses = {}
}

Client.id = function() {
  return Math.random().toString(36).slice(2)
}

Client.prototype = new events.EventEmitter

Client.prototype.attachSocket = function(socket) {
  socket.on("message", this.handleMessage.bind(this))
  socket.on("close", this.handleClose.bind(this))

  this.socket = socket

  return this
}

Client.prototype.handleClose = function() {
  delete this.server.clients[this.id]
}

Client.prototype.handleMessage = function(data) {
  var self = this

  try { data = JSON.parse(data) }
  catch (error) { return this.emit("error", error) }

  if (data.statusCode) {
    data.headers["Content-Length"] = Buffer.byteLength(data.body)

    var id = data.headers["x-brow-req-id"]
    delete data.headers["x-brow-req-id"]

    var res = this.responses[id]

    res.writeHead(data.statusCode, data.headers)
    res.end(data.body)

    delete this.responses[id]
  }

  else if (data.method) {
    data.path = data.url
    delete data.path

    data.host = data.headers.host
    delete data.headers.host

    var id = data.headers["x-brow-req-id"]
    delete data.headers["x-brow-req-id"]

    var req = http.request(data, function(res) {
      var body = ""

      res.headers["x-brow-req-id"] = id
      res.setEncoding("utf8")
      res.on("data", function(data){ body += data })
      res.on("end", function() {
        self.socket.send(JSON.stringify({
          statusCode: res.statusCode,
          headers: res.headers,
          body: body || undefined
        }))
      })
    })

    if (data.body) req.write(data.body)

    req.end()
  }

  else {
    // invalid type
  }
}

Client.prototype.handleRequest = function(req, res) {
  var id = Math.random().toString(36).slice(2)

  req.headers["x-brow-req-id"] = id
  delete req.headers.host
  this.responses[id] = res

  var payload = JSON.stringify({
    method: req.method,
    headers: req.headers,
    url: req.url,
    body: req.body || undefined
  })

  this.socket.send(payload)
}

exports.Server = Server
exports.Client = Client
<|endoftext|>