<commit_before>//! License: MIT Adapted (as stated in the LICENSE file)

var placeholder = "Search, drag and drop video, or paste its URL...";

var playImgSrc = "//cdn.rawgit.com/iconic/open-iconic/master/png/media-play-4x.png";
var removeImgSrc = "//cdn.rawgit.com/iconic/open-iconic/master/png/x-4x.png";

var videoUrl;
var videoName;
var videoTime = null;

var videos = [];
var videoCounter = 0;
var videoIteration = 0;
var bufferTime = 2000;
var waitEndTime = 1500;

var videoPaused;
var stayPaused;
var backRestart;

var loopTimer;
var progressTimer;

function Timer(callback, delay) {
  var id, started, remaining = delay, running;
  this.resume = function() {
    running = true;
    started = new Date();
    id = window.setTimeout(callback, remaining);
  }
  this.pause = function() {
    running = false;
    window.clearTimeout(id);
    remaining -= new Date() - started;
  }
  this.getTimeLeft = function() {
    if (running) {
      this.pause();
      this.resume();
    }
    return remaining;
  }
  this.getStateRunning = function() {
    return running;
  }
  this.resume();
}

Array.prototype.move = function(from, to) {
  this.splice(to, 0, this.splice(from, 1)[0]);
};

function msConversion(millis) {
  var minutes = Math.floor(millis / 60000);
  var seconds = ((millis % 60000) / 1000).toFixed(0);
  return minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
}

function highlight(i) {
  $("tr:nth-child(" + i + ")").attr("id", "newSelected");
  $("tr.selected").removeClass("selected");
  $("#newSelected").addClass("selected");
  $("#newSelected").removeAttr("id");
}

