<commit_before>var _ = require("underscore")._,
    colors = require("colors");

function ArgParser() {
   this.commands = {};  // expected commands
   this.specs = {};     // option specifications
}

ArgParser.prototype = {
  /* Add a command to the expected commands */
  command : function(name) {
    var command;
    if (name) {
      command = this.commands[name] = {
        name: name,
        specs: {}
      };
    }
    else {
      command = this.fallback = {
        specs: {}
      };
    }

    // facilitates command('name').options().cb().help()
    var chain = {
      options : function(specs) {
        command.specs = specs;
        return chain;
      },
      opts : function(specs) {
        // old API
        return this.options(specs);
      },
      option : function(name, spec) {
        command.specs[name] = spec;
        return chain;
      },
      callback : function(cb) {
        command.cb = cb;
        return chain;
      },
      help : function(help) {
        command.help = help;
        return chain;
      },
      usage : function(usage) {
        command._usage = usage;
        return chain;
      }
    };
    return chain;
  },

  nocommand : function() {
    return this.command();
  },

  options : function(specs) {
    this.specs = specs;
    return this;
  },

  opts : function(specs) {
    // old API
    return this.options(specs);
  },

  globalOpts : function(specs) {
    // old API
    return this.options(specs);
  },

  option : function(name, spec) {
    this.specs[name] = spec;
    return this;
  },

  usage : function(usage) {
    this._usage = usage;
    return this;
  },

  printer : function(print) {
    this.print = print;
    return this;
  },

  script : function(script) {
    this._script = script;
    return this;
  },

  scriptName : function(script) {
    // old API
    return this.script(script);
  },

  help : function(help) {
    this._help = help;
    return this;
  },

  colors : function() {
    this._colors = true;
    return this;
  },

  parseArgs : function(argv) {
    // old API
    return this.parse(argv);
  },

  nom : function(argv) {
    return this.parse(argv);
  },

  parse : function(argv) {
    this.print = this.print || function(str, code) {
      console.log(str + '\n');
      process.exit(code || 0);
    };
    this._help = this._help || "";
    this._script = this._script || process.argv[0] + " "
          + require('path').basename(process.argv[1]);
    this.specs = this.specs || {};

    var argv = argv || process.argv.slice(2);

    var arg = Arg(argv[0]).isValue && argv[0],
        command = arg && this.commands[arg],
        commandExpected = !_(this.commands).isEmpty();

    if (commandExpected) {
       if (command) {
          _(this.specs).extend(command.specs);
          this._script += " " + command.name;
          if (command.help) {
            this._help = command.help;
          }
          this.command = command;
       }
       else if (arg) {
          return this.print(this._script + ": no such command '" + arg + "'", 1);
       }
       else {
          // no command but command expected e.g. 'git -v'
          this.specs.command = {
            position: 0,
            help: 'one of: ' + _(this.commands).keys().join(", ")
          }
          if (this.fallback) {
            _(this.specs).extend(this.fallback.specs);
            this._help = this.fallback.help;
          } else {
            this.specs.command.required = true;
          }
       }
    }

    if (this.specs.length === undefined) {
      // specs is a hash not an array
      this.specs = _(this.specs).map(function(opt, name) {
        opt.name = name;
        return opt;
      });
    }
    this.specs = this.specs.map(function(opt) {
      return Opt(opt);
    });

    if (argv.indexOf("--help") >= 0 || argv.indexOf("-h") >= 0) {
      return this.print(this.getUsage());
    }

    var options = {};
    var args = argv.map(function(arg) {
      return Arg(arg);
    })
    .concat(Arg());

    var positionals = [];

    /* parse the args */
    var that = this;
    args.reduce(function(arg, val) {
      /* positional */
      if (arg.isValue) {
        positionals.push(arg.value);
      }
      else if (arg.chars) {
        var last = arg.chars.pop();

        /* -cfv */
        (arg.chars).forEach(function(ch) {
          that.setOption(options, ch, true);
        });

        /* -v key */
        if (!that.opt(last).flag) {
           if (val.isValue)  {
              that.setOption(options, last, val.value);
              return Arg(); // skip next turn - swallow arg
           }
           else {
              that.print("'-" + (that.opt(last).name || last) + "'"
                + " expects a value\n\n" + that.getUsage(), 1);
           }
        }
        else {
          /* -v */
          that.setOption(options, last, true);
        }

      }
      else if (arg.full) {
        var value = arg.value;

        /* --key */
        if (value === undefined) {
          /* --key value */
          if (!that.opt(arg.full).flag) {
            if (val.isValue) {
              that.setOption(options, arg.full, val.value);
              return Arg();
            }
            else {
              that.print("'--" + (that.opt(arg.full).name || arg.full) + "'"
                + " expects a value\n\n" + that.getUsage(), 1);
            }
          }
          else {
            /* --flag */
            value = true;
          }
        }
        that.setOption(options, arg.full, value);
      }
      return val;
    });

    positionals.forEach(function(pos, index) {
      this.setOption(options, index, pos);
    }, this);

    options._ = positionals;

    this.specs.forEach(function(opt) {
      if (opt.default !== undefined && options[opt.name] === undefined) {
        options[opt.name] = opt.default;
      }
    }, this);

    // exit if required arg isn't present
    this.specs.forEach(function(opt) {
      if (opt.required && options[opt.name] === undefined) {
         this.print("\n" + opt.name + " argument is required\n" + this.getUsage(), 1);
      }
    }, this);

    if (command && command.cb) {
      command.cb(options);
    }
    else if (this.fallback && this.fallback.cb) {
      this.fallback.cb(options);
    }

    return options;
  },

  getUsage : function() {
    if (this.command && this.command._usage) {
      return this.command._usage;
    }
    else if (this.fallback && this.fallback._usage) {
      return this.fallback._usage;
    }
    if (this._usage) {
      return this._usage;
    }

    // todo: use a template
    var str = "\n"
    if (this._colors) {
      str += "Usage:".bold;
    }
    else {
      str += "Usage:";
    }
    str += " " + this._script;

    var positionals = _(this.specs).select(function(opt) {
      return opt.position != undefined;
    })
    positionals = _(positionals).sortBy(function(opt) {
      return opt.position;
    });
    var options = _(this.specs).select(function(opt) {
      return opt.position === undefined;
    });

    // assume there are no gaps in the specified pos. args
    positionals.forEach(function(pos) {
      str += " ";
      var posStr = pos.string;
      if (!posStr) {
        posStr = pos.name || "arg" + pos.position;
        if (pos.required) {
            posStr = "<" + posStr + ">";
        } else {
            posStr = "[" + posStr + "]";
        }
        if (pos.list) {
          posStr += "...";
        }
      }
      str += posStr;
    });

    if (options.length) {
      if (this._colors) {
        // must be a better way to do this
        str += " [options]".blue;
      }
      else {
        str += " [options]";
      }
    }

    if (options.length || positionals.length) {
      str += "\n\n";
    }

    function spaces(length) {
      var spaces = "";
      for (var i = 0; i < length; i++) {
        spaces += " ";
      }
      return spaces;
    }
    var longest = positionals.reduce(function(max, pos) {
      return pos.name.length > max ? pos.name.length : max;
    }, 0);

    positionals.forEach(function(pos) {
      var posStr = pos.string || pos.name;
      str += posStr + spaces(longest - posStr.length) + "     ";
      if (this._colors) {
        str += (pos.help || "").grey
      }
      else {
        str += (pos.help || "")
      }
      str += "\n";
    }, this);
    if (positionals.length && options.length) {
      str += "\n";
    }

    if (options.length) {
      if (this._colors) {
        str += "Options:".blue;
      }
      else {
        str += "Options:";
      }
      str += "\n"

      var longest = options.reduce(function(max, opt) {
        return opt.string.length > max && !opt.hidden ? opt.string.length : max;
      }, 0);

      options.forEach(function(opt) {
        if (!opt.hidden) {
          str += "   " + opt.string + spaces(longest - opt.string.length) + "   ";
          if (this._colors) {
            str += (opt.help || "").grey;
          }
          else {
            str += (opt.help || "")
          }
          str += "\n";
        }
      }, this);
    }

    if (this._help) {
      str += "\n" + this._help;
    }
    return str + "\n";
  }
};

ArgParser.prototype.opt = function(arg) {
  // get the specified opt for this parsed arg
  var match = Opt({});
  this.specs.forEach(function(opt) {
    if (opt.matches(arg)) {
       match = opt;
    }
  });
  return match;
};

ArgParser.prototype.setOption = function(options, arg, value) {
  var option = this.opt(arg);
  if (option.callback) {
    var message = option.callback(value);

    if (typeof message == "string") {
      this.print(message, 1);
    }
  }

  if (option.type != "string") {
     try {
       // infer type by JSON parsing the string
       value = JSON.parse(value)
     }
     catch(e) {}
  }

  var name = option.name || arg;
  if (option.choices && option.choices.indexOf(value) == -1) {
     this.print(name + " must be one of: " + option.choices.join(", "), 1);
  }

  if (option.list) {
    if (!options[name]) {
      options[name] = [value];
    }
    else {
      options[name].push(value);
    }
  }
  else {
    options[name] = value;
  }
};

/* an arg is an item that's actually parsed from the command line
   e.g. "-l", "log.txt", or "--logfile=log.txt" */
Arg = function(str) {
  var abbrRegex = /^\-(\w+?)$/,
      fullRegex = /^\-\-(no\-)?(.+?)(?:=(.+))?$/,
      valRegex = /^[^\-].*/;

  var charMatch = abbrRegex.exec(str),
      chars = charMatch && charMatch[1].split("");

  var fullMatch = fullRegex.exec(str),
      full = fullMatch && fullMatch[2];

  var isValue = str !== undefined && (str === "" || valRegex.test(str));
  var value;
  if (isValue) {
    value = str;
  }
  else if (full) {
    value = fullMatch[1] ? false : fullMatch[3];
  }

  return {
    str: str,
    chars: chars,
    full: full,
    value: value,
    isValue: isValue
  }
}

/* an opt is what's specified by the user in opts hash */
Opt = function(opt) {
  var strings = (opt.string || "").split(","),
      abbr, full, metavar;
  for (var i = 0; i < strings.length; i++) {
    var string = strings[i].trim(),
        matches;
    if (matches = string.match(/^\-([^-])(?:\s+(.*))?$/)) {
      abbr = matches[1];
      metavar = matches[2];
    }
    else if (matches = string.match(/^\-\-(.+?)(?:[=\s]+(.+))?$/)) {
      full = matches[1];
      metavar = metavar || matches[2];
    }
  }

  matches = matches || [];
  var abbr = opt.abbr || abbr,   // e.g. v from -v
      full = opt.full || full, // e.g. verbose from --verbose
      metavar = opt.metavar || metavar;  // e.g. PATH from '--config=PATH'

  var string;
  if (opt.string) {
    string = opt.string;
  }
  else if (opt.position === undefined) {
    string = "";
    if (abbr) {
      string += "-" + abbr;
      if (metavar)
        string += " " + metavar
      string += ", ";
    }
    string += "--" + (full || opt.name);
    if (metavar) {
      string += " " + metavar;
    }
  }

  opt = _(opt).extend({
    name: opt.name || full || abbr,
    string: string,
    abbr: abbr,
    full: full,
    metavar: metavar,
    matches: function(arg) {
      return opt.full == arg || opt.abbr == arg || opt.position == arg
        || opt.name == arg || (opt.list && arg >= opt.position);
    }
  });
  return opt;
}

var createParser = function() {
  return new ArgParser();
}

var nomnom = createParser();

for (var i in nomnom) {
  if (typeof nomnom[i] == "function") {
     createParser[i] = _(nomnom[i]).bind(nomnom);
  }
}

module.exports = createParser;
<commit_msg>Append default values to options help if any.<commit_after>var _ = require("underscore")._,
    colors = require("colors");

function ArgParser() {
   this.commands = {};  // expected commands
   this.specs = {};     // option specifications
}

ArgParser.prototype = {
  /* Add a command to the expected commands */
  command : function(name) {
    var command;
    if (name) {
      command = this.commands[name] = {
        name: name,
        specs: {}
      };
    }
    else {
      command = this.fallback = {
        specs: {}
      };
    }

    // facilitates command('name').options().cb().help()
    var chain = {
      options : function(specs) {
        command.specs = specs;
        return chain;
      },
      opts : function(specs) {
        // old API
        return this.options(specs);
      },
      option : function(name, spec) {
        command.specs[name] = spec;
        return chain;
      },
      callback : function(cb) {
        command.cb = cb;
        return chain;
      },
      help : function(help) {
        command.help = help;
        return chain;
      },
      usage : function(usage) {
        command._usage = usage;
        return chain;
      }
    };
    return chain;
  },

  nocommand : function() {
    return this.command();
  },

  options : function(specs) {
    this.specs = specs;
    return this;
  },

  opts : function(specs) {
    // old API
    return this.options(specs);
  },

  globalOpts : function(specs) {
    // old API
    return this.options(specs);
  },

  option : function(name, spec) {
    this.specs[name] = spec;
    return this;
  },

  usage : function(usage) {
    this._usage = usage;
    return this;
  },

  printer : function(print) {
    this.print = print;
    return this;
  },

  script : function(script) {
    this._script = script;
    return this;
  },

  scriptName : function(script) {
    // old API
    return this.script(script);
  },

  help : function(help) {
    this._help = help;
    return this;
  },

  colors : function() {
    this._colors = true;
    return this;
  },

  parseArgs : function(argv) {
    // old API
    return this.parse(argv);
  },

  nom : function(argv) {
    return this.parse(argv);
  },

  parse : function(argv) {
    this.print = this.print || function(str, code) {
      console.log(str + '\n');
      process.exit(code || 0);
    };
    this._help = this._help || "";
    this._script = this._script || process.argv[0] + " "
          + require('path').basename(process.argv[1]);
    this.specs = this.specs || {};

    var argv = argv || process.argv.slice(2);

    var arg = Arg(argv[0]).isValue && argv[0],
        command = arg && this.commands[arg],
        commandExpected = !_(this.commands).isEmpty();

    if (commandExpected) {
       if (command) {
          _(this.specs).extend(command.specs);
          this._script += " " + command.name;
          if (command.help) {
            this._help = command.help;
          }
          this.command = command;
       }
       else if (arg) {
          return this.print(this._script + ": no such command '" + arg + "'", 1);
       }
       else {
          // no command but command expected e.g. 'git -v'
          this.specs.command = {
            position: 0,
            help: 'one of: ' + _(this.commands).keys().join(", ")
          }
          if (this.fallback) {
            _(this.specs).extend(this.fallback.specs);
            this._help = this.fallback.help;
          } else {
            this.specs.command.required = true;
          }
       }
    }

    if (this.specs.length === undefined) {
      // specs is a hash not an array
      this.specs = _(this.specs).map(function(opt, name) {
        opt.name = name;
        return opt;
      });
    }
    this.specs = this.specs.map(function(opt) {
      return Opt(opt);
    });

    if (argv.indexOf("--help") >= 0 || argv.indexOf("-h") >= 0) {
      return this.print(this.getUsage());
    }

    var options = {};
    var args = argv.map(function(arg) {
      return Arg(arg);
    })
    .concat(Arg());

    var positionals = [];

    /* parse the args */
    var that = this;
    args.reduce(function(arg, val) {
      /* positional */
      if (arg.isValue) {
        positionals.push(arg.value);
      }
      else if (arg.chars) {
        var last = arg.chars.pop();

        /* -cfv */
        (arg.chars).forEach(function(ch) {
          that.setOption(options, ch, true);
        });

        /* -v key */
        if (!that.opt(last).flag) {
           if (val.isValue)  {
              that.setOption(options, last, val.value);
              return Arg(); // skip next turn - swallow arg
           }
           else {
              that.print("'-" + (that.opt(last).name || last) + "'"
                + " expects a value\n\n" + that.getUsage(), 1);
           }
        }
        else {
          /* -v */
          that.setOption(options, last, true);
        }

      }
      else if (arg.full) {
        var value = arg.value;

        /* --key */
        if (value === undefined) {
          /* --key value */
          if (!that.opt(arg.full).flag) {
            if (val.isValue) {
              that.setOption(options, arg.full, val.value);
              return Arg();
            }
            else {
              that.print("'--" + (that.opt(arg.full).name || arg.full) + "'"
                + " expects a value\n\n" + that.getUsage(), 1);
            }
          }
          else {
            /* --flag */
            value = true;
          }
        }
        that.setOption(options, arg.full, value);
      }
      return val;
    });

    positionals.forEach(function(pos, index) {
      this.setOption(options, index, pos);
    }, this);

    options._ = positionals;

    this.specs.forEach(function(opt) {
      if (opt.default !== undefined && options[opt.name] === undefined) {
        options[opt.name] = opt.default;
      }
    }, this);

    // exit if required arg isn't present
    this.specs.forEach(function(opt) {
      if (opt.required && options[opt.name] === undefined) {
         this.print("\n" + opt.name + " argument is required\n" + this.getUsage(), 1);
      }
    }, this);

    if (command && command.cb) {
      command.cb(options);
    }
    else if (this.fallback && this.fallback.cb) {
      this.fallback.cb(options);
    }

    return options;
  },

  getUsage : function() {
    if (this.command && this.command._usage) {
      return this.command._usage;
    }
    else if (this.fallback && this.fallback._usage) {
      return this.fallback._usage;
    }
    if (this._usage) {
      return this._usage;
    }

    // todo: use a template
    var str = "\n"
    if (this._colors) {
      str += "Usage:".bold;
    }
    else {
      str += "Usage:";
    }
    str += " " + this._script;

    var positionals = _(this.specs).select(function(opt) {
      return opt.position != undefined;
    })
    positionals = _(positionals).sortBy(function(opt) {
      return opt.position;
    });
    var options = _(this.specs).select(function(opt) {
      return opt.position === undefined;
    });

    // assume there are no gaps in the specified pos. args
    positionals.forEach(function(pos) {
      str += " ";
      var posStr = pos.string;
      if (!posStr) {
        posStr = pos.name || "arg" + pos.position;
        if (pos.required) {
            posStr = "<" + posStr + ">";
        } else {
            posStr = "[" + posStr + "]";
        }
        if (pos.list) {
          posStr += "...";
        }
      }
      str += posStr;
    });

    if (options.length) {
      if (this._colors) {
        // must be a better way to do this
        str += " [options]".blue;
      }
      else {
        str += " [options]";
      }
    }

    if (options.length || positionals.length) {
      str += "\n\n";
    }

    function spaces(length) {
      var spaces = "";
      for (var i = 0; i < length; i++) {
        spaces += " ";
      }
      return spaces;
    }
    var longest = positionals.reduce(function(max, pos) {
      return pos.name.length > max ? pos.name.length : max;
    }, 0);

    positionals.forEach(function(pos) {
      var posStr = pos.string || pos.name;
      str += posStr + spaces(longest - posStr.length) + "     ";
      if (this._colors) {
        str += (pos.help || "").grey
      }
      else {
        str += (pos.help || "")
      }
      str += "\n";
    }, this);
    if (positionals.length && options.length) {
      str += "\n";
    }

    if (options.length) {
      if (this._colors) {
        str += "Options:".blue;
      }
      else {
        str += "Options:";
      }
      str += "\n"

      var longest = options.reduce(function(max, opt) {
        return opt.string.length > max && !opt.hidden ? opt.string.length : max;
      }, 0);

      options.forEach(function(opt) {
        if (!opt.hidden) {
          str += "   " + opt.string + spaces(longest - opt.string.length) + "   ";
          if (this._colors) {
            str += ((opt.help + (opt.default != null ? "  [" + opt.default + "]" : "")) || "").grey;
          }
          else {
            str += ((opt.help + (opt.default != null ? "  [" + opt.default + "]" : "")) || "")
          }
          str += "\n";
        }
      }, this);
    }

    if (this._help) {
      str += "\n" + this._help;
    }
    return str + "\n";
  }
};

ArgParser.prototype.opt = function(arg) {
  // get the specified opt for this parsed arg
  var match = Opt({});
  this.specs.forEach(function(opt) {
    if (opt.matches(arg)) {
       match = opt;
    }
  });
  return match;
};

ArgParser.prototype.setOption = function(options, arg, value) {
  var option = this.opt(arg);
  if (option.callback) {
    var message = option.callback(value);

    if (typeof message == "string") {
      this.print(message, 1);
    }
  }

  if (option.type != "string") {
     try {
       // infer type by JSON parsing the string
       value = JSON.parse(value)
     }
     catch(e) {}
  }

  var name = option.name || arg;
  if (option.choices && option.choices.indexOf(value) == -1) {
     this.print(name + " must be one of: " + option.choices.join(", "), 1);
  }

  if (option.list) {
    if (!options[name]) {
      options[name] = [value];
    }
    else {
      options[name].push(value);
    }
  }
  else {
    options[name] = value;
  }
};

/* an arg is an item that's actually parsed from the command line
   e.g. "-l", "log.txt", or "--logfile=log.txt" */
Arg = function(str) {
  var abbrRegex = /^\-(\w+?)$/,
      fullRegex = /^\-\-(no\-)?(.+?)(?:=(.+))?$/,
      valRegex = /^[^\-].*/;

  var charMatch = abbrRegex.exec(str),
      chars = charMatch && charMatch[1].split("");

  var fullMatch = fullRegex.exec(str),
      full = fullMatch && fullMatch[2];

  var isValue = str !== undefined && (str === "" || valRegex.test(str));
  var value;
  if (isValue) {
    value = str;
  }
  else if (full) {
    value = fullMatch[1] ? false : fullMatch[3];
  }

  return {
    str: str,
    chars: chars,
    full: full,
    value: value,
    isValue: isValue
  }
}

/* an opt is what's specified by the user in opts hash */
Opt = function(opt) {
  var strings = (opt.string || "").split(","),
      abbr, full, metavar;
  for (var i = 0; i < strings.length; i++) {
    var string = strings[i].trim(),
        matches;
    if (matches = string.match(/^\-([^-])(?:\s+(.*))?$/)) {
      abbr = matches[1];
      metavar = matches[2];
    }
    else if (matches = string.match(/^\-\-(.+?)(?:[=\s]+(.+))?$/)) {
      full = matches[1];
      metavar = metavar || matches[2];
    }
  }

  matches = matches || [];
  var abbr = opt.abbr || abbr,   // e.g. v from -v
      full = opt.full || full, // e.g. verbose from --verbose
      metavar = opt.metavar || metavar;  // e.g. PATH from '--config=PATH'

  var string;
  if (opt.string) {
    string = opt.string;
  }
  else if (opt.position === undefined) {
    string = "";
    if (abbr) {
      string += "-" + abbr;
      if (metavar)
        string += " " + metavar
      string += ", ";
    }
    string += "--" + (full || opt.name);
    if (metavar) {
      string += " " + metavar;
    }
  }

  opt = _(opt).extend({
    name: opt.name || full || abbr,
    string: string,
    abbr: abbr,
    full: full,
    metavar: metavar,
    matches: function(arg) {
      return opt.full == arg || opt.abbr == arg || opt.position == arg
        || opt.name == arg || (opt.list && arg >= opt.position);
    }
  });
  return opt;
}

var createParser = function() {
  return new ArgParser();
}

var nomnom = createParser();

for (var i in nomnom) {
  if (typeof nomnom[i] == "function") {
     createParser[i] = _(nomnom[i]).bind(nomnom);
  }
}

module.exports = createParser;
<|endoftext|>


<commit_before>app.directive('connectStudentsaddremove', [
  "settings",
  "User",
  "Course",
  "$routeParams",
  function(
    settings,
    User,
    Course,
    $routeParams
  ) {
      return {
      templateUrl: settings.widgets + 'connect/studentsaddremove.html',
      link: function(scope, element, attrs) {

	   scope.students = [];

	   var AvailableCourses = Course.get();
	   var courseUrl = "";

	   scope.courseSelect = {
		  repeatSelect: null,
		  availableOptions: AvailableCourses
	   };

	  // scope.selectCourseChanged = function (){
		 // courseUrl = $routeParams.url;
		 // updateGUI();
	   //}
	    courseUrl = $routeParams.url;
	   var onLoad = function(){

	   	  scope.course = "";

			Course.get({url: courseUrl}, function(course){
			          scope.course = course[0];
			          updateGUI();
			      });

	   }

		var updateGUI = function(){

			 scope.students= [];
			 scope.studentsToBeAdded= [];

		  	if(courseUrl===""){
			  	console.log("select a course dumb guy");

		  	}else{

			  	User.get({_populate:"courses"},function(user){
				  	for(var i = 0; i < user.length; i++)
				  	{
						//console.log(user);

					  	if(user[i].courses.length > 0)
					  	{
						  	//console.log(user[i]);
						  	//console.log("yolo", courseUrl);

						  	for (var x = 0; x < user[i].courses.length; x++)
						  	{

								if(user[i].courses[x].url === courseUrl)
								{
							  		console.log("Dont add", user[i].email);
							  		scope.studentsToBeAdded.push(user[i]);
							  		break;
						  		}
						  		else
						  		{
							  		console.log("Add", user[i].email);
							  		scope.students.push(user[i]);
							  		break;
						  		}
						  	}
					  	}

					  	else
					  	{
					  		console.log("Add", user[i].email);
					  		scope.students.push(user[i]);
					  	}
				  	}
			  	});

	  	/*
	    User.get({courses: {name: "epiccourse"}, _populate:"courses"},function(users){
		    scope.students = "";
		  	scope.students = users;
		});

		*/

				Course.get({url: courseUrl, _populate:"students"},function(course){
					//console.log(course[0].students);
					scope.studentsToBeAdded = "";

					//var students = User.get({role:Student});
					//console.log(students);
				  	scope.studentsToBeAdded = course[0].students;
				  	console.log(course[0]);
				});
	    	}
	    }
	       //calls updateGUI on page load
           onLoad();

          // scope.studentsToBeAdded = [];

          // Add Item to Checked List and delete from Unchecked List
	    scope.stageMeToCourse = function (index) {

			scope.studentsToBeAdded.push(scope.students[index]);

		    Course.get({url: courseUrl},function(course){

			 	Course.update({_relate:{items:course[0],students:scope.studentsToBeAdded}},function(res){
			 		//console.log(res);
			 		//console.log("updated");

			 		// console.log(scope.studentsToBeAdded);

			 		User.update({_relate:{items:scope.students[index],courses:course[0]}},function(newres){
				 		//console.log(newres);
				 		scope.students.splice(index, 1);
				 	});
			 	});
            });
	    };

	              // Add Item to Checked List and delete from Unchecked List
	    scope.unstageMeToCourse = function (index) {

	    // console.log(index);

	    // scope.students.push(scope.studentsToBeAdded[index]);

		// Remove user from course

    	Course.get({url: courseUrl}, function(course){

	    	Course.update(
        	{url: courseUrl},
        	{ $pull: { 'students': scope.studentsToBeAdded[index]._id}}, function(res){

	        	//console.log(res);

	        	User.update(
					{_id: scope.studentsToBeAdded[index]._id},
					{ $pull: { 'courses': course[0]._id}}, function(rnes){

						scope.students.push(scope.studentsToBeAdded[index]);
						scope.studentsToBeAdded.splice(index, 1);
						//console.log(rnes);
					}
				);

				}
			);

    	});

    	};

	    }

	    }

}
]);

<commit_msg>fixes<commit_after>app.directive('connectStudentsaddremove', [
  "settings",
  "User",
  "Course",
  "$routeParams",
  function(
    settings,
    User,
    Course,
    $routeParams
  ) {
      return {
      templateUrl: settings.widgets + 'connect/studentsaddremove.html',
      link: function(scope, element, attrs) {

	   scope.students = [];

	   var AvailableCourses = Course.get();
	   var courseUrl = "";

	   scope.courseSelect = {
		  repeatSelect: null,
		  availableOptions: AvailableCourses
	   };

	  // scope.selectCourseChanged = function (){
		 // courseUrl = $routeParams.url;
		 // updateGUI();
	   //}
	    courseUrl = $routeParams.url;
	   var onLoad = function(){

	   	  scope.course = "";

			Course.get({url: courseUrl}, function(course){
			          scope.course = course[0];
			          updateGUI();
			      });

	   }

		var updateGUI = function(){

			 scope.students= [];
			 scope.studentsToBeAdded= [];

		  	if(courseUrl===""){
			  	console.log("select a course dumb guy");

		  	}else{

			  	User.get({_populate:"courses"},function(user){
				  	for(var i = 0; i < user.length; i++)
				  	{
						//console.log(user);

					  	if(user[i].courses.length > 0)
					  	{
						  	//console.log(user[i]);
						  	//console.log("yolo", courseUrl);

							//THERE IS A BUG HERE THAT CREATES DUPLICATE USERS IN THE TOBEADDED LIST
						  	for (var x = 0; x < user[i].courses.length; x++)
						  	{

								if(user[i].courses[x].url === courseUrl)
								{
							  		console.log("Dont add", user[i].email);
							  		scope.studentsToBeAdded.push(user[i]);
							  		break;
						  		}
						  		else
						  		{
							  		console.log("Add", user[i].email);
							  		scope.students.push(user[i]);
							  		break;
						  		}
						  	}
					  	}

					  	else
					  	{
					  		console.log("Add", user[i].email);
					  		scope.students.push(user[i]);
					  	}
				  	}
			  	});

	  	/*
	    User.get({courses: {name: "epiccourse"}, _populate:"courses"},function(users){
		    scope.students = "";
		  	scope.students = users;
		});

		*/

				Course.get({url: courseUrl, _populate:"students"},function(course){
					//console.log(course[0].students);
					scope.studentsToBeAdded = "";

					//var students = User.get({role:Student});
					//console.log(students);
				  	scope.studentsToBeAdded = course[0].students;
				  	console.log(course[0]);
				});
	    	}
	    }
	       //calls updateGUI on page load
           onLoad();

          // scope.studentsToBeAdded = [];

          // Add Item to Checked List and delete from Unchecked List
	    scope.stageMeToCourse = function (index) {

			scope.studentsToBeAdded.push(scope.students[index]);

		    Course.get({url: courseUrl},function(course){

			 	Course.update({_relate:{items:course[0],students:scope.studentsToBeAdded}},function(res){
			 		//console.log(res);
			 		//console.log("updated");

			 		// console.log(scope.studentsToBeAdded);

			 		User.update({_relate:{items:scope.students[index],courses:course[0]}},function(newres){
				 		//console.log(newres);
				 		scope.students.splice(index, 1);
				 	});
			 	});
            });
	    };

	              // Add Item to Checked List and delete from Unchecked List
	    scope.unstageMeToCourse = function (index) {

	    // console.log(index);

	    // scope.students.push(scope.studentsToBeAdded[index]);

		// Remove user from course

    	Course.get({url: courseUrl}, function(course){

	    	Course.update(
        	{url: courseUrl},
        	{ $pull: { 'students': scope.studentsToBeAdded[index]._id}}, function(res){

	        	//console.log(res);

	        	User.update(
					{_id: scope.studentsToBeAdded[index]._id},
					{ $pull: { 'courses': course[0]._id}}, function(rnes){

						scope.students.push(scope.studentsToBeAdded[index]);
						scope.studentsToBeAdded.splice(index, 1);
						//console.log(rnes);
					}
				);

				}
			);

    	});

    	};

	    }

	    }

}
]);

<|endoftext|>


<commit_before><commit_msg>#5404: changes for page/product redirection.<commit_after><|endoftext|>


<commit_before>(function (root, factory) {

    'use strict';

    if (typeof define === 'function' && define.amd) {
        // AMD environment
        define('notify', [], function () {
            return factory(root, document);
        });
    } else if (typeof exports === 'object') {
        // CommonJS environment
        module.exports = factory(root, document);
    } else {
        // Browser environment
        root.Notify = factory(root, document);
    }

}(window, function (w, d) {

    'use strict';

    function isFunction (item) {
        return typeof item === 'function';
    }

    function Notify(title, options) {

        if (typeof title !== 'string') {
            throw new Error('Notify(): first arg (title) must be a string.');
        }

        this.title = title;

        this.options = {
            icon: '',
            body: '',
            tag: '',
            notifyShow: null,
            notifyClose: null,
            notifyClick: null,
            notifyError: null,
            permissionGranted: null,
            permissionDenied: null,
            timeout: null
        };

        this.permission = null;

        if (!Notify.isSupported) {
            return;
        }

        //User defined options for notification content
        if (typeof options === 'object') {

            for (var i in options) {
                if (options.hasOwnProperty(i)) {
                    this.options[i] = options[i];
                }
            }

            //callback when notification is displayed
            if (isFunction(this.options.notifyShow)) {
                this.onShowCallback = this.options.notifyShow;
            }

            //callback when notification is closed
            if (isFunction(this.options.notifyClose)) {
                this.onCloseCallback = this.options.notifyClose;
            }

            //callback when notification is clicked
            if (isFunction(this.options.notifyClick)) {
                this.onClickCallback = this.options.notifyClick;
            }

            //callback when notification throws error
            if (isFunction(this.options.notifyError)) {
                this.onErrorCallback = this.options.notifyError;
            }
        }
    }

    // true if the browser supports HTML5 Notification
    Notify.isSupported = 'Notification' in w;

    // returns true if the permission is not granted
    Notify.needsPermission = function () {
        return !(Notify.isSupported && Notification.permission === 'granted');
    };

    // asks the user for permission to display notifications.  Then calls the callback functions is supplied.
    Notify.requestPermission = function (onPermissionGrantedCallback, onPermissionDeniedCallback) {
        if (Notify.isSupported) {
            w.Notification.requestPermission(function (perm) {
                switch (perm) {
                    case 'granted':
                        if (isFunction(onPermissionGrantedCallback)) {
                            onPermissionGrantedCallback();
                        }
                        break;
                    case 'denied':
                        if (isFunction(onPermissionDeniedCallback)) {
                            onPermissionDeniedCallback();
                        }
                        break;
                }
            });
        }
    };

    Notify.prototype.show = function () {
        var that = this;

        if (!Notify.isSupported) {
            return;
        }

        this.myNotify = new Notification(this.title, {
            'body': this.options.body,
            'tag' : this.options.tag,
            'icon' : this.options.icon
        });

        if (this.options.timeout && !isNaN(this.options.timeout)) {
            setTimeout(this.close.bind(this), this.options.timeout * 1000);
        }

        this.myNotify.addEventListener('show', this, false);
        this.myNotify.addEventListener('error', this, false);
        this.myNotify.addEventListener('close', this, false);
        this.myNotify.addEventListener('click', this, false);
    };

    Notify.prototype.onShowNotification = function (e) {
        if (this.onShowCallback) {
            this.onShowCallback(e);
        }
    };

    Notify.prototype.onCloseNotification = function (e) {
        if (this.onCloseCallback) {
            this.onCloseCallback(e);
        }
        this.destroy();
    };

    Notify.prototype.onClickNotification = function (e) {
        if (this.onClickCallback) {
            this.onClickCallback(e);
        }
    };

    Notify.prototype.onErrorNotification = function (e) {
        if (this.onErrorCallback) {
            this.onErrorCallback(e);
        }
        this.destroy();
    };

    Notify.prototype.destroy = function () {
        this.myNotify.removeEventListener('show', this, false);
        this.myNotify.removeEventListener('error', this, false);
        this.myNotify.removeEventListener('close', this, false);
        this.myNotify.removeEventListener('click', this, false);
    };

    Notify.prototype.close = function () {
        this.myNotify.close();
    };

    Notify.prototype.handleEvent = function (e) {
        switch (e.type) {
        case 'show':
            this.onShowNotification(e);
            break;
        case 'close':
            this.onCloseNotification(e);
            break;
        case 'click':
            this.onClickNotification(e);
            break;
        case 'error':
            this.onErrorNotification(e);
            break;
        }
    };

    return Notify;

}));
<commit_msg>refactor(notify): use return when false to be consistent with other APIs<commit_after>(function (root, factory) {

    'use strict';

    if (typeof define === 'function' && define.amd) {
        // AMD environment
        define('notify', [], function () {
            return factory(root, document);
        });
    } else if (typeof exports === 'object') {
        // CommonJS environment
        module.exports = factory(root, document);
    } else {
        // Browser environment
        root.Notify = factory(root, document);
    }

}(window, function (w, d) {

    'use strict';

    function isFunction (item) {
        return typeof item === 'function';
    }

    function Notify(title, options) {

        if (typeof title !== 'string') {
            throw new Error('Notify(): first arg (title) must be a string.');
        }

        this.title = title;

        this.options = {
            icon: '',
            body: '',
            tag: '',
            notifyShow: null,
            notifyClose: null,
            notifyClick: null,
            notifyError: null,
            permissionGranted: null,
            permissionDenied: null,
            timeout: null
        };

        this.permission = null;

        if (!Notify.isSupported) {
            return;
        }

        //User defined options for notification content
        if (typeof options === 'object') {

            for (var i in options) {
                if (options.hasOwnProperty(i)) {
                    this.options[i] = options[i];
                }
            }

            //callback when notification is displayed
            if (isFunction(this.options.notifyShow)) {
                this.onShowCallback = this.options.notifyShow;
            }

            //callback when notification is closed
            if (isFunction(this.options.notifyClose)) {
                this.onCloseCallback = this.options.notifyClose;
            }

            //callback when notification is clicked
            if (isFunction(this.options.notifyClick)) {
                this.onClickCallback = this.options.notifyClick;
            }

            //callback when notification throws error
            if (isFunction(this.options.notifyError)) {
                this.onErrorCallback = this.options.notifyError;
            }
        }
    }

    // true if the browser supports HTML5 Notification
    Notify.isSupported = 'Notification' in w;

    // returns true if the permission is not granted
    Notify.needsPermission = function () {
        return !(Notify.isSupported && Notification.permission === 'granted');
    };

    // asks the user for permission to display notifications.  Then calls the callback functions is supplied.
    Notify.requestPermission = function (onPermissionGrantedCallback, onPermissionDeniedCallback) {

        if (!Notify.isSupported) {
            return;
        }

        w.Notification.requestPermission(function (perm) {
            if (isFunction(onPermissionGrantedCallback)) {
                onPermissionGrantedCallback();
            }
            switch (perm) {
                case 'granted':
                    break;
                case 'denied':
                    if (isFunction(onPermissionDeniedCallback)) {
                        onPermissionDeniedCallback();
                    }
                    break;
            }
        });
    };

    Notify.prototype.show = function () {
        var that = this;

        if (!Notify.isSupported) {
            return;
        }

        this.myNotify = new Notification(this.title, {
            'body': this.options.body,
            'tag' : this.options.tag,
            'icon' : this.options.icon
        });

        if (this.options.timeout && !isNaN(this.options.timeout)) {
            setTimeout(this.close.bind(this), this.options.timeout * 1000);
        }

        this.myNotify.addEventListener('show', this, false);
        this.myNotify.addEventListener('error', this, false);
        this.myNotify.addEventListener('close', this, false);
        this.myNotify.addEventListener('click', this, false);
    };

    Notify.prototype.onShowNotification = function (e) {
        if (this.onShowCallback) {
            this.onShowCallback(e);
        }
    };

    Notify.prototype.onCloseNotification = function (e) {
        if (this.onCloseCallback) {
            this.onCloseCallback(e);
        }
        this.destroy();
    };

    Notify.prototype.onClickNotification = function (e) {
        if (this.onClickCallback) {
            this.onClickCallback(e);
        }
    };

    Notify.prototype.onErrorNotification = function (e) {
        if (this.onErrorCallback) {
            this.onErrorCallback(e);
        }
        this.destroy();
    };

    Notify.prototype.destroy = function () {
        this.myNotify.removeEventListener('show', this, false);
        this.myNotify.removeEventListener('error', this, false);
        this.myNotify.removeEventListener('close', this, false);
        this.myNotify.removeEventListener('click', this, false);
    };

    Notify.prototype.close = function () {
        this.myNotify.close();
    };

    Notify.prototype.handleEvent = function (e) {
        switch (e.type) {
        case 'show':
            this.onShowNotification(e);
            break;
        case 'close':
            this.onCloseNotification(e);
            break;
        case 'click':
            this.onClickNotification(e);
            break;
        case 'error':
            this.onErrorNotification(e);
            break;
        }
    };

    return Notify;

}));
<|endoftext|>


<commit_before>'use strict';
require('webrtc-adapter');

var NextRTC = function NextRTC(config) {
    if (!(this instanceof NextRTC)) {
        return new NextRTC(config);
    }
    var that = this;
    this.mediaConfig = config.mediaConfig !== undefined ? config.mediaConfig : null;
    this.type = config.type;

    this.signaling = new WebSocket(config.wsURL);
    this.peerConnections = {};
    this.localStream = null;
    this.signals = {};
    this.channelReady = false;
    this.waiting = [];

    this.call = function(event, data) {
        for ( var signal in this.signals) {
            if (event === signal) {
                return this.signals[event](this, data);
            }
        }
        console.log('Event ' + event + ' do not have defined function');
    };

    this.request = function(signal, to, convId, custom) {
        var req = JSON.stringify({
            signal: signal,
            to: to,
            content: convId,
            custom: custom });
        if(!this.channelReady){
            if(req.signal !== ''){
                this.waiting.push(req);
            }
        } else {
            console.log("req: " + req);
            this.signaling.send(req);
        }
    };

    this.signaling.onmessage = function(event) {
        console.log("res: " + event.data);
        var signal = JSON.parse(event.data);
        that.call(signal.signal, signal);
    };

    this.signaling.onopen = function() {
        console.log("channel ready");
        that.setChannelReady();
    };

    this.signaling.onclose = function(event) {
        that.call('close', event);
    };

    this.signaling.onerror = function(event) {
        that.call('error', event);
    };

    this.setChannelReady = function(){
        for(var w in that.waiting){
            console.log("req: " + w);
            that.signaling.send(w);
        }
        that.channelReady = true;
    }

    this.preparePeerConnection = function(nextRTC, member) {
        if (nextRTC.peerConnections[member] == undefined) {
            var pc = new RTCPeerConnection(config.peerConfig);
            pc.onaddstream = function(evt) {
                nextRTC.call('remoteStream', {
                    member : member,
                    stream : evt.stream
                });
            };
            pc.onicecandidate = function(evt) {
                handle(pc, evt);

                function handle(pc, evt){
                    if((pc.signalingState || pc.readyState) == 'stable'
                        && nextRTC.peerConnections[member]['rem'] == true){
                        nextRTC.onIceCandidate(nextRTC, member, evt);
                        return;
                    }
                    setTimeout(function(){ handle(pc, evt); }, 2000);
                }
            };
            nextRTC.peerConnections[member] = {}
            nextRTC.peerConnections[member]['pc'] = pc;
            nextRTC.peerConnections[member]['rem'] = false;
        }
        return nextRTC.peerConnections[member];
    };

    this.offerRequest = function(nextRTC, from) {
        nextRTC.offerResponse(nextRTC, from);
    };

    this.offerResponse = function(nextRTC, signal) {
        var pc = nextRTC.preparePeerConnection(nextRTC, signal.from);
        pc['pc'].addStream(nextRTC.localStream);
        pc['pc'].createOffer({offerToReceiveAudio: 1, offerToReceiveVideo: 1})
            .then(function(desc) {
                pc['pc'].setLocalDescription(desc)
                    .then(function() {
                        nextRTC.request('offerResponse', signal.from, desc.sdp);
                    }, that.error);
            });
    };

    this.answerRequest = function(nextRTC, signal) {
        nextRTC.answerResponse(nextRTC, signal);
    };

    this.answerResponse = function(nextRTC, signal) {
        var pc = nextRTC.preparePeerConnection(nextRTC, signal.from);
        pc['pc'].addStream(nextRTC.localStream);
        pc['pc'].setRemoteDescription(new RTCSessionDescription({
            type : 'offer',
            sdp : signal.content
        })).then(function() {
            pc['rem'] = true;
            pc['pc'].createAnswer().then(function(desc) {
                pc['pc'].setLocalDescription(desc).then(function() {
                    nextRTC.request('answerResponse', signal.from, desc.sdp);
                });
              });
          });
    };

    this.finalize = function(nextRTC, signal) {
        var pc = nextRTC.preparePeerConnection(nextRTC, signal.from);
        pc['pc'].setRemoteDescription(new RTCSessionDescription({
            type : 'answer',
            sdp : signal.content
        })).then(function(){
            pc['rem'] = true;
        });
    };

    this.close = function(nextRTC, event) {
        nextRTC.signaling.close();
        if(nextRTC.localStream != null){
            nextRTC.localStream.stop();
        }
    };

    this.candidate = function(nextRTC, signal) {
        var pc = nextRTC.preparePeerConnection(nextRTC, signal.from);
        pc['pc'].addIceCandidate(new RTCIceCandidate(JSON.parse(signal.content.replace(new RegExp('\'', 'g'), '"'))), that.success, that.error);
    }

    this.init = function() {
        this.on('offerRequest', this.offerRequest);
        this.on('answerRequest', this.answerRequest);
        this.on('finalize', this.finalize);
        this.on('candidate', this.candidate);
        this.on('close', this.close);
        this.on('error', this.error);
        this.on('ping', function(){});
    };

    this.onIceCandidate = function(nextRTC, member, event) {
        if (event.candidate) {
            nextRTC.request('candidate', member, JSON.stringify(event.candidate));
        }
    }

    this.init();

    this.error = function(arg){
        console.log('error: ' + arg);
    }

    this.success = function(arg){
        console.log('success: ' + arg);
    }

    that.onReady = function() {
        console.log('It is highly recommended to override method NextRTC.onReady');
    };

    if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', function() {
            that.onReady();
        });
    }
};

NextRTC.prototype.on = function on(signal, operation) {
    this.signals[signal] = operation;
};

NextRTC.prototype.create = function create(convId, custom) {
    var nextRTC = this;
    navigator.mediaDevices.getUserMedia(nextRTC.mediaConfig).then(function(stream) {
    nextRTC.localStream = stream;
    nextRTC.call('localStream', {
        stream : stream
    });
    nextRTC.request('create', null, convId, custom);
    }, this.error);
};

NextRTC.prototype.join = function join(convId, custom) {
    var nextRTC = this;
    navigator.mediaDevices.getUserMedia(nextRTC.mediaConfig).then(function(stream) {
        nextRTC.localStream = stream;
        nextRTC.call('localStream', {
            stream : stream
        });
        nextRTC.request('join', null, convId, custom);
    }, this.error);
};

NextRTC.prototype.leave = function leave() {
    var nextRTC = this;
    nextRTC.request('left');
    nextRTC.signaling.close();
    if(nextRTC.localStream != null){
        nextRTC.localStream.stop();
    }
};

module.exports.NextRTC = NextRTC;<commit_msg>small fix<commit_after>'use strict';
require('webrtc-adapter');

var NextRTC = function NextRTC(config) {
    if (!(this instanceof NextRTC)) {
        return new NextRTC(config);
    }
    var that = this;
    this.mediaConfig = config.mediaConfig !== undefined ? config.mediaConfig : null;
    this.type = config.type;

    this.signaling = new WebSocket(config.wsURL);
    this.peerConnections = {};
    this.localStream = null;
    this.signals = {};
    this.channelReady = false;
    this.waiting = [];

    this.call = function(event, data) {
        for ( var signal in this.signals) {
            if (event === signal) {
                return this.signals[event](this, data);
            }
        }
        console.log('Event ' + event + ' do not have defined function');
    };

    this.request = function(signal, to, convId, custom) {
        var req = JSON.stringify({
            signal: signal,
            to: to,
            content: convId,
            custom: custom });
        if(!this.channelReady){
            if(req.signal !== undefined && req.signal !== ''){
                this.waiting.push(req);
            }
        } else {
            console.log("req: " + req);
            this.signaling.send(req);
        }
    };

    this.signaling.onmessage = function(event) {
        console.log("res: " + event.data);
        var signal = JSON.parse(event.data);
        that.call(signal.signal, signal);
    };

    this.signaling.onopen = function() {
        console.log("channel ready");
        that.setChannelReady();
    };

    this.signaling.onclose = function(event) {
        that.call('close', event);
    };

    this.signaling.onerror = function(event) {
        that.call('error', event);
    };

    this.setChannelReady = function(){
        for(var w in that.waiting){
            console.log("req: " + w);
            that.signaling.send(w);
        }
        that.channelReady = true;
    }

    this.preparePeerConnection = function(nextRTC, member) {
        if (nextRTC.peerConnections[member] == undefined) {
            var pc = new RTCPeerConnection(config.peerConfig);
            pc.onaddstream = function(evt) {
                nextRTC.call('remoteStream', {
                    member : member,
                    stream : evt.stream
                });
            };
            pc.onicecandidate = function(evt) {
                handle(pc, evt);

                function handle(pc, evt){
                    if((pc.signalingState || pc.readyState) == 'stable'
                        && nextRTC.peerConnections[member]['rem'] == true){
                        nextRTC.onIceCandidate(nextRTC, member, evt);
                        return;
                    }
                    setTimeout(function(){ handle(pc, evt); }, 2000);
                }
            };
            nextRTC.peerConnections[member] = {}
            nextRTC.peerConnections[member]['pc'] = pc;
            nextRTC.peerConnections[member]['rem'] = false;
        }
        return nextRTC.peerConnections[member];
    };

    this.offerRequest = function(nextRTC, from) {
        nextRTC.offerResponse(nextRTC, from);
    };

    this.offerResponse = function(nextRTC, signal) {
        var pc = nextRTC.preparePeerConnection(nextRTC, signal.from);
        pc['pc'].addStream(nextRTC.localStream);
        pc['pc'].createOffer({offerToReceiveAudio: 1, offerToReceiveVideo: 1})
            .then(function(desc) {
                pc['pc'].setLocalDescription(desc)
                    .then(function() {
                        nextRTC.request('offerResponse', signal.from, desc.sdp);
                    }, that.error);
            });
    };

    this.answerRequest = function(nextRTC, signal) {
        nextRTC.answerResponse(nextRTC, signal);
    };

    this.answerResponse = function(nextRTC, signal) {
        var pc = nextRTC.preparePeerConnection(nextRTC, signal.from);
        pc['pc'].addStream(nextRTC.localStream);
        pc['pc'].setRemoteDescription(new RTCSessionDescription({
            type : 'offer',
            sdp : signal.content
        })).then(function() {
            pc['rem'] = true;
            pc['pc'].createAnswer().then(function(desc) {
                pc['pc'].setLocalDescription(desc).then(function() {
                    nextRTC.request('answerResponse', signal.from, desc.sdp);
                });
              });
          });
    };

    this.finalize = function(nextRTC, signal) {
        var pc = nextRTC.preparePeerConnection(nextRTC, signal.from);
        pc['pc'].setRemoteDescription(new RTCSessionDescription({
            type : 'answer',
            sdp : signal.content
        })).then(function(){
            pc['rem'] = true;
        });
    };

    this.close = function(nextRTC, event) {
        nextRTC.signaling.close();
        if(nextRTC.localStream != null){
            nextRTC.localStream.stop();
        }
    };

    this.candidate = function(nextRTC, signal) {
        var pc = nextRTC.preparePeerConnection(nextRTC, signal.from);
        pc['pc'].addIceCandidate(new RTCIceCandidate(JSON.parse(signal.content.replace(new RegExp('\'', 'g'), '"'))), that.success, that.error);
    }

    this.init = function() {
        this.on('offerRequest', this.offerRequest);
        this.on('answerRequest', this.answerRequest);
        this.on('finalize', this.finalize);
        this.on('candidate', this.candidate);
        this.on('close', this.close);
        this.on('error', this.error);
        this.on('ping', function(){});
    };

    this.onIceCandidate = function(nextRTC, member, event) {
        if (event.candidate) {
            nextRTC.request('candidate', member, JSON.stringify(event.candidate));
        }
    }

    this.init();

    this.error = function(arg){
        console.log('error: ' + arg);
    }

    this.success = function(arg){
        console.log('success: ' + arg);
    }

    that.onReady = function() {
        console.log('It is highly recommended to override method NextRTC.onReady');
    };

    if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', function() {
            that.onReady();
        });
    }
};

NextRTC.prototype.on = function on(signal, operation) {
    this.signals[signal] = operation;
};

NextRTC.prototype.create = function create(convId, custom) {
    var nextRTC = this;
    navigator.mediaDevices.getUserMedia(nextRTC.mediaConfig).then(function(stream) {
    nextRTC.localStream = stream;
    nextRTC.call('localStream', {
        stream : stream
    });
    nextRTC.request('create', null, convId, custom);
    }, this.error);
};

NextRTC.prototype.join = function join(convId, custom) {
    var nextRTC = this;
    navigator.mediaDevices.getUserMedia(nextRTC.mediaConfig).then(function(stream) {
        nextRTC.localStream = stream;
        nextRTC.call('localStream', {
            stream : stream
        });
        nextRTC.request('join', null, convId, custom);
    }, this.error);
};

NextRTC.prototype.leave = function leave() {
    var nextRTC = this;
    nextRTC.request('left');
    nextRTC.signaling.close();
    if(nextRTC.localStream != null){
        nextRTC.localStream.stop();
    }
};

module.exports.NextRTC = NextRTC;<|endoftext|>


<commit_before>/*jshint undef:true*/
/*global angular*/
angular.module('ngQueue', [])

.factory('$queueFactory', [
         '$q', '$window', '$timeout', '$rootScope',
function ($q,   $window,   $timeout,   $rootScope) {

  var Queue = function Queue(config) {
    this.init(config);
  };

  var p = Queue.prototype;

  // number of simultaneously runnable tasks
  p._limit = null;

  // the queue
  p._queue = [];

  // function used for deferring
  p._deferFunc = null;

  p.init = function (config) {
    p._limit = config.limit;
    p._queue = [];

    if (config.deferred) {
      if ($window.setImmediate) {
        this._deferFunc = function (todo) {
          $window.setImmediate(function () {
            todo();
            $rootScope.$apply();
          });
        };
      }
      else {
        this._deferFunc = function (todo) {
          // $timeout(todo, 0, true);
          $timeout(todo);
        };
      }
    }
  };

  p.enqueue = function (todo, context, args) {
    var task = [todo, context, args];

    p._queue.push([todo, context, args]);

    p.dequeue();
    return task;
  };

  p.remove = function (task) {
    var index = p._queue.indexOf(task),
    item = p._queue.splice(index, 1)[0];
    return item;
  };

  p.dequeue = function () {
    if (p._limit <= 0 || p._queue.length === 0) {
      return;
    }

    p._limit--;

    var buf = p._queue.shift(),
        todo = buf[0],
        context = buf[1],
        args = buf[2],
        success, error;

    success = error = function () {
      p._limit++;

      if (p._deferFunc) {
        p._deferFunc(function () {
          p.dequeue();
        });
      }
      else {
        p.dequeue();
      }
    };

    $q.when(todo.apply(context || null, args || null))
    .then(success, error);
  };

  p.clear = function () {
    p._queue = [];
  };

  return function factory(limit, deferred) {
    var config;

    if (angular.isObject(limit)) {
      config = limit;
    }
    else {
      limit = limit || 1;

      if (angular.isUndefined(deferred)) {
        deferred = false;
      }
      config = {
        limit: limit,
        deferred: !!deferred
      };
    }

    return new Queue(config);
  };
}]);
<commit_msg>Added queue statistics: total queued items, items not yet resolved and boolean queueIdle<commit_after>/*jshint undef:true*/
/*global angular*/
angular.module('ngQueue', [])

.factory('$queueFactory', [
         '$q', '$window', '$timeout', '$rootScope', '$filter',
function ($q,   $window,   $timeout,   $rootScope, $filter) {

  var Queue = function Queue(config) {
    this.init(config);
  };

  var p = Queue.prototype,
  updateStats = function () {
    p.queueTotal = p._queue.length + p._list.length;
    p.queuePending = $filter('filter')(p._list, {resolved:false}).length + p._queue.length;
    p.queueIdle = p.queuePending < 1;
  };

  // number of simultaneously runnable tasks
  p._limit = null;

  // the queue
  p._queue = [];

  // function used for deferring
  p._deferFunc = null;

  p._list = [];

  p.queueTotal = 0;
  p.queuePending = 0;
  p.queueIdle = true;

  p.init = function (config) {
    p._limit = config.limit;
    p._queue = [];

    if (config.deferred) {
      if ($window.setImmediate) {
        this._deferFunc = function (todo) {
          $window.setImmediate(function () {
            todo();
            $rootScope.$apply();
          });
        };
      }
      else {
        this._deferFunc = function (todo) {
          // $timeout(todo, 0, true);
          $timeout(todo);
        };
      }
    }
  };

  p.enqueue = function (todo, context, args) {
    var task = [todo, context, args];

    p._queue.push([todo, context, args]);

    updateStats();

    p.dequeue();
    return task;
  };

  p.remove = function (task) {
    var index = p._queue.indexOf(task),
    item = p._queue.splice(index, 1)[0];
    updateStats();
    return item;
  };

  p.dequeue = function () {
    if (p._limit <= 0 || p._queue.length === 0) {
      return;
    }

    p._limit--;

    var buf = p._queue.shift(),
        timestamp = new Date().getTime(),
        todo = buf[0],
        context = buf[1],
        args = buf[2],
        success, error;

    p._list.push({id:timestamp,resolved:false});

    success = error = function () {
      p._limit++;

      if (p._deferFunc) {
        p._deferFunc(function () {
          p.dequeue();
        });
      }
      else {
        p.dequeue();
      }
    },
    always = function () {

      var item = $filter('filter')(p._list, {id:timestamp})[0];
      item.resolved = true;

      updateStats();

    };

    $q.when(todo.apply(context || null, args || null))
    .then(success, error).finally(always);
  };

  p.clear = function () {
    p._queue = [];
    p._list = [];
    updateStats();
  };

  return function factory(limit, deferred) {
    var config;

    if (angular.isObject(limit)) {
      config = limit;
    }
    else {
      limit = limit || 1;

      if (angular.isUndefined(deferred)) {
        deferred = false;
      }
      config = {
        limit: limit,
        deferred: !!deferred
      };
    }

    return new Queue(config);
  };
}]);
<|endoftext|>


<commit_before>#!/usr/bin/env node

/*
 * Copyright 2015 Donn Felker, Zeb Deos, Donnie West
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var wrench = require('wrench'),
    util = require('util'),
    spawn = require('child_process').spawn,
    fs = require('fs'),
    async = require('async'),
    program = require('commander');

/*
 * Project generator route.
 * This entire route is super brute force and rather naive. However, it works and is easy to follow.
 * TODO: Possible improvements include doing more async calls with the fs module since this uses the async.js
 * lib it shouldn't be too bad to impelement.
*/

program
    .version('0.0.1')
    .option('-p --package-name [value]', 'Package name of Project')
    .option('-n --application-name [value]', 'Name of package')
    .option('-i --input-directory <path>', 'Input Directory')
    .option('-o --output-directory <path>', 'Output Directory')
    .parse(process.argv);

convert = function() {

    // 1. Create a temporary file(s) location.
    // 2. Rename the directories accordingly.
    // 3. Loop over all the files and perform replacements.
    // 4. Zip up the content & Send to the output stream
    // 5. Delete the temporary file(s).
    // 6. All Done - Do some 12 ounce curls.

    console.log(process.env.PWD);

    var appName = program.applicationName;
    var packageName = program.packageName;

    console.log("App Name:" + appName);
    console.log("Package Name:" + packageName);

    // Android Bootstrap source directory
    var sourceDir = program.inputDirectory;

    // Temporary locationwhere the users project will be generated.
    var destDir = process.env.PWD + '/tmp/' + packageName;

    //Final Location where project is generated
    var finalDir = program.outputDirectory

    console.log("sourceDir: " + sourceDir);
    console.log("destDir: " + destDir);
    console.log("sourceDir: " + finalDir);

    // Copy the files to temp directory.
    wrench.copyDirSyncRecursive(sourceDir, destDir);

    var theFiles = wrench.readdirSyncRecursive(destDir);
    console.log(theFiles);

    var callItems = [];

    theFiles.forEach(function(currentFile) {
      var genFileFunc = generateFileFunc(destDir + "/" + currentFile, packageName, appName);
      callItems.push(genFileFunc);

    });

    async.parallel(callItems, function(err, results) {

      if(err) {
        console.error("**** ERROR ****");
      } else {

        // Now, all items have been executed, perform the copying/etc.
        createSourceDirectories(destDir, packageName);
        copySourceDirectories(destDir, packageName);
        removeBootstrapDirectories(destDir);
        wrench.copyDirSyncRecursive(destDir, finalDir);
      }
    });
}

function getFileObjectsFrom(destDir, files) {
  var fileObjs = []
  for(var i=0; i<files.length;i++) {
    var filePath = destDir + "/" + files[i];
    var stats = fs.lstatSync(filePath);
    if(!stats.isDirectory())
      fileObjs.push({ name: files[i], path: filePath });
  }
  return fileObjs;
}

function generateFileFunc(file, packageName, appName) {
  return function(callback) {
    generateFile(file, packageName, appName, callback);
  }
}

function removeBootstrapDirectories(destDir) {

  // TODO: remove the old bootstrap source, unit-test and integration-test folders that are not valid anymore.
  console.log("Removing temporary work directories.");

  // Clean up - delete all the files we were just working with.
  var bootstrapSourceDir = destDir + "/app/src/main/java/com/donnfelker";
  var bootstrapUnitTestDir = destDir + "/app/src/test/java/com/donnfelker";
  var integrationTestDir = destDir +  "/integration-tests/src/main/java/com/donnfelker";

  console.log("Removing: " + bootstrapSourceDir);
  console.log("Removing: " + bootstrapUnitTestDir);
  console.log("Removing: " + integrationTestDir);

  wrench.rmdirSyncRecursive(bootstrapSourceDir, false);
  wrench.rmdirSyncRecursive(bootstrapUnitTestDir, false);
  wrench.rmdirSyncRecursive(integrationTestDir, false);

}

// Creates the various new folder structures needed for the users new project.
function createSourceDirectories(destDir, packageName) {

  var newPathChunk = getNewFilePath(packageName);

  var newSourceDirectory = destDir + "/app/src/main/java/" + newPathChunk;
  console.log("Creating new source directory at: " + newSourceDirectory);
  wrench.mkdirSyncRecursive(newSourceDirectory);

  var newUnitTestDirectory = destDir + "/app/src/test/java/" + newPathChunk;
  console.log("Creating new source directory at: " + newUnitTestDirectory);
  wrench.mkdirSyncRecursive(newUnitTestDirectory);

  var newIntegrationTestDirectory = destDir + "/integration-tests/src/main/java/" + newPathChunk;
  console.log("Creating new integration tests directory at: " + newIntegrationTestDirectory);
  wrench.mkdirSyncRecursive(newIntegrationTestDirectory);
}

function copySourceDirectories(destDir, packageName) {

  console.log(destDir);
  console.log(packageName);

  var newPathChunk = getNewFilePath(packageName);

  var oldSourceDir = destDir  +  "/app/src/main/java/com/donnfelker/android/bootstrap";
  var newSourceDir = destDir    +  "/app/src/main/java/" + newPathChunk;
  console.log("Copying source from" + oldSourceDir + " to directory " + newSourceDir);
  wrench.copyDirSyncRecursive(oldSourceDir, newSourceDir);

  var oldUnitTestDir = destDir + "/app/src/test/java/com/donnfelker/android/bootstrap";
  var newUnitTestDir = destDir + "/app/src/test/java/" + newPathChunk;
  console.log("Copying source from" + oldUnitTestDir + " to directory " + newUnitTestDir);
  wrench.copyDirSyncRecursive(oldUnitTestDir, newUnitTestDir);

  var oldIntegrationTestDir = destDir + "/integration-tests/src/main/java/com/donnfelker/android/bootstrap";
  var newIntegrationTestDir = destDir + "/integration-tests/src/main/java/" + newPathChunk;
  console.log("Copying source from" + oldIntegrationTestDir + " to directory " + newIntegrationTestDir);
  wrench.copyDirSyncRecursive(oldIntegrationTestDir, newIntegrationTestDir);
}

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};

function generateFile(file, packageName, appName, callback) {

  var stats = fs.lstatSync(file);
  if(!stats.isDirectory() && !file.endsWith(".png")) {
    // Only work with text files, no directories or png files.
    // Above == terrible code, but for android-bootstrap, it works. Pragmatic & KISS. FTW.

    // Must include the encoding otherwise the raw buffer will
    // be returned as the data.
    var data = fs.readFileSync(file, 'utf-8');

    //console.log("Current File: " + file);

    console.log("File: " + file);
    // Sure, we could chain these, but this is easier to read.
    data = replacePackageName(data, packageName);
    data = replaceAuthToken(data, packageName);
    data = replaceAppName(data, appName);
    data = replaceHyphenatedNames(data, packageName);
    data = replaceProguardValues(data, packageName);

    // Finally all done doing replacing, save this bad mother.
    fs.writeFileSync(file, data);
  }

   // Call back to async lib.
    callback(null, file);
}

// Turns a package name into a file path string.
// Example: com.foo.bar.bang turns into com\foo\bar\bang
function getNewFilePath(newPackageName) {
  return newPackageName.split('.').join('/');
}

function getOldFilePath() {
  return "com.donnfelker.android.bootstrap".split('.').join('/');
}

// Takes the old boostrap file name and returns the new file name
// that is created via the transform from the new package name.
function getBootstrappedFileName(bootstrapFileName, newPackageName) {
  return bootstrapFileName.replace( getOldFilePath(), getNewFilePath(newPackageName) );
}

function replacePackageName(fileContents, newPackageName) {
  var BOOTSTRAP_PACKAGE_NAME = "com.donnfelker.android.bootstrap"; // replace all needs a regex with the /g (global) modifier
  var packageNameRegExp = new RegExp(BOOTSTRAP_PACKAGE_NAME, 'g');

  // Replace package name
  return fileContents.replace(packageNameRegExp, newPackageName);
}

function replaceAuthToken(fileContents, newPackageName) {
  var BOOTSTRAP_TOKEN = "com.androidbootstrap";
  var tokenRegExp = new RegExp(BOOTSTRAP_TOKEN, 'g'); // global search

  return fileContents.replace( tokenRegExp, newPackageName );
}

function replaceAppName(fileContents, newAppName) {
  var APP_NAME = "Android Bootstrap";
  var nameRegExp = new RegExp(APP_NAME, 'g'); // global search

  return fileContents.replace(nameRegExp, newAppName);
}

function replaceHyphenatedNames(fileContents, newPackageName) {
  var newHyphenatedName = newPackageName.toLowerCase().split('.').join('-');
  var hyphenatedRegExp = new RegExp("android-bootstrap", 'g'); // global search

  return fileContents.replace(hyphenatedRegExp, newHyphenatedName);
}

function replaceProguardValues(fileContents, newPackageName) {
  var newValue = newPackageName + '.';
  var valueToFind = new RegExp("com.donnfelker.android.", 'g');

  return fileContents.replace(valueToFind, newValue);
}

convert();
<commit_msg>Update copyright<commit_after>#!/usr/bin/env node

/*
 * Copyright 2012 Donn Felker
 * Copyright 2015 Zeb DeOs, Donnie West
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var wrench = require('wrench'),
    util = require('util'),
    spawn = require('child_process').spawn,
    fs = require('fs'),
    async = require('async'),
    program = require('commander');

/*
 * Project generator route.
 * This entire route is super brute force and rather naive. However, it works and is easy to follow.
 * TODO: Possible improvements include doing more async calls with the fs module since this uses the async.js
 * lib it shouldn't be too bad to impelement.
*/

program
    .version('0.0.1')
    .option('-p --package-name [value]', 'Package name of Project')
    .option('-n --application-name [value]', 'Name of package')
    .option('-i --input-directory <path>', 'Input Directory')
    .option('-o --output-directory <path>', 'Output Directory')
    .parse(process.argv);

convert = function() {

    // 1. Create a temporary file(s) location.
    // 2. Rename the directories accordingly.
    // 3. Loop over all the files and perform replacements.
    // 4. Zip up the content & Send to the output stream
    // 5. Delete the temporary file(s).
    // 6. All Done - Do some 12 ounce curls.

    console.log(process.env.PWD);

    var appName = program.applicationName;
    var packageName = program.packageName;

    console.log("App Name:" + appName);
    console.log("Package Name:" + packageName);

    // Android Bootstrap source directory
    var sourceDir = program.inputDirectory;

    // Temporary locationwhere the users project will be generated.
    var destDir = process.env.PWD + '/tmp/' + packageName;

    //Final Location where project is generated
    var finalDir = program.outputDirectory

    console.log("sourceDir: " + sourceDir);
    console.log("destDir: " + destDir);
    console.log("sourceDir: " + finalDir);

    // Copy the files to temp directory.
    wrench.copyDirSyncRecursive(sourceDir, destDir);

    var theFiles = wrench.readdirSyncRecursive(destDir);
    console.log(theFiles);

    var callItems = [];

    theFiles.forEach(function(currentFile) {
      var genFileFunc = generateFileFunc(destDir + "/" + currentFile, packageName, appName);
      callItems.push(genFileFunc);

    });

    async.parallel(callItems, function(err, results) {

      if(err) {
        console.error("**** ERROR ****");
      } else {

        // Now, all items have been executed, perform the copying/etc.
        createSourceDirectories(destDir, packageName);
        copySourceDirectories(destDir, packageName);
        removeBootstrapDirectories(destDir);
        wrench.copyDirSyncRecursive(destDir, finalDir);
      }
    });
}

function getFileObjectsFrom(destDir, files) {
  var fileObjs = []
  for(var i=0; i<files.length;i++) {
    var filePath = destDir + "/" + files[i];
    var stats = fs.lstatSync(filePath);
    if(!stats.isDirectory())
      fileObjs.push({ name: files[i], path: filePath });
  }
  return fileObjs;
}

function generateFileFunc(file, packageName, appName) {
  return function(callback) {
    generateFile(file, packageName, appName, callback);
  }
}

function removeBootstrapDirectories(destDir) {

  // TODO: remove the old bootstrap source, unit-test and integration-test folders that are not valid anymore.
  console.log("Removing temporary work directories.");

  // Clean up - delete all the files we were just working with.
  var bootstrapSourceDir = destDir + "/app/src/main/java/com/donnfelker";
  var bootstrapUnitTestDir = destDir + "/app/src/test/java/com/donnfelker";
  var integrationTestDir = destDir +  "/integration-tests/src/main/java/com/donnfelker";

  console.log("Removing: " + bootstrapSourceDir);
  console.log("Removing: " + bootstrapUnitTestDir);
  console.log("Removing: " + integrationTestDir);

  wrench.rmdirSyncRecursive(bootstrapSourceDir, false);
  wrench.rmdirSyncRecursive(bootstrapUnitTestDir, false);
  wrench.rmdirSyncRecursive(integrationTestDir, false);

}

// Creates the various new folder structures needed for the users new project.
function createSourceDirectories(destDir, packageName) {

  var newPathChunk = getNewFilePath(packageName);

  var newSourceDirectory = destDir + "/app/src/main/java/" + newPathChunk;
  console.log("Creating new source directory at: " + newSourceDirectory);
  wrench.mkdirSyncRecursive(newSourceDirectory);

  var newUnitTestDirectory = destDir + "/app/src/test/java/" + newPathChunk;
  console.log("Creating new source directory at: " + newUnitTestDirectory);
  wrench.mkdirSyncRecursive(newUnitTestDirectory);

  var newIntegrationTestDirectory = destDir + "/integration-tests/src/main/java/" + newPathChunk;
  console.log("Creating new integration tests directory at: " + newIntegrationTestDirectory);
  wrench.mkdirSyncRecursive(newIntegrationTestDirectory);
}

function copySourceDirectories(destDir, packageName) {

  console.log(destDir);
  console.log(packageName);

  var newPathChunk = getNewFilePath(packageName);

  var oldSourceDir = destDir  +  "/app/src/main/java/com/donnfelker/android/bootstrap";
  var newSourceDir = destDir    +  "/app/src/main/java/" + newPathChunk;
  console.log("Copying source from" + oldSourceDir + " to directory " + newSourceDir);
  wrench.copyDirSyncRecursive(oldSourceDir, newSourceDir);

  var oldUnitTestDir = destDir + "/app/src/test/java/com/donnfelker/android/bootstrap";
  var newUnitTestDir = destDir + "/app/src/test/java/" + newPathChunk;
  console.log("Copying source from" + oldUnitTestDir + " to directory " + newUnitTestDir);
  wrench.copyDirSyncRecursive(oldUnitTestDir, newUnitTestDir);

  var oldIntegrationTestDir = destDir + "/integration-tests/src/main/java/com/donnfelker/android/bootstrap";
  var newIntegrationTestDir = destDir + "/integration-tests/src/main/java/" + newPathChunk;
  console.log("Copying source from" + oldIntegrationTestDir + " to directory " + newIntegrationTestDir);
  wrench.copyDirSyncRecursive(oldIntegrationTestDir, newIntegrationTestDir);
}

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};

function generateFile(file, packageName, appName, callback) {

  var stats = fs.lstatSync(file);
  if(!stats.isDirectory() && !file.endsWith(".png")) {
    // Only work with text files, no directories or png files.
    // Above == terrible code, but for android-bootstrap, it works. Pragmatic & KISS. FTW.

    // Must include the encoding otherwise the raw buffer will
    // be returned as the data.
    var data = fs.readFileSync(file, 'utf-8');

    //console.log("Current File: " + file);

    console.log("File: " + file);
    // Sure, we could chain these, but this is easier to read.
    data = replacePackageName(data, packageName);
    data = replaceAuthToken(data, packageName);
    data = replaceAppName(data, appName);
    data = replaceHyphenatedNames(data, packageName);
    data = replaceProguardValues(data, packageName);

    // Finally all done doing replacing, save this bad mother.
    fs.writeFileSync(file, data);
  }

   // Call back to async lib.
    callback(null, file);
}

// Turns a package name into a file path string.
// Example: com.foo.bar.bang turns into com\foo\bar\bang
function getNewFilePath(newPackageName) {
  return newPackageName.split('.').join('/');
}

function getOldFilePath() {
  return "com.donnfelker.android.bootstrap".split('.').join('/');
}

// Takes the old boostrap file name and returns the new file name
// that is created via the transform from the new package name.
function getBootstrappedFileName(bootstrapFileName, newPackageName) {
  return bootstrapFileName.replace( getOldFilePath(), getNewFilePath(newPackageName) );
}

function replacePackageName(fileContents, newPackageName) {
  var BOOTSTRAP_PACKAGE_NAME = "com.donnfelker.android.bootstrap"; // replace all needs a regex with the /g (global) modifier
  var packageNameRegExp = new RegExp(BOOTSTRAP_PACKAGE_NAME, 'g');

  // Replace package name
  return fileContents.replace(packageNameRegExp, newPackageName);
}

function replaceAuthToken(fileContents, newPackageName) {
  var BOOTSTRAP_TOKEN = "com.androidbootstrap";
  var tokenRegExp = new RegExp(BOOTSTRAP_TOKEN, 'g'); // global search

  return fileContents.replace( tokenRegExp, newPackageName );
}

function replaceAppName(fileContents, newAppName) {
  var APP_NAME = "Android Bootstrap";
  var nameRegExp = new RegExp(APP_NAME, 'g'); // global search

  return fileContents.replace(nameRegExp, newAppName);
}

function replaceHyphenatedNames(fileContents, newPackageName) {
  var newHyphenatedName = newPackageName.toLowerCase().split('.').join('-');
  var hyphenatedRegExp = new RegExp("android-bootstrap", 'g'); // global search

  return fileContents.replace(hyphenatedRegExp, newHyphenatedName);
}

function replaceProguardValues(fileContents, newPackageName) {
  var newValue = newPackageName + '.';
  var valueToFind = new RegExp("com.donnfelker.android.", 'g');

  return fileContents.replace(valueToFind, newValue);
}

convert();
<|endoftext|>