<commit_before>var path = require("path")
  , assert = require("assert")
  , fs = require("graceful-fs")
  , http = require("http")
  , log = require("npmlog")
  , semver = require("semver")
  , readJson = require("read-package-json")
  , url = require("url")
  , npm = require("../npm.js")
  , deprCheck = require("../utils/depr-check.js")
  , inflight = require("inflight")
  , addRemoteTarball = require("./add-remote-tarball.js")
  , cachedPackageRoot = require("./cached-package-root.js")
  , mapToRegistry = require("../utils/map-to-registry.js")

module.exports = addNamed

function getOnceFromRegistry (name, from, next, done) {
  mapToRegistry(name, npm.config, function (er, uri, auth) {
    if (er) return done(er)

    var key = "registry:" + uri
    next = inflight(key, next)
    if (!next) return log.verbose(from, key, "already in flight; waiting")
    else log.verbose(from, key, "not in flight; fetching")

    npm.registry.get(uri, { auth : auth }, next)
  })
}

function addNamed (name, version, data, cb_) {
  assert(typeof name === "string", "must have module name")
  assert(typeof cb_ === "function", "must have callback")

  var key = name + "@" + version
  log.verbose("addNamed", key)

  function cb (er, data) {
    if (data && !data._fromGithub) data._from = key
    cb_(er, data)
  }

  log.silly("addNamed", "semver.valid", semver.valid(version))
  log.silly("addNamed", "semver.validRange", semver.validRange(version))
  var fn = ( semver.valid(version, true) ? addNameVersion
           : semver.validRange(version, true) ? addNameRange
           : addNameTag
           )
  fn(name, version, data, cb)
}

function addNameTag (name, tag, data, cb) {
  log.info("addNameTag", [name, tag])
  var explicit = true
  if (!tag) {
    explicit = false
    tag = npm.config.get("tag")
  }

  getOnceFromRegistry(name, "addNameTag", next, cb)

  function next (er, data, json, resp) {
    if (!er) er = errorResponse(name, resp)
    if (er) return cb(er)

    log.silly("addNameTag", "next cb for", name, "with tag", tag)

    engineFilter(data)
    if (data["dist-tags"] && data["dist-tags"][tag]
        && data.versions[data["dist-tags"][tag]]) {
      var ver = data["dist-tags"][tag]
      return addNamed(name, ver, data.versions[ver], cb)
    }
    if (!explicit && Object.keys(data.versions).length) {
      return addNamed(name, "*", data, cb)
    }

    er = installTargetsError(tag, data)
    return cb(er)
  }
}

function engineFilter (data) {
  var npmv = npm.version
    , nodev = npm.config.get("node-version")
    , strict = npm.config.get("engine-strict")

  if (!nodev || npm.config.get("force")) return data

  Object.keys(data.versions || {}).forEach(function (v) {
    var eng = data.versions[v].engines
    if (!eng) return
    if (!strict && !data.versions[v].engineStrict) return
    if (eng.node && !semver.satisfies(nodev, eng.node, true)
        || eng.npm && !semver.satisfies(npmv, eng.npm, true)) {
      delete data.versions[v]
    }
  })
}

function addNameVersion (name, v, data, cb) {
  var ver = semver.valid(v, true)
  if (!ver) return cb(new Error("Invalid version: "+v))

  var response

  if (data) {
    response = null
    return next()
  }

  getOnceFromRegistry(name, "addNameVersion", setData, cb)

  function setData (er, d, json, resp) {
    if (!er) {
      er = errorResponse(name, resp)
    }
    if (er) return cb(er)
    data = d && d.versions[ver]
    if (!data) {
      er = new Error("version not found: "+name+"@"+ver)
      er.package = name
      er.statusCode = 404
      return cb(er)
    }
    response = resp
    next()
  }

  function next () {
    deprCheck(data)
    var dist = data.dist

    if (!dist) return cb(new Error("No dist in "+data._id+" package"))

    if (!dist.tarball) return cb(new Error(
      "No dist.tarball in " + data._id + " package"))

    if ((response && response.statusCode !== 304) || npm.config.get("force")) {
      return fetchit()
    }

    // we got cached data, so let's see if we have a tarball.
    var pkgroot = cachedPackageRoot({name : name, version : ver})
    var pkgtgz = path.join(pkgroot, "package.tgz")
    var pkgjson = path.join(pkgroot, "package", "package.json")
    fs.stat(pkgtgz, function (er) {
      if (!er) {
        readJson(pkgjson, function (er, data) {
          if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)

          if (data) {
            if (!data.name) return cb(new Error("No name provided"))
            if (!data.version) return cb(new Error("No version provided"))

            // check the SHA of the package we have, to ensure it wasn't installed
            // from somewhere other than the registry (eg, a fork)
            if (data._shasum && dist.shasum && data._shasum !== dist.shasum) {
              return fetchit()
            }
          }

          if (er) return fetchit()
            else return cb(null, data)
        })
      } else return fetchit()
    })

    function fetchit () {
      mapToRegistry(name, npm.config, function (er, _, auth, ruri) {
        if (er) return cb(er)

        // Use the same protocol as the registry.  https registry --> https
        // tarballs, but only if they're the same hostname, or else detached
        // tarballs may not work.
        var tb = url.parse(dist.tarball)
        var rp = url.parse(ruri)
        if (tb.hostname === rp.hostname && tb.protocol !== rp.protocol) {
          tb.protocol = rp.protocol
          delete tb.href
        }
        tb = url.format(tb)

        // Only add non-shasum'ed packages if --forced. Only ancient things
        // would lack this for good reasons nowadays.
        if (!dist.shasum && !npm.config.get("force")) {
          return cb(new Error("package lacks shasum: " + data._id))
        }

        addRemoteTarball(tb, data, dist.shasum, auth, cb)
      })
    }
  }
}

function addNameRange (name, range, data, cb) {
  range = semver.validRange(range, true)
  if (range === null) return cb(new Error(
    "Invalid version range: " + range
  ))

  log.silly("addNameRange", {name:name, range:range, hasData:!!data})

  if (data) return next()

  getOnceFromRegistry(name, "addNameRange", setData, cb)

  function setData (er, d, json, resp) {
    if (!er) {
      er = errorResponse(name, resp)
    }
    if (er) return cb(er)
    data = d
    next()
  }

  function next () {
    log.silly( "addNameRange", "number 2"
             , {name:name, range:range, hasData:!!data})
    engineFilter(data)

    log.silly("addNameRange", "versions"
             , [data.name, Object.keys(data.versions || {})])

    // if the tagged version satisfies, then use that.
    var tagged = data["dist-tags"][npm.config.get("tag")]
    if (tagged
        && data.versions[tagged]
        && semver.satisfies(tagged, range, true)) {
      return addNamed(name, tagged, data.versions[tagged], cb)
    }

    // find the max satisfying version.
    var versions = Object.keys(data.versions || {})
    var ms = semver.maxSatisfying(versions, range, true)
    if (!ms) {
      return cb(installTargetsError(range, data))
    }

    // if we don't have a registry connection, try to see if
    // there's a cached copy that will be ok.
    addNamed(name, ms, data.versions[ms], cb)
  }
}

function installTargetsError (requested, data) {
  var targets = Object.keys(data["dist-tags"]).filter(function (f) {
    return (data.versions || {}).hasOwnProperty(f)
  }).concat(Object.keys(data.versions || {}))

  requested = data.name + (requested ? "@'" + requested + "'" : "")

  targets = targets.length
          ? "Valid install targets:\n" + JSON.stringify(targets) + "\n"
          : "No valid targets found.\n"
          + "Perhaps not compatible with your version of node?"

  var er = new Error( "No compatible version found: "
                  + requested + "\n" + targets)
  er.code = "ETARGET"
  return er
}

function errorResponse (name, response) {
  var er
  if (response.statusCode >= 400) {
    er = new Error(http.STATUS_CODES[response.statusCode])
    er.statusCode = response.statusCode
    er.code = "E" + er.statusCode
    er.pkgid = name
  }
  return er
}
<commit_msg>src: deprecate engineStrict in package.json<commit_after>var path = require("path")
  , assert = require("assert")
  , fs = require("graceful-fs")
  , http = require("http")
  , log = require("npmlog")
  , semver = require("semver")
  , readJson = require("read-package-json")
  , url = require("url")
  , npm = require("../npm.js")
  , deprCheck = require("../utils/depr-check.js")
  , inflight = require("inflight")
  , addRemoteTarball = require("./add-remote-tarball.js")
  , cachedPackageRoot = require("./cached-package-root.js")
  , mapToRegistry = require("../utils/map-to-registry.js")

module.exports = addNamed

function getOnceFromRegistry (name, from, next, done) {
  mapToRegistry(name, npm.config, function (er, uri, auth) {
    if (er) return done(er)

    var key = "registry:" + uri
    next = inflight(key, next)
    if (!next) return log.verbose(from, key, "already in flight; waiting")
    else log.verbose(from, key, "not in flight; fetching")

    npm.registry.get(uri, { auth : auth }, next)
  })
}

function addNamed (name, version, data, cb_) {
  assert(typeof name === "string", "must have module name")
  assert(typeof cb_ === "function", "must have callback")

  var key = name + "@" + version
  log.verbose("addNamed", key)

  function cb (er, data) {
    if (data && !data._fromGithub) data._from = key
    cb_(er, data)
  }

  log.silly("addNamed", "semver.valid", semver.valid(version))
  log.silly("addNamed", "semver.validRange", semver.validRange(version))
  var fn = ( semver.valid(version, true) ? addNameVersion
           : semver.validRange(version, true) ? addNameRange
           : addNameTag
           )
  fn(name, version, data, cb)
}

function addNameTag (name, tag, data, cb) {
  log.info("addNameTag", [name, tag])
  var explicit = true
  if (!tag) {
    explicit = false
    tag = npm.config.get("tag")
  }

  getOnceFromRegistry(name, "addNameTag", next, cb)

  function next (er, data, json, resp) {
    if (!er) er = errorResponse(name, resp)
    if (er) return cb(er)

    log.silly("addNameTag", "next cb for", name, "with tag", tag)

    engineFilter(data)
    if (data["dist-tags"] && data["dist-tags"][tag]
        && data.versions[data["dist-tags"][tag]]) {
      var ver = data["dist-tags"][tag]
      return addNamed(name, ver, data.versions[ver], cb)
    }
    if (!explicit && Object.keys(data.versions).length) {
      return addNamed(name, "*", data, cb)
    }

    er = installTargetsError(tag, data)
    return cb(er)
  }
}

