<commit_before>'use strict';

/**
 * App.Views.ListItem
 * @type {*}
 */
App.Views.ListItem = Backbone.View.extend({
    render: function () {
        // grep template with jquery and generate template stub
        var html = App.render(this.options.template, { model: this.model });
        if (html) {
            // fill model date into template and push it into element html
            this.$el.html(html);

            // add element id with prefix
            this.$el.attr('id', this.elId());
        }

        return this;
    },
    remove: function () {
        this.undelegateEvents();
        this.$el.detach().remove();
        return this;
    },
    elId: function () {
        var id = this.model.get('id');
        return (this.options.prefix) ? this.options.prefix + id : id;
    }
});

/**
 * App.Views.List
 * @type {*}
 */
App.Views.List = Backbone.View.extend({
    options: {
        prefix: '',
        item: {
            attributes: {},
            prepend: false,
            prependNew: false,
            tagName: 'div',
            template: '',
            View: App.Views.ListItem
        }
    },
    initialize: function (config) {
        this.items = {};
        // Assign function to collection events
        if (this.collection) {
            this.collection.on('reset', this.addAll, this);
            this.collection.on('sort', this.addAll, this);
            this.collection.on('add', this.addItem, this);
            this.collection.on('change', this.changeItem, this);
            this.collection.on('remove', this.removeItem, this);
        }
    },
    render: function () {
        if (this.options.templateEl) {
            this.setElement(this.options.templateEl);
        }

        if (this.collection) {
            this.addAll();
        }

        return this;
    },
    remove: function () {
        for (var name in this.items) {
            if (this.items.hasOwnProperty(name)) {
                this.items[name].remove();
            }
        }
        this.items = {};

        if (this.collection) {
            this.collection.off('reset', this.addAll, this);
            this.collection.off('sort', this.addAll, this);
            this.collection.off('add', this.addItem, this);
            this.collection.off('change', this.changeItem, this);
            this.collection.off('remove', this.removeItem, this);
        }
        return this;
    },
    addAll: function () {
        var tEmpty = '', that = this;

        if (this.options.emptyTemplate) {
            tEmpty = App.render(this.options.emptyTemplate);
        }

        // remove all content
        this.$el.addClass('loading').html('');

        // run addItem on each collection item
        if (this.collection && this.collection.length > 0) {
            this.options.isEmpty = false;

            if (this.options.groupBy && that.options.groupBy.key) {
                var groupTemplate = App.render(this.options.groupBy.template),
                    items = this.collection.groupBy(that.options.groupBy.key),
                    sorted = _.without(_.keys(items), 'undefined').sort();

                for (var i = 0; i < sorted.length; i++) {
                    var name = sorted[i];
                    this.addElement($(groupTemplate({ title: name })));
                    _.each(items[name], function (model) {
                        var view = that.renderItem(model);
                        that.items[model.id] = view;
                        that.addElement(view.$el);
                    });
                }

                if (items['undefined'] && this.options.groupBy['undefined']) {
                    this.addElement($(groupTemplate({ title: this.options.groupBy['undefined'] })));
                    _.each(items['undefined'], function (model) {
                        var view = that.renderItem(model);
                        that.items[model.id] = view;
                        that.addElement(view.$el);
                    });
                }

            } else {
                this.collection.each(function (model) {
                    var view = that.renderItem(model);
                    that.items[model.id] = view;
                    that.addElement(view.$el);
                });
            }
        }

        this.$el.removeClass('loading');

        if (this.options.emptyTemplate && this.$el.is(":empty")) {
            this.$el.html(tEmpty());
            this.options.isEmpty = true;
        }
        return this;
    },
    addElement: function ($el) {
        if (!$el.is(':empty')) {
            if (this.options.item.prepend) {
                this.$el.prepend($el);
            } else {
                this.$el.append($el);
            }
        }
    },
    addItem: function (model) {
        if (this.options.isEmpty) {
            this.$el.html('');
            this.options.isEmpty = false;
        }

        var view = this.renderItem(model);
        this.addElement(view.$el);
        this.items[model.id] = view;

        return this;
    },
    changeItem: function (model) {
        if (model.id !== undefined) {
            var oldView = this.items[model.id],
                newItem = this.renderItem(model);

            //newItem.$el.addClass(classes);
            //item.replaceWith(newItem.el);
            oldView.$el.after(newItem.el);
            oldView.remove();
            this.items[model.id] = newItem;
        } else { // run addAll if item has no Id
            this.addAll();
        }
        return this;
    },
    renderItem: function (model) {
        return new this.options.item.View({
            model: model,
            collection: this.collection,
            prefix: this.options.prefix,
            attributes: this.options.item.attributes,
            tagName: this.options.item.tagName,
            template: this.options.item.template
        }).render();
    },
    removeItem: function (model) {
        if (model.id !== undefined) {
            $('#' + this.options.prefix + model.id).empty().detach();
            if (this.collection.length === 0) {
                this.collection.reset();
            }
        }
        return this;
    }
});

App.Module.Object = {
    'Set': function(obj, path, value) {
        if (_.isString(path)) {
            path = path.split('.');
        }
        var parent = obj,
            len = path.length;

        for (var i=0; i<len; i++) {
            var name = path[i];
            if (i >= len - 1) {
                if (name.search(/\[\]/) !== -1) {
                    name = name.replace('[]', '');
                    if (parent[name] === undefined) {
                        parent[name] = [];
                    }
                    parent[name].push(value);
                } else {
                    parent[name] = value;
                }
            } else if (parent[name] === undefined) {
                parent[name] = {};
            }
            parent = parent[name];
        }

        return obj;
    },
    'Get': function(obj, path) {
        if (obj && path) {
            if (_.isString(path)) {
                path = path.split('.');
            }

            var parent = obj;
            for (var i=0; i<path.length; i++) {
                var name = path[i].replace('[]', '');
                if (parent[name]) {
                    parent = parent[name];
                } else {
                    parent = undefined;
                    break;
                }
            }

            return parent;
        }
        return undefined;
    }
};

App.Module.Form = {
    Bind: function($form, data, ignore) {
        ignore = ignore || {};

        $(':input[name]', $form).each(function (idx, input) {
            var $input = $(input),
                name = input.name;

            if (name && !ignore[name]) {
                var parts = name.split('-'),
                    value = App.Module.Object.Get(data, parts);

                switch (input.type) {
                    case 'checkbox':
                        input.checked = (value !== undefined);
                        break;
                    case 'radio':
                        input.checked = ($input.val() == value);
                        break;
                    default:
                        $input.val(value);
                }
                $input.trigger('change');
            }
        });
    },
    Serialize: function($form, ignore, withoutEmpty) {
        ignore = ignore || {};
        var data = {},
            component = {};

        // Grep inputs with name
        $(':input[name]', $form).each(function (idx, input) {
            var $input = $(input),
                name = input.name;

            if (name) {
                if (component[name]) {
                    return;
                }

                var val = $input.val(),
                    parts = name.split('-');

                switch(input.type) {
                    case 'checkbox':
                        if (input.checked) {
                            if (val === undefined || _.isEmpty(val)) {
                                val = true;
                            }
                        } else {
                            val = false;
                        }
                        break;
                    case 'radio':
                        if (input.checked) {
                            component[name] = true;
                            if (val === undefined || _.isEmpty(val)) {
                                val = true;
                            }
                        } else {
                            val = false;
                        }
                        break;
                    case 'button': // button values are not intresting
                        return;
                }

                if (withoutEmpty) {
                    if (val === undefined || _.isEmpty(val)) {
                        return;
                    }
                }

                App.Module.Object.Set(data, parts, val);
            }
        });

        return data;
    }
};
<commit_msg>add all only when collection has items<commit_after>'use strict';

/**
 * App.Views.ListItem
 * @type {*}
 */
App.Views.ListItem = Backbone.View.extend({
    render: function () {
        // grep template with jquery and generate template stub
        var html = App.render(this.options.template, { model: this.model });
        if (html) {
            // fill model date into template and push it into element html
            this.$el.html(html);

            // add element id with prefix
            this.$el.attr('id', this.elId());
        }

        return this;
    },
    remove: function () {
        this.undelegateEvents();
        this.$el.detach().remove();
        return this;
    },
    elId: function () {
        var id = this.model.get('id');
        return (this.options.prefix) ? this.options.prefix + id : id;
    }
});

/**
 * App.Views.List
 * @type {*}
 */
