function coerceControllerAlias(property) {
  return computed(property, {
    get() {
      let controllerName = this.get('controllerName') || this.get('routeName');
      let controller = this.get('controller') || this.controllerFor(controllerName);
      return controller.get(property);
    },
    set(key, value) {
      let controllerName = this.get('controllerName') || this.get('routeName');
      let controller = this.get('controller') || this.controllerFor(controllerName);
      controller.set(property, value);
      return value;
    }
  });
}

function coerceControllerAlias ( property ) { return computed ( property , { get ( ) { let controllerName = this . get ( 'controllerName' ) || this . get ( 'routeName' ) ; let controller = this . get ( 'controller' ) || this . controllerFor ( controllerName ) ; return controller . get ( property ) ; } , set ( key , value ) { let controllerName = this . get ( 'controllerName' ) || this . get ( 'routeName' ) ; let controller = this . get ( 'controller' ) || this . controllerFor ( controllerName ) ; controller . set ( property , value ) ; return value ; } } ) ; }

Delegates a given property to the related controller (or specified controller
if `controllerName` is defined. This is useful so that properties are
available to use on the controller.

Delegates a given property to the related controller ( or specified controller if controllerName is defined . This is useful so that properties are available to use on the controller .


function encode() {
  var data = this.data;
  var length = 11;
  var sender = this.sender;
  var target = this.target;
  var header = new Buffer(9);
  var content = !data || isBuffer(data) ? data : this.encode(data);

  if (content) length += content.length;

  header.writeUInt8(length, 0);
  header.writeUInt8(sender.subnet, 1);
  header.writeUInt8(sender.id, 2);
  header.writeUInt16BE(sender.type, 3);
  header.writeUInt16BE(this.code, 5);
  header.writeUInt8(target.subnet, 7);
  header.writeUInt8(target.id, 8);

  return content ? Buffer.concat([header, content]) : header;
}

function encode ( ) { var data = this . data ; var length = 11 ; var sender = this . sender ; var target = this . target ; var header = new Buffer ( 9 ) ; var content = ! data || isBuffer ( data ) ? data : this . encode ( data ) ; if ( content ) length += content . length ; header . writeUInt8 ( length , 0 ) ; header . writeUInt8 ( sender . subnet , 1 ) ; header . writeUInt8 ( sender . id , 2 ) ; header . writeUInt16BE ( sender . type , 3 ) ; header . writeUInt16BE ( this . code , 5 ) ; header . writeUInt8 ( target . subnet , 7 ) ; header . writeUInt8 ( target . id , 8 ) ; return content ? Buffer . concat ( [ header , content ] ) : header ; }

Return compiled command message

@param  {Object|Buffer} data
@return {Buffer}


function isValid(message) {
  if (!Constants.equals(message.slice(4, 16))) return false;

  var checksum = message.readUInt16BE(message.length - 2);

  return checksum === crc(message.slice(16, -2));
}

function isValid ( message ) { if ( ! Constants . equals ( message . slice ( 4 , 16 ) ) ) return false ; var checksum = message . readUInt16BE ( message . length - 2 ) ; return checksum === crc ( message . slice ( 16 , - 2 ) ) ; }

Check if buffer is valid Smart Bus command

@param  {Buffer} message
@return {Boolean}


function source(message) {
  var ip = [];

  for (var i = 0; i < 4; i++) ip.push(message[i]);

  return ip.join('.');
}

function source ( message ) { var ip = [ ] ; for ( var i = 0 ; i < 4 ; i ++ ) ip . push ( message [ i ] ) ; return ip . join ( '.' ) ; }

Return message sender IP address

@param  {Buffer} message
@return {String}


function parse(resource) {
  if (typeof resource === 'object') return resource;

  var config = url.parse(resource);

  return {
    port: config.port,
    device: config.auth,
    gateway: config.hostname
  };
}

function parse ( resource ) { if ( typeof resource === 'object' ) return resource ; var config = url . parse ( resource ) ; return { port : config . port , device : config . auth , gateway : config . hostname } ; }

Parse bus configuration from connection string with following format

hdl://device@gateway[:port]

@param  {String|Object} resource - connection string or configutaion
@return {Object} - bus connection configuration


function getComponentDescendants (root, component, onlyChildren, includeSelf) {
    var node = rquery_getDOMNode(component),
        descendants = [];

    if (onlyChildren) {
      descendants = node.children;
    } else {
      descendants = node.getElementsByTagName('*');
    }

    // convert to array
    descendants = _.toArray(descendants);

    if (includeSelf) {
      descendants.unshift(rquery_getDOMNode(component));
    }

    injectCompositeComponents(root, descendants);

    return descendants;
  }

function
getComponentDescendants
(
root
,
component
,
onlyChildren
,
includeSelf
)
{
var
node
=
rquery_getDOMNode
(
component
)
,
descendants
=
[
]
;
if
(
onlyChildren
)
{
descendants
=
node
.
children
;
}
else
{
descendants
=
node
.
getElementsByTagName
(
'*'
)
;
}
// convert to array
descendants
=
_
.
toArray
(
descendants
)
;
if
(
includeSelf
)
{
descendants
.
unshift
(
rquery_getDOMNode
(
component
)
)
;
}
injectCompositeComponents
(
root
,
descendants
)
;
return
descendants
;
}

Reduces the list of descendants to only DOM nodes. Then, it will splice in
the React components for any composite components.

Reduces the list of descendants to only DOM nodes . Then it will splice in the React components for any composite components .


function flushDeferredPadding(blocks) {
                if (!padding)
                    return;
                let prevBlock = blocks[blocks.length - 2];
                prevBlock.text += padding;
            }

function flushDeferredPadding ( blocks ) { if ( ! padding ) return ; let prevBlock = blocks [ blocks . length - 2 ] ; prevBlock . text += padding ; }

there is no sense to put padding to the expression text since it will be lost while evaluating


function(e) {
			e.data.handler.over = true;
			$.iframeTracker.retrieveFocus();
			try {
				e.data.handler.overCallback(this, e);
			} catch (ex) {}
		}

function ( e ) { e . data . handler . over = true ; $ . iframeTracker . retrieveFocus ( ) ; try { e . data . handler . overCallback ( this , e ) ; } catch ( ex ) { } }


function(e) {
			e.data.handler.over = false;
			$.iframeTracker.retrieveFocus();
			try {
				e.data.handler.outCallback(this, e);
			} catch (ex) {}
		}

function ( e ) { e . data . handler . over = false ; $ . iframeTracker . retrieveFocus ( ) ; try { e . data . handler . outCallback ( this , e ) ; } catch ( ex ) { } }


function() {
			if (document.activeElement && document.activeElement.tagName === "IFRAME") {
				$.iframeTracker.focusRetriever.focus();
				$.iframeTracker.focusRetrieved = true;
			}
		}

function ( ) { if ( document . activeElement && document . activeElement . tagName === "IFRAME" ) { $ . iframeTracker . focusRetriever . focus ( ) ; $ . iframeTracker . focusRetrieved = true ; } }

Give back focus from an iframe to parent page


function(e) {
			for (var i in this.handlersList) {
				if (this.handlersList[i].over === true) {
					try {
						this.handlersList[i].blurCallback(e);
					} catch (ex) {}
				}
			}
		}

function ( e ) { for ( var i in this . handlersList ) { if ( this . handlersList [ i ] . over === true ) { try { this . handlersList [ i ] . blurCallback ( e ) ; } catch ( ex ) { } } } }

Calls blurCallback for every handler with over=true on window blur

Calls blurCallback for every handler with over = true on window blur


function funcWithReturnFromSnippet(js) {
    // auto-"return"
    if (js.indexOf('return') === -1) {
        if (js.substring(js.length - 1) === ';') {
            js = js.substring(0, js.length - 1);
        }
        js = 'return (' + js + ')';
    }

    // Expose level definitions to condition func context
    var varDefs = [];
    Object.keys(upperNameFromLevel).forEach(function (lvl) {
        varDefs.push(format('var %s = %d;',
                upperNameFromLevel[lvl], lvl));
    });
    varDefs = varDefs.join('\n') + '\n';

    return (new Function(varDefs + js));
}

Return a function for the given JS code that returns.

If no 'return' in the given javascript snippet, then assume we are a single
statement and wrap in 'return (...)'. This is for convenience for short
'-c ...' snippets.

Return a function for the given JS code that returns .


function parseArgv(argv) {
    var parsed = {
        args: [],
        help: false,
        color: null,
        paginate: null,
        outputMode: OM_LONG,
        jsonIndent: 2,
        level: null,
        strict: false,
        pids: null,
        pidsType: null,
        timeFormat: TIME_UTC  // one of the TIME_ constants
    };

    // Turn '-iH' into '-i -H', except for argument-accepting options.
    var args = argv.slice(2);  // drop ['node', 'scriptname']
    var newArgs = [];
    var optTakesArg = {'d': true, 'o': true, 'c': true, 'l': true, 'p': true};
    for (var i = 0; i < args.length; i++) {
        if (args[i].charAt(0) === '-' && args[i].charAt(1) !== '-' &&
            args[i].length > 2)
        {
            var splitOpts = args[i].slice(1).split('');
            for (var j = 0; j < splitOpts.length; j++) {
                newArgs.push('-' + splitOpts[j]);
                if (optTakesArg[splitOpts[j]]) {
                    var optArg = splitOpts.slice(j+1).join('');
                    if (optArg.length) {
                        newArgs.push(optArg);
                    }
                    break;
                }
            }
        } else {
            newArgs.push(args[i]);
        }
    }
    args = newArgs;

    // Expose level definitions to condition vm context
    var condDefines = [];
    Object.keys(upperNameFromLevel).forEach(function (lvl) {
        condDefines.push(
            format('Object.prototype.%s = %s;', upperNameFromLevel[lvl], lvl));
    });
    condDefines = condDefines.join('\n') + '\n';

    var endOfOptions = false;
    while (args.length > 0) {
        var arg = args.shift();
        switch (arg) {
            case '--':
                endOfOptions = true;
                break;
            case '-h': // display help and exit
            case '--help':
                parsed.help = true;
                break;
            case '--version':
                parsed.version = true;
                break;
            case '--strict':
                parsed.strict = true;
                break;
            case '--color':
                parsed.color = true;
                break;
            case '--no-color':
                parsed.color = false;
                break;
            case '--pager':
                parsed.paginate = true;
                break;
            case '--no-pager':
                parsed.paginate = false;
                break;
            case '-o':
            case '--output':
                var name = args.shift();
                var idx = name.lastIndexOf('-');
                if (idx !== -1) {
                    var indentation = Number(name.slice(idx+1));
                    if (! isNaN(indentation)) {
                        parsed.jsonIndent = indentation;
                        name = name.slice(0, idx);
                    }
                }
                parsed.outputMode = OM_FROM_NAME[name];
                if (parsed.outputMode === undefined) {
                    throw new Error('unknown output mode: "'+name+'"');
                }
                break;
            case '-j': // output with JSON.stringify
                parsed.outputMode = OM_JSON;
                break;
            case '-0':
                parsed.outputMode = OM_BUNYAN;
                break;
            case '-L':
                parsed.timeFormat = TIME_LOCAL;
                if (!moment) {
                    throw new Error(
                        'could not find moment package required for "-L"');
                }
                break;
            case '--time':
                var timeArg = args.shift();
                switch (timeArg) {
                case 'utc':
                    parsed.timeFormat = TIME_UTC;
                    break
                case 'local':
                    parsed.timeFormat = TIME_LOCAL;
                    if (!moment) {
                        throw new Error('could not find moment package '
                            + 'required for "--time=local"');
                    }
                    break
                case undefined:
                    throw new Error('missing argument to "--time"');
                default:
                    throw new Error(format('invalid time format: "%s"',
                        timeArg));
                }
                break;
            case '-p':
                if (!parsed.pids) {
                    parsed.pids = [];
                }
                var pidArg = args.shift();
                var pid = +(pidArg);
                if (!isNaN(pid) || pidArg === '*') {
                    if (parsed.pidsType && parsed.pidsType !== 'num') {
                        throw new Error(format('cannot mix PID name and '
                            + 'number arguments: "%s"', pidArg));
                    }
                    parsed.pidsType = 'num';
                    if (!parsed.pids) {
                        parsed.pids = [];
                    }
                    parsed.pids.push(isNaN(pid) ? pidArg : pid);
                } else {
                    if (parsed.pidsType && parsed.pidsType !== 'name') {
                        throw new Error(format('cannot mix PID name and '
                            + 'number arguments: "%s"', pidArg));
                    }
                    parsed.pidsType = 'name';
                    parsed.pids = pidArg;
                }
                break;
            case '-l':
            case '--level':
                var levelArg = args.shift();
                var level = +(levelArg);
                if (isNaN(level)) {
                    level = +levelFromName[levelArg.toLowerCase()];
                }
                if (isNaN(level)) {
                    throw new Error('unknown level value: "'+levelArg+'"');
                }
                parsed.level = level;
                break;
            case '-c':
            case '--condition':
                gUsingConditionOpts = true;
                var condition = args.shift();
                if (Boolean(process.env.BUNYAN_EXEC &&
                    process.env.BUNYAN_EXEC === 'vm'))
                {
                    parsed.condVm = parsed.condVm || [];
                    var scriptName = 'bunyan-condition-'+parsed.condVm.length;
                    var code = condDefines + condition;
                    var script;
                    try {
                        script = vm.createScript(code, scriptName);
                    } catch (complErr) {
                        throw new Error(format('illegal CONDITION code: %s\n'
                            + '  CONDITION script:\n'
                            + '%s\n'
                            + '  Error:\n'
                            + '%s',
                            complErr, indent(code), indent(complErr.stack)));
                    }

                    // Ensure this is a reasonably safe CONDITION.
                    try {
                        script.runInNewContext(minValidRecord);
                    } catch (condErr) {
                        throw new Error(format(
                            /* JSSTYLED */
                            'CONDITION code cannot safely filter a minimal Bunyan log record\n'
                            + '  CONDITION script:\n'
                            + '%s\n'
                            + '  Minimal Bunyan log record:\n'
                            + '%s\n'
                            + '  Filter error:\n'
                            + '%s',
                            indent(code),
                            indent(JSON.stringify(minValidRecord, null, 2)),
                            indent(condErr.stack)
                            ));
                    }
                    parsed.condVm.push(script);
                } else  {
                    parsed.condFuncs = parsed.condFuncs || [];
                    parsed.condFuncs.push(funcWithReturnFromSnippet(condition));
                }
                break;
            default: // arguments
                if (!endOfOptions && arg.length > 0 && arg[0] === '-') {
                    throw new Error('unknown option "'+arg+'"');
                }
                parsed.args.push(arg);
                break;
        }
    }
    //TODO: '--' handling and error on a first arg that looks like an option.

    return parsed;
}

Parse the command-line options and arguments into an object.

{
'args': [...]       // arguments
'help': true,       // true if '-h' option given
// etc.
}

@return {Object} The parsed options. `.args` is the argument list.
@throws {Error} If there is an error parsing argv.

Parse the command - line options and arguments into an object .


function processStdin(opts, stylize, callback) {
    var leftover = '';  // Left-over partial line from last chunk.
    var stdin = process.stdin;
    stdin.resume();
    stdin.setEncoding('utf8');
    stdin.on('data', function (chunk) {
        var lines = chunk.split(/\r\n|\n/);
        var length = lines.length;
        if (length === 1) {
            leftover += lines[0];
            return;
        }

        if (length > 1) {
            handleLogLine(null, leftover + lines[0], opts, stylize);
        }
        leftover = lines.pop();
        length -= 1;
        for (var i = 1; i < length; i++) {
            handleLogLine(null, lines[i], opts, stylize);
        }
    });
    stdin.on('end', function () {
        if (leftover) {
            handleLogLine(null, leftover, opts, stylize);
            leftover = '';
        }
        callback();
    });
}

Process all input from stdin.

@params opts {Object} Bunyan options object.
@param stylize {Function} Output stylize function to use.
@param callback {Function} `function ()`


function getPids(cb) {
        if (opts.pidsType === 'num') {
            return cb(null, opts.pids);
        }
        if (process.platform === 'sunos') {
            execFile('/bin/pgrep', ['-lf', opts.pids],
                function (pidsErr, stdout, stderr) {
                    if (pidsErr) {
                        warn('bunyan: error getting PIDs for "%s": %s\n%s\n%s',
                            opts.pids, pidsErr.message, stdout, stderr);
                        return cb(1);
                    }
                    var pids = stdout.trim().split('\n')
                        .map(function (line) {
                            return line.trim().split(/\s+/)[0]
                        })
                        .filter(function (pid) {
                            return Number(pid) !== process.pid
                        });
                    if (pids.length === 0) {
                        warn('bunyan: error: no matching PIDs found for "%s"',
                            opts.pids);
                        return cb(2);
                    }
                    cb(null, pids);
                }
            );
        } else {
            var regex = opts.pids;
            if (regex && /[a-zA-Z0-9_]/.test(regex[0])) {
                // 'foo' -> '[f]oo' trick to exclude the 'grep' PID from its
                // own search.
                regex = '[' + regex[0] + ']' + regex.slice(1);
            }
            exec(format('ps -A -o pid,command | grep \'%s\'', regex),
                function (pidsErr, stdout, stderr) {
                    if (pidsErr) {
                        warn('bunyan: error getting PIDs for "%s": %s\n%s\n%s',
                            opts.pids, pidsErr.message, stdout, stderr);
                        return cb(1);
                    }
                    var pids = stdout.trim().split('\n')
                        .map(function (line) {
                            return line.trim().split(/\s+/)[0];
                        })
                        .filter(function (pid) {
                            return Number(pid) !== process.pid;
                        });
                    if (pids.length === 0) {
                        warn('bunyan: error: no matching PIDs found for "%s"',
                            opts.pids);
                        return cb(2);
                    }
                    cb(null, pids);
                }
            );
        }
    }

Left-over partial line from last chunk.
Get the PIDs to dtrace.

@param cb {Function} `function (errCode, pids)`

Left - over partial line from last chunk . Get the PIDs to dtrace .


function processFile(file, opts, stylize, callback) {
    var stream = fs.createReadStream(file);
    if (/\.gz$/.test(file)) {
        stream = stream.pipe(require('zlib').createGunzip());
    }
    // Manually decode streams - lazy load here as per node/lib/fs.js
    var decoder = new (require('string_decoder')
      .StringDecoder)('utf8');

    streams[file].stream = stream;

    stream.on('error', function (err) {
        streams[file].done = true;
        callback(err);
    });

    var leftover = '';  // Left-over partial line from last chunk.
    stream.on('data', function (data) {
        var chunk = decoder.write(data);
        if (!chunk.length) {
            return;
        }
        var lines = chunk.split(/\r\n|\n/);
        var length = lines.length;
        if (length === 1) {
            leftover += lines[0];
            return;
        }

        if (length > 1) {
            handleLogLine(file, leftover + lines[0], opts, stylize);
        }
        leftover = lines.pop();
        length -= 1;
        for (var i = 1; i < length; i++) {
            handleLogLine(file, lines[i], opts, stylize);
        }
    });

    stream.on('end', function () {
        streams[file].done = true;
        if (leftover) {
            handleLogLine(file, leftover, opts, stylize);
            leftover = '';
        } else {
            emitNextRecord(opts, stylize);
        }
        callback();
    });
}

Process all input from the given log file.

@param file {String} Log file path to process.
@params opts {Object} Bunyan options object.
@param stylize {Function} Output stylize function to use.
@param callback {Function} `function ()`

Process all input from the given log file .


function MochaWorkerReporter (runner) {
  EVENTS.forEach(function (eventName) {
    runner.on(eventName, function (test, error) {
      var data = {
        'event' : eventName,
        'test'  : clean(test, error)
      };

      try {
        process.send({
          type : 'testResults',
          data : data
        });
      } catch (e) {
        console.log('MochaWorkerReporter: Error sending test results.', JSON.stringify(data), e.message, e.stack);
        process.exit(1);
      }
    });
  });
}

Sends test results back to the master test running process.

Sends test results back to the master test running process .


function CucumberReporter (eventMediator) {
  var options = {
    snippets  : true,
    stream    : process.stdout,
    useColors : true
  };
  this.failureCount  = 0;
  this.eventMediator = eventMediator;
  this.formatter     = DotFormatter(options);

  // all feature files are finished
  this.eventMediator.on('end', this.allFeaturesDone.bind(this));
}

function
CucumberReporter
(
eventMediator
)
{
var
options
=
{
snippets
:
true
,
stream
:
process
.
stdout
,
useColors
:
true
}
;
this
.
failureCount
=
0
;
this
.
eventMediator
=
eventMediator
;
this
.
formatter
=
DotFormatter
(
options
)
;
// all feature files are finished
this
.
eventMediator
.
on
(
'end'
,
this
.
allFeaturesDone
.
bind
(
this
)
)
;
}

Assembles test results from the worker processes and outputs the results
to the console.

Assembles test results from the worker processes and outputs the results to the console .


function closest (element, selector) {
    while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
        if (typeof element.matches === 'function' &&
            element.matches(selector)) {
          return element;
        }
        element = element.parentNode;
    }
}

function closest ( element , selector ) { while ( element && element . nodeType !== DOCUMENT_NODE_TYPE ) { if ( typeof element . matches === 'function' && element . matches ( selector ) ) { return element ; } element = element . parentNode ; } }

Finds the closest parent that matches a selector.

@param {Element} element
@param {String} selector
@return {Function}

Finds the closest parent that matches a selector .


function delegate(elements, selector, type, callback, useCapture) {
    // Handle the regular Element usage
    if (typeof elements.addEventListener === 'function') {
        return _delegate.apply(null, arguments);
    }

    // Handle Element-less usage, it defaults to global delegation
    if (typeof type === 'function') {
        // Use `document` as the first parameter, then apply arguments
        // This is a short way to .unshift `arguments` without running into deoptimizations
        return _delegate.bind(null, document).apply(null, arguments);
    }

    // Handle Selector-based usage
    if (typeof elements === 'string') {
        elements = document.querySelectorAll(elements);
    }

    // Handle Array-like based usage
    return Array.prototype.map.call(elements, function (element) {
        return _delegate(element, selector, type, callback, useCapture);
    });
}

Delegates event to a selector.

@param {Element|String|Array} [elements]
@param {String} selector
@param {String} type
@param {Function} callback
@param {Boolean} useCapture
@return {Object}


function listener(element, selector, type, callback) {
    return function(e) {
        e.delegateTarget = closest_1(e.target, selector);

        if (e.delegateTarget) {
            callback.call(element, e);
        }
    }
}

function listener ( element , selector , type , callback ) { return function ( e ) { e . delegateTarget = closest_1 ( e . target , selector ) ; if ( e . delegateTarget ) { callback . call ( element , e ) ; } } }

Finds closest match and invokes callback.

@param {Element} element
@param {String} selector
@param {String} type
@param {Function} callback
@return {Function}

Finds closest match and invokes callback .


function listenNode(node, type, callback) {
    node.addEventListener(type, callback);

    return {
        destroy: function() {
            node.removeEventListener(type, callback);
        }
    }
}

function listenNode ( node , type , callback ) { node . addEventListener ( type , callback ) ; return { destroy : function ( ) { node . removeEventListener ( type , callback ) ; } } }

Adds an event listener to a HTML element
and returns a remove listener function.

@param {HTMLElement} node
@param {String} type
@param {Function} callback
@return {Object}

Adds an event listener to a HTML element and returns a remove listener function .


function listenNodeList(nodeList, type, callback) {
    Array.prototype.forEach.call(nodeList, function(node) {
        node.addEventListener(type, callback);
    });

    return {
        destroy: function() {
            Array.prototype.forEach.call(nodeList, function(node) {
                node.removeEventListener(type, callback);
            });
        }
    }
}

function listenNodeList ( nodeList , type , callback ) { Array . prototype . forEach . call ( nodeList , function ( node ) { node . addEventListener ( type , callback ) ; } ) ; return { destroy : function ( ) { Array . prototype . forEach . call ( nodeList , function ( node ) { node . removeEventListener ( type , callback ) ; } ) ; } } }

Add an event listener to a list of HTML elements
and returns a remove listener function.

@param {NodeList|HTMLCollection} nodeList
@param {String} type
@param {Function} callback
@return {Object}

Add an event listener to a list of HTML elements and returns a remove listener function .


function listenSelector(selector, type, callback) {
    return delegate_1(document.body, selector, type, callback);
}

function listenSelector ( selector , type , callback ) { return delegate_1 ( document . body , selector , type , callback ) ; }

Add an event listener to a selector
and returns a remove listener function.

@param {String} selector
@param {String} type
@param {Function} callback
@return {Object}

Add an event listener to a selector and returns a remove listener function .


function getAttributeValue(suffix, element) {
        var attribute = 'data-clipboard-' + suffix;

        if (!element.hasAttribute(attribute)) {
            return;
        }

        return element.getAttribute(attribute);
    }

function getAttributeValue ( suffix , element ) { var attribute = 'data-clipboard-' + suffix ; if ( ! element . hasAttribute ( attribute ) ) { return ; } return element . getAttribute ( attribute ) ; }

Helper function to retrieve attribute value.
@param {String} suffix
@param {Element} element

Helper function to retrieve attribute value .


function AssetLoader(manifest, loader) {
  this.assets = loadAssets(manifest, loader, function(err) {
    if (err) {
      console.error(err);
    }
  });
}

function AssetLoader ( manifest , loader ) { this . assets = loadAssets ( manifest , loader , function ( err ) { if ( err ) { console . error ( err ) ; } } ) ; }

Loads external assets, lets you track their progress, and lets you access the loaded data.
@constructor

Loads external assets lets you track their progress and lets you access the loaded data .


function FontLoader(fontFamiliesArray, delegate, timeout) {
		// Public
		this.delegate = delegate;
		this.timeout = (typeof timeout !== "undefined") ? timeout : 3000;

		// Private
		this._fontFamiliesArray = fontFamiliesArray.slice(0);
		this._testContainer = null;
		this._adobeBlankSizeWatcher = null;
		this._timeoutId = null;
		this._intervalId = null;
		this._intervalDelay = 50;
		this._numberOfLoadedFonts = 0;
		this._numberOfFontFamilies = this._fontFamiliesArray.length;
		this._fontsMap = {};
		this._finished = false;
	}

function
FontLoader
(
fontFamiliesArray
,
delegate
,
timeout
)
{
// Public
this
.
delegate
=
delegate
;
this
.
timeout
=
(
typeof
timeout
!==
"undefined"
)
timeout
:
3000
;
// Private
this
.
_fontFamiliesArray
=
fontFamiliesArray
.
slice
(
0
)
;
this
.
_testContainer
=
;
this
.
_adobeBlankSizeWatcher
=
;
this
.
_timeoutId
=
;
this
.
_intervalId
=
;
this
.
_intervalDelay
=
50
;
this
.
_numberOfLoadedFonts
=
0
;
this
.
_numberOfFontFamilies
=
this
.
_fontFamiliesArray
.
length
;
this
.
_fontsMap
=
{
}
;
this
.
_finished
=
false
;
}

FontLoader detects when web fonts specified in the "fontFamiliesArray" array were loaded and rendered. Then it
notifies the specified delegate object via "fontLoaded" and "fontsLoaded" methods when specific or all fonts were
loaded respectively. The use of this functions implies that the insertion of specified web fonts into the
document is done elsewhere.

If timeout (default 3000ms) is reached before all fonts were loaded and rendered, then "fontsLoaded" delegate
method is invoked with an error object as its single parameter. The error object has two fields: the "message"
field holding the error description and the "notLoadedFontFamilies" field holding an array with all the
font-families that weren't loaded. Otherwise the parameter is null.

@param {Array}     fontFamiliesArray       Array of font-family strings.
@param {Object}    delegate                Delegate object whose delegate methods will be invoked in its own context.
@param {Function}  [delegate.fontsLoaded]  Delegate method invoked after all fonts are loaded or timeout is reached.
@param {Function}  [delegate.fontLoaded]   Delegate method invoked for each loaded font with its font-family string as its single parameter.
@param {Number}    [timeout=3000]          Timeout in milliseconds. Pass "null" to disable timeout.
@constructor

FontLoader detects when web fonts specified in the fontFamiliesArray array were loaded and rendered . Then it notifies the specified delegate object via fontLoaded and fontsLoaded methods when specific or all fonts were loaded respectively . The use of this functions implies that the insertion of specified web fonts into the document is done elsewhere .


function(sizeWatcher) {
			var watchedElement = sizeWatcher.getWatchedElement();
			if (sizeWatcher === this._adobeBlankSizeWatcher) {
				this._adobeBlankLoaded(watchedElement);
			} else {
				this._elementSizeChanged(watchedElement);
			}
		}

function ( sizeWatcher ) { var watchedElement = sizeWatcher . getWatchedElement ( ) ; if ( sizeWatcher === this . _adobeBlankSizeWatcher ) { this . _adobeBlankLoaded ( watchedElement ) ; } else { this . _elementSizeChanged ( watchedElement ) ; } }

SizeWatcher delegate method
@param {SizeWatcher} sizeWatcher


function SizeWatcher(element, options) {
		this._element = element;
		this._delegate = options.delegate;
		this._size = null;
		this._continuous = !!options.continuous;
		this._direction = options.direction ? options.direction : SizeWatcher.directions.both;
		this._dimension = options.dimension ? options.dimension : SizeWatcher.dimensions.both;
		this._sizeIncreaseWatcherContentElm = null;
		this._sizeDecreaseWatcherElm = null;
		this._sizeIncreaseWatcherElm = null;
		this._state = SizeWatcher.states.initialized;

		this._generateScrollWatchers(options.size);
		this._appendScrollWatchersToElement(options.container);
	}

function SizeWatcher ( element , options ) { this . _element = element ; this . _delegate = options . delegate ; this . _size = null ; this . _continuous = ! ! options . continuous ; this . _direction = options . direction ? options . direction : SizeWatcher . directions . both ; this . _dimension = options . dimension ? options . dimension : SizeWatcher . dimensions . both ; this . _sizeIncreaseWatcherContentElm = null ; this . _sizeDecreaseWatcherElm = null ; this . _sizeIncreaseWatcherElm = null ; this . _state = SizeWatcher . states . initialized ; this . _generateScrollWatchers ( options . size ) ; this . _appendScrollWatchersToElement ( options . container ) ; }

SizeWatcher observes size of an element and notifies when its size is changed. It doesn't use any timeouts
to check the element size, when change in size occurs a callback method immediately invoked.

To watch for element's size changes the element, and other required elements are appended to a container element
you specify, and which must be added to the DOM tree before invoking prepareForWatch() method. Your container
element should be positioned outside of client's visible area. Therefore you shouldn't use SizeWatcher to watch
for size changes of elements used for UI.
Such container element could be a simple
 that is a child of the  element:

You must invoke SizeWatcher's methods in a specific order to establish size change listeners:

1. Create SizeWatcher instance by invoke SizeWatcher constructor passing the element (size of which you want to
observe), the container element, the delegate object and optional size parameter of type Size which should be
the pre-calculated initial size of your element.
4. Invoke prepareForWatch() method. This method will calculate element size if you didn't passed it to the constructor.
5. Invoke beginWatching() method. This method will set event listeners and invoke your delegate's method once
element size changes.

Failing to invoke above methods in their predefined order will throw an exception.

@param {HTMLElement} element An element, size of which will be observed for changes.
@param {Object}      options
@param {HTMLElement} options.container An element to which special observing elements will be added. Must be in DOM tree
when prepareForWatch() method is called.
@param {Object}      options.delegate A delegate object with a sizeWatcherChangedSize method which will be invoked, in
context of the delegate object, when change in size occurs. This method is invoked with single
parameter which is the current SizeWatcher instance.
@param {Size}        [options.size] The pre-calculated initial size of your element. When passed, the element is not
asked for offsetWidth and offsetHeight, which may be useful to reduce browser's CSS
recalculations. If you will not pass the size parameter then its size calculation will be
deferred to prepareForWatch() method.
@param {Boolean}     [options.continuous=false] A boolean flag indicating if the SizeWatcher will watch only for
the first size change (default) or will continuously watch for size changes.
@param {Number}      [options.direction=SizeWatcher.directions.both] The direction of size change that should be
watched: SizeWatcher.directions.increase, SizeWatcher.directions.decrease or
SizeWatcher.directions.both
@param {Number}      [options.dimension=SizeWatcher.dimensions.both] The dimension of size change that should be
watched: SizeWatcher.dimensions.horizontal, SizeWatcher.dimensions.vertical or
SizeWatcher.dimensions.both
@constructor

SizeWatcher observes size of an element and notifies when its size is changed . It doesn t use any timeouts to check the element size when change in size occurs a callback method immediately invoked .


function(prefab) {
    /**
     * The name of a prefab to instantiate for the particle, as defined in prefabs.json.
     * @member {string}
     */
    this.prefab = prefab;
    /**
     * The origin point in which to create particles.
     *
     * If the origin is a number it represents an entity and a random point inside the entity will be used.
     * If origin is a point like {"x": 50, "y": 50} particles will spawn at that position.
     * @member {object | number}
     */
    this.origin = { "x": 0, "y": 0 };
    /**
     * How to distribute particles along the {@link module:splat-ecs/lib/particles.Config#arcWidth arcWidth}.
     *
     * Possible values:
     *

     *
"even"

     *
Distribute the particles evenly along the arc.

     *
"random"

     *
Scatter the particles on random points of the arc.

     *

     * @member {string}
     */
    this.spreadType = "random";
    /**
     * The direction (an angle in radians) that the particles should move.
     * @member {number}
     */
    this.angle = 0;
    /**
     * The width of an arc (represented by an angle in radians) to spread the particles. The arc is centered around {@link module:splat-ecs/lib/particles.Config#angle angle}.
     * @member {number}
     */
    this.arcWidth = Math.PI / 2;
    /**
     * The minimum number of particles to create.
     * @member {number}
     */
    this.qtyMin = 1;
    /**
     * The maximum number of particles to create.
     * @member {number}
     */
    this.qtyMax = 1;
    /**
     * The minimum percentage to scale each particle.
     *

     *
A scale of 0.5 means the particle will spawn at 50% (half) of the original size.

     *
A scale of 1 means the particle will spawn at the original size.

     *
A scale of 2 means the particle will spawn at 200% (double) the original size.

     *

     * @member {number}
     */
    this.sizeMin = 1;
    /**
     * The maximum percentage to scale each particle.
     *

     *
A scale of 0.5 means the particle will spawn at 50% (half) of the original size.

     *
A scale of 1 means the particle will spawn at the original size.

     *
A scale of 2 means the particle will spawn at 200% (double) the original size.

     *

     * @member {number}
     */
    this.sizeMax = 1;
    /**
     * The minimum velocity to apply to each particle.
     * @member {number}
     */
    this.velocityMin = 0.5;
    /**
     * The maximum velocity to apply to each particle.
     * @member {number}
     */
    this.velocityMax = 0.5;
    /**
     * The acceleration on the x-axis to apply to each particle.
     * @member {number}
     */
    this.accelerationX = 0;
    /**
     * The acceleration on the y-axis to apply to each particle.
     * @member {number}
     */
    this.accelerationY = 0;
    /**
     * The minimum life span to apply to each particle.
     * @member {number}
     */
    this.lifeSpanMin = 0;
    /**
     * The maximum life span to apply to each particle.
     * @member {number}
     */
    this.lifeSpanMax = 500;
  }

/**
     * The origin point in which to create particles.
     *
     * If the origin is a number it represents an entity and a random point inside the entity will be used.
     * If origin is a point like <code>{"x": 50, "y": 50}</code> particles will spawn at that position.
     * @member {object | number}
     */

The settings for a type of particle.
@constructor
@param {string} prefab The name of a prefab to instantiate for the particle, as defined in prefabs.json.


function centerEntityOnPoint(game, entity, point) {
  var size = game.entities.getComponent(entity, "size");
  var position = game.entities.addComponent(entity, "position");
  position.x = point.x - (size.width / 2);
  position.y = point.y - (size.height / 2);
}

function centerEntityOnPoint ( game , entity , point ) { var size = game . entities . getComponent ( entity , "size" ) ; var position = game . entities . addComponent ( entity , "position" ) ; position . x = point . x - ( size . width / 2 ) ; position . y = point . y - ( size . height / 2 ) ; }

Center an entity on a given point.
@private
@param {object} game Required for game.entities.get().
@param {integer} entity The id of entity to center.
@param {object} point A point object <code>{"x": 50, "y": 50}</code> on which to center the entity.


function choosePointInEntity(game, entity) {
  var position = game.entities.getComponent(entity, "position");
  var size = game.entities.getComponent(entity, "size");
  if (size === undefined) {
    return {
      "x": position.x,
      "y": position.y
    };
  }
  return {
    "x": random.inRange(position.x, (position.x + size.width)),
    "y": random.inRange(position.y, (position.y + size.height))
  };
}

function choosePointInEntity ( game , entity ) { var position = game . entities . getComponent ( entity , "position" ) ; var size = game . entities . getComponent ( entity , "size" ) ; if ( size === undefined ) { return { "x" : position . x , "y" : position . y } ; } return { "x" : random . inRange ( position . x , ( position . x + size . width ) ) , "y" : random . inRange ( position . y , ( position . y + size . height ) ) } ; }

Choose a random point inside the bounding rectangle of an entity.
@private
@param {object} game Required for game.entities.get().
@param {integer} entity The id of entity to pick a point within.
@returns {object} an point object <code>{"x": 50, "y": 50}</code>.

Choose a random point inside the bounding rectangle of an entity .


function makeBuffer(width, height, drawFun) {
  var canvas = makeCanvas(width, height);
  var ctx = canvas.getContext("2d");
  // when image smoothing is enabled, the image gets blurred and the pixel data isn't correct even when the image shouldn't be scaled which breaks NinePatch
  if (platform.isEjecta()) {
    ctx.imageSmoothingEnabled = false;
  }
  drawFun(ctx);
  return canvas;
}

Make an invisible canvas buffer, and draw on it.
@param {number} width The width of the buffer
@param {number} height The height of the buffer
@param {drawCallback} drawFun The callback that draws on the buffer
@returns {external:canvas} The drawn buffer

Make an invisible canvas buffer and draw on it .


function flipBufferHorizontally(buffer) {
  return makeBuffer(buffer.width, buffer.height, function(context) {
    context.scale(-1, 1);
    context.drawImage(buffer, -buffer.width, 0);
  });
}

function flipBufferHorizontally ( buffer ) { return makeBuffer ( buffer . width , buffer . height , function ( context ) { context . scale ( - 1 , 1 ) ; context . drawImage ( buffer , - buffer . width , 0 ) ; } ) ; }

Make a horizonally-flipped copy of a buffer or image.
@param {external:canvas|external:image} buffer The original image
@return {external:canvas} The flipped buffer

Make a horizonally - flipped copy of a buffer or image .


function flipBufferVertically(buffer) {
  return makeBuffer(buffer.width, buffer.height, function(context) {
    context.scale(1, -1);
    context.drawImage(buffer, 0, -buffer.height);
  });
}

function flipBufferVertically ( buffer ) { return makeBuffer ( buffer . width , buffer . height , function ( context ) { context . scale ( 1 , - 1 ) ; context . drawImage ( buffer , 0 , - buffer . height ) ; } ) ; }

Make a vertically-flipped copy of a buffer or image.
@param {external:canvas|external:image} buffer The original image
@return {external:canvas} The flipped buffer

Make a vertically - flipped copy of a buffer or image .


function rotateClockwise(buffer) {
  var w = buffer.height;
  var h = buffer.width;
  var w2 = Math.floor(w / 2);
  var h2 = Math.floor(h / 2);
  return makeBuffer(w, h, function(context) {
    context.translate(w2, h2);
    context.rotate(Math.PI / 2);
    context.drawImage(buffer, -h2, -w2);
  });
}

function rotateClockwise ( buffer ) { var w = buffer . height ; var h = buffer . width ; var w2 = Math . floor ( w / 2 ) ; var h2 = Math . floor ( h / 2 ) ; return makeBuffer ( w , h , function ( context ) { context . translate ( w2 , h2 ) ; context . rotate ( Math . PI / 2 ) ; context . drawImage ( buffer , - h2 , - w2 ) ; } ) ; }

Make a copy of a buffer that is rotated 90 degrees clockwise.
@param {external:canvas|external:image} buffer The original image
@return {external:canvas} The rotated buffer

Make a copy of a buffer that is rotated 90 degrees clockwise .


function chromeStorageGet(keys, callback) {
  window.chrome.storage.sync.get(keys, function(data) {
    if (window.chrome.runtime.lastError) {
      callback(window.chrome.runtime.lastError);
    } else {
      callback(undefined, data);
    }
  });
}

function chromeStorageGet ( keys , callback ) { window . chrome . storage . sync . get ( keys , function ( data ) { if ( window . chrome . runtime . lastError ) { callback ( window . chrome . runtime . lastError ) ; } else { callback ( undefined , data ) ; } } ) ; }

A function that is called when save data has finished being retrieved.
@callback saveDataGetFinished
@param {error} err If defined, err is the error that occurred when retrieving the data.
@param {object} data The key-value pairs of data that were previously saved.

Retrieve data previously stored with {@link Splat.saveData.set}.
@alias Splat.saveData.get
@param {string | Array} keys A single key or array of key names of data items to retrieve.
@param {saveDataGetFinished} callback A callback that is called with the data when it has been retrieved.

A function that is called when save data has finished being retrieved .


function chromeStorageSet(data, callback) {
  window.chrome.storage.sync.set(data, function() {
    callback(window.chrome.runtime.lastError);
  });
}

function chromeStorageSet ( data , callback ) { window . chrome . storage . sync . set ( data , function ( ) { callback ( window . chrome . runtime . lastError ) ; } ) ; }

A function that is called when save data has finished being stored.
@callback saveDataSetFinished
@param {error} err If defined, err is the error that occurred when saving the data.

Store data for later.
@alias Splat.saveData.set
@param {object} data An object containing key-value pairs of data to save.
@param {saveDataSetFinished} callback A callback that is called when the data has finished saving.

A function that is called when save data has finished being stored .


function SoundManager(manifest) {
  /**
   * A flag signifying if sounds have been muted through {@link SoundManager#mute}.
   * @member {boolean}
   * @private
   */
  this.muted = false;
  /**
   * A key-value object that stores named looping sounds.
   * @member {object}
   * @private
   */
  this.looping = {};

  /**
   * The Web Audio API AudioContext
   * @member {external:AudioContext}
   * @private
   */
  this.context = new window.AudioContext();

  this.gainNode = this.context.createGain();
  this.gainNode.connect(this.context.destination);
  this.volume = this.gainNode.gain.value;
  this.installSafariWorkaround();
  this.assets = new AssetLoader(manifest, loadSound.bind(undefined, this.context));
}

Plays audio, tracks looping sounds, and manages volume.
This implementation uses the Web Audio API.
@constructor
@param {Object} manifest A hash where the key is the name of a sound, and the value is the URL of a sound file.

Plays audio tracks looping sounds and manages volume . This implementation uses the Web Audio API .


function (program, callback) {
    var config = configHelpers.getConfig();
    config.plugins = config.plugins || {};
    var loadPlugin = function (pluginName, cb) {
      pluginHelpers.loadPlugin(pluginName, program, cb);
    };

    Object.keys(config.plugins).forEach(loadPlugin);
    nodeHelpers.invoke(callback);
  }

function ( program , callback ) { var config = configHelpers . getConfig ( ) ; config . plugins = config . plugins || { } ; var loadPlugin = function ( pluginName , cb ) { pluginHelpers . loadPlugin ( pluginName , program , cb ) ; } ; Object . keys ( config . plugins ) . forEach ( loadPlugin ) ; nodeHelpers . invoke ( callback ) ; }

Loads all plugins.

@param program Program or Plain object.
@param callback Termination.


function (program, app, callback) {
    var attachPlugin = function (pluginName, cb) {
      pluginHelpers.start(pluginName, program, app, cb);
    };

    var plugins = Object.keys(pluginHelpers.loadedPlugins)
    async.eachSeries(plugins, attachPlugin, function() {
      callback();
    });
  }

function ( program , app , callback ) { var attachPlugin = function ( pluginName , cb ) { pluginHelpers . start ( pluginName , program , app , cb ) ; } ; var plugins = Object . keys ( pluginHelpers . loadedPlugins ) async . eachSeries ( plugins , attachPlugin , function ( ) { callback ( ) ; } ) ; }

Start all plugins.

@param program Program or Plain object.
@param app Express app.
@param callback Termination.


function (callback) {
    var plugins = Object.keys(pluginHelpers.loadedPlugins || {});
    async.eachSeries(plugins, pluginHelpers.stop, callback);
  }

function ( callback ) { var plugins = Object . keys ( pluginHelpers . loadedPlugins || { } ) ; async . eachSeries ( plugins , pluginHelpers . stop , callback ) ; }

Stop all plugins.

@param callback Termination.


function (program, callback) {
    var cozyLight = require('./cozy-light');

    applicationHelpers.resetDefaultPort();
    cozyLight.setStarted();

    // start app
    var app = express();
    var morgand = morgan('combined');
    if (expressLog) {
      app.use(morgand);
    }

    pluginHelpers.startAll(program, app, function(){
      mainAppHelper.start(app);
      applicationHelpers.startAll(function() {

        // always connect it after the proxy
        // https://github.com/nodejitsu/node-http-proxy/issues/180
        var jsonParser = bodyParser.json();
        var urlencodedParser = bodyParser.urlencoded({extended: false});
        app.use(urlencodedParser);
        app.use(jsonParser);
        nodeHelpers.invoke(callback, null, app, server);
      });
    });
  }

Apply plugin customatisation on server. Then get all installed app
modules. Expect that a start function is available, then run the app
server on given port. Ports are expected to be available.

@param {Object} program The command line options.
@param {Function} callback Termination.

Apply plugin customatisation on server . Then get all installed app modules . Expect that a start function is available then run the app server on given port . Ports are expected to be available .


function (apporplugin) {
    try {
      configHelpers.enable(apporplugin);
      logger.info(apporplugin + ' enabled');
    } catch (err) {
      logger.error(
        'Cannot enable given app or plugin, ' +
        apporplugin +
        ' cannot find it in the config file.');
    }
  }

function
(
apporplugin
)
{
try
{
configHelpers
.
enable
(
apporplugin
)
;
logger
.
info
(
apporplugin
+
' enabled'
)
;
}
catch
(
err
)
{
logger
.
error
(
'Cannot enable given app or plugin, '
+
apporplugin
+
' cannot find it in the config file.'
)
;
}
}

Remove disabled mark from config file for given app or plugin.

Remove disabled mark from config file for given app or plugin .


function (apporplugin) {
    try {
      configHelpers.disable(apporplugin);
      logger.info(apporplugin + ' disabled');
    } catch (err) {
      logger.error(
        'Cannot disable given app or plugin, ' +
        apporplugin +
        ' cannot find it in the config file.');
      logger.raw(err);
    }
  }

function
(
apporplugin
)
{
try
{
configHelpers
.
disable
(
apporplugin
)
;
logger
.
info
(
apporplugin
+
' disabled'
)
;
}
catch
(
err
)
{
logger
.
error
(
'Cannot disable given app or plugin, '
+
apporplugin
+
' cannot find it in the config file.'
)
;
logger
.
raw
(
err
)
;
}
}

Mark given app or plugin as disabled. It won't be activated or started
in that case.

Mark given app or plugin as disabled . It won t be activated or started in that case .


function (callback) {
    var cozyLight = require('./cozy-light');
    if (cozyLight.getStatus() === 'started') {
      cozyLight.setStopped();
      logger.info('Stopping apps...');
      return applicationHelpers.stopAll(function (appErr) {
        if (appErr) {
          logger.error('An error occurred while stopping applications');
          logger.raw(appErr);
        }

        logger.info('Stopping plugins...');
        pluginHelpers.stopAll(function (pluginErr) {
          if (pluginErr) {
            logger.error('An error occurred while stopping plugins');
            logger.raw(pluginErr);
          }

          logger.info('Stopping server...');
          var timeout = nodeHelpers.throwTimeout(
              'main server is too slow to stop...', 5000);

          mainAppHelper.stop(function(){
            clearTimeout(timeout);
            logger.info('\t' + symbols.ok + '\tmain server');
            nodeHelpers.invoke(callback);
          });
        });
      });
    }
    logger.debug('Apps already stopped');
    return nodeHelpers.invoke(callback);
  }

Stop all running applications.

@param {Function} callback Termination.


function (callback) {
    var cozyLight = require('./cozy-light');
    logger.info('Restarting...');

    actions.stop(function(){
      configHelpers.loadConfigFile();
      cozyLight.routes = {};

      logger.info('Starting all apps...');
      pluginHelpers.loadAll(this.program, function() {
        actions.start(this.program, function(){
          logger.info('...Cozy Light was properly restarted.');
          nodeHelpers.invoke(callback);
          actionsEvent.emit('restarted');
        });
      });
    });
  }

function
(
callback
)
{
var
cozyLight
=
require
(
'./cozy-light'
)
;
logger
.
info
(
'Restarting...'
)
;
actions
.
stop
(
function
(
)
{
configHelpers
.
loadConfigFile
(
)
;
cozyLight
.
routes
=
{
}
;
logger
.
info
(
'Starting all apps...'
)
;
pluginHelpers
.
loadAll
(
this
.
program
,
function
(
)
{
actions
.
start
(
this
.
program
,
function
(
)
{
logger
.
info
(
'...Cozy Light was properly restarted.'
)
;
nodeHelpers
.
invoke
(
callback
)
;
actionsEvent
.
emit
(
'restarted'
)
;
}
)
;
}
)
;
}
)
;
}

Stops application server, its apps, and its plugins,
reload everyone, then restart everyone

Stops application server its apps and its plugins reload everyone then restart everyone


function (app, callback) {
    var cozyLight = require('./cozy-light');
    var config = configHelpers.getConfig();
    logger.info('Uninstalling ' + app + '...');
    if (config.apps[app] === undefined) {
      logger.error(app + ' is not installed.');
      nodeHelpers.invoke(callback, true);
    } else {
      var module = config.apps[app].name;
      npmHelpers.uninstall(module, function removeAppFromConfig (err) {
        if (err) {
          logger.raw(err);
          logger.error('npm did not uninstall ' + app + ' correctly.');
          nodeHelpers.invoke(callback, err);
        } else {
          logger.info(app + ' successfully uninstalled.');
          configHelpers.watcher.one(callback);
          configHelpers.removeApp(app);
        }
      });
    }
  }

function
(
app
,
callback
)
{
var
cozyLight
=
require
(
'./cozy-light'
)
;
var
config
=
configHelpers
.
getConfig
(
)
;
logger
.
info
(
'Uninstalling '
+
app
+
'...'
)
;
if
(
config
.
apps
[
app
]
===
undefined
)
{
logger
.
error
(
app
+
' is not installed.'
)
;
nodeHelpers
.
invoke
(
callback
,
true
)
;
}
else
{
var
module
=
config
.
apps
[
app
]
.
name
;
npmHelpers
.
uninstall
(
module
,
function
removeAppFromConfig
(
err
)
{
if
(
err
)
{
logger
.
raw
(
err
)
;
logger
.
error
(
'npm did not uninstall '
+
app
+
' correctly.'
)
;
nodeHelpers
.
invoke
(
callback
,
err
)
;
}
else
{
logger
.
info
(
app
+
' successfully uninstalled.'
)
;
configHelpers
.
watcher
.
one
(
callback
)
;
configHelpers
.
removeApp
(
app
)
;
}
}
)
;
}
}

Remove app from config and its source from node module folder.

@param {String} app App to uninstall.
@param {Function} callback Termination.

Remove app from config and its source from node module folder .


function (plugin, callback){
    var cozyLight = require('./cozy-light');
    var config = configHelpers.getConfig();
    logger.info('Removing ' + plugin + '...');

    if (config.plugins[plugin] === undefined) {
      logger.error(plugin + ' is not installed.');
      nodeHelpers.invoke(callback, true);

    } else {
      var module = config.plugins[plugin].name;
      npmHelpers.uninstall(module, function removePluginFromConfig (err) {

        if (err) {
          logger.raw(err);
          logger.error('npm did not uninstall ' + plugin + ' correctly.');
          nodeHelpers.invoke(callback, err);

        } else {
          logger.info(plugin + ' successfully uninstalled.');
          pluginHelpers.stop(plugin, function(){
            pluginHelpers.unloadPlugin(plugin);
            configHelpers.watcher.one(callback);
            configHelpers.removePlugin(plugin);
          });
        }
      });
    }
  }

function
(
plugin
,
callback
)
{
var
cozyLight
=
require
(
'./cozy-light'
)
;
var
config
=
configHelpers
.
getConfig
(
)
;
logger
.
info
(
'Removing '
+
plugin
+
'...'
)
;
if
(
config
.
plugins
[
plugin
]
===
undefined
)
{
logger
.
error
(
plugin
+
' is not installed.'
)
;
nodeHelpers
.
invoke
(
callback
,
true
)
;
}
else
{
var
module
=
config
.
plugins
[
plugin
]
.
name
;
npmHelpers
.
uninstall
(
module
,
function
removePluginFromConfig
(
err
)
{
if
(
err
)
{
logger
.
raw
(
err
)
;
logger
.
error
(
'npm did not uninstall '
+
plugin
+
' correctly.'
)
;
nodeHelpers
.
invoke
(
callback
,
err
)
;
}
else
{
logger
.
info
(
plugin
+
' successfully uninstalled.'
)
;
pluginHelpers
.
stop
(
plugin
,
function
(
)
{
pluginHelpers
.
unloadPlugin
(
plugin
)
;
configHelpers
.
watcher
.
one
(
callback
)
;
configHelpers
.
removePlugin
(
plugin
)
;
}
)
;
}
}
)
;
}
}

Remove plugin from config and its source from node module folder.

@param {String} plugin Plugin to remove.
@param {Function} callback Termination.

Remove plugin from config and its source from node module folder .


function (distroName, actions, callback) {
    if (distros[distroName] !== undefined) {
      var distro = distros[distroName];
      logger.info('Installing plugins...');
      async.eachSeries(distro.plugins, function addPlugin (pluginName, cb) {
        actions.installPlugin(pluginName, cb);
      }, function installApps (err) {
        if (err) {
          callback(err);
        } else {
          logger.info('Installing apps...');
          async.eachSeries(distro.apps, function addApp (appName, cb) {
            actions.installApp(appName, cb);
          }, callback);
        }
      });
    } else {
      throw new Error('Unknown distro, can\'t install it');
    }
  }

function
(
distroName
,
actions
,
callback
)
{
if
(
distros
[
distroName
]
!==
undefined
)
{
var
distro
=
distros
[
distroName
]
;
logger
.
info
(
'Installing plugins...'
)
;
async
.
eachSeries
(
distro
.
plugins
,
function
addPlugin
(
pluginName
,
cb
)
{
actions
.
installPlugin
(
pluginName
,
cb
)
;
}
,
function
installApps
(
err
)
{
if
(
err
)
{
callback
(
err
)
;
}
else
{
logger
.
info
(
'Installing apps...'
)
;
async
.
eachSeries
(
distro
.
apps
,
function
addApp
(
appName
,
cb
)
{
actions
.
installApp
(
appName
,
cb
)
;
}
,
callback
)
;
}
}
)
;
}
else
{
throw
new
Error
(
'Unknown distro, can\'t install it'
)
;
}
}

Install a full suite of application and plugins listed in given distro.

@param {String} distroName The name of the distribution to install.

Install a full suite of application and plugins listed in given distro .


function (distroName) {
    logger.raw('\n\x1B[36m* ' + distroName + '\x1B[39m');

    var logAttributeList = function (key) {
      logger.raw('    \x1B[32m' + key + ':\x1B[39m');
      var list = distros[distroName][key];
      if (list !== undefined && list.length > 0) {
        list.forEach(function displayListElement (keyName) {
          logger.raw('        - ' + keyName.split('/')[1]);
        });
      } else {
        logger.raw('        no ' + key);
      }
    };

    logAttributeList('plugins');
    logAttributeList('apps');
  }

function
(
distroName
)
{
logger
.
raw
(
'\n\x1B[36m* '
+
distroName
+
'\x1B[39m'
)
;
var
logAttributeList
=
function
(
key
)
{
logger
.
raw
(
'    \x1B[32m'
+
key
+
':\x1B[39m'
)
;
var
list
=
distros
[
distroName
]
[
key
]
;
if
(
list
!==
undefined
&&
list
.
length
>
0
)
{
list
.
forEach
(
function
displayListElement
(
keyName
)
{
logger
.
raw
(
'        - '
+
keyName
.
split
(
'/'
)
[
1
]
)
;
}
)
;
}
else
{
logger
.
raw
(
'        no '
+
key
)
;
}
}
;
logAttributeList
(
'plugins'
)
;
logAttributeList
(
'apps'
)
;
}

Display given distro plugins and apps.

@param {String} distroName The name of the distribution to display.


function saveWallet(filename, walletData) {
  return new Promise((resolve, reject) => {
    fs.writeFile(filename, JSON.stringify(walletData, null, 2), function(err) {
      if (err) return reject(console.error(err))

      //console.log(`${name}.json written successfully.`)
      return resolve()
    })
  })
}


function openWallet(filename) {
  try {
    // Delete the cached copy of the wallet. This allows testing of list-wallets.
    delete require.cache[require.resolve(filename)]

    const walletInfo = require(filename)
    return walletInfo
  } catch (err) {
    throw new Error(`Could not open ${filename}`)
  }
}


function changeAddrFromMnemonic(walletInfo, index, BITBOX) {
  // root seed buffer
  const rootSeed = BITBOX.Mnemonic.toSeed(walletInfo.mnemonic)

  // master HDNode
  if (walletInfo.network === "testnet")
    var masterHDNode = BITBOX.HDNode.fromSeed(rootSeed, "testnet")
  else var masterHDNode = BITBOX.HDNode.fromSeed(rootSeed)

  // HDNode of BIP44 account
  const account = BITBOX.HDNode.derivePath(masterHDNode, "m/44'/145'/0'")

  // derive the first external change address HDNode which is going to spend utxo
  const change = BITBOX.HDNode.derivePath(account, `0/${index}`)

  return change
}

Generate a change address from a Mnemonic of a private key.

Generate a change address from a Mnemonic of a private key .


async function getUTXOs(walletInfo, BITBOX) {
  try {
    const retArray = []

    // Loop through each address that has a balance.
    for (var i = 0; i < walletInfo.hasBalance.length; i++) {
      const thisAddr = walletInfo.hasBalance[i].cashAddress

      // Get the UTXOs for that address.
      const u = await BITBOX.Address.utxo([thisAddr])
      //console.log(`u for ${thisAddr}: ${util.inspect(u[0])}`)

      // Loop through each UXTO returned
      for (var j = 0; j < u[0].length; j++) {
        const thisUTXO = u[0][j]
        //console.log(`thisUTXO: ${util.inspect(thisUTXO)}`)

        // Add the HD node index to the UTXO for use later.
        thisUTXO.hdIndex = walletInfo.hasBalance[i].index

        // Add the UTXO to the array if it has at least one confirmation.
        if (thisUTXO.confirmations > 0) retArray.push(thisUTXO)
      }
    }

    return retArray
  } catch (err) {
    console.log(`Error in getUTXOs.`)
    throw err
  }
}

Returns an array of UTXO objects. These objects contain the metadata needed to optimize the selection of a UTXO for spending.

Returns an array of UTXO objects . These objects contain the metadata needed to optimize the selection of a UTXO for spending .


function (cozyHome, port) {
    fs.mkdirsSync(cozyHome);

    configHelpers.setHomePath(cozyHome);
    configHelpers.setMainAppPort(parseInt(port));
    configHelpers.setDefaultAppsPort(parseInt(port) + 100);

    configHelpers.copyDependency('pouchdb');

    configHelpers.createConfigFile();
    configHelpers.watcher = configWatcher;
    configHelpers.watcher.init(configHelpers.getConfigPath());

    return configHelpers.loadConfigFile();
  }

function ( cozyHome , port ) { fs . mkdirsSync ( cozyHome ) ; configHelpers . setHomePath ( cozyHome ) ; configHelpers . setMainAppPort ( parseInt ( port ) ) ; configHelpers . setDefaultAppsPort ( parseInt ( port ) + 100 ) ; configHelpers . copyDependency ( 'pouchdb' ) ; configHelpers . createConfigFile ( ) ; configHelpers . watcher = configWatcher ; configHelpers . watcher . init ( configHelpers . getConfigPath ( ) ) ; return configHelpers . loadConfigFile ( ) ; }


function () {
   var filePath = configHelpers.getConfigPath();
   config = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
   return config;
  }

function ( ) { var filePath = configHelpers . getConfigPath ( ) ; config = JSON . parse ( fs . readFileSync ( filePath , 'utf-8' ) ) ; return config ; }

Load config file

@return {Object} config


function () {
    var configString = JSON.stringify(config, null, 2);
    fs.writeFileSync(configHelpers.getConfigPath(), configString);
  }

function ( ) { var configString = JSON . stringify ( config , null , 2 ) ; fs . writeFileSync ( configHelpers . getConfigPath ( ) , configString ) ; }


function () {
    var exists = fs.existsSync(configHelpers.getConfigPath());
    if (!exists) {
      config = { apps: {}, plugins: {} };
      configHelpers.saveConfig();
    }
  }

function ( ) { var exists = fs . existsSync ( configHelpers . getConfigPath ( ) ) ; if ( ! exists ) { config = { apps : { } , plugins : { } } ; configHelpers . saveConfig ( ) ; } }


function (name) {
    var destPath = configHelpers.modulePath(name);
    var sourcePath = pathExtra.join(__dirname, '..', 'node_modules', name);

    if (!fs.existsSync(destPath)) {
      fs.copySync(sourcePath, destPath);
    }
  }

function ( name ) { var destPath = configHelpers . modulePath ( name ) ; var sourcePath = pathExtra . join ( __dirname , '..' , 'node_modules' , name ) ; if ( ! fs . existsSync ( destPath ) ) { fs . copySync ( sourcePath , destPath ) ; } }

Copy given dependency to app folder to avoid apps to fetch and rebuild it
every time it's required as dependency.
Most dependencies are common and can be reused.

Copy given dependency to app folder to avoid apps to fetch and rebuild it every time it s required as dependency . Most dependencies are common and can be reused .


function (app, manifest) {
    if (manifest.type === undefined) {
      manifest.type = 'classic';
    }
    config.apps[app] = {
      name: manifest.name,
      displayName: manifest.displayName,
      version: manifest.version,
      description: manifest.description,
      type: manifest.type
    };
    configHelpers.saveConfig();
  }

function ( app , manifest ) { if ( manifest . type === undefined ) { manifest . type = 'classic' ; } config . apps [ app ] = { name : manifest . name , displayName : manifest . displayName , version : manifest . version , description : manifest . description , type : manifest . type } ; configHelpers . saveConfig ( ) ; }

Add a new application to the configuration file.
The configuration file is written in JSON.
It adds an entry to the apps field.
Name, display name, version and description are required.

@param {String} app The app name as it's typed by the user (user/repo).
@param {Object} manifest Manifest containing application fields.

Add a new application to the configuration file . The configuration file is written in JSON . It adds an entry to the apps field . Name display name version and description are required .


function (app) {
    var ret = false;
    if (config.apps[app] !== undefined) {
      delete config.apps[app];
      configHelpers.saveConfig();
      ret = true;
    }
    return ret;
  }

function ( app ) { var ret = false ; if ( config . apps [ app ] !== undefined ) { delete config . apps [ app ] ; configHelpers . saveConfig ( ) ; ret = true ; } return ret ; }

Remove given application from the configuration file.
The configuration file is written in JSON.

@param {String} app The app name as it's typed by the user (user/repo).

Remove given application from the configuration file . The configuration file is written in JSON .


function (plugin, manifest) {
    if (config.plugins === undefined) {
      config.plugins = {};
    }

    config.plugins[plugin] = {
      name: manifest.name,
      displayName: manifest.displayName,
      version: manifest.version,
      description: manifest.description
    };
    configHelpers.saveConfig();
  }

function ( plugin , manifest ) { if ( config . plugins === undefined ) { config . plugins = { } ; } config . plugins [ plugin ] = { name : manifest . name , displayName : manifest . displayName , version : manifest . version , description : manifest . description } ; configHelpers . saveConfig ( ) ; }

Add a new plugin to the configuration file.
The configuration file is written in JSON.
It adds an entry to the plugins field.
Name, display name, version and description are required.

@param {String} plugin The plugin name as it's typed by the user.
It s in the form user/repo.
@param {Object} manifest Manifest containing plugin fields.

Add a new plugin to the configuration file . The configuration file is written in JSON . It adds an entry to the plugins field . Name display name version and description are required .


function (plugin) {
    var ret = false;
    if (config.plugins[plugin] !== undefined) {
      delete config.plugins[plugin];
      configHelpers.saveConfig();
      ret = true;
    }
    return ret;
  }

function ( plugin ) { var ret = false ; if ( config . plugins [ plugin ] !== undefined ) { delete config . plugins [ plugin ] ; configHelpers . saveConfig ( ) ; ret = true ; } return ret ; }

Remove given plugin from the configuration file.

@param {String} plugin The plugin name as it's typed by the user
(user/repo).

Remove given plugin from the configuration file .


function (apporplugin) {
    if (config.plugins[apporplugin] !== undefined) {
      config.plugins[apporplugin].disabled = undefined;
      configHelpers.saveConfig();
    } else if (config.apps[apporplugin] !== undefined) {
      config.apps[apporplugin].disabled = undefined;
      configHelpers.saveConfig();
    } else {
      throw new Error(
        'Cannot enable, given app or plugin ' +
        apporplugin +
        ' is not configured.');
    }
  }

function
(
apporplugin
)
{
if
(
config
.
plugins
[
apporplugin
]
!==
undefined
)
{
config
.
plugins
[
apporplugin
]
.
disabled
=
undefined
;
configHelpers
.
saveConfig
(
)
;
}
else
if
(
config
.
apps
[
apporplugin
]
!==
undefined
)
{
config
.
apps
[
apporplugin
]
.
disabled
=
undefined
;
configHelpers
.
saveConfig
(
)
;
}
else
{
throw
new
Error
(
'Cannot enable, given app or plugin '
+
apporplugin
+
' is not configured.'
)
;
}
}

Remove from given app or plugin the disabled field.

@param {String} apporplugin The plugin/app name
as it's typed by the user.

Remove from given app or plugin the disabled field .


function () {
    var plugins = {};
    Object.keys(config.plugins || {}).forEach(function(name){
      var template = '';
      //if (loadedPlugins[name] && loadedPlugins[name].getTemplate) {
      //  template = loadedPlugins[name].getTemplate(config);
      //}
      plugins[name] = {
        name: config.plugins[name].name,
        displayName: config.plugins[name].displayName,
        version: config.plugins[name].version,
        template: template
      };
    });
    return plugins;
  }

Prepare plugins to be sent as json file to the web UI.

@returns {Object}

Prepare plugins to be sent as json file to the web UI .


function () {
    var apps = {};
    var baseUrl = configHelpers.getServerUrl();
    Object.keys(config.apps || {}).forEach(function(name){
      apps[name] = {
        name: config.apps[name].name,
        displayName: config.apps[name].displayName,
        version: config.apps[name].version,
        url: baseUrl + '/apps/' + config.apps[name].name + '/'
      };
    });
    return apps;
  }

function ( ) { var apps = { } ; var baseUrl = configHelpers . getServerUrl ( ) ; Object . keys ( config . apps || { } ) . forEach ( function ( name ) { apps [ name ] = { name : config . apps [ name ] . name , displayName : config . apps [ name ] . displayName , version : config . apps [ name ] . version , url : baseUrl + '/apps/' + config . apps [ name ] . name + '/' } ; } ) ; return apps ; }

Prepare apps to be sent as json file to the web UI.

@returns {Object}

Prepare apps to be sent as json file to the web UI .


function (app, callback) {
    var options = {
      local: true,
      dir: configHelpers.getModulesPath(),
      prefix: ''
    };
    npm.load(options, function () {
      app = pathExtra.resolve(npmHelpers.initialWd, app);
      npm.commands.link([app], callback);
    });
  }

function ( app , callback ) { var options = { local : true , dir : configHelpers . getModulesPath ( ) , prefix : '' } ; npm . load ( options , function ( ) { app = pathExtra . resolve ( npmHelpers . initialWd , app ) ; npm . commands . link ( [ app ] , callback ) ; } ) ; }

Link given app source and dependencies from local file system.

@param {String} app Path to the module to link.
@param {Function} callback Callback to run once work is done.

Link given app source and dependencies from local file system .


function (app, callback) {
    var options = {
      dir: configHelpers.getModulesPath(),
      prefix: ''
    };
    npm.load(options, function () {
      npm.commands.uninstall([app], callback);
    });
  }

function ( app , callback ) { var options = { dir : configHelpers . getModulesPath ( ) , prefix : '' } ; npm . load ( options , function ( ) { npm . commands . uninstall ( [ app ] , callback ) ; } ) ; }

Remove application source and dependencies using NPM lib.

@param {String} app App to fetch from NPM.
@param {Function} callback Callback to run once work is done.

Remove application source and dependencies using NPM lib .


function (app, callback) {
    var appPath = pathExtra.resolve(npmHelpers.initialWd, app);
    var manifestPath = pathExtra.join(appPath, 'package.json');

    if (fs.existsSync(appPath) && fs.existsSync(manifestPath)) {
      fs.readFile(manifestPath, function checkError (err, manifest) {
        if (err) {
          logger.error(err);
          nodeHelpers.invoke(callback, err);
        } else {
          nodeHelpers.invoke(callback, err, JSON.parse(manifest), 'file');
        }
      });
    } else {
      var client = request.newClient('https://raw.githubusercontent.com/');
      /* Checking if a branch of the github repo is specified
       * within the application path parameter (separated with a @).
       */
      if (app.indexOf('@') > 1) {
        // if a branch is specified, we build the url with it.
        var manifestUrl = app.split('@')[0] + '/' + app.split('@')[1] +  '/package.json';
      } else {
        // if no branch is specified, we build the url with master branch.
        var manifestUrl = app + '/master/package.json';
      }
      console.log(manifestUrl);

      client.get(manifestUrl, function (err, res, manifest) {
        if (err) {
          logger.error(err);
          nodeHelpers.invoke(callback, err);
        } else if (res.statusCode !== 200) {
          logger.error(err);
          nodeHelpers.invoke(callback, err);
        } else {
          nodeHelpers.invoke(callback, err, manifest, 'url');
        }
      });
    }
  }

Fetch application or plugin manifest from an url or a path

@param {String} app App or Plugin name to fetch from url or path.
@param {Function} callback Termination.


function (msg) {
    // Convert binary blobs into native buffers pre-send
    if (msg && msg.message && msg.message.message &&
        msg.message.message.binary) {
      var out = [], i = 0;
      for (i = 0; i < msg.message.message.binary.length; i += 1) {
        out.push(new Buffer(new Uint8Array(msg.message.message.binary[i])));
      }
      msg.message.message.binary = out;
    }
    process.send(msg);
  }

postMessage - sending messages out of the module.

postMessage - sending messages out of the module .


function (script) {
    var file, name;
    try {
      //TODO: enforce constrained location of loaded files.
      if (script.indexOf('node://') === 0) {
        name = script.substr(7);
      }
      file = fs.readFileSync(name);
      vm.runInContext(file, freedomVM, name);
    } catch (e) {
      console.error(e);
      process.exit(1);
    }
  }

importScripts - Loading code into the module.

importScripts - Loading code into the module .


function sortPitches (pitches) {
  return pitches.map(Pitch).sort(function (a, b) {
    return a - b
  }).map(function (pitch) {
    return pitch.sciPitch()
  })
}

function sortPitches ( pitches ) { return pitches . map ( Pitch ) . sort ( function ( a , b ) { return a - b } ) . map ( function ( pitch ) { return pitch . sciPitch ( ) } ) }

helper function to sort an array of pitches from lowest to highest
@param {string[]} pitches - an array of pitch strings
@returns {string[]} a new clone of the provided pitch string
array sorted from low pitch to high pitch


function parseNavItem (item) {
        if (item.route === req.path) {
            item.isActive = true;
        }

        // replace object by array structure
        var childArray = [];
        for (var child in item.children) {
            var subItem = parseNavItem( item.children[ child ] );
            if (subItem.isActive || subItem.hasActiveChildren) {
                item.hasActiveChildren = true;
            }
            // check if user can access item
            if (userHasAccess(subItem)) {
                childArray.push(subItem);
            }
        }
        // sort by _w
        childArray.sort(function (a, b) { return a._w - b._w });
        item.children = childArray;

        return item;
    }

function
parseNavItem
(
item
)
{
if
(
item
.
route
===
req
.
path
)
{
item
.
isActive
=
true
;
}
// replace object by array structure
var
childArray
=
[
]
;
for
(
var
child
in
item
.
children
)
{
var
subItem
=
parseNavItem
(
item
.
children
[
child
]
)
;
if
(
subItem
.
isActive
||
subItem
.
hasActiveChildren
)
{
item
.
hasActiveChildren
=
true
;
}
// check if user can access item
if
(
userHasAccess
(
subItem
)
)
{
childArray
.
push
(
subItem
)
;
}
}
// sort by _w
childArray
.
sort
(
function
(
a
,
b
)
{
return
a
.
_w
b
.
_w
}
)
;
item
.
children
=
childArray
;
return
item
;
}

Method recursively iterates over items and adds `isActive` and `hasActiveChild` fields

Method recursively iterates over items and adds isActive and hasActiveChild fields


function userHasAccess (item) {
       if (typeof item.isSecure !== 'boolean' || item.isSecure === false) {
           // page has no security settings or false, let user pass
           return true;
       } else {
           // page is secured, check if user has access
           var pageRoles = item.roles;
           debug('pageRoles', item.title, pageRoles)

           if (Array.isArray(pageRoles) && pageRoles.length === 0) {
               // page is secured, but requires no specific role
               if (req.session.user) {
                   // user is authenticated, let pass
                   return true;
               } else {
                   // user is not authenticated, reject
                   return false
               }
           }

           if (!req.session.user || !req.session.user.roleIds) {
               // user session does not exist, skip
               return false;
           }

           // make sure roleIds are strings (on first request they are objects)
           var userRoles = [];
           var sessionRoleIds = req.session.user.roleIds;
           for (var r in sessionRoleIds) {
               userRoles.push(sessionRoleIds[r].toString());
           }

           // compare required roles and user roles
           for (var r in pageRoles) {
               var pageRoleId = pageRoles[r].toString();
               if (userRoles.indexOf(pageRoleId) !== -1) {
                   // user has role, let pass
                   return true;
               }
           }
       }
       // all pass rules failed, reject user
       return false;
   }

Returns true if user is allowed to see page


function(scope){
			if(!scope) throw('textAngular Error: A toolbar requires a scope');
			if(!scope.name || scope.name === '') throw('textAngular Error: A toolbar requires a name');
			if(toolbars[scope.name]) throw('textAngular Error: A toolbar with name "' + scope.name + '" already exists');
			toolbars[scope.name] = scope;
			angular.forEach(editors, function(_editor){
				_editor._registerToolbar(scope);
			});
		}

registers a toolbar such that it can be linked to editors


function(name){
			var result = [], _this = this;
			angular.forEach(this.retrieveEditor(name).toolbars, function(name){
				result.push(_this.retrieveToolbar(name));
			});
			return result;
		}

function ( name ) { var result = [ ] , _this = this ; angular . forEach ( this . retrieveEditor ( name ) . toolbars , function ( name ) { result . push ( _this . retrieveToolbar ( name ) ) ; } ) ; return result ; }

retrieve toolbars by editor name, largely used by testing suites only

retrieve toolbars by editor name largely used by testing suites only


function(newTaTools){
			// pass a partial struct of the taTools, this allows us to update the tools on the fly, will not change the defaults.
			var _this = this;
			angular.forEach(newTaTools, function(_newTool, key){
				_this.updateToolDisplay(key, _newTool);
			});
		}

functions for updating the toolbar buttons display


function(toolKey, _newTool){
			var _this = this;
			angular.forEach(toolbars, function(toolbarScope, toolbarKey){
				_this.updateToolbarToolDisplay(toolbarKey, toolKey, _newTool);
			});
		}

function ( toolKey , _newTool ) { var _this = this ; angular . forEach ( toolbars , function ( toolbarScope , toolbarKey ) { _this . updateToolbarToolDisplay ( toolbarKey , toolKey , _newTool ) ; } ) ; }


function(toolbarKey, toolKey, _newTool){
			if(toolbars[toolbarKey]) toolbars[toolbarKey].updateToolDisplay(toolKey, _newTool);
			else throw('textAngular Error: No Toolbar with name "' + toolbarKey + '" exists');
		}


function(toolbarKey, toolKey){
			if(toolbars[toolbarKey]) toolbars[toolbarKey].updateToolDisplay(toolKey, taTools[toolKey], true);
			else throw('textAngular Error: No Toolbar with name "' + toolbarKey + '" exists');
		}

reset a tool on a specific toolbar to it's default starting value

reset a tool on a specific toolbar to it s default starting value


function(toolKey){
			delete taTools[toolKey];
			angular.forEach(toolbars, function(toolbarScope){
				delete toolbarScope.tools[toolKey];
				for(var i = 0; i < toolbarScope.toolbar.length; i++){
					var toolbarIndex;
					for(var j = 0; j < toolbarScope.toolbar[i].length; j++){
						if(toolbarScope.toolbar[i][j] === toolKey){
							toolbarIndex = {
								group: i,
								index: j
							};
							break;
						}
						if(toolbarIndex !== undefined) break;
					}
					if(toolbarIndex !== undefined){
						toolbarScope.toolbar[toolbarIndex.group].slice(toolbarIndex.index, 1);
						toolbarScope._$element.children().eq(toolbarIndex.group).children().eq(toolbarIndex.index).remove();
					}
				}
			});
		}

function ( toolKey ) { delete taTools [ toolKey ] ; angular . forEach ( toolbars , function ( toolbarScope ) { delete toolbarScope . tools [ toolKey ] ; for ( var i = 0 ; i < toolbarScope . toolbar . length ; i ++ ) { var toolbarIndex ; for ( var j = 0 ; j < toolbarScope . toolbar [ i ] . length ; j ++ ) { if ( toolbarScope . toolbar [ i ] [ j ] === toolKey ) { toolbarIndex = { group : i , index : j } ; break ; } if ( toolbarIndex !== undefined ) break ; } if ( toolbarIndex !== undefined ) { toolbarScope . toolbar [ toolbarIndex . group ] . slice ( toolbarIndex . index , 1 ) ; toolbarScope . _$element . children ( ) . eq ( toolbarIndex . group ) . children ( ) . eq ( toolbarIndex . index ) . remove ( ) ; } } } ) ; }

removes a tool from all toolbars and it's definition

removes a tool from all toolbars and it s definition


function(toolKey, toolDefinition, group, index){
			taRegisterTool(toolKey, toolDefinition);
			angular.forEach(toolbars, function(toolbarScope){
				toolbarScope.addTool(toolKey, toolDefinition, group, index);
			});
		}

function ( toolKey , toolDefinition , group , index ) { taRegisterTool ( toolKey , toolDefinition ) ; angular . forEach ( toolbars , function ( toolbarScope ) { toolbarScope . addTool ( toolKey , toolDefinition , group , index ) ; } ) ; }

toolkey, toolDefinition are required. If group is not specified will pick the last group, if index isnt defined will append to group

toolkey toolDefinition are required . If group is not specified will pick the last group if index isnt defined will append to group


function(toolKey, toolDefinition, toolbarKey, group, index){
			taRegisterTool(toolKey, toolDefinition);
			toolbars[toolbarKey].addTool(toolKey, toolDefinition, group, index);
		}

function ( toolKey , toolDefinition , toolbarKey , group , index ) { taRegisterTool ( toolKey , toolDefinition ) ; toolbars [ toolbarKey ] . addTool ( toolKey , toolDefinition , group , index ) ; }

adds a Tool but only to one toolbar not all


function(element, attribute){
			var resultingElements = [];
			var childNodes = element.children();
			if(childNodes.length){
				angular.forEach(childNodes, function(child){
					resultingElements = resultingElements.concat(taDOM.getByAttribute(angular.element(child), attribute));
				});
			}
			if(element.attr(attribute) !== undefined) resultingElements.push(element);
			return resultingElements;
		}

function ( element , attribute ) { var resultingElements = [ ] ; var childNodes = element . children ( ) ; if ( childNodes . length ) { angular . forEach ( childNodes , function ( child ) { resultingElements = resultingElements . concat ( taDOM . getByAttribute ( angular . element ( child ) , attribute ) ) ; } ) ; } if ( element . attr ( attribute ) !== undefined ) resultingElements . push ( element ) ; return resultingElements ; }

recursive function that returns an array of angular.elements that have the passed attribute set on them

recursive function that returns an array of angular . elements that have the passed attribute set on them


function (elem, eventName, callback) {
		var listener = function (event) {
			event = event || window.event;
			var target = event.target || event.srcElement;
			var block = callback.apply(elem, [event, target]);
			if (block === false) {
				if (!!event.preventDefault) event.preventDefault();
				else {
					event.returnValue = false;
					event.cancelBubble = true;
				}
			}
			return block;
		};
		if (elem.attachEvent) { // IE only.  The "on" is mandatory.
			elem.attachEvent("on" + eventName, listener);
		} else { // Other browsers.
			elem.addEventListener(eventName, listener, false);
		}
		return listener;
	}

function
(
elem
,
eventName
,
callback
)
{
var
listener
=
function
(
event
)
{
event
=
event
||
window
.
event
;
var
target
=
event
.
target
||
event
.
srcElement
;
var
block
=
callback
.
apply
(
elem
,
[
event
,
target
]
)
;
if
(
block
===
false
)
{
if
(
!
!
event
.
preventDefault
)
event
.
preventDefault
(
)
;
else
{
event
.
returnValue
=
false
;
event
.
cancelBubble
=
true
;
}
}
return
block
;
}
;
if
(
elem
.
attachEvent
)
{
// IE only.  The "on" is mandatory.
elem
.
attachEvent
(
"on"
+
eventName
,
listener
)
;
}
else
{
// Other browsers.
elem
.
addEventListener
(
eventName
,
listener
,
false
)
;
}
return
listener
;
}

Adds a listener callback to a DOM element which is fired on a specified event.  Callback is sent the event object and the element that triggered the event

Adds a listener callback to a DOM element which is fired on a specified event . Callback is sent the event object and the element that triggered the event


function (elem, event, listener) {
		if (elem.detachEvent) {	// IE only.  The "on" is mandatory.
			elem.detachEvent("on" + event, listener);
		} else { // Other browsers.
			elem.removeEventListener(event, listener, false);
		}
	}

function
(
elem
,
event
,
listener
)
{
if
(
elem
.
detachEvent
)
{
// IE only.  The "on" is mandatory.
elem
.
detachEvent
(
"on"
+
event
,
listener
)
;
}
else
{
// Other browsers.
elem
.
removeEventListener
(
event
,
listener
,
false
)
;
}
}

Removes a listener callback from a DOM element which is fired on a specified event.

Removes a listener callback from a DOM element which is fired on a specified event .


function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) {
        var milliseconds = duration._milliseconds,
            days = duration._days,
            months = duration._months,
            minutes,
            hours,
            currentDate;

        if (milliseconds) {
            mom._d.setTime(+mom._d + milliseconds * isAdding);
        }
        // store the minutes and hours so we can restore them
        if (days || months) {
            minutes = mom.minute();
            hours = mom.hour();
        }
        if (days) {
            mom.date(mom.date() + days * isAdding);
        }
        if (months) {
            mom.month(mom.month() + months * isAdding);
        }
        if (milliseconds && !ignoreUpdateOffset) {
            moment.updateOffset(mom);
        }
        // restore the minutes and hours after possibly changing dst
        if (days || months) {
            mom.minute(minutes);
            mom.hour(hours);
        }
    }

