<commit_before>var spawn = require('child_process').spawn,
    http = require('http'),
    urlmod = require('url'),
    fs = require('fs');
var vidProc,
    player,
    files = [],
    currFile = 0,
    playing = false;
var localAddress = '',
    peerAddress = '',
    port = 3000,
    req,
    res;

// INIT ////////////////////////////////////

var logLevel = 2;

// standardized exit function
var exitFunction = function (code) {
    console.log('exiting');
    if (code) console.log('exited with code '+code);
    // show cursor
    console.log('\033[?12l\033[?25h');
    process.exit();
}

var warn = function (msg) {
    if (logLevel > 0) console.log(msg);
}
var echo = function (msg) {
    if (logLevel > 1) console.log(msg);
}

// HTTP SERVER /////////////////////////////

// find local ip address
var findLocalAddress = function () {
  var ip_re = /(?!127)\d{1,3}\.(?!0)\d{1,3}\.(?!0)\d{1,3}\.\d{1,3}/;
    require('child_process').exec('ifconfig eth0 | grep \'inet addr:\' | cut -d: -f2 | awk \'{ print $1}\'', function (error, stdout, stderr) {
        if (stdout.search(ip_re) !== -1) {
            localAddress = stdout.trim();
            echo('local ip address: '+localAddress);
            startServer();
        } else {
          require('child_process').exec('ifconfig wlan0 | grep \'inet\' | cut -d: -f2 | awk \'{ print $2}\'', function (error, stdout, stderr) {
              if (stdout.search(ip_re) !== -1) {
                  localAddress = stdout.trim();
                  echo('local ip address: '+localAddress);
                  startServer();
              } else {
                require('child_process').exec('ifconfig en0 | grep \'inet\' | cut -d: -f2 | awk \'{ print $2}\'', function (error, stdout, stderr) {
                    if (stdout.search(ip_re) !== -1) {
                        localAddress = stdout.trim();
                        echo('local ip address: '+localAddress);
                        startServer();
                    } else {
                      require('child_process').exec('ifconfig en1 | grep \'inet\' | cut -d: -f2 | awk \'{ print $2}\'', function (error, stdout, stderr) {
                          if (stdout.search(ip_re) !== -1) {
                              localAddress = stdout.trim();
                              echo('local ip address: '+localAddress);
                              startServer();
                          } else {
                            require('child_process').exec('ip addr show | grep \'inet\' | cut -d: -f2 | awk \'{ print $2}\' | cut -d/ -f1', function (error, stdout, stderr) {
                                if (stdout.search(ip_re) !== -1) {
                                    localAddress = stdout.trim();
                                    echo('local ip address: '+localAddress);
                                    startServer();
                                } else {
                                    echo('couldn\'t find local ip address, play in offline mode');
                                    echo('.-.');
                                    playNextVideo();
                                }
                            });
                          }
                      });
                    }
                });
              }
          });
        }
    });
}

// start local http server
var startServer = function () {
    http.createServer(function (req_, res_) {
        req = req_;
        res = res_;
        if (req.method === 'GET') {
            req.on('close', function() { echo('connection remotely closed'); });
            req.on('data', function(data) { /* void */ });
            req.on('end', function() { parseRequest(); });
        } else {
            echo('error: no accepted HTTP method');
            respond('no');
        }
    }).listen(port, localAddress);
    echo('local server running at http://'+localAddress+':'+port);
    echo(',-´');
    // call peer for status
    callPeer('playing');
}

// parse incoming http requests
var parseRequest = function () {
    var url = urlmod.parse(req.url);
    if (url.href) {
        var cmd = url.href.slice(1);
        echo('peer call: '+cmd);
        if (cmd === 'playing') respond(isPlaying());
        else if (cmd === 'ended') playNextVideo();
        else respond('bad command');
    } else {
        echo('bad request: '+url);
        respond('bad request');
    }
}

// respond to peer http requests
var respond = function (data) {
    echo('response to peer: '+ data);
    var headers = {
        'Content-Length': Buffer.byteLength(data),
        'Content-Type': 'text/plain; charset=utf-8',
        'Expires': (new Date(Date.now)).toUTCString()
    }
    res.writeHead(200, headers);
    res.end(data);
}

// PEER QUERIES //////////////////////////

// call peer
var callPeer = function (msg) {
    echo('call peer: '+ msg);
    var url = 'http://'+peerAddress+':'+port+'/'+msg;
    http.get(url, function(res_) {
        res_.on('data', function (data) { parsePeerResponse(data) });
    }).on('error', function(e) {
        if (e.code === 'ECONNREFUSED') {
            echo('peer isn\'t ready, wait for a call')
            echo('|');
        }
    });
}

// parse peer's response to call
var parsePeerResponse = function (data) {
    echo('peer response: '+ data);
    if (data == 'no') {
        // peer is not playing, play local file
        echo('peer isn\'t playing, play');
        playNextVideo();
    } else {
        echo('peer is playing, wait for a call');
        echo('|');
        // wait for peer message, so, do nothing
    }
}

// VIDEO ///////////////////////////////////

// establish video playing status
var isPlaying = function () {
    if (playing) return 'yes';
    else return 'no';
}

// play video files
var playNextVideo = function () {
    // next file to play
    var filename = files[currFile];
    // if the next file doesn't exist, reset filename
    if (!filename) {
        currFile = 0;
        filename = files[0];
        warn('filename reset to: '+filename);
    }
    // play only if the file really exists
    if (!filename) {
        warn('filename is not valid: '+filename);
        exitFunction();
    } else {
      if (fs.existsSync(filename)) {
        currFile++;
        playing = true;
        echo('play video: '+filename);
        echo('..');
        // vidProc = (player === 'omxplayer') ? spawn('omxplayer', ['-o', 'local', filename]) : spawn('mplayer', ['-vm', filename]);
        switch (player) {
          case 'omxplayer':
            vidProc =  spawn(player, ['-o', 'local', filename]);
            break;
          case 'mplayer':
            vidProc = spawn(player, ['-vm', filename]);
            break;
          case 'vlc':
            vidProc = spawn(player, ['-f', '--play-and-exit', filename]);
            break;
          case '/Applications/VLC.app/Contents/MacOS/VLC':
            vidProc = spawn(player, ['-f', '--play-and-exit', filename]);
            break;
          case '~/Applications/VLC.app/Contents/MacOS/VLC':
            vidProc = spawn(player, ['-f', '--play-and-exit', filename]);
            break;
          default:
            vidProc = '';
        }
        vidProc.stdout.on('data', function (data) { echo(data.toString()); });
        vidProc.stderr.on('data', function (data) { echo(data.toString()); });
        vidProc.on('exit', function (code) {
            echo(player+' exited with code '+code);
            playing = false;
            callPeer('ended');
            echo('|');
        });
      } else {
        warn(filename+' doesn´t exist');
        exitFunction();
      }
    }
}

// PROCESS /////////////////////////////////

// parse process' incoming arguments
var parseArgv = function () {
    var conf;
    files = [];

    // parse arguments
    if (process.argv.length < 3) {
        // no arguments case
        conf = 'v-sync.conf';
        echo('no input arguments, will play from: '+conf);
    } else {
        process.argv.forEach(function (val, idx, arr) {
            if (val.search(/^\.*[^\.]+\.conf$/) !== -1) {
                // configuration file case
                conf = val;
                // readConf();
            } else if (val.search(/^\.*[^\.]+\.(mp4|m4v|mov)$/) !== -1) {
                // video filename case
                files.push(val);
            } else if (val.search(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) !== -1) {
                // peer address case
                peerAddress = val;
            }
        });
        if (conf) echo('input conf file(s): '+conf);
        if (files.length) echo('input video file(s): '+JSON.stringify(files));
        if (peerAddress) echo('input peer ip: '+peerAddress);
    }

    // if a configuration file was given
    if (conf) {
        var data;
        try {
          data = fs.readFileSync(conf, {encoding:'utf-8'});
        } catch (e) {
          warn('couldn´t load '+ conf);
          exitFunction();
          return;
        }

        if (data.length) {
            data.split('\n').forEach(function (val, idx, arr) {
                if (val.search(/^\.*[^\.]+\.(mp4|m4v|mov)$/) !== -1) {
                    // video filename case
                    files.push(val);
                    echo('will play: '+val);
                } else if (val.search(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) !== -1) {
                    // peer address case
                    peerAddress = val;
                    echo('will connect to: '+val);
                }
            });
        }
        if (files.length) echo('conf video file(s): '+JSON.stringify(files));
        if (peerAddress) echo('conf peer ip: '+peerAddress);
    }

    // if video files were given
    if (files.length) {
        // clear terminal, move cursor to top left and hide it
        // echo('\033[2J\033\033[H\033[?25l');

        // if a peer address was given
        if (peerAddress.length) {
            findLocalAddress();
        } else {
            echo('-.-');
            playNextVideo();
        }
    } else {
      exitFunction();
      return;
    }

    // failsafe
    if (!conf && !files.length) {
        exitFunction();
    }
}

// check whether other v-sync process is running on the system
var checkForDuplicates = function () {
    require('child_process').exec('ps aux | grep '+player+' | grep -v grep', function (error, stdout, stderr) {
        if (stdout.length) {
            warn('another video player is already running on this machine');
            warn(stdout);
            exitFunction();
        } else {
            echo('no other video player is running, v-sync will start');
            parseArgv();
        }
    });
}

// handle ctrl-C gracefully
process.on('SIGINT', function () {
    console.log(' ');
    exitFunction();
});

// START ///////////////////////////////////

// check which player is available on the system
require('child_process').exec('which omxplayer', function (error, stdout, stderr) {
    if (stdout[0] !== '/') {
        require('child_process').exec('which mplayer', function (error, stdout, stderr) {
            if (stdout[0] !== '/') {
              require('child_process').exec('which vlc', function (error, stdout, stderr) {
                  if (stdout[0] !== '/') {
                    require('child_process').exec('which /Applications/VLC.app/Contents/MacOS/VLC', function (error, stdout, stderr) {
                        if (stdout[0] !== '/') {
                          require('child_process').exec('which ~/Applications/VLC.app/Contents/MacOS/VLC', function (error, stdout, stderr) {
                              if (stdout[0] !== '/') {
                                  warn('no video player available');
                                  exitFunction();
                              } else {
                                  player = '~/Applications/VLC.app/Contents/MacOS/VLC';
                                  echo('available video player: '+player);
                                  checkForDuplicates();
                              }
                          });
                        } else {
                            player = '/Applications/VLC.app/Contents/MacOS/VLC';
                            echo('available video player: '+player);
                            checkForDuplicates();
                        }
                    });
                  } else {
                      player = 'vlc';
                      echo('available video player: '+player);
                      checkForDuplicates();
                  }
              });
            } else {
                player = 'mplayer';
                echo('available video player: '+player);
                checkForDuplicates();
            }
        });
    } else {
        player = 'omxplayer';
        echo('available video player: '+player);
        checkForDuplicates();
    }
});
<commit_msg>silenced player stdout<commit_after>var spawn = require('child_process').spawn,
    http = require('http'),
    urlmod = require('url'),
    fs = require('fs');