App.Views.List = Backbone.View.extend({
    options: {
        prefix: '',
        item: {
            attributes: {},
            prepend: false,
            prependNew: false,
            tagName: 'div',
            template: '',
            View: App.Views.ListItem
        }
    },
    initialize: function (config) {
        this.items = {};
        // Assign function to collection events
        if (this.collection) {
            this.collection.on('reset', this.addAll, this);
            this.collection.on('sort', this.addAll, this);
            this.collection.on('add', this.addItem, this);
            this.collection.on('change', this.changeItem, this);
            this.collection.on('remove', this.removeItem, this);
        }
    },
    render: function () {
        if (this.options.templateEl) {
            this.setElement(this.options.templateEl);
        }

        if (this.collection && this.collection.length > 0) {
            this.addAll();
        }

        return this;
    },
    remove: function () {
        for (var name in this.items) {
            if (this.items.hasOwnProperty(name)) {
                this.items[name].remove();
            }
        }
        this.items = {};

        if (this.collection) {
            this.collection.off('reset', this.addAll, this);
            this.collection.off('sort', this.addAll, this);
            this.collection.off('add', this.addItem, this);
            this.collection.off('change', this.changeItem, this);
            this.collection.off('remove', this.removeItem, this);
        }
        return this;
    },
    addAll: function () {
        var tEmpty = '', that = this;

        if (this.options.emptyTemplate) {
            tEmpty = App.render(this.options.emptyTemplate);
        }

        // remove all content
        this.$el.addClass('loading').html('');

        // run addItem on each collection item
        if (this.collection && this.collection.length > 0) {
            this.options.isEmpty = false;

            if (this.options.groupBy && that.options.groupBy.key) {
                var groupTemplate = App.render(this.options.groupBy.template),
                    items = this.collection.groupBy(that.options.groupBy.key),
                    sorted = _.without(_.keys(items), 'undefined').sort();

                for (var i = 0; i < sorted.length; i++) {
                    var name = sorted[i];
                    this.addElement($(groupTemplate({ title: name })));
                    _.each(items[name], function (model) {
                        var view = that.renderItem(model);
                        that.items[model.id] = view;
                        that.addElement(view.$el);
                    });
                }

                if (items['undefined'] && this.options.groupBy['undefined']) {
                    this.addElement($(groupTemplate({ title: this.options.groupBy['undefined'] })));
                    _.each(items['undefined'], function (model) {
                        var view = that.renderItem(model);
                        that.items[model.id] = view;
                        that.addElement(view.$el);
                    });
                }

            } else {
                this.collection.each(function (model) {
                    var view = that.renderItem(model);
                    that.items[model.id] = view;
                    that.addElement(view.$el);
                });
            }
        }

        this.$el.removeClass('loading');

        if (this.options.emptyTemplate && this.$el.is(":empty")) {
            this.$el.html(tEmpty());
            this.options.isEmpty = true;
        }
        return this;
    },
    addElement: function ($el) {
        if (!$el.is(':empty')) {
            if (this.options.item.prepend) {
                this.$el.prepend($el);
            } else {
                this.$el.append($el);
            }
        }
    },
    addItem: function (model) {
        if (this.options.isEmpty) {
            this.$el.html('');
            this.options.isEmpty = false;
        }

        var view = this.renderItem(model);
        this.addElement(view.$el);
        this.items[model.id] = view;

        return this;
    },
    changeItem: function (model) {
        if (model.id !== undefined) {
            var oldView = this.items[model.id],
                newItem = this.renderItem(model);

            //newItem.$el.addClass(classes);
            //item.replaceWith(newItem.el);
            oldView.$el.after(newItem.el);
            oldView.remove();
            this.items[model.id] = newItem;
        } else { // run addAll if item has no Id
            this.addAll();
        }
        return this;
    },
    renderItem: function (model) {
        return new this.options.item.View({
            model: model,
            collection: this.collection,
            prefix: this.options.prefix,
            attributes: this.options.item.attributes,
            tagName: this.options.item.tagName,
            template: this.options.item.template
        }).render();
    },
    removeItem: function (model) {
        if (model.id !== undefined) {
            $('#' + this.options.prefix + model.id).empty().detach();
            if (this.collection.length === 0) {
                this.collection.reset();
            }
        }
        return this;
    }
});

App.Module.Object = {
    'Set': function(obj, path, value) {
        if (_.isString(path)) {
            path = path.split('.');
        }
        var parent = obj,
            len = path.length;

        for (var i=0; i<len; i++) {
            var name = path[i];
            if (i >= len - 1) {
                if (name.search(/\[\]/) !== -1) {
                    name = name.replace('[]', '');
                    if (parent[name] === undefined) {
                        parent[name] = [];
                    }
                    parent[name].push(value);
                } else {
                    parent[name] = value;
                }
            } else if (parent[name] === undefined) {
                parent[name] = {};
            }
            parent = parent[name];
        }

        return obj;
    },
    'Get': function(obj, path) {
        if (obj && path) {
            if (_.isString(path)) {
                path = path.split('.');
            }

            var parent = obj;
            for (var i=0; i<path.length; i++) {
                var name = path[i].replace('[]', '');
                if (parent[name]) {
                    parent = parent[name];
                } else {
                    parent = undefined;
                    break;
                }
            }

            return parent;
        }
        return undefined;
    }
};

App.Module.Form = {
    Bind: function($form, data, ignore) {
        ignore = ignore || {};

        $(':input[name]', $form).each(function (idx, input) {
            var $input = $(input),
                name = input.name;

            if (name && !ignore[name]) {
                var parts = name.split('-'),
                    value = App.Module.Object.Get(data, parts);

                switch (input.type) {
                    case 'checkbox':
                        input.checked = (value !== undefined);
                        break;
                    case 'radio':
                        input.checked = ($input.val() == value);
                        break;
                    default:
                        $input.val(value);
                }
                $input.trigger('change');
            }
        });
    },
    Serialize: function($form, ignore, withoutEmpty) {
        ignore = ignore || {};
        var data = {},
            component = {};

        // Grep inputs with name
        $(':input[name]', $form).each(function (idx, input) {
            var $input = $(input),
                name = input.name;

            if (name) {
                if (component[name]) {
                    return;
                }

                var val = $input.val(),
                    parts = name.split('-');

                switch(input.type) {
                    case 'checkbox':
                        if (input.checked) {
                            if (val === undefined || _.isEmpty(val)) {
                                val = true;
                            }
                        } else {
                            val = false;
                        }
                        break;
                    case 'radio':
                        if (input.checked) {
                            component[name] = true;
                            if (val === undefined || _.isEmpty(val)) {
                                val = true;
                            }
                        } else {
                            val = false;
                        }
                        break;
                    case 'button': // button values are not intresting
                        return;
                }

                if (withoutEmpty) {
                    if (val === undefined || _.isEmpty(val)) {
                        return;
                    }
                }

                App.Module.Object.Set(data, parts, val);
            }
        });

        return data;
    }
};
<|endoftext|>


<commit_before>
module.exports = exports = build

var fs = require('graceful-fs')
  , path = require('path')
  , glob = require('glob')
  , log = require('npmlog')
  , which = require('which')
  , exec = require('child_process').exec
  , win = process.platform === 'win32'

exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'