helper function for _.addTime and _.subtractTime

helper function for _ . addTime and _ . subtractTime


function getLangDefinition(key) {
        if (!key) {
            return moment.fn._lang;
        }
        if (!languages[key] && hasModule) {
            try {
                require('./lang/' + key);
            } catch (e) {
                // call with no params to set to default
                return moment.fn._lang;
            }
        }
        return languages[key];
    }

Determines which language definition to use and returns it.  With no parameters, it will return the global language.  If you pass in a language key, such as 'en', it will return the definition for 'en', so long as 'en' has already been loaded using moment.lang.

Determines which language definition to use and returns it . With no parameters it will return the global language . If you pass in a language key such as en it will return the definition for en so long as en has already been loaded using moment . lang .


function formatMoment(m, format) {
        var i = 5;

        function replaceLongDateFormatTokens(input) {
            return m.lang().longDateFormat(input) || input;
        }

        while (i-- && localFormattingTokens.test(format)) {
            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
        }

        if (!formatFunctions[format]) {
            formatFunctions[format] = makeFormatFunction(format);
        }

        return formatFunctions[format](m);
    }

function formatMoment ( m , format ) { var i = 5 ; function replaceLongDateFormatTokens ( input ) { return m . lang ( ) . longDateFormat ( input ) || input ; } while ( i -- && localFormattingTokens . test ( format ) ) { format = format . replace ( localFormattingTokens , replaceLongDateFormatTokens ) ; } if ( ! formatFunctions [ format ] ) { formatFunctions [ format ] = makeFormatFunction ( format ) ; } return formatFunctions [ format ] ( m ) ; }


function addTimeToArrayFromToken(token, input, config) {
        var a, datePartArray = config._a;

        switch (token) {
        // MONTH
        case 'M' : // fall through to MM
        case 'MM' :
            datePartArray[1] = (input == null) ? 0 : ~~input - 1;
            break;
        case 'MMM' : // fall through to MMMM
        case 'MMMM' :
            a = getLangDefinition(config._l).monthsParse(input);
            // if we didn't find a month name, mark the date as invalid.
            if (a != null) {
                datePartArray[1] = a;
            } else {
                config._isValid = false;
            }
            break;
        // DAY OF MONTH
        case 'D' : // fall through to DDDD
        case 'DD' : // fall through to DDDD
        case 'DDD' : // fall through to DDDD
        case 'DDDD' :
            if (input != null) {
                datePartArray[2] = ~~input;
            }
            break;
        // YEAR
        case 'YY' :
            datePartArray[0] = ~~input + (~~input > 68 ? 1900 : 2000);
            break;
        case 'YYYY' :
        case 'YYYYY' :
            datePartArray[0] = ~~input;
            break;
        // AM / PM
        case 'a' : // fall through to A
        case 'A' :
            config._isPm = getLangDefinition(config._l).isPM(input);
            break;
        // 24 HOUR
        case 'H' : // fall through to hh
        case 'HH' : // fall through to hh
        case 'h' : // fall through to hh
        case 'hh' :
            datePartArray[3] = ~~input;
            break;
        // MINUTE
        case 'm' : // fall through to mm
        case 'mm' :
            datePartArray[4] = ~~input;
            break;
        // SECOND
        case 's' : // fall through to ss
        case 'ss' :
            datePartArray[5] = ~~input;
            break;
        // MILLISECOND
        case 'S' :
        case 'SS' :
        case 'SSS' :
            datePartArray[6] = ~~ (('0.' + input) * 1000);
            break;
        // UNIX TIMESTAMP WITH MS
        case 'X':
            config._d = new Date(parseFloat(input) * 1000);
            break;
        // TIMEZONE
        case 'Z' : // fall through to ZZ
        case 'ZZ' :
            config._useUTC = true;
            config._tzm = timezoneMinutesFromString(input);
            break;
        }

        // if the input is null, the date is not valid
        if (input == null) {
            config._isValid = false;
        }
    }

function to convert string input to date


function makeDateFromStringAndFormat(config) {
        // This array is used to make a Date, either with `new Date` or `Date.UTC`
        var tokens = config._f.match(formattingTokens),
            string = config._i,
            i, parsedInput;

        config._a = [];

        for (i = 0; i < tokens.length; i++) {
            parsedInput = (getParseRegexForToken(tokens[i], config).exec(string) || [])[0];
            if (parsedInput) {
                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
            }
            // don't parse if its not a known token
            if (formatTokenFunctions[tokens[i]]) {
                addTimeToArrayFromToken(tokens[i], parsedInput, config);
            }
        }

        // add remaining unparsed input to the string
        if (string) {
            config._il = string;
        }

        // handle am pm
        if (config._isPm && config._a[3] < 12) {
            config._a[3] += 12;
        }
        // if is 12 am, change hours to 0
        if (config._isPm === false && config._a[3] === 12) {
            config._a[3] = 0;
        }
        // return
        dateFromArray(config);
    }


function makeDateFromString(config) {
        var i,
            string = config._i,
            match = isoRegex.exec(string);

        if (match) {
            // match[2] should be "T" or undefined
            config._f = 'YYYY-MM-DD' + (match[2] || " ");
            for (i = 0; i < 4; i++) {
                if (isoTimes[i][1].exec(string)) {
                    config._f += isoTimes[i][0];
                    break;
                }
            }
            if (parseTokenTimezone.exec(string)) {
                config._f += " Z";
            }
            makeDateFromStringAndFormat(config);
        } else {
            config._d = new Date(string);
        }
    }

function
makeDateFromString
(
config
)
{
var
i
,
string
=
config
.
_i
,
match
=
isoRegex
.
exec
(
string
)
;
if
(
match
)
{
// match[2] should be "T" or undefined
config
.
_f
=
'YYYY-MM-DD'
+
(
match
[
2
]
||
" "
)
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
if
(
isoTimes
[
i
]
[
1
]
.
exec
(
string
)
)
{
config
.
_f
+=
isoTimes
[
i
]
[
0
]
;
break
;
}
}
if
(
parseTokenTimezone
.
exec
(
string
)
)
{
config
.
_f
+=
" Z"
;
}
makeDateFromStringAndFormat
(
config
)
;
}
else
{
config
.
_d
=
new
Date
(
string
)
;
}
}


function _loadProcessor(processorName) {
	const compatibleVersion = compatibleProcessors[processorName]

	// Check if module is compatible
	if(compatibleVersion === undefined) {
		const error = new Error(`Processor ${processorName} is not supported yet.`)
		error.code = 'MODULE_NOT_SUPPORTED'
		throw error
	}

	return require(`./processors/${processorName}`)(_loadModule(processorName))
}

function
_loadProcessor
(
processorName
)
{
const
compatibleVersion
=
compatibleProcessors
[
processorName
]
// Check if module is compatible
if
(
compatibleVersion
===
undefined
)
{
const
error
=
new
Error
(
`
${
processorName
}
`
)
error
.
code
=
'MODULE_NOT_SUPPORTED'
throw
error
}
return
require
(
`
${
processorName
}
`
)
(
_loadModule
(
processorName
)
)
}

Loads a processor

@private
@param {String} processorName
@returns {Function} processor


function getJson(filename, cb) {
  fs.readFile(filename, function(err, data) {
    if (err) return cb(err, null)
    try {
      var json = JSON.parse(data)
      cb(null, json)
    } catch(e) {
      cb(e, null)
    }
  })
}

function getJson ( filename , cb ) { fs . readFile ( filename , function ( err , data ) { if ( err ) return cb ( err , null ) try { var json = JSON . parse ( data ) cb ( null , json ) } catch ( e ) { cb ( e , null ) } } ) }


function sauceConfigured(config) {
  var sauceAccessKey = config.access_key
  var sauceUsername = config.username

  if (!sauceAccessKey || !sauceUsername) {
    return false
  }

  return true
}

function sauceConfigured ( config ) { var sauceAccessKey = config . access_key var sauceUsername = config . username if ( ! sauceAccessKey || ! sauceUsername ) { return false } return true }


function cleanup(ctx, cb) {
  cleanupRun = true
  var msg = "Shutting down Sauce Connector"
  console.log(msg)
  ctx.comment(msg)
  if (connectorProc) connectorProc.kill("SIGINT")
  // Give Sauce Connector 5 seconds to gracefully stop before sending SIGKILL
  setTimeout(function() {
    if (connectorProc) connectorProc.kill("SIGKILL")
    fs.unlink(PIDFILE, function() {})
    msg = "Sauce Connector successfully shut down"
    console.log(msg)
    ctx.comment(msg)

    return cb(0)
  }, 5000)
}

This will shut down the tunnel in a nice way