## WaitingRoom constructor

Creates a new instance of WaitingRoom

@param {object} config Configuration object

@see HostRoom
493785
function WaitingRoom(config) {
    // Supercall
    HostRoom.call(this, 'Waiting', config);
    if (!this.logicPath) this.logicPath = ngt.resolve('waitroom/waitroom.js');

    /**
     * ### WaitingRoom.roomOpen
     *
     * Flag indicating whether the room is open
     */
    this.roomOpen = config.roomOpen || true;

    /**
     * ### WaitingRoom.dispatching
     *
     * Numeric flag indicating whether the room is dispatching a new game
     *
     *
     */
    this.dispatching = 0;

    /**
     * ### WaitingRoom.timeOuts
     *
     * Array of setTimeout return values indexed by playerIDs
     */
    this.timeOuts = {};

    /**
     * ### WaitingRoom.notifyTimeout
     *
     * A timeout to notify players about updates in the number of players
     *
     * @see WaitingRoom.notifyPlayers
     */
    this.notifyTimeout = null;

    /**
     * ### WaitingRoom.numberOfDispatches
     *
     * Non-negative integer indicating the number of game dispatches
     */
    this.numberOfDispatches = config.numberOfDispatches || 0;

    /**
     * ### WaitingRoom.lastGameRoom
     *
     * Reference to the last created game room
     */
    this.lastGameRoom = null;

    /**
     * ### WaitingRoom.GROUP_SIZE
     *
     * Positive non-zero integer indicating the size of each group
     */
    this.GROUP_SIZE = null;

    /**
     * ### WaitingRoom.POOL_SIZE
     *
     * Positive non-zero integer indicating number of clients for group forming
     */
    this.POOL_SIZE = null;

    /**
     * ### WaitingRoom.DISCONNECT_IF_NOT_SELECTED
     *
     * Boolean or null, indicating whether unselected players are disconnected
     */
    this.DISCONNECT_IF_NOT_SELECTED = null;

    /**
     * ### WaitingRoom.timeOuts
     *
     * Array of setTimeout return values indexed by playerIDs
     */
    this.N_GAMES = null;

    /**
     * ### WaitingRoom.START_DATE
     *
     * Time and date of game start
     *
     * Must be valid input for `Date` constructor
     */
    this.START_DATE = null;

    /**
     * ### WaitingRoom.EXECUTION_MODE
     *
     * String indicating execution mode
     *
     * In the execution mode `'TIMEOUT`, one waits until the time is up, then
     * it will be checked whether enough players are there to start the game.
     * In the execution mode `WAIT_FOR_N_PLAYERS`, the game starts right away
     * if there are the desired number of players. Otherwise, when the time is
     * up, it will be checked if there are at least a certain minimum number of
     * players to start the game. If the execution mode is `WAIT_FOR_DISPATCH`,
     * it simply waits for a dispatch command from monitor, the number of
     * connected players is not taken into account.
     */
    this.EXECUTION_MODE = null;

    /**
     * ### WaitingRoom.MAX_WAIT_TIME
     *
     * Positive non-zero integer indicating max number of milliseconds to start
     *
     * Cannot be defined at the same time as `WaitingRoom.START_DATE`
     */
    this.MAX_WAIT_TIME = null;

    /**
     * ### WaitingRoom.ON_TIMEOUT
     *
     * Callback to be executed client-side after waiting time has elapsed
     */
    this.ON_TIMEOUT = null;

    /**
     * ### WaitingRoom.ON_TIMEOUT_SERVER
     *
     * Callback to be executed after a timeout has expired
     */
    this.ON_TIMEOUT_SERVER = null;

    /**
     * ### WaitingRoom.ON_OPEN
     *
     * Callback to be executed when the waiting room becomes open
     */
    this.ON_OPEN = null;

    /**
     * ### WaitingRoom.ON_CLOSE
     *
     * Callback to be executed when the waiting room becomes close
     */
    this.ON_CLOSE = null;

    /**
     * ### WaitingRoom.ON_CONNECT
     *
     * Callback to be executed when a player connects
     */
    this.ON_CONNECT = null;

    /**
     * ### WaitingRoom.ON_DISCONNECT
     *
     * Callback to be executed when a player disconnects
     */
    this.ON_DISCONNECT = null;

    /**
     * ### WaitingRoom.ON_INIT
     *
     * Callback to be executed after the settings have been parsed
     */
    this.ON_INIT = null;

    /**
     * ### WaitingRoom.ON_DISPATCH
     *
     * Callback to be executed just before starting dispatching
     *
     * Receives the options of the dispatch call as second param
     */
    this.ON_DISPATCH = null;

    /**
     * ### WaitingRoom.ON_DISPATCHED
     *
     * Callback to be executed at the end of a dispatch call
     */
    this.ON_DISPATCHED = null;

    /**
     * ### WaitingRoom.ON_FAILED_DISPATCH
     *
     * Callback to be executed if a dispatch attempt failed
     */
    this.ON_FAILED_DISPATCH = null;

    /**
     * ### WaitingRoom.CHOSEN_TREATMENT
     *
     * String or undefined indicating chosen treatment
     */
    this.CHOSEN_TREATMENT = null;

    /**
     * ### WaitingRoom.OVERWRITE_CHOSEN_TREATMENT
     *
     * If set, it overwrites chosen treatment for the next dispatch only
     *
     * When dispatch is invoked remotely, users may specify a treatment.
     *
     * It is set to null at every dispatch.
     *
     * @see WaitingRoom.ALLOW_SELECT_TREATMENT
     */
    this.OVERWRITE_CHOSEN_TREATMENT = null;

    /**
     * ### WaitingRoom.PLAYER_SORTING
     *
     * Callback to sort the list of players before dispatching
     *
     * If NULL, random sorting takes place. Default: 'timesNotSelected'
     */
    this.PLAYER_SORTING = WaitingRoom.sortingCallbacks.timesNotSelected;

    /**
     * ### WaitingRoom.PING_BEFORE_DISPATCH
     *
     * If TRUE, all players are pinged before a dispatch (Default: TRUE)
     *
     * Non-responding clients are disconnected.
     *
     * If only one player is needed and mode is 'WAIT_FOR_N_PLAYERS',
     * pinging is skipped.
     *
     * @see PING_MAX_REPLY_TIME
     */
    this.PING_BEFORE_DISPATCH = true;

    /**
     * ### WaitingRoom.PING_MAX_REPLY_TIME
     *
     * The time to wait to receive a ping back
     *
     * Clients will be disconnected if they do not reply in time.
     *
     * @see PING_BEFORE_DISPATCH
     */
    this.PING_MAX_REPLY_TIME = 3000;

    /**
     * ### WaitingRoom.PING_DISPATCH_ANYWAY
     *
     * If TRUE, dispatch continues even if disconnections occur during PING
     *
     * @see PING_BEFORE_DISPATCH
     * @see PING_MAX_REPLY_TIME
     */
    this.PING_DISPATCH_ANYWAY = false;

    /**
     * ### WaitingRoom.TEXTS
     *
     * List of texts replacing default ones in WaitingRoom widget
     *
     * @see WaitingRoom.texts (widget)
     */
    this.TEXTS = {};

    /**
     * ### WaitingRoom.SOUNDS
     *
     * List of paths to sounds replacing default ones in WaitingRoom widget
     *
     * @see WaitingRoom.sounds (widget)
     */
    this.SOUNDS = {};

    /**
     * ### WaitingRoom.PAGE_TITLE
     *
     * Sets the page title, optionally adds to page
     *
     */
    this.PAGE_TITLE =  { title: 'Welcome!', addToBody: true };

    /**
     * ### WaitingRoom.isPingInProgress
     *
     * Flag to indicate whether currently pinging for unresponsive players
     */
    this.isPingInProgress = false;

    /**
     * ### WaitingRoom.suspendedPings
     *
     * Flag to indicate whether currently pinging for unresponsive players
     */
    this.suspendedPings = [];

    /**
     * ### WaitingRoom.closeAfterDispatch
     *
     * Flag that the waiting room will close after next dispatch
     *
     * Note: waiting room can dispatch multiple groups, and then will close.
     */
    this.closeAfterDispatch = false;

    /**
     * ### WaitingRoom.makeClientTimeouts
     *
     * TRUE, if it makes timeouts for connecting clients
     *
     * Makes timeout if START_DATE or MAX_WAIT_TIME is set.
     *
     * @see WaitingRoom.makeTimeOut
     * @see WaitingRoom.clearTimeOut
     * @see WaitingRoom.START_DATE
     * @see WaitingRoom.MAX_WAIT_TIME
     */
    this.makeClientTimeOuts = false;

    /**
     * ### WaitingRoom.NOTIFY_INTERVAL
     *
     * The number of milliseconds to wait before sending a player-update message
     *
     * @see WaitingRoom.notifyPlayerUpdate
     */
    this.NOTIFY_INTERVAL = 200;

    /**
     * ### WaitingRoom.availableTreatments
     *
     * List of available treatments including treatment callbacks
     *
     * Maps names to descriptions.
     */
    this.availableTreatments = (function(that) {
        var o, t, key;
        if (that.gameLevel) {
            // Treatments are not yet parsed.
            t = that.game.levels[that.gameLevel].settings.treatments;
        }
        else {
            // Treatments are already parsed at this point.
            t = that.game.settings;
        }
        // Hard-cloned, check names in treatmentCallbacks.
        o = {
            treatment_random:
            WaitingRoom.treatmentCallbacks['treatment_random'],
            treatment_rotate:
            WaitingRoom.treatmentCallbacks['treatment_rotate']
        };
        for (key in t) {
            if (t.hasOwnProperty(key)) {
                o[key] = t[key].description || 'no description';
            }
        }
        return o;
    })(this);
}
802470
function init(config) {
    var tokenConfig = config.security.token || {};
    var privateKey = tokenConfig.privateKey;
    var decryptedToken = {
        _id: tokenConfig.webserverId,
        authToken: tokenConfig.webserverToken
    };
    var jwt = jsonwebtoken.sign(decryptedToken, privateKey);

    headers = { 'Authorization': 'Bearer ' + jwt };

    admin._id =  mongo.newObjectId('000000000000000000000000');
    admin.name = 'systemAdmin';
    admin.type = 'user';
    admin.role = 'admin';

    var apiConfig = config.api || {};
    var host = apiConfig.internalHost || apiConfig.host;  // from web server to api use internalHost name
    var useSSL = apiConfig.serverUseSSL !== undefined ?
        apiConfig.serverUseSSL : config.useSSL;
    baseUrl = (useSSL ? 'https://' : 'http://') + host;

    var port = config.api.port;
    if (port !== 80 && port !== 443) {
        baseUrl += ':' + port;
    }

    baseUrl += '/' + config.api.version;

    return config;
}
1063058
function Parser(config) {
  if (!(this instanceof Parser)) return new Parser(config);

  this.config = config;

  this.config.on('read', function read(type) {
    this[type]();
  }.bind(this));
}
633140
function INIT(config) {
  if (__init) return;

  CONF = _.extend(CONF, config)

  LOG = LOG.use(require('./lib/sentry')(CONF.sentry))

  JOBS = Q.init(CONF, LOG)

  if (CONF.auth)
    WWW.use('/'+CONF.admin_url_prefix,
            express.basicAuth(CONF.auth.user, CONF.auth.pass));

  WWW.use(express.bodyParser())
  WWW.use('/'+CONF.admin_url_prefix, Q.kue.app)

  __init = true
}
950300
function SessionStorage_construct(config) {
        this.timeouts = {};
        this.config = core.extend(
            {
                cookieKey: 'session_id',
                time: 60 * 20 * 1000, // 20 min default session time
                storage: null,
                key_prefix: 'SESSION_ID_KEY_'
            },
            config
        );

        if (!this.config.storage) {
            this.config.storage = cache;
        } else if (Type.isString(this.config.storage)) {
            this.config.storage = di.load(this.config.storage);
        }

        if(!(this.config.storage instanceof StorageInterface)) {
            throw new error.HttpError(500, this.config, 'Session storage must be instance of interface/storage');
        }
    }