function engineFilter (data) {
  var npmv = npm.version
    , nodev = npm.config.get("node-version")
    , strict = npm.config.get("engine-strict")

  if (!nodev || npm.config.get("force")) return data

  Object.keys(data.versions || {}).forEach(function (v) {
    var eng = data.versions[v].engines
    if (!eng) return
    if (data.versions[v].engineStrict) {
      log.warn("deprecation", "Per-package engineStrict will no longer be used")
      log.warn("deprecation", "in upcoming versions of npm. Use the config")
      log.warn("deprecation", "setting `engine-strict` instead.")
    }
    if (!strict && !data.versions[v].engineStrict) return
    if (eng.node && !semver.satisfies(nodev, eng.node, true)
        || eng.npm && !semver.satisfies(npmv, eng.npm, true)) {
      delete data.versions[v]
    }
  })
}

function addNameVersion (name, v, data, cb) {
  var ver = semver.valid(v, true)
  if (!ver) return cb(new Error("Invalid version: "+v))

  var response

  if (data) {
    response = null
    return next()
  }

  getOnceFromRegistry(name, "addNameVersion", setData, cb)

  function setData (er, d, json, resp) {
    if (!er) {
      er = errorResponse(name, resp)
    }
    if (er) return cb(er)
    data = d && d.versions[ver]
    if (!data) {
      er = new Error("version not found: "+name+"@"+ver)
      er.package = name
      er.statusCode = 404
      return cb(er)
    }
    response = resp
    next()
  }

  function next () {
    deprCheck(data)
    var dist = data.dist

    if (!dist) return cb(new Error("No dist in "+data._id+" package"))

    if (!dist.tarball) return cb(new Error(
      "No dist.tarball in " + data._id + " package"))

    if ((response && response.statusCode !== 304) || npm.config.get("force")) {
      return fetchit()
    }

    // we got cached data, so let's see if we have a tarball.
    var pkgroot = cachedPackageRoot({name : name, version : ver})
    var pkgtgz = path.join(pkgroot, "package.tgz")
    var pkgjson = path.join(pkgroot, "package", "package.json")
    fs.stat(pkgtgz, function (er) {
      if (!er) {
        readJson(pkgjson, function (er, data) {
          if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)

          if (data) {
            if (!data.name) return cb(new Error("No name provided"))
            if (!data.version) return cb(new Error("No version provided"))

            // check the SHA of the package we have, to ensure it wasn't installed
            // from somewhere other than the registry (eg, a fork)
            if (data._shasum && dist.shasum && data._shasum !== dist.shasum) {
              return fetchit()
            }
          }

          if (er) return fetchit()
            else return cb(null, data)
        })
      } else return fetchit()
    })

    function fetchit () {
      mapToRegistry(name, npm.config, function (er, _, auth, ruri) {
        if (er) return cb(er)

        // Use the same protocol as the registry.  https registry --> https
        // tarballs, but only if they're the same hostname, or else detached
        // tarballs may not work.
        var tb = url.parse(dist.tarball)
        var rp = url.parse(ruri)
        if (tb.hostname === rp.hostname && tb.protocol !== rp.protocol) {
          tb.protocol = rp.protocol
          delete tb.href
        }
        tb = url.format(tb)

        // Only add non-shasum'ed packages if --forced. Only ancient things
        // would lack this for good reasons nowadays.
        if (!dist.shasum && !npm.config.get("force")) {
          return cb(new Error("package lacks shasum: " + data._id))
        }

        addRemoteTarball(tb, data, dist.shasum, auth, cb)
      })
    }
  }
}

function addNameRange (name, range, data, cb) {
  range = semver.validRange(range, true)
  if (range === null) return cb(new Error(
    "Invalid version range: " + range
  ))

  log.silly("addNameRange", {name:name, range:range, hasData:!!data})

  if (data) return next()

  getOnceFromRegistry(name, "addNameRange", setData, cb)

  function setData (er, d, json, resp) {
    if (!er) {
      er = errorResponse(name, resp)
    }
    if (er) return cb(er)
    data = d
    next()
  }

  function next () {
    log.silly( "addNameRange", "number 2"
             , {name:name, range:range, hasData:!!data})
    engineFilter(data)

    log.silly("addNameRange", "versions"
             , [data.name, Object.keys(data.versions || {})])

    // if the tagged version satisfies, then use that.
    var tagged = data["dist-tags"][npm.config.get("tag")]
    if (tagged
        && data.versions[tagged]
        && semver.satisfies(tagged, range, true)) {
      return addNamed(name, tagged, data.versions[tagged], cb)
    }

    // find the max satisfying version.
    var versions = Object.keys(data.versions || {})
    var ms = semver.maxSatisfying(versions, range, true)
    if (!ms) {
      return cb(installTargetsError(range, data))
    }

    // if we don't have a registry connection, try to see if
    // there's a cached copy that will be ok.
    addNamed(name, ms, data.versions[ms], cb)
  }
}

function installTargetsError (requested, data) {
  var targets = Object.keys(data["dist-tags"]).filter(function (f) {
    return (data.versions || {}).hasOwnProperty(f)
  }).concat(Object.keys(data.versions || {}))

  requested = data.name + (requested ? "@'" + requested + "'" : "")

  targets = targets.length
          ? "Valid install targets:\n" + JSON.stringify(targets) + "\n"
          : "No valid targets found.\n"
          + "Perhaps not compatible with your version of node?"

  var er = new Error( "No compatible version found: "
                  + requested + "\n" + targets)
  er.code = "ETARGET"
  return er
}

function errorResponse (name, response) {
  var er
  if (response.statusCode >= 400) {
    er = new Error(http.STATUS_CODES[response.statusCode])
    er.statusCode = response.statusCode
    er.code = "E" + er.statusCode
    er.pkgid = name
  }
  return er
}
<|endoftext|>


<commit_before>/**
 * FormValidator.js
 * User: rnugraha
 * Date: 29-10-13
 * Time: 15:27
 */

// Default error messages
var defaults = {
    messages: {
        required: 'The {0} field is required.',
        matches: 'The {0} field does not match the {1} field.',
        "default": 'The {0} field is still set to default, please change.',
        valid_email: 'The {0} field must contain a valid email address.',
        valid_emails: 'The {0} field must contain all valid email addresses.',
        min_length: 'The {0} field must be at least {1} characters in length.',
        max_length: 'The {0} field must not exceed {1} characters in length.',
        exact_length: 'The {0} field must be exactly {1} characters in length.',
        greater_than: 'The {0} field must contain a number greater than {1}.',
        less_than: 'The {0} field must contain a number less than {1}.',
        alpha: 'The {0} field must only contain alphabetical characters.',
        alpha_numeric: 'The {0} field must only contain alpha-numeric characters.',
        alpha_dash: 'The {0} field must only contain alpha-numeric characters, underscores, and dashes.',
        numeric: 'The {0} field must contain only numbers.',
        integer: 'The {0} field must contain an integer.',
        integer_range: '{0} must be between {1} and {2}.',
        integer_min: '{0} must be greater than or equal to {1}.',
        integer_max: '{0} must be less than or equal to {1}.',
        decimal: 'The {0} field must contain a decimal number.',
        is_natural: 'The {0} field must contain only positive numbers.',
        is_natural_no_zero: 'The {0} field must contain a number greater than zero.',
        valid_ip: 'The {0} field must contain a valid IP.',
        valid_base64: 'The {0} field must contain a base64 string.',
        valid_credit_card: 'The {0} field must contain a valid credit card number.',
        is_file_type: 'The {0} field must contain only {1} files.',
        valid_url: 'The {0} field must contain a valid URL.',
        valid_high_dimensional_node: 'The {0} field must contain high dimensional node only.',
        valid_high_dimensional_type: 'The {0} field contains invalid high dimensional data type.',
        no_high_dimensional_type: 'Unknown high dimensional data. Please verify first the high dimensional data ' +
            'in field {0}.',
        no_high_dimensional_pathway: 'Please define pathway/gene for selected high dimensional data.',
        min_two_nodes: 'The {0} must be more than one nodes.',
        min_two_subsets: 'Marker Selection requires two subsets of cohorts to be selected. Please use the Comparison ' +
            'Tab and select the cohorts'
    },
    callback: function(errors) {

    }
};