function build (gyp, argv, callback) {
  var platformMake = 'make'
  if (process.platform === 'aix') {
    platformMake = 'gmake'
  } else if (process.platform.indexOf('bsd') !== -1) {
    platformMake = 'gmake'
  } else if (win && argv.length > 0) {
    argv = argv.map(function(target) {
      return '/t:' + target
    })
  }

  var makeCommand = gyp.opts.make || process.env.MAKE || platformMake
    , command = win ? 'msbuild' : makeCommand
    , jobs = gyp.opts.jobs || process.env.JOBS
    , buildType
    , config
    , arch
    , nodeDir

  loadConfigGypi()

  /**
   * Load the "config.gypi" file that was generated during "configure".
   */

  function loadConfigGypi () {
    var configPath = path.resolve('build', 'config.gypi')
    fs.readFile(configPath, 'utf8', function (err, data) {
      if (err) {
        if (err.code == 'ENOENT') {
          callback(new Error('You must run `node-gyp configure` first!'))
        } else {
          callback(err)
        }
        return
      }
      config = JSON.parse(data.replace(/\#.+\n/, ''))

      // get the 'arch', 'buildType', and 'nodeDir' vars from the config
      buildType = config.target_defaults.default_configuration
      arch = config.variables.target_arch
      nodeDir = config.variables.nodedir

      if ('debug' in gyp.opts) {
        buildType = gyp.opts.debug ? 'Debug' : 'Release'
      }
      if (!buildType) {
        buildType = 'Release'
      }

      log.verbose('build type', buildType)
      log.verbose('architecture', arch)
      log.verbose('node dev dir', nodeDir)

      if (win) {
        findSolutionFile()
      } else {
        doWhich()
      }
    })
  }

  /**
   * On Windows, find the first build/*.sln file.
   */

  function findSolutionFile () {
    glob('build/*.sln', function (err, files) {
      if (err) return callback(err)
      if (files.length === 0) {
        return callback(new Error('Could not find *.sln file. Did you run "configure"?'))
      }
      guessedSolution = files[0]
      log.verbose('found first Solution file', guessedSolution)
      doWhich()
    })
  }

  /**
   * Uses node-which to locate the msbuild / make executable.
   */

  function doWhich () {
    // First make sure we have the build command in the PATH
    which(command, function (err, execPath) {
      if (err) {
        if (win && /not found/.test(err.message)) {
          // On windows and no 'msbuild' found. Let's guess where it is
          findMsbuild()
        } else {
          // Some other error or 'make' not found on Unix, report that to the user
          callback(err)
        }
        return
      }
      log.verbose('`which` succeeded for `' + command + '`', execPath)
      doBuild()
    })
  }

  /**
   * Search for the location of "msbuild.exe" file on Windows.
   */

  function findMsbuild () {
    if (config.variables.msbuild_path) {
      command = config.variables.msbuild_path
      log.verbose('using MSBuild:', command)
      doBuild()
      return
    }

    log.verbose('could not find "msbuild.exe" in PATH - finding location in registry')
    var notfoundErr = 'Can\'t find "msbuild.exe". Do you have Microsoft Visual Studio C++ 2008+ installed?'
    var cmd = 'reg query "HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions" /s'
    if (process.arch !== 'ia32')
      cmd += ' /reg:32'
    exec(cmd, function (err, stdout) {
      if (err) {
        return callback(new Error(err.message + '\n' + notfoundErr))
      }
      var reVers = /ToolsVersions\\([^\\]+)$/i
        , rePath = /\r\n[ \t]+MSBuildToolsPath[ \t]+REG_SZ[ \t]+([^\r]+)/i
        , msbuilds = []
        , r
        , msbuildPath
      stdout.split('\r\n\r\n').forEach(function(l) {
        if (!l) return
        l = l.trim()
        if (r = reVers.exec(l.substring(0, l.indexOf('\r\n')))) {
          var ver = parseFloat(r[1], 10)
          if (ver >= 3.5) {
            if (r = rePath.exec(l)) {
              msbuilds.push({
                version: ver,
                path: r[1]
              })
            }
          }
        }
      })
      msbuilds.sort(function (x, y) {
        return (x.version < y.version ? -1 : 1)
      })
      ;(function verifyMsbuild () {
        if (!msbuilds.length) return callback(new Error(notfoundErr))
        msbuildPath = path.resolve(msbuilds.pop().path, 'msbuild.exe')
        fs.stat(msbuildPath, function (err) {
          if (err) {
            if (err.code == 'ENOENT') {
              if (msbuilds.length) {
                return verifyMsbuild()
              } else {
                callback(new Error(notfoundErr))
              }
            } else {
              callback(err)
            }
            return
          }
          command = msbuildPath
          doBuild()
        })
      })()
    })
  }

  /**
   * Actually spawn the process and compile the module.
   */

  function doBuild () {
    // Enable Verbose build
    var verbose = log.levels[log.level] <= log.levels.verbose
    if (!win && verbose) {
      argv.push('V=1')
    }
    if (win && !verbose) {
      argv.push('/clp:Verbosity=minimal')
    }

    if (win) {
      // Turn off the Microsoft logo on Windows
      argv.push('/nologo')
    }

    // Specify the build type, Release by default
    if (win) {
      // Convert .gypi config target_arch to MSBuild /Platform
      // Since there are many ways to state '32-bit Intel', default to it.
      // N.B. msbuild's Condition string equality tests are case-insensitive.
      var archLower = arch.toLowerCase()
      var p = archLower === 'x64' ? 'x64' :
              (archLower === 'arm' ? 'ARM' :
              (archLower === 'arm64' ? 'ARM64' : 'Win32'))
      argv.push('/p:Configuration=' + buildType + ';Platform=' + p)
      if (jobs) {
        var j = parseInt(jobs, 10)
        if (!isNaN(j) && j > 0) {
          argv.push('/m:' + j)
        } else if (jobs.toUpperCase() === 'MAX') {
          argv.push('/m:' + require('os').cpus().length)
        }
      }
    } else {
      argv.push('BUILDTYPE=' + buildType)
      // Invoke the Makefile in the 'build' dir.
      argv.push('-C')
      argv.push('build')
      if (jobs) {
        var j = parseInt(jobs, 10)
        if (!isNaN(j) && j > 0) {
          argv.push('--jobs')
          argv.push(j)
        } else if (jobs.toUpperCase() === 'MAX') {
          argv.push('--jobs')
          argv.push(require('os').cpus().length)
        }
      }
    }

    if (win) {
      // did the user specify their own .sln file?
      var hasSln = argv.some(function (arg) {
        return path.extname(arg) == '.sln'
      })
      if (!hasSln) {
        argv.unshift(gyp.opts.solution || guessedSolution)
      }
    }

    var proc = gyp.spawn(command, argv)
    proc.on('exit', onExit)
  }

  function onExit (code, signal) {
    if (code !== 0) {
      return callback(new Error('`' + command + '` failed with exit code: ' + code))
    }
    if (signal) {
      return callback(new Error('`' + command + '` got signal: ' + signal))
    }
    callback()
  }
}
<commit_msg>win: use msbuild from the configure stage<commit_after>
module.exports = exports = build

var fs = require('graceful-fs')
  , path = require('path')
  , glob = require('glob')
  , log = require('npmlog')
  , which = require('which')
  , exec = require('child_process').exec
  , win = process.platform === 'win32'

exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'

function build (gyp, argv, callback) {
  var platformMake = 'make'
  if (process.platform === 'aix') {
    platformMake = 'gmake'
  } else if (process.platform.indexOf('bsd') !== -1) {
    platformMake = 'gmake'
  } else if (win && argv.length > 0) {
    argv = argv.map(function(target) {
      return '/t:' + target
    })
  }

  var makeCommand = gyp.opts.make || process.env.MAKE || platformMake
    , command = win ? 'msbuild' : makeCommand
    , jobs = gyp.opts.jobs || process.env.JOBS
    , buildType
    , config
    , arch
    , nodeDir

  loadConfigGypi()

  /**
   * Load the "config.gypi" file that was generated during "configure".
   */

  function loadConfigGypi () {
    var configPath = path.resolve('build', 'config.gypi')
    fs.readFile(configPath, 'utf8', function (err, data) {
      if (err) {
        if (err.code == 'ENOENT') {
          callback(new Error('You must run `node-gyp configure` first!'))
        } else {
          callback(err)
        }
        return
      }
      config = JSON.parse(data.replace(/\#.+\n/, ''))

      // get the 'arch', 'buildType', and 'nodeDir' vars from the config
      buildType = config.target_defaults.default_configuration
      arch = config.variables.target_arch
      nodeDir = config.variables.nodedir

      if ('debug' in gyp.opts) {
        buildType = gyp.opts.debug ? 'Debug' : 'Release'
      }
      if (!buildType) {
        buildType = 'Release'
      }

      log.verbose('build type', buildType)
      log.verbose('architecture', arch)
      log.verbose('node dev dir', nodeDir)

      if (win) {
        findSolutionFile()
      } else {
        doWhich()
      }
    })
  }

  /**
   * On Windows, find the first build/*.sln file.
   */

  function findSolutionFile () {
    glob('build/*.sln', function (err, files) {
      if (err) return callback(err)
      if (files.length === 0) {
        return callback(new Error('Could not find *.sln file. Did you run "configure"?'))
      }
      guessedSolution = files[0]
      log.verbose('found first Solution file', guessedSolution)
      doWhich()
    })
  }

  /**
   * Uses node-which to locate the msbuild / make executable.
   */

  function doWhich () {
    // On Windows use msbuild provided by node-gyp configure
    if (win && config.variables.msbuild_path) {
      command = config.variables.msbuild_path
      log.verbose('using MSBuild:', command)
      doBuild()
      return
    }
    // First make sure we have the build command in the PATH
    which(command, function (err, execPath) {
      if (err) {
        if (win && /not found/.test(err.message)) {
          // On windows and no 'msbuild' found. Let's guess where it is
          findMsbuild()
        } else {
          // Some other error or 'make' not found on Unix, report that to the user
          callback(err)
        }
        return
      }
      log.verbose('`which` succeeded for `' + command + '`', execPath)
      doBuild()
    })
  }

  /**
   * Search for the location of "msbuild.exe" file on Windows.
   */

  function findMsbuild () {
    log.verbose('could not find "msbuild.exe" in PATH - finding location in registry')
    var notfoundErr = 'Can\'t find "msbuild.exe". Do you have Microsoft Visual Studio C++ 2008+ installed?'
    var cmd = 'reg query "HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions" /s'
    if (process.arch !== 'ia32')
      cmd += ' /reg:32'
    exec(cmd, function (err, stdout) {
      if (err) {
        return callback(new Error(err.message + '\n' + notfoundErr))
      }
      var reVers = /ToolsVersions\\([^\\]+)$/i
        , rePath = /\r\n[ \t]+MSBuildToolsPath[ \t]+REG_SZ[ \t]+([^\r]+)/i
        , msbuilds = []
        , r
        , msbuildPath
      stdout.split('\r\n\r\n').forEach(function(l) {
        if (!l) return
        l = l.trim()
        if (r = reVers.exec(l.substring(0, l.indexOf('\r\n')))) {
          var ver = parseFloat(r[1], 10)
          if (ver >= 3.5) {
            if (r = rePath.exec(l)) {
              msbuilds.push({
                version: ver,
                path: r[1]
              })
            }
          }
        }
      })
      msbuilds.sort(function (x, y) {
        return (x.version < y.version ? -1 : 1)
      })
      ;(function verifyMsbuild () {
        if (!msbuilds.length) return callback(new Error(notfoundErr))
        msbuildPath = path.resolve(msbuilds.pop().path, 'msbuild.exe')
        fs.stat(msbuildPath, function (err) {
          if (err) {
            if (err.code == 'ENOENT') {
              if (msbuilds.length) {
                return verifyMsbuild()
              } else {
                callback(new Error(notfoundErr))
              }
            } else {
              callback(err)
            }
            return
          }
          command = msbuildPath
          doBuild()
        })
      })()
    })
  }

  /**
   * Actually spawn the process and compile the module.
   */

  function doBuild () {
    // Enable Verbose build
    var verbose = log.levels[log.level] <= log.levels.verbose
    if (!win && verbose) {
      argv.push('V=1')
    }
    if (win && !verbose) {
      argv.push('/clp:Verbosity=minimal')
    }

    if (win) {
      // Turn off the Microsoft logo on Windows
      argv.push('/nologo')
    }

    // Specify the build type, Release by default
    if (win) {
      // Convert .gypi config target_arch to MSBuild /Platform
      // Since there are many ways to state '32-bit Intel', default to it.
      // N.B. msbuild's Condition string equality tests are case-insensitive.
      var archLower = arch.toLowerCase()
      var p = archLower === 'x64' ? 'x64' :
              (archLower === 'arm' ? 'ARM' :
              (archLower === 'arm64' ? 'ARM64' : 'Win32'))
      argv.push('/p:Configuration=' + buildType + ';Platform=' + p)
      if (jobs) {
        var j = parseInt(jobs, 10)
        if (!isNaN(j) && j > 0) {
          argv.push('/m:' + j)
        } else if (jobs.toUpperCase() === 'MAX') {
          argv.push('/m:' + require('os').cpus().length)
        }
      }
    } else {
      argv.push('BUILDTYPE=' + buildType)
      // Invoke the Makefile in the 'build' dir.
      argv.push('-C')
      argv.push('build')
      if (jobs) {
        var j = parseInt(jobs, 10)
        if (!isNaN(j) && j > 0) {
          argv.push('--jobs')
          argv.push(j)
        } else if (jobs.toUpperCase() === 'MAX') {
          argv.push('--jobs')
          argv.push(require('os').cpus().length)
        }
      }
    }

    if (win) {
      // did the user specify their own .sln file?
      var hasSln = argv.some(function (arg) {
        return path.extname(arg) == '.sln'
      })
      if (!hasSln) {
        argv.unshift(gyp.opts.solution || guessedSolution)
      }
    }

    var proc = gyp.spawn(command, argv)
    proc.on('exit', onExit)
  }

  function onExit (code, signal) {
    if (code !== 0) {
      return callback(new Error('`' + command + '` failed with exit code: ' + code))
    }
    if (signal) {
      return callback(new Error('`' + command + '` got signal: ' + signal))
    }
    callback()
  }
}
<|endoftext|>


<commit_before>define(function() {
    var suite = function(setName, newTests) {
        if(!('testsToRun' in run)) {
            run.testsToRun = [];
        }

        if(setName && newTests) {
            run.testsToRun.push({name: setName, tests: newTests});
        }
    };

    var clone = function(o) {
        // http://www.andrewsellick.com/93/javascript-clone-object-function
        if(typeof(o) != 'object' || !o) {
            return o;
        }

        var newO = new Object();

        for(var i in o) {
            newO[i] = clone(o[i]);
        }

        return newO;
    };

    var run = function(opts) {
        var passedTests = 0;
        var testTotal = 0;
        var out = [];

        if(!('output' in opts)) {
            console.log('bunit.run is missing output sink!');

            return;
        }

        var refresh = 'refresh' in opts? opts.refresh: 0;

        if(refresh) {
            run._refresh = refresh;
            play();
        }

        for(var i = 0; i < run.testsToRun.length; i++) {
            var model = run.testsToRun[i];
            var testSet = model.tests;

            var attrs = testSet._ || {};
            delete testSet._;

            out.push({state: 'started', text: 'Running "' + model.name + '" tests'});

            for(var testName in testSet) {
                var test = testSet[testName];

                try {
                    test.apply(clone(attrs));

                    out.push({state: 'passed', text: 'PASSED: ' + testName});

                    passedTests++;
                }
                catch(e) {
                    out.push({state: 'failed', text: 'FAILED: ' + testName});
                    out.push({state: 'error', text: e});
                }

                testTotal++;
            }
        }

        var finished = {state: 'finished', text: passedTests + '/' + testTotal + ' tests passed'};
        out.unshift(finished);
        out.push(finished);

        var output = opts.output;

        for(i = 0; i < out.length; i++) {
            var line = out[i];

            output(line);
        }
    };

    // playback
    var stop = function() {
        clearTimeout(run._timerId);
    };

    var play = function() {
        var refresh = '_refresh' in run? run._refresh: 1000;
        var reload = function() {
            location.reload(true);
        };

        run._timerId = setTimeout(reload, refresh);
    };

    var playbackUI = function() {
        var elem = document.createElement('div');
        var stopped = !('_timerId' in run);

        var setText = function() {
            elem.innerHTML = stopped? 'Stop tests': 'Play tests';
        };

        var setState = function() {
            stopped = !stopped;
            setText();
            stopped? play(): stop();
        };

        elem.id = 'playback';
        elem.onclick = setState;

        setText();

        return elem;
    };

    // output
    var consoleOutput = function(report) {
        console.log(report.text);
    };

    var HTMLOutput = function(target) {
        return function(report) {
            target.innerHTML += '
' + report.text + '
';
        }
    }

    // assert
    var assert = function(stmt) {
        var argumentsError = function() {
            // slow! http://bonsaiden.github.com/JavaScript-Garden/#function.arguments
            var args = Array.prototype.slice.call(arguments);

            if(args.length == 1) {
                return stmt + ' is not ' + args[0] + '!';
            }

            return stmt + ' not in: ' + args.join(', ');
        };

        var checkArguments = function(args, cb) {
            for(var i = 0; i < args.length; i++) {
                var value = args[i];

                if(cb(value)) {
                    return true;
                }
            }

            return false;
        };

        var isArray = function(o) {
            return Object.prototype.toString.call(o) === '[object Array]';
        };

        var methods = {
            equals: {
                error: function(val) {
                    return val + ' did not equal ' + stmt + '!'
                },
                method: function(val) {
                    if(isArray(val)) {
                        var ret = true;

                        for(var k in val) {
                            if(val[k] !== stmt[k]) {
                                return false;
                            }
                        }

                        return true;
                    }

                    return val == stmt;
                }
            },
            is: {
                error: argumentsError,
                method: function() {
                    // borrowed from RightJS
                    var to_s = Object.prototype.toString;

                    var typeChecks = {
                        'function': function(val) {
                            return typeof(val) === 'function';
                        },
                        string: function(val) {
                            return typeof(val) === 'string';
                        },
                        number: function(val) {
                            return typeof(val) === 'number';
                        },
                        object: function(val) {
                            return to_s.call(val) === '[object Object]';
                        },
                        array: isArray
                    };

                    return checkArguments(arguments,
                        function(value) {
                            if(value in typeChecks) {
                                var matched = typeChecks[value](stmt);

                                if(matched) {
                                    return true;
                                }
                            }

                            return false;
                        }
                    );
                }
            },
            within: {
                error: argumentsError,
                method: function() {
                    return checkArguments(arguments,
                        function(value) {
                            return value == stmt;
                        }
                    );

                    return false;
                }
            },
            isDefined: {
                error: function() {
                    return 'Expected a defined value, got undefined instead!';
                },
                method: function() {
                    // borrowed from RightJS
                    return typeof(stmt) !== 'undefined';
                }
            },
            between: {
                error: function(a, b) {
                    // TODO: improve msgs for null cases
                    return stmt + ' was not between ' + a + ' and ' + b + '!'
                },
                method: function(a, b) {
                    if(a == null) {
                        return stmt <= b;
                    }

                    if(b == null) {
                        return a <= stmt;
                    }

                    return a <= stmt && stmt <= b;
                }
            },
            not: {
                error: function() {},
                method: function() {
                    invertNext = !invertNext;

                    return true;
                }
            }
        };
        var ret = {};
        var invertNext = false;

        var insertMethod = function(name, data) {
            ret[name] = function() {
                var success = data.method.apply(this, arguments);

                if(name != 'not' && invertNext) {
                    success = !success;
                    invertNext = false;
                }

                if(success) {
                    return ret;
                }

                // http://aymanh.com/9-javascript-tips-you-may-not-know#assertion
                function AssertionError(message) {
                    this.message = message;
                }
                AssertionError.prototype.toString = function () {
                    return 'AssertionError: ' + this.message;
                }

                var errorText = data.error.apply(this, arguments);
                throw new AssertionError(errorText);
            }
        }

        for(var methodName in methods) {
            var methodData = methods[methodName];

            insertMethod(methodName, methodData);
        }

        return ret;
    }

    var defaultUI = function(tests) {
        var outputArea = document.createElement('div');

        document.body.appendChild(playbackUI());
        document.body.appendChild(outputArea);

        run({
            tests: tests,
            output: HTMLOutput(outputArea),
            refresh: 2000
        });
    };

    return {
        suite: suite,
        run: run,
        play: play,
        stop: stop,
        playbackUI: playbackUI,
        consoleOutput: consoleOutput,
        HTMLOutput: HTMLOutput,
        assert: assert,
        defaultUI: defaultUI
    };
});
<commit_msg>Update bunit.js<commit_after>define(function() {
    var suite = function(setName, newTests) {
        if(!('testsToRun' in run)) {
            run.testsToRun = [];
        }

        if(setName && newTests) {
            run.testsToRun.push({name: setName, tests: newTests});
        }
    };

    // XXX: move to utils
    var clone = function(o) {
        // http://www.andrewsellick.com/93/javascript-clone-object-function
        if(typeof(o) != 'object' || !o) {
            return o;
        }

        var newO = new Object();

        for(var i in o) {
            newO[i] = clone(o[i]);
        }

        return newO;
    };

    // XXX: move to utils
    var isArray = function(o) {
        return Object.prototype.toString.call(o) === '[object Array]';
    };

    // XXX: move to utils
    var equals = function(a, b) {
        if(isArray(a)) {
            for(var k in a) {
                if(a[k] !== b[k]) {
                    return false;
                }
            }

            for(k in b) {
                if(a[k] !== b[k]) {
                    return false;
                }
            }

            return true;
        }

        return a === b;
    };

    var run = function(opts) {
        var passedTests = 0;
        var testTotal = 0;
        var out = [];

        if(!('output' in opts)) {
            console.log('bunit.run is missing output sink!');

            return;
        }

        var refresh = 'refresh' in opts? opts.refresh: 0;

        if(refresh) {
            run._refresh = refresh;
            play();
        }

        for(var i = 0; i < run.testsToRun.length; i++) {
            var model = run.testsToRun[i];
            var testSet = model.tests;

            var attrs = testSet._ || {};
            delete testSet._;

            out.push({state: 'started', text: 'Running "' + model.name + '" tests'});

            for(var testName in testSet) {
                var test = testSet[testName];

                try {
                    test.apply(clone(attrs));

                    out.push({state: 'passed', text: 'PASSED: ' + testName});

                    passedTests++;
                }
                catch(e) {
                    out.push({state: 'failed', text: 'FAILED: ' + testName});
                    out.push({state: 'error', text: e});
                }

                testTotal++;
            }
        }

        var finished = {state: 'finished', text: passedTests + '/' + testTotal + ' tests passed'};
        out.unshift(finished);
        out.push(finished);

        var output = opts.output;

        for(i = 0; i < out.length; i++) {
            var line = out[i];

            output(line);
        }
    };

    // playback
    var stop = function() {
        clearTimeout(run._timerId);
    };

    var play = function() {
        var refresh = '_refresh' in run? run._refresh: 1000;
        var reload = function() {
            location.reload(true);
        };

        run._timerId = setTimeout(reload, refresh);
    };

    var playbackUI = function() {
        var elem = document.createElement('div');
        var stopped = !('_timerId' in run);

        var setText = function() {
            elem.innerHTML = stopped? 'Stop tests': 'Play tests';
        };

        var setState = function() {
            stopped = !stopped;
            setText();
            stopped? play(): stop();
        };

        elem.id = 'playback';
        elem.onclick = setState;

        setText();

        return elem;
    };

    // output
    var consoleOutput = function(report) {
        console.log(report.text);
    };

    var HTMLOutput = function(target) {
        return function(report) {
            target.innerHTML += '
' + report.text + '
';
        }
    }

    // assert
    var assert = function(stmt) {
        var argumentsError = function() {
            // slow! http://bonsaiden.github.com/JavaScript-Garden/#function.arguments
            var args = Array.prototype.slice.call(arguments);

            if(args.length == 1) {
                return stmt + ' is not ' + args[0] + '!';
            }

            return stmt + ' not in: ' + args.join(', ');
        };

        var checkArguments = function(args, cb) {
            for(var i = 0; i < args.length; i++) {
                var value = args[i];

                if(cb(value)) {
                    return true;
                }
            }

            return false;
        };

        var methods = {
            equals: {
                error: function(val) {
                    return val + ' did not equal ' + stmt + '!'
                },
                method: function(val) {
                    return equals(val, stmt);
                }
            },
            is: {
                error: argumentsError,
                method: function() {
                    // borrowed from RightJS
                    var to_s = Object.prototype.toString;

                    var typeChecks = {
                        'function': function(val) {
                            return typeof(val) === 'function';
                        },
                        string: function(val) {
                            return typeof(val) === 'string';
                        },
                        number: function(val) {
                            return typeof(val) === 'number';
                        },
                        object: function(val) {
                            return to_s.call(val) === '[object Object]';
                        },
                        array: isArray
                    };

                    return checkArguments(arguments,
                        function(value) {
                            if(value in typeChecks) {
                                var matched = typeChecks[value](stmt);

                                if(matched) {
                                    return true;
                                }
                            }

                            return false;
                        }
                    );
                }
            },
            within: {
                error: argumentsError,
                method: function() {
                    return checkArguments(arguments,
                        function(value) {
                            return value == stmt;
                        }
                    );

                    return false;
                }
            },
            isDefined: {
                error: function() {
                    return 'Expected a defined value, got undefined instead!';
                },
                method: function() {
                    // borrowed from RightJS
                    return typeof(stmt) !== 'undefined';
                }
            },
            between: {
                error: function(a, b) {
                    // TODO: improve msgs for null cases
                    return stmt + ' was not between ' + a + ' and ' + b + '!'
                },
                method: function(a, b) {
                    if(a == null) {
                        return stmt <= b;
                    }

                    if(b == null) {
                        return a <= stmt;
                    }

                    return a <= stmt && stmt <= b;
                }
            },
            not: {
                error: function() {},
                method: function() {
                    invertNext = !invertNext;

                    return true;
                }
            }
        };
        var ret = {};
        var invertNext = false;

        var insertMethod = function(name, data) {
            ret[name] = function() {
                var success = data.method.apply(this, arguments);

                if(name != 'not' && invertNext) {
                    success = !success;
                    invertNext = false;
                }

                if(success) {
                    return ret;
                }

                // http://aymanh.com/9-javascript-tips-you-may-not-know#assertion
                function AssertionError(message) {
                    this.message = message;
                }
                AssertionError.prototype.toString = function () {
                    return 'AssertionError: ' + this.message;
                }

                var errorText = data.error.apply(this, arguments);
                throw new AssertionError(errorText);
            }
        }

        for(var methodName in methods) {
            var methodData = methods[methodName];

            insertMethod(methodName, methodData);
        }

        return ret;
    }

    var defaultUI = function(tests) {
        var outputArea = document.createElement('div');

        document.body.appendChild(playbackUI());
        document.body.appendChild(outputArea);

        run({
            tests: tests,
            output: HTMLOutput(outputArea),
            refresh: 2000
        });
    };

    return {
        suite: suite,
        run: run,
        play: play,
        stop: stop,
        playbackUI: playbackUI,
        consoleOutput: consoleOutput,
        HTMLOutput: HTMLOutput,
        assert: assert,
        defaultUI: defaultUI
    };
});
<|endoftext|>


<commit_before>define(["md5baseJS", "dataManager"], function(md5, DataManager) {

    var peer,
        streamers = {},
        remoteCatalogue = {},
        queue = [],
        videoPieceQueue = [],
        actions = [
            {type : "getCatalogue", response : "sendCatalogue" },
            {type : "recieveCatalogue", response : "storeCatalogue"},
            {type : "sendStreamPiece", response : "requestStreamPiece"},
            {type : "recieveStreamPiece", response : "cacheStreamPiece" },
            {type : "getStreamers", response : "sendStreamers" },
            {type : "recieveStreamers", response : "cacheStreamers" },

        ],
        responses = {
            sendCatalogue : function(streamer, data) {
                makeRequest(streamer, {type : "1", payload : JSON.stringify(DataManager.getMyCatalogue())});
            },
            storeCatalogue : function(streamer, data) {
                remoteCatalogue[streamer] = JSON.parse(data.payload);
            },
            requestStreamPiece : function(streamer, data) {
                for(var i = 0; i < data.pieces.length; i++) {
                    queue.push({
                        streamer : streamer,
                        type : "3",
                        pieceID : data.pieces[i]
                    });
                }
                processQueue();

            },
            cacheStreamPiece : function(streamer, data) {
                DataManager.cachePiecesInMemory(data.pieces);
            },
            sendStreamers : function(streamer, data) {
                makeRequest(streamer, {type : "5", payload : streamers});
                streamers[streamer] = Date.now();
                makeRequest(streamer, {type : 0});
                updateStreamers();

            },
            cacheStreamers : function(streamer, data) {
                for (var streamer in data.payload) { streamers[streamer] = data.payload[streamer]; }
                getRemoteCataloges();
            }

        };

    var processQueue = function() {
        var nextItem = queue.shift();
        if(nextItem) {
            if(nextItem.type === "3") {
                DataManager.getPiece(nextItem.pieceID, function(pieceID, piece) {

                    var pieces = {};
                    pieces[pieceID] = piece;
                    makeRequest(nextItem.streamer, {type : "3", pieces : pieces});

                });

            }
        }

    };

    var connectToSignallingHost = function(callback) {

        var peer = new Peer("", {host: 'aqueous-refuge-7092.herokuapp.com', secure:true, port:443, path: '/'});

        peer.on("open", function(id) {
            console.log("helel", id);
            if(callback) {
                callback(id);
            }
        });

        peer.on('connection', function(conn) {
            conn.on('data', function(data){
                console.log("receive reqest", data, conn);
                recieveRequest(data, conn);
            });
        });

        return peer;
    };

    var getRemoteCataloges = function() {
        for(var streamer in streamers) {
            if(streamer != peer.id) {
                makeRequest(streamer, {type : 0});
            }
        }
    };

    var updateStreamers = function() {
        for(var streamer in streamers) {
            if(streamer != peer.id) {
                makeRequest(streamer, {type : "5", payload : streamers});
            }
        }
    };

    var getStreamers = function(callback, group) {
        makeRequest(group, {type : 4});
    };

    var makeRequest = function(streamer, action) {
        var conn = peer.connect(streamer);
        console.log("make request", streamer, action);
        conn.on('open', function(){
            conn.send(action);
            processQueue();
        });
    };

    var recieveRequest = function(data, conn) {
        var requestType = data.type;
        var streamer = conn.peer;
        for(var i = 0; i < actions.length; i++) {
            if(String(requestType) === String(i)) {
                responses[actions[i].response](streamer, data);
            }
        }
    };

    var getStoredCatalogues = function() {
        var mergedCatalogue = [];
        for(var remoteCatalogueStreamer in remoteCatalogue) {
            mergedCatalogue = mergedCatalogue.concat(remoteCatalogue[remoteCatalogueStreamer]);
        }
        return mergedCatalogue;
    };

    var searchCatalogueForItem = function(item) {
        for(var remoteCatalogueStreamer in remoteCatalogue) {
            var catalogue = remoteCatalogue[remoteCatalogueStreamer];
            for(var i = 0; i < catalogue.length; i++) {
                if(catalogue[i].name === item.name &&
                   catalogue[i].season === item.season &&
                   catalogue[i].episode === item.episode) {
                    return {
                        streamer : remoteCatalogueStreamer,
                        data : catalogue[i]
                    };
                }
            }
        }
    };

    var getVideo = function(item) {

        var catalogueEntry = searchCatalogueForItem(item);
        if(catalogueEntry) {
            makeRequest(catalogueEntry.streamer, {type : "2", pieces : catalogueEntry.data.pieces});
            videoPieceQueue = catalogueEntry.data.pieces;
            return true;
        } else {
            return "failed no streamer found with that in their catalogue";
        }

    };

    var getVideoData = function(callback) {
        var nextPiece = videoPieceQueue[0];
        DataManager.getPiece(nextPiece, function(pieceID, piece) {
            if(pieceID && videoPieceQueue.length > 0) {
                videoPieceQueue.shift();
                callback(pieceID, piece);
            } else if(!pieceID && videoPieceQueue.length === 0) {
                callback("finished");
            } else {
                callback();
            }
        });
    };

    var getStreamerCount = function() {
        return Object.keys(streamers).length;
    };

    var getMediaCount = function() {
        return Object.keys(remoteCatalogue).length;
    };

    var init = function() {

        var hash = window.location.hash;
        var group = hash.split("=")[1];
        peer = connectToSignallingHost(function(id) {
            console.log("test1");
            if(!group) {
                window.location.hash = "?group="+id;
                streamers[id] = Date.now();
            } else {
                getStreamers(getRemoteCataloges, group);
            }
        });

    };

    init();

    return {
        getStoredCatalogues : getStoredCatalogues,
        cacheStreamFile : DataManager.cacheStreamFile,
        cachePiece : DataManager.cachePiece,
        getVideo : getVideo,
        getVideoData : getVideoData,
        loadLocalFile : DataManager.loadLocalFile,
        getStreamerCount : getStreamerCount,
        getMediaCount : getMediaCount
    }
});

<commit_msg>test deply<commit_after>define(["md5baseJS", "dataManager"], function(md5, DataManager) {

    var peer,
        streamers = {},
        remoteCatalogue = {},
        queue = [],
        videoPieceQueue = [],
        actions = [
            {type : "getCatalogue", response : "sendCatalogue" },
            {type : "recieveCatalogue", response : "storeCatalogue"},
            {type : "sendStreamPiece", response : "requestStreamPiece"},
            {type : "recieveStreamPiece", response : "cacheStreamPiece" },
            {type : "getStreamers", response : "sendStreamers" },
            {type : "recieveStreamers", response : "cacheStreamers" },

        ],
        responses = {
            sendCatalogue : function(streamer, data) {
                makeRequest(streamer, {type : "1", payload : JSON.stringify(DataManager.getMyCatalogue())});
            },
            storeCatalogue : function(streamer, data) {
                remoteCatalogue[streamer] = JSON.parse(data.payload);
            },
            requestStreamPiece : function(streamer, data) {
                for(var i = 0; i < data.pieces.length; i++) {
                    queue.push({
                        streamer : streamer,
                        type : "3",
                        pieceID : data.pieces[i]
                    });
                }
                processQueue();

            },
            cacheStreamPiece : function(streamer, data) {
                DataManager.cachePiecesInMemory(data.pieces);
            },
            sendStreamers : function(streamer, data) {
                makeRequest(streamer, {type : "5", payload : streamers});
                streamers[streamer] = Date.now();
                makeRequest(streamer, {type : 0});
                updateStreamers();

            },
            cacheStreamers : function(streamer, data) {
                for (var streamer in data.payload) { streamers[streamer] = data.payload[streamer]; }
                getRemoteCataloges();
            }

        };

    var processQueue = function() {
        var nextItem = queue.shift();
        if(nextItem) {
            if(nextItem.type === "3") {
                DataManager.getPiece(nextItem.pieceID, function(pieceID, piece) {

                    var pieces = {};
                    pieces[pieceID] = piece;
                    makeRequest(nextItem.streamer, {type : "3", pieces : pieces});

                });

            }
        }

    };

    var connectToSignallingHost = function(callback) {

        var peer = new Peer("", {host: 'aqueous-refuge-7092.herokuapp.com', secure:true, port:443, path: '/'});

        peer.on("open", function(id) {
            console.log("helel", id);
            if(callback) {
                callback(id);
            }
        });

        peer.on('connection', function(conn) {
            conn.on('data', function(data){
                console.log("receive reqest", data, conn);
                recieveRequest(data, conn);
            });
        });

        return peer;
    };

    var getRemoteCataloges = function() {
        for(var streamer in streamers) {
            if(streamer != peer.id) {
                makeRequest(streamer, {type : 0});
            }
        }
    };

    var updateStreamers = function() {
        for(var streamer in streamers) {
            if(streamer != peer.id) {
                makeRequest(streamer, {type : "5", payload : streamers});
            }
        }
    };

    var getStreamers = function(callback, group) {
        makeRequest(group, {type : 4});
    };

    var makeRequest = function(streamer, action) {
        var conn = peer.connect(streamer);
        console.log("make request", streamer, action);
        conn.on('open', function(){
            conn.send(action);
            processQueue();
        });
    };

    var recieveRequest = function(data, conn) {
        var requestType = data.type;
        var streamer = conn.peer;
        for(var i = 0; i < actions.length; i++) {
            if(String(requestType) === String(i)) {
                responses[actions[i].response](streamer, data);
            }
        }
    };

    var getStoredCatalogues = function() {
        var mergedCatalogue = [];
        for(var remoteCatalogueStreamer in remoteCatalogue) {
            mergedCatalogue = mergedCatalogue.concat(remoteCatalogue[remoteCatalogueStreamer]);
        }
        return mergedCatalogue;
    };

    var searchCatalogueForItem = function(item) {
        for(var remoteCatalogueStreamer in remoteCatalogue) {
            var catalogue = remoteCatalogue[remoteCatalogueStreamer];
            for(var i = 0; i < catalogue.length; i++) {
                if(catalogue[i].name === item.name &&
                   catalogue[i].season === item.season &&
                   catalogue[i].episode === item.episode) {
                    return {
                        streamer : remoteCatalogueStreamer,
                        data : catalogue[i]
                    };
                }
            }
        }
    };

    var getVideo = function(item) {

        var catalogueEntry = searchCatalogueForItem(item);
        if(catalogueEntry) {
            makeRequest(catalogueEntry.streamer, {type : "2", pieces : catalogueEntry.data.pieces});
            videoPieceQueue = catalogueEntry.data.pieces;
            return true;
        } else {
            return "failed no streamer found with that in their catalogue";
        }

    };

    var getVideoData = function(callback) {
        var nextPiece = videoPieceQueue[0];
        DataManager.getPiece(nextPiece, function(pieceID, piece) {
            if(pieceID && videoPieceQueue.length > 0) {
                videoPieceQueue.shift();
                callback(pieceID, piece);
            } else if(!pieceID && videoPieceQueue.length === 0) {
                callback("finished");
            } else {
                callback();
            }
        });
    };

    var getStreamerCount = function() {
        return Object.keys(streamers).length;
    };

    var getMediaCount = function() {
        return Object.keys(remoteCatalogue).length;
    };

    var init = function() {

        var hash = window.location.hash;
        var group = hash.split("=")[1];
        peer = connectToSignallingHost(function(id) {
            console.log("test12");
            if(!group) {
                window.location.hash = "?group="+id;
                streamers[id] = Date.now();
            } else {
                getStreamers(getRemoteCataloges, group);
            }
        });

    };

    init();

    return {
        getStoredCatalogues : getStoredCatalogues,
        cacheStreamFile : DataManager.cacheStreamFile,
        cachePiece : DataManager.cachePiece,
        getVideo : getVideo,
        getVideoData : getVideoData,
        loadLocalFile : DataManager.loadLocalFile,
        getStreamerCount : getStreamerCount,
        getMediaCount : getMediaCount
    }
});

<|endoftext|>


<commit_before>var subscriptions = {

  init: function() {
    if ($('#subscriptions').length >= 1) {
      this.setCSRFToken($('meta[name="csrf-token"]').attr('content'));

      $.ajax('/api/users/' + this.els.addForm.data('id'), {
        dataType: 'json',
        success: this.show.bind(this),
        complete: function() {
          $('#spinner').hide();
        }
      });

      this.els.addForm.on('submit', this.update.bind(this));
      this.els.list.on('click', '.glyphicon-remove', this.remove);
    }
  },

  els: {
    'addForm': $('#addSub'),
    'list': $('#subsList'),
    'searchInput': $('#searchSub')
  },

  data: {
    subs: [],
    loading: false
  },

  setCSRFToken: function(securityToken) {
    $.ajaxPrefilter(function(options, _, xhr) {
      if (!xhr.crossDomain) {
        xhr.setRequestHeader('X-CSRF-Token', securityToken);
      }
    });
  },

  cleanInput: function(input) {
    return input.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>') ;
  },

  show: function(res) {
    res.subscriptions.sort(function(a, b) {
      return b.toLowerCase() < a.toLowerCase();
    });
    $.each(res.subscriptions, this.render.bind(this));
  },

  render: function(index, sub) {
    sub = this.cleanInput(sub);
    var display = '
' +
                  '' + sub + '	' +
                  '	' +
                  '
';
    this.els.list.append(display);
    this.data.subs.push(sub.toLowerCase());
  },

  update: function(e) {
    e.preventDefault();

    if (this.data.loading) {
      return;
    }

    var input = this.cleanInput(this.els.searchInput.val().toLowerCase());
    if (this.data.subs.indexOf(input) >= 0) {
      return $('.top-right').notify({
        type: 'danger',
        message: { text: 'You already added ' + this.els.searchInput.val() + '.'  }
      }).show();
    }

    this.data.loading = true;

    var req = $.ajax(this.els.addForm.attr('action'), {
      type: 'PUT',
      dataType: 'json',
      data: { 'addSub': this.els.searchInput.val() },
    });

    var success = function(res) {
      var searchInput = this.els.searchInput;
      var value = this.cleanInput(searchInput.val());
      var display = '
' +
                    '' + value + '	' +
                    '	' +
                    '
';
      this.els.list.prepend(display);
      this.data.subs.push(value.toLowerCase());
      this.data.loading = false;
      searchInput.val('');
      setTimeout(function() {
        $('.highlight').removeClass('highlight');
      }, 1000);
    };

    var error = function(err, status, msg) {
      console.log(status + msg);
      this.data.loading = false;
    };

    req.then(success.bind(this), error.bind(this));
  },

  remove: function() {
    subscriptions.tempEl = $(this).closest('.removeSub');
    $.ajax('/api/users/' + subscriptions.els.addForm.data('id'), {
      type: 'PUT',
      dataType: 'json',
      context: subscriptions,
      data: { 'removeSub': subscriptions.tempEl.data('sub') },
      success: function(res) {
        var removeSub = subscriptions.tempEl.closest('.removeSub');
        delete subscriptions.tempEl;
        this.data.subs.splice(this.data.subs.indexOf(removeSub.data('sub')), 1);
        removeSub.remove();
      },
      error: function(err, status, msg) {
        console.log(status + msg);
      }
    });
  }

};

$(function() { subscriptions.init(); });
<commit_msg>Add total subscriptions<commit_after>var subscriptions = {

  init: function() {
    if ($('#subscriptions').length >= 1) {
      this.setCSRFToken($('meta[name="csrf-token"]').attr('content'));

      $.ajax('/api/users/' + this.els.addForm.data('id'), {
        dataType: 'json',
        success: this.show.bind(this),
        complete: function() {
          $('#spinner').hide();
        }
      });

      this.els.addForm.on('submit', this.update.bind(this));
      this.els.list.on('click', '.glyphicon-remove', this.remove);
    }
  },

  els: {
    'addForm': $('#addSub'),
    'list': $('#subsList'),
    'searchInput': $('#searchSub')
  },

  data: {
    subs: [],
    loading: false
  },

  setCSRFToken: function(securityToken) {
    $.ajaxPrefilter(function(options, _, xhr) {
      if (!xhr.crossDomain) {
        xhr.setRequestHeader('X-CSRF-Token', securityToken);
      }
    });
  },

  cleanInput: function(input) {
    return input.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>') ;
  },

  show: function(res) {
    res.subscriptions.sort(function(a, b) {
      return b.toLowerCase() < a.toLowerCase();
    });
    $.each(res.subscriptions, this.render.bind(this));
    this.els.searchInput.attr('placeholder', 'Add a subscription (Total subscriptions: ' + this.data.subs.length + ')');
  },

  render: function(index, sub) {
    sub = this.cleanInput(sub);
    var display = '
' +
                  '' + sub + '	' +
                  '	' +
                  '
';

    this.els.list.append(display);
    this.data.subs.push(sub.toLowerCase());
  },

  update: function(e) {
    e.preventDefault();

    if (this.data.loading) {
      return;
    }

    var input = this.cleanInput(this.els.searchInput.val().toLowerCase());
    if (this.data.subs.indexOf(input) >= 0) {
      return $('.top-right').notify({
        type: 'danger',
        message: { text: 'You already added ' + this.els.searchInput.val() + '.'  }
      }).show();
    }

    this.data.loading = true;

    var req = $.ajax(this.els.addForm.attr('action'), {
      type: 'PUT',
      dataType: 'json',
      data: { 'addSub': this.els.searchInput.val() },
    });

    var success = function(res) {
      var searchInput = this.els.searchInput;
      var value = this.cleanInput(searchInput.val());
      var display = '
' +
                    '' + value + '	' +
                    '	' +
                    '
';
      this.els.list.prepend(display);
      this.data.subs.push(value.toLowerCase());
      this.els.searchInput.attr('placeholder', 'Add a subscription (Total subscriptions: ' + this.data.subs.length + ')');
      this.data.loading = false;
      searchInput.val('');
      setTimeout(function() {
        $('.highlight').removeClass('highlight');
      }, 1000);
    };

    var error = function(err, status, msg) {
      console.log(status + msg);
      this.data.loading = false;
    };

    req.then(success.bind(this), error.bind(this));
  },

  remove: function() {
    subscriptions.tempEl = $(this).closest('.removeSub');
    $.ajax('/api/users/' + subscriptions.els.addForm.data('id'), {
      type: 'PUT',
      dataType: 'json',
      context: subscriptions,
      data: { 'removeSub': subscriptions.tempEl.data('sub') },
      success: function(res) {
        var removeSub = subscriptions.tempEl.closest('.removeSub');
        delete subscriptions.tempEl;
        this.data.subs.splice(this.data.subs.indexOf(removeSub.data('sub')), 1);
        this.els.searchInput.attr('placeholder', 'Add a subscription (Total subscriptions: ' + this.data.subs.length + ')');
        removeSub.remove();
      },
      error: function(err, status, msg) {
        console.log(status + msg);
      }
    });
  }

};

$(function() { subscriptions.init(); });
<|endoftext|>


<commit_before>/* global window, document, $, mapboxgl */
/* eslint no-var: "off", prefer-arrow-callback: "off", no-unused-vars: "off" */

const maps = {};

function formatRoute(route) {
  const html = route.route_url ? $('<a>').attr('href', route.route_url) : $('<div>');

  html.addClass('route-item text-sm mb-2');

  if (route.route_color) {
    $('<div>')
      .addClass('route-color-swatch mr-2 flex-shrink-0')
      .css('backgroundColor', route.route_color)
      .appendTo(html);
  }

  $('<span>')
    .text(`${route.route_short_name} ${route.route_long_name}`)
    .appendTo(html);

  return html.prop('outerHTML');
}

function formatStopPopup(feature) {
  const routes = JSON.parse(feature.properties.routes);
  const html = $('<div>');

  $('<div>')
    .addClass('popup-title')
    .text(feature.properties.stop_name)
    .appendTo(html);

  if (feature.properties.stop_code !== null) {
    $('<label>')
      .addClass('mr-1')
      .text('Stop Code:')
      .appendTo(html);

    $('<strong>')
      .text(feature.properties.stop_code)
      .appendTo(html);
  }

  $('<div>')
    .text('Routes Served:')
    .appendTo(html);

  $(html).append(routes.map(route => formatRoute(route)));

  return html.prop('outerHTML');
}

function getBounds(geojson) {
  const bounds = new mapboxgl.LngLatBounds();
  for (const feature of geojson.features) {
    if (feature.geometry.type === 'Point') {
      bounds.extend(feature.geometry.coordinates);
    } else if (feature.geometry.type === 'LineString') {
      for (const coordinate of feature.geometry.coordinates) {
        bounds.extend(coordinate);
      }
    }
  }

  return bounds;
}

function createMap(id, geojson, routeColor) {
  const defaultRouteColor = '#FF4728';

  if (!geojson || geojson.features.length === 0) {
    $('#map_' + id).hide();
    return false;
  }

  if (!routeColor) {
    routeColor = defaultRouteColor;
  }

  const bounds = getBounds(geojson);
  const map = new mapboxgl.Map({
    container: 'map_' + id,
    style: 'mapbox://styles/mapbox/light-v10',
    center: bounds.getCenter(),
    zoom: 12,
    preserveDrawingBuffer: true
  });

  map.scrollZoom.disable();
  map.addControl(new mapboxgl.NavigationControl());

  map.on('load', () => {
    map.fitBounds(bounds, {
      padding: {
        top: 40,
        bottom: 40,
        left: 20,
        right: 40
      },
      duration: 0
    });

    // Add route line outline first
    map.addLayer({
      id: 'route-line-outline',
      type: 'line',
      source: {
        type: 'geojson',
        data: geojson
      },
      paint: {
        'line-color': '#FFFFFF',
        'line-opacity': 1,
        'line-width': 6
      },
      layout: {
        'line-join': 'round',
        'line-cap': 'round'
      },
      filter: ['!has', 'stop_id']
    });

    map.addLayer({
      id: 'route-line',
      type: 'line',
      source: {
        type: 'geojson',
        data: geojson
      },
      paint: {
        'line-color': routeColor,
        'line-opacity': 1,
        'line-width': 2
      },
      layout: {
        'line-join': 'round',
        'line-cap': 'round'
      },
      filter: ['!has', 'stop_id']
    });

    map.addLayer({
      id: 'stops',
      type: 'circle',
      source: {
        type: 'geojson',
        data: geojson
      },
      paint: {
        'circle-radius': {
          stops: [
            [9, 3],
            [13, 6],
            [15, 8]
          ]
        },
        'circle-stroke-width': 1,
        'circle-stroke-color': '#363636',
        'circle-color': routeColor
      },
      filter: ['has', 'stop_id']
    });

    map.addLayer({
      id: 'stops-highlighted',
      type: 'circle',
      source: {
        type: 'geojson',
        data: geojson
      },
      paint: {
        'circle-radius': {
          stops: [
            [9, 6],
            [13, 9],
            [15, 10]
          ]
        },
        'circle-stroke-width': 2,
        'circle-stroke-color': '#111111',
        'circle-color': routeColor
      },
      filter: ['==', 'stop_id', '']
    });

    map.on('mouseenter', 'stops', () => {
      map.getCanvas().style.cursor = 'pointer';
    });

    map.on('mouseleave', 'stops', () => {
      map.getCanvas().style.cursor = '';
    });

    map.on('mousemove', event => {
      const features = map.queryRenderedFeatures(event.point, {
        layers: ['stops']
      });
      if (features.length > 0) {
        map.getCanvas().style.cursor = 'pointer';
        highlightStop(features[0].properties.stop_id);
      } else {
        map.getCanvas().style.cursor = '';
        unHighlightStop();
      }
    });

    map.on('click', event => {
      // Set bbox as 5px reactangle area around clicked point
      const bbox = [
        [event.point.x - 5, event.point.y - 5],
        [event.point.x + 5, event.point.y + 5]
      ];
      const features = map.queryRenderedFeatures(bbox, {
        layers: ['stops']
      });

      if (!features || features.length === 0) {
        return;
      }

      // Get the first feature and show popup
      const feature = features[0];

      new mapboxgl.Popup()
        .setLngLat(feature.geometry.coordinates)
        .setHTML(formatStopPopup(feature))
        .addTo(map);
    });

    function highlightStop(stopId) {
      map.setFilter('stops-highlighted', ['==', 'stop_id', stopId]);
      map.setPaintProperty('stops', 'circle-opacity', 0.5);
      map.setPaintProperty('stops', 'circle-stroke-opacity', 0.5);
    }

    function unHighlightStop() {
      map.setFilter('stops-highlighted', ['==', 'stop_id', '']);
      map.setPaintProperty('stops', 'circle-opacity', 1);
      map.setPaintProperty('stops', 'circle-stroke-opacity', 1);
    }

    // On table hover, highlight stop on map
    $('th, td', $('#' + id + ' table')).hover(event => {
      let stopId;
      const table = $(event.target).parents('table');
      if (table.data('orientation') === 'vertical') {
        var index = $(event.target).index();
        stopId = $('colgroup col', table).eq(index).data('stop-id');
      } else {
        stopId = $(event.target).parents('tr').data('stop-id');
      }

      if (stopId === undefined) {
        return;
      }

      highlightStop(stopId.toString());
    }, unHighlightStop);
  });

  maps[id] = map;
}
<commit_msg>timetable map stop styles<commit_after>/* global window, document, $, mapboxgl */
/* eslint no-var: "off", prefer-arrow-callback: "off", no-unused-vars: "off" */

const maps = {};

function formatRoute(route) {
  const html = route.route_url ? $('<a>').attr('href', route.route_url) : $('<div>');

  html.addClass('route-item text-sm mb-2');

  if (route.route_color) {
    $('<div>')
      .addClass('route-color-swatch mr-2 flex-shrink-0')
      .css('backgroundColor', route.route_color)
      .appendTo(html);
  }

  $('<span>')
    .text(`${route.route_short_name} ${route.route_long_name}`)
    .appendTo(html);

  return html.prop('outerHTML');
}

function formatStopPopup(feature) {
  const routes = JSON.parse(feature.properties.routes);
  const html = $('<div>');

  $('<div>')
    .addClass('popup-title')
    .text(feature.properties.stop_name)
    .appendTo(html);

  if (feature.properties.stop_code !== null) {
    $('<label>')
      .addClass('mr-1')
      .text('Stop Code:')
      .appendTo(html);

    $('<strong>')
      .text(feature.properties.stop_code)
      .appendTo(html);
  }

  $('<div>')
    .text('Routes Served:')
    .appendTo(html);

  $(html).append(routes.map(route => formatRoute(route)));

  return html.prop('outerHTML');
}

function getBounds(geojson) {
  const bounds = new mapboxgl.LngLatBounds();
  for (const feature of geojson.features) {
    if (feature.geometry.type === 'Point') {
      bounds.extend(feature.geometry.coordinates);
    } else if (feature.geometry.type === 'LineString') {
      for (const coordinate of feature.geometry.coordinates) {
        bounds.extend(coordinate);
      }
    }
  }

  return bounds;
}

function createMap(id, geojson, routeColor) {
  const defaultRouteColor = '#FF4728';

  if (!geojson || geojson.features.length === 0) {
    $('#map_' + id).hide();
    return false;
  }

  if (!routeColor) {
    routeColor = defaultRouteColor;
  }

  const bounds = getBounds(geojson);
  const map = new mapboxgl.Map({
    container: 'map_' + id,
    style: 'mapbox://styles/mapbox/light-v10',
    center: bounds.getCenter(),
    zoom: 12,
    preserveDrawingBuffer: true
  });

  map.scrollZoom.disable();
  map.addControl(new mapboxgl.NavigationControl());

  map.on('load', () => {
    map.fitBounds(bounds, {
      padding: {
        top: 40,
        bottom: 40,
        left: 20,
        right: 40
      },
      duration: 0
    });

    // Add route line outline first
    map.addLayer({
      id: 'route-line-outline',
      type: 'line',
      source: {
        type: 'geojson',
        data: geojson
      },
      paint: {
        'line-color': '#FFFFFF',
        'line-opacity': 1,
        'line-width': 6
      },
      layout: {
        'line-join': 'round',
        'line-cap': 'round'
      },
      filter: ['!has', 'stop_id']
    });

    map.addLayer({
      id: 'route-line',
      type: 'line',
      source: {
        type: 'geojson',
        data: geojson
      },
      paint: {
        'line-color': routeColor,
        'line-opacity': 1,
        'line-width': 2
      },
      layout: {
        'line-join': 'round',
        'line-cap': 'round'
      },
      filter: ['!has', 'stop_id']
    });

    map.addLayer({
      id: 'stops',
      type: 'circle',
      source: {
        type: 'geojson',
        data: geojson
      },
      paint: {
        'circle-radius': {
          stops: [
            [9, 2],
            [13, 4],
            [15, 6]
          ]
        },
        'circle-stroke-width': 1,
        'circle-stroke-color': '#363636',
        'circle-color': '#363636'
      },
      filter: ['has', 'stop_id']
    });

    map.addLayer({
      id: 'stops-highlighted',
      type: 'circle',
      source: {
        type: 'geojson',
        data: geojson
      },
      paint: {
        'circle-radius': {
          stops: [
            [9, 3],
            [13, 4],
            [15, 7]
          ]
        },
        'circle-stroke-width': 2,
        'circle-stroke-color': '#666666',
        'circle-color': '#888888'
      },
      filter: ['==', 'stop_id', '']
    });

    map.on('mousemove', event => {
      const features = map.queryRenderedFeatures(event.point, {
        layers: ['stops']
      });
      if (features.length > 0) {
        map.getCanvas().style.cursor = 'pointer';
        highlightStop(features[0].properties.stop_id);
      } else {
        map.getCanvas().style.cursor = '';
        unHighlightStop();
      }
    });

    map.on('click', event => {
      // Set bbox as 5px rectangle area around clicked point
      const bbox = [
        [event.point.x - 5, event.point.y - 5],
        [event.point.x + 5, event.point.y + 5]
      ];
      const features = map.queryRenderedFeatures(bbox, {
        layers: ['stops']
      });

      if (!features || features.length === 0) {
        return;
      }

      // Get the first feature and show popup
      const feature = features[0];

      new mapboxgl.Popup()
        .setLngLat(feature.geometry.coordinates)
        .setHTML(formatStopPopup(feature))
        .addTo(map);
    });

    function highlightStop(stopId) {
      map.setFilter('stops-highlighted', ['==', 'stop_id', stopId]);
      map.setPaintProperty('stops', 'circle-opacity', 0.5);
      map.setPaintProperty('stops', 'circle-stroke-opacity', 0.5);
    }

    function unHighlightStop() {
      map.setFilter('stops-highlighted', ['==', 'stop_id', '']);
      map.setPaintProperty('stops', 'circle-opacity', 1);
      map.setPaintProperty('stops', 'circle-stroke-opacity', 1);
    }

    // On table hover, highlight stop on map
    $('th, td', $('#' + id + ' table')).hover(event => {
      let stopId;
      const table = $(event.target).parents('table');
      if (table.data('orientation') === 'vertical') {
        var index = $(event.target).index();
        stopId = $('colgroup col', table).eq(index).data('stop-id');
      } else {
        stopId = $(event.target).parents('tr').data('stop-id');
      }

      if (stopId === undefined) {
        return;
      }

      highlightStop(stopId.toString());
    }, unHighlightStop);
  });

  maps[id] = map;
}
<|endoftext|>