var vidProc,
    player,
    files = [],
    currFile = 0,
    playing = false;
var localAddress = '',
    peerAddress = '',
    port = 3000,
    req,
    res;

// INIT ////////////////////////////////////

var logLevel = 2;

// standardized exit function
var exitFunction = function (code) {
    console.log('exiting');
    if (code) console.log('exited with code '+code);
    // show cursor
    console.log('\033[?12l\033[?25h');
    process.exit();
}

var warn = function (msg) {
    if (logLevel > 0) console.log(msg);
}
var echo = function (msg) {
    if (logLevel > 1) console.log(msg);
}

// HTTP SERVER /////////////////////////////

// find local ip address
var findLocalAddress = function () {
  var ip_re = /(?!127)\d{1,3}\.(?!0)\d{1,3}\.(?!0)\d{1,3}\.\d{1,3}/;
    require('child_process').exec('ifconfig eth0 | grep \'inet addr:\' | cut -d: -f2 | awk \'{ print $1}\'', function (error, stdout, stderr) {
        if (stdout.search(ip_re) !== -1) {
            localAddress = stdout.trim();
            echo('local ip address: '+localAddress);
            startServer();
        } else {
          require('child_process').exec('ifconfig wlan0 | grep \'inet\' | cut -d: -f2 | awk \'{ print $2}\'', function (error, stdout, stderr) {
              if (stdout.search(ip_re) !== -1) {
                  localAddress = stdout.trim();
                  echo('local ip address: '+localAddress);
                  startServer();
              } else {
                require('child_process').exec('ifconfig en0 | grep \'inet\' | cut -d: -f2 | awk \'{ print $2}\'', function (error, stdout, stderr) {
                    if (stdout.search(ip_re) !== -1) {
                        localAddress = stdout.trim();
                        echo('local ip address: '+localAddress);
                        startServer();
                    } else {
                      require('child_process').exec('ifconfig en1 | grep \'inet\' | cut -d: -f2 | awk \'{ print $2}\'', function (error, stdout, stderr) {
                          if (stdout.search(ip_re) !== -1) {
                              localAddress = stdout.trim();
                              echo('local ip address: '+localAddress);
                              startServer();
                          } else {
                            require('child_process').exec('ip addr show | grep \'inet\' | cut -d: -f2 | awk \'{ print $2}\' | cut -d/ -f1', function (error, stdout, stderr) {
                                if (stdout.search(ip_re) !== -1) {
                                    localAddress = stdout.trim();
                                    echo('local ip address: '+localAddress);
                                    startServer();
                                } else {
                                    echo('couldn\'t find local ip address, play in offline mode');
                                    echo('.-.');
                                    playNextVideo();
                                }
                            });
                          }
                      });
                    }
                });
              }
          });
        }
    });
}

// start local http server
var startServer = function () {
    http.createServer(function (req_, res_) {
        req = req_;
        res = res_;
        if (req.method === 'GET') {
            req.on('close', function() { echo('connection remotely closed'); });
            req.on('data', function(data) { /* void */ });
            req.on('end', function() { parseRequest(); });
        } else {
            echo('error: no accepted HTTP method');
            respond('no');
        }
    }).listen(port, localAddress);
    echo('local server running at http://'+localAddress+':'+port);
    echo(',-´');
    // call peer for status
    callPeer('playing');
}

// parse incoming http requests
var parseRequest = function () {
    var url = urlmod.parse(req.url);
    if (url.href) {
        var cmd = url.href.slice(1);
        echo('peer call: '+cmd);
        if (cmd === 'playing') respond(isPlaying());
        else if (cmd === 'ended') playNextVideo();
        else respond('bad command');
    } else {
        echo('bad request: '+url);
        respond('bad request');
    }
}

// respond to peer http requests
var respond = function (data) {
    echo('response to peer: '+ data);
    var headers = {
        'Content-Length': Buffer.byteLength(data),
        'Content-Type': 'text/plain; charset=utf-8',
        'Expires': (new Date(Date.now)).toUTCString()
    }
    res.writeHead(200, headers);
    res.end(data);
}

// PEER QUERIES //////////////////////////

// call peer
var callPeer = function (msg) {
    echo('call peer: '+ msg);
    var url = 'http://'+peerAddress+':'+port+'/'+msg;
    http.get(url, function(res_) {
        res_.on('data', function (data) { parsePeerResponse(data) });
    }).on('error', function(e) {
        if (e.code === 'ECONNREFUSED') {
            echo('peer isn\'t ready, wait for a call')
            echo('|');
        }
    });
}

// parse peer's response to call
var parsePeerResponse = function (data) {
    echo('peer response: '+ data);
    if (data == 'no') {
        // peer is not playing, play local file
        echo('peer isn\'t playing, play');
        playNextVideo();
    } else {
        echo('peer is playing, wait for a call');
        echo('|');
        // wait for peer message, so, do nothing
    }
}

// VIDEO ///////////////////////////////////

// establish video playing status
var isPlaying = function () {
    if (playing) return 'yes';
    else return 'no';
}

// play video files
var playNextVideo = function () {
    // next file to play
    var filename = files[currFile];
    // if the next file doesn't exist, reset filename
    if (!filename) {
        currFile = 0;
        filename = files[0];
        warn('filename reset to: '+filename);
    }
    // play only if the file really exists
    if (!filename) {
        warn('filename is not valid: '+filename);
        exitFunction();
    } else {
      if (fs.existsSync(filename)) {
        currFile++;
        playing = true;
        echo('play video: '+filename);
        echo('..');
        // vidProc = (player === 'omxplayer') ? spawn('omxplayer', ['-o', 'local', filename]) : spawn('mplayer', ['-vm', filename]);
        switch (player) {
          case 'omxplayer':
            vidProc =  spawn(player, ['-o', 'local', filename], { stdio: 'silent' });
            break;
          case 'mplayer':
            vidProc = spawn(player, ['-vm', '-fs', filename], { stdio: 'silent' });
            break;
          case 'vlc':
            vidProc = spawn(player, ['-f', '--play-and-exit', filename], { stdio: 'silent' });
            break;
          case '/Applications/VLC.app/Contents/MacOS/VLC':
            vidProc = spawn(player, ['-f', '--play-and-exit', filename], { stdio: 'silent' });
            break;
          case '~/Applications/VLC.app/Contents/MacOS/VLC':
            vidProc = spawn(player, ['-f', '--play-and-exit', filename], { stdio: 'silent' });
            break;
          default:
            vidProc = '';
        }
        vidProc.stdout.on('data', function (data) { echo(data.toString()); });
        vidProc.stderr.on('data', function (data) { echo(data.toString()); });
        vidProc.on('exit', function (code) {
            echo(player+' exited with code '+code);
            playing = false;
            callPeer('ended');
            echo('|');
        });
      } else {
        warn(filename+' doesn´t exist');
        exitFunction();
      }
    }
}

// PROCESS /////////////////////////////////

// parse process' incoming arguments
var parseArgv = function () {
    var conf;
    files = [];

    // parse arguments
    if (process.argv.length < 3) {
        // no arguments case
        conf = 'v-sync.conf';
        echo('no input arguments, will play from: '+conf);
    } else {
        process.argv.forEach(function (val, idx, arr) {
            if (val.search(/^\.*[^\.]+\.conf$/) !== -1) {
                // configuration file case
                conf = val;
                // readConf();
            } else if (val.search(/^\.*[^\.]+\.(mp4|m4v|mov)$/) !== -1) {
                // video filename case
                files.push(val);
            } else if (val.search(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) !== -1) {
                // peer address case
                peerAddress = val;
            }
        });
        if (conf) echo('input conf file(s): '+conf);
        if (files.length) echo('input video file(s): '+JSON.stringify(files));
        if (peerAddress) echo('input peer ip: '+peerAddress);
    }

    // if a configuration file was given
    if (conf) {
        var data;
        try {
          data = fs.readFileSync(conf, {encoding:'utf-8'});
        } catch (e) {
          warn('couldn´t load '+ conf);
          exitFunction();
          return;
        }

        if (data.length) {
            data.split('\n').forEach(function (val, idx, arr) {
                if (val.search(/^\.*[^\.]+\.(mp4|m4v|mov)$/) !== -1) {
                    // video filename case
                    files.push(val);
                    echo('will play: '+val);
                } else if (val.search(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) !== -1) {
                    // peer address case
                    peerAddress = val;
                    echo('will connect to: '+val);
                }
            });
        }
        if (files.length) echo('conf video file(s): '+JSON.stringify(files));
        if (peerAddress) echo('conf peer ip: '+peerAddress);
    }

    // if video files were given
    if (files.length) {
        // clear terminal, move cursor to top left and hide it
        // echo('\033[2J\033\033[H\033[?25l');

        // if a peer address was given
        if (peerAddress.length) {
            findLocalAddress();
        } else {
            echo('-.-');
            playNextVideo();
        }
    } else {
      exitFunction();
      return;
    }

    // failsafe
    if (!conf && !files.length) {
        exitFunction();
    }
}

// check whether other v-sync process is running on the system
var checkForDuplicates = function () {
    require('child_process').exec('ps aux | grep '+player+' | grep -v grep', function (error, stdout, stderr) {
        if (stdout.length) {
            warn('another video player is already running on this machine');
            warn(stdout);
            exitFunction();
        } else {
            echo('no other video player is running, v-sync will start');
            parseArgv();
        }
    });
}

// handle ctrl-C gracefully
process.on('SIGINT', function () {
    console.log(' ');
    exitFunction();
});

// START ///////////////////////////////////

// check which player is available on the system
require('child_process').exec('which omxplayer', function (error, stdout, stderr) {
    if (stdout[0] !== '/') {
        require('child_process').exec('which mplayer', function (error, stdout, stderr) {
            if (stdout[0] !== '/') {
              require('child_process').exec('which vlc', function (error, stdout, stderr) {
                  if (stdout[0] !== '/') {
                    require('child_process').exec('which /Applications/VLC.app/Contents/MacOS/VLC', function (error, stdout, stderr) {
                        if (stdout[0] !== '/') {
                          require('child_process').exec('which ~/Applications/VLC.app/Contents/MacOS/VLC', function (error, stdout, stderr) {
                              if (stdout[0] !== '/') {
                                  warn('no video player available');
                                  exitFunction();
                              } else {
                                  player = '~/Applications/VLC.app/Contents/MacOS/VLC';
                                  echo('available video player: '+player);
                                  checkForDuplicates();
                              }
                          });
                        } else {
                            player = '/Applications/VLC.app/Contents/MacOS/VLC';
                            echo('available video player: '+player);
                            checkForDuplicates();
                        }
                    });
                  } else {
                      player = 'vlc';
                      echo('available video player: '+player);
                      checkForDuplicates();
                  }
              });
            } else {
                player = 'mplayer';
                echo('available video player: '+player);
                checkForDuplicates();
            }
        });
    } else {
        player = 'omxplayer';
        echo('available video player: '+player);
        checkForDuplicates();
    }
});
<|endoftext|>


<commit_before>/** @module supertask-cluster */
/// Required Core Modules
var cluster = require('cluster');
var os = require('os');
///
/// External Modules
var SuperTask = require('supertask');
var shortid = require('shortid');
var async = require('async');
///
/// Internal Modules
var BufferTransfer = require('./lib/BufferTransfer');
var StorageObject = require('./lib/StorageObject');
///
// No Operation function
function noop() { return null; }

/**
 * Creates new instance.
 * @constructor
 * @alias supertask-cluster
 * @example Creating a new instance.
 * var SuperTaskCluster = require('supertask-cluster');
 * var TaskCluster = new SuperTaskCluster();
 *
 * @returns {Instance} Returns a new instance of the module.
 */
var SuperTaskCluster = SuperTask;
var ClusterMap = new Map();
// Storage Map
var STC_STORAGE_MAP = new Map();

// Setup protocol
var CommunicationModel = require('./lib/CommunicationModel');
var COM = new CommunicationModel(cluster, STC_STORAGE_MAP);

/* AUTHOR'S NOTE *
The cluster's children can be called as
Worker/(child)process/thread/core/etc. depending
on your perspective on the underlying implementation
but for the sake of consistency they will be referred
to as Worker(s) in this module.
*/

SuperTaskCluster.prototype._STC_GET_ALIVE = function STC_GET_ALIVE() {
    var aliveWorkers = {};
    Object.keys(cluster.workers).forEach(function(id) {
        if(!cluster.workers[id].isDead()) {
            aliveWorkers[id] = cluster.workers[id];
        }
    });
    return aliveWorkers;
};

SuperTaskCluster.prototype._STC_HANDLER = function STC_HANDLER() {
    var args = Array.prototype.slice.call(arguments);
    var name = args.shift(), context = args.shift(), callback = args.pop();
    // Run task on a free Worker
    var Candidate = { v: Infinity, i: 'master', refs: 0 };
    // Check arguments for StorageObject (only supports Buffer for now)
    var RequiredBufferReferences = [];
    for(var i = 0; i < args.length; i++) {
        if(StorageObject.is(args[i])) {
            RequiredBufferReferences.push(args[i].name);
        }
    }
    // Find the best worker
    ClusterMap.forEach(function(Worker, ID) {
        if(!Worker.load) return;
        /* Prioritizing the last worker
        by using <= we set the priority to the
        last worker.
        */
        var hasRefs = 0;
        // If there are references filter workers with those references
        if(RequiredBufferReferences) COM.getmap().forEach(function(Store, name) {
            if(!Store) return;
            if(RequiredBufferReferences.indexOf(name) !== -1) {
                if(Store[ID] === true) hasRefs++;
            }
        });
        if((hasRefs > Candidate.refs) || (Worker.load.size <= Candidate.v)) {
            Candidate.v = Worker.load.size;
            Candidate.i = ID;
        }
    });
    if((Candidate.i === 'master') || (!cluster.workers[Candidate.i])) {
        // Apply locally
        this.get(name).model.func.apply(context, [callback]);
    }else{
        // Send to Cluster Worker
        var ticket = COM.send(Candidate.i, {
            type: "do",
            name: name,
            args: args
        }, true, function(error, success, response) {
            // Delete Load Ticket
            ClusterMap.get(Candidate.i).load.delete(ticket);
            if(error || !success) return callback(error || new Error("Unknown error occurred"));
            callback.apply(null, response.args || []);
        });
        ClusterMap.get(Candidate.i).load.set(ticket, true);
    }
};

SuperTaskCluster.prototype._STC_KILL = function STC_KILL(id, callback) {
    cluster.workers[id].kill();
    // Call callback once worker is dead
    if(callback) COM.once("CLUSTER_WORKER_DEAD::" + id, function(code, signal){
        callback(null, code, signal);
    });
};

SuperTaskCluster.prototype._STC_GRACEFUL_KILL = function STC_KILL(id, callback) {
    var _this = this;
    COM.send(id, { type: 'STC_KILL_YOURSELF_PLEASE' }, true, function(error) {
        // Worker denied to kill itself
        if(error && callback) return callback(error || new Error('Worker did not respect a graceful kill.'));

        _this._STC_KILL(id, callback);
    });
};

/**
 * Deploy/Redeploy workers based on the maximum number of workers. Use {@link SuperTaskCluster#setMaxWorkers} to set total workers.
 *
 * @param {Number} maxTotalWorkers - The maximum number of workers
 * that should be deployed at any given time.
 */
SuperTaskCluster.prototype.deploy = function STC_DEPLOY_CLUSTER(maxTotalWorkers) {
    var _this = this;
    this.STC_MAX_TOTAL_WORKERS = maxTotalWorkers || this.STC_MAX_TOTAL_WORKERS || os.cpus().length;
    var WorkersRequired = Math.max(this.STC_MAX_TOTAL_WORKERS - COM.headcount(), 0) || 0;

    // Prevent reseting setupMaster & recreating event listeners
    if(!this.STC_IS_CLUSTER_SETUP) {
        // Setup Master & Worker script
        cluster.setupMaster({
            exec: (this.STC_DEBUG)?'./lib/Worker.debug.js':'./lib/Worker.js',
            args: [],
            silent: (this.STC_DEBUG)?false:true
        });
        this.STC_IS_CLUSTER_SETUP = true;

        // Listen & Create ClusterMap
        cluster.on('fork', function(worker) {
            ClusterMap.set(worker.id, {
                load: new Map()
            });
            worker.on('message', function(response) {
                COM.incoming(worker.id, response);
            });
        });
        // Listen & respawn Workers
        cluster.on('exit', function CLUSTER_EXIT_LISTENER(worker, code, signal) {
            // Emit dead event
            COM.emit('CLUSTER_WORKER_DEAD::' + worker.id, code, signal);
            // Delete Map & inner Map
            if(ClusterMap.get(worker.id).load) ClusterMap.get(worker.id).load.clear();
            ClusterMap.delete(worker.id);
            // Delete Cluster from Buffer Map
            COM.getmap().forEach(function(value, key) {
                value[worker.id] = false;
            });
            if(this.STC_DEBUG) console.log('worker #' + worker.id + ' died');
            // Replace dead workers
            // this uses STC_MAX_TOTAL_WORKERS property
            // to prevent deploying extra workers
            _this.deploy();
        });
    }

    // Fork workers.
    for (var i = 0; i < WorkersRequired; i++) {
        // Give the Worker an id
        // Note that NODE_UNIQUE_ID doesn't seem to work with setupMaster
        // as env is not passed down
        cluster.setupMaster({args: [i]});
        cluster.fork();
    }
};

/**
 * Add a new task to SuperTask.
 *
 * @param {String} name - Unique name of the task.
 * @param {(String|Function)} source - Source/Function of the task.
 * @param {AddCallback} callback - The callback that handles the response.
 */
SuperTaskCluster.prototype.addShared = function STC_ADD_SHARED(name, source, callback) {
    // Overrides addShared implementation
    // VM requires a String source to compile
    // If given source is a function convert it to source (context is lost)
    if (typeof source === 'function') {
        source = 'module.exports = ' + source.toString();
    }
    var _this = this;
    this._addTask(name, source, this._STC_HANDLER.bind(this), SuperTask.ST_SHARED_TYPE, function(error, task) {
        if(error) return callback(error);
        // Extend Task Model
        task.distribute = function STC__TASK_MODEL_DISTRIBUTE(callback) {
            // Distribute task across cluster
            COM.broadcast({
                type: "task",
                name: task.model.name,
                source: task.model.source,
                isModule: task.model.isModule,
                priority: task.model.priority,
                defaultContext: task.model.defaultContext,
                access: task.model.access
            }, true, (callback)?callback:noop);
        };
        /**
         * @callback AddCallback
         * @param {Object} task
         */
        callback(null, task);
    });
};

/**
 * Get all alive Workers.
 *
 * @returns {Object} an Object including Worker objects indexed (keyed) by Worker ID.
 */
SuperTaskCluster.prototype.getWorkers = function STC_GET_WORKERS() {
    // Get all alive workers
    return this._STC_GET_ALIVE();
};

/**
 * Get total number of alive Workers.
 *
 * @returns {Number}
 */
SuperTaskCluster.prototype.totalWorkers = function STC_TOTAL_WORKERS() {
    // Returs total number of alive workers
    return COM.headcount();
};

/**
 * Set total number of Workers and deploy new Workers if higher than before. Note that this does
 * not reduce the number of workers (kill/terminate) but will add
 * new workers to the cluster if the given argument exceeds
 * previous maximum.
 *
 * @param {Number} maxTotalWorkers - The maximum number of workers
 * that should be deployed at any given time.
 */
SuperTaskCluster.prototype.setMaxWorkers = function STC_SET_MAX_WORKERS(n) {
    // Another interface to deploy
    this.deploy(n);
};

/**
 * Add and deploy new Workers to the Cluster.
 *
 * @param {Number} n - Adds n number of workers to the cluster.
 */
SuperTaskCluster.prototype.addWorkers = function STC_ADD_WORKERS(n) {
    // Add Additional workers
    this.STC_MAX_TOTAL_WORKERS += n;
    this.deploy();
};

/**
 * Forcefully/Gracefully kills a Worker. Note that another worker is immediately
 * forked to replace the killed Worker. In order to reduce the number of workers
 * set setMaxWorkers before calling this function.
 *
 * @param {Number} workerID - ID of the Worker
 * @param {Boolean} graceful=false - Determine if the Worker should be give the
 * chance to finish tasks before killing itself.
 * @param {Function} [callback] - An optional callback to determine when the
 * worker was actually killed. Calls with error, exitCode, signal arguments.
 */
SuperTaskCluster.prototype.killWorker = function STC_KILL_WORKER(workerID, graceful, callback) {
    if(!graceful) {
        this._STC_KILL(workerID, callback);
    }else{
        this._STC_GRACEFUL_KILL(workerID, callback);
    }
};

/**
 * Send/Upload a local Buffer object to a worker with the given ID. Note that although performance is relative to the hardware on average it takes about 20 seconds to upload a 1GB Buffer with nearly relative speeds for smaller sizes (e.g. 200ms for 10MB).
 *
 * @param {Number} workerID - ID of the Worker
 * @param {String} name - Unique Buffer name
 * @param {Buffer} buffer - A NodeJS Buffer object
 * @param {String} encoding - Encoding type of Buffer e.g. 'utf8'
 * @param {Boolean} mutable=true - Indicates whether Buffer will be mutable/editable
 * in the Worker or copies of the buffer will be passed.
 * @param {Boolean} [chunky] - Indicates whether the Buffer should be sent in
 * chunks or whole. Anything above 64kb will be sent in chunks by default
 * which is a good idea.
 * @param {Function} [callback] - Called after Buffer and its chunks have been
 * fully uploaded to the Worker.
 */
SuperTaskCluster.prototype.createBufferOnWorker = function STC_CREATE_BUFFER(workerID, name, buffer, encoding, mutable, chunky, callback) {
    COM.buffer(workerID, name, buffer, encoding, mutable, chunky, callback);
};

/**
 * Send/Upload a local Buffer object to a worker with the given ID. Note that although performance is relative to the hardware on average it takes about 20 seconds to upload a 1GB Buffer with nearly relative speeds for smaller sizes (e.g. 200ms for 10MB).
 *
 * @param {Number} workerID - ID of the Worker
 * @param {String} name - Buffer name
 * @param {Function} [callback] - Called after Buffer and its chunks have been
 * fully downloaded. Buffer will be passed as the second argument followed by encoding
 */
SuperTaskCluster.prototype.getBufferFromWorker = function STC_CREATE_BUFFER(workerID, name, callback) {
    COM.send(workerID, {
        type: "buffer",
        subtype: "get",
        name: name
    }, false, function(error) {
        if(error) return callback(error);
        var BufferObject = STC_STORAGE_MAP.get(name);
        callback(error, BufferObject.get(), BufferObject.encoding);
    });
};

/**
 * Creates a Buffer reference on a Worker
 * as a passable argument
 *
 * @param {String} name - Name of the Buffer uploaded to the Worker
 * using {@link SuperTaskCluster#createBufferOnWorker}
 * @returns {Object} reference - A reference that can be passed as an argument
 * to do function.
 */
SuperTaskCluster.prototype.workerBufferReference = function STC_BUFFER_REF(name, partition) {
    return StorageObject.create('Buffer', name, partition);
};

/**
 * Set the cluster to debug. Note that this uses a separate Worker code
 * therefore currently online Workers will not log debug information.
 *
 * @param {Boolean} toggle - Toggles debug.
 */
SuperTaskCluster.prototype.setClusterDebug = function STC_SET_DEBUG(toggle) {
    this.STC_DEBUG = (!!toggle);
};

/**
 * Gets/Sets the cluster response timeout. Callbacks will be called if the
 * response has taken more than this set amount of time with a timeout error.
 * Defaults to 30,000 ms or 30 seconds.
 *
 * @param {Number} [time] - time in milliseconds (ms)
 * @returns {Number} time
 */
SuperTaskCluster.prototype.clusterResponseTimeout = function STC_CRESPONSE_TIMEOUT(time) {
    if(time) COM.CLUSTER_TIMEOUT = time;
    return COM.CLUSTER_TIMEOUT;
};

module.exports = SuperTaskCluster;<commit_msg>Updated getBufferFromWorker to work with partitions<commit_after>/** @module supertask-cluster */
/// Required Core Modules
var cluster = require('cluster');
var os = require('os');
///
/// External Modules
var SuperTask = require('supertask');
var shortid = require('shortid');
var async = require('async');
///
/// Internal Modules
var BufferTransfer = require('./lib/BufferTransfer');
var StorageObject = require('./lib/StorageObject');
///
// No Operation function
function noop() { return null; }

/**
 * Creates new instance.
 * @constructor
 * @alias supertask-cluster
 * @example Creating a new instance.
 * var SuperTaskCluster = require('supertask-cluster');
 * var TaskCluster = new SuperTaskCluster();
 *
 * @returns {Instance} Returns a new instance of the module.
 */
var SuperTaskCluster = SuperTask;
var ClusterMap = new Map();
// Storage Map
var STC_STORAGE_MAP = new Map();

// Setup protocol
var CommunicationModel = require('./lib/CommunicationModel');
var COM = new CommunicationModel(cluster, STC_STORAGE_MAP);

/* AUTHOR'S NOTE *
The cluster's children can be called as
Worker/(child)process/thread/core/etc. depending
on your perspective on the underlying implementation
but for the sake of consistency they will be referred
to as Worker(s) in this module.
*/

SuperTaskCluster.prototype._STC_GET_ALIVE = function STC_GET_ALIVE() {
    var aliveWorkers = {};
    Object.keys(cluster.workers).forEach(function(id) {
        if(!cluster.workers[id].isDead()) {
            aliveWorkers[id] = cluster.workers[id];
        }
    });
    return aliveWorkers;
};

SuperTaskCluster.prototype._STC_HANDLER = function STC_HANDLER() {
    var args = Array.prototype.slice.call(arguments);
    var name = args.shift(), context = args.shift(), callback = args.pop();
    // Run task on a free Worker
    var Candidate = { v: Infinity, i: 'master', refs: 0 };
    // Check arguments for StorageObject (only supports Buffer for now)
    var RequiredBufferReferences = [];
    for(var i = 0; i < args.length; i++) {
        if(StorageObject.is(args[i])) {
            RequiredBufferReferences.push(args[i].name);
        }
    }
    // Find the best worker
    ClusterMap.forEach(function(Worker, ID) {
        if(!Worker.load) return;
        /* Prioritizing the last worker
        by using <= we set the priority to the
        last worker.
        */
        var hasRefs = 0;
        // If there are references filter workers with those references
        if(RequiredBufferReferences) COM.getmap().forEach(function(Store, name) {
            if(!Store) return;
            if(RequiredBufferReferences.indexOf(name) !== -1) {
                if(Store[ID] === true) hasRefs++;
            }
        });
        if((hasRefs > Candidate.refs) || (Worker.load.size <= Candidate.v)) {
            Candidate.v = Worker.load.size;
            Candidate.i = ID;
        }
    });
    if((Candidate.i === 'master') || (!cluster.workers[Candidate.i])) {
        // Apply locally
        this.get(name).model.func.apply(context, [callback]);
    }else{
        // Send to Cluster Worker
        var ticket = COM.send(Candidate.i, {
            type: "do",
            name: name,
            args: args
        }, true, function(error, success, response) {
            // Delete Load Ticket
            ClusterMap.get(Candidate.i).load.delete(ticket);
            if(error || !success) return callback(error || new Error("Unknown error occurred"));
            callback.apply(null, response.args || []);
        });
        ClusterMap.get(Candidate.i).load.set(ticket, true);
    }
};

SuperTaskCluster.prototype._STC_KILL = function STC_KILL(id, callback) {
    cluster.workers[id].kill();
    // Call callback once worker is dead
    if(callback) COM.once("CLUSTER_WORKER_DEAD::" + id, function(code, signal){
        callback(null, code, signal);
    });
};

SuperTaskCluster.prototype._STC_GRACEFUL_KILL = function STC_KILL(id, callback) {
    var _this = this;
    COM.send(id, { type: 'STC_KILL_YOURSELF_PLEASE' }, true, function(error) {
        // Worker denied to kill itself
        if(error && callback) return callback(error || new Error('Worker did not respect a graceful kill.'));

        _this._STC_KILL(id, callback);
    });
};

/**
 * Deploy/Redeploy workers based on the maximum number of workers. Use {@link SuperTaskCluster#setMaxWorkers} to set total workers.
 *
 * @param {Number} maxTotalWorkers - The maximum number of workers
 * that should be deployed at any given time.
 */
SuperTaskCluster.prototype.deploy = function STC_DEPLOY_CLUSTER(maxTotalWorkers) {
    var _this = this;
    this.STC_MAX_TOTAL_WORKERS = maxTotalWorkers || this.STC_MAX_TOTAL_WORKERS || os.cpus().length;
    var WorkersRequired = Math.max(this.STC_MAX_TOTAL_WORKERS - COM.headcount(), 0) || 0;

    // Prevent reseting setupMaster & recreating event listeners
    if(!this.STC_IS_CLUSTER_SETUP) {
        // Setup Master & Worker script
        cluster.setupMaster({
            exec: (this.STC_DEBUG)?'./lib/Worker.debug.js':'./lib/Worker.js',
            args: [],
            silent: (this.STC_DEBUG)?false:true
        });
        this.STC_IS_CLUSTER_SETUP = true;

        // Listen & Create ClusterMap
        cluster.on('fork', function(worker) {
            ClusterMap.set(worker.id, {
                load: new Map()
            });
            worker.on('message', function(response) {
                COM.incoming(worker.id, response);
            });
        });
        // Listen & respawn Workers
        cluster.on('exit', function CLUSTER_EXIT_LISTENER(worker, code, signal) {
            // Emit dead event
            COM.emit('CLUSTER_WORKER_DEAD::' + worker.id, code, signal);
            // Delete Map & inner Map
            if(ClusterMap.get(worker.id).load) ClusterMap.get(worker.id).load.clear();
            ClusterMap.delete(worker.id);
            // Delete Cluster from Buffer Map
            COM.getmap().forEach(function(value, key) {
                value[worker.id] = false;
            });
            if(this.STC_DEBUG) console.log('worker #' + worker.id + ' died');
            // Replace dead workers
            // this uses STC_MAX_TOTAL_WORKERS property
            // to prevent deploying extra workers
            _this.deploy();
        });
    }

    // Fork workers.
    for (var i = 0; i < WorkersRequired; i++) {
        // Give the Worker an id
        // Note that NODE_UNIQUE_ID doesn't seem to work with setupMaster
        // as env is not passed down
        cluster.setupMaster({args: [i]});
        cluster.fork();
    }
};

/**
 * Add a new task to SuperTask.
 *
 * @param {String} name - Unique name of the task.
 * @param {(String|Function)} source - Source/Function of the task.
 * @param {AddCallback} callback - The callback that handles the response.
 */
SuperTaskCluster.prototype.addShared = function STC_ADD_SHARED(name, source, callback) {
    // Overrides addShared implementation
    // VM requires a String source to compile
    // If given source is a function convert it to source (context is lost)
    if (typeof source === 'function') {
        source = 'module.exports = ' + source.toString();
    }
    var _this = this;
    this._addTask(name, source, this._STC_HANDLER.bind(this), SuperTask.ST_SHARED_TYPE, function(error, task) {
        if(error) return callback(error);
        // Extend Task Model
        task.distribute = function STC__TASK_MODEL_DISTRIBUTE(callback) {
            // Distribute task across cluster
            COM.broadcast({
                type: "task",
                name: task.model.name,
                source: task.model.source,
                isModule: task.model.isModule,
                priority: task.model.priority,
                defaultContext: task.model.defaultContext,
                access: task.model.access
            }, true, (callback)?callback:noop);
        };
        /**
         * @callback AddCallback
         * @param {Object} task
         */
        callback(null, task);
    });
};

/**
 * Get all alive Workers.
 *
 * @returns {Object} an Object including Worker objects indexed (keyed) by Worker ID.
 */
SuperTaskCluster.prototype.getWorkers = function STC_GET_WORKERS() {
    // Get all alive workers
    return this._STC_GET_ALIVE();
};

/**
 * Get total number of alive Workers.
 *
 * @returns {Number}
 */
SuperTaskCluster.prototype.totalWorkers = function STC_TOTAL_WORKERS() {
    // Returs total number of alive workers
    return COM.headcount();
};

/**
 * Set total number of Workers and deploy new Workers if higher than before. Note that this does
 * not reduce the number of workers (kill/terminate) but will add
 * new workers to the cluster if the given argument exceeds
 * previous maximum.
 *
 * @param {Number} maxTotalWorkers - The maximum number of workers
 * that should be deployed at any given time.
 */
SuperTaskCluster.prototype.setMaxWorkers = function STC_SET_MAX_WORKERS(n) {
    // Another interface to deploy
    this.deploy(n);
};

/**
 * Add and deploy new Workers to the Cluster.
 *
 * @param {Number} n - Adds n number of workers to the cluster.
 */
SuperTaskCluster.prototype.addWorkers = function STC_ADD_WORKERS(n) {
    // Add Additional workers
    this.STC_MAX_TOTAL_WORKERS += n;
    this.deploy();
};

/**
 * Forcefully/Gracefully kills a Worker. Note that another worker is immediately
 * forked to replace the killed Worker. In order to reduce the number of workers
 * set setMaxWorkers before calling this function.
 *
 * @param {Number} workerID - ID of the Worker
 * @param {Boolean} graceful=false - Determine if the Worker should be give the
 * chance to finish tasks before killing itself.
 * @param {Function} [callback] - An optional callback to determine when the
 * worker was actually killed. Calls with error, exitCode, signal arguments.
 */
SuperTaskCluster.prototype.killWorker = function STC_KILL_WORKER(workerID, graceful, callback) {
    if(!graceful) {
        this._STC_KILL(workerID, callback);
    }else{
        this._STC_GRACEFUL_KILL(workerID, callback);
    }
};

/**
 * Send/Upload a local Buffer object to a worker with the given ID. Note that although performance is relative to the hardware on average it takes about 20 seconds to upload a 1GB Buffer with nearly relative speeds for smaller sizes (e.g. 200ms for 10MB).
 *
 * @param {Number} workerID - ID of the Worker
 * @param {String} name - Unique Buffer name
 * @param {Buffer} buffer - A NodeJS Buffer object
 * @param {String} encoding - Encoding type of Buffer e.g. 'utf8'
 * @param {Boolean} mutable=true - Indicates whether Buffer will be mutable/editable
 * in the Worker or copies of the buffer will be passed.
 * @param {Boolean} [chunky] - Indicates whether the Buffer should be sent in
 * chunks or whole. Anything above 64kb will be sent in chunks by default
 * which is a good idea.
 * @param {Function} [callback] - Called after Buffer and its chunks have been
 * fully uploaded to the Worker.
 */
SuperTaskCluster.prototype.createBufferOnWorker = function STC_CREATE_BUFFER(workerID, name, buffer, encoding, mutable, chunky, callback) {
    COM.buffer(workerID, name, buffer, encoding, mutable, chunky, callback);
};

/**
 * Send/Upload a local Buffer object to a worker with the given ID. Note that although performance is relative to the hardware on average it takes about 20 seconds to upload a 1GB Buffer with nearly relative speeds for smaller sizes (e.g. 200ms for 10MB).
 *
 * @param {Number} workerID - ID of the Worker
 * @param {String} name - Buffer name
 * @param {Function} [callback] - Called after Buffer and its chunks have been
 * fully downloaded. Buffer will be passed as the second argument followed by encoding
 */
SuperTaskCluster.prototype.getBufferFromWorker = function STC_CREATE_BUFFER(workerID, name, partition, callback) {
    // Parameter override
    if(typeof partition === 'function') {
        callback = partition;
        partition = null;
    }
    COM.send(workerID, {
        type: "buffer",
        subtype: "get",
        name: name
    }, false, function(error) {
        partition: partition || {}
        if(error) return callback(error);
        var BufferObject = STC_STORAGE_MAP.get(name);
        callback(error, BufferObject.get(), BufferObject.encoding);
    });
};

/**
 * Creates a Buffer reference on a Worker
 * as a passable argument
 *
 * @param {String} name - Name of the Buffer uploaded to the Worker
 * using {@link SuperTaskCluster#createBufferOnWorker}
 * @returns {Object} reference - A reference that can be passed as an argument
 * to do function.
 */
SuperTaskCluster.prototype.workerBufferReference = function STC_BUFFER_REF(name, partition) {
    return StorageObject.create('Buffer', name, partition);
};

/**
 * Set the cluster to debug. Note that this uses a separate Worker code
 * therefore currently online Workers will not log debug information.
 *
 * @param {Boolean} toggle - Toggles debug.
 */
SuperTaskCluster.prototype.setClusterDebug = function STC_SET_DEBUG(toggle) {
    this.STC_DEBUG = (!!toggle);
};

/**
 * Gets/Sets the cluster response timeout. Callbacks will be called if the
 * response has taken more than this set amount of time with a timeout error.
 * Defaults to 30,000 ms or 30 seconds.
 *
 * @param {Number} [time] - time in milliseconds (ms)
 * @returns {Number} time
 */
SuperTaskCluster.prototype.clusterResponseTimeout = function STC_CRESPONSE_TIMEOUT(time) {
    if(time) COM.CLUSTER_TIMEOUT = time;
    return COM.CLUSTER_TIMEOUT;
};

module.exports = SuperTaskCluster;<|endoftext|>


<commit_before><commit_msg>plugins: jsAPI: add gripper for setproperties api endpoint<commit_after><|endoftext|>


<commit_before>var histograms = function() {

  var hists = [];

  function ready(){
    refresh = histograms_refresh;
    module_ready();
  }

  function histograms_refresh() {
    module_get(update, error);
  }

  function update(data) {
    module_update(data);

    var histograms = data.histograms;
    var d3hists = Object.keys(histograms).reduce(function(acc, key){
      var d3hist = histogram1d.process_histogram(histograms[key]);
      d3hist.columnName = key;
      acc.push(d3hist);
      return acc;
    }, []);

    var charts = d3hists.map(function(elt){
      return histogram1d.chart(elt);
    });

    var histElts = d3.select("#histograms").selectAll(".hist").data(d3hists);
    var hist = histElts.enter()
                      .append("div")
                      .attr("class", "hist");
    hist.append("div")
        .attr("class", "colName")
        .text(function(d){ return d.columnName; });
    hist.append("div")
        .attr("class", "chart");

    var chartElts = d3.select("#histograms").selectAll(".chart").data(charts);

    chartElts.each(function(elt, idx){
      //update data
      charts[idx].histogram(d3hists[idx]);
      //render
      charts[idx](d3.select(this));
    });

  }

  function error(err) {
    console.log(err);
  }

  return {
    ready: ready,
  };
}();
<commit_msg>remove exit selection elements<commit_after>var histograms = function() {

  var hists = [];

  function ready(){
    refresh = histograms_refresh;
    module_ready();
  }

  function histograms_refresh() {
    module_get(update, error);
  }

  function update(data) {
    module_update(data);

    var histograms = data.histograms;
    var d3hists = Object.keys(histograms).reduce(function(acc, key){
      var d3hist = histogram1d.process_histogram(histograms[key]);
      d3hist.columnName = key;
      acc.push(d3hist);
      return acc;
    }, []);

    var charts = d3hists.map(function(elt){
      return histogram1d.chart(elt);
    });

    var histElts = d3.select("#histograms").selectAll(".hist").data(d3hists);
    var hist = histElts.enter()
                      .append("div")
                      .attr("class", "hist");
    hist.append("div")
        .attr("class", "colName")
        .text(function(d){ return d.columnName; });
    hist.append("div")
        .attr("class", "chart");

    var chartElts = d3.select("#histograms").selectAll(".chart").data(charts);

    chartElts.each(function(elt, idx){
      //update data
      charts[idx].histogram(d3hists[idx]);
      //render
      charts[idx](d3.select(this));
    });

    histElts.exit().remove();

  }

  function error(err) {
    console.log(err);
  }

  return {
    ready: ready,
  };
}();
<|endoftext|>


<commit_before>(function () {
    var $lightbox = $('#lightbox');
    var $section = $lightbox.find('section');
    var $content = $lightbox.find('.content');
    var currentApp;
    var previews;
    var slider;

    // prevent mouse cursors from dragging these images.
    $lightbox.on('dragstart', function(e) {
        e.preventDefault();
    });

    function showLightbox() {
        var which = $(this).closest('li').index();
        var $tray = $(this).closest('.tray');
        var $tile = $tray.prev();

        // we get the screenshots from the associated tile. No tile? bail.
        if (!$tile.hasClass('mkt-tile')) return;

        var product = $tile.data('product');
        var id = product.id;

        if (id != currentApp || !slider) {
            currentApp = id;
            previews = product.previews;
            renderPreviews();
        }

        // set up key bindings
        $(window).bind('keydown.lightboxDismiss', function(e) {
            switch (e.which) {
                case z.keys.ESCAPE:
                    e.preventDefault();
                    hideLightbox();
                    break;
                case z.keys.LEFT:
                    e.preventDefault();
                    if (slider) slider.toPrev();
                    break;
                case z.keys.RIGHT:
                    e.preventDefault();
                    if (slider) slider.toNext();
                    break;
            }
        });

        // fade that bad boy in
        $lightbox.show();
        setTimeout(function() {
            slider.moveToPoint(which);
            resize();
            $lightbox.addClass('show');
        }, 0);
    }

    function renderPreviews() {
        // clear out the existing content
        $content.empty();

        // place in a pane for each image/video with a 'loading' placeholder
        // and caption.
        _.each(previews, function(p) {
            var $el = $('
');
            var $cap = $('
');
            $cap.text(p.caption);
            $el.append($cap);
            $content.append($el);

            // let's fail elegantly when our images don't load.
            // videos on the other hand will always be injected.
            if (p.type == 'video/webm') {
                // we can check for `HTMLMediaElement.NETWORK_NO_SOURCE` on the
                // video's `networkState` property at some point.
                var v = $('<video src="' + p.fullUrl + '" controls></video>');
                $el.removeClass('loading');
                $el.append(v);
            } else {
                var i = new Image();

                i.onload = function() {
                    $el.removeClass('loading');
                    $el.append(i);
                };
                i.onerror = function() {
                    $el.removeClass('loading');
                    $el.append('⚠');
                };

                // attempt to load the image.
                i.src = p.fullUrl;
            }
        });

        // $section doesn't have its proper width until after a paint.
        slider = Flipsnap($content[0]);
    }

    // we need to adjust the scroll distances on resize.
    $(window).on('resize', _.debounce(resize, 200));

    function resize() {
        if (!slider) return;
        $content.find('.caption').lineclamp(2);
        slider.distance = $section.width();
        slider.refresh();
    }

    // if a tray thumbnail is clicked, load up our lightbox.
    z.page.on('click', '.tray ul a', _pd(showLightbox));

    // dismiss the lighbox when we click outside it or on the close button.
    $lightbox.click(function(e) {
        if ($(e.target).is('#lightbox')) {
            hideLightbox();
            e.preventDefault();
        }
    });
    $lightbox.find('.close').click(_pd(function(e) {
        hideLightbox();
    }));

    function hideLightbox() {
        $lightbox.removeClass('show');
        $content.find('video')[0].pause();
        // We can't trust transitionend to fire in all cases.
        setTimeout(function() {
            $lightbox.hide();
        }, 500);
        $(window).unbind('keydown.lightboxDismiss');
    }

})();

<commit_msg>pause video only if it exists<commit_after>(function () {
    var $lightbox = $('#lightbox');
    var $section = $lightbox.find('section');
    var $content = $lightbox.find('.content');
    var currentApp;
    var previews;
    var slider;

    // prevent mouse cursors from dragging these images.
    $lightbox.on('dragstart', function(e) {
        e.preventDefault();
    });

    function showLightbox() {
        var which = $(this).closest('li').index();
        var $tray = $(this).closest('.tray');
        var $tile = $tray.prev();

        // we get the screenshots from the associated tile. No tile? bail.
        if (!$tile.hasClass('mkt-tile')) return;

        var product = $tile.data('product');
        var id = product.id;

        if (id != currentApp || !slider) {
            currentApp = id;
            previews = product.previews;
            renderPreviews();
        }

        // set up key bindings
        $(window).bind('keydown.lightboxDismiss', function(e) {
            switch (e.which) {
                case z.keys.ESCAPE:
                    e.preventDefault();
                    hideLightbox();
                    break;
                case z.keys.LEFT:
                    e.preventDefault();
                    if (slider) slider.toPrev();
                    break;
                case z.keys.RIGHT:
                    e.preventDefault();
                    if (slider) slider.toNext();
                    break;
            }
        });

        // fade that bad boy in
        $lightbox.show();
        setTimeout(function() {
            slider.moveToPoint(which);
            resize();
            $lightbox.addClass('show');
        }, 0);
    }

    function renderPreviews() {
        // clear out the existing content
        $content.empty();

        // place in a pane for each image/video with a 'loading' placeholder
        // and caption.
        _.each(previews, function(p) {
            var $el = $('
');
            var $cap = $('
');
            $cap.text(p.caption);
            $el.append($cap);
            $content.append($el);

            // let's fail elegantly when our images don't load.
            // videos on the other hand will always be injected.
            if (p.type == 'video/webm') {
                // we can check for `HTMLMediaElement.NETWORK_NO_SOURCE` on the
                // video's `networkState` property at some point.
                var v = $('<video src="' + p.fullUrl + '" controls></video>');
                $el.removeClass('loading');
                $el.append(v);
            } else {
                var i = new Image();

                i.onload = function() {
                    $el.removeClass('loading');
                    $el.append(i);
                };
                i.onerror = function() {
                    $el.removeClass('loading');
                    $el.append('⚠');
                };

                // attempt to load the image.
                i.src = p.fullUrl;
            }
        });

        // $section doesn't have its proper width until after a paint.
        slider = Flipsnap($content[0]);
    }

    // we need to adjust the scroll distances on resize.
    $(window).on('resize', _.debounce(resize, 200));

    function resize() {
        if (!slider) return;
        $content.find('.caption').lineclamp(2);
        slider.distance = $section.width();
        slider.refresh();
    }

    // if a tray thumbnail is clicked, load up our lightbox.
    z.page.on('click', '.tray ul a', _pd(showLightbox));

    // dismiss the lighbox when we click outside it or on the close button.
    $lightbox.click(function(e) {
        if ($(e.target).is('#lightbox')) {
            hideLightbox();
            e.preventDefault();
        }
    });
    $lightbox.find('.close').click(_pd(function(e) {
        hideLightbox();
    }));

    function hideLightbox() {
        var vid = $content.find('video');
        $lightbox.removeClass('show');
        if (vid.length) {
            vid[0].pause();
        }
        // We can't trust transitionend to fire in all cases.
        setTimeout(function() {
            $lightbox.hide();
        }, 500);
        $(window).unbind('keydown.lightboxDismiss');
    }

})();

<|endoftext|>


<commit_before>

/**
 * Yo, the single page dependency management script created by pocketninja for his own amusement
 *
 * @module Yo
 * @returns {object} public functions
 */
var Yo = function() {
  // Yo.loadedState.tooltip.{
  //    loaded: boolean
  //    loadedFunc: function
  //    dependedBy: [string],
  //    dependencies: [string]
  // }

  /**
   * container of the namespace object provided by the user with Yo.init()
   * @private
   * @var {object} ns
   */
  var ns;
  var scriptRoot = 'modules';

  /**
   * After creating Yo you need to provide it with your main namespace to any level within it. Like "company" or "company.cool.scripts"
   *
   * @method init
   * @param {object} data - initial data object.
   * @param {object} data.namespace - users main script namespace.
   *
   * @example
   * Yo.init({
   *   namespace: your.script.name.space,
   *   scriptRoot: 'cheese'
   * });
   */
  var init = function(data){
    ns = data.namespace || Yo;
    Yo.loadedState = {};
    if(data.scriptRoot) {
      scriptRoot = data.scriptRoot;
    }
    ns[scriptRoot] = ns[scriptRoot] || {};
  };

  var isTypeOf = function(str, obj) {
    return '[object ' + str + ']' === Object.prototype.toString.call(obj);
  };

  var argumentChecker = function(args, argSequence) {
    if(args.length === argSequence.length) {
      var i, val;
      for (i = 0; i < args.length; i++) {
        val = args[i];
        if (!isTypeOf(argSequence[i], val)) {
          console.log('Error with value comparison: ' + val + ', EXPECTED: ' + argSequence[i]);
          return false;
        }
      }

      return true;
    }
    else {
      return false;
    }
  };

  var arrayClone = function(arr) {
    return arr.slice(0);
  };

  var extend = function() {
    for(var i=1; i < arguments.length; i++) {
      for(var key in arguments[i]) {
        if(arguments[i].hasOwnProperty(key)) {
          arguments[0][key] = arguments[i][key];
        }
      }
    }
    return arguments[0];
  };

  /**
   * Gets either and object or false
   *
   * @method add
   * @param {string} _nsStr Script namespace or name
   * @param {object} _nsObject Namespace object
   * @param {boolean} _getObjectRoot What does this mean !!!?
   *
   * @returns {object || boolean} functions
   *
   */
  var nsGet = function(_nsStr, _nsObject, _getObjectRoot) {
    var keyArr = _nsStr.split('.');
    var currentObj = _nsObject;
    _getObjectRoot = _getObjectRoot || false;

    for(var i = 0; i < keyArr.length; i++) {
      if (!currentObj[keyArr[i]]) {
        return false;
      }
      if(_getObjectRoot && (i === keyArr.length - 1)) {
        return currentObj;
      }
      currentObj = currentObj[keyArr[i]];
    }

    return currentObj;
  };

  /**
   * Set new branches to your namespace tree
   * WIll run through the object tree creating
   * everything that doesn't exist.
   *
   * @method add
   * @param {string} _nsStr Script namespace or name
   * @param {object} _nsObject Namespace object
   * @param {boolean} _getObjectRoot What does this mean, find out?!?!?
   *
   * @returns {object} Section of the object param
   *
   */
  var nsSet = function(_nsStr, _nsObject, _getObjectRoot) {
    var keyArr = _nsStr.split('.');
    var currentObj = _nsObject;
    _getObjectRoot = _getObjectRoot || false;

    if (keyArr.length < 2) {
      if(!currentObj[_nsStr]) {
        currentObj[_nsStr] = {};
      }
      if(_getObjectRoot) {
        return _nsObject;
      }
      return currentObj[_nsStr];
    }
    else {
      for(var i = 0; i < keyArr.length; i++) {
        if (!currentObj[keyArr[i]]) {
          currentObj[keyArr[i]] = {};
        }
        if(_getObjectRoot && (i === keyArr.length - 1)) {
          return currentObj;
        }
        currentObj = currentObj[keyArr[i]];
      }
    }

    return currentObj;
  };

  /**
   * For adding new scripts with their own dependencies
   *
   * @method add
   * @param {string} scriptName Script name
   * @param {array} [scriptDependencies=undefined] Script list of dependencies
   * @param {function} scriptCallback Script module callback
   *
   * @example
   * Yo.add('WidgetName', ['dependency1', 'dependency2', 'etc'], function() {
   *   // your code in here
   *   return {}
   * });
   */
  var add = function() {

    var scriptName;
    var scriptDependencies = [];
    var scriptCallback;
    var hasNoDependencies = true;

    var getLoadedState = function(_script) {
      return nsGet(_script, Yo.loadedState);
    };

    var setLoadedState = function(_script, _data) {
      extend(nsSet(_script, Yo.loadedState), _data);
    };

    var activateScript = function(_script) {
      var nsLocation = nsSet(_script, ns[scriptRoot], true);
      var lastNameSpace = _script.split('.');
      lastNameSpace = lastNameSpace[lastNameSpace.length - 1];

      if(getLoadedState(_script).loaded) {
        nsLocation[lastNameSpace] = getLoadedState(_script).loadedFunc();
        getLoadedState(_script).runAfterActivation();
      }
    };

    var getScript = function(_script) {
      return nsSet(_script, ns[scriptRoot]);
    };

    var createOrEditLoadedState = function(_data, _script) {
      _script = _script || scriptName;

      setLoadedState(_script, extend({
        loaded: false,
        loadedFunc: function(){},
        runAfterActivation: function(){},
        dependedBy: [],
        dependencies: []
      }, nsSet(_script, Yo.loadedState) || {}, _data));
    };

    /**
     * Callback added to loadState[scriptName].loadedFunc which is run once all of it's dependencies have loaded
     *
     * @function pushFunction
     * @private
     */
    var pushFunction = function() {
      createOrEditLoadedState({
        loaded: true,
        loadedFunc: function() { console.log(scriptName + ' called and already loaded'); }
      });

      return scriptCallback.apply(null, scriptDependencies.map(function(_scriptName) {
        return getScript(_scriptName);
      }));
    };

    var checkDependedBy = function() {
      var dependedBy = getLoadedState(scriptName).dependedBy;

      dependedBy.forEach(function(otherScript) {
        for(var i = 0; i < dependedBy.length; i++) {
          for(var a = 0; a < getLoadedState(otherScript).dependencies.length; a++) {
            if (getLoadedState(otherScript).dependencies[a] === scriptName) {
              getLoadedState(otherScript).dependencies.splice(a, 1);
              dependedBy.splice(i, 1);
              break;
            }
          }
        }

        if (getLoadedState(otherScript).dependencies.length < 1) {
          getLoadedState(otherScript).loaded = true;
          activateScript(otherScript);
        }
      });
    };

    var checkDependencies = function() {
      var allDependenciesLoaded = true;
      var scriptDependents = getLoadedState(scriptName).dependencies;
      var dependencyScriptName;

      var looper = function() {
        for(var i = 0; i < scriptDependents.length; i++) {
          dependencyScriptName = scriptDependents[i];
          // If script name loadState doesn't
          // exist then create one
          if(!nsGet(dependencyScriptName, Yo.loadedState)) {
            createOrEditLoadedState({}, dependencyScriptName);
          }

          if(!getLoadedState(dependencyScriptName).loaded) {
            getLoadedState(dependencyScriptName).dependedBy.push(scriptName);
            allDependenciesLoaded = false;
          }
          else {
            scriptDependents.splice(i, 1);
            looper();
            break;
          }
        }
      };

      looper();

      if(allDependenciesLoaded) {
        getLoadedState(scriptName).loaded = true;
      }
    };

    if(argumentChecker(arguments, ['String', 'Array', 'Function'])) {
      scriptName = arguments[0].toLowerCase();
      scriptDependencies = arguments[1];
      scriptCallback = arguments[2];
      hasNoDependencies = scriptDependencies.length < 1;
    }
    else if(argumentChecker(arguments, ['String', 'Function'])) {
      scriptName = arguments[0].toLowerCase();
      scriptCallback = arguments[1];
    }
    else {
      console.log('incorrect params added', arguments);
      return false;
    }

    //console.log('YO.ADD: ' + scriptName);

    if (hasNoDependencies) {
      createOrEditLoadedState({
        loaded: true,
        loadedFunc: scriptCallback
      });
      activateScript(scriptName);
      checkDependedBy();
    }
    else {
      createOrEditLoadedState({
        loadedFunc: pushFunction,
        dependencies: arrayClone(scriptDependencies),
        runAfterActivation: function() {
          checkDependedBy();
        }
      });
      checkDependencies();
      activateScript(scriptName);
    }
  };

  return {
    init: init,
    add: add,
    isTypeOf: isTypeOf,
    argumentChecker: argumentChecker,
    arrayClone: arrayClone,
    extend: extend
  }
}();<commit_msg>added jsdoc notes<commit_after>

/**
 * Yo, the single page dependency management script created by pocketninja for his own amusement
 *
 * @module Yo
 * @returns {object} public functions
 */
var Yo = function() {
  "use strict";

  // Yo.loadedState.tooltip.{
  //    loaded: boolean
  //    loadedFunc: function
  //    dependedBy: [string],
  //    dependencies: [string]
  // }

  /**
   * container of the namespace object provided by the user with Yo.init()
   * @private
   * @var {object} ns
   */
  var ns;
  var scriptRoot = 'modules';

  /**
   * After creating Yo you need to provide it with your main namespace to any level within it. Like "company" or "company.cool.scripts"
   *
   * @method init
   * @param {object} data - initial data object.
   * @param {object} data.namespace - users main script namespace.
   *
   * @example
   * Yo.init({
   *   namespace: your.script.name.space,
   *   scriptRoot: 'cheese'
   * });
   */
  var init = function(data){
    ns = data.namespace || Yo;
    Yo.loadedState = {};
    if(data.scriptRoot) {
      scriptRoot = data.scriptRoot;
    }
    ns[scriptRoot] = ns[scriptRoot] || {};
  };

  var isTypeOf = function(str, obj) {
    return '[object ' + str + ']' === Object.prototype.toString.call(obj);
  };

  /**
   * Arguments checker
   *
   * Take an array of arguments and compare it's type with an array sequence of
   * strings type values.
   *
   * @method argumentChecker
   * @param {array} args List of arguments
   * @param {array} argSequence List of String argument types
   *
   * @returns {object || boolean} functions
   *
   */
  var argumentChecker = function(args, argSequence) {
    if(args.length === argSequence.length) {
      var i, val;
      for (i = 0; i < args.length; i++) {
        val = args[i];
        if (!isTypeOf(argSequence[i], val)) {
          console.log('Error with value comparison: ' + val + ', EXPECTED: ' + argSequence[i]);
          return false;
        }
      }

      return true;
    }
    else {
      return false;
    }
  };

  var arrayClone = function(arr) {
    return arr.slice(0);
  };

  var extend = function() {
    for(var i=1; i < arguments.length; i++) {
      for(var key in arguments[i]) {
        if(arguments[i].hasOwnProperty(key)) {
          arguments[0][key] = arguments[i][key];
        }
      }
    }
    return arguments[0];
  };

  /**
   * Gets either and object or false
   *
   * @method nsGet
   * @param {string} _nsStr Script namespace or name
   * @param {object} _nsObject Namespace object
   * @param {boolean} _getObjectRoot What does this mean !!!?
   *
   * @returns {object || boolean} functions
   *
   */
  var nsGet = function(_nsStr, _nsObject, _getObjectRoot) {
    var keyArr = _nsStr.split('.');
    var currentObj = _nsObject;
    _getObjectRoot = _getObjectRoot || false;

    for(var i = 0; i < keyArr.length; i++) {
      if (!currentObj[keyArr[i]]) {
        return false;
      }
      if(_getObjectRoot && (i === keyArr.length - 1)) {
        return currentObj;
      }
      currentObj = currentObj[keyArr[i]];
    }

    return currentObj;
  };

  /**
   * Set new branches to your namespace tree
   * WIll run through the object tree creating
   * everything that doesn't exist.
   *
   * @method nsSet
   * @param {string} _nsStr Script namespace or name
   * @param {object} _nsObject Namespace object
   * @param {boolean} _getObjectRoot What does this mean, find out?!?!?
   *
   * @returns {object} Section of the object param
   *
   */
  var nsSet = function(_nsStr, _nsObject, _getObjectRoot) {
    var keyArr = _nsStr.split('.');
    var currentObj = _nsObject;
    _getObjectRoot = _getObjectRoot || false;

    if (keyArr.length < 2) {
      if(!currentObj[_nsStr]) {
        currentObj[_nsStr] = {};
      }
      if(_getObjectRoot) {
        return _nsObject;
      }
      return currentObj[_nsStr];
    }
    else {
      for(var i = 0; i < keyArr.length; i++) {
        if (!currentObj[keyArr[i]]) {
          currentObj[keyArr[i]] = {};
        }
        if(_getObjectRoot && (i === keyArr.length - 1)) {
          return currentObj;
        }
        currentObj = currentObj[keyArr[i]];
      }
    }

    return currentObj;
  };

  /**
   * For adding new scripts with their own dependencies
   *
   * @method add
   * @param {string} scriptName Script name
   * @param {array} [scriptDependencies=undefined] Script list of dependencies
   * @param {function} scriptCallback Script module callback
   *
   * @example
   * Yo.add('WidgetName', ['dependency1', 'dependency2', 'etc'], function() {
   *   // your code in here
   *   return {}
   * });
   */
  var add = function() {

    var scriptName;
    var scriptDependencies = [];
    var scriptCallback;
    var hasNoDependencies = true;

    var getLoadedState = function(_script) {
      return nsGet(_script, Yo.loadedState);
    };

    var setLoadedState = function(_script, _data) {
      extend(nsSet(_script, Yo.loadedState), _data);
    };

    var activateScript = function(_script) {
      var nsLocation = nsSet(_script, ns[scriptRoot], true);
      var lastNameSpace = _script.split('.');
      lastNameSpace = lastNameSpace[lastNameSpace.length - 1];

      if(getLoadedState(_script).loaded) {
        nsLocation[lastNameSpace] = getLoadedState(_script).loadedFunc();
        getLoadedState(_script).runAfterActivation();
      }
    };

    var getScript = function(_script) {
      return nsSet(_script, ns[scriptRoot]);
    };

    var createOrEditLoadedState = function(_data, _script) {
      _script = _script || scriptName;

      setLoadedState(_script, extend({
        loaded: false,
        loadedFunc: function(){},
        runAfterActivation: function(){},
        dependedBy: [],
        dependencies: []
      }, nsSet(_script, Yo.loadedState) || {}, _data));
    };

    /**
     * Callback added to loadState[scriptName].loadedFunc which is run once all of it's dependencies have loaded
     *
     * @function pushFunction
     * @private
     */
    var pushFunction = function() {
      createOrEditLoadedState({
        loaded: true,
        loadedFunc: function() { console.log(scriptName + ' called and already loaded'); }
      });

      return scriptCallback.apply(null, scriptDependencies.map(function(_scriptName) {
        return getScript(_scriptName);
      }));
    };

    var checkDependedBy = function() {
      var dependedBy = getLoadedState(scriptName).dependedBy;

      dependedBy.forEach(function(otherScript) {
        for(var i = 0; i < dependedBy.length; i++) {
          for(var a = 0; a < getLoadedState(otherScript).dependencies.length; a++) {
            if (getLoadedState(otherScript).dependencies[a] === scriptName) {
              getLoadedState(otherScript).dependencies.splice(a, 1);
              dependedBy.splice(i, 1);
              break;
            }
          }
        }

        if (getLoadedState(otherScript).dependencies.length < 1) {
          getLoadedState(otherScript).loaded = true;
          activateScript(otherScript);
        }
      });
    };

    var checkDependencies = function() {
      var allDependenciesLoaded = true;
      var scriptDependents = getLoadedState(scriptName).dependencies;
      var dependencyScriptName;

      var looper = function() {
        for(var i = 0; i < scriptDependents.length; i++) {
          dependencyScriptName = scriptDependents[i];
          // If script name loadState doesn't
          // exist then create one
          if(!nsGet(dependencyScriptName, Yo.loadedState)) {
            createOrEditLoadedState({}, dependencyScriptName);
          }

          if(!getLoadedState(dependencyScriptName).loaded) {
            getLoadedState(dependencyScriptName).dependedBy.push(scriptName);
            allDependenciesLoaded = false;
          }
          else {
            scriptDependents.splice(i, 1);
            looper();
            break;
          }
        }
      };

      looper();

      if(allDependenciesLoaded) {
        getLoadedState(scriptName).loaded = true;
      }
    };

    if(argumentChecker(arguments, ['String', 'Array', 'Function'])) {
      scriptName = arguments[0].toLowerCase();
      scriptDependencies = arguments[1];
      scriptCallback = arguments[2];
      hasNoDependencies = scriptDependencies.length < 1;
    }
    else if(argumentChecker(arguments, ['String', 'Function'])) {
      scriptName = arguments[0].toLowerCase();
      scriptCallback = arguments[1];
    }
    else {
      console.log('incorrect params added', arguments);
      return false;
    }

    console.log('YO.ADD: ' + scriptName);

    if (hasNoDependencies) {
      createOrEditLoadedState({
        loaded: true,
        loadedFunc: scriptCallback
      });
      activateScript(scriptName);
      checkDependedBy();
    }
    else {
      createOrEditLoadedState({
        loadedFunc: pushFunction,
        dependencies: arrayClone(scriptDependencies),
        runAfterActivation: function() {
          checkDependedBy();
        }
      });
      checkDependencies();
      activateScript(scriptName);
    }
  };

  return {
    init: init,
    add: add,
    isTypeOf: isTypeOf,
    argumentChecker: argumentChecker,
    arrayClone: arrayClone,
    extend: extend
  }
}();<|endoftext|>


<commit_before>//collapse page navs after use
$(function(){
	$('body').delegate('.content-secondary .ui-collapsible-content', 'click',  function(){
		$(this).trigger("collapse");
	});
});

// display the version of jQM
$(function() {
	var version = $.mobile.version || "dev",
		words = version.split( "-" ),
		ver = words[0],
		str = (words[1] || "Final"),
		html = ver;

	str = str.charAt( 0 ).toUpperCase() + str.slice( 1 );
	if ( $.mobile.version && str ) {
		html += " " + str + "";
	}
	$( "p.jqm-version" ).html( html );
})

// Turn off AJAX for local file browsing
if ( location.protocol.substr(0,4)  === 'file' ||
     location.protocol.substr(0,11) === '*-extension' ||
     location.protocol.substr(0,6)  === 'widget' ) {

  // Start with links with only the trailing slash and that aren't external links
  var fixLinks = function() {
    $( "a[href$='/'], a[href='.'], a[href='..']" ).not( "[rel='external']" ).each( function() {
      this.href = $( this ).attr( "href" ).replace( /\/$/, "" ) + "/index.html";
    });
  };

  // fix the links for the initial page
  $(fixLinks);

  // fix the links for subsequent ajax page loads
  $(document).bind( 'pagecreate', fixLinks );

  // Check to see if ajax can be used. This does a quick ajax request and blocks the page until its done
  $.ajax({
    url: '.',
    async: false,
    isLocal: true
  }).error(function() {
    // Ajax doesn't work so turn it off
    $( document ).bind( "mobileinit", function() {
      $.mobile.ajaxEnabled = false;

      var message = $( '
' , {
        'class': "ui-footer ui-bar-e",
        style: "overflow: auto; padding:10px 15px;",
        'data-ajax-warning': true
      });

      message
        .append( "
Note: Navigation may not work if viewed locally
" )
        .append( "
The AJAX-based navigation used throughout the jQuery Mobile docs may need to be viewed on a web server to work in certain browsers. If you see an error message when you click a link, try a different browser or view help.
" );

      $( document ).bind( "pagecreate", function( event ) {
        $( event.target ).append( message );
      });
    });
  });
}
<commit_msg>Docs: Suggestion for #4211 Version text disappears; $() := pageinit<commit_after>//collapse page navs after use
$(function(){
	$('body').delegate('.content-secondary .ui-collapsible-content', 'click',  function(){
		$(this).trigger("collapse");
	});
});

// display the version of jQM
$(document).bind( 'pageinit', function() {
	var version = $.mobile.version || "dev",
		words = version.split( "-" ),
		ver = words[0],
		str = (words[1] || "Final"),
		html = ver;

	str = str.charAt( 0 ).toUpperCase() + str.slice( 1 );
	if ( $.mobile.version && str ) {
		html += " " + str + "";
	}
	$( "p.jqm-version" ).html( html );
})

// Turn off AJAX for local file browsing
if ( location.protocol.substr(0,4)  === 'file' ||
     location.protocol.substr(0,11) === '*-extension' ||
     location.protocol.substr(0,6)  === 'widget' ) {

  // Start with links with only the trailing slash and that aren't external links
  var fixLinks = function() {
    $( "a[href$='/'], a[href='.'], a[href='..']" ).not( "[rel='external']" ).each( function() {
      this.href = $( this ).attr( "href" ).replace( /\/$/, "" ) + "/index.html";
    });
  };

  // fix the links for the initial page
  $(fixLinks);

  // fix the links for subsequent ajax page loads
  $(document).bind( 'pagecreate', fixLinks );

  // Check to see if ajax can be used. This does a quick ajax request and blocks the page until its done
  $.ajax({
    url: '.',
    async: false,
    isLocal: true
  }).error(function() {
    // Ajax doesn't work so turn it off
    $( document ).bind( "mobileinit", function() {
      $.mobile.ajaxEnabled = false;

      var message = $( '
' , {
        'class': "ui-footer ui-bar-e",
        style: "overflow: auto; padding:10px 15px;",
        'data-ajax-warning': true
      });

      message
        .append( "
Note: Navigation may not work if viewed locally
" )
        .append( "
The AJAX-based navigation used throughout the jQuery Mobile docs may need to be viewed on a web server to work in certain browsers. If you see an error message when you click a link, try a different browser or view help.
" );

      $( document ).bind( "pagecreate", function( event ) {
        $( event.target ).append( message );
      });
    });
  });
}
<|endoftext|>


<commit_before>"use strict";
function LsFunction() {
	let placeholder = "available";
	let resultTimeout = 8000;

	//Register a function by its name, itself (callback) and the needed time span for the check cycle
	this.RegisterLocalStorageFunction = function(name, callback) {

		//Set local storage items for function and its result
		resetFunction(name);

		//Setting the event
		window.addEventListener('storage', function(e) {
			//Getting the params or eventually just the placeholder

			//Call the function if params are set and reset all
			if (e.key === name && e.newValue != placeholder) {
				let result = callback(e.newValue);
				//Set result
				localStorage.setItem(name + "Result", result);
				//Reset call
				localStorage.setItem(name, placeholder);
			}
		});
	}

	this.CallLocalStorageFunction = function(name, params, callback) {
		//Check if the function is already called
		if (localStorage.getItem(name) == placeholder && localStorage.getItem(name + "Result") == placeholder) {

			//Call remote function
			localStorage.setItem(name, params);

			//Define timeout and event for future usage
			let timeout = {};
			let storageEvent = {};

			//Check in interval for result
			storageEvent = function(e) {
				//Check wheter the result is set
				if (e.key == name + "Result" && e.newValue != placeholder) {
					//Call callback with results
					callback(e.newValue);

					//Reset result in local storage
					localStorage.setItem(name + "Result", placeholder);

					//Dismiss listener and timeout
					clearTimeout(timeout);
					window.removeEventListener('storage', storageEvent, false);
				}
			}

			//Add listener to event
			window.addEventListener('storage', storageEvent);

			//Start timout to cancel listener if no result is set, hence no remote function was called
			timeout = setTimeout(function() {
				//Dismiss interval
				clearTimeout(timeout);
				//Clean up
				window.removeEventListener('storage', storageEvent, false);
			}, resultTimeout);
		}
	}

	//Reset local storage values
	function resetFunction(name) {
		localStorage.setItem(name, placeholder);
		localStorage.setItem(name + "Result", placeholder);
	}
};
<commit_msg>Update communicator2.js<commit_after>"use strict";
/*
The MIT License (MIT)
Copyright (c) 2016 Astasian
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
https://github.com/Astasian/LocalStorageFunctionCall
*/
function LsFunction() {
	let placeholder = "available";
	let resultTimeout = 8000;

	//Register a function by its name, itself (callback) and the needed time span for the check cycle
	this.RegisterLocalStorageFunction = function(name, callback) {

		//Set local storage items for function and its result
		resetFunction(name);

		//Setting the event
		window.addEventListener('storage', function(e) {
			//Getting the params or eventually just the placeholder

			//Call the function if params are set and reset all
			if (e.key === name && e.newValue != placeholder) {
				let result = callback(e.newValue);
				//Set result
				localStorage.setItem(name + "Result", result);
				//Reset call
				localStorage.setItem(name, placeholder);
			}
		});
	}

	this.CallLocalStorageFunction = function(name, params, callback) {
		//Check if the function is already called
		if (localStorage.getItem(name) == placeholder && localStorage.getItem(name + "Result") == placeholder) {

			//Call remote function
			localStorage.setItem(name, params);

			//Define timeout and event for future usage
			let timeout = {};
			let storageEvent = {};

			//Check in interval for result
			storageEvent = function(e) {
				//Check wheter the result is set
				if (e.key == name + "Result" && e.newValue != placeholder) {
					//Call callback with results
					callback(e.newValue);

					//Reset result in local storage
					localStorage.setItem(name + "Result", placeholder);

					//Dismiss listener and timeout
					clearTimeout(timeout);
					window.removeEventListener('storage', storageEvent, false);
				}
			}

			//Add listener to event
			window.addEventListener('storage', storageEvent);

			//Start timout to cancel listener if no result is set, hence no remote function was called
			timeout = setTimeout(function() {
				//Dismiss interval
				clearTimeout(timeout);
				//Clean up
				window.removeEventListener('storage', storageEvent, false);
			}, resultTimeout);
		}
	}

	//Reset local storage values
	function resetFunction(name) {
		localStorage.setItem(name, placeholder);
		localStorage.setItem(name + "Result", placeholder);
	}
};
<|endoftext|>


<commit_before>const gulp = require('gulp');

const path = require('path');
const bsHtmlInjector = require('bs-html-injector');

const setup = require('setup/setup');

module.exports = function(taskDone) {
  const assets = setup.assets;

  const watches = assets.watch;

  gulp.watch(watches.docs, gulp.parallel('build:docs'));
  gulp.watch(watches.styles, gulp.parallel('build:styles'));
  gulp.watch(
    [watches.scripts],
    gulp.parallel('build:scripts', 'build:modernizr')
  );
  gulp.watch(watches.images, gulp.parallel('build:images'));
  gulp.watch(watches.extras, gulp.parallel('build:extras'));
  gulp.watch(path.join(assets.build, assets.dest.docs), bsHtmlInjector);
  taskDone();
};
<commit_msg>Cleanup removed task<commit_after>const gulp = require('gulp');

const path = require('path');
const bsHtmlInjector = require('bs-html-injector');

const setup = require('setup/setup');

module.exports = function(taskDone) {
  const assets = setup.assets;

  const watches = assets.watch;

  gulp.watch(watches.docs, gulp.parallel('build:docs'));
  gulp.watch(watches.styles, gulp.parallel('build:styles'));
  gulp.watch(
    [watches.scripts],
    gulp.parallel('build:scripts')
  );
  gulp.watch(watches.images, gulp.parallel('build:images'));
  gulp.watch(watches.extras, gulp.parallel('build:extras'));
  gulp.watch(path.join(assets.build, assets.dest.docs), bsHtmlInjector);
  taskDone();
};
<|endoftext|>


<commit_before>var FullScreenFallback = function() {
	FullScreenFallback._super.constructor.apply(this, arguments);
};

extend(FullScreenFallback, FullScreenAbstract, {
	__isFullScreen: false,
	__allowedKeys: [
		// left arrow, right arrow, up arrow, down arrow, space, page up, page down, home, end, tab,
		37, 39, 38, 40, 32, 0, 0, 0, 0, 9,
		// meta, shift, control, alt
		224, 16, 17, 18
	],
	__keydownHandler: function(e) {
		if (!this.isFullScreen()) {
			return true;
		}

		var key = e.which;
		for (var i = 0; i < this.__allowedKeys.length; ++i) {
			if (key === this.__allowedKeys[i]) {
				return true;
			}
		}

		this.exit();
		return false; // ?
	},
	_init: function() {
		FullScreenFallback._super._init.apply(this, arguments);

		$(document).delegate('*', 'keydown.fullscreen', $.proxy(this.__keydownHandler, this)); // use delegateFirst?
	},
	open: function(elem) {
		FullScreenFallback._super.open.apply(this, arguments);
		this.__isFullScreen = true;
		this._fullScreenChange();
	},
	exit: function() {
		this.__isFullScreen = false;
		this._fullScreenChange();
	},
	isFullScreen: function() {
		return this.__isFullScreen;
	}
});
<commit_msg>more allowed keys added<commit_after>var FullScreenFallback = function() {
	FullScreenFallback._super.constructor.apply(this, arguments);
};

extend(FullScreenFallback, FullScreenAbstract, {
	__isFullScreen: false,
	__allowedKeys: [
		// left arrow, right arrow, up arrow, down arrow, space, page up, page down, home, end, tab,
		37, 39, 38, 40, 32, 33, 34, 36, 35, 9,
		// shift, control, alt, cmd, win
		16, 17, 18, 224, 91
	],
	__keydownHandler: function(e) {
		if (!this.isFullScreen() || $.inArray(e.which, this.__allowedKeys) !== -1) {
			return true;
		}

		this.exit();
		return false; // ?
	},
	_init: function() {
		FullScreenFallback._super._init.apply(this, arguments);

		$(document).delegate('*', 'keydown.fullscreen', $.proxy(this.__keydownHandler, this)); // use delegateFirst?
	},
	open: function(elem) {
		FullScreenFallback._super.open.apply(this, arguments);
		this.__isFullScreen = true;
		this._fullScreenChange();
	},
	exit: function() {
		this.__isFullScreen = false;
		this._fullScreenChange();
	},
	isFullScreen: function() {
		return this.__isFullScreen;
	}
});
<|endoftext|>