// Some basic RegExp
var ruleRegex = /^(.+?)\[(.+)\]$/,
    numericRegex = /^[0-9]+$/,
    integerRegex = /^\-?[0-9]+$/,
    decimalRegex = /^\-?[0-9]*\.?[0-9]+$/,
    emailRegex = /^[a-zA-Z0-9.!#$%&'*+\-\/=?\^_`{|}~\-]+@[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*$/,
    alphaRegex = /^[a-z]+$/i,
    alphaNumericRegex = /^[a-z0-9]+$/i,
    alphaDashRegex = /^[a-z0-9_\-]+$/i,
    naturalRegex = /^[0-9]+$/i,
    naturalNoZeroRegex = /^[1-9][0-9]*$/i,
    ipRegex = /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/i,
    base64Regex = /[^a-zA-Z0-9\/\+=]/i,
    numericDashRegex = /^[\d\-\s]+$/,
    urlRegex = /^((http|https):\/\/(\w+:{0,1}\w*@)?(\S+)|)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;

var FormValidator = function (inputArray) {
    this.inputs = inputArray;
    this.error_messages = [];
}

FormValidator.prototype.validateInputForm = function () {

    var _isValid = true; //init
    var _inputArr = this.inputs;

    for (var i=0; i < _inputArr.length; i++) { // loop through input array

        // single instance of input object
        var _el = _inputArr[i].el;
        var _value = _inputArr[i].value;
        var _label = _inputArr[i].label;
        var _validations = _inputArr[i].validations;

        // initialize
        var _isRequired = false;
        var _isInteger = false;
        var _isHighDimensional = false;
        var _isTwoSubsets = false;

        for (var j = 0; j < _validations.length; j++) { // loop into validations for an input

            // 1st level validation - check mandatory
            if (_validations[j].type == "REQUIRED") {
                _isRequired = this.required(_el, _label);
                _isValid = _isValid && _isRequired;
            }

            if (_isValid) {
                switch (_validations[j].type)
                {
                    case 'INTEGER' :
                        _isInteger =  this.valid_integer(_el, _label, _validations[j]);
                        _isValid = _isValid && _isInteger;
                        break;
                    case 'HIGH_DIMENSIONAL' :
                        _isHighDimensional =  this.valid_high_dimensional(_el, _label, _validations[j]);
                        _isValid = _isValid && _isHighDimensional;
                        break;
                    case 'HIGH_DIMENSIONAL_ACGH' :
                        _isHighDimensional =  this.valid_high_dimensional_acgh(_el, _label, _validations[j]);
                        _isValid = _isValid && _isHighDimensional;
                        break;
                    case 'GROUP_VARIABLE' :
                        _isHighDimensional =  this.valid_group_variable(_el, _label);
                        _isValid = _isValid && _isHighDimensional;
                        break;
                    case 'MIN_TWO_SUBSETS' :
                        _isTwoSubsets = this.min_two_subsets(_value, _label);
                        _isValid = _isValid && _isTwoSubsets;
                        break;
                }
            }
        } // end validation loop
    }

    return _isValid;
}

// General validations
// -------------------------------------------------

FormValidator.prototype.required = function (el, label) {

    var retVal = true;

    if (el instanceof Ext.Element) {  // if input element is instance of Ext JS
        retVal = el.dom.childElementCount > 0 ? true : false;
    } else {
        var value = el.value;
        retVal = (value !== null && value !== '');
    }

    if (!retVal) {
        this.push_error(defaults.messages.required, [label]);
    }

    return retVal;

}

FormValidator.prototype.valid_integer = function (el, label, validator) {

    var retVal = integerRegex.test(el.value);

    if (!retVal) {
        this.push_error(defaults.messages.integer, [label]);
    } else {
        if (validator.min && validator.max) {
            var isWithinRange = (el.value >= validator.min) && (el.value <= validator.max) ? true : false;
            retVal = retVal && isWithinRange;
            if (!retVal)  this.push_error(defaults.messages.integer_range, [label, validator.min, validator.max]);
        } else if (validator.min && !validator.max) {
            var isGreaterThanEqual = (el.value >= validator.min) ? true : false;
            retVal = retVal && isGreaterThanEqual;
            if (!retVal)  this.push_error(defaults.messages.integer_min, [label, validator.min]);
        } else if (!validator.min &&  validator.max) {
            var isLessThanEqual = (el.value <= validator.min) ? true : false;
            retVal = retVal && isLessThanEqual;
            if (!retVal)  this.push_error(defaults.messages.integer_max, [label, validator.max]);
        }
    }
    return retVal;
}

// Custom validations
// -------------------------------------------------

FormValidator.prototype.valid_high_dimensional_acgh = function (el, label, validator) {

    var retVal = true;
    var nodes = el.dom.childNodes;

    for (var i=0; i<nodes.length; i++) { // loop through container
        var strVisualAttributes = nodes[i].attributes['visualattributes'].value;
        var isHD = true;

        // check if node is high dimensional data node
        if (strVisualAttributes.indexOf('HIGH_DIMENSIONAL') == -1) { // if not

            isHD = false;
            retVal = retVal && isHD;
            this.push_error(defaults.messages.valid_high_dimensional_node, [label]);

        }
    }
    return retVal;
}

FormValidator.prototype.valid_group_variable = function (el, label) {

    var retVal = true;
    var nodes = el.dom.childNodes;

    if (nodes.length < 2) {
        this.push_error(defaults.messages.min_two_nodes, [label]);
        return false;
    }

    return retVal;
}

// validate input to receive only high dimensional node
FormValidator.prototype.valid_high_dimensional = function (el, label, validator) {

    var retVal = true;
    var nodes = el.dom.childNodes;

    for (var i=0; i<nodes.length; i++) { // loop through container

        var strVisualAttributes = nodes[i].attributes['visualattributes'].value;
        var isHD = true;

        // check if node is high dimensional data node
        if (strVisualAttributes.indexOf('HIGH_DIMENSIONAL') == -1) { // if not

            isHD = false;
            retVal = retVal && isHD;
            this.push_error(defaults.messages.valid_high_dimensional_node, [label]);

        } else { // if yes
            retVal = retVal &&
                this.valid_high_dimensional_type (validator, label) &&
                this.valid_high_dimensional_pathway(validator, label);
        }
    }
    return retVal;
}

// validate selected high dimensional platform
FormValidator.prototype.valid_high_dimensional_type = function (validator, label) {
    var retVal = false;

    // validate high dimensional platform
    if (!validator.high_dimensional_type) {
        this.push_error(defaults.messages.no_high_dimensional_type, [label]);
    } else {

        // validate supported high dimensional data types
        var _highDimensionalTypes = new HighDimensionalData();

        for (var key in _highDimensionalTypes.supportedTypes) {
            if (validator.high_dimensional_type == (_highDimensionalTypes.supportedTypes[key]).type) {
                retVal = true;
                break;
            }
        }

        if (!retVal) {
            this.push_error(
                defaults.messages.valid_high_dimensional_type, [label]);
        }
    }

    return retVal;
}

// validate selected high dimensional gene/pathway
FormValidator.prototype.valid_high_dimensional_pathway = function (validator, label) {
    var retVal = false;
    // validate high dimensional pathway
    if (!validator.high_dimensional_pathway) {
        this.push_error(defaults.messages.no_high_dimensional_pathway, [label]);
    } else {
        retVal = true;
    }

    return retVal;
}

// validate cohort selection must have at least two cohorts
FormValidator.prototype.min_two_subsets = function (subsets, label) {
    // validate high dimensional pathway
    for (var i=0; i<subsets.length; i++) {
        if (!subsets[i]) {
            this.push_error(defaults.messages.min_two_subsets, [label]);
            return false;
        }
    }
    return true;
}

// Utils
// -------------------------------------------------

FormValidator.prototype.format = function (str, arguments)
{
    var replaced = str;
    for (var i = 0; i < arguments.length; i++) {
        var regex = new RegExp('\\{'+i+'\\}');
        replaced = replaced.replace(regex,arguments[i]);
    }
    return replaced;
}

FormValidator.prototype.push_error = function (err_msg, args) {
    var err = this.format(err_msg, args);
    this.error_messages.push(err);
}

FormValidator.prototype.display_errors = function () {

    var _err_msgs = this.error_messages;
    var _err_str = "";

    // concatenate all error messages into a nice HTML friendly string message.
    for (var i=0; i<_err_msgs.length; i++) {
        _err_str = _err_str.concat("- " + _err_msgs[i] + "<br>");
    }

    // Display error messages inside extJs message box
    Ext.MessageBox.show({
        title: 'Validation Error',
        msg: _err_str,
        buttons: Ext.MessageBox.OK,
        icon: Ext.MessageBox.ERROR
    });
}
<commit_msg>remove pathway checking<commit_after>/**
 * FormValidator.js
 * User: rnugraha
 * Date: 29-10-13
 * Time: 15:27
 */

// Default error messages
var defaults = {
    messages: {
        required: 'The {0} field is required.',
        matches: 'The {0} field does not match the {1} field.',
        "default": 'The {0} field is still set to default, please change.',
        valid_email: 'The {0} field must contain a valid email address.',
        valid_emails: 'The {0} field must contain all valid email addresses.',
        min_length: 'The {0} field must be at least {1} characters in length.',
        max_length: 'The {0} field must not exceed {1} characters in length.',
        exact_length: 'The {0} field must be exactly {1} characters in length.',
        greater_than: 'The {0} field must contain a number greater than {1}.',
        less_than: 'The {0} field must contain a number less than {1}.',
        alpha: 'The {0} field must only contain alphabetical characters.',
        alpha_numeric: 'The {0} field must only contain alpha-numeric characters.',
        alpha_dash: 'The {0} field must only contain alpha-numeric characters, underscores, and dashes.',
        numeric: 'The {0} field must contain only numbers.',
        integer: 'The {0} field must contain an integer.',
        integer_range: '{0} must be between {1} and {2}.',
        integer_min: '{0} must be greater than or equal to {1}.',
        integer_max: '{0} must be less than or equal to {1}.',
        decimal: 'The {0} field must contain a decimal number.',
        is_natural: 'The {0} field must contain only positive numbers.',
        is_natural_no_zero: 'The {0} field must contain a number greater than zero.',
        valid_ip: 'The {0} field must contain a valid IP.',
        valid_base64: 'The {0} field must contain a base64 string.',
        valid_credit_card: 'The {0} field must contain a valid credit card number.',
        is_file_type: 'The {0} field must contain only {1} files.',
        valid_url: 'The {0} field must contain a valid URL.',
        valid_high_dimensional_node: 'The {0} field must contain high dimensional node only.',
        valid_high_dimensional_type: 'The {0} field contains invalid high dimensional data type.',
        no_high_dimensional_type: 'Unknown high dimensional data. Please verify first the high dimensional data ' +
            'in field {0}.',
        min_two_nodes: 'The {0} must be more than one nodes.',
        min_two_subsets: 'Marker Selection requires two subsets of cohorts to be selected. Please use the Comparison ' +
            'Tab and select the cohorts'
    },
    callback: function(errors) {

    }
};

// Some basic RegExp
var ruleRegex = /^(.+?)\[(.+)\]$/,
    numericRegex = /^[0-9]+$/,
    integerRegex = /^\-?[0-9]+$/,
    decimalRegex = /^\-?[0-9]*\.?[0-9]+$/,
    emailRegex = /^[a-zA-Z0-9.!#$%&'*+\-\/=?\^_`{|}~\-]+@[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*$/,
    alphaRegex = /^[a-z]+$/i,
    alphaNumericRegex = /^[a-z0-9]+$/i,
    alphaDashRegex = /^[a-z0-9_\-]+$/i,
    naturalRegex = /^[0-9]+$/i,
    naturalNoZeroRegex = /^[1-9][0-9]*$/i,
    ipRegex = /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/i,
    base64Regex = /[^a-zA-Z0-9\/\+=]/i,
    numericDashRegex = /^[\d\-\s]+$/,
    urlRegex = /^((http|https):\/\/(\w+:{0,1}\w*@)?(\S+)|)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;

var FormValidator = function (inputArray) {
    this.inputs = inputArray;
    this.error_messages = [];
}

FormValidator.prototype.validateInputForm = function () {

    var _isValid = true; //init
    var _inputArr = this.inputs;

    for (var i=0; i < _inputArr.length; i++) { // loop through input array

        // single instance of input object
        var _el = _inputArr[i].el;
        var _value = _inputArr[i].value;
        var _label = _inputArr[i].label;
        var _validations = _inputArr[i].validations;

        // initialize
        var _isRequired = false;
        var _isInteger = false;
        var _isHighDimensional = false;
        var _isTwoSubsets = false;

        for (var j = 0; j < _validations.length; j++) { // loop into validations for an input

            // 1st level validation - check mandatory
            if (_validations[j].type == "REQUIRED") {
                _isRequired = this.required(_el, _label);
                _isValid = _isValid && _isRequired;
            }

            if (_isValid) {
                switch (_validations[j].type)
                {
                    case 'INTEGER' :
                        _isInteger =  this.valid_integer(_el, _label, _validations[j]);
                        _isValid = _isValid && _isInteger;
                        break;
                    case 'HIGH_DIMENSIONAL' :
                        _isHighDimensional =  this.valid_high_dimensional(_el, _label, _validations[j]);
                        _isValid = _isValid && _isHighDimensional;
                        break;
                    case 'HIGH_DIMENSIONAL_ACGH' :
                        _isHighDimensional =  this.valid_high_dimensional_acgh(_el, _label, _validations[j]);
                        _isValid = _isValid && _isHighDimensional;
                        break;
                    case 'GROUP_VARIABLE' :
                        _isHighDimensional =  this.valid_group_variable(_el, _label);
                        _isValid = _isValid && _isHighDimensional;
                        break;
                    case 'MIN_TWO_SUBSETS' :
                        _isTwoSubsets = this.min_two_subsets(_value, _label);
                        _isValid = _isValid && _isTwoSubsets;
                        break;
                }
            }
        } // end validation loop
    }

    return _isValid;
}

// General validations
// -------------------------------------------------

FormValidator.prototype.required = function (el, label) {

    var retVal = true;

    if (el instanceof Ext.Element) {  // if input element is instance of Ext JS
        retVal = el.dom.childElementCount > 0 ? true : false;
    } else {
        var value = el.value;
        retVal = (value !== null && value !== '');
    }

    if (!retVal) {
        this.push_error(defaults.messages.required, [label]);
    }

    return retVal;

}

FormValidator.prototype.valid_integer = function (el, label, validator) {

    var retVal = integerRegex.test(el.value);

    if (!retVal) {
        this.push_error(defaults.messages.integer, [label]);
    } else {
        if (validator.min && validator.max) {
            var isWithinRange = (el.value >= validator.min) && (el.value <= validator.max) ? true : false;
            retVal = retVal && isWithinRange;
            if (!retVal)  this.push_error(defaults.messages.integer_range, [label, validator.min, validator.max]);
        } else if (validator.min && !validator.max) {
            var isGreaterThanEqual = (el.value >= validator.min) ? true : false;
            retVal = retVal && isGreaterThanEqual;
            if (!retVal)  this.push_error(defaults.messages.integer_min, [label, validator.min]);
        } else if (!validator.min &&  validator.max) {
            var isLessThanEqual = (el.value <= validator.min) ? true : false;
            retVal = retVal && isLessThanEqual;
            if (!retVal)  this.push_error(defaults.messages.integer_max, [label, validator.max]);
        }
    }
    return retVal;
}

// Custom validations
// -------------------------------------------------

FormValidator.prototype.valid_high_dimensional_acgh = function (el, label, validator) {

    var retVal = true;
    var nodes = el.dom.childNodes;

    for (var i=0; i<nodes.length; i++) { // loop through container
        var strVisualAttributes = nodes[i].attributes['visualattributes'].value;
        var isHD = true;

        // check if node is high dimensional data node
        if (strVisualAttributes.indexOf('HIGH_DIMENSIONAL') == -1) { // if not

            isHD = false;
            retVal = retVal && isHD;
            this.push_error(defaults.messages.valid_high_dimensional_node, [label]);

        }
    }
    return retVal;
}

FormValidator.prototype.valid_group_variable = function (el, label) {

    var retVal = true;
    var nodes = el.dom.childNodes;

    if (nodes.length < 2) {
        this.push_error(defaults.messages.min_two_nodes, [label]);
        return false;
    }

    return retVal;
}

// validate input to receive only high dimensional node
FormValidator.prototype.valid_high_dimensional = function (el, label, validator) {

    var retVal = true;
    var nodes = el.dom.childNodes;

    for (var i=0; i<nodes.length; i++) { // loop through container

        var strVisualAttributes = nodes[i].attributes['visualattributes'].value;
        var isHD = true;

        // check if node is high dimensional data node
        if (strVisualAttributes.indexOf('HIGH_DIMENSIONAL') == -1) { // if not

            isHD = false;
            retVal = retVal && isHD;
            this.push_error(defaults.messages.valid_high_dimensional_node, [label]);

        } else { // if yes
            retVal = retVal && this.valid_high_dimensional_type (validator, label)
        }
    }
    return retVal;
}

// validate selected high dimensional platform
FormValidator.prototype.valid_high_dimensional_type = function (validator, label) {
    var retVal = false;

    // validate high dimensional platform
    if (!validator.high_dimensional_type) {
        this.push_error(defaults.messages.no_high_dimensional_type, [label]);
    } else {

        // validate supported high dimensional data types
        var _highDimensionalTypes = new HighDimensionalData();

        for (var key in _highDimensionalTypes.supportedTypes) {
            if (validator.high_dimensional_type == (_highDimensionalTypes.supportedTypes[key]).type) {
                retVal = true;
                break;
            }
        }

        if (!retVal) {
            this.push_error(
                defaults.messages.valid_high_dimensional_type, [label]);
        }
    }

    return retVal;
}

// validate cohort selection must have at least two cohorts
FormValidator.prototype.min_two_subsets = function (subsets, label) {
    // validate high dimensional pathway
    for (var i=0; i<subsets.length; i++) {
        if (!subsets[i]) {
            this.push_error(defaults.messages.min_two_subsets, [label]);
            return false;
        }
    }
    return true;
}

// Utils
// -------------------------------------------------

FormValidator.prototype.format = function (str, arguments)
{
    var replaced = str;
    for (var i = 0; i < arguments.length; i++) {
        var regex = new RegExp('\\{'+i+'\\}');
        replaced = replaced.replace(regex,arguments[i]);
    }
    return replaced;
}

FormValidator.prototype.push_error = function (err_msg, args) {
    var err = this.format(err_msg, args);
    this.error_messages.push(err);
}

FormValidator.prototype.display_errors = function () {

    var _err_msgs = this.error_messages;
    var _err_str = "";

    // concatenate all error messages into a nice HTML friendly string message.
    for (var i=0; i<_err_msgs.length; i++) {
        _err_str = _err_str.concat("- " + _err_msgs[i] + "<br>");
    }

    // Display error messages inside extJs message box
    Ext.MessageBox.show({
        title: 'Validation Error',
        msg: _err_str,
        buttons: Ext.MessageBox.OK,
        icon: Ext.MessageBox.ERROR
    });
}
<|endoftext|>


<commit_before>
//
// Copyright 2016 Kary Foundation, Inc.
//   Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

'use strict'

//
// ─── DEFS ───────────────────────────────────────────────────────────────────────
//

    const electron                          = require( 'electron' )
    const { ipcMain, BrowserWindow, app }   = require( 'electron' )
    const messenger                         = require('messenger')
    const fs                                = require('fs')
    const path                              = require('path')

//
// ─── CONSTANTS ──────────────────────────────────────────────────────────────────
//

    const uniqueWindowIdKey = 'orchestra-unique-window-id'

    const orchestraVersion = '1.0'
    const quartetVersion = '1.2'

//
// ─── STORAGE ────────────────────────────────────────────────────────────────────
//

    let windowCount = 0
    let isHelpWindowOpen = false
    let isAboutWindowOpen = false
    let helpWindow

//
// ─── HELPER TOOLS ───────────────────────────────────────────────────────────────
//

    function existsSync ( filename ) {
        try {
            fs.accessSync( filename )
            return true
        } catch( ex ) {
            return false
        }
    }

//
// ─── GENERATE MAIN WINDOW ───────────────────────────────────────────────────────
//

    function createWindow ( file ) {
        let editorWindow

        const window_width = 1100
        const window_height = 640
        editorWindow = new BrowserWindow({
            show: false,
            width:  window_width,   minWidth: window_width - 150,
            height: window_height,  minHeight: window_height - 100,
            backgroundColor: '#F7F7F7',
            frame: false,
            fullscreen: false,
        })

        editorWindow.maximize( )

        editorWindow.openDevTools( )

        windowCount++

        if ( file === undefined | null )
            editorWindow.loadURL( `file://${ __dirname }/index.html` )
        else
            editorWindow.loadURL( `file://${ __dirname }/index.html?${ encodeURI( file ) }` )

        editorWindow.setMenuBarVisibility( false )

        editorWindow.once('ready-to-show', ( ) => {
            editorWindow.show( )
            editorWindow.focus( )
        })

        // editorWindow.openDevTools( );

        editorWindow.on( 'closed' , ( ) => {
            windowCount--
        })
    }

//
// ─── OPEN HELP WINDOW ───────────────────────────────────────────────────────────
//

    function openHelpWindow ( arg = '' ) {
        if ( isHelpWindowOpen ) return
        isHelpWindowOpen = true

        helpWindow = new BrowserWindow({
            title: "Quartet's Block Reference",
            width:  1050, minWidth: 1050,
            height: 600, minHeight: 200,
            backgroundColor: 'white',
            fullscreen: false,
        })

        if ( arg === '' ) {
            helpWindow.loadURL( `file://${ __dirname }/help/index.html?none` )
        } else {
            helpWindow.loadURL( `file://${ __dirname }/help/index.html?ref-${ arg }` )
        }

        helpWindow.on( 'closed' , ( ) => {
            isHelpWindowOpen = false
            helpWindow = null
        })
    }

//
// ─── OPEN ABOUT PAGE ────────────────────────────────────────────────────────────
//

    function openAboutWindow ( ) {
        if ( isAboutWindowOpen ) return
        isAboutWindowOpen = true

        let aboutWindow = new BrowserWindow({
            title: 'About Orchestra',
            width: 650, minWidth: 650, maxWidth: 650,
            height: 410, minHeight: 410, maxHeight: 410,
            backgroundColor: '#ECECEC',
            //show: false
        })

        aboutWindow.loadURL( `file://${ __dirname }/about/index.html?ov=${ orchestraVersion }&qv=${ quartetVersion }` )

        /*aboutWindow.once( 'ready-to-show', ( ) => {
            aboutWindow.show( )
        });*/

        aboutWindow.on( 'closed' , ( ) => {
            isAboutWindowOpen = false
            aboutWindow = null
        })
    }

//
// ─── SINGE INSTANCE APP ─────────────────────────────────────────────────────────
//

    const mustQuit = app.makeSingleInstance(( argv, workingDir ) => {
        createWindow( )
    })

    if ( mustQuit ) app.quit( )

//
// ─── ON OPEN FILE EVENT ─────────────────────────────────────────────────────────
//

    app.on( 'open-file', ( event, filePath ) => {
        event.preventDefault( )
        createWindow( filePath )
    })

//
// ─── ON READY ───────────────────────────────────────────────────────────────────
//

    app.on( 'ready' , ( ) => {
        console.log(`Orchestra, Version ${ orchestraVersion }`)
        console.log('Copyright 2016 - Kary Foundation, Inc.')

        runExtensionServer( )
        createWindow( )
    })

//
// ─── ON OPEN HELP WINDOW ────────────────────────────────────────────────────────
//

    ipcMain.on ( 'open-help-page', ( event, arg ) => openHelpWindow ( ))

//
// ─── OPEN HELP FOR REFERENCE ────────────────────────────────────────────────────
//

    ipcMain.on ( 'open-help-for-ref', ( event, arg ) => {
        if ( isHelpWindowOpen ) {
            helpWindow.focus( )
            helpWindow.webContents.send( 'help-window-open-ref', `ref-${ arg }` )
        } else {
            openHelpWindow( arg )
        }
    })

//
// ─── ON WINDOW ASKS ─────────────────────────────────────────────────────────────
//

    ipcMain.on( 'open-new-window', ( event, arg ) => createWindow( ) )

//
// ─── OPEN ABOUT PAGE ────────────────────────────────────────────────────────────
//

    ipcMain.on( 'open-about-page', ( event, arg ) => openAboutWindow( ) )

//
// ─── ON APP QUIT REQUEST ────────────────────────────────────────────────────────
//

    ipcMain.on( 'app-quit', ( event, arg ) => app.quit( ) )

//
// ─── QUIT APP ON WINDOWS CLOSE ──────────────────────────────────────────────────
//

    app.on( 'window-all-closed', ( e, win ) => {
        // On macOS it is common for applications and their menu bar
        // to stay active until the user quits explicitly with Cmd + Q
        if ( process.platform !== 'darwin' ) {
            app.quit( )
        }
    })

//
// ─── ON ACTIVE ──────────────────────────────────────────────────────────────────
//

    app.on( 'activate', ( ) => {
        // On macOS it's common to re-create a window in the app when the
        // dock icon is clicked and there are no other windows open.
        if ( windowCount === 0 ) {
            createWindow( )
        }
    });

//
// ─── EXTENSION SERVER ───────────────────────────────────────────────────────────
//

    function runExtensionServer ( ) {

        //
        // ─── CREATE SERVER ───────────────────────────────────────────────
        //

            const extensionServer = messenger.createListener( 5994 )

        //
        // ─── ON OPEN ORCHESTRA FOR A REGEX ───────────────────────────────
        //

            extensionServer.on( 'open', ( message, data ) => {
                if ( data !== null || data !== undefined ) {
                    if ( existsSync( data ) ) {
                        createWindow( data )
                    } else {
                        message.reply('404')
                    }
                } else {
                    createWindow( )
                }
            })

        // ─────────────────────────────────────────────────────────────────

    }

// ────────────────────────────────────────────────────────────────────────────────
<commit_msg>min...<commit_after>
//
// Copyright 2016 Kary Foundation, Inc.
//   Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

'use strict'

//
// ─── DEFS ───────────────────────────────────────────────────────────────────────
//

    const electron                          = require( 'electron' )
    const { ipcMain, BrowserWindow, app }   = require( 'electron' )
    const messenger                         = require('messenger')
    const fs                                = require('fs')
    const path                              = require('path')

//
// ─── CONSTANTS ──────────────────────────────────────────────────────────────────
//

    const uniqueWindowIdKey = 'orchestra-unique-window-id'

    const orchestraVersion = '1.0'
    const quartetVersion = '1.2'

//
// ─── STORAGE ────────────────────────────────────────────────────────────────────
//

    let windowCount = 0
    let isHelpWindowOpen = false
    let isAboutWindowOpen = false
    let helpWindow

//
// ─── HELPER TOOLS ───────────────────────────────────────────────────────────────
//

    function existsSync ( filename ) {
        try {
            fs.accessSync( filename )
            return true
        } catch( ex ) {
            return false
        }
    }

//
// ─── GENERATE MAIN WINDOW ───────────────────────────────────────────────────────
//

    function createWindow ( file ) {
        let editorWindow

        const window_width = 1100
        const window_height = 640
        editorWindow = new BrowserWindow({
            show: false,
            width:  window_width,   minWidth: window_width - 150,
            height: window_height,  minHeight: window_height - 100,
            backgroundColor: '#F7F7F7',
            frame: false,
            fullscreen: false,
        })

        editorWindow.maximize( )

        editorWindow.openDevTools( )

        windowCount++

        if ( file === undefined | null )
            editorWindow.loadURL( `file://${ __dirname }/index.html` )
        else
            editorWindow.loadURL( `file://${ __dirname }/index.html?${ encodeURI( file ) }` )

        editorWindow.setMenuBarVisibility( false )

        editorWindow.once('ready-to-show', ( ) => {
            editorWindow.show( )
            editorWindow.focus( )
        })

        // editorWindow.openDevTools( );

        editorWindow.on( 'closed' , ( ) => {
            windowCount--
        })
    }

//
// ─── OPEN HELP WINDOW ───────────────────────────────────────────────────────────
//

    function openHelpWindow ( arg = '' ) {
        if ( isHelpWindowOpen ) return
        isHelpWindowOpen = true

        helpWindow = new BrowserWindow({
            title: "Quartet's Block Reference",
            width:  1050, minWidth: 1050,
            height: 600, minHeight: 200,
            backgroundColor: 'white',
            fullscreen: false,
        })

        if ( arg === '' ) {
            helpWindow.loadURL( `file://${ __dirname }/help/index.html?none` )
        } else {
            helpWindow.loadURL( `file://${ __dirname }/help/index.html?ref-${ arg }` )
        }

        helpWindow.on( 'closed' , ( ) => {
            isHelpWindowOpen = false
            helpWindow = null
        })
    }

//
// ─── OPEN ABOUT PAGE ────────────────────────────────────────────────────────────
//

    function openAboutWindow ( ) {
        if ( isAboutWindowOpen ) return
        isAboutWindowOpen = true

        let aboutWindow = new BrowserWindow({
            title: 'About Orchestra',
            width: 650, minWidth: 650, maxWidth: 650,
            height: 410, minHeight: 410, maxHeight: 410,
            backgroundColor: '#ECECEC',
            //show: false
        })

        aboutWindow.loadURL( `file://${ __dirname }/about/index.html?ov=${ orchestraVersion }&qv=${ quartetVersion }` )

        /*aboutWindow.once( 'ready-to-show', ( ) => {
            aboutWindow.show( )
        });*/

        aboutWindow.on( 'closed' , ( ) => {
            isAboutWindowOpen = false
            aboutWindow = null
        })
    }

//
// ─── SINGE INSTANCE APP ─────────────────────────────────────────────────────────
//

    const mustQuit = app.makeSingleInstance(( argv, workingDir ) => {
        createWindow( )
    })

    if ( mustQuit ) app.quit( )

//
// ─── ON READY ───────────────────────────────────────────────────────────────────
//

    app.on( 'ready' , ( ) => {
        console.log(`Orchestra, Version ${ orchestraVersion }`)
        console.log('Copyright 2016 - Kary Foundation, Inc.')

        runExtensionServer( )
        createWindow( )
    })

//
// ─── ON OPEN FILE EVENT ─────────────────────────────────────────────────────────
//

    app.on( 'open-file', ( event, filePath ) => {
        event.preventDefault( )
        createWindow( filePath )
    })

//
// ─── ON OPEN HELP WINDOW ────────────────────────────────────────────────────────
//

    ipcMain.on ( 'open-help-page', ( event, arg ) => openHelpWindow ( ))

//
// ─── OPEN HELP FOR REFERENCE ────────────────────────────────────────────────────
//

    ipcMain.on ( 'open-help-for-ref', ( event, arg ) => {
        if ( isHelpWindowOpen ) {
            helpWindow.focus( )
            helpWindow.webContents.send( 'help-window-open-ref', `ref-${ arg }` )
        } else {
            openHelpWindow( arg )
        }
    })

//
// ─── ON WINDOW ASKS ─────────────────────────────────────────────────────────────
//

    ipcMain.on( 'open-new-window', ( event, arg ) => createWindow( ) )

//
// ─── OPEN ABOUT PAGE ────────────────────────────────────────────────────────────
//

    ipcMain.on( 'open-about-page', ( event, arg ) => openAboutWindow( ) )

//
// ─── ON APP QUIT REQUEST ────────────────────────────────────────────────────────
//

    ipcMain.on( 'app-quit', ( event, arg ) => app.quit( ) )

//
// ─── QUIT APP ON WINDOWS CLOSE ──────────────────────────────────────────────────
//

    app.on( 'window-all-closed', ( e, win ) => {
        // On macOS it is common for applications and their menu bar
        // to stay active until the user quits explicitly with Cmd + Q
        if ( process.platform !== 'darwin' ) {
            app.quit( )
        }
    })

//
// ─── ON ACTIVE ──────────────────────────────────────────────────────────────────
//

    app.on( 'activate', ( ) => {
        // On macOS it's common to re-create a window in the app when the
        // dock icon is clicked and there are no other windows open.
        if ( windowCount === 0 ) {
            createWindow( )
        }
    });

//
// ─── EXTENSION SERVER ───────────────────────────────────────────────────────────
//

    function runExtensionServer ( ) {

        //
        // ─── CREATE SERVER ───────────────────────────────────────────────
        //

            const extensionServer = messenger.createListener( 5994 )

        //
        // ─── ON OPEN ORCHESTRA FOR A REGEX ───────────────────────────────
        //

            extensionServer.on( 'open', ( message, data ) => {
                if ( data !== null || data !== undefined ) {
                    if ( existsSync( data ) ) {
                        createWindow( data )
                    } else {
                        message.reply('404')
                    }
                } else {
                    createWindow( )
                }
            })

        // ─────────────────────────────────────────────────────────────────

    }

// ────────────────────────────────────────────────────────────────────────────────
<|endoftext|>


<commit_before>'use strict';

var node_path         = require('path');
var async           = require('async');
var fs              = require('fs-sync');
var Installer       = require('cortex-install');

// used by ctx.commands.build
var argv_parser     = require('../util/parse-argv');
var command_build   = require('./build');

var USER_HOME = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];

// TODO:
// migrate to cortex-profile
var CORTEX_ROOT = node_path.join(USER_HOME, '.cortex');
var module_root = node_path.join(USER_HOME, '.cortex', 'modules');

function log(msg){
    process.stdout.write(msg + '\n');
};

// Attension: there will no arguments checking
// @param {Object} options:
// - modules: {Object} modules to install, ['a@1.0.1', 'b@0.0.2'], notice that the version of each module must be specified:
//    'a' should be 'a@latest'
// - save: {boolean} save cortexDependencies
// - cwd: {string}

// @param {function()} callback
module.exports = function(options, callback){
    var modules = options.modules;
    var should_save = options.save;
    var cwd = options.cwd;

    //
    var temp_dir = node_path.join(CORTEX_ROOT, 'tmp', + new Date + '');

    var installer = new Installer({

        // install modules into a temporary directory
        dir : temp_dir,
        key : "cortexDependencies",
        registry : options.registry
    });

    async.waterfall([
        function(done) {
            log('Installing: ["' + modules.join('", "') + '"]');

            // suppose:
            // 1. modules -> ['a@0.0.1', 'b@0.0.2']
            // 2. dependencies of 'b@0.0.2' -> ['a@0.0.2']
            installer.install(modules, function(
                error,

                // @type {Object} all versions including dependencies
                // {
                //     'a': {
                //         '0.0.1': {...}
                //         '0.0.2': {...}
                //     },
                //     'b': {
                //         '0.0.2': {...}
                //     }
                // }
                data,

                // @type {Object} the direct version of the module to be installed
                // { 'a': '0.0.1' }
                installed_map_without_deps
            ) {
                if(error){
                    throw error;
                }

                var installed_modules = [];
                var name;

                for(name in data){

                    // ['a@0.0.1', 'a@0.0.2']
                    installed_modules = installed_modules.concat(
                        Object.keys(data[name]).map(function(version) {
                            return name + '@' + version;
                        })
                    );
                }

                done(null, installed_modules, installed_map_without_deps);
            });
        },

        function(installed_modules, installed_map_without_deps, done) {
            // build modules
            var series = [];
            var installed_module_paths = installed_modules.map(function(module_at_version) {
                return module_at_version.replace('@', node_path.sep);
            });

            installed_module_paths.forEach(function(path) {
                series.push(function(d) {

                    // mock process.argv
                    var argv = ['', '', 'build', '--cwd', node_path.join(temp_dir, path, 'package') ];
                    var parsed = argv_parser(argv);

                    // exec cortex.commands.build method
                    command_build(parsed.options, function() {
                        d();
                    });
                });
            });

            async.series(series, function() {
                done(null, installed_module_paths, installed_map_without_deps);
            });
        }

    ], function(err, installed_module_paths, installed_map_without_deps) {

        // moving folder
        installed_module_paths.forEach(function(module_slash_version) {
            fs.copy(
                node_path.join(temp_dir, module_slash_version),
                node_path.join(module_root, module_slash_version), {
                    force: true
                }
            );
        });

        // remove temp_dir
        fs.delete(temp_dir);

        // save to package.json
        if(should_save){
            var package_file = node_path.join(cwd, 'package.json');
            var pkg = fs.readJSON(package_file);

            var deps = pkg.cortexDependencies || (pkg.cortexDependencies = {});
            var exact_deps = pkg.cortexExactDependencies || (pkg.cortexExactDependencies = {});

            Object.keys(installed_map_without_deps).forEach(function(name) {
                var exact_version = installed_map_without_deps[name];

                deps[name] = '~' + exact_version;
                exact_deps[name] = exact_version;
            });

            fs.write( package_file, JSON.stringify(pkg, null, 4) );
        }

        callback && callback();
    });
};

<commit_msg>migrate commander to "sub-commander"<commit_after>'use strict';

var node_path       = require('path');
var async           = require('async');
var fs              = require('fs-sync');
var Installer       = require('cortex-install');
var commander       = require('../commander');
var command_build   = require('./build');

var USER_HOME = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];