function addVideoToList(name, time) {
  name = decodeURIComponent(name);
  $("#videosTable").append("
" + name + "<button class=\"tableButton removeButton\" onclick=\"actionRemoveVideo(this);\"></button>" +
  "<button class=\"tableButton playButton\" onclick=\"actionPlayVideo(this);\"></button>	" + time + "
");
}

function resetTimer(which) {
  if (which != 0) {
      which.pause();
    }
    which = 0;
}

var ActionTimers = function() {
  this.pause = function() {
    loopTimer.pause();
    progressTimer.pause();
  }
  this.resume = function() {
    loopTimer.resume();
    progressTimer.resume();
  }
  this.clear = function() {
    resetTimer(loopTimer);
    resetTimer(progressTimer);
    $("#progress").css("width", "0%");
    $("#currentTime").text("0:00");
    $("#videoTime").text("0:00");
  }
}
var actionTimers = new ActionTimers();

function videoProgress() {
  var time = videos[videoIteration][1] * 1000;
  $("#videoTime").text(msConversion(time));
  function progressLoop() {
    var currentTime = (time + waitEndTime) - loopTimer.getTimeLeft();
    var currentPercent = (currentTime / time) * 100;
    progressTimer = new Timer(function() {
      if (currentTime > 0) {
        $("#progress").css("width", currentPercent + "%");
        $("#currentTime").text(msConversion(currentTime));
      }
      if (currentTime < time) {
        progressLoop();
      }
    }, 500);
  }
  progressLoop();
}

function playVideo() {
  highlight(videoIteration);
  document.title = "Streamly - " + decodeURIComponent(videos[videoIteration][0]);
  var embedUrl = videos[videoIteration][2];

  var autoplay = "";
  if (!stayPaused) {
    autoplay = "?autoplay=1";
  }

  embedUrl = "https://www.youtube.com/embed/" + videos[videoIteration][2] + autoplay;
  $("#youtube").attr("src", embedUrl);

  backRestart = false;
  window.setTimeout(function() {
    backRestart = true;
  }, 3000);
}

function loopVideo() {
  videoIteration++;
  playVideo();
  loopTimer = new Timer(function() {
    if (videoIteration < videoCounter) {
      actionTimers.clear();
      loopVideo();
    }
    else {
      actionTimers.clear();
      $("#youtube").attr("src", "");
      if (videos[0] !== undefined && videos[0] !== null) {
        document.title = "Streamly - " + decodeURIComponent(videos[0]);
      }
      else {
        document.title = "Streamly";
      }
    }
  }, (videos[videoIteration][1] * 1000) + bufferTime + waitEndTime);

  videoProgress();

  if (stayPaused) {
    actionTimers.pause();
  }
}

function pauseVideo() {
  if (!videoPaused) {
    actionTimers.pause();
    videoPaused = true;
    if (videos[0] !== undefined && videos[0] !== null) {
      document.title = "Streamly - " + decodeURIComponent(videos[0]);
    }
  }
  else {
    actionTimers.resume();
    videoPaused = false;
    stayPaused = false;
    document.title = "Streamly - " + decodeURIComponent(videos[videoIteration][0]);
  }
  $("#pauseOverlay").css("display", "none");
  setTimeout(function(){
    $("#pauseOverlay").css("display", "block");
    $("#youtube").blur();
  }, 500);
}

function forwardVideo() {
  if (videoIteration + 1 <= videoCounter) {
    actionTimers.clear();

    if (videoPaused) {
      stayPaused = true;
    }
    loopVideo();
  }
}

function backVideo() {
  if (videoPaused) {
    stayPaused = true;
  }
  if (!backRestart) {
    if (videoIteration - 2 > -1) {
      videoIteration = videoIteration - 2;
      actionTimers.clear();
      loopVideo();
    }
  }
  else {
    videoIteration = videoIteration - 1;
    actionTimers.clear();
    loopVideo();
  }
}

function setPlaylist() {
  if (videos.length > 1) {
    var playlist = JSON.stringify(videos);
    playlist = window.btoa(playlist);
    playlist = encodeURIComponent(playlist);
    window.location.hash = playlist;
  }
  else {
    window.location.hash = "";
  }
}

function getPlaylist() {
  if (window.location.hash.substr(1) !== "") {
    var playlist = window.location.hash.substr(1);
    playlist = decodeURIComponent(playlist);
    playlist = window.atob(playlist);
    playlist = JSON.parse(playlist);
    videos = playlist;

    if (videos[0] !== undefined && videos[0] !== null) {
      $("#playlistNameBox").val(decodeURIComponent(videos[0]));
    }

    for (i = 1; i < videos.length; i++) {
      videoCounter = i;
      var printTime = msConversion(videos[videoCounter][1] * 1000);
      addVideoToList(videos[videoCounter][0], printTime);
    }
    loopVideo();
  }
}

function getVideoData() {
  $.ajax({
    url: videoUrl,
    type: 'GET',
    success: function(res) {
      var data = $(res.responseText);
      try {
        videoName = data.find("span#eow-title");
        videoName = videoName[0].textContent;
        videoName = $("
").html(videoName).text();
        videoName = videoName.trim();
      } catch(err) {
        videoName = prompt("Please enter the name of the video", "");
      }
      videoName = encodeURIComponent(videoName).replace(/%20/g, " ");
      try {
        videoTime = null;
        for (iteration in data) {
          var str = data[iteration].innerHTML;
          if (videoTime == null && typeof str != "undefined") {
            videoTime = str.match(/,"length_seconds":"\d+",/g);
          }
        }
        videoTime = videoTime[0];
        videoTime = videoTime.replace(/,"length_seconds":"/g, "").replace(/",/g, "");
        videoTime = +videoTime * 1000;
      } catch(err) {
        videoTime = prompt("Please enter the length of the video", "3:00");
        videoTime = videoTime.split(":");
        videoTime = (+videoTime[0]) * 60 + (+videoTime[1]);
        videoTime = videoTime * 1000;
      }
    },
    complete: function(jqXHR, textStatus) {
      $("#inputBox").val("").attr("placeholder", placeholder);
      addVideo();
    },
    error: function(jqXHR, textStatus, errorThrown) {
      videoName = prompt("Please enter the name of the video", "");

      videoTime = prompt("Please enter the length of the video", "3:00");
      videoTime = videoTime.split(":");
      videoTime = (+videoTime[0]) * 60 + (+videoTime[1]);
      videoTime = videoTime * 1000;
    }
  });
}

function addVideo() {
  videoCounter++;
  var video = [];
  video[0] = videoName;
  video[1] = videoTime / 1000;
  video[2] = videoUrl.replace(/^htt(p|ps):\/\/www\.youtube\.com\/watch\?v=/i, "");
  videos[videoCounter] = video;

  var printTime = msConversion(videoTime);

  addVideoToList(videoName, printTime);

  setPlaylist();
  makeSortable();

  if (videoCounter == 1 || (loopTimer.getStateRunning() === false && !videoPaused)) {
    loopVideo();
  }
}

function actionPlayVideo(element) {
  var index = $(".playButton").index(element);
  videoIteration = index;
  if (videoPaused) {
    stayPaused = true;
  }
  actionTimers.clear();
  loopVideo();
}

function actionRemoveVideo(element) {
  var index = $(".removeButton").index(element) + 1;
  if (index == videoIteration) {
    if (videoIteration + 1 <= videoCounter) {
      forwardVideo();
      videoIteration--;
    }
    else {
      actionTimers.clear();
      $("#youtube").attr("src", "");
      document.title = "Streamly";
      videoIteration--;
    }
  }
  else if (index < videoIteration) {
    videoIteration--;
  }
  videoCounter--;
  videos.splice(index, 1);
  $("tr:nth-child(" + index + ")").remove();
  setPlaylist();
  makeSortable();
}

function actionMoveVideo(oldIndex, newIndex) {
  videos.move(oldIndex, newIndex);
  if (oldIndex == videoIteration) {
    videoIteration = newIndex;
  }
  else if (oldIndex < videoIteration && newIndex >= videoIteration) {
    videoIteration--;
  }
  else if (oldIndex > videoIteration && newIndex <= videoIteration) {
    videoIteration++;
  }
}

function makeSortable() {
  $("#videosTable").sortable("destroy");
  var oldIndex;
  $("#videosTable").sortable({
    containerSelector: "table",
    itemPath: "> tbody",
    itemSelector: "tr",
    placeholder: "
",
    delay: 100,
    onDragStart: function ($item, container, _super) {
      oldIndex = $item.index();
    },
    onDrop: function ($item, container, _super) {
      actionMoveVideo(oldIndex + 1, $item.index() + 1);
      setPlaylist();
    }
  });
}

function urlValidate(url) {
  var isValidYouTube = /^htt(p|ps):\/\/www\.youtube\.com\/watch\?v=.+$/i;

  url = url.trim();
  url = url.replace(/&index=.+/i, "").replace(/&list=.+/i, "");

  if (url.search(isValidYouTube) > -1) {
    return url;
  }
  else {
    return false;
  }
}

function input(type) {
  var inputBox = $("#inputBox").val();
  var playlistNameBox = $("#playlistNameBox").val();
  switch (type) {
    case 0:
      if (inputBox != "") {
        window.open("https://www.youtube.com/results?search_query=" + inputBox.replace(/ /g, "+"));
        $("#inputBox").val("").attr("placeholder", placeholder);
      }
      break;
    case 1:
      if (inputBox != "") {
        inputBox = urlValidate(inputBox);
        if (inputBox) {
          videoUrl = inputBox;
          $("#inputBox").val("").attr("placeholder", "Loading video data from YouTube...");
          getVideoData();
        }
        else {
          alert("That video's URL seems broken\n\nTry copying it again, or drag and drop the video directly");
        }
      }
      break;
    case 2:
      if (playlistNameBox != "") {
        videos[0] = encodeURIComponent(playlistNameBox).replace(/%20/g, " ");
      }
      else {
        videos[0] = undefined;
      }
      setPlaylist();
      break;
  }
}

document.addEventListener("drop", function(event) {
  event.preventDefault();
  var data = event.dataTransfer.getData("URL");

  $("#inputBox").val(data);
  input(1);
});

document.addEventListener("dragover", function(event) {
  event.preventDefault();
});
<commit_msg>run the new URL to the share playlist button<commit_after>//! License: MIT Adapted (as stated in the LICENSE file)

var placeholder = "Search, drag and drop video, or paste its URL...";

var playImgSrc = "//cdn.rawgit.com/iconic/open-iconic/master/png/media-play-4x.png";
var removeImgSrc = "//cdn.rawgit.com/iconic/open-iconic/master/png/x-4x.png";

var videoUrl;
var videoName;
var videoTime = null;

var videos = [];
var videoCounter = 0;
var videoIteration = 0;
var bufferTime = 2000;
var waitEndTime = 1500;

var videoPaused;
var stayPaused;
var backRestart;

var loopTimer;
var progressTimer;

function Timer(callback, delay) {
  var id, started, remaining = delay, running;
  this.resume = function() {
    running = true;
    started = new Date();
    id = window.setTimeout(callback, remaining);
  }
  this.pause = function() {
    running = false;
    window.clearTimeout(id);
    remaining -= new Date() - started;
  }
  this.getTimeLeft = function() {
    if (running) {
      this.pause();
      this.resume();
    }
    return remaining;
  }
  this.getStateRunning = function() {
    return running;
  }
  this.resume();
}

Array.prototype.move = function(from, to) {
  this.splice(to, 0, this.splice(from, 1)[0]);
};

function msConversion(millis) {
  var minutes = Math.floor(millis / 60000);
  var seconds = ((millis % 60000) / 1000).toFixed(0);
  return minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
}

function highlight(i) {
  $("tr:nth-child(" + i + ")").attr("id", "newSelected");
  $("tr.selected").removeClass("selected");
  $("#newSelected").addClass("selected");
  $("#newSelected").removeAttr("id");
}

function addVideoToList(name, time) {
  name = decodeURIComponent(name);
  $("#videosTable").append("
" + name + "<button class=\"tableButton removeButton\" onclick=\"actionRemoveVideo(this);\"></button>" +
  "<button class=\"tableButton playButton\" onclick=\"actionPlayVideo(this);\"></button>	" + time + "
");
}

function resetTimer(which) {
  if (which != 0) {
      which.pause();
    }
    which = 0;
}

var ActionTimers = function() {
  this.pause = function() {
    loopTimer.pause();
    progressTimer.pause();
  }
  this.resume = function() {
    loopTimer.resume();
    progressTimer.resume();
  }
  this.clear = function() {
    resetTimer(loopTimer);
    resetTimer(progressTimer);
    $("#progress").css("width", "0%");
    $("#currentTime").text("0:00");
    $("#videoTime").text("0:00");
  }
}
var actionTimers = new ActionTimers();

function videoProgress() {
  var time = videos[videoIteration][1] * 1000;
  $("#videoTime").text(msConversion(time));
  function progressLoop() {
    var currentTime = (time + waitEndTime) - loopTimer.getTimeLeft();
    var currentPercent = (currentTime / time) * 100;
    progressTimer = new Timer(function() {
      if (currentTime > 0) {
        $("#progress").css("width", currentPercent + "%");
        $("#currentTime").text(msConversion(currentTime));
      }
      if (currentTime < time) {
        progressLoop();
      }
    }, 500);
  }
  progressLoop();
}

function playVideo() {
  highlight(videoIteration);
  document.title = "Streamly - " + decodeURIComponent(videos[videoIteration][0]);
  var embedUrl = videos[videoIteration][2];

  var autoplay = "";
  if (!stayPaused) {
    autoplay = "?autoplay=1";
  }

  embedUrl = "https://www.youtube.com/embed/" + videos[videoIteration][2] + autoplay;
  $("#youtube").attr("src", embedUrl);

  backRestart = false;
  window.setTimeout(function() {
    backRestart = true;
  }, 3000);
}

function loopVideo() {
  videoIteration++;
  playVideo();
  loopTimer = new Timer(function() {
    if (videoIteration < videoCounter) {
      actionTimers.clear();
      loopVideo();
    }
    else {
      actionTimers.clear();
      $("#youtube").attr("src", "");
      if (videos[0] !== undefined && videos[0] !== null) {
        document.title = "Streamly - " + decodeURIComponent(videos[0]);
      }
      else {
        document.title = "Streamly";
      }
    }
  }, (videos[videoIteration][1] * 1000) + bufferTime + waitEndTime);

  videoProgress();

  if (stayPaused) {
    actionTimers.pause();
  }
}

function pauseVideo() {
  if (!videoPaused) {
    actionTimers.pause();
    videoPaused = true;
    if (videos[0] !== undefined && videos[0] !== null) {
      document.title = "Streamly - " + decodeURIComponent(videos[0]);
    }
  }
  else {
    actionTimers.resume();
    videoPaused = false;
    stayPaused = false;
    document.title = "Streamly - " + decodeURIComponent(videos[videoIteration][0]);
  }
  $("#pauseOverlay").css("display", "none");
  setTimeout(function(){
    $("#pauseOverlay").css("display", "block");
    $("#youtube").blur();
  }, 500);
}

function forwardVideo() {
  if (videoIteration + 1 <= videoCounter) {
    actionTimers.clear();

    if (videoPaused) {
      stayPaused = true;
    }
    loopVideo();
  }
}

function backVideo() {
  if (videoPaused) {
    stayPaused = true;
  }
  if (!backRestart) {
    if (videoIteration - 2 > -1) {
      videoIteration = videoIteration - 2;
      actionTimers.clear();
      loopVideo();
    }
  }
  else {
    videoIteration = videoIteration - 1;
    actionTimers.clear();
    loopVideo();
  }
}

function setPlaylist() {
  if (videos.length > 1) {
    var playlist = JSON.stringify(videos);
    playlist = window.btoa(playlist);
    playlist = encodeURIComponent(playlist);
    window.location.hash = playlist;
    $("#shareButton").attr("data-clipboard-text", "https://lnfwebsite.github.io/Streamly/#" + playlist);
  }
  else {
    window.location.hash = "";
  }
}

function getPlaylist() {
  if (window.location.hash.substr(1) !== "") {
    var playlist = window.location.hash.substr(1);
    playlist = decodeURIComponent(playlist);
    playlist = window.atob(playlist);
    playlist = JSON.parse(playlist);
    videos = playlist;

    if (videos[0] !== undefined && videos[0] !== null) {
      $("#playlistNameBox").val(decodeURIComponent(videos[0]));
    }

    for (i = 1; i < videos.length; i++) {
      videoCounter = i;
      var printTime = msConversion(videos[videoCounter][1] * 1000);
      addVideoToList(videos[videoCounter][0], printTime);
    }
    loopVideo();
  }
}

function getVideoData() {
  $.ajax({
    url: videoUrl,
    type: 'GET',
    success: function(res) {
      var data = $(res.responseText);
      try {
        videoName = data.find("span#eow-title");
        videoName = videoName[0].textContent;
        videoName = $("
").html(videoName).text();
        videoName = videoName.trim();
      } catch(err) {
        videoName = prompt("Please enter the name of the video", "");
      }
      videoName = encodeURIComponent(videoName).replace(/%20/g, " ");
      try {
        videoTime = null;
        for (iteration in data) {
          var str = data[iteration].innerHTML;
          if (videoTime == null && typeof str != "undefined") {
            videoTime = str.match(/,"length_seconds":"\d+",/g);
          }
        }
        videoTime = videoTime[0];
        videoTime = videoTime.replace(/,"length_seconds":"/g, "").replace(/",/g, "");
        videoTime = +videoTime * 1000;
      } catch(err) {
        videoTime = prompt("Please enter the length of the video", "3:00");
        videoTime = videoTime.split(":");
        videoTime = (+videoTime[0]) * 60 + (+videoTime[1]);
        videoTime = videoTime * 1000;
      }
    },
    complete: function(jqXHR, textStatus) {
      $("#inputBox").val("").attr("placeholder", placeholder);
      addVideo();
    },
    error: function(jqXHR, textStatus, errorThrown) {
      videoName = prompt("Please enter the name of the video", "");

      videoTime = prompt("Please enter the length of the video", "3:00");
      videoTime = videoTime.split(":");
      videoTime = (+videoTime[0]) * 60 + (+videoTime[1]);
      videoTime = videoTime * 1000;
    }
  });
}

function addVideo() {
  videoCounter++;
  var video = [];
  video[0] = videoName;
  video[1] = videoTime / 1000;
  video[2] = videoUrl.replace(/^htt(p|ps):\/\/www\.youtube\.com\/watch\?v=/i, "");
  videos[videoCounter] = video;

  var printTime = msConversion(videoTime);

  addVideoToList(videoName, printTime);

  setPlaylist();
  makeSortable();

  if (videoCounter == 1 || (loopTimer.getStateRunning() === false && !videoPaused)) {
    loopVideo();
  }
}

function actionPlayVideo(element) {
  var index = $(".playButton").index(element);
  videoIteration = index;
  if (videoPaused) {
    stayPaused = true;
  }
  actionTimers.clear();
  loopVideo();
}

function actionRemoveVideo(element) {
  var index = $(".removeButton").index(element) + 1;
  if (index == videoIteration) {
    if (videoIteration + 1 <= videoCounter) {
      forwardVideo();
      videoIteration--;
    }
    else {
      actionTimers.clear();
      $("#youtube").attr("src", "");
      document.title = "Streamly";
      videoIteration--;
    }
  }
  else if (index < videoIteration) {
    videoIteration--;
  }
  videoCounter--;
  videos.splice(index, 1);
  $("tr:nth-child(" + index + ")").remove();
  setPlaylist();
  makeSortable();
}

function actionMoveVideo(oldIndex, newIndex) {
  videos.move(oldIndex, newIndex);
  if (oldIndex == videoIteration) {
    videoIteration = newIndex;
  }
  else if (oldIndex < videoIteration && newIndex >= videoIteration) {
    videoIteration--;
  }
  else if (oldIndex > videoIteration && newIndex <= videoIteration) {
    videoIteration++;
  }
}

function makeSortable() {
  $("#videosTable").sortable("destroy");
  var oldIndex;
  $("#videosTable").sortable({
    containerSelector: "table",
    itemPath: "> tbody",
    itemSelector: "tr",
    placeholder: "
",
    delay: 100,
    onDragStart: function ($item, container, _super) {
      oldIndex = $item.index();
    },
    onDrop: function ($item, container, _super) {
      actionMoveVideo(oldIndex + 1, $item.index() + 1);
      setPlaylist();
    }
  });
}

function urlValidate(url) {
  var isValidYouTube = /^htt(p|ps):\/\/www\.youtube\.com\/watch\?v=.+$/i;

  url = url.trim();
  url = url.replace(/&index=.+/i, "").replace(/&list=.+/i, "");

  if (url.search(isValidYouTube) > -1) {
    return url;
  }
  else {
    return false;
  }
}

function input(type) {
  var inputBox = $("#inputBox").val();
  var playlistNameBox = $("#playlistNameBox").val();
  switch (type) {
    case 0:
      if (inputBox != "") {
        window.open("https://www.youtube.com/results?search_query=" + inputBox.replace(/ /g, "+"));
        $("#inputBox").val("").attr("placeholder", placeholder);
      }
      break;
    case 1:
      if (inputBox != "") {
        inputBox = urlValidate(inputBox);
        if (inputBox) {
          videoUrl = inputBox;
          $("#inputBox").val("").attr("placeholder", "Loading video data from YouTube...");
          getVideoData();
        }
        else {
          alert("That video's URL seems broken\n\nTry copying it again, or drag and drop the video directly");
        }
      }
      break;
    case 2:
      if (playlistNameBox != "") {
        videos[0] = encodeURIComponent(playlistNameBox).replace(/%20/g, " ");
      }
      else {
        videos[0] = undefined;
      }
      setPlaylist();
      break;
  }
}

document.addEventListener("drop", function(event) {
  event.preventDefault();
  var data = event.dataTransfer.getData("URL");

  $("#inputBox").val(data);
  input(1);
});

document.addEventListener("dragover", function(event) {
  event.preventDefault();
});
<|endoftext|>


<commit_before>var parseArgs = require('./lib/parse-args')
var budo = require('./lib/budo')
var color = require('term-color')

module.exports = budo
module.exports.cli = budoCLI

function budoCLI (args, opts) {
  var argv = parseArgs(args, opts)

  // default to stdout
  if (argv.stream !== false) {
    argv.stream = process.stdout
  }

  var entries = argv._
  delete argv._

  argv.browserifyArgs = argv['--']
  delete argv['--']

  if (argv.version) {
    console.log(require('./package.json').version)
    return null
  }

  if (argv.help) {
    var help = require('path').join(__dirname, 'bin', 'help.txt')
    require('fs').createReadStream(help)
      .pipe(process.stdout)
    return null
  }

  if (argv.outfile) {
    console.error(color.yellow('WARNING'), '--outfile has been removed in budo@3.0')
    // ensure we don't pass to watchify
    delete argv.outfile
  }

  // opts.live can be a glob or a boolean
  if (typeof argv.live === 'string' && /(true|false)/.test(argv.live)) {
    argv.live = argv.live === 'true'
  }

  return budo(entries, argv).on('error', exit)
}

function exit (err) {
  console.log(color.red('ERROR'), err.message)
  process.exit(1)
}
<commit_msg>no longer need to worry about conflicts because of full-stop in args<commit_after>var parseArgs = require('./lib/parse-args')
var budo = require('./lib/budo')
var color = require('term-color')

module.exports = budo
module.exports.cli = budoCLI

function budoCLI (args, opts) {
  var argv = parseArgs(args, opts)

  // default to stdout
  if (argv.stream !== false) {
    argv.stream = process.stdout
  }

  var entries = argv._
  delete argv._

  argv.browserifyArgs = argv['--']
  delete argv['--']

  if (argv.version) {
    console.log(require('./package.json').version)
    return null
  }

  if (argv.help) {
    var help = require('path').join(__dirname, 'bin', 'help.txt')
    require('fs').createReadStream(help)
      .pipe(process.stdout)
    return null
  }

  if (argv.outfile) {
    console.error(color.yellow('WARNING'), '--outfile has been removed in budo@3.0')
  }

  // opts.live can be a glob or a boolean
  if (typeof argv.live === 'string' && /(true|false)/.test(argv.live)) {
    argv.live = argv.live === 'true'
  }

  return budo(entries, argv).on('error', exit)
}

function exit (err) {
  console.log(color.red('ERROR'), err.message)
  process.exit(1)
}
<|endoftext|>


<commit_before>module.exports = template

var dotpather = require('dotpather')

function template(thing) {
  var str = thing.toString()
  return function template_generator(obj) {
    return str.replace(/\{\{\s*([\w_\.]+)\s*\}\}/g, template_lookup)

    function template_lookup(chunk, word) {
      return dotpather(word)(obj)
    }
  }
}
<commit_msg>minor update<commit_after>module.exports = template

var dotpather = require('dotpather'),
    template_rex = /\{\{\s*([\w_\.]+)\s*\}\}/g

function template(thing) {
  var str = thing.toString()
  return function template_generator(obj) {
    return str.replace(template_rex, template_lookup)

    function template_lookup(chunk, word) {
      return dotpather(word)(obj)
    }
  }
}
<|endoftext|>


<commit_before>/**
 * This script takes raw OCP data and processes it into something that can be
 * used more easily by other applications.
 */
'use strict';

var _ = require('lodash');
var async = require('async');
var fs = require('fs-extra');

var sourceDir = './data/oc-status';
var targetDir = './dist/oc-status';

var mapData = require('./lib/ne_110m_admin_0_countries.json');
var tableData = {
  meta: {
    display: [
      {
        key: 'country',
        value: 'Country'
      },
      {
        key: 'ocds_data',
        value: 'Publishing OCDS data'
      },
      {
        key: 'ocds_implementation',
        value: 'OCDS implementation'
      },
      {
        key: 'ogp_commitment',
        value: 'Relevant OGP commitment'
      }
    ]
  },
  data: []
};

var output = {
  merged: {
    data: [],
    file: '_all.json'
  },
  index: {
    data: {},
    file: '_index.json'
  },
  map: {
    data: mapData,
    file: '_map.json'
  },
  table: {
    data: tableData,
    file: '_table.json'
  }
};

function processOCDS (countryData) {
  if (countryData.results.ocds_historic_data && countryData.results.ocds_ongoing_data) {
    return 'Historic and ongoing';
  } else if (countryData.results.ocds_historic_data) {
    return 'Historic';
  } else if (countryData.results.ocds_ongoing_data) {
    return 'Ongoing';
  } else {
    return 'No';
  }
}

function prepTableData (countryData) {
  var d = {
    country: countryData.name,
    ocds_data: processOCDS(countryData),
    ocds_implementation: countryData.results.ocds_implementation ? 'Yes' : 'No'
  };
  if (countryData.results.ogp_commitments[0]) {
    d.ogp_commitment = countryData.results.ogp_commitments[0].ogp_commitment !== '' || null ? 'Yes' : 'No';
  }
  return d;
}

async.waterfall([
  function (callback) {
    // Write the original data files
    fs.copy(sourceDir, targetDir, function (err) {
      callback(err);
    });
  },
  function (callback) {
    // Process the data
    fs.readdir(sourceDir, function (err, list) {
      for (var f in list) {
        var jsonData = JSON.parse(fs.readFileSync(`${sourceDir}/${list[f]}`));

        // Add an indication if the country has any data reported
        // False values on booleans count as no data
        jsonData.results.has_data = _.every(jsonData.results, _.negate(_.isEmpty));

        var i = _.findIndex(output.map.data.features, function (o) { return o.properties.iso_a2.toLowerCase() === jsonData.iso; });
        if (i !== -1) {
          _.merge(output.map.data.features[i].properties, jsonData.results);
        }

        output.index.data[list[f]] = {name: jsonData.name};
        output.table.data.data.push(prepTableData(jsonData));
        output.merged.data.push(jsonData);
      }
      callback(err, output);
    });
  },
  function (output, callback) {
    var tasks = [];
    _.forEach(output, function (f) {
      tasks.push(function (cb) {
        fs.writeFile(`${targetDir}/${f.file}`, JSON.stringify(f.data), function (err) {
          cb(err);
        });
      });
    });
    async.parallel(tasks, callback);
  }
], function (err) {
  if (err) console.error(err.message);
  console.log('Success, all data processed and ready to serve beautiful things.');
});
<commit_msg>Ignore the new _index.json when processing data<commit_after>/**
 * This script takes raw OCP data and processes it into something that can be
 * used more easily by other applications.
 */
'use strict';

var _ = require('lodash');
var async = require('async');
var fs = require('fs-extra');

var sourceDir = './data/oc-status';
var targetDir = './dist/oc-status';

var mapData = require('./lib/ne_110m_admin_0_countries.json');
var tableData = {
  meta: {
    display: [
      {
        key: 'country',
        value: 'Country'
      },
      {
        key: 'ocds_data',
        value: 'Publishing OCDS data'
      },
      {
        key: 'ocds_implementation',
        value: 'OCDS implementation'
      },
      {
        key: 'ogp_commitment',
        value: 'Relevant OGP commitment'
      }
    ]
  },
  data: []
};

var output = {
  merged: {
    data: [],
    file: '_all.json'
  },
  index: {
    data: {},
    file: '_index.json'
  },
  map: {
    data: mapData,
    file: '_map.json'
  },
  table: {
    data: tableData,
    file: '_table.json'
  }
};

function processOCDS (countryData) {
  if (countryData.results.ocds_historic_data && countryData.results.ocds_ongoing_data) {
    return 'Historic and ongoing';
  } else if (countryData.results.ocds_historic_data) {
    return 'Historic';
  } else if (countryData.results.ocds_ongoing_data) {
    return 'Ongoing';
  } else {
    return 'No';
  }
}

function prepTableData (countryData) {
  var d = {
    country: countryData.name,
    ocds_data: processOCDS(countryData),
    ocds_implementation: countryData.results.ocds_implementation ? 'Yes' : 'No'
  };
  if (countryData.results.ogp_commitments[0]) {
    d.ogp_commitment = countryData.results.ogp_commitments[0].ogp_commitment !== '' || null ? 'Yes' : 'No';
  }
  return d;
}

async.waterfall([
  function (callback) {
    // Write the original data files
    fs.copy(sourceDir, targetDir, function (err) {
      callback(err);
    });
  },
  function (callback) {
    // Process the data
    fs.readdir(sourceDir, function (err, list) {
      for (var f in list) {
        if (list[f] !== '_index.json') {
          var jsonData = JSON.parse(fs.readFileSync(`${sourceDir}/${list[f]}`));

          // Add an indication if the country has any data reported
          // False values on booleans count as no data
          jsonData.results.has_data = _.every(jsonData.results, _.negate(_.isEmpty));

          var i = _.findIndex(output.map.data.features, function (o) { return o.properties.iso_a2.toLowerCase() === jsonData.iso; });
          if (i !== -1) {
            _.merge(output.map.data.features[i].properties, jsonData.results);
          }

          output.index.data[list[f]] = {name: jsonData.name};
          output.table.data.data.push(prepTableData(jsonData));
          output.merged.data.push(jsonData);
        }
      }
      callback(err, output);
    });
  },
  function (output, callback) {
    var tasks = [];
    _.forEach(output, function (f) {
      tasks.push(function (cb) {
        fs.writeFile(`${targetDir}/${f.file}`, JSON.stringify(f.data), function (err) {
          cb(err);
        });
      });
    });
    async.parallel(tasks, callback);
  }
], function (err) {
  if (err) console.error(err.message);
  console.log('Success, all data processed and ready to serve beautiful things.');
});
<|endoftext|>


<commit_before>var prompt = require('prompt');
var fs = require('fs');

var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:20010'));
var myId = web3.shh.newIdentity();

var util = require('./util.js');

var nodeName = 'unset';
var constellationNodes = [];
var nodeNames = {};

function startWhisperListeners(){
  web3.shh.filter({"topics":["Constellation"]}).watch(function(err, msg) {
    if(err){console.log("ERROR:", err);};
    var message = util.Hex2a(msg.payload);
    if(message.indexOf('request|publicKey') >= 0){
      getThisNodesConstellationPubKey(function(publicKey){
        var message = 'response|publicKey|'+publicKey;
        var hexString = new Buffer(message).toString('hex');
        web3.shh.post({
          "topics": ["Constellation"],
          "from": myId,
          "payload": hexString,
          "ttl": 10,
          "workToProve": 1
        }, function(err, res){
          if(err){console.log('err', err);}
        });
      });
    } else if(message.indexOf('response|publicKey') >= 0){
      // TODO: add check that this is a new constellation node
      var publicKey = message.substring('response|publicKey|'.length+1)
      var constellationNode = {
        id: msg.from,
        publicKey: publicKey
      };
      constellationNodes.push(constellationNode);
    }
  });
}

function getThisNodesConstellationPubKey(cb){
  fs.readFile('../QuorumNetworkManager/Constellation/node.pub', function read(err, data) {
    if (err) { console.log('ERROR:', err); }
    var publicKey = new Buffer(data).toString();
   cb(publicKey);
  });
}

function requestConstellationKeys(cb){
  console.log('Requesting constellation public keys:');
  var message = 'request|publicKey';
  var hexString = new Buffer(message).toString('hex');
  web3.shh.post({
    "topics": ["Constellation"],
    "from": myId,
    "payload": hexString,
    "ttl": 10,
    "workToProve": 1
  }, function(err, res){
    if(err){console.log('err', err);}
    cb();
  });
}

function displayConstellationKeys(cb){
  for(var i in constellationNodes){
    var node = constellationNodes[i];
    console.log(node.publicKey + ' | ' + node.id);
  }
  cb();
}

function setNodeName(cb){
  promt.get(['name'], function(err, node){
    nodeName = node.name;
    cb();
  });
}

prompt.start();
function menu(){
  console.log('1) Set node name');
  console.log('2) Get other node names');
  console.log('3) Request other nodes\' constellation keys');
  console.log('4) Display known constellation keys');
  console.log('0) Quit');
  prompt.get(['option'], function (err, o) {
    if(o.option == 1){
      setNodeName(function(){
        menu();
      });
    } else if(o.option == 2){
      requestOtherNodeNames(function(){
        menu();
      });
    } else if(o.option == 3){
      requestConstellationKeys(function(){
        menu();
      });
    } else if(o.option == 4){
      displayConstellationKeys(function(){
        menu();
      });
    } else if(o.option == 0){
      console.log('Quiting');
      return;
    } else {
      menu();
    }
  });
}

startWhisperListeners();
menu();
<commit_msg>Can now get other nodes identity names<commit_after>var prompt = require('prompt');
var fs = require('fs');

var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:20010'));
var myId = web3.shh.newIdentity();

var util = require('./util.js');

var nodeIdentityName = 'unset';
var constellationNodes = [];
var nodeNames = {};

function startConstellationListeners(){
  web3.shh.filter({"topics":["Constellation"]}).watch(function(err, msg) {
    if(err){console.log("ERROR:", err);};
    var message = util.Hex2a(msg.payload);
    console.log('Message:', message);
    if(message.indexOf('request|publicKey') >= 0){
      getThisNodesConstellationPubKey(function(publicKey){
        var message = 'response|publicKey|'+publicKey;
        var hexString = new Buffer(message).toString('hex');
        web3.shh.post({
          "topics": ["Constellation"],
          "from": myId,
          "payload": hexString,
          "ttl": 10,
          "workToProve": 1
        }, function(err, res){
          if(err){console.log('err', err);}
        });
      });
    } else if(message.indexOf('response|publicKey') >= 0){
      // TODO: add check that this is a new constellation node
      var publicKey = message.substring('response|publicKey|'.length+1)
      var constellationNode = {
        id: msg.from,
        publicKey: publicKey
      };
      constellationNodes.push(constellationNode);
    }
  });
}

function startNodeNameListeners(){
  web3.shh.filter({"topics":["NodeName"]}).watch(function(err, msg) {
    if(err){console.log("ERROR:", err);};
    var message = util.Hex2a(msg.payload);
    console.log('Node Name Message:', message);
    if(message.indexOf('request|nodeName') >= 0){
      var response = 'response|nodeName|'+nodeIdentityName;
      console.log('nodeName:', nodeIdentityName);
      console.log('response:', response);
      var hexString = new Buffer(response).toString('hex');
      web3.shh.post({
        "topics": ["NodeName"],
        "from": myId,
        "payload": hexString,
        "ttl": 10,
        "workToProve": 1
      }, function(err, res){
        if(err){console.log('err', err);}
      });
    } else if(message.indexOf('response|nodeName') >= 0){
      // TODO: add check that this is a new node name
      var nodeName = message.substring('response|nodeName|'.length+1);
      nodeNames[msg.from] = nodeName;
    }
  });
}

function getThisNodesConstellationPubKey(cb){
  fs.readFile('../QuorumNetworkManager/Constellation/node.pub', function read(err, data) {
    if (err) { console.log('ERROR:', err); }
    var publicKey = new Buffer(data).toString();
   cb(publicKey);
  });
}

function requestConstellationKeys(cb){
  var message = 'request|publicKey';
  var hexString = new Buffer(message).toString('hex');
  web3.shh.post({
    "topics": ["Constellation"],
    "from": myId,
    "payload": hexString,
    "ttl": 10,
    "workToProve": 1
  }, function(err, res){
    if(err){console.log('err', err);}
    cb();
  });
}

function displayConstellationKeys(cb){
  console.log('Known constellation keys:');
  for(var i in constellationNodes){
    var node = constellationNodes[i];
    var name = nodeNames[node.id];
    console.log(node.publicKey + ' | ' + name);
  }
  cb();
}

function setNodeName(cb){
  prompt.get(['name'], function(err, node){
    nodeIdentityName = node.name;
    cb();
  });
}

function requestNodeNames(cb){
  var message = 'request|nodeName';
  var hexString = new Buffer(message).toString('hex');
  web3.shh.post({
    "topics": ["NodeName"],
    "from": myId,
    "payload": hexString,
    "ttl": 10,
    "workToProve": 1
  }, function(err, res){
    if(err){console.log('err', err);}
    cb();
  });
}

prompt.start();
function menu(){
  console.log('1) Set node name');
  console.log('2) Get other node names');
  console.log('3) Request other nodes\' constellation keys');
  console.log('4) Display known constellation keys');
  console.log('0) Quit');
  prompt.get(['option'], function (err, o) {
    if(o.option == 1){
      setNodeName(function(){
        menu();
      });
    } else if(o.option == 2){
      requestNodeNames(function(){
        menu();
      });
    } else if(o.option == 3){
      requestConstellationKeys(function(){
        menu();
      });
    } else if(o.option == 4){
      displayConstellationKeys(function(){
        menu();
      });
    } else if(o.option == 0){
      console.log('Quiting');
      return;
    } else {
      menu();
    }
  });
}

startConstellationListeners();
startNodeNameListeners();
menu();
<|endoftext|>


<commit_before>(function () {
    "use strict";
    /*global gpf, xhrGet*/

    function _newLine (codeElement) {
        var line = document.createElement("div"),
            parts = [].slice.call(codeElement.querySelectorAll("code > span"), 0);
        if (0 < parts.length) {
            parts.forEach(function (part) {
                line.appendChild(part);
            });
            line.setAttribute("class", "line");
            codeElement.appendChild(line);
        }
    }

    function _onTokenFound (event) {
        var me = this, //eslint-disable-line no-invalid-this
            type = event.type(),
            token = event.get("token");
        if ("space" === type) {
            // Trim any space token before the first non space one
            if (!me.hasChildNodes()) {
                return;
            }
            // Replace tabs with 4 spaces
            token = gpf.replaceEx(token, {
                "\t": "    "
            });
        }
        token.split("\n").forEach(function (text, index) {
            var tag;
            if (0 < index) {
                _newLine(me);
            }
            // Concatenate to the code element
            tag = document.createElement("span");
            tag.className = type;
            tag.appendChild(document.createTextNode(text));
            me.appendChild(tag);
        });
    }

    function _reformatCode (codeElement) {
        var content = codeElement.innerHTML
                .replace(/(<)/g, "<")
                .replace(/(>)/g, ">")
                .replace(/(&)/g, "&");
        codeElement.innerHTML = ""; // Easy way to clear current content
        gpf.js.tokenize.apply(codeElement, [content, _onTokenFound]);
        _newLine(codeElement); // potential last line
    }

    function findCurrentInLine (line, column) {
        var pos = column,
            current = line.firstChild;
        while (current && current.textContent.length < pos) {
            pos -= current.textContent.length;
            current = current.nextSibling;
        }
        if (!current) {
            current = document.createElement("span");
            current.className = "space";
            current.innerHTML = " ";
            line.appendChild(current);
        }
        return current;
    }

    function _showEslintErrors (codeElement, messages) {
        messages.forEach(function (message) {
            var line = codeElement.querySelectorAll("div.line")[message.line - 1],
                current = findCurrentInLine(line, message.column),
                eslintData;
            line.className += " eslint-error";
            current.className += " eslint-error";
            eslintData = current.getAttribute("data-eslint");
            if (eslintData) {
                eslintData = JSON.parse(eslintData);
            } else {
                eslintData = [];
            }
            eslintData.push({
                severity: message.severity,
                ruleId: message.ruleId,
                message: message.message
            });
            current.setAttribute("data-eslint", JSON.stringify(eslintData));
        });
    }

    function _onClick (event) {
        var eslintData = event.target.getAttribute("data-eslint"),
            eslintPopup = document.getElementById("eslint"),
            clientWidth,
            x;
        if (eslintData) {
            eslintPopup.innerHTML = JSON.parse(eslintData).map(function (message) {
                return "" + message.message.replace(/ /g, " ") + "";
            }).join("
");
            x = event.pageX;
            clientWidth = document.body.scrollWidth;
            eslintPopup.className = "";
            if (x + eslintPopup.clientWidth > clientWidth) {
                x = clientWidth - eslintPopup.clientWidth - 16;
            }
            eslintPopup.setAttribute("style", "left: " + x + "px; top: " + (event.pageY + 16) + "px;");
        } else {
            eslintPopup.className = "hidden";
        }
    }

    window.addEventListener("load", function () {
        var fileUrl = window.location.search.substr(1),
            eslintUrl,
            preview = document.getElementById("preview");
        if (-1 < fileUrl.indexOf("&")) {
            fileUrl = fileUrl.split("&");
            eslintUrl = fileUrl[1];
            fileUrl = fileUrl[0];
        }
        if (fileUrl) {
            xhrGet("../" + fileUrl)
                .then(function (responseText) {
                    document.title = fileUrl;
                    preview.innerHTML = responseText;
                    _reformatCode(preview);
                    if (eslintUrl) {
                        return xhrGet("../" + eslintUrl);
                    }
                    return Promise.resolve("[]"); // Empty configuration
                })
                .then(function (eslintText) {
                    var fileName = fileUrl.split("/").pop(),
                        fileNameLength = fileName.length; // last
                    JSON.parse(eslintText).every(function (data) {
                        // Match the filename only
                        if (data.filePath.indexOf(fileName) === data.filePath.length - fileNameLength) {
                            _showEslintErrors(preview, data.messages);
                            document.addEventListener("click", _onClick);
                            return false;
                        }
                        return true;
                    });
                });
        }
    });

}());
<commit_msg>Adds filename background<commit_after>(function () {
    "use strict";
    /*global gpf, xhrGet*/

    function _newLine (codeElement) {
        var line = document.createElement("div"),
            parts = [].slice.call(codeElement.querySelectorAll("code > span"), 0);
        if (0 < parts.length) {
            parts.forEach(function (part) {
                line.appendChild(part);
            });
            line.setAttribute("class", "line");
            codeElement.appendChild(line);
        }
    }

    function _onTokenFound (event) {
        var me = this, //eslint-disable-line no-invalid-this
            type = event.type(),
            token = event.get("token");
        if ("space" === type) {
            // Trim any space token before the first non space one
            if (!me.hasChildNodes()) {
                return;
            }
            // Replace tabs with 4 spaces
            token = gpf.replaceEx(token, {
                "\t": "    "
            });
        }
        token.split("\n").forEach(function (text, index) {
            var tag;
            if (0 < index) {
                _newLine(me);
            }
            // Concatenate to the code element
            tag = document.createElement("span");
            tag.className = type;
            tag.appendChild(document.createTextNode(text));
            me.appendChild(tag);
        });
    }

    function _reformatCode (codeElement) {
        var content = codeElement.innerHTML
                .replace(/(<)/g, "<")
                .replace(/(>)/g, ">")
                .replace(/(&)/g, "&");
        codeElement.innerHTML = ""; // Easy way to clear current content
        gpf.js.tokenize.apply(codeElement, [content, _onTokenFound]);
        _newLine(codeElement); // potential last line
    }

    function findCurrentInLine (line, column) {
        var pos = column,
            current = line.firstChild;
        while (current && current.textContent.length < pos) {
            pos -= current.textContent.length;
            current = current.nextSibling;
        }
        if (!current) {
            current = document.createElement("span");
            current.className = "space";
            current.innerHTML = " ";
            line.appendChild(current);
        }
        return current;
    }

    function _showEslintErrors (codeElement, messages) {
        messages.forEach(function (message) {
            var line = codeElement.querySelectorAll("div.line")[message.line - 1],
                current = findCurrentInLine(line, message.column),
                eslintData;
            line.className += " eslint-error";
            current.className += " eslint-error";
            eslintData = current.getAttribute("data-eslint");
            if (eslintData) {
                eslintData = JSON.parse(eslintData);
            } else {
                eslintData = [];
            }
            eslintData.push({
                severity: message.severity,
                ruleId: message.ruleId,
                message: message.message
            });
            current.setAttribute("data-eslint", JSON.stringify(eslintData));
        });
    }

    function _onClick (event) {
        var eslintData = event.target.getAttribute("data-eslint"),
            eslintPopup = document.getElementById("eslint"),
            clientWidth,
            x;
        if (eslintData) {
            eslintPopup.innerHTML = JSON.parse(eslintData).map(function (message) {
                return "" + message.message.replace(/ /g, " ") + "";
            }).join("
");
            x = event.pageX;
            clientWidth = document.body.scrollWidth;
            eslintPopup.className = "";
            if (x + eslintPopup.clientWidth > clientWidth) {
                x = clientWidth - eslintPopup.clientWidth - 16;
            }
            eslintPopup.setAttribute("style", "left: " + x + "px; top: " + (event.pageY + 16) + "px;");
        } else {
            eslintPopup.className = "hidden";
        }
    }

    window.addEventListener("load", function () {
        var fileUrl = window.location.search.substr(1),
            eslintUrl,
            preview = document.getElementById("preview");
        if (-1 < fileUrl.indexOf("&")) {
            fileUrl = fileUrl.split("&");
            eslintUrl = fileUrl[1];
            fileUrl = fileUrl[0];
        }
        document.getElementById("filename").innerHTML = fileUrl;
        if (fileUrl) {
            xhrGet("../" + fileUrl)
                .then(function (responseText) {
                    document.title = fileUrl;
                    preview.innerHTML = responseText;
                    _reformatCode(preview);
                    if (eslintUrl) {
                        return xhrGet("../" + eslintUrl);
                    }
                    return Promise.resolve("[]"); // Empty configuration
                })
                .then(function (eslintText) {
                    var fileName = fileUrl.split("/").pop(),
                        fileNameLength = fileName.length; // last
                    JSON.parse(eslintText).every(function (data) {
                        // Match the filename only
                        if (data.filePath.indexOf(fileName) === data.filePath.length - fileNameLength) {
                            _showEslintErrors(preview, data.messages);
                            document.addEventListener("click", _onClick);
                            return false;
                        }
                        return true;
                    });
                });
        }
    });

}());
<|endoftext|>


<commit_before>'use strict';

var browserify, browserifyTask, browserSync, watchify, bundleLogger, gulp, handleErrors, source, buffer, sourcemaps, config, wrap;

browserify = require('browserify');
browserSync = require('browser-sync');
watchify = require('watchify');
bundleLogger = require('../util/bundleLogger');
gulp = require('gulp');
handleErrors = require('../util/handleErrors');
sourcemaps = require('gulp-sourcemaps');
source = require('vinyl-source-stream');
buffer = require('vinyl-buffer');
config = require('../config').browserify;
wrap = require('gulp-wrap');

browserifyTask = function(callback, devMode) {
  var bundleQueue, browserifyThis;

  bundleQueue = config.bundleConfigs.length;
  browserifyThis = function(bundleConfig) {
    var browserifyLoader, bundle, reportFinished;

    if (devMode) {
      _.extend(bundleConfig, watchify.args, { debug: true });
      bundleConfig = _.omit(bundleConfig, ['external', 'require']);
    }

    browserifyLoader = browserify(bundleConfig);

    bundle = function() {
      bundleLogger.start(bundleConfig.outputName);

      return browserifyLoader.bundle()
        .on('error', handleErrors)
        .pipe(source(bundleConfig.outputName))
        .pipe(buffer())
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(sourcemaps.write('./'))
        .pipe(wrap({ src: bundleConfig.template }))
        .pipe(gulp.dest(bundleConfig.dest))
        .on('end', reportFinished)
        .pipe(browserSync.reload({stream:true}));
    };

    if (devMode) {

      browserifyLoader = watchify(browserifyLoader);
      browserifyLoader.on('update', bundle);
      bundleLogger.watch(bundleConfig.outputName);
    } else {
      if(bundleConfig.require) {
        browserifyLoader.require(bundleConfig.require);
      }

      if(bundleConfig.external) {
        browserifyLoader.external(bundleConfig.external);
      }
    }

    reportFinished = function() {
      bundleLogger.end(bundleConfig.outputName);

      if (bundleQueue) {
        bundleQueue--;

        if (bundleQueue === 0) {
          callback();
        }
      }
    };

    return bundle();
  };

  config.bundleConfigs.forEach(browserifyThis);
};

gulp.task('browserify', browserifyTask);

module.exports = browserifyTask;
<commit_msg>added transform to browserify task<commit_after>'use strict';

var browserify, browserifyTask, browserSync, watchify, bundleLogger, gulp, handleErrors, source, buffer, sourcemaps, config, wrap, to5ify;

browserify = require('browserify');
browserSync = require('browser-sync');
watchify = require('watchify');
bundleLogger = require('../util/bundleLogger');
gulp = require('gulp');
handleErrors = require('../util/handleErrors');
sourcemaps = require('gulp-sourcemaps');
source = require('vinyl-source-stream');
buffer = require('vinyl-buffer');
config = require('../config').browserify;
wrap = require('gulp-wrap');
to5ify = require('6to5ify');

browserifyTask = function(callback, devMode) {
  var bundleQueue, browserifyThis;

  bundleQueue = config.bundleConfigs.length;
  browserifyThis = function(bundleConfig) {
    var browserifyLoader, bundle, reportFinished;

    if (devMode) {
      _.extend(bundleConfig, watchify.args, { debug: true });
      bundleConfig = _.omit(bundleConfig, ['external', 'require']);
    }

    browserifyLoader = browserify(bundleConfig);

    bundle = function() {
      bundleLogger.start(bundleConfig.outputName);

      return browserifyLoader.transform('to5ify')
        .bundle()
        .on('error', handleErrors)
        .pipe(source(bundleConfig.outputName))
        .pipe(buffer())
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(sourcemaps.write('./'))
        .pipe(wrap({ src: bundleConfig.template }))
        .pipe(gulp.dest(bundleConfig.dest))
        .on('end', reportFinished)
        .pipe(browserSync.reload({stream:true}));
    };

    if (devMode) {

      browserifyLoader = watchify(browserifyLoader);
      browserifyLoader.on('update', bundle);
      bundleLogger.watch(bundleConfig.outputName);
    } else {
      if(bundleConfig.require) {
        browserifyLoader.require(bundleConfig.require);
      }

      if(bundleConfig.external) {
        browserifyLoader.external(bundleConfig.external);
      }
    }

    reportFinished = function() {
      bundleLogger.end(bundleConfig.outputName);

      if (bundleQueue) {
        bundleQueue--;

        if (bundleQueue === 0) {
          callback();
        }
      }
    };

    return bundle();
  };

  config.bundleConfigs.forEach(browserifyThis);
};

gulp.task('browserify', browserifyTask);

module.exports = browserifyTask;
<|endoftext|>


<commit_before>import nodeResolve from 'rollup-plugin-node-resolve';
import invariantPlugin from 'rollup-plugin-invariant';
import { terser as minify } from 'rollup-plugin-terser';
import fs from 'fs';

import packageJson from '../package.json';

const distDir = './dist';

const globals = {
  'tslib': 'tslib',
  'ts-invariant': 'invariant',
  'symbol-observable': '$$observable',
  'graphql/language/printer': 'print',
  optimism: 'optimism',
  'graphql/language/visitor': 'visitor',
  'graphql/language/printer': 'printer',
  'graphql/execution/execute': 'execute',
  'fast-json-stable-stringify': 'stringify',
  '@wry/equality': 'wryEquality',
  graphql: 'graphql',
  react: 'React',
  'zen-observable': 'Observable'
};

const hasOwn = Object.prototype.hasOwnProperty;

function external(id) {
  return hasOwn.call(globals, id);
}

function prepareESM() {
  return {
    input: packageJson.module,
    external,
    output: {
      dir: distDir,
      format: 'esm',
      sourcemap: true,
    },
    // The purpose of this job is to ensure each `./dist` ESM file is run
    // through the `invariantPlugin`, with any resulting changes added
    // directly back into each ESM file. By setting `preserveModules`
    // to `true`, we're making sure Rollup doesn't attempt to create a single
    // combined ESM bundle with the final result of running this job.
    preserveModules: true,
    plugins: [
      nodeResolve(),
      invariantPlugin({
        // Instead of completely stripping InvariantError messages in
        // production, this option assigns a numeric code to the
        // production version of each error (unique to the call/throw
        // location), which makes it much easier to trace production
        // errors back to the unminified code where they were thrown,
        // where the full error string can be found. See #4519.
        errorCodes: true,
      }),
    ]
  };
}

function prepareCJS() {
  return {
    input: packageJson.module,
    external,
    output: {
      file: packageJson.main,
      format: 'cjs',
      sourcemap: true,
      exports: 'named'
    }
  }
}

function prepareCJSMinified() {
  return {
    input: packageJson.main,
    output: {
      file: packageJson.main.replace('.js', '.min.js'),
      format: 'cjs',
    },
    plugins: [
      minify({
        mangle: {
          toplevel: true,
        },
        compress: {
          global_defs: {
            '@process.env.NODE_ENV': JSON.stringify('production'),
          },
        },
      }),
    ],
  };
}

// Build a separate CJS only `testing.js` bundle, that includes React
// testing utilities like `MockedProvider` (testing utilities are kept out of
// the main `apollo-client` bundle). This bundle can be accessed directly
// like:
//
// import { MockedProvider } from '@apollo/client/testing';
//
// Note: The `ApolloProvider` reference is marked as being global so it can
// then be replaced with a hard coded path to the `apollo-client.cjs.js`
// bundle. This is done to ensure that when using this bundle `MockedProvider`
// always uses the same `ApolloProvider` instance as the rest of the
// application under test. This means they'll share the exact same React
// context, and be able to share the same Apollo Client instance stored in that
// context.
function prepareTesting() {
  const bundleName = 'testing';
  const apolloProviderPath = 'context/ApolloProvider';

  const testingGlobals = {
    ...globals,
    [`../../${apolloProviderPath}`]: 'ApolloProvider'
  };

  const output = {
    file: `${distDir}/${bundleName}.js`,
    format: 'cjs',
  };

  // Create a type file for the new testing bundle that points to the existing
  // `react/testing` type definitions.
  fs.writeFileSync(
    `${distDir}/${bundleName}.d.ts`,
    "export * from './react/testing';"
  );

  return {
    input: `${distDir}/react/testing/index.js`,
    external: (id) => hasOwn.call(testingGlobals, id),
    output,
    plugins: [
      nodeResolve({
        extensions: ['.js', '.jsx'],
      }),
      // Update the external ApolloProvider require in the testing bundle
      // to point to the main Apollo Client CJS bundle, to make sure the
      // testing bundle uses the exact same ApolloProvider as the main
      // AC CJS bundle. This helps ensure the same React Context is used
      // by both React testing utilities and the application under test.
      (() => {
        const bundleJs = `${bundleName}.js`;
        return {
          generateBundle(_option, bundle) {
            bundle[bundleJs].code =
              bundle[bundleJs].code.replace(
                `../${apolloProviderPath}`,
                packageJson.main.replace(distDir, '.')
              );
          }
        }
      })()
    ],
  };
}

function rollup() {
  return [
    prepareESM(),
    prepareCJS(),
    prepareCJSMinified(),
    prepareTesting()
  ];
}

export default rollup();
<commit_msg>Remove duplicate `graphql/language/printer` rollup exclusion<commit_after>import nodeResolve from 'rollup-plugin-node-resolve';
import invariantPlugin from 'rollup-plugin-invariant';
import { terser as minify } from 'rollup-plugin-terser';
import fs from 'fs';

import packageJson from '../package.json';

const distDir = './dist';

const globals = {
  'tslib': 'tslib',
  'ts-invariant': 'invariant',
  'symbol-observable': '$$observable',
  'graphql/language/printer': 'print',
  optimism: 'optimism',
  'graphql/language/visitor': 'visitor',
  'graphql/execution/execute': 'execute',
  'fast-json-stable-stringify': 'stringify',
  '@wry/equality': 'wryEquality',
  graphql: 'graphql',
  react: 'React',
  'zen-observable': 'Observable'
};

const hasOwn = Object.prototype.hasOwnProperty;

function external(id) {
  return hasOwn.call(globals, id);
}

function prepareESM() {
  return {
    input: packageJson.module,
    external,
    output: {
      dir: distDir,
      format: 'esm',
      sourcemap: true,
    },
    // The purpose of this job is to ensure each `./dist` ESM file is run
    // through the `invariantPlugin`, with any resulting changes added
    // directly back into each ESM file. By setting `preserveModules`
    // to `true`, we're making sure Rollup doesn't attempt to create a single
    // combined ESM bundle with the final result of running this job.
    preserveModules: true,
    plugins: [
      nodeResolve(),
      invariantPlugin({
        // Instead of completely stripping InvariantError messages in
        // production, this option assigns a numeric code to the
        // production version of each error (unique to the call/throw
        // location), which makes it much easier to trace production
        // errors back to the unminified code where they were thrown,
        // where the full error string can be found. See #4519.
        errorCodes: true,
      }),
    ]
  };
}

function prepareCJS() {
  return {
    input: packageJson.module,
    external,
    output: {
      file: packageJson.main,
      format: 'cjs',
      sourcemap: true,
      exports: 'named'
    }
  }
}

function prepareCJSMinified() {
  return {
    input: packageJson.main,
    output: {
      file: packageJson.main.replace('.js', '.min.js'),
      format: 'cjs',
    },
    plugins: [
      minify({
        mangle: {
          toplevel: true,
        },
        compress: {
          global_defs: {
            '@process.env.NODE_ENV': JSON.stringify('production'),
          },
        },
      }),
    ],
  };
}

// Build a separate CJS only `testing.js` bundle, that includes React
// testing utilities like `MockedProvider` (testing utilities are kept out of
// the main `apollo-client` bundle). This bundle can be accessed directly
// like:
//
// import { MockedProvider } from '@apollo/client/testing';
//
// Note: The `ApolloProvider` reference is marked as being global so it can
// then be replaced with a hard coded path to the `apollo-client.cjs.js`
// bundle. This is done to ensure that when using this bundle `MockedProvider`
// always uses the same `ApolloProvider` instance as the rest of the
// application under test. This means they'll share the exact same React
// context, and be able to share the same Apollo Client instance stored in that
// context.
function prepareTesting() {
  const bundleName = 'testing';
  const apolloProviderPath = 'context/ApolloProvider';

  const testingGlobals = {
    ...globals,
    [`../../${apolloProviderPath}`]: 'ApolloProvider'
  };

  const output = {
    file: `${distDir}/${bundleName}.js`,
    format: 'cjs',
  };

  // Create a type file for the new testing bundle that points to the existing
  // `react/testing` type definitions.
  fs.writeFileSync(
    `${distDir}/${bundleName}.d.ts`,
    "export * from './react/testing';"
  );

  return {
    input: `${distDir}/react/testing/index.js`,
    external: (id) => hasOwn.call(testingGlobals, id),
    output,
    plugins: [
      nodeResolve({
        extensions: ['.js', '.jsx'],
      }),
      // Update the external ApolloProvider require in the testing bundle
      // to point to the main Apollo Client CJS bundle, to make sure the
      // testing bundle uses the exact same ApolloProvider as the main
      // AC CJS bundle. This helps ensure the same React Context is used
      // by both React testing utilities and the application under test.
      (() => {
        const bundleJs = `${bundleName}.js`;
        return {
          generateBundle(_option, bundle) {
            bundle[bundleJs].code =
              bundle[bundleJs].code.replace(
                `../${apolloProviderPath}`,
                packageJson.main.replace(distDir, '.')
              );
          }
        }
      })()
    ],
  };
}

function rollup() {
  return [
    prepareESM(),
    prepareCJS(),
    prepareCJSMinified(),
    prepareTesting()
  ];
}

export default rollup();
<|endoftext|>


<commit_before>define(function(require) {
    var num = require('num'),
        Vector2 = num.Vector2,
        Jello = require('jello'),
        Material = Jello.Material,
        World = Jello.World,
        Entity = require('engine/map/entity'),
        MapBuilder = require('basic/mapbuilder');

  var Layer = mini.Class.subclass({
    initialize: function(name) {
      this.name = name || '';
      this.entities = [];
      this.enabled = true;

      this.zIndex = 0;
      this.scrollFactor = Vector2.One.copy();
      this.scale = Vector2.One.copy();

      this._canvas = document.createElement('canvas');
    },

    // Update all entities.
    update: function() {
      if(this.enabled) {
        env.camera.pushLayer(this);
        env.renderer.updateCanvasWorldAABB();
        if(typeof this.getWorld() !== 'undefined') {
          this.getWorld().update(1/60); // env.time.timePassed
        }

        for(var index in this.entities) {
          if(!this.entities.hasOwnProperty(index)) {
            continue;
          }

          this.entities[index].update();
        }

        if(typeof this.interaction === 'function') {
          this.interaction.call(this);
        }

        env.camera.popLayer();
      }
    },

    _prepareRendering: function() {
      this._canvas.width = env.canvas.extent.x;
      this._canvas.height = env.canvas.extent.y;
      env.renderer.renderToTexture(this._canvas);
      env.renderer.pushLayer(this);
    },

    _finishRendering: function() {
      env.renderer.popLayer();
      env.renderer.renderNormally();
    },

    draw: function(renderer) {
      if(this.enabled) {
        env.camera.pushLayer(this);
        env.renderer.updateCanvasWorldAABB();
        this._prepareRendering();

        renderer.clear();
        this._normalDraw(renderer);
        this._debugDraw(renderer);

        this._finishRendering();
        env.camera.popLayer();
      }
    },

    /**
     *
     * @private
     * @param renderer
     */
    _normalDraw: function(renderer) {
      // draw Entities
      var entityCount = this.entities.length;
      for(var i = 0; i < entityCount; i++) {
        this.entities[i].draw(renderer, this);
      }
    },

    /**
     *
     * @private
     * @param renderer
     */
    _debugDraw: function(renderer) {
      // draw Entities
      var entityCount = this.entities.length;
      for(var i = 0; i < entityCount; i++) {
        this.entities[i].debugDraw(renderer);
      }

      if(typeof this.getWorld() !== 'undefined') {
        this.getWorld().debugDraw(renderer);
      }
    },

    /*
     * Soft body engine
     */
    setWorld: function(world) {
      this.world = world;
      if(typeof Editor === 'undefined') {
        MapBuilder.setUpTestMap(this, this.world);
      }

      return this;
    },

    getWorld: function() {
      return this.world;
    },

    /*
     * Manage Entities
     */
    addEntity: function(entity) {
      this.entities.push(entity);

      return this;
    },

    getEntities: function() {
      return this.entities;
    },

    getEntityWithName: function(name) {
      return this.getEntitiesWithName(name)[0];
    },

    getEntitiesWithName: function(name) {
      return _.filter(this.entities, function(entity) {
        return entity.name == name;
      }, this);
    },

    getEntityWithTag: function(tag) {
      return this.getEntitiesWithTag(tag)[0];
    },

    getEntitiesWithTag: function(tag) {
      return _.filter(this.entities, function(entity) {
        return entity.hasTag(tag);
      }, this);
    },

    /*
     * Interactions
     */
    setInteraction: function(callback) {
      this.interaction = callback;
    },

    /*
     * Interaction and debug
     */
    initDatGui: function(mapFolder, index) {
      if(!Bloob.debug || !Bloob.debug.datGui) return;
      if(typeof this.world === 'undefined') return;
      var layerFolder = mapFolder.addFolder('Layer' + index);
      layerFolder.open();
      layerFolder.add(Material.Default, 'friction').name('Friction').min(-2).max(2).listen().step(0.1);
      layerFolder.add(Material.Default, 'elasticity').name('Elasticity').min(-2).max(2).listen().step(0.1);
      layerFolder.add(this.world.gravitation, 'x').name('Gravitation_x').listen().min(-20).max(20).step(0.01);
      layerFolder.add(this.world.gravitation, 'y').name('Gravitation_y').listen().min(-20).max(20).step(0.01);
      layerFolder.add(this, 'zIndex').listen().min(0.01).max(20).step(0.01);
      layerFolder.add(this.scrollFactor, 'x').name('ScrollFactor_x').listen();
      layerFolder.add(this.scrollFactor, 'y').name('ScrollFactor_y').listen();
      layerFolder.add(this.scale, 'x').name('Scale_x').listen();
      layerFolder.add(this.scale, 'y').name('Scale_y').listen();
    }
  });

  Layer.prototype.toJson = function() {
    var json = {
      name: this.name,
      zIndex: this.zIndex,
      scrollFactor: this.scrollFactor.toJson(),
      scale: this.scale.toJson(),
      entities: []
    };

    // Serialize world if existing.
    if(typeof this.world !== 'undefined') {
      json.world = this.world.toJson();
    }

    var entities = this.getEntities(),
        entityCount = entities.length;
    for(var i = 0; i < entityCount; i++) {
      json.entities.push(entities[i].toJson());
    }
    return json;
  };

  Layer.fromJson = function(json) {
    var layer = new Layer(json.name);

    if(typeof json.world !== 'undefined') {
      var world = World.fromJson(json.world);
      layer.setWorld(world);
    }
    if(typeof json.zIndex !== 'undefined') {
      layer.zIndex = json.zIndex;
    }
    if(typeof json.scrollFactor !== 'undefined') {
      layer.scrollFactor = Vector2.fromJson(json.scrollFactor);
    }
    if(typeof json.scale !== 'undefined') {
      layer.scale = Vector2.fromJson(json.scale);
    }

    if(typeof json.entities !== 'undefined') {
      for(var index in json.entities)
        Entity.fromJson(json.entities[index], layer.getWorld()).addToLayer(layer);
    }

    return layer;
  };

  Layer.WorldLayer = Layer;

  return Layer;
});
<commit_msg>Layer: forEach instead of for in<commit_after>define(function(require) { 'use strict';
    var num = require('num'),
        Vector2 = num.Vector2,
        Jello = require('jello'),
        Material = Jello.Material,
        World = Jello.World,
        Entity = require('engine/map/entity'),
        MapBuilder = require('basic/mapbuilder');

  var Layer = mini.Class.subclass({
    initialize: function(name) {
      this.name = name || '';
      this.entities = [];
      this.enabled = true;

      this.zIndex = 0;
      this.scrollFactor = Vector2.One.copy();
      this.scale = Vector2.One.copy();

      this._canvas = document.createElement('canvas');
    },

    // Update all entities.
    update: function() {
      if(this.enabled) {
        env.camera.pushLayer(this);
        env.renderer.updateCanvasWorldAABB();
        if(typeof this.getWorld() !== 'undefined') {
          this.getWorld().update(1/60); // env.time.timePassed
        }

        this.getEntities().forEach(function(entity) {
          entity.update();
        });

        if(typeof this.interaction === 'function') {
          this.interaction.call(this);
        }

        env.camera.popLayer();
      }
    },

    _prepareRendering: function() {
      this._canvas.width = env.canvas.extent.x;
      this._canvas.height = env.canvas.extent.y;
      env.renderer.renderToTexture(this._canvas);
      env.renderer.pushLayer(this);
    },

    _finishRendering: function() {
      env.renderer.popLayer();
      env.renderer.renderNormally();
    },

    draw: function(renderer) {
      if(this.enabled) {
        env.camera.pushLayer(this);
        env.renderer.updateCanvasWorldAABB();
        this._prepareRendering();

        renderer.clear();
        this._normalDraw(renderer);
        this._debugDraw(renderer);

        this._finishRendering();
        env.camera.popLayer();
      }
    },

    /**
     *
     * @private
     * @param renderer
     */
    _normalDraw: function(renderer) {
      // draw Entities
      this.getEntities().forEach(function(entity) {
        entity.draw(renderer, this);
      }, this);
    },

    /**
     *
     * @private
     * @param renderer
     */
    _debugDraw: function(renderer) {
      // draw Entities
      this.getEntities().forEach(function(entity) {
        entity.debugDraw(renderer);
      });

      if(typeof this.getWorld() !== 'undefined') {
        this.getWorld().debugDraw(renderer);
      }
    },

    /*
     * Soft body engine
     */
    setWorld: function(world) {
      this.world = world;
      if(typeof Editor === 'undefined') {
        MapBuilder.setUpTestMap(this, this.world);
      }

      return this;
    },

    getWorld: function() {
      return this.world;
    },

    /*
     * Manage Entities
     */
    addEntity: function(entity) {
      this.entities.push(entity);

      return this;
    },

    getEntities: function() {
      return this.entities;
    },

    getEntityWithName: function(name) {
      return this.getEntitiesWithName(name)[0];
    },

    getEntitiesWithName: function(name) {
      return _.filter(this.entities, function(entity) {
        return entity.name == name;
      }, this);
    },

    getEntityWithTag: function(tag) {
      return this.getEntitiesWithTag(tag)[0];
    },

    getEntitiesWithTag: function(tag) {
      return _.filter(this.entities, function(entity) {
        return entity.hasTag(tag);
      }, this);
    },

    /*
     * Interactions
     */
    setInteraction: function(callback) {
      this.interaction = callback;
    },

    /*
     * Interaction and debug
     */
    initDatGui: function(mapFolder, index) {
      if(!Bloob.debug || !Bloob.debug.datGui) { return; }
      if(typeof this.world === 'undefined') { return; }
      var layerFolder = mapFolder.addFolder('Layer' + index);
      layerFolder.open();
      layerFolder.add(Material.Default, 'friction').name('Friction').min(-2).max(2).listen().step(0.1);
      layerFolder.add(Material.Default, 'elasticity').name('Elasticity').min(-2).max(2).listen().step(0.1);
      layerFolder.add(this.world.gravitation, 'x').name('Gravitation_x').listen().min(-20).max(20).step(0.01);
      layerFolder.add(this.world.gravitation, 'y').name('Gravitation_y').listen().min(-20).max(20).step(0.01);
      layerFolder.add(this, 'zIndex').listen().min(0.01).max(20).step(0.01);
      layerFolder.add(this.scrollFactor, 'x').name('ScrollFactor_x').listen();
      layerFolder.add(this.scrollFactor, 'y').name('ScrollFactor_y').listen();
      layerFolder.add(this.scale, 'x').name('Scale_x').listen();
      layerFolder.add(this.scale, 'y').name('Scale_y').listen();
    }
  });

  Layer.prototype.toJson = function() {
    var json = {
      name: this.name,
      zIndex: this.zIndex,
      scrollFactor: this.scrollFactor.toJson(),
      scale: this.scale.toJson(),
      entities: []
    };

    // Serialize world if existing.
    if(typeof this.world !== 'undefined') {
      json.world = this.world.toJson();
    }

    this.getEntities().forEach(function(entity) {
      json.entities.push(entity.toJson());
    });

    return json;
  };

  Layer.fromJson = function(json) {
    var layer = new Layer(json.name);

    if(typeof json.world !== 'undefined') {
      var world = World.fromJson(json.world);
      layer.setWorld(world);
    }
    if(typeof json.zIndex !== 'undefined') {
      layer.zIndex = json.zIndex;
    }
    if(typeof json.scrollFactor !== 'undefined') {
      layer.scrollFactor = Vector2.fromJson(json.scrollFactor);
    }
    if(typeof json.scale !== 'undefined') {
      layer.scale = Vector2.fromJson(json.scale);
    }

    if(typeof json.entities !== 'undefined') {
      json.entities.forEach(function(entity) {
        Entity.fromJson(entity, layer.getWorld()).addToLayer(layer);
      });
    }

    return layer;
  };

  Layer.WorldLayer = Layer;

  return Layer;
});
<|endoftext|>


<commit_before>var util     = require('util'),
    events   = require('events'),
    extend   = require('node.extend'),
    amqp     = require('amqp'),
    when     = require('when');

var subscriber = require('../log_subscribers/eventsource/amqp_subscriber');

function onConnectionReady(deferred) {
  deferred.resolve(this.connection);

  this.emit('ready', this);
}

function onConnectionError(deferred, err) {
  // This event double fires for some reason
  if(this.connection) {
    deferred.reject(err);

    this.emit('error', err, this);

    this.connection.removeAllListeners();
    this.connection = null;
  }
}

function AmqpEventSource(options, implOptions) {
  events.EventEmitter.call(this);
  this.options = options;
  this.implOptions = implOptions || {};

  // Prevents an uncaught error exception
  this.on('error', function(){});

  // Watch for memory leaks?
  var logSub = new subscriber();
  logSub.attachTo(this);
}

function connect() {
  this.emit('beforeConnect', this);

  var deferred = when.defer();

  if(this.connection) {
    if(this.connection._connecting) {
      this.connection.once('ready', deferred.resolve);
    } else {
      deferred.resolve(this.connection);
    }
  } else {
    this.connection = amqp.createConnection(this.options, this.implOptions);
    this.connection.on('error', onConnectionError.bind(this, deferred));
    this.connection.on('ready', onConnectionReady.bind(this, deferred));
  }

  return deferred.promise;
}

function queueBind(stack) {
  var self       = this,
      deferred   = when.defer(),
      subscriber = stack.subscriber,
      fanout     = stack.fanout,
      queue      = stack.queue,
      routingKey = stack.routingKey;

  self.emit('beforeQueueBind', self, queue, fanout, subscriber);

  queue.bind(fanout, routingKey);

  queue.subscribe(function(message, headers, deliveryInfo) {
    subscriber.onMessage.call(subscriber, message, headers, deliveryInfo, routingKey);
  }).addCallback(function(subscription) {
    stack.subscription = subscription;
    self.emit('queueBind', self, fanout, subscriber);
    subscriber.onSubscribe.call(subscriber, stack);
    deferred.resolve(stack);
  });

  return deferred.promise;
}

function queueName(subscriber) {
  // Appending a random number ensures that each window/request gets its own
  // unique queue. Otherwise, queues shared between windows would get messages
  // delivered in a round-robin manner and would thus miss messages.
  var rand = process.hrtime()[1];
  return this.options.queueName || 'town_crier-'+process.env.NODE_ENV+'-'+subscriber.req.params.app_name+':'+subscriber.userId+':'+rand;
}

function onQueueDeclare(stack, deferred, queue) {
  stack.queue = queue;
  this.emit('queueDeclare', this);
  deferred.resolve(stack);
}

function queueDeclare(stack) {
  var deferred   = when.defer(),
      subscriber = stack.subscriber,
      name       = this.queueName(subscriber),
      opts       = {
        autoDelete : true,
        durable    : false,
        closeChannelOnUnsubscribe : true
      };

  this.emit('beforeQueueDeclare', this, name, subscriber);
  this.connection.queue(name, opts, onQueueDeclare.bind(this, stack, deferred), deferred.reject);

  return deferred.promise;
}

function onFanoutBind(stack, deferred) {
  this.emit('fanoutBind', this);
  deferred.resolve(stack);
}

function fanoutBind(stack) {
  var deferred     = when.defer(),
      subscriber   = stack.subscriber,
      fanout       = stack.fanout,
      exchangeName = stack.exchangeName,
      routingKey   = stack.routingKey;

  this.emit('beforeFanoutBind', this, fanout, exchangeName, subscriber);

  fanout.bind(exchangeName, routingKey, onFanoutBind.bind(this, stack, deferred), deferred.reject);

  return deferred.promise;
}

function fanoutName(exchangeName, routingKey) {
  return this.options.fanoutName || 'town_crier-'+process.env.NODE_ENV+'-'+exchangeName+'-'+routingKey;
}

function onFanoutDeclared(stack, deferred, fanout) {
  this.emit('fanoutDeclared', this);
  stack.fanout = fanout;
  deferred.resolve(stack);
}

function fanoutDeclare(stack) {
  var deferred = when.defer(),
      name     = this.fanoutName(stack.exchangeName, stack.routingKey),
      opts     = {
        type       : 'fanout',
        durable    : false,
        autoDelete : true
      };

  this.emit('beforeFanoutDeclare', this, name, stack.subscriber);
  this.connection.exchange(name, opts, onFanoutDeclared.bind(this, stack, deferred), deferred.reject);

  return deferred.promise;
}

function bindingError(subscriber, err) {
  this.emit('bindingError', this, err, subscriber);
}

function bindSubscriber(subscriber) {
  var query       = subscriber.req.query,
      exchanges   = query.exchanges,
      routingKeys = query.routingKeys;

  return function() {
    subscriber.openStream();

    exchanges.forEach(function(exchange, i) {
      var stack = {
        subscriber   : subscriber,
        exchangeName : exchange,
        routingKey   : routingKeys[i]
      };

      this.fanoutDeclare(stack)
        .then(this.fanoutBind.bind(this))
        .then(this.queueDeclare.bind(this))
        .then(this.queueBind.bind(this), bindingError.bind(this, subscriber));
    }.bind(this));
  };
}

function validateSubscriber(subscriber) {
  var exchanges = subscriber.req.query.exchanges;

  exchanges.forEach(function(exchange) {
    if( !exchange || exchange === '' || exchange.match(/^amq\./) ) {
      return !subscriber.invalid();
    }
  }.bind(this));

  return true;
}

// Declare the public API
util.inherits(AmqpEventSource, events.EventEmitter);
extend(AmqpEventSource.prototype, {
  connect            : connect,
  queueBind          : queueBind,
  queueName          : queueName,
  queueDeclare       : queueDeclare,
  fanoutBind         : fanoutBind,
  fanoutName         : fanoutName,
  fanoutDeclare      : fanoutDeclare,
  bindingError       : bindingError,
  bindSubscriber     : bindSubscriber,
  validateSubscriber : validateSubscriber
});

module.exports = AmqpEventSource;<commit_msg>Swaps the position of resolving deferrers and firing events. Events win.<commit_after>var util     = require('util'),
    events   = require('events'),
    extend   = require('node.extend'),
    amqp     = require('amqp'),
    when     = require('when');

var subscriber = require('../log_subscribers/eventsource/amqp_subscriber');

function onConnectionReady(deferred) {
  this.emit('ready', this);
  deferred.resolve(this.connection);
}

function onConnectionError(deferred, err) {
  // This event double fires for some reason
  if(this.connection) {
    deferred.reject(err);

    this.emit('error', err, this);

    this.connection.removeAllListeners();
    this.connection = null;
  }
}

function AmqpEventSource(options, implOptions) {
  events.EventEmitter.call(this);
  this.options = options;
  this.implOptions = implOptions || {};

  // Prevents an uncaught error exception
  this.on('error', function(){});

  // Watch for memory leaks?
  var logSub = new subscriber();
  logSub.attachTo(this);
}

function connect() {
  this.emit('beforeConnect', this);

  var deferred = when.defer();

  if(this.connection) {
    if(this.connection._connecting) {
      this.connection.once('ready', deferred.resolve);
    } else {
      deferred.resolve(this.connection);
    }
  } else {
    this.connection = amqp.createConnection(this.options, this.implOptions);
    this.connection.on('error', onConnectionError.bind(this, deferred));
    this.connection.on('ready', onConnectionReady.bind(this, deferred));
  }

  return deferred.promise;
}

function queueBind(stack) {
  var self       = this,
      deferred   = when.defer(),
      subscriber = stack.subscriber,
      fanout     = stack.fanout,
      queue      = stack.queue,
      routingKey = stack.routingKey;

  self.emit('beforeQueueBind', self, queue, fanout, subscriber);

  queue.bind(fanout, routingKey);

  queue.subscribe(function(message, headers, deliveryInfo) {
    subscriber.onMessage.call(subscriber, message, headers, deliveryInfo, routingKey);
  }).addCallback(function(subscription) {
    stack.subscription = subscription;
    self.emit('queueBind', self, fanout, subscriber);
    subscriber.onSubscribe.call(subscriber, stack);
    deferred.resolve(stack);
  });

  return deferred.promise;
}

function queueName(subscriber) {
  // Appending a random number ensures that each window/request gets its own
  // unique queue. Otherwise, queues shared between windows would get messages
  // delivered in a round-robin manner and would thus miss messages.
  var rand = process.hrtime()[1];
  return this.options.queueName || 'town_crier-'+process.env.NODE_ENV+'-'+subscriber.req.params.app_name+':'+subscriber.userId+':'+rand;
}

function onQueueDeclare(stack, deferred, queue) {
  stack.queue = queue;
  this.emit('queueDeclare', this);
  deferred.resolve(stack);
}

function queueDeclare(stack) {
  var deferred   = when.defer(),
      subscriber = stack.subscriber,
      name       = this.queueName(subscriber),
      opts       = {
        autoDelete : true,
        durable    : false,
        closeChannelOnUnsubscribe : true
      };

  this.emit('beforeQueueDeclare', this, name, subscriber);
  this.connection.queue(name, opts, onQueueDeclare.bind(this, stack, deferred), deferred.reject);

  return deferred.promise;
}

function onFanoutBind(stack, deferred) {
  this.emit('fanoutBind', this);
  deferred.resolve(stack);
}

function fanoutBind(stack) {
  var deferred     = when.defer(),
      subscriber   = stack.subscriber,
      fanout       = stack.fanout,
      exchangeName = stack.exchangeName,
      routingKey   = stack.routingKey;

  this.emit('beforeFanoutBind', this, fanout, exchangeName, subscriber);

  fanout.bind(exchangeName, routingKey, onFanoutBind.bind(this, stack, deferred), deferred.reject);

  return deferred.promise;
}

function fanoutName(exchangeName, routingKey) {
  return this.options.fanoutName || 'town_crier-'+process.env.NODE_ENV+'-'+exchangeName+'-'+routingKey;
}

function onFanoutDeclared(stack, deferred, fanout) {
  this.emit('fanoutDeclared', this);
  stack.fanout = fanout;
  deferred.resolve(stack);
}

function fanoutDeclare(stack) {
  var deferred = when.defer(),
      name     = this.fanoutName(stack.exchangeName, stack.routingKey),
      opts     = {
        type       : 'fanout',
        durable    : false,
        autoDelete : true
      };

  this.emit('beforeFanoutDeclare', this, name, stack.subscriber);
  this.connection.exchange(name, opts, onFanoutDeclared.bind(this, stack, deferred), deferred.reject);

  return deferred.promise;
}

function bindingError(subscriber, err) {
  this.emit('bindingError', this, err, subscriber);
}

function bindSubscriber(subscriber) {
  var query       = subscriber.req.query,
      exchanges   = query.exchanges,
      routingKeys = query.routingKeys;

  return function() {
    subscriber.openStream();

    exchanges.forEach(function(exchange, i) {
      var stack = {
        subscriber   : subscriber,
        exchangeName : exchange,
        routingKey   : routingKeys[i]
      };

      this.fanoutDeclare(stack)
        .then(this.fanoutBind.bind(this))
        .then(this.queueDeclare.bind(this))
        .then(this.queueBind.bind(this), bindingError.bind(this, subscriber));
    }.bind(this));
  };
}

function validateSubscriber(subscriber) {
  var exchanges = subscriber.req.query.exchanges;

  exchanges.forEach(function(exchange) {
    if( !exchange || exchange === '' || exchange.match(/^amq\./) ) {
      return !subscriber.invalid();
    }
  }.bind(this));

  return true;
}

// Declare the public API
util.inherits(AmqpEventSource, events.EventEmitter);
extend(AmqpEventSource.prototype, {
  connect            : connect,
  queueBind          : queueBind,
  queueName          : queueName,
  queueDeclare       : queueDeclare,
  fanoutBind         : fanoutBind,
  fanoutName         : fanoutName,
  fanoutDeclare      : fanoutDeclare,
  bindingError       : bindingError,
  bindSubscriber     : bindSubscriber,
  validateSubscriber : validateSubscriber
});

module.exports = AmqpEventSource;<|endoftext|>