function(name, valueName) {
      if (this.__scope.vars[name] === undefined) {
        this.__scope.vars[name] = valueName || true;
        var unresolved = this.__scope.unresolved;
        delete unresolved[name];
        var re = new RegExp(name + "\\.");
        for (var tmp in unresolved) {
          if (re.test(tmp)) {
            delete unresolved[tmp];
          }
        }
      }
    }

function ( name , valueName ) { if ( this . __scope . vars [ name ] === undefined ) { this . __scope . vars [ name ] = valueName || true ; var unresolved = this . __scope . unresolved ; delete unresolved [ name ] ; var re = new RegExp ( name + "\\." ) ; for ( var tmp in unresolved ) { if ( re . test ( tmp ) ) { delete unresolved [ tmp ] ; } } } }

Adds a variable declaration to the current scope; if the symbol was
previously "unresolved" it is removed from the unresolved list

@param name {String} the name of the variabvle being declared
@param valueName {String} the value to assign to the variable

Adds a variable declaration to the current scope ; if the symbol was previously unresolved it is removed from the unresolved list


function(name) {
      var pos = name.indexOf(".");
      if (pos > -1) {
        name = name.substring(0, pos);
      }
      for (var tmp = this.__scope; tmp; tmp = tmp.parent) {
        if (tmp.vars[name] !== undefined) {
          return true;
        }
      }
      return false;
    }

function ( name ) { var pos = name . indexOf ( "." ) ; if ( pos > - 1 ) { name = name . substring ( 0 , pos ) ; } for ( var tmp = this . __scope ; tmp ; tmp = tmp . parent ) { if ( tmp . vars [ name ] !== undefined ) { return true ; } } return false ; }

Tests whether there is a variable declaration accessible to the current
scope, ie including parent scope

@param name
@returns {Boolean}

Tests whether there is a variable declaration accessible to the current scope ie including parent scope


function(name, loc) {
      var str = "";
      for (var i = 0; i < name.length; i++) {
        if (i) {
          str += ".";
        }
        str += name[i];
        if (qx.tool.compiler.ClassFile.GLOBAL_SYMBOLS[str] || this.isIgnored(str)) {
          return;
        }
      }
      name = name.join(".");
      if (name == this.__className || name.startsWith(this.__className + ".") || name.startsWith("(")) {
        return;
      }
      if (name == "qx.ui.tooltip.ToolTip")
        debugger;
      var scope = this.__scope;
      if (scope.vars[name] !== undefined) {
        return;
      }

      if (!scope.unresolved[name]) {
        scope.unresolved[name] = {
          name: name,
          locations: loc ? [loc] : [],
          load: this.isLoadScope(),
          defer: this.__inDefer
        };
      } else if (loc) {
        scope.unresolved[name].locations.push(loc);
      }
    }

function ( name , loc ) { var str = "" ; for ( var i = 0 ; i < name . length ; i ++ ) { if ( i ) { str += "." ; } str += name [ i ] ; if ( qx . tool . compiler . ClassFile . GLOBAL_SYMBOLS [ str ] || this . isIgnored ( str ) ) { return ; } } name = name . join ( "." ) ; if ( name == this . __className || name . startsWith ( this . __className + "." ) || name . startsWith ( "(" ) ) { return ; } if ( name == "qx.ui.tooltip.ToolTip" ) debugger ; var scope = this . __scope ; if ( scope . vars [ name ] !== undefined ) { return ; } if ( ! scope . unresolved [ name ] ) { scope . unresolved [ name ] = { name : name , locations : loc ? [ loc ] : [ ] , load : this . isLoadScope ( ) , defer : this . __inDefer } ; } else if ( loc ) { scope . unresolved [ name ] . locations . push ( loc ) ; } }

Adds a reference to a symbol; unknown symbols are marked as unresolved
@param name
@param loc

Adds a reference to a symbol ; unknown symbols are marked as unresolved


function(name) {
      delete this.__scope.unresolved[name];
      var stub = name + ".";
      for (var id in this.__scope.unresolved) {
        if (id.startsWith(stub)) {
          delete this.__scope.unresolved[id];
        }
      }
    }

function ( name ) { delete this . __scope . unresolved [ name ] ; var stub = name + "." ; for ( var id in this . __scope . unresolved ) { if ( id . startsWith ( stub ) ) { delete this . __scope . unresolved [ id ] ; } } }

Removes a reference from scope; this should only really be used after scanning is complete
@param name

Removes a reference from scope ; this should only really be used after scanning is complete


function(name) {
      var scope = this.__scope;
      if (!scope.ignore) {
        scope.ignore = {};
      }
      var segs = name.split(",");
      segs.forEach(name => {
        if (name.endsWith(".*")) {
          scope.ignore[name] = name.substring(0, name.length - 2);
        } else if (name.endsWith("*")) {
          scope.ignore[name] = name.substring(0, name.length - 1);
        } else {
          scope.ignore[name] = true;
        }
      });
    }

function ( name ) { var scope = this . __scope ; if ( ! scope . ignore ) { scope . ignore = { } ; } var segs = name . split ( "," ) ; segs . forEach ( name => { if ( name . endsWith ( ".*" ) ) { scope . ignore [ name ] = name . substring ( 0 , name . length - 2 ) ; } else if ( name . endsWith ( "*" ) ) { scope . ignore [ name ] = name . substring ( 0 , name . length - 1 ) ; } else { scope . ignore [ name ] = true ; } } ) ; }

Adds an ignored symbol
@param name {String} name of the symbol


function(name) {
      for (var tmp = this.__scope; tmp; tmp = tmp.parent) {
        if (tmp.ignore) {
          if (tmp.ignore[name]) {
            return true;
          }
          for (var key in tmp.ignore) {
            if (tmp.ignore[key] !== true) {
              if (name.startsWith(tmp.ignore[key])) {
                return true;
              }
            }
          }
        }
      }
      return false;
    }

function ( name ) { for ( var tmp = this . __scope ; tmp ; tmp = tmp . parent ) { if ( tmp . ignore ) { if ( tmp . ignore [ name ] ) { return true ; } for ( var key in tmp . ignore ) { if ( tmp . ignore [ key ] !== true ) { if ( name . startsWith ( tmp . ignore [ key ] ) ) { return true ; } } } } } return false ; }

Tests whether a symbol has already been marked as ignore
@param name {String} symbol name
@param {Boolean} true if ignored


function(name, location) {
      var t = this;
      var requiredOpts = {
        load: t.isLoadScope(),
        defer: t.__inDefer,
        construct: t.__classMeta && t.__classMeta.functionName == "$$constructor",
        location: location
      };
      var dest = t.__environmentChecks.required[name];
      if (!dest) {
        dest = t.__environmentChecks.required[name] = {};
      }
      if (requiredOpts.load) {
        dest.load = true;
      }
      if (requiredOpts.defer) {
        dest.defer = true;
      }
      if (requiredOpts.construct) {
        dest.construct = true;
      }
      t._requireClass("qx.core.Environment", { location: location });
      if (qx.tool.compiler.ClassFile.ENVIRONMENT_CONSTANTS[name] === undefined) {
        var entry = qx.tool.compiler.ClassFile.ENVIRONMENT_CHECKS[name];
        if (entry && entry.className) {
          t._requireClass(entry.className, { load: requiredOpts.load, location: location });
          dest.className = entry.className;
        } else if (!entry) {
          t._requireClass(name, { load: requiredOpts.load, location: location });
        }
      }
    }

function ( name , location ) { var t = this ; var requiredOpts = { load : t . isLoadScope ( ) , defer : t . __inDefer , construct : t . __classMeta && t . __classMeta . functionName == "$$constructor" , location : location } ; var dest = t . __environmentChecks . required [ name ] ; if ( ! dest ) { dest = t . __environmentChecks . required [ name ] = { } ; } if ( requiredOpts . load ) { dest . load = true ; } if ( requiredOpts . defer ) { dest . defer = true ; } if ( requiredOpts . construct ) { dest . construct = true ; } t . _requireClass ( "qx.core.Environment" , { location : location } ) ; if ( qx . tool . compiler . ClassFile . ENVIRONMENT_CONSTANTS [ name ] === undefined ) { var entry = qx . tool . compiler . ClassFile . ENVIRONMENT_CHECKS [ name ] ; if ( entry && entry . className ) { t . _requireClass ( entry . className , { load : requiredOpts . load , location : location } ) ; dest . className = entry . className ; } else if ( ! entry ) { t . _requireClass ( name , { load : requiredOpts . load , location : location } ) ; } } }

Adds an environment check made by the class

@param name
@param opts {Object?} see _requireClass


function(name, opts) {
      if (qx.lang.Type.isArray(name)) {
        name.forEach(name => this._requireClass(name));
        return null;
      }
      let t = this;
      if (name == this.__className) {
        return null;
      }
      if (!name) {
        throw new Error("No classname");
      }
      if (this.isIgnored(name)) {
        return null;
      }

      let requireOpts = {
        load: t.isLoadScope(),
        defer: t.__inDefer,
        construct: t.__classMeta && t.__classMeta.functionName == "$$constructor"
      };
      if (opts) {
        for (let key in opts) {
          requireOpts[key] = opts[key];
        }
      }

      let info = t.__analyser.getSymbolType(name);
      let symbolType = info ? info.symbolType : null;
      let className = info ? info.className : null;
      if (symbolType != "package" && className && className != t.__className) {
        // Re-check the class name as ignored if this is a member
        if (symbolType == "member" && t.isIgnored(className)) {
          return null;
        }
        let data = t.__requiredClasses[className];
        if (!data) {
          data = t.__requiredClasses[className] = {};
        }

        if (requireOpts.where !== undefined) {
          if (requireOpts.where == "ignore") {
            data.ignore = true;
          } else if (requireOpts.where == "require") {
            data.require = true;
          }
        }
        if (requireOpts.load) {
          data.load = true;
          if (requireOpts.usage === "dynamic") {
            if (data.usage !== "static") {
              data.usage = "dynamic";
            }
            data.load = true;
          } else if (!data.load) {
            data.load = true;
            data.usage = "static";
          }
        }
        if (requireOpts.defer) {
          if (requireOpts.load) {
            data.defer = "load";
          } else if (data.defer !== "load") {
            data.defer = "runtime";
          }

          if (!name.startsWith(t.__className)) {
            if (!qx.tool.compiler.ClassFile.DEFER_SAFE_SYMBOLS.some(function(symbol) {
              return name.startsWith(symbol);
            })) {
              // Temporarily disabled until Qooxdoo framework catches up
              // t.addMarker("defer.unsafe", (opts && opts.location)||null, name);
            }
          }
        }
        if (requireOpts.construct) {
          data.construct = true;
        }
        t.deleteReference(className);
      }
      return info;
    }

Adds a required class

@param name {String} the name of the class
@param opts {Map?} which is:

@param where {"ignore"|"require"|"use"|null} where it's mentioned
@param load {Boolean?} whether it is a load-time dependency or not
@param defer {Boolean?} whether the dependency is in defer or not
@return {Map?} info about the symbol type of the named class, @see {Analyser.getSymbolType}


function(path) {
      if (path.indexOf("/") < 0 && path.indexOf(".") > -1) {
        path = path.replace(/\./g, "/");
      }
      if (!qx.lang.Array.contains(this.__requiredAssets, path)) {
        this.__requiredAssets.push(path);
      }
    }

function ( path ) { if ( path . indexOf ( "/" ) < 0 && path . indexOf ( "." ) > - 1 ) { path = path . replace ( / \. / g , "/" ) ; } if ( ! qx . lang . Array . contains ( this . __requiredAssets , path ) ) { this . __requiredAssets . push ( path ) ; } }


function(library, className) {
      return pathModule.join(library.getRootDir(), library.getSourcePath(), className.replace(/\./g, pathModule.sep) + ".js");
    }

function ( library , className ) { return pathModule . join ( library . getRootDir ( ) , library . getSourcePath ( ) , className . replace ( / \. / g , pathModule . sep ) + ".js" ) ; }

Returns the absolute path to the class file

@param library {qx.tool.compiler.app.Library}
@param className {String}
@returns {String}


function(analyser, className) {
      var filename = pathModule.join(analyser.getOutputDir(), "transpiled", className.replace(/\./g, pathModule.sep) + ".js");
      return filename;
    }

function ( analyser , className ) { var filename = pathModule . join ( analyser . getOutputDir ( ) , "transpiled" , className . replace ( / \. / g , pathModule . sep ) + ".js" ) ; return filename ; }

Returns the path to the rewritten class file

@param library {qx.tool.compiler.app.Library}
@param className {String}
@returns {String}


function(array, searchElement) {
        var minIndex = 0;
        var maxIndex = array.length - 1;
        var currentIndex;
        var currentElement;

        while (minIndex <= maxIndex) {
            currentIndex = (minIndex + maxIndex) / 2 | 0;
            currentElement = array[currentIndex];

            if (currentElement < searchElement) {
                minIndex = currentIndex + 1;
            } else if (currentElement > searchElement) {
                maxIndex = currentIndex - 1;
            } else {
                return currentIndex;
            }
        }

        return -1;
    }

function ( array , searchElement ) { var minIndex = 0 ; var maxIndex = array . length - 1 ; var currentIndex ; var currentElement ; while ( minIndex <= maxIndex ) { currentIndex = ( minIndex + maxIndex ) / 2 | 0 ; currentElement = array [ currentIndex ] ; if ( currentElement < searchElement ) { minIndex = currentIndex + 1 ; } else if ( currentElement > searchElement ) { maxIndex = currentIndex - 1 ; } else { return currentIndex ; } } return - 1 ; }

Performs a binary search on the host array.

Thanks to Oliver Caldwell for this snippet, https://oli.me.uk/2013/06/08/searching-javascript-arrays-with-a-binary-search/

@param {*} array The array to search.
@param {*} searchElement The item to search for within the array.
@return {Number} The index of the element which defaults to -1 when not found.

Performs a binary search on the host array .


async function() {
      let compile = await this.parseCompileConfig();
      for (let target of compile.targets) {
        await this.__removePath(path.join(process.cwd(), target.outputPath));
      }
      await this.__removePath(path.join(process.cwd(), "contrib"));
    }

async function ( ) { let compile = await this . parseCompileConfig ( ) ; for ( let target of compile . targets ) { await this . __removePath ( path . join ( process . cwd ( ) , target . outputPath ) ) ; } await this . __removePath ( path . join ( process . cwd ( ) , "contrib" ) ) ; }


function getPages(files, metalsmith, done) {
  var metadata = metalsmith.metadata();

  var pages = [];
  var order = {};
  if (metadata.site.pages)
    metadata.site.pages.forEach((url, index) => typeof url == "string" ? order[url] = index : null);
  var unorderedPages = [];

  function addPage(url, title) {
    var page = {
      url: url,
      title: title
    };
    var index = order[url];
    if (index !== undefined)
      pages[index] = page;
    else
      unorderedPages.push(page);
  }

  for (var filename in files) {
    var file = files[filename];
    if (filename == "index.html")
      addPage("/", file.title||"Home Page");
    else if (file.permalink || file.navigation)
      addPage(file.permalink||filename, file.title||"Home Page");
  }

  unorderedPages.forEach(page => pages.push(page));
  metadata.site.pages = pages;

  done();
}

function
getPages
(
files
,
metalsmith
,
done
)
{
var
metadata
=
metalsmith
.
metadata
(
)
;
var
pages
=
[
]
;
var
order
=
{
}
;
if
(
metadata
.
site
.
pages
)
metadata
.
site
.
pages
.
forEach
(
(
url
,
index
)
=>
typeof
url
==
"string"
order
[
url
]
=
index
:
)
;
var
unorderedPages
=
[
]
;
function
addPage
(
url
,
title
)
{
var
page
=
{
url
:
url
,
title
:
title
}
;
var
index
=
order
[
url
]
;
if
(
index
!==
undefined
)
pages
[
index
]
=
page
;
else
unorderedPages
.
push
(
page
)
;
}
for
(
var
filename
in
files
)
{
var
file
=
files
[
filename
]
;
if
(
filename
==
"index.html"
)
addPage
(
"/"
,
file
.
title
||
"Home Page"
)
;
else
if
(
file
.
permalink
||
file
.
navigation
)
addPage
(
file
.
permalink
||
filename
,
file
.
title
||
"Home Page"
)
;
}
unorderedPages
.
forEach
(
page
=>
pages
.
push
(
page
)
)
;
metadata
.
site
.
pages
=
pages
;
done
(
)
;
}

Metalsmith Plugin that collates a list of pages that are to be included in the site navigation
into the metadata, along with their URLs.

If the metadata has a `sites.pages`, then it is expected to be an array of URLs which indicates
the ordering to be applied; `sites.pages` is replaced with an array of objects, one per page,
that contains `url` and `title` properties.

Metalsmith Plugin that collates a list of pages that are to be included in the site navigation into the metadata along with their URLs .


function loadPartials(files, metalsmith, done) {
  var metadata = metalsmith.metadata();

  fs.readdirAsync("./partials", "utf8")
    .then(files => {
      var promises = files.map(filename => {
        var m = filename.match(/^(.+)\.([^.]+)$/);
        if (!m)
          return;
        var name = m[1];
        var ext = m[2];
        return fs.readFileAsync("partials/" + filename, "utf8")
          .then(data => {
            var fn;
            try {
              fn = dot.template(data);
            }catch(err) {
              console.log("Failed to load partial " + filename + ": " + err);
              return;
            }
            fn.name = filename;
            metadata.partials[filename] = fn;
            if (ext == "html")
              metadata.partials[name] = fn;
          });
      });
      return Promise.all(promises);
    })
    .then(() => done())
    .catch(err => done(err));
}

function
loadPartials
(
files
,
metalsmith
,
done
)
{
var
metadata
=
metalsmith
.
metadata
(
)
;
fs
.
readdirAsync
(
"./partials"
,
"utf8"
)
.
then
(
files
=>
{
var
promises
=
files
.
map
(
filename
=>
{
var
m
=
filename
.
match
(
/
^(.+)\.([^.]+)$
/
)
;
if
(
!
m
)
return
;
var
name
=
m
[
1
]
;
var
ext
=
m
[
2
]
;
return
fs
.
readFileAsync
(
"partials/"
+
filename
,
"utf8"
)
.
then
(
data
=>
{
var
fn
;
try
{
fn
=
dot
.
template
(
data
)
;
}
catch
(
err
)
{
console
.
log
(
"Failed to load partial "
+
filename
+
": "
+
err
)
;
return
;
}
fn
.
name
=
filename
;
metadata
.
partials
[
filename
]
=
fn
;
if
(
ext
==
"html"
)
metadata
.
partials
[
name
]
=
fn
;
}
)
;
}
)
;
return
Promise
.
all
(
promises
)
;
}
)
.
then
(
(
)
=>
done
(
)
)
.
catch
(
err
=>
done
(
err
)
)
;
}

Metalsmith plugin that loads partials and adding them to the metadata.partials map.  Each file
is added with it's filename, and if it is a .html filename is also added without the .html
extension.

Metalsmith plugin that loads partials and adding them to the metadata . partials map . Each file is added with it s filename and if it is a . html filename is also added without the . html extension .


function generateSite() {
  return new Promise((resolve, reject) => {
    Metalsmith(__dirname)
      .metadata({
        site: {
          title: "Qooxdoo Application Server",
          description: "Mini website used by \"qx serve\"",
          email: "info@qooxdoo.org",
          twitter_username: "qooxdoo",
          github_username: "qooxdoo",
          pages: [ "/", "/about/" ]
        },
        baseurl: "",
        url: "",
        lang: "en",
        partials: {}
      })
      .source('./src')
      .destination('./build')
      .clean(true)
      .use(loadPartials)
      .use(markdown())
      .use(getPages)
      .use(layouts({
        engine: 'dot'
      }))
      .build(function(err) {
        if (err)
          reject(err);
        else
          resolve();
      });
  });
}

function
generateSite
(
)
{
return
new
Promise
(
(
resolve
,
reject
)
=>
{
Metalsmith
(
__dirname
)
.
metadata
(
{
site
:
{
title
:
"Qooxdoo Application Server"
,
description
:
"Mini website used by \"qx serve\""
,
email
:
"info@qooxdoo.org"
,
twitter_username
:
"qooxdoo"
,
github_username
:
"qooxdoo"
,
pages
:
[
"/"
,
"/about/"
]
}
,
baseurl
:
""
,
url
:
""
,
lang
:
"en"
,
partials
:
{
}
}
)
.
source
(
'./src'
)
.
destination
(
'./build'
)
.
clean
(
true
)
.
use
(
loadPartials
)
.
use
(
markdown
(
)
)
.
use
(
getPages
)
.
use
(
layouts
(
{
engine
:
'dot'
}
)
)
.
build
(
function
(
err
)
{
if
(
err
)
reject
(
err
)
;
else
resolve
(
)
;
}
)
;
}
)
;
}

Generates the site with Metalsmith

@returns {Promise}


function compileScss() {
  return new Promise((resolve, reject) => {
      sass.render({
        file: "sass/qooxdoo.scss",
        outFile: "build/qooxdoo.css"
      }, function(err, result) {
        if (err)
          reject(err);
        else
          resolve(result);
      });
    })
    .then(result => fs.writeFileAsync("build/qooxdoo.css", result.css, "utf8"));
}

function compileScss ( ) { return new Promise ( ( resolve , reject ) => { sass . render ( { file : "sass/qooxdoo.scss" , outFile : "build/qooxdoo.css" } , function ( err , result ) { if ( err ) reject ( err ) ; else resolve ( result ) ; } ) ; } ) . then ( result => fs . writeFileAsync ( "build/qooxdoo.css" , result . css , "utf8" ) ) ; }

Compiles SCSS into CSS

@returns {Promise}


function() {
      return {
        command: "list [repository]",
        describe:
          "if no repository name is given, lists all available contribs that are compatible with the project's qooxdoo version (\"--all\" lists incompatible ones as well). Otherwise, list all compatible contrib libraries.",
        builder: {
          all: {
            alias: "a",
            describe: "Show all versions, including incompatible ones"
          },
          verbose: {
            alias: "v",
            describe: "Verbose logging"
          },
          quiet: {
            alias: "q",
            describe: "No output"
          },
          json: {
            alias: "j",
            describe: "Output list as JSON literal"
          },
          installed: {
            alias: "i",
            describe: "Show only installed libraries"
          },
          namespace: {
            alias: "n",
            describe: "Display library namespace"
          },
          match: {
            alias: "m",
            describe: "Filter by regular expression (case-insensitive)"
          },
          "libraries": {
            alias: "l",
            describe: "List libraries only (no repositories)"
          },
          "short": {
            alias: "s",
            describe: "Omit title and description to make list more compact"
          },
          "noheaders": {
            alias: "H",
            describe: "Omit header and footer"
          }

        },
        handler: function(argv) {
          return new qx.tool.cli.commands.contrib.List(argv)
            .process()
            .catch(e => {
              console.error(e.stack || e.message);
              process.exit(1);
            });
        }
      };
    }

Returns the yargs command data
@return {Object}


async function() {
      if (!this.__mtime) {
        return this.read();
      }
      var poFile = this.getPoFilename();
      let stat = await qx.tool.compiler.files.Utils.safeStat(poFile);
      if (stat && this.__mtime == stat.mtime) {
        return undefined;
      }
      return this.read();
    }

async function ( ) { if ( ! this . __mtime ) { return this . read ( ) ; } var poFile = this . getPoFilename ( ) ; let stat = await qx . tool . compiler . files . Utils . safeStat ( poFile ) ; if ( stat && this . __mtime == stat . mtime ) { return undefined ; } return this . read ( ) ; }

Reads the .po file, but only if it has not been loaded or has changed

@returns {Promise}|

Reads the . po file but only if it has not been loaded or has changed


function(filename, cb) {
      var t = this;
      var lines = [];

      function write(key, value) {
        if (value === undefined || value === null) {
          return;
        }
        value = value.replace(/\t/g, "\\t").replace(/\r/g, "\\r")
          .replace(/\n/g, "\\n")
          .replace(/"/g, "\\\"");
        lines.push(key + " \"" + value + "\"");
      }

      for (var msgid in t.__translations) {
        var entry = t.__translations[msgid];
        if (entry.comments) {
          if (entry.comments.translator) {
            lines.push("# " + entry.comments.translator);
          }
          if (entry.comments.extracted) {
            lines.push("#. " + entry.comments.extracted);
          }
          if (entry.comments.reference) {
            let refStr = "#:";
            const ref = entry.comments.reference;
            for (let classname in ref) {
              if (ref[classname]) {
                for (let lineNo of ref[classname]) {
                  const addStr = " " + classname + ":" + lineNo;
                  if (refStr.length + addStr.length > 78) { // 78 is default length in python po library
                    // line break
                    lines.push(refStr);
                    refStr = "#:" + addStr;
                  } else {
                    refStr += addStr;
                  }
                }
              }
            }
            if (refStr.length > 3) { // write remaining refStr
              lines.push(refStr);
            }
          }
          if (entry.comments.flags) {
            lines.push("#, " + entry.comments.flags.join(","));
          }
        } else {
          lines.push("#");
        }
        if (entry.msgctxt) {
          lines.push("msgctxt \"" + entry.msgctxt + "\"");
        }
        write("msgid", entry.msgid);
        write("msgid_plural", entry.msgid_plural);
        if (qx.lang.Type.isArray(entry.msgstr)) {
          entry.msgstr.forEach(function(value, index) {
            write("msgstr[" + index + "]", value);
          });
        } else if (entry.msgid_plural) {
          write("msgstr[0]", "");
          write("msgstr[1]", "");
        } else {
          write("msgstr", entry.msgstr || "");
        }
        lines.push("");
      }
      var data = lines.join("\n");
      return qx.tool.compiler.utils.Promisify.fs.writeFileAsync(filename, data, { encoding: "utf8" });
    }

Writes the .po file to a specific filename
@param filename {String}

Writes the . po file to a specific filename


function(id) {
      var t = this;
      var entry = t.__translations[id];
      if (!entry) {
        entry = t.__translations[id] = {
          msgid: id
        };
      }
      return entry;
    }

function ( id ) { var t = this ; var entry = t . __translations [ id ] ; if ( ! entry ) { entry = t . __translations [ id ] = { msgid : id } ; } return entry ; }

Returns the entry with the given msgid, creating it if it does not exist
@param id
@returns {*|null}

Returns the entry with the given msgid creating it if it does not exist


async function() {
      let {libraries} = await this.getProjectData();
      if (libraries instanceof Array && libraries.length) {
        return path.resolve(process.cwd(), libraries[0].path);
      }
      throw new qx.tool.cli.Utils.UserError("Cannot find library path - are you in the right directory?");
    }

Returns the path to the current library. If the current directory contains several libraries,
the first one found is returned.
@throws {Error} Throws an error if no library can be found.
@return {Promise(String)} A promise that resolves with the absolute path to the library

Returns the path to the current library . If the current directory contains several libraries the first one found is returned .


async function() {
      let {applications} = await this.getProjectData();
      if (applications instanceof Array && applications.length) {
        return path.resolve(process.cwd(), applications[0].path);
      }
      throw new qx.tool.cli.Utils.UserError("Cannot find application path - are you in the right directory?");
    }

Returns the path to the current application, depending on the current
working directory. If a directory contains several applications, the first one found is
returned.
@throws {Error} Throws an error if no application can be found.
@return {Promise(String)} A promise that resolves with the absolute path to the application

Returns the path to the current application depending on the current working directory . If a directory contains several applications the first one found is returned .


async function(filePath) {
      var data = await fs.readFileAsync(filePath, "utf8");
      try {
        let compileAst = JsonToAst.parseToAst(data, {verbose: true});
        let compileJson = JsonToAst.astToObject(compileAst);
        return compileJson;
      } catch (e) {
        throw new qx.tool.cli.Utils.UserError(`Cannot parse ${filePath}:` + e.message);
      }
    }

async function ( filePath ) { var data = await fs . readFileAsync ( filePath , "utf8" ) ; try { let compileAst = JsonToAst . parseToAst ( data , { verbose : true } ) ; let compileJson = JsonToAst . astToObject ( compileAst ) ; return compileJson ; } catch ( e ) { throw new qx . tool . cli . Utils . UserError ( ` ${ filePath } ` + e . message ) ; } }

Return the content of a json file in the library as an object.
@param {String} filePath absolute path to the file
@throws {Error} Throws if file cannot be parsed.
@return {Promise(Object)}

Return the content of a json file in the library as an object .


async function() {
      let compileJsonPath = null;
      try {
        path.join(await this.getApplicationPath(), "compile.json");
      } catch (ex) {
        // Nothing - cannot find compile.json
      }
      if (compileJsonPath && await fs.existsAsync(compileJsonPath)) {
        let compileConfig = await this.parseCompileConfig();
        let qxpath = false;
        let appPath = await this.getApplicationPath();
        if (compileConfig.libraries) {
          for (let somepath of compileConfig.libraries) {
            let manifestPath = somepath;
            if (!path.isAbsolute(somepath)) {
              manifestPath = path.join(appPath, manifestPath);
            }
            manifestPath = path.join(manifestPath, "Manifest.json");
            let manifest = await this.parseJsonFile(manifestPath);
            try {
              if (manifest.provides.namespace === "qx") {
                qxpath = path.dirname(manifestPath);
                return qxpath;
              }
            } catch (e) {
              console.warn(`Invalid manifest file ${manifestPath}.`);
            }
          }
        }
      }
      return this.getGlobalQxPath();
    }

async
function
(
)
{
let
compileJsonPath
=
;
try
{
path
.
join
(
await
this
.
getApplicationPath
(
)
,
"compile.json"
)
;
}
catch
(
ex
)
{
// Nothing - cannot find compile.json
}
if
(
compileJsonPath
&&
await
fs
.
existsAsync
(
compileJsonPath
)
)
{
let
compileConfig
=
await
this
.
parseCompileConfig
(
)
;
let
qxpath
=
false
;
let
appPath
=
await
this
.
getApplicationPath
(
)
;
if
(
compileConfig
.
libraries
)
{
for
(
let
somepath
of
compileConfig
.
libraries
)
{
let
manifestPath
=
somepath
;
if
(
!
path
.
isAbsolute
(
somepath
)
)
{
manifestPath
=
path
.
join
(
appPath
,
manifestPath
)
;
}
manifestPath
=
path
.
join
(
manifestPath
,
"Manifest.json"
)
;
let
manifest
=
await
this
.
parseJsonFile
(
manifestPath
)
;
try
{
if
(
manifest
.
provides
.
namespace
===
"qx"
)
{
qxpath
=
path
.
dirname
(
manifestPath
)
;
return
qxpath
;
}
}
catch
(
e
)
{
console
.
warn
(
`
${
manifestPath
}
`
)
;
}
}
}
}
return
this
.
getGlobalQxPath
(
)
;
}

Returns the absolute path to the qooxdoo framework used by the current project
@return {Promise(String)} Promise that resolves with the path {String}


async function() {
      let qxpath = await this.getAppQxPath();
      return path.isAbsolute(qxpath) ? qxpath : path.resolve(qxpath);
    }

async function ( ) { let qxpath = await this . getAppQxPath ( ) ; return path . isAbsolute ( qxpath ) ? qxpath : path . resolve ( qxpath ) ; }

Returns the absolute path to the qooxdoo framework used by the current project, unless
the user provided a CLI option "qxpath", in which case this value is returned.
@return {Promise(String)} Promise that resolves with the absolute path

Returns the absolute path to the qooxdoo framework used by the current project unless the user provided a CLI option qxpath in which case this value is returned .


async function(libPath) {
      let manifestPath = path.join(libPath, "Manifest.json");
      let manifest = await this.parseJsonFile(manifestPath);
      let version;
      try {
        version = manifest.info.version;
      } catch (e) {
        throw new qx.tool.cli.Utils.UserError(`No valid version data in manifest.`);
      }
      if (!semver.valid(version)) {
        throw new qx.tool.cli.Utils.UserError(`Manifest at ${manifestPath} contains invalid version number "${version}". Please use a semver compatible version.`);
      }
      return version;
    }

async function ( libPath ) { let manifestPath = path . join ( libPath , "Manifest.json" ) ; let manifest = await this . parseJsonFile ( manifestPath ) ; let version ; try { version = manifest . info . version ; } catch ( e ) { throw new qx . tool . cli . Utils . UserError ( ` ` ) ; } if ( ! semver . valid ( version ) ) { throw new qx . tool . cli . Utils . UserError ( ` ${ manifestPath } ${ version } ` ) ; } return version ; }

Given the path to a library folder, returns the library version from its manifest
@param {String} libPath
@return {String} Version

Given the path to a library folder returns the library version from its manifest


function(cmd, args) {
      let opts = {env: process.env};
      return new Promise((resolve, reject) => {
        let exe = child_process.spawn(cmd, args, opts);
        // suppress all output unless in verbose mode
        exe.stdout.on("data", data => {
          if (this.argv.verbose) {
            console.log(data.toString());
          }
        });
        exe.stderr.on("data", data => {
          if (this.argv.verbose) {
            console.error(data.toString());
          }
        });
        exe.on("close", code => {
          if (code !== 0) {
            let message = `Error executing ${cmd.join(" ")}. Use --verbose to see what went wrong.`;
            throw new qx.tool.cli.Utils.UserError(message);
          } else {
            resolve(0);
          }
        });
        exe.on("error", reject);
      });
    }

Awaitable wrapper around child_process.spawn.
Runs a command in a separate process. The output of the command
is ignored. Throws when the exit code is not 0.
@param  {String} cmd Name of the command
@param  {Array} args Array of arguments to the command
@return {Promise} A promise that resolves with the exit code

Awaitable wrapper around child_process . spawn . Runs a command in a separate process . The output of the command is ignored . Throws when the exit code is not 0 .


function(cmd) {
      return new Promise((resolve, reject) => {
        child_process.exec(cmd, (err, stdout, stderr) => {
          if (err) {
            reject(err);
          }
          if (stderr) {
            reject(new Error(stderr));
          }
          resolve(stdout);
        });
      });
    }

function ( cmd ) { return new Promise ( ( resolve , reject ) => { child_process . exec ( cmd , ( err , stdout , stderr ) => { if ( err ) { reject ( err ) ; } if ( stderr ) { reject ( new Error ( stderr ) ) ; } resolve ( stdout ) ; } ) ; } ) ; }

Awaitable wrapper around child_process.exec
Executes a command and return its result wrapped in a Promise.
@param cmd {String} Command with all parameters
@return {Promise} Promise that resolves with the result

Awaitable wrapper around child_process . exec Executes a command and return its result wrapped in a Promise .


function(yargs, classNames, packageName) {
      let pkg = null;
      packageName.split(".").forEach(seg => {
        if (pkg === null) {
          pkg = window[seg];
        } else {
          pkg = pkg[seg];
        }
      });
      classNames.forEach(cmd => {
        require("../../../" + packageName.replace(/\./g, "/") + "/" + cmd);
        let data = pkg[cmd].getYargsCommand();
        yargs.command(data);
      });
    }

function ( yargs , classNames , packageName ) { let pkg = null ; packageName . split ( "." ) . forEach ( seg => { if ( pkg === null ) { pkg = window [ seg ] ; } else { pkg = pkg [ seg ] ; } } ) ; classNames . forEach ( cmd => { require ( "../../../" + packageName . replace ( / \. / g , "/" ) + "/" + cmd ) ; let data = pkg [ cmd ] . getYargsCommand ( ) ; yargs . command ( data ) ; } ) ; }

Adds commands to Yargs

@param yargs {yargs} the Yargs instance
@param classNames {String[]} array of class names, each of which is in the `packageName` package
@param packageName {String} the name of the package to find each command class


function(msgId, ...args) {
      for (var i = 0; i < args.length; i++) {
        var arg = args[i];
        if (typeof arg !== "string" && typeof arg !== "number" && arg !== null) {
          args[i] = String(arg);
        }
      }
      if (this.isMachineReadable()) {
        let str = "##" + msgId + ":" + JSON.stringify(args);
        console.log(str);
      } else {
        var writer = this.getWriter();
        let str = this.decode(msgId, ...args);
        if (writer) {
          writer(str, msgId, ...args);
        } else {
          console.log(str);
        }
      }
    }

function ( msgId , ... args ) { for ( var i = 0 ; i < args . length ; i ++ ) { var arg = args [ i ] ; if ( typeof arg !== "string" && typeof arg !== "number" && arg !== null ) { args [ i ] = String ( arg ) ; } } if ( this . isMachineReadable ( ) ) { let str = "##" + msgId + ":" + JSON . stringify ( args ) ; console . log ( str ) ; } else { var writer = this . getWriter ( ) ; let str = this . decode ( msgId , ... args ) ; if ( writer ) { writer ( str , msgId , ... args ) ; } else { console . log ( str ) ; } } }

Prints the message

@param msgId {String} translatable message ID
@param args {Object...} arguments


function(msgId, ...args) {
      var msg = qx.tool.compiler.Console.MESSAGE_IDS[msgId]||msgId;
      var str = qx.lang.String.format(msg.message, args||[]);
      return str;
    }

function ( msgId , ... args ) { var msg = qx . tool . compiler . Console . MESSAGE_IDS [ msgId ] || msgId ; var str = qx . lang . String . format ( msg . message , args || [ ] ) ; return str ; }

Decodes the message ID and arguments into a string to be presented in the output

@param msgId {String} translatable message ID
@param args {Object...} arguments
@return {String} complete message


function(marker, showPosition) {
      var msg = qx.tool.compiler.Console.MESSAGE_IDS[marker.msgId]||marker.msgId;
      var str = "";
      var pos = marker.pos;
      if (showPosition !== false && pos && pos.start && pos.start.line) {
        str += "[" + pos.start.line;
        if (pos.start.column) {
          str += "," + pos.start.column;
        }
        if (pos.end && pos.end.line &&
            pos.end.line !== pos.start.line &&
            pos.end.column !== pos.start.column) {
          str += " to " + pos.end.line;
          if (pos.end.column) {
            str += "," + pos.end.column;
          }
        }
        str += "] ";
      }
      str += qx.lang.String.format(msg.message, marker.args||[]);
      return str;
    }

function
(
marker
,
showPosition
)
{
var
msg
=
qx
.
tool
.
compiler
.
Console
.
MESSAGE_IDS
[
marker
.
msgId
]
||
marker
.
msgId
;
var
str
=
""
;
var
pos
=
marker
.
pos
;
if
(
showPosition
!==
false
&&
pos
&&
pos
.
start
&&
pos
.
start
.
line
)
{
str
+=
"["
+
pos
.
start
.
line
;
if
(
pos
.
start
.
column
)
{
str
+=
","
+
pos
.
start
.
column
;
}
if
(
pos
.
end
&&
pos
.
end
.
line
&&
pos
.
end
.
line
!==
pos
.
start
.
line
&&
pos
.
end
.
column
!==
pos
.
start
.
column
)
{
str
+=
" to "
+
pos
.
end
.
line
;
if
(
pos
.
end
.
column
)
{
str
+=
","
+
pos
.
end
.
column
;
}
}
str
+=
"] "
;
}
str
+=
qx
.
lang
.
String
.
format
(
msg
.
message
,
marker
.
args
||
[
]
)
;
return
str
;
}

Decodes a marker into a String description
@param marker {Map} containing:
msgId {String}
start {Map} containing:
line {Integer}
column? {Integer}
end? {Map} containing:
line {Integer}
column? {Integer}
args? {Object[]}
@param showPosition {Boolean?} whether to include line/column info (default is true)
@return {String}


async function() {
      let apps = [];
      let argv = this.argv;
      let result = {
        target: argv.target,
        outputPath: argv.outputPath||null,
        locales: null,
        writeAllTranslations: argv.writeAllTranslations,
        environment: {},
        applications: apps,
        libraries: argv.library||[],
        config: argv.configFile||"compile.json",
        continuous: argv.continuous,
        verbose: argv.verbose
      };
      if (argv.set) {
        argv.set.forEach(function(kv) {
          var m = kv.match(/^([^=\s]+)(=(.+))?$/);
          if (m) {
            var key = m[1];
            var value = m[3];
            try {
              result.environment[key] = Function("\"use strict\";return (" + value + ")")();
            } catch (error) {
              throw new Error("Failed to translate environment value '"+value+"' to a js datatype - "+error);
            }
          } else {
            throw new Error("Failed to parse environment setting commandline option '"+kv+"'");
          }
        });
      }

      if (argv.locale && argv.locale.length) {
        result.locales = argv.locale;
      }
      return result;
    }

Parses the command line, and produces a normalised configuration;

@return {Object}

Parses the command line and produces a normalised configuration ;


function() {
      return {
        command: "migrate [options]",
        desc: "migrates a qooxdoo application to the next major version",
        usage: "migrate",
        builder: {
          "verbose": {
            alias : "v",
            describe: "enables additional progress output to console",
            type: "boolean"
          }
        },
        handler: function(argv) {
          return new qx.tool.cli.commands.Migrate(argv)
            .process()
            .catch(e => {
              console.error(e.stack || e.message);
              process.exit(1);
            });
        }
      };
    }


function(type) {
      if (!type) {
        return null;
      }
      if (type.$$type == "Class") {
        return type;
      }
      if (type == "build") {
        return qx.tool.compiler.targets.BuildTarget;
      }
      if (type == "source") {
        return qx.tool.compiler.targets.SourceTarget;
      }
      if (type == "typescript") {
        throw new qx.tool.cli.Utils.UserError("Typescript targets are no longer supported - please use `typescript: true` in source target instead");
      }
      if (type) {
        var targetClass;
        if (type.indexOf(".") < 0) {
          targetClass = qx.Class.getByName("qx.tool.compiler.targets." + type);
        } else {
          targetClass = qx.Class.getByName(type);
        }
        return targetClass;
      }
      return null;
    }

Resolves the target class instance from the type name; accepts "source" or "build" or
a class name
@param type {String}
@returns {Maker}

Resolves the target class instance from the type name ; accepts source or build or a class name


function(callback) {
      var t = this;
      async.waterfall([
        function readDb(callback) {
          fs.exists(t.__dbFilename, function(exists) {
            if (exists) {
              fs.readFile(t.__dbFilename, {
                encoding: "utf-8"
              }, callback);
            } else {
              callback(null, null);
            }
          });
        },

        function parseDb(data, callback) {
          t.__db = data && data.trim().length ? jsonlint.parse(data) : {};
          callback(null, t.__db);
        }
      ], callback);
    }

function ( callback ) { var t = this ; async . waterfall ( [ function readDb ( callback ) { fs . exists ( t . __dbFilename , function ( exists ) { if ( exists ) { fs . readFile ( t . __dbFilename , { encoding : "utf-8" } , callback ) ; } else { callback ( null , null ) ; } } ) ; } , function parseDb ( data , callback ) { t . __db = data && data . trim ( ) . length ? jsonlint . parse ( data ) : { } ; callback ( null , t . __db ) ; } ] , callback ) ; }

Loads the cached database

@param callback


function scanDir(rootDir, dir, resource, doNotCopy, callback) {
            // Get the list of files
            fs.readdir(dir, function(err, files) {
              if (err) {
                callback(err);
                return;
              }

              // and process each one
              async.forEach(files,
                function(file, callback) {
                  var absFile = path.join(dir, file);
                  fs.stat(absFile, function(err, stat) {
                    if (err) {
                      callback(err);
                      return;
                    }

                    // Directory? recurse
                    if (stat.isDirectory()) {
                      scanDir(rootDir, absFile, resource, doNotCopy, callback);
                    } else {
                      var relFile = absFile.substring(rootDir.length + 1).replace(/\\/g, "/");
                      var fileInfo = resources[relFile];
                      delete unconfirmed[relFile];
                      if (!fileInfo) {
                        fileInfo = resources[relFile] = {};
                      }
                      fileInfo.doNotCopy = doNotCopy;
                      fileInfo.resource = resource;
                      t.__librariesByResourceUri[relFile] = library;
                      var relDir = dir.substring(rootDir.length + 1).replace(/\\/g, "/");
                      t.__librariesByResourceFolderUri[relDir] = library;
                      var tmp = "";
                      relDir.split("/").forEach(seg => {
                        if (tmp.length) {
                          tmp += "/";
                        }
                        tmp += seg;
                        t.__librariesByResourceFolderUri[tmp] = library;
                      });

                      var handlers = t.__handlers.filter(handler => handler.matches(absFile));
                      if (!handlers.length) {
                        callback();
                        return;
                      }

                      if (handlers.some(handler => handler.needsCompile(absFile, fileInfo, stat))) {
                        fileInfo.mtime = stat.mtime;
                        tasks.push({
                          fileInfo: fileInfo,
                          absFile: absFile,
                          library: library,
                          handlers: handlers
                        });
                      }
                      callback();
                    }
                  });
                },
                callback);
            });
          }

function
scanDir
(
rootDir
,
dir
,
resource
,
doNotCopy
,
callback
)
{
// Get the list of files
fs
.
readdir
(
dir
,
function
(
err
,
files
)
{
if
(
err
)
{
callback
(
err
)
;
return
;
}
// and process each one
async
.
forEach
(
files
,
function
(
file
,
callback
)
{
var
absFile
=
path
.
join
(
dir
,
file
)
;
fs
.
stat
(
absFile
,
function
(
err
,
stat
)
{
if
(
err
)
{
callback
(
err
)
;
return
;
}
// Directory? recurse
if
(
stat
.
isDirectory
(
)
)
{
scanDir
(
rootDir
,
absFile
,
resource
,
doNotCopy
,
callback
)
;
}
else
{
var
relFile
=
absFile
.
substring
(
rootDir
.
length
+
1
)
.
replace
(
/
\\
/
g
,
"/"
)
;
var
fileInfo
=
resources
[
relFile
]
;
delete
unconfirmed
[
relFile
]
;
if
(
!
fileInfo
)
{
fileInfo
=
resources
[
relFile
]
=
{
}
;
}
fileInfo
.
doNotCopy
=
doNotCopy
;
fileInfo
.
resource
=
resource
;
t
.
__librariesByResourceUri
[
relFile
]
=
library
;
var
relDir
=
dir
.
substring
(
rootDir
.
length
+
1
)
.
replace
(
/
\\
/
g
,
"/"
)
;
t
.
__librariesByResourceFolderUri
[
relDir
]
=
library
;
var
tmp
=
""
;
relDir
.
split
(
"/"
)
.
forEach
(
seg
=>
{
if
(
tmp
.
length
)
{
tmp
+=
"/"
;
}
tmp
+=
seg
;
t
.
__librariesByResourceFolderUri
[
tmp
]
=
library
;
}
)
;
var
handlers
=
t
.
__handlers
.
filter
(
handler
=>
handler
.
matches
(
absFile
)
)
;
if
(
!
handlers
.
length
)
{
callback
(
)
;
return
;
}
if
(
handlers
.
some
(
handler
=>
handler
.
needsCompile
(
absFile
,
fileInfo
,
stat
)
)
)
{
fileInfo
.
mtime
=
stat
.
mtime
;
tasks
.
push
(
{
fileInfo
:
fileInfo
,
absFile
:
absFile
,
library
:
library
,
handlers
:
handlers
}
)
;
}
callback
(
)
;
}
}
)
;
}
,
callback
)
;
}
)
;
}

Scans a folder, recursively, looking for resource files

Scans a folder recursively looking for resource files


function(srcPaths) {
      var t = this;
      var db = this.__db;

      // Generate a lookup that maps the resource name to the meta file that
      //  contains the composite
      var metas = {};
      for (var libraryName in db.resources) {
        var libraryData = db.resources[libraryName];
        for (var resourcePath in libraryData) {
          var fileInfo = libraryData[resourcePath];
          if (!fileInfo.meta) {
            continue;
          }
          for (var altPath in fileInfo.meta) {
            metas[altPath] = resourcePath;
          }
        }
      }

      // Collect a list of assets
      var assets = [];
      var assetPaths = {};

      function addAsset(library, resourceName) {
        if (assetPaths[resourceName] !== undefined) {
          return;
        }

        var libraryData = db.resources[library.getNamespace()];
        var fileInfo = libraryData[resourceName];
        if (fileInfo.doNotCopy === true) {
          return;
        }
        var asset = {
          libraryName: library.getNamespace(),
          filename: resourceName,
          fileInfo: fileInfo
        };

        // Does this have meta data for a composite?
        var metaPath = metas[resourceName];
        if (metaPath !== null) {
          var metaInfo = libraryData[metaPath];
          if (metaInfo) {
            // Extract the fragment from the meta data for this particular resource
            var resMetaData = metaInfo.meta[resourceName];
            fileInfo.composite = resMetaData[3];
            fileInfo.x = resMetaData[4];
            fileInfo.y = resMetaData[5];
            if (!assetPaths[metaPath]) {
              srcPaths.push(metaPath);
            }
          }
        }
        assets.push(asset);
        assetPaths[resourceName] = assets.length - 1;
      }

      for (var i = 0; i < srcPaths.length; i++) {
        var srcPath = srcPaths[i];
        var library = t.findLibraryForResource(srcPath);
        if (!library) {
          t.warn("Cannot find library for " + srcPath);
          continue;
        }

        var pos = srcPath.indexOf(":");
        if (pos > -1) {
          srcPath = srcPath.substring(pos + 1);
        }

        libraryData = db.resources[library.getNamespace()];
        pos = srcPath.indexOf("*");
        if (pos > -1) {
          srcPath = srcPath.substring(0, pos);
          for (var resourceName in libraryData) {
            if (resourceName.substring(0, srcPath.length) == srcPath) {
              addAsset(library, resourceName);
            }
          }
        } else {
          fileInfo = libraryData[srcPath];
          if (fileInfo && (fileInfo.doNotCopy !== true)) {
            addAsset(library, srcPath);
          }
        }
      }

      return assets;
    }

Collects information about the assets listed in srcPaths;
@param srcPaths

Collects information about the assets listed in srcPaths ;


async function(data) {
      let t = this;
      let result = {};
      return new Promise((resolve, reject) => {
        async.forEach(data.libraries,
          function(path, cb) {
            t.__addLibrary(path, result, cb);
          },
          function(err) {
            if (err) {
              reject(err);
            } else {
              resolve(result);
            }
          });
      });
    }

async function ( data ) { let t = this ; let result = { } ; return new Promise ( ( resolve , reject ) => { async . forEach ( data . libraries , function ( path , cb ) { t . __addLibrary ( path , result , cb ) ; } , function ( err ) { if ( err ) { reject ( err ) ; } else { resolve ( result ) ; } } ) ; } ) ; }

Scan all libraries and add the namespace to globals


function(rootDir, result, cb) {
      var lib = new qx.tool.compiler.app.Library();
      lib.loadManifest(rootDir, function(err) {
        if (!err) {
          let s = lib.getNamespace();
          let libs = s.split(".");
          result[libs[0]] = false;
        }
        return cb && cb(err, lib);
      });
    }

function ( rootDir , result , cb ) { var lib = new qx . tool . compiler . app . Library ( ) ; lib . loadManifest ( rootDir , function ( err ) { if ( ! err ) { let s = lib . getNamespace ( ) ; let libs = s . split ( "." ) ; result [ libs [ 0 ] ] = false ; } return cb && cb ( err , lib ) ; } ) ; }

Load library and add namespace to result


function(str) {
      if (str === null) {
        return null;
      }
      str = str.trim();
      if (!str) {
        return null;
      }
      var ast = JsonToAst.parseToAst(str);
      var json = JsonToAst.astToObject(ast);
      return json;
    }

function ( str ) { if ( str === null ) { return null ; } str = str . trim ( ) ; if ( ! str ) { return null ; } var ast = JsonToAst . parseToAst ( str ) ; var json = JsonToAst . astToObject ( ast ) ; return json ; }

Parses JSON string into an object

@param str {String} the data to parse
@return {Object}


async function(filename) {
      if (!await fs.existsAsync(filename)) {
        return null;
      }
      var data = await fs.readFileAsync(filename, "utf8");
      try {
        return qx.tool.compiler.utils.Json.parseJson(data);
      } catch (ex) {
        throw new Error("Failed to load " + filename + ": " + ex);
      }
    }

async
function
(
filename
)
{
if
(
!
await
fs
.
existsAsync
(
filename
)
)
{
return
;
}
var
data
=
await
fs
.
readFileAsync
(
filename
,
"utf8"
)
;
try
{
return
qx
.
tool
.
compiler
.
utils
.
Json
.
parseJson
(
data
)
;
}
catch
(
ex
)
{
throw
new
Error
(
"Failed to load "
+
filename
+
": "
+
ex
)
;
}
}

Loads JSON data from a file and returns it as an object; if the file does not exist, then
null is returned

@param filename {String} the filename to load
@return {Object?} the parsed contents, or null if the file does not exist

Loads JSON data from a file and returns it as an object ; if the file does not exist then null is returned


async function(filename, data) {
      if (!data) {
        if (await fs.existsAsync(filename)) {
          fs.unlinkAsync(filename);
        }
      } else {
        await fs.writeFileAsync(filename, JSON.stringify(data, null, 2), "utf8");
      }
    }

async function ( filename , data ) { if ( ! data ) { if ( await fs . existsAsync ( filename ) ) { fs . unlinkAsync ( filename ) ; } } else { await fs . writeFileAsync ( filename , JSON . stringify ( data , null , 2 ) , "utf8" ) ; } }

Saves JSON data to a file, or erases the file if data is null

@param filename {String} filename to write to
@param data {Object?} the data to write

Saves JSON data to a file or erases the file if data is null


function(from, to) {
      return new Promise((resolve, reject) => {
        util.mkParentPath(to, function() {
          var rs = fs.createReadStream(from, { flags: "r", encoding: "binary" });
          var ws = fs.createWriteStream(to, { flags: "w", encoding: "binary" });
          rs.on("end", function() {
            resolve();
          });
          rs.on("error", reject);
          ws.on("error", reject);
          rs.pipe(ws);
        });
      });
    }

function ( from , to ) { return new Promise ( ( resolve , reject ) => { util . mkParentPath ( to , function ( ) { var rs = fs . createReadStream ( from , { flags : "r" , encoding : "binary" } ) ; var ws = fs . createWriteStream ( to , { flags : "w" , encoding : "binary" } ) ; rs . on ( "end" , function ( ) { resolve ( ) ; } ) ; rs . on ( "error" , reject ) ; ws . on ( "error" , reject ) ; rs . pipe ( ws ) ; } ) ; } ) ; }

Copies a file
@param from {String} path to copy from
@param to {String} path to copy to
@param cb(err) {Function}
@async


function(filename) {
      return new Promise((resolve, reject) => {
        fs.stat(filename, function(err, stats) {
          if (err && err.code != "ENOENT") {
            reject(err);
          } else {
            resolve(err ? null : stats);
          }
        });
      });
    }

function ( filename ) { return new Promise ( ( resolve , reject ) => { fs . stat ( filename , function ( err , stats ) { if ( err && err . code != "ENOENT" ) { reject ( err ) ; } else { resolve ( err ? null : stats ) ; } } ) ; } ) ; }

Returns the stats for a file, or null if the file does not exist

@param filename
@returns {fs.Stat}
@async

Returns the stats for a file or null if the file does not exist


function(filename) {
      return new Promise((resolve, reject) => {
        fs.unlink(filename, function(err) {
          if (err && err.code != "ENOENT") {
            reject(err);
          } else {
            resolve();
          }
        });
      });
    }

function ( filename ) { return new Promise ( ( resolve , reject ) => { fs . unlink ( filename , function ( err ) { if ( err && err . code != "ENOENT" ) { reject ( err ) ; } else { resolve ( ) ; } } ) ; } ) ; }

Deletes a file, does nothing if the file does not exist

@param filename {String} file to delete
@async

Deletes a file does nothing if the file does not exist


async function(filename, length) {
      if (await this.safeStat(filename) && length > 1) {
        var lastFile = null;
        for (var i = length; i > 0; i--) {
          var tmp = filename + "." + i;
          if (i == length) {
            await this.safeUnlink(tmp);
          } else if (await this.safeStat(tmp)) {
            await rename(tmp, lastFile);
          }
          lastFile = tmp;
        }
        await rename(filename, lastFile);
      }
    }

async function ( filename , length ) { if ( await this . safeStat ( filename ) && length > 1 ) { var lastFile = null ; for ( var i = length ; i > 0 ; i -- ) { var tmp = filename + "." + i ; if ( i == length ) { await this . safeUnlink ( tmp ) ; } else if ( await this . safeStat ( tmp ) ) { await rename ( tmp , lastFile ) ; } lastFile = tmp ; } await rename ( filename , lastFile ) ; } }

Rotates files so that this file does not exist, by renaming the existing file to have a ".1"
appended, and the ".1" to be renamed to ".2" etc, up to `length` versions

@param filename {String} filename to rotate
@param length {Integer} maximum number of files
@async

Rotates files so that this file does not exist by renaming the existing file to have a . 1 appended and the . 1 to be renamed to . 2 etc up to length versions


function(name) {
      return new Promise((resolve, reject) => {
        rimraf(name, err => {
          if (err) {
            reject(err);
          } else {
            resolve();
          }
        });
      });
    }

function ( name ) { return new Promise ( ( resolve , reject ) => { rimraf ( name , err => { if ( err ) { reject ( err ) ; } else { resolve ( ) ; } } ) ; } ) ; }

Deletes a file or directory; directories are recursively removed
@param name {String} file or dir to delete
@async

Deletes a file or directory ; directories are recursively removed


function(dir) {
      var drivePrefix = "";
      if (process.platform === "win32" && dir.match(/^[a-zA-Z]:/)) {
        drivePrefix = dir.substring(0, 2);
        dir = dir.substring(2);
      }
      dir = dir.replace(/\\/g, "/");
      var segs = dir.split("/");
      if (!segs.length) {
        return drivePrefix + dir;
      }

      var currentDir;
      var index;
      if (segs[0].length) {
        currentDir = "";
        index = 0;
      } else {
        currentDir = "/";
        index = 1;
      }

      function bumpToNext(nextSeg) {
        index++;
        if (currentDir.length && currentDir !== "/") {
          currentDir += "/";
        }
        currentDir += nextSeg;
        return next();
      }

      function next() {
        if (index == segs.length) {
          if (process.platform === "win32") {
            currentDir = currentDir.replace(/\//g, "\\");
          }
          return Promise.resolve(drivePrefix + currentDir);
        }

        let nextSeg = segs[index];
        if (nextSeg == "." || nextSeg == "..") {
          return bumpToNext(nextSeg);
        }

        return new Promise((resolve, reject) => {
          fs.readdir(currentDir.length == 0 ? "." : drivePrefix + currentDir, { encoding: "utf8" }, (err, files) => {
            if (err) {
              reject(err);
              return;
            }

            let nextLowerCase = nextSeg.toLowerCase();
            let exact = false;
            let insensitive = null;
            for (let i = 0; i < files.length; i++) {
              if (files[i] === nextSeg) {
                exact = true;
                break;
              }
              if (files[i].toLowerCase() === nextLowerCase) {
                insensitive = files[i];
              }
            }
            if (!exact && insensitive) {
              nextSeg = insensitive;
            }

            bumpToNext(nextSeg).then(resolve);
          });
        });
      }

      return new Promise((resolve, reject) => {
        fs.stat(drivePrefix + dir, err => {
          if (err) {
            if (err.code == "ENOENT") {
              resolve(drivePrefix + dir);
            } else {
              reject(err);
            }
          } else {
            next().then(resolve);
          }
        });
      });
    }

function ( dir ) { var drivePrefix = "" ; if ( process . platform === "win32" && dir . match ( / ^[a-zA-Z]: / ) ) { drivePrefix = dir . substring ( 0 , 2 ) ; dir = dir . substring ( 2 ) ; } dir = dir . replace ( / \\ / g , "/" ) ; var segs = dir . split ( "/" ) ; if ( ! segs . length ) { return drivePrefix + dir ; } var currentDir ; var index ; if ( segs [ 0 ] . length ) { currentDir = "" ; index = 0 ; } else { currentDir = "/" ; index = 1 ; } function bumpToNext ( nextSeg ) { index ++ ; if ( currentDir . length && currentDir !== "/" ) { currentDir += "/" ; } currentDir += nextSeg ; return next ( ) ; } function next ( ) { if ( index == segs . length ) { if ( process . platform === "win32" ) { currentDir = currentDir . replace ( / \/ / g , "\\" ) ; } return Promise . resolve ( drivePrefix + currentDir ) ; } let nextSeg = segs [ index ] ; if ( nextSeg == "." || nextSeg == ".." ) { return bumpToNext ( nextSeg ) ; } return new Promise ( ( resolve , reject ) => { fs . readdir ( currentDir . length == 0 ? "." : drivePrefix + currentDir , { encoding : "utf8" } , ( err , files ) => { if ( err ) { reject ( err ) ; return ; } let nextLowerCase = nextSeg . toLowerCase ( ) ; let exact = false ; let insensitive = null ; for ( let i = 0 ; i < files . length ; i ++ ) { if ( files [ i ] === nextSeg ) { exact = true ; break ; } if ( files [ i ] . toLowerCase ( ) === nextLowerCase ) { insensitive = files [ i ] ; } } if ( ! exact && insensitive ) { nextSeg = insensitive ; } bumpToNext ( nextSeg ) . then ( resolve ) ; } ) ; } ) ; } return new Promise ( ( resolve , reject ) => { fs . stat ( drivePrefix + dir , err => { if ( err ) { if ( err . code == "ENOENT" ) { resolve ( drivePrefix + dir ) ; } else { reject ( err ) ; } } else { next ( ) . then ( resolve ) ; } } ) ; } ) ; }

Normalises the path and corrects the case of the path to match what is actually on the filing system

@param fsPath {String} the filename to normalise
@returns {String} the new path
@async


function(args)
    {
      var opts;
      for (var i=0, l=args.length; i<l; i++) {
        if (args[i].indexOf("settings=") == 0) {
          opts = args[i].substr(9);
          break;
        }
        else if (args[i].indexOf("'settings=") == 0) {
          opts = /'settings\=(.*?)'/.exec(args[i])[1];
          break;
        }
      }
      if (opts) {
        opts = opts.replace(/\\\{/g, "{").replace(/\\\}/g, "}");
        opts = qx.lang.Json.parse(opts);
        for (var prop in opts) {
          var value = opts[prop];
          if (typeof value == "string") {
            value = value.replace(/\$$/g, " ");
          }
          try {
            qx.core.Environment.add(prop, value);
          } catch(ex) {
            this.error("Unable to define command-line setting " + prop + ": " + ex);
          }
        }
      }
    }

Converts the value of the "settings" command line option to qx settings.

@param args {String[]} Rhino arguments object

Converts the value of the settings command line option to qx settings .


function ScaleColumns(colsByGroup, maxWidth, totalFlexGrow) {
  // calculate total width and flexgrow points for coulumns that can be resized
  angular.forEach(colsByGroup, (cols) => {
    cols.forEach((column) => {
      if (!column.canAutoResize){
        maxWidth -= column.width;
        totalFlexGrow -= column.flexGrow;
      } else {
        column.width = 0;
      }
    });
  });

  var hasMinWidth = {}
  var remainingWidth = maxWidth;

  // resize columns until no width is left to be distributed
  do {
    let widthPerFlexPoint = remainingWidth / totalFlexGrow;
    remainingWidth = 0;
    angular.forEach(colsByGroup, (cols) => {
      cols.forEach((column, i) => {
        // if the column can be resize and it hasn't reached its minimum width yet
        if (column.canAutoResize && !hasMinWidth[i]){
          let newWidth = column.width  + column.flexGrow * widthPerFlexPoint;
          if (column.minWidth !== undefined && newWidth < column.minWidth){
            remainingWidth += newWidth - column.minWidth;
            column.width = column.minWidth;
            hasMinWidth[i] = true;
          } else {
            column.width = newWidth;
          }
        }
      });
    });
  } while (remainingWidth !== 0);

}

Resizes columns based on the flexGrow property, while respecting manually set widths
@param {array} colsByGroup
@param {int} maxWidth
@param {int} totalFlexGrow

Resizes columns based on the flexGrow property while respecting manually set widths


function GetTotalFlexGrow(columns){
  var totalFlexGrow = 0;

  for (let c of columns) {
    totalFlexGrow += c.flexGrow || 0;
  }

  return totalFlexGrow;
}

function GetTotalFlexGrow ( columns ) { var totalFlexGrow = 0 ; for ( let c of columns ) { totalFlexGrow += c . flexGrow || 0 ; } return totalFlexGrow ; }

Calculates the Total Flex Grow
@param {array}


function ForceFillColumnWidths(allColumns, expectedWidth, startIdx){
  var contentWidth = 0,
      columnsToResize = startIdx > -1 ?
        allColumns.slice(startIdx, allColumns.length).filter((c) => { return c.canAutoResize }) :
        allColumns.filter((c) => { return c.canAutoResize });

  allColumns.forEach((c) => {
    if(!c.canAutoResize){
      contentWidth += c.width;
    } else {
      contentWidth += (c.$$oldWidth || c.width);
    }
  });

  var remainingWidth = expectedWidth - contentWidth,
      additionWidthPerColumn = remainingWidth / columnsToResize.length,
      exceedsWindow = contentWidth > expectedWidth;

  columnsToResize.forEach((column) => {
    if(exceedsWindow){
      column.width = column.$$oldWidth || column.width;
    } else {
      if(!column.$$oldWidth){
        column.$$oldWidth = column.width;
      }

      var newSize = column.$$oldWidth + additionWidthPerColumn;
      if(column.minWith && newSize < column.minWidth){
        column.width = column.minWidth;
      } else if(column.maxWidth && newSize > column.maxWidth){
        column.width = column.maxWidth;
      } else {
        column.width = newSize;
      }
    }
  });
}

function ForceFillColumnWidths ( allColumns , expectedWidth , startIdx ) { var contentWidth = 0 , columnsToResize = startIdx > - 1 ? allColumns . slice ( startIdx , allColumns . length ) . filter ( ( c ) => { return c . canAutoResize } ) : allColumns . filter ( ( c ) => { return c . canAutoResize } ) ; allColumns . forEach ( ( c ) => { if ( ! c . canAutoResize ) { contentWidth += c . width ; } else { contentWidth += ( c . $$oldWidth || c . width ) ; } } ) ; var remainingWidth = expectedWidth - contentWidth , additionWidthPerColumn = remainingWidth / columnsToResize . length , exceedsWindow = contentWidth > expectedWidth ; columnsToResize . forEach ( ( column ) => { if ( exceedsWindow ) { column . width = column . $$oldWidth || column . width ; } else { if ( ! column . $$oldWidth ) { column . $$oldWidth = column . width ; } var newSize = column . $$oldWidth + additionWidthPerColumn ; if ( column . minWith && newSize < column . minWidth ) { column . width = column . minWidth ; } else if ( column . maxWidth && newSize > column . maxWidth ) { column . width = column . maxWidth ; } else { column . width = newSize ; } } } ) ; }

Forces the width of the columns to
distribute equally but overflowing when nesc.

Rules:

- If combined withs are less than the total width of the grid,
proporation the widths given the min / max / noraml widths to fill the width.

- If the combined widths, exceed the total width of the grid,
use the standard widths.

- If a column is resized, it should always use that width

- The proporational widths should never fall below min size if specified.

- If the grid starts off small but then becomes greater than the size ( + / - )
the width should use the orginial width; not the newly proporatied widths.

@param {array} allColumns
@param {int} expectedWidth

Forces the width of the columns to distribute equally but overflowing when nesc .


function PDU() {
    this.type = asn1ber.pduTypes.GetRequestPDU;
    this.reqid = 1;
    this.error = 0;
    this.errorIndex = 0;
    this.varbinds = [ new VarBind() ];
}

function PDU ( ) { this . type = asn1ber . pduTypes . GetRequestPDU ; this . reqid = 1 ; this . error = 0 ; this . errorIndex = 0 ; this . varbinds = [ new VarBind ( ) ] ; }

The `PDU` contains the SNMP request or response fields and a list of `VarBinds`.

The PDU contains the SNMP request or response fields and a list of VarBinds .


function clearRequest(reqs, reqid) {
    var self = this;

    var entry = reqs[reqid];
    if (entry) {
        if (entry.timeout) {
            clearTimeout(entry.timeout);
        }
        delete reqs[reqid];
    }
}

function clearRequest ( reqs , reqid ) { var self = this ; var entry = reqs [ reqid ] ; if ( entry ) { if ( entry . timeout ) { clearTimeout ( entry . timeout ) ; } delete reqs [ reqid ] ; } }

Clear a pending packet when it times out or is successfully received.

Clear a pending packet when it times out or is successfully received .


function parseSingleOid(oid) {
    if (typeof oid !== 'string') {
        return oid;
    }

    if (oid[0] !== '.') {
        throw new Error('Invalid OID format');
    }

    oid = oid.split('.')
        .filter(function (s) {
            return s.length > 0;
        })
        .map(function (s) {
            return parseInt(s, 10);
        });

    return oid;
}

function
parseSingleOid
(
oid
)
{
if
(
typeof
oid
!==
'string'
)
{
return
oid
;
}
if
(
oid
[
0
]
!==
'.'
)
{
throw
new
Error
(
'Invalid OID format'
)
;
}
oid
=
oid
.
split
(
'.'
)
.
filter
(
function
(
s
)
{
return
s
.
length
>
0
;
}
)
.
map
(
function
(
s
)
{
return
parseInt
(
s
,
10
)
;
}
)
;
return
oid
;
}

Convert a string formatted OID to an array, leaving anything non-string alone.

Convert a string formatted OID to an array leaving anything non - string alone .


function parseOids(options) {
    if (options.oid) {
        options.oid = parseSingleOid(options.oid);
    }
    if (options.oids) {
        options.oids = options.oids.map(parseSingleOid);
    }
}

function parseOids ( options ) { if ( options . oid ) { options . oid = parseSingleOid ( options . oid ) ; } if ( options . oids ) { options . oids = options . oids . map ( parseSingleOid ) ; } }

Fix any OIDs in the 'oid' or 'oids' objects that are passed as strings.

Fix any OIDs in the oid or oids objects that are passed as strings .


function defaults(targ, _defs) {
    [].slice.call(arguments, 1).forEach(function (def) {
        Object.keys(def).forEach(function (key) {
            if (!targ.hasOwnProperty(key)) {
                targ[key] = def[key];
            }
        });
    });
}

function defaults ( targ , _defs ) { [ ] . slice . call ( arguments , 1 ) . forEach ( function ( def ) { Object . keys ( def ) . forEach ( function ( key ) { if ( ! targ . hasOwnProperty ( key ) ) { targ [ key ] = def [ key ] ; } } ) ; } ) ; }

Update targ with attributes from _defs. Any existing attributes on targ are untouched.

Update targ with attributes from _defs . Any existing attributes on targ are untouched .


function compareOids (oidA, oidB) {
    var mlen, i;

    // The undefined OID, if there is any, is deemed lesser.
    if (typeof oidA === 'undefined' && typeof oidB !== 'undefined') {
        return 1;
    } else if (typeof oidA !== 'undefined' && typeof oidB === 'undefined') {
        return -1;
    }

    // Check each number part of the OIDs individually, and if there is any
    // position where one OID is larger than the other, return accordingly.
    // This will only check up to the minimum length of both OIDs.
    mlen = Math.min(oidA.length, oidB.length);
    for (i = 0; i < mlen; i++) {
        if (oidA[i] > oidB[i]) {
            return -1;
        } else if (oidB[i] > oidA[i]) {
            return 1;
        }
    }

    // If there is one OID that is longer than the other after the above comparison,
    // consider the shorter OID to be lesser.
    if (oidA.length > oidB.length) {
        return -1;
    } else if (oidB.length > oidA.length) {
        return 1;
    } else {
        // The OIDs are obviously equal.
        return 0;
    }
}

Compare two OIDs, returning -1, 0 or +1 depending on the relation between oidA and oidB.

Compare two OIDs returning - 1 0 or + 1 depending on the relation between oidA and oidB .


function Session(options) {
    var self = this;

    self.options = options || {};
    defaults(self.options, exports.defaultOptions);

    self.reqs = {};
    self.socket = dgram.createSocket(self.options.family);
    self.socket.on('message', msgReceived.bind(self));
    self.socket.on('close', function () {
        // Remove the socket so we don't try to send a message on
        // it when it's closed.
        self.socket = undefined;
    });
    self.socket.on('error', function () {
        // Errors will be emitted here as well as on the callback to the send function.
        // We handle them there, so doing anything here is unnecessary.
        // But having no error handler trips up the test suite.
    });
    // If exclusive is false (default), then cluster workers will use the same underlying handle,
    // allowing connection handling duties to be shared.
    // When exclusive is true, the handle is not shared, and attempted port sharing results in an error.
    self.socket.bind({
        port: 0, //get a random port automatically
        exclusive: true // you should not share the same port, otherwise yours packages will be screwed up between workers
    });
}


function inTree(root, oid) {
        var i;
        if (oid.length <= root.length) {
            return false;
        }
        for (i = 0; i < root.length; i++) {
            if (oid[i] !== root[i]) {
                return false;
            }
        }
        return true;
    }

function inTree ( root , oid ) { var i ; if ( oid . length <= root . length ) { return false ; } for ( i = 0 ; i < root . length ; i ++ ) { if ( oid [ i ] !== root [ i ] ) { return false ; } } return true ; }

Helper to check whether `oid` in inside the tree rooted at `root` or not.

Helper to check whether oid in inside the tree rooted at root or not .


function wrapper(type, contents) {
    var buf, len, i;

    // Get the encoded length of the contents
    len = lengthArray(contents.length);

    // Set up a buffer with the type and length bytes plus a straight copy of the content.
    buf = new Buffer(1 + contents.length + len.length);
    buf[0] = type;
    for (i = 1; i < len.length + 1; i++) {
        buf[i] = len[i - 1];
    }
    contents.copy(buf, len.length + 1, 0);
    return buf;
}

Return a wrapped copy of the passed `contents`, with the specified wrapper type. This is used for Sequence and other constructed types.

Return a wrapped copy of the passed contents with the specified wrapper type . This is used for Sequence and other constructed types .


function oidArray(oid) {
    var bytes, i, val;

    // Enforce some minimum requirements on the OID.
    if (oid.length < 2) {
        throw new Error("Minimum OID length is two.");
    } else if (oid[0] > 2) {
        throw new Error("Invalid OID");
    } else if (oid[0] == 0 && oid[1] > 39) {
        throw new Error("Invalid OID");
    } else if (oid[0] == 1 && oid[1] > 39) {
        throw new Error("Invalid OID");
    } else if (oid[0] == 2 && oid[1] > 79) {
        throw new Error("Invalid OID");
    }

    // Calculate the first byte of the encoded OID according to the 'special' rule.
    bytes = [ 40 * oid[0] + oid[1] ];

    // For the rest of the OID, encode each number individually and add the
    // resulting bytes to the buffer.
    for (i = 2; i < oid.length; i++) {
        val = oid[i];
        if (val > 127) {
            bytes = bytes.concat(oidInt(val));
        } else {
            bytes.push(val);
        }
    }

    return bytes;
}

Encode an OID. The first two number are encoded specially in the first octet, then the rest are encoded as one octet per number unless the number exceeds 127. If so, it's encoded as several base-127 octets with the high bit set to indicate continuation.

Encode an OID . The first two number are encoded specially in the first octet then the rest are encoded as one octet per number unless the number exceeds 127 . If so it s encoded as several base - 127 octets with the high bit set to indicate continuation .


function intArray(val) {
    var array = [], encVal = val, bytes;

    if (val === 0) {
        array.push(0);
    } else {
        if (val < 0) {
            bytes = Math.floor(1 + Math.log(-val) / LOG256);
            // Encode negatives as 32-bit two's complement. Let's hope that fits.
            encVal += Math.pow(2, 8 * bytes);
        }
        while (encVal > 0) {
            array.push(encVal % 256);
            encVal = parseInt(encVal / 256, 10);
        }
    }

    // Do not produce integers that look negative (high bit
    // of first byte set).
    if (val > 0 && array[array.length - 1] >= 0x80) {
        array.push(0);
    }

    return array.reverse();
}

Divide an integer into base-256 bytes. Most significant byte first.

Divide an integer into base - 256 bytes . Most significant byte first .


function insureFreshToken(conn, cb) {
    var rh = conn.requestHeaders;
    if (rh && rh.authorization &&
        conn.user && rh.authorization.indexOf('Bearer ') === 0) {
      var stashedToken = tokenMgmt.currentToken(conn.user, conn.loginBaseUrl, conn.mgmtServer);
      if (tokenMgmt.isInvalidOrExpired(stashedToken)) {
        return conn.refreshToken(stashedToken, function(e, result){
          if (e) {
            throw new Error('error refreshing token: ' + e );
          }
          cb(merge(true, { headers: rh}));
        });
      }
      else {
        cb(merge(true, { headers: rh}));
      }
    }
    else {
      cb(merge(true, { headers: rh}));
    }
  }

function
insureFreshToken
(
conn
,
cb
)
{
var
rh
=
conn
.
requestHeaders
;
if
(
rh
&&
rh
.
authorization
&&
conn
.
user
&&
rh
.
authorization
.
indexOf
(
'Bearer '
)
===
0
)
{
var
stashedToken
=
tokenMgmt
.
currentToken
(
conn
.
user
,
conn
.
loginBaseUrl
,
conn
.
mgmtServer
)
;
if
(
tokenMgmt
.
isInvalidOrExpired
(
stashedToken
)
)
{
return
conn
.
refreshToken
(
stashedToken
,
function
(
e
,
result
)
{
if
(
e
)
{
throw
new
Error
(
'error refreshing token: '
+
e
)
;
}
cb
(
merge
(
true
,
{
headers
:
rh
}
)
)
;
}
)
;
}
else
{
cb
(
merge
(
true
,
{
headers
:
rh
}
)
)
;
}
}
else
{
cb
(
merge
(
true
,
{
headers
:
rh
}
)
)
;
}
}


function (arg) {
                var value  = arg.value;
                var flag   = arg.flag;
                var result = null;

                if (value) {
                    value  = Array.isArray(value) ? value : [value];
                    result = [];

                    value.forEach(function (path) {
                        result.push(flag);
                        result.push(path);
                    });
                }

                return result;
            }

function ( arg ) { var value = arg . value ; var flag = arg . flag ; var result = null ; if ( value ) { value = Array . isArray ( value ) ? value : [ value ] ; result = [ ] ; value . forEach ( function ( path ) { result . push ( flag ) ; result . push ( path ) ; } ) ; } return result ; }

"exclude" option could be used multiple times in this case the values are provided in an array

exclude option could be used multiple times in this case the values are provided in an array


function scaleSankeySize(graph, margin) {

    var maxColumn = max(graph.nodes, function (node) {
      return node.column;
    });

    var currentWidth = x1 - x0;
    var currentHeight = y1 - y0;

    var newWidth = currentWidth + margin.right + margin.left;
    var newHeight = currentHeight + margin.top + margin.bottom;

    var scaleX = currentWidth / newWidth;
    var scaleY = currentHeight / newHeight;

    x0 = x0 * scaleX + margin.left;
    x1 = margin.right == 0 ? x1 : x1 * scaleX;
    y0 = y0 * scaleY + margin.top;
    y1 = y1 * scaleY;

    graph.nodes.forEach(function (node) {
      node.x0 = x0 + node.column * ((x1 - x0 - dx) / maxColumn);
      node.x1 = node.x0 + dx;
    });

    return scaleY;
  }

function scaleSankeySize ( graph , margin ) { var maxColumn = max ( graph . nodes , function ( node ) { return node . column ; } ) ; var currentWidth = x1 - x0 ; var currentHeight = y1 - y0 ; var newWidth = currentWidth + margin . right + margin . left ; var newHeight = currentHeight + margin . top + margin . bottom ; var scaleX = currentWidth / newWidth ; var scaleY = currentHeight / newHeight ; x0 = x0 * scaleX + margin . left ; x1 = margin . right == 0 ? x1 : x1 * scaleX ; y0 = y0 * scaleY + margin . top ; y1 = y1 * scaleY ; graph . nodes . forEach ( function ( node ) { node . x0 = x0 + node . column * ( ( x1 - x0 - dx ) / maxColumn ) ; node . x1 = node . x0 + dx ; } ) ; return scaleY ; }

Update the x0, y0, x1 and y1 for the sankeyCircular, to allow space for any circular links

Update the x0 y0 x1 and y1 for the sankeyCircular to allow space for any circular links


function computeNodeDepths(graph) {
    var nodes, next, x;

    for (nodes = graph.nodes, next = [], x = 0; nodes.length; ++x, nodes = next, next = []) {
      nodes.forEach(function (node) {
        node.depth = x;
        node.sourceLinks.forEach(function (link) {
          if (next.indexOf(link.target) < 0 && !link.circular) {
            next.push(link.target);
          }
        });
      });
    }

    for (nodes = graph.nodes, next = [], x = 0; nodes.length; ++x, nodes = next, next = []) {
      nodes.forEach(function (node) {
        node.height = x;
        node.targetLinks.forEach(function (link) {
          if (next.indexOf(link.source) < 0 && !link.circular) {
            next.push(link.source);
          }
        });
      });
    }

    // assign column numbers, and get max value
    graph.nodes.forEach(function (node) {
      node.column = Math.floor(align.call(null, node, x));
    });
  }

Iteratively assign the depth for each node. Nodes are assigned the maximum depth of incoming neighbors plus one; nodes with no incoming links are assigned depth zero, while nodes with no outgoing links are assigned the maximum depth.

Iteratively assign the depth for each node . Nodes are assigned the maximum depth of incoming neighbors plus one ; nodes with no incoming links are assigned depth zero while nodes with no outgoing links are assigned the maximum depth .


function sortLinkColumnAscending(link1, link2) {
  if (linkColumnDistance(link1) == linkColumnDistance(link2)) {
    return link1.circularLinkType == 'bottom' ? sortLinkSourceYDescending(link1, link2) : sortLinkSourceYAscending(link1, link2);
  } else {
    return linkColumnDistance(link2) - linkColumnDistance(link1);
  }
}

function sortLinkColumnAscending ( link1 , link2 ) { if ( linkColumnDistance ( link1 ) == linkColumnDistance ( link2 ) ) { return link1 . circularLinkType == 'bottom' ? sortLinkSourceYDescending ( link1 , link2 ) : sortLinkSourceYAscending ( link1 , link2 ) ; } else { return linkColumnDistance ( link2 ) - linkColumnDistance ( link1 ) ; } }

sort links based on the distance between the source and tartget node columns if the same, then use Y position of the source node

sort links based on the distance between the source and tartget node columns if the same then use Y position of the source node


function selfLinking(link, id) {
  return getNodeID(link.source, id) == getNodeID(link.target, id);
}

function selfLinking ( link , id ) { return getNodeID ( link . source , id ) == getNodeID ( link . target , id ) ; }

check if link is self linking, ie links a node to the same node

check if link is self linking ie links a node to the same node


function find (nodeById, id) {
    var node = nodeById.get(id)
    if (!node) throw new Error('missing: ' + id)
    return node
  }

function
find
(
nodeById
,
id
)
{
var
node
=
nodeById
.
get
(
id
)
if
(
!
node
)
throw
new
Error
(
'missing: '
+
id
)
return
node
}

Return the node from the collection that matches the provided ID, or throw an error if no match

Return the node from the collection that matches the provided ID or throw an error if no match


function computeNodeLinks (graph) {
      graph.nodes.forEach(function (node, i) {
        node.index = i
        node.sourceLinks = []
        node.targetLinks = []
      })
      var nodeById = map(graph.nodes, id)
      graph.links.forEach(function (link, i) {
        link.index = i
        var source = link.source
        var target = link.target
        if (typeof source !== 'object') {
          source = link.source = find(nodeById, source)
        }
        if (typeof target !== 'object') {
          target = link.target = find(nodeById, target)
        }
        source.sourceLinks.push(link)
        target.targetLinks.push(link)
      })
      return graph
    }

function computeNodeLinks ( graph ) { graph . nodes . forEach ( function ( node , i ) { node . index = i node . sourceLinks = [ ] node . targetLinks = [ ] } ) var nodeById = map ( graph . nodes , id ) graph . links . forEach ( function ( link , i ) { link . index = i var source = link . source var target = link . target if ( typeof source !== 'object' ) { source = link . source = find ( nodeById , source ) } if ( typeof target !== 'object' ) { target = link . target = find ( nodeById , target ) } source . sourceLinks . push ( link ) target . targetLinks . push ( link ) } ) return graph }

Populate the sourceLinks and targetLinks for each node. Also, if the source and target are not objects, assume they are indices.

Populate the sourceLinks and targetLinks for each node . Also if the source and target are not objects assume they are indices .


function linkAngle (link) {
    var adjacent = Math.abs(link.y1 - link.y0)
    var opposite = Math.abs(link.target.x0 - link.source.x1)

    return Math.atan(opposite / adjacent)
  }

function linkAngle ( link ) { var adjacent = Math . abs ( link . y1 - link . y0 ) var opposite = Math . abs ( link . target . x0 - link . source . x1 ) return Math . atan ( opposite / adjacent ) }

Return the angle between a straight line between the source and target of the link, and the vertical plane of the node

Return the angle between a straight line between the source and target of the link and the vertical plane of the node


function circularLinksCross (link1, link2) {
    if (link1.source.column < link2.target.column) {
      return false
    } else if (link1.target.column > link2.source.column) {
      return false
    } else {
      return true
    }
  }

function circularLinksCross ( link1 , link2 ) { if ( link1 . source . column < link2 . target . column ) { return false } else if ( link1 . target . column > link2 . source . column ) { return false } else { return true } }

Check if two circular links potentially overlap


function numberOfNonSelfLinkingCycles (node, id) {
    var sourceCount = 0
    node.sourceLinks.forEach(function (l) {
      sourceCount = l.circular && !selfLinking(l, id)
        ? sourceCount + 1
        : sourceCount
    })

    var targetCount = 0
    node.targetLinks.forEach(function (l) {
      targetCount = l.circular && !selfLinking(l, id)
        ? targetCount + 1
        : targetCount
    })

    return sourceCount + targetCount
  }

function numberOfNonSelfLinkingCycles ( node , id ) { var sourceCount = 0 node . sourceLinks . forEach ( function ( l ) { sourceCount = l . circular && ! selfLinking ( l , id ) ? sourceCount + 1 : sourceCount } ) var targetCount = 0 node . targetLinks . forEach ( function ( l ) { targetCount = l . circular && ! selfLinking ( l , id ) ? targetCount + 1 : targetCount } ) return sourceCount + targetCount }

Return the number of circular links for node, not including self linking links

Return the number of circular links for node not including self linking links


function onlyCircularLink (link) {
    var nodeSourceLinks = link.source.sourceLinks
    var sourceCount = 0
    nodeSourceLinks.forEach(function (l) {
      sourceCount = l.circular ? sourceCount + 1 : sourceCount
    })

    var nodeTargetLinks = link.target.targetLinks
    var targetCount = 0
    nodeTargetLinks.forEach(function (l) {
      targetCount = l.circular ? targetCount + 1 : targetCount
    })

    if (sourceCount > 1 || targetCount > 1) {
      return false
    } else {
      return true
    }
  }

function onlyCircularLink ( link ) { var nodeSourceLinks = link . source . sourceLinks var sourceCount = 0 nodeSourceLinks . forEach ( function ( l ) { sourceCount = l . circular ? sourceCount + 1 : sourceCount } ) var nodeTargetLinks = link . target . targetLinks var targetCount = 0 nodeTargetLinks . forEach ( function ( l ) { targetCount = l . circular ? targetCount + 1 : targetCount } ) if ( sourceCount > 1 || targetCount > 1 ) { return false } else { return true } }

Check if a circular link is the only circular link for both its source and target node


function nodesOverlap (nodeA, nodeB) {
    // test if nodeA top partially overlaps nodeB
    if (nodeA.y0 > nodeB.y0 && nodeA.y0 < nodeB.y1) {
      return true
    } else if (nodeA.y1 > nodeB.y0 && nodeA.y1 < nodeB.y1) {
      // test if nodeA bottom partially overlaps nodeB
      return true
    } else if (nodeA.y0 < nodeB.y0 && nodeA.y1 > nodeB.y1) {
      // test if nodeA covers nodeB
      return true
    } else {
      return false
    }
  }


function (options, callback) {
      if (!('headers' in options)) {
        options.headers = {};
      }

      options.json = true;
      options.headers['User-Agent'] = Poloniex.USER_AGENT;
      options.strictSSL = Poloniex.STRICT_SSL;
      options.timeout = Poloniex.TIMEOUT;

      return new Promise(function (resolve, reject) {
        request(options, function (err, response, body) {
          // Empty response
          if (!err && (typeof body === 'undefined' || body === null)) {
            err = new Error('Empty response from remote server');
          }

          if (err) {
            reject(err);
          }

          else {
            resolve(body);
          }

          if (typeof callback === 'function') {
            callback(err, body);
          }
        });
      });
    }

function
(
options
,
callback
)
{
if
(
!
(
'headers'
in
options
)
)
{
options
.
headers
=
{
}
;
}
options
.
json
=
true
;
options
.
headers
[
'User-Agent'
]
=
Poloniex
.
USER_AGENT
;
options
.
strictSSL
=
Poloniex
.
STRICT_SSL
;
options
.
timeout
=
Poloniex
.
TIMEOUT
;
return
new
Promise
(
function
(
resolve
,
reject
)
{
request
(
options
,
function
(
err
,
response
,
body
)
{
// Empty response
if
(
!
err
&&
(
typeof
body
===
'undefined'
||
body
===
)
)
{
err
=
new
Error
(
'Empty response from remote server'
)
;
}
if
(
err
)
{
reject
(
err
)
;
}
else
{
resolve
(
body
)
;
}
if
(
typeof
callback
===
'function'
)
{
callback
(
err
,
body
)
;
}
}
)
;
}
)
;
}


function (command, parameters, callback) {
      if (typeof parameters === 'function') {
        callback = parameters;
        parameters = {};
      }

      parameters || (parameters = {});
      parameters.command = command;

      const options = {
        method: 'GET',
        url: PUBLIC_API_URL,
        qs: parameters
      };

      options.qs.command = command;

      return this._request(options, callback);
    }

function ( command , parameters , callback ) { if ( typeof parameters === 'function' ) { callback = parameters ; parameters = { } ; } parameters || ( parameters = { } ) ; parameters . command = command ; const options = { method : 'GET' , url : PUBLIC_API_URL , qs : parameters } ; options . qs . command = command ; return this . _request ( options , callback ) ; }


function (command, parameters, callback) {
      if (typeof parameters === 'function') {
        callback = parameters;
        parameters = {};
      }

      parameters || (parameters = {});
      parameters.command = command;
      parameters.nonce = nonce();

      const options = {
        method: 'POST',
        url: PRIVATE_API_URL,
        form: parameters,
        headers: this._getPrivateHeaders(parameters)
      };

      return this._request(options, callback);
    }

function ( command , parameters , callback ) { if ( typeof parameters === 'function' ) { callback = parameters ; parameters = { } ; } parameters || ( parameters = { } ) ; parameters . command = command ; parameters . nonce = nonce ( ) ; const options = { method : 'POST' , url : PRIVATE_API_URL , form : parameters , headers : this . _getPrivateHeaders ( parameters ) } ; return this . _request ( options , callback ) ; }


function spawnChildProcess(bin, args, option) {
    const result = spawnCancelableChild(bin, args, option);
    return result.process;
}

function spawnChildProcess ( bin , args , option ) { const result = spawnCancelableChild ( bin , args , option ) ; return result . process ; }

Spawn a child process.

@param  {string}    bin
the same as the 1st argument of `child_process.spawn()`.
@param  {Array}     args
the same as the 2nd argument of `child_process.spawn()`.
@param  {Object}    option
the same as the 3rd argument of `child_process.spawn()`.

@return {!PromiseLike<number>}


function spawnCancelableChild(bin, args, option) {
    let innerCancel = null;
    let isCanceled = false;
    const canceller = function () {
        if (isCanceled) {
            return;
        }

        isCanceled = true;
        if (typeof innerCancel === 'function') {
            innerCancel();
        }
    };

    const process = new Promise(function(resolve, reject){
        if (isCanceled) {
            reject();
            return;
        }

        console.log('spawn: ' + bin + ' ' + args.join(' '));
        const proc = childProcess.spawn(bin, args, option);
        innerCancel = function () {
            proc.kill('SIGINT');
        };

        proc.on('exit', function(status) {
            resolve(status);
        });
    });

    return {
        canceller,
        process,
    };
}

function
spawnCancelableChild
(
bin
,
args
,
option
)
{
let
innerCancel
=
;
let
isCanceled
=
false
;
const
canceller
=
function
(
)
{
if
(
isCanceled
)
{
return
;
}
isCanceled
=
true
;
if
(
typeof
innerCancel
===
'function'
)
{
innerCancel
(
)
;
}
}
;
const
process
=
new
Promise
(
function
(
resolve
,
reject
)
{
if
(
isCanceled
)
{
reject
(
)
;
return
;
}
console
.
log
(
'spawn: '
+
bin
+
' '
+
args
.
join
(
' '
)
)
;
const
proc
=
childProcess
.
spawn
(
bin
,
args
,
option
)
;
innerCancel
=
function
(
)
{
proc
.
kill
(
'SIGINT'
)
;
}
;
proc
.
on
(
'exit'
,
function
(
status
)
{
resolve
(
status
)
;
}
)
;
}
)
;
return
{
canceller
,
process
,
}
;
}

Spawn a child process with the canceller function.

XXX: This should be implemented with using a cancelable promise.

@param  {string}    bin
the same as the 1st argument of `child_process.spawn()`.
@param  {Array}     args
the same as the 2nd argument of `child_process.spawn()`.
@param  {Object}    option
the same as the 3rd argument of `child_process.spawn()`.

@return { !{ process: !PromiseLike<number>, canceller: !function(): void, } }
- `process`: This is fulfilled with the process's exit status.
- `canceller`: try to cancel the process if you call this.

Spawn a child process with the canceller function .