// TODO:
// migrate to cortex-profile
var CORTEX_ROOT = node_path.join(USER_HOME, '.cortex');
var module_root = node_path.join(USER_HOME, '.cortex', 'modules');

function log(msg){
    process.stdout.write(msg + '\n');
};

// Attension: there will no arguments checking
// @param {Object} options:
// - modules: {Object} modules to install, ['a@1.0.1', 'b@0.0.2'], notice that the version of each module must be specified:
//    'a' should be 'a@latest'
// - save: {boolean} save cortexDependencies
// - cwd: {string}

// @param {function()} callback
module.exports = function(options, callback){
    var modules = options.modules;
    var should_save = options.save;
    var cwd = options.cwd;

    //
    var temp_dir = node_path.join(CORTEX_ROOT, 'tmp', + new Date + '');

    var installer = new Installer({

        // install modules into a temporary directory
        dir : temp_dir,
        key : "cortexDependencies",
        registry : options.registry
    });

    async.waterfall([
        function(done) {
            log('Installing: ["' + modules.join('", "') + '"]');

            // suppose:
            // 1. modules -> ['a@0.0.1', 'b@0.0.2']
            // 2. dependencies of 'b@0.0.2' -> ['a@0.0.2']
            installer.install(modules, function(
                error,

                // @type {Object} all versions including dependencies
                // {
                //     'a': {
                //         '0.0.1': {...}
                //         '0.0.2': {...}
                //     },
                //     'b': {
                //         '0.0.2': {...}
                //     }
                // }
                data,

                // @type {Object} the direct version of the module to be installed
                // { 'a': '0.0.1' }
                installed_map_without_deps
            ) {
                if(error){
                    throw error;
                }

                var installed_modules = [];
                var name;

                for(name in data){

                    // ['a@0.0.1', 'a@0.0.2']
                    installed_modules = installed_modules.concat(
                        Object.keys(data[name]).map(function(version) {
                            return name + '@' + version;
                        })
                    );
                }

                done(null, installed_modules, installed_map_without_deps);
            });
        },

        function(installed_modules, installed_map_without_deps, done) {
            // build modules
            var series = [];
            var installed_module_paths = installed_modules.map(function(module_at_version) {
                return module_at_version.replace('@', node_path.sep);
            });

            installed_module_paths.forEach(function(path) {
                series.push(function(d) {

                    // mock process.argv
                    var argv = ['', '', 'build', '--cwd', node_path.join(temp_dir, path, 'package') ];
                    var parsed = commander.parse(argv);

                    // exec cortex.commands.build method
                    command_build(parsed.options, function() {
                        d();
                    });
                });
            });

            async.series(series, function() {
                done(null, installed_module_paths, installed_map_without_deps);
            });
        }

    ], function(err, installed_module_paths, installed_map_without_deps) {

        // moving folder
        installed_module_paths.forEach(function(module_slash_version) {
            fs.copy(
                node_path.join(temp_dir, module_slash_version),
                node_path.join(module_root, module_slash_version), {
                    force: true
                }
            );
        });

        // remove temp_dir
        fs.delete(temp_dir);

        // save to package.json
        if(should_save){
            var package_file = node_path.join(cwd, 'package.json');
            var pkg = fs.readJSON(package_file);

            var deps = pkg.cortexDependencies || (pkg.cortexDependencies = {});
            var exact_deps = pkg.cortexExactDependencies || (pkg.cortexExactDependencies = {});

            Object.keys(installed_map_without_deps).forEach(function(name) {
                var exact_version = installed_map_without_deps[name];

                deps[name] = '~' + exact_version;
                exact_deps[name] = exact_version;
            });

            fs.write( package_file, JSON.stringify(pkg, null, 4) );
        }

        callback && callback();
    });
};

<|endoftext|>


<commit_before>'use strict';

var install = module.exports = {};

var lang        = require('../util/lang');
var semver_helper = require('../util/semver');
var pkg_helper  = require('../util/package');
var node_path   = require('path');
var async       = require('async');
var fs          = require('fs-sync');
var spawn       = require('child_process').spawn;

// Attension: there will no arguments checking
// @param {Object} options:
// - modules: {Array.<string>} modules to install, ['a@1.0.1', 'b@0.0.2'], notice that the version of each module must be specified:
//    'a' should be 'a@latest', or there will be an failure
// - save: {boolean} save cortexDependencies
// - cwd: {string}
// - desc: {string} private property, which will never called by command-line
// - recursive: {boolean} if false, cortex will not install dependencies

// @param {function()} callback
install.run = function(options, callback) {
    options.module_root = this.context.profile.get('cache_root');

    var self = this;
    async.waterfall([
        function (done) {
            self.download_package(options, done);
        },

        function (done) {
            self.build_package(options, done);
        },

        function (done) {
            self.save_dependencies(options, done);
        },

        function (done) {
            self.clone_to_workspace(options, done);
        }

    ], callback);
};

install.download_package = function (options, callback) {
    var command_description = options.desc || 'installing';
    var modules = options.modules;

    this.logger.info('{{cyan ' + command_description + '}}', '["' + modules.join('", "') + '"]');

    // suppose:
    // 1. modules -> ['a@~0.0.1', 'b@0.0.2']
    // 2. dependencies of 'b@0.0.2' -> ['~a@0.1.2']
    this.context.neuropil.install({
        modules: modules,
        dir: options.module_root,
        recursive: options.recursive,
        dependency_key: 'dependencies'

    }, function (err, data) {
        if ( err ) {
            return callback(err);
        }

        options.data = data;
        callback(null);
    });
};