1041131
function init(config) {
            var property;

            for (property in config) {
                if (config.hasOwnProperty(property)) {
                    this[property] = config[property];
                }
            }

            if(this.processors instanceof Array === false){
                this.processors = [].concat(this.constructor.processors);
            }
			if(this.preprocessors instanceof Array === false){
                this.preprocessors = [].concat(this.constructor.preprocessors);
            }
        }
698511
function (config) {
    var that = this;
    console.log(logCord$6, 'You maybe known some config information');
    var svr = new ProxyServer();
    svr.start(config);
    that.mc.trigger(TypeMsg$5.OnCallActive, '');
    return that
  }
331781
function createInstance (
  instanceId,
  appCode,
  config,
  data,
  env
) {
  if ( appCode === void 0 ) appCode = '';
  if ( config === void 0 ) config = {};
  if ( env === void 0 ) env = {};

  // Set active instance id and put some information into `instances` map.
  activeId = instanceId;

  // Virtual-DOM object.
  var document = new renderer.Document(instanceId, config.bundleUrl);

  // All function/callback of parameters before sent to native
  // will be converted as an id. So `callbacks` is used to store
  // these real functions. When a callback invoked and won't be
  // called again, it should be removed from here automatically.
  var callbacks = [];

  // The latest callback id, incremental.
  var callbackId = 1;

  instances[instanceId] = {
    instanceId: instanceId, config: config, data: data,
    document: document, callbacks: callbacks, callbackId: callbackId
  };

  // Prepare native module getter and HTML5 Timer APIs.
  var moduleGetter = genModuleGetter(instanceId);
  var timerAPIs = getInstanceTimer(instanceId, moduleGetter);

  // Prepare `jud` instance variable.
  var judInstanceVar = {
    config: config,
    document: document,
    require: moduleGetter
  };
  Object.freeze(judInstanceVar);

  // Each instance has a independent `Vue` variable and it should have
  // all top-level public APIs.
  var subVue = Vue$2.extend({});

  // ensure plain-object components are extended from the subVue
  subVue.options._base = subVue

  // expose global utility
  ;['util', 'set', 'delete', 'nextTick', 'version', 'judVersion', 'config'].forEach(function (name) {
    subVue[name] = Vue$2[name];
  });

  // The function which create a closure the JS Bundle will run in.
  // It will declare some instance variables like `Vue`, HTML5 Timer APIs etc.
  var instanceVars = Object.assign({
    Vue: subVue,
    jud: judInstanceVar,
    __jud_require_module__: judInstanceVar.require // deprecated
  }, timerAPIs);
  callFunction(instanceVars, appCode);

  // Send `createFinish` signal to native.
  renderer.sendTasks(instanceId + '', [{ module: 'dom', method: 'createFinish', args: [] }], -1);
}
72745
function _createSandbox(config) {
  if (proxiedGlobal && proxiedGlobal) return workspaces.get(...makeArray(config.workspace));

  const sandbox = {};
  if (config.includeGlobals && (!proxiedGlobal || !config.proxyGlobal)) Object.assign(sandbox, global);

  return vm.createContext(sandbox);
}
526172
function ConfigUtil() {

    var self = this; //, mainConfig

    /**
     * Init
     * @contructor
     * */
    var init = function() {

        if ( !ConfigUtil.instance ) {
            try {
                self.paths = getContext('paths')
            } catch (err) {
                self.paths = {}
            }

            var path = new _(__dirname).toUnixStyle();
            self.__dirname =  _( path.substring(0, (path.length - 4)) );

            ConfigUtil.instance = self;
            return self
        } else {
            self = ConfigUtil.instance;
            return ConfigUtil.instance
        }
    }


    /**
     * Set config file if !exists
     *
     * @param {string} app - App name
     * @param {string} file - File to save
     * @param {object} content - JSON content to save
     * */
    this.set = function(app, file, content, callback){
        switch (app) {
            case 'gina':
            case 'gina.utils':
                setFile(app, file, content, function(err){
                    callback(err);
                });
                break;
        }
    }

    /**
     * Get config file if exists
     *
     * @param {string} project - Project name
     * @param {strins} key - File name to save + .ext
     *
     * @callback callback
     * @param {string|boolean} err
     * @param {object} config - Bundle Configuration
     * */
    this.get = function(project, file, callback){

        var config = null, err = false;

        switch (project) {
            case 'gina':
            case 'gina.utils':
                try {
                    //You are under gina.utils/lib/...
                    if ( typeof(self.value) != "undefined" ) {

                        try {
                            config = self.value;//????
                        } catch (err) {
                            err = 'Utils.Config.get(...) : self.value['+file+'] : key not found.\n' + err;
                        }

                    } else {
                        //Getting paths.
                        if ( typeof(self.paths.root) != 'undefined' ) {
                            //console.error("requiring :=> ",  self.paths.root + '/.gna/locals.json');
                            try {
                                config = require(self.paths.root  + '/.gna/' + file);
                                self.value = config;
                                self.paths = config['paths'];

                            } catch (err) {
                                //Means that the file was not found..
                                console.error(err.stack || err.message);
                                err = new Error(self.__dirname  + '/.gna/locals.json: project configuration file not found.');
                                process.exit(1)
                            }
                        }
                    }
                    callback(err, config)

                } catch (err) {
                    var err = new Error('.gna/locals.json: project configuration file not found. \n' + (err.stack||err.message));
                    //logger.error('gina', 'UTILS:CONFIG:ERR:3', err, __stack);
                    callback(err);
                }
                break;

            default :
                callback('Config.get('+project+'): case not found');
        }
    }

    /**
     * Get sync config file if exists
     *
     * @param {string} app - App name
     * @return {object} config - App Configuration
     *
     * @private
     * */
    this.getSync = function(project, file, i){
        var maxRetry    = 7
            , delay     = 300
            , i         = i || 0;

        if (typeof(file) == 'undefined') {
            var file = 'locals.json'
        }

        if ( typeof(self.value) != "undefined" ) {
            return self.value;
        } else {
            var filename = self.paths.root +'/.gna/'+ file;
            if (i > 0) {
                console.debug('retrying [ '+i+' ] to load: ' + filename)
            }

            try {
                if ( fs.existsSync(filename) ) {
                    return require(filename)
                } else {
                    // you might just be experimenting some latencies
                    if (i < maxRetry) {
                        console.debug('retrying to load config after timeout');
                        setTimeout(function(){
                            console.debug('It is time re reload config');
                            self.getSync(project, file, i+1)
                        }, delay);
                        //return
                    } else {
                        var err = new Error(filename+ ' not found');
                        console.emerg(err.stack||err.message);
                        process.exit(1);
                    }
                }
            } catch (err) {
                if (i < maxRetry) {
                    console.debug('(catched) retrying to load config after timeout');
                    setTimeout(function(){
                        console.debug('It is time re reload config');
                        self.getSync(project, file, i+1)
                    }, delay);
                } else {
                    console.error(err.stack);
                    throw new Error(err.message);
                }
            }
        }
    }

    /**
     * Create a config file
     *
     * @param {string} app - Targeted application
     * @param {string} file - File save
     * @param {string} content - Content fo the file to save
     *
     *
     * TOTO - Avoid systematics file override.
     * @private
     * */

    var setFile = function(app, file, content, callback) {

        var paths = {
            root : content.paths.root,
            utils : content.paths.utils
        };
        var gnaFolder = content.paths.root + '/.gna';

        self.project = content.project;

        self.paths = paths;

        //Create path.
        var createFolder = function(){
            if ( fs.existsSync(gnaFolder) ) {
                if ( !fs.existsSync(gnaFolder +'/'+ file) ) {
                    createContent(gnaFolder +'/'+ file, gnaFolder, content, function(err){
                        setTimeout(function(){
                            callback(err)
                        }, 500)
                    })
                } else { // already existing ... won't overwrite
                    callback(false)
                }

            } else {
                fs.mkdir(gnaFolder, 0777, function(err){
                    if (err) {
                        console.error(err.stack);
                        callback(err)
                    } else {
                        //Creating content.
                        createContent(gnaFolder+ '/' +file, gnaFolder, content, function(err){
                            setTimeout(function(){
                                callback(err)
                            }, 500)
                        })
                    }
                })
            }

        };

        fs.exists(gnaFolder, function(exists){
            if (!exists) {
                createFolder()
            } else {
                // test if decalred path matches real path and overwrite if not the same
                // in case you move your project
                var filename        = _(gnaFolder +'/'+ file, true);
                var checksumFileOld = _(gnaFolder +'/'+ math.checkSumSync( JSON.stringify( require(filename) ), 'sha1'), true) + '.txt';
                var checksumFile    = _(gnaFolder +'/'+ math.checkSumSync( JSON.stringify(content), 'sha1'), true) + '.txt';

                var verified        = (checksumFileOld == checksumFile) ? true : false;


                if ( !fs.existsSync(checksumFile) && fs.existsSync(filename) || !fs.existsSync(filename) || !verified) {
                    if ( fs.existsSync(filename) ) fs.unlinkSync(filename);
                    if ( fs.existsSync(checksumFile) ) fs.unlinkSync(checksumFile);

                    createContent(filename, gnaFolder, content, function(err){
                        fs.openSync(checksumFile, 'w');
                        setTimeout(function(){
                            callback(err)
                        }, 500)
                    })
                } else if ( fs.existsSync(filename) ) {

                    var locals = require(gnaFolder +'/'+ file);

                    if (paths.utils != locals.paths.utils) {

                        new _(gnaFolder).rm( function(err){
                            if (err) {
                                console.warn('found error while trying to remove `.gna`\n' + err.stack)
                            }

                            //setTimeout(function(){
                                //console.debug('Done removing `gnaFolder` : '+ gnaFolder);
                            createFolder();
                            //}, 200);
                        })
                    } else {
                        callback(false)// nothing to do
                    }
                } else {
                    callback(false)// nothing to do
                }
            }
        })
    }


    /**
     * Remove symbolic link
     *
     * @param {string} path
     * @callback callback
     *
     * @private
     * */
    var removeSymlink = function(path, callback){

        fs.exists(path, function(exists){
            if (exists) {
                fs.lstat(path, function(err, stats){
                    if (err) console.error(err.stack);

                    if ( stats.isSymbolicLink() ) fs.unlink(path, function(err){
                        if (err) {
                            console.error(err.stack);
                            callback(err)
                        } else {
                            //Trigger.
                            onSymlinkRemoved(self.paths, function(err){
                                if (err) console.error(err.stack);

                                callback(false)
                            })
                        }
                    })
                })
            } else {
                //log & ignore. This is not a real issue.
                //logger.warn('gina', 'UTILS:CONFIG:WARN:1', 'Path not found: ' + path, __stack);
                console.warn( 'Path not found: ' + path, __stack);
                onSymlinkRemoved(self.paths, function(err){
                    //if (err) logger.error('gina', 'UTILS:CONFIG:ERR:9', err, __stack);
                    if (err) console.error(err.stack||err.message);

                    callback(false)
                })
            }
        })
    }

    /**
     * Symbolic link remove event
     *
     * @param {string} [err]
     * @callback callback
     *
     * @private
     * */
    var onSymlinkRemoved = function(paths, callback){
        //Remove original.
        var p = new _(paths.root + '/.gna');
        var path = p.toString();

        //Remove folers.
        fs.exists(path, function(exists){
            //delete when exists.
            if (exists) {
                //console.log("yeah about to delete main folder: ", p.toString());
                //Delete ans die here..
                p.rm(function(err, path){
                    //console.log("receives ", err, path);
                    if (err) {
                        //logger.error('gina', 'UTILS:CONFIG:ERR:8', err, __stack);
                        console.error(err.stack||err.message);
                        callback(err)
                    } else {
                        //logger.info('gina', 'UTILS:CONFIG:INFO:1', path +': deleted with success !');
                        console.info( path +': deleted with success !');
                        callback(false)
                    }
                })
            }
        })
    }

    /**
     * Create content
     *
     * @param {string} filename - Fullpath
     * @content {string} content
     *
     * @private
     * */
    var createContent = function(filename, gnaFolder, content, callback){
        if ( fs.existsSync(filename) ) {
            fs.unlinkSync(filename)
        }
        fs.appendFile(
            filename,
            JSON.stringify(content, null, '\t'),
            null,
            function(err){
                if (err) {
                    //logger.error('gina', 'UTILS:CONFIG:ERR:2', err, __stack);
                    console.error('`Error on while calling createContent()`: ' + err.stack||err.message);
                    callback(err)
                } else {
                    setTimeout(function(){
                        callback(err)
                    }, 1000)
                }
            }//EO function
        )//EO fs.appendFile
    }

    /**
     * Get var value by namespace
     *
     * @param {string} namespace
     * @param {object} [config ] - Config object
     * @return {*} value - Can be String or Array
     *
     * @private
     * */
    var getVar = function(namespace, config) {
        if ( typeof(config) == "undefined" )
            var config = self.getSync(app);

        if (config != null) {
            var split = namespace.split('.'), k=0;
            while (k<split.length) {
                config = config[split[k++]]
            }
            return config
        } else {
            return null
        }
    }

    /**
     * Get path by app & namespance
     *
     * @param {string} app
     * @param {string} namespace
     *
     * @callback callback
     * @param {string} err
     * @param {string} path
     *
     * @private
     * */
    var getPath = function(app, namespace, callback){

        self.get(app, function(err, config){
            if (err) {
                //logger.error('gina', 'UTILS:CONFIG:ERR:4', err, __stack);
                console.error(err.stack||err.message);
                callback(err + 'Utils.Config.get(...)');
            }

            try {
                callback( false, getVar('paths.' + namespace, config) );

            } catch (err) {
                var err = new Error('Config.getPath(app, cat, callback): cat not found');
                callback(err)
            }
        })
    }


    /**
     * Get project name
     *
     * @return {string} projectName
     *
     * */
    this.getProjectName = function(){
        if ( this.paths != undefined && this.paths.root != undefined ) {
            var arr = this.paths.root.split("/");
            return arr[arr.length-1]
        } else {
            return null
        }
    }

    return init()
}
230304
function make_singleton( Constructor, singleton_config ) {
		process_after( Constructor );

		var instance = Constructor.create.apply( null, singleton_config === true ? [] : [].concat( singleton_config ) );

		util.def( Constructor, __singleton__, util.describe( { value : instance }, 'r' ) );

		return instance;
	}
508454
function initServices (config) {
    // get services directory
    var dirs = getDir(config, 'services')
    // load services definitions from each directory
    _.each(dirs, dir => initServicesDir(config, dir))
    // create new service instances from definitions
    _.each(config.services, (service, name) => {
        config.services[name] = new ImmutableCoreService(service)
    })
    // initialize all services
    return ImmutableCoreService.initializeAll()
}
1130311
function clientConnects(p) {
        var pList;
        var nPlayers;
        var waitTime;
        var widgetConfig;

        node.remoteSetup('page', p.id, {
            clearBody: true,
            title: { title: 'Welcome!', addToBody: true }
        });

        node.remoteSetup('widgets', p.id, {
            destroyAll: true,
            append: { 'WaitingRoom': {} }
        });

        if (waitRoom.isRoomOpen()) {
            console.log('Client connected to waiting room: ', p.id);

            // Mark code as used.
            channel.registry.markInvalid(p.id);

            pList = waitRoom.clients.player;
            nPlayers = pList.size();


            if (waitRoom.START_DATE) {
                waitTime = new Date(waitRoom.START_DATE).getTime() -
                    (new Date().getTime());
            }
            else if (waitRoom.MAX_WAIT_TIME) {
                waitTime = waitRoom.MAX_WAIT_TIME;
            }
            else {
                waitTime = null; // Widget won't start timer.
            }

            // Send the number of minutes to wait and all waitRoom settings.
            widgetConfig = waitRoom.makeWidgetConfig();
            widgetConfig.waitTime = waitTime;
            node.remoteSetup('waitroom', p.id, widgetConfig);

            console.log('NPL ', nPlayers);

            // Notify all players of new connection.
            node.say('PLAYERSCONNECTED', 'ROOM', nPlayers);

            // Start counting a timeout for max stay in waiting room.
            waitRoom.makeTimeOut(p.id, waitTime);

            // Wait for all players to connect.
            if (nPlayers < waitRoom.POOL_SIZE) return;

            if (waitRoom.EXECUTION_MODE === 'WAIT_FOR_N_PLAYERS') {
                waitRoom.dispatch({
                    action: 'AllPlayersConnected',
                    exit: 0
                });
            }
        }
        else {
            node.say('ROOM_CLOSED', p.id);
        }
    }
319998
function configure(config) {
        var layout = null;
        if (config.layout) {
            layout = layouts.layout(config.layout.type, config.layout);
        }
        if(config.maxBufferSize){
            maxBufferSize = config.maxBufferSize;
        }
        return memoryAppender(layout, config.timezoneOffset);
    }
212279
function createConfig(configObj, providerObj, platformPath) {
    forEach(configObj, function(value, namespace) {

      if (angular.isObject(configObj[namespace])) {
        // recursively drill down the config object so we can create a method for each one
        providerObj[namespace] = {};
        createConfig(configObj[namespace], providerObj[namespace], platformPath + '.' + namespace);

      } else {
        // create a method for the provider/config methods that will be exposed
        providerObj[namespace] = function(newValue) {
          if (arguments.length) {
            configObj[namespace] = newValue;
            return providerObj;
          }
          if (configObj[namespace] == PLATFORM) {
            // if the config is set to 'platform', then get this config's platform value
            var platformConfig = stringObj(configProperties.platform, ionic.Platform.platform() + platformPath + '.' + namespace);
            if (platformConfig || platformConfig === false) {
              return platformConfig;
            }
            // didnt find a specific platform config, now try the default
            return stringObj(configProperties.platform, 'default' + platformPath + '.' + namespace);
          }
          return configObj[namespace];
        };
      }

    });
  }
131721
function init(_config) {
  if (initialized)
    return;

  // Validate the config
  config = helpers.validateConfig(_config);

  // Create a user for the bot
  users[config.name] = helpers.createUser(true);

  // Create a user for the channel owner
  var name = config.channel.replace('#', '');
  users[name] = helpers.createUser(true);

  // Init the client
  ircClient = new irc.Client(config.server, config.name, {
    userName: config.name,
    realName: config.name,
    password: config.password,
    port:     config.port,
    secure:   config.secure,
  });

  // Add listeners
  ircClient.addListener('error',                    onError);
  ircClient.addListener('registered',               onRegistered);
  ircClient.addListener('join' + config.channel,    onJoin);
  ircClient.addListener('part' + config.channel,    onPart);
  ircClient.addListener('motd',                     onMotd);
  ircClient.addListener('notice',                   onNotice);
  ircClient.addListener('message' + config.channel, onMessage);
  ircClient.addListener('raw',                      onRaw);

  // If there is a discord token
  if (config.discordToken) {
    // Init the discord client
    discordClient = new Discord.Client({
      token:   config.discordToken,
      autorun: true,
    });

    // Add listeners
    discordClient.on('ready',   onDiscordReady);
    discordClient.on('message', onDiscordMessage);
  }

  // If we are logging, create the directory if not exists
  if (config.log && typeof config.log === 'string')
    mkdirp.sync(config.log);

  // Init stream checker
  if (config.autoExit || config.discordToken)
    streamInterval = setInterval(onCheckStream, 60 * 1000)

  initialized = true;
}
1300557
async function init({ options = { config: {} }, handleInsert } = {}) {
  const { publicKey, ...globalConfig } = options.config;
  const baseConfig = { ...defaultConfig, ...globalConfig };

  window.UPLOADCARE_PUBLIC_KEY = publicKey;

  /**
   * Register the effects tab by default because the effects tab is awesome. Can
   * be disabled via config.
   */
  uploadcare.registerTab('preview', uploadcareTabEffects);

  return {
    /**
     * On show, create a new widget, cache it in the widgets object, and open.
     * No hide method is provided because the widget doesn't provide it.
     */
    show: ({ value, config: instanceConfig = {}, allowMultiple, imagesOnly = false } = {}) => {
      const config = { ...baseConfig, imagesOnly, ...instanceConfig };
      const multiple = allowMultiple === false ? false : !!config.multiple;
      const resolvedConfig = { ...config, multiple };
      const files = getFiles(value);

      /**
       * Resolve the promise only if it's ours. Only the jQuery promise objects
       * from the Uploadcare library will have a `state` method.
       */
      if (files && !files.state) {
        return files.then(result => openDialog(result, resolvedConfig, handleInsert));
      } else {
        return openDialog(files, resolvedConfig, handleInsert);
      }
    },

    /**
     * Uploadcare doesn't provide a "media library" widget for viewing and
     * selecting existing files, so we return `false` here so Netlify CMS only
     * opens the Uploadcare widget when called from an editor control. This
     * results in the "Media" button in the global nav being hidden.
     */
    enableStandalone: () => false,
  };
}