// @type {Object} options.data
// {
//     origins: {
//         'a': ['~0.0.1'],
//         'b': ['0.0.2']
//     },

//     packages: {
//         'a': {
//             '0.0.7': <pkg>,
//             '0.1.3': <pkg>
//         },

//         'b': {
//             '0.0.2': <pkg>
//         }
//     },

//     // according to `options.dependency_key`
//     dependencies: {
//         'a': {
//             '0.0.7': {}, // no deps
//             '0.1.3': {}
//         },

//         'b': {
//             '0.0.2': {
//                 'a': '~0.1.2'
//             }
//         }
//     },

//     ranges: {
//         'a': {
//             '~0.0.1': '0.0.7',
//             '~0.1.2': '0.1.3'
//         }
//     }
// }
install.build_package = function (options, callback) {
    // build modules
    var tasks = [];
    var commander = this.context.commander;

    this.iterate_packages(options.data, function(name, version) {
        tasks.push(function(done) {

            // mock process.argv
            var argv = [
                '', '',
                'build',

                // don't run `scripts.prebuild`
                '--no-prebuild',

                // run `scripts.preinstall`
                '--preinstall',
                '--cwd',
                node_path.join(options.module_root, name, version, 'package')
            ];

            commander.parse(argv, function(err, result, details) {
                if (err) {
                    return done(err);
                }

                // exec cortex.commands.build method
                commander.run('build', result.opt, done);
            });
        });
    });

    async.parallel(tasks, function (err) {
        callback(err);
    });
};

install.save_dependencies = function (options, callback) {
    // save to package.json
    if (options.save || options['save-async']) {
        var data = options.data;

        pkg_helper.get_original_package(options.cwd, function (err, ctx) {
            if ( err ) {
                return callback(err);
            }

            // if --save --save-async, --save-async will be ignored
            var key = options.save ? 'dependencies' : 'asyncDependencies';

            var deps = ctx[key] || (ctx[key] = {});
            // var exact_deps = ctx.exactDependencies || (ctx.exactDependencies = {});

            Object.keys(data.origins).forEach(function(name) {
                var versions = data.origins[name];
                var ranges = data.ranges[name] || {};

                versions.forEach(function(version) {
                    var exact_version = ranges[version] || version;

                    // It's great that `semver` does a awesome job on prerelease versions:
                    // '1.0.0-alpha' satisfies '~1.0.0',
                    // so we simply remove prerelease version before saving into field `dependencies`
                    deps[name] = '~' + semver_helper.remove_prerelease(exact_version);
                });
            });

            pkg_helper.save_package(options.cwd, ctx, callback);

        // use_inherits
        }, true);

    } else {
        callback(null);
    }
};

function just_done (done) {
    done();
}

install.clone_to_workspace = function(options, callback) {
    if ( !options.clone ) {
        return callback(null);
    }

    var data = options.data;
    var modules = [];
    var mod;

    // get all origin modules from cli
    for (mod in data.origins) {
        data.origins[mod].forEach(function(v) {
            modules.push({
                name: mod,
                version: v
            });
        });
    }

    var repos = {};
    var logger = this.logger;
    var workspace = this.context.profile.get('workspace') || options.cwd;

    var tasks = modules.map(function(mod) {
        var version = data.ranges[mod.name][mod.version];
        var package_json = data.packages[mod.name].versions[version];

        var is_git = lang.object_member_by_namespaces(package_json, "repository.type") == "git";
        var repo_url = lang.object_member_by_namespaces(package_json, "repository.url");

        if (!is_git || !repo_url || repos[repo_url]) {
            return just_done;

        } else {
            repos[repo_url] = true;

            return function(done) {
                logger.info("\n{{cyan clone}}", mod.name + ':', repo_url);
                var dir = node_path.join(workspace, mod.name);

                var child = spawn("git", ["clone", repo_url, dir], {
                    stdio: "inherit"
                });

                child.on("close", function(code, signal) {
                    if ( code ) {
                        done({
                            code: 'EGITCLONE',
                            message: 'fails to git-clone "' + repo_url + '"',
                            data: {
                                repo: repo_url,
                                dir : dir
                            }
                        });
                    } else {
                        done(null);
                    }
                });
            }
        }
    });

    async.parallel(tasks, callback);
}

// @param {Object} packages
// @param {function(name, version)} callback
install.iterate_packages = function(data, callback) {
    var origins = data.origins;

    lang.each(origins, function (versions, name) {
        var range = data.ranges[name] || {};
        versions.forEach(function (version) {
            callback(name, range[version] || version);
        });
    });
};

<commit_msg>command/install: change the install typo<commit_after>'use strict';

var install = module.exports = {};

var lang        = require('../util/lang');
var semver_helper = require('../util/semver');
var pkg_helper  = require('../util/package');
var node_path   = require('path');
var async       = require('async');
var fs          = require('fs-sync');
var spawn       = require('child_process').spawn;

// Attension: there will no arguments checking
// @param {Object} options:
// - modules: {Array.<string>} modules to install, ['a@1.0.1', 'b@0.0.2'], notice that the version of each module must be specified:
//    'a' should be 'a@latest', or there will be an failure
// - save: {boolean} save cortexDependencies
// - cwd: {string}
// - desc: {string} private property, which will never called by command-line
// - recursive: {boolean} if false, cortex will not install dependencies

// @param {function()} callback
install.run = function(options, callback) {
    options.module_root = this.context.profile.get('cache_root');

    var self = this;
    async.waterfall([
        function (done) {
            self.download_package(options, done);
        },

        function (done) {
            self.build_package(options, done);
        },

        function (done) {
            self.save_dependencies(options, done);
        },

        function (done) {
            self.clone_to_workspace(options, done);
        }

    ], callback);
};

install.download_package = function (options, callback) {
    var command_description = options.desc || 'installing';
    var modules = options.modules;

    this.logger.info('{{cyan ' + command_description + '}}', modules.join(', '));

    // suppose:
    // 1. modules -> ['a@~0.0.1', 'b@0.0.2']
    // 2. dependencies of 'b@0.0.2' -> ['~a@0.1.2']
    this.context.neuropil.install({
        modules: modules,
        dir: options.module_root,
        recursive: options.recursive,
        dependency_key: 'dependencies'

    }, function (err, data) {
        if ( err ) {
            return callback(err);
        }

        options.data = data;
        callback(null);
    });
};

// @type {Object} options.data
// {
//     origins: {
//         'a': ['~0.0.1'],
//         'b': ['0.0.2']
//     },

//     packages: {
//         'a': {
//             '0.0.7': <pkg>,
//             '0.1.3': <pkg>
//         },

//         'b': {
//             '0.0.2': <pkg>
//         }
//     },

//     // according to `options.dependency_key`
//     dependencies: {
//         'a': {
//             '0.0.7': {}, // no deps
//             '0.1.3': {}
//         },

//         'b': {
//             '0.0.2': {
//                 'a': '~0.1.2'
//             }
//         }
//     },

//     ranges: {
//         'a': {
//             '~0.0.1': '0.0.7',
//             '~0.1.2': '0.1.3'
//         }
//     }
// }
install.build_package = function (options, callback) {
    // build modules
    var tasks = [];
    var commander = this.context.commander;

    this.iterate_packages(options.data, function(name, version) {
        tasks.push(function(done) {

            // mock process.argv
            var argv = [
                '', '',
                'build',

                // don't run `scripts.prebuild`
                '--no-prebuild',

                // run `scripts.preinstall`
                '--preinstall',
                '--cwd',
                node_path.join(options.module_root, name, version, 'package')
            ];

            commander.parse(argv, function(err, result, details) {
                if (err) {
                    return done(err);
                }

                // exec cortex.commands.build method
                commander.run('build', result.opt, done);
            });
        });
    });

    async.parallel(tasks, function (err) {
        callback(err);
    });
};

install.save_dependencies = function (options, callback) {
    // save to package.json
    if (options.save || options['save-async']) {
        var data = options.data;

        pkg_helper.get_original_package(options.cwd, function (err, ctx) {
            if ( err ) {
                return callback(err);
            }

            // if --save --save-async, --save-async will be ignored
            var key = options.save ? 'dependencies' : 'asyncDependencies';

            var deps = ctx[key] || (ctx[key] = {});
            // var exact_deps = ctx.exactDependencies || (ctx.exactDependencies = {});

            Object.keys(data.origins).forEach(function(name) {
                var versions = data.origins[name];
                var ranges = data.ranges[name] || {};

                versions.forEach(function(version) {
                    var exact_version = ranges[version] || version;

                    // It's great that `semver` does a awesome job on prerelease versions:
                    // '1.0.0-alpha' satisfies '~1.0.0',
                    // so we simply remove prerelease version before saving into field `dependencies`
                    deps[name] = '~' + semver_helper.remove_prerelease(exact_version);
                });
            });

            pkg_helper.save_package(options.cwd, ctx, callback);

        // use_inherits
        }, true);

    } else {
        callback(null);
    }
};

function just_done (done) {
    done();
}

install.clone_to_workspace = function(options, callback) {
    if ( !options.clone ) {
        return callback(null);
    }

    var data = options.data;
    var modules = [];
    var mod;

    // get all origin modules from cli
    for (mod in data.origins) {
        data.origins[mod].forEach(function(v) {
            modules.push({
                name: mod,
                version: v
            });
        });
    }

    var repos = {};
    var logger = this.logger;
    var workspace = this.context.profile.get('workspace') || options.cwd;

    var tasks = modules.map(function(mod) {
        var version = data.ranges[mod.name][mod.version];
        var package_json = data.packages[mod.name].versions[version];

        var is_git = lang.object_member_by_namespaces(package_json, "repository.type") == "git";
        var repo_url = lang.object_member_by_namespaces(package_json, "repository.url");

        if (!is_git || !repo_url || repos[repo_url]) {
            return just_done;

        } else {
            repos[repo_url] = true;

            return function(done) {
                logger.info("\n{{cyan clone}}", mod.name + ':', repo_url);
                var dir = node_path.join(workspace, mod.name);

                var child = spawn("git", ["clone", repo_url, dir], {
                    stdio: "inherit"
                });

                child.on("close", function(code, signal) {
                    if ( code ) {
                        done({
                            code: 'EGITCLONE',
                            message: 'fails to git-clone "' + repo_url + '"',
                            data: {
                                repo: repo_url,
                                dir : dir
                            }
                        });
                    } else {
                        done(null);
                    }
                });
            }
        }
    });

    async.parallel(tasks, callback);
}

// @param {Object} packages
// @param {function(name, version)} callback
install.iterate_packages = function(data, callback) {
    var origins = data.origins;

    lang.each(origins, function (versions, name) {
        var range = data.ranges[name] || {};
        versions.forEach(function (version) {
            callback(name, range[version] || version);
        });
    });
};

<|endoftext|>


<commit_before>import fs from 'fs';
import path from 'path';
import {execSync} from 'child_process';
import {outputFileSync} from 'fs-extra';
import shelljs from 'shelljs/shell';

import {checkFileExists, createDir, getFileContent, createFile, getLineBreak, getCustomConfig} from '../utils';
import {logger} from '../logger';

export default function create(appPath, options = {}) {
  if (checkFileExists(`${shelljs.pwd()}/.meteor`)) {
    console.log('You are already in a Meteor project');
    return;
  }

  if (!appPath) {
    console.log('Please supply the path of project');
    console.log('Run `mantra create --help` for more options.');
    return;
  }
  const lineBreak = getLineBreak();
  let appName = path.basename(appPath).replace(/\..*$/, '');

  createDir(`${appPath}`);

  if (process.env.NODE_ENV !== 'test') {
    logger.invoke('init');
    shelljs.set('-e');
    let currentPath = shelljs.pwd();
    shelljs.exec(`meteor create ${appPath}`, {silent: !options.verbose});
    shelljs.cd(appPath);
    shelljs.rm('-rf', ['client', 'server']);
    `kadira:flow-router${lineBreak}`.toEnd('.meteor/packages');
    shelljs.cd(currentPath);
  }

  createFile(`${__dirname}/../../templates/client/configs/context.js`,
           `${appPath}/client/configs/context.js`);
  createFile(`${__dirname}/../../templates/client/main.js`,
           `${appPath}/client/main.js`);
  createFile(`${__dirname}/../../templates/client/modules/core/index.js`,
           `${appPath}/client/modules/core/index.js`);
  createFile(`${__dirname}/../../templates/client/modules/core/routes.jsx`,
           `${appPath}/client/modules/core/routes.jsx`);
  createDir(`${appPath}/client/modules/core/containers`);
  createDir(`${appPath}/client/modules/core/configs`);
  createDir(`${appPath}/client/modules/core/libs`);
  createFile(`${__dirname}/../../templates/client/modules/core/actions/index.js`,
           `${appPath}/client/modules/core/actions/index.js`);
  createFile(`${__dirname}/../../templates/client/modules/core/components/main_layout.jsx`,
           `${appPath}/client/modules/core/components/main_layout.jsx`);
  createFile(`${__dirname}/../../templates/client/modules/core/components/home.jsx`,
           `${appPath}/client/modules/core/components/home.jsx`);

  createFile(`${__dirname}/../../templates/lib/collections/index.js`,
           `${appPath}/lib/collections/index.js`);
  createDir(`${appPath}/server/configs`);
  createFile(`${__dirname}/../../templates/server/main.js`,
           `${appPath}/server/main.js`);
  createFile(`${__dirname}/../../templates/server/methods/index.js`,
           `${appPath}/server/methods/index.js`);
  createFile(`${__dirname}/../../templates/server/publications/index.js`,
           `${appPath}/server/publications/index.js`);
  createFile(`${__dirname}/../../templates/package.tt`,
          `${appPath}/package.json`, {appName: appName});
  createFile(`${__dirname}/../../templates/gitignore.tt`,
          `${appPath}/.gitignore`);
  createFile(`${__dirname}/../../templates/eslintrc.tt`,
          `${appPath}/.eslintrc`);
  createFile(`${__dirname}/../../templates/babelrc.tt`,
          `${appPath}/.babelrc`);
  createFile(`${__dirname}/../../templates/.scripts/mocha_boot.tt`,
          `${appPath}/.scripts/mocha_boot.js`);

  // Generate storybook related files
  if (options.storybook) {
    createDir(`${appPath}/.storybook`);
    createFile(`${__dirname}/../../templates/.storybook/config.js`,
      `${appPath}/.storybook/config.js`);
    createFile(`${__dirname}/../../templates/.storybook/webpack.config.js`,
      `${appPath}/.storybook/webpack.config.js`);
    createDir(`${appPath}/client/modules/core/components/.stories`);
    createFile(`${__dirname}/../../templates/client/modules/core/components/.stories/index.js`,
      `${appPath}/client/modules/core/components/.stories/index.js`);
  }

  // Generate test directories
  createDir(`${appPath}/client/modules/core/containers/tests`);
  createDir(`${appPath}/client/modules/core/actions/tests`);
  createDir(`${appPath}/client/modules/core/components/tests`);

  // Generate config file
  let customConfig = getCustomConfig({ storybook: Boolean(options.storybook) });
  outputFileSync(`${appPath}/mantra_cli.yaml`, customConfig);

  if (process.env.NODE_ENV !== 'test') {
    logger.invoke('after_init');
    shelljs.set('-e');
    let currentPath = shelljs.pwd();
    shelljs.cd(appPath);
    shelljs.exec('npm install', {silent: !options.verbose});
    shelljs.cd(currentPath);
  }

  console.log('');
  console.log(`Created a new app using Mantra v0.2.0 at ${appPath}`);
  console.log('');
  console.log('To run your app:');
  console.log(`  cd ${appPath}`);
  console.log(`  meteor`);
  console.log('');
  console.log('For the full Mantra specifications, see: https://kadirahq.github.io/mantra');
}
<commit_msg>Make sure that reactive-dict is added<commit_after>import fs from 'fs';
import path from 'path';
import {execSync} from 'child_process';
import {outputFileSync} from 'fs-extra';
import shelljs from 'shelljs/shell';

import {checkFileExists, createDir, getFileContent, createFile, getLineBreak, getCustomConfig} from '../utils';
import {logger} from '../logger';

export default function create(appPath, options = {}) {
  if (checkFileExists(`${shelljs.pwd()}/.meteor`)) {
    console.log('You are already in a Meteor project');
    return;
  }

  if (!appPath) {
    console.log('Please supply the path of project');
    console.log('Run `mantra create --help` for more options.');
    return;
  }
  const lineBreak = getLineBreak();
  let appName = path.basename(appPath).replace(/\..*$/, '');

  createDir(`${appPath}`);

  if (process.env.NODE_ENV !== 'test') {
    logger.invoke('init');
    shelljs.set('-e');
    let currentPath = shelljs.pwd();
    shelljs.exec(`meteor create ${appPath}`, {silent: !options.verbose});
    shelljs.cd(appPath);
    shelljs.rm('-rf', ['client', 'server']);
    `kadira:flow-router${lineBreak}`.toEnd('.meteor/packages');
    shelljs.rm('-rf', ['client', 'server']);
    `reactive-dict${lineBreak}`.toEnd('.meteor/packages');
    shelljs.cd(currentPath);
  }

  createFile(`${__dirname}/../../templates/client/configs/context.js`,
           `${appPath}/client/configs/context.js`);
  createFile(`${__dirname}/../../templates/client/main.js`,
           `${appPath}/client/main.js`);
  createFile(`${__dirname}/../../templates/client/modules/core/index.js`,
           `${appPath}/client/modules/core/index.js`);
  createFile(`${__dirname}/../../templates/client/modules/core/routes.jsx`,
           `${appPath}/client/modules/core/routes.jsx`);
  createDir(`${appPath}/client/modules/core/containers`);
  createDir(`${appPath}/client/modules/core/configs`);
  createDir(`${appPath}/client/modules/core/libs`);
  createFile(`${__dirname}/../../templates/client/modules/core/actions/index.js`,
           `${appPath}/client/modules/core/actions/index.js`);
  createFile(`${__dirname}/../../templates/client/modules/core/components/main_layout.jsx`,
           `${appPath}/client/modules/core/components/main_layout.jsx`);
  createFile(`${__dirname}/../../templates/client/modules/core/components/home.jsx`,
           `${appPath}/client/modules/core/components/home.jsx`);

  createFile(`${__dirname}/../../templates/lib/collections/index.js`,
           `${appPath}/lib/collections/index.js`);
  createDir(`${appPath}/server/configs`);
  createFile(`${__dirname}/../../templates/server/main.js`,
           `${appPath}/server/main.js`);
  createFile(`${__dirname}/../../templates/server/methods/index.js`,
           `${appPath}/server/methods/index.js`);
  createFile(`${__dirname}/../../templates/server/publications/index.js`,
           `${appPath}/server/publications/index.js`);
  createFile(`${__dirname}/../../templates/package.tt`,
          `${appPath}/package.json`, {appName: appName});
  createFile(`${__dirname}/../../templates/gitignore.tt`,
          `${appPath}/.gitignore`);
  createFile(`${__dirname}/../../templates/eslintrc.tt`,
          `${appPath}/.eslintrc`);
  createFile(`${__dirname}/../../templates/babelrc.tt`,
          `${appPath}/.babelrc`);
  createFile(`${__dirname}/../../templates/.scripts/mocha_boot.tt`,
          `${appPath}/.scripts/mocha_boot.js`);

  // Generate storybook related files
  if (options.storybook) {
    createDir(`${appPath}/.storybook`);
    createFile(`${__dirname}/../../templates/.storybook/config.js`,
      `${appPath}/.storybook/config.js`);
    createFile(`${__dirname}/../../templates/.storybook/webpack.config.js`,
      `${appPath}/.storybook/webpack.config.js`);
    createDir(`${appPath}/client/modules/core/components/.stories`);
    createFile(`${__dirname}/../../templates/client/modules/core/components/.stories/index.js`,
      `${appPath}/client/modules/core/components/.stories/index.js`);
  }

  // Generate test directories
  createDir(`${appPath}/client/modules/core/containers/tests`);
  createDir(`${appPath}/client/modules/core/actions/tests`);
  createDir(`${appPath}/client/modules/core/components/tests`);

  // Generate config file
  let customConfig = getCustomConfig({ storybook: Boolean(options.storybook) });
  outputFileSync(`${appPath}/mantra_cli.yaml`, customConfig);

  if (process.env.NODE_ENV !== 'test') {
    logger.invoke('after_init');
    shelljs.set('-e');
    let currentPath = shelljs.pwd();
    shelljs.cd(appPath);
    shelljs.exec('npm install', {silent: !options.verbose});
    shelljs.cd(currentPath);
  }

  console.log('');
  console.log(`Created a new app using Mantra v0.2.0 at ${appPath}`);
  console.log('');
  console.log('To run your app:');
  console.log(`  cd ${appPath}`);
  console.log(`  meteor`);
  console.log('');
  console.log('For the full Mantra specifications, see: https://kadirahq.github.io/mantra');
}
<|endoftext|>