<commit_before>var C2 = 65.41; // C2 note, in Hz.
var notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
var octaves = ["2", "3", "4", "5", "6", "7"];
var testFrequencies = [];
var noteMap = [
  "222E2UL",
  "214F2U",
  "206G2U",
  "198A2U",
  "190B2U",
  "182C3U",
  "174D3D",
  "166E3D",
  "158F3D",
  "150G3D",
  "143A3D",
  "135B3D",
  "127C4DL",
  "111C4UL",
  "103D4U",
  "095E4U",
  "087F4U",
  "080G4U",
  "072A4U",
  "064B4U",
  "056C5D",
  "048D5D",
  "040E5D",
  "032F5D",
  "024G5D",
  "016A5DL"
];
// The above encodes note info like so: first 3 digits represent y coord, letter represents note name
// next digit represents octave, U or D shows whether stem goes up or down, L is added at the end if a ledger line is needed.
var currentNote = "";
var currentNotePosition = 175;
var maxWhitenoise = 0;
var whitenoiseMeasurements = 0;
var notesPlayed = 0;
var staffNotes = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""];
var desiredNotes = [];
var minNote = 0;
var maxNote = 26;
var barEnabled = true; // bar in the code refers to the bar moving across the screen dictating when to play notes.
var barPosition = 135;
var barDuration = 30000;
var AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = null;
var scriptProcessor = null;
var ios = false;
for (var i = 0; i < 72; i++) {
  // Fill up the mapping between frequencies and notes
  var noteFrequency = C2 * Math.pow(2, i / 12);
  var noteName = notes[i % 12] + octaves[Math.floor(i / 12)];
  var note = { frequency: noteFrequency, name: noteName };
  testFrequencies = testFrequencies.concat([note]);
}

$(window).on("load", function() {
  var getUserMedia = navigator.getUserMedia;
  getUserMedia = getUserMedia || navigator.webkitGetUserMedia;
  getUserMedia = getUserMedia || navigator.mozGetUserMedia;
  getUserMedia.call(navigator, { audio: true }, useAudioStream, function() {
    $("#loading").text("Error: No Microphone");
  });
  if ($("#barcheckbox").prop("checked")) {
    $("[id^='bpm']").fadeOut(0);
  }
  updateNoteRange(); // Because autocomplete exists
  useBar();
});

async function useBar() {
  while (true) {
    await new Promise(resolve => setTimeout(resolve, 1));
    barPosition = parseInt(
      $("#bar")
        .css("left")
        .substring(0, 3)
    );
    if (barPosition > currentNotePosition + 25) {
      continuePractice(false);
    }
  }
}

function useAudioStream(stream) {
  audioContext = new AudioContext(); // These four lines set up microphone
  var microphone = audioContext.createMediaStreamSource(stream);
  scriptProcessor = audioContext.createScriptProcessor(1024, 1, 1); // In global namespace so Safari doesn't garbage-collect it
  scriptProcessor.connect(audioContext.destination);
  microphone.connect(scriptProcessor);
  var buffer = [];
  var sampleLengthMilliseconds = 50;
  var recording = true;
  scriptProcessor.onaudioprocess = function(event) {
    if (!recording) return;
    buffer = buffer.concat(Array.prototype.slice.call(event.inputBuffer.getChannelData(0)));
    if (buffer.length > sampleLengthMilliseconds * audioContext.sampleRate / 1000) {
      // Stop recording after sampleLengthMilliseconds.
      recording = false;
      interpretAudioStream(buffer, audioContext.sampleRate);
      buffer = [];
      setTimeout(function() {
        recording = true;
      }, 250);
    }
  };
}

$("#resume").on("click", function() {
  audioContext.resume(); // audioContext starts paused on iOS
  ios = true; // In case I need to design around iOS in the future
});

function interpretAudioStream(timeseries, sampleRate) {
  var scaleFactor = 2 * Math.PI / sampleRate; // 2pi * frequency gives the appropriate period to (co)sine.
  var frequencyAmplitudes = testFrequencies.map(function(f) {
    var frequency = f.frequency;
    var accumulator = [0, 0]; // Represent a complex number as a length-2 array [ real, imaginary ].
    for (var t = 0; t < timeseries.length; t++) {
      accumulator[0] += timeseries[t] * Math.cos(scaleFactor * frequency * t); // timeseries index / sampleRate gives the appropriate time coordinate.
      accumulator[1] += timeseries[t] * Math.sin(scaleFactor * frequency * t);
    }
    return accumulator;
  });
  var magnitudes = frequencyAmplitudes.map(function(z) {
    return z[0] * z[0] + z[1] * z[1]; // Compute the (squared) magnitudes of the complex amplitudes for each test frequency.
  });
  var maximumIndex = -1;
  var maximumMagnitude = 0;
  for (var i = 0; i < magnitudes.length; i++) {
    // Find the maximum in the list of magnitudes.
    if (magnitudes[i] <= maximumMagnitude) continue;
    maximumIndex = i;
    maximumMagnitude = magnitudes[i];
  }
  if (whitenoiseMeasurements < 5) {
    // The white noise measurements make sure that white noise doesn't register as a note.
    $("#loading").text("Calibrating microphone:" + (whitenoiseMeasurements + 1) * 100 / 5 + "%");
    whitenoiseMeasurements++;
    if (maxWhitenoise < maximumMagnitude) {
      maxWhitenoise = maximumMagnitude;
    }
  }
  if (whitenoiseMeasurements === 5) {
    // Once enough data on whitenoise is gathered, generate sheet music and start listening.
    $("#loading").text("");
    whitenoiseMeasurements++;
  }
  var average =
    magnitudes.reduce(function(a, b) {
      return a + b;
    }, 0) / magnitudes.length;
  var confidence = maximumMagnitude / average;
  var confidenceThreshold = 15; // empirical, arbitrary.
  if (confidence > confidenceThreshold && maximumMagnitude > maxWhitenoise * 3) {
    var dominantFrequency = testFrequencies[maximumIndex];
    var a = testFrequencies[maximumIndex + 12]; // The algorithm can be off by 1 octave, so need these as workarounds.
    var b = testFrequencies[maximumIndex - 12];
    console.log("expected" + currentNote + "actual" + dominantFrequency.name);
    try {
      // b.name can sometimes not exist and throw an error, so try block is used
      if ($.inArray(currentNote, [dominantFrequency, a, b]) || currentNote === "") {
        continuePractice(true);
      }
    } finally {
      return;
    }
  }
}

function startPractice() {
  barEnabled = !$("#barcheckbox").prop("checked");
  if (parseFloat($("#bpm").val())) {
    barDuration = 970000 / $("#bpm").val();
  } // Conversion of user input to animation speed.
  notesPlayed = 0;
  currentNotePosition = 150;
  $("#bar").stop();
  $("#bar").css("left", "135px");
  $("[id^='note']").fadeIn(0);
  $("[id^='sharp']").fadeOut(0);
  $("#Extra").fadeOut(0);
  $("[id^='note']").each(function(noteNum) {
    if (desiredNotes[0]) {
      // desiredNotes is an array when notes are preselected, empty when randomly generated
      if (noteNum === 15 && desiredNotes[1]) {
        if (desiredNotes[1] !== -1) {
          // Code only runs if the next note is not a rest.
          $("#Extra").fadeIn(0);
          var extraNoteInfo = noteMap[parseInt(desiredNotes[1].toString().substring(0, 2))];
          if (desiredNotes[1].includes("s")) {
            $("#sharpExtra").fadeIn(0);
          }
          $("#Extra").attr("height", 15);
          $("#Extra").css("top", parseInt(extraNoteInfo.substring(0, 3), 10) + "px");
          $("#sharpExtra").css("top", parseInt(extraNoteInfo.substring(0, 3)) - 12 + "px");
          $("#Extra").attr("src", extraNoteInfo.length === 7 ? "Images\\notewithline.png" : "Images\\note.png");
        }
      }
      if (desiredNotes[0] === -1) {
        // Only true when there should be a rest (no note)
        $("#note" + noteNum).fadeOut(0);
        var noteInfo = "127  L";
        var tempNote = "";
      } else {
        var noteInfo = noteMap[parseInt(desiredNotes[0].toString().substring(0, 2))];
        var tempNote = noteInfo.substring(3, 5);
        if (desiredNotes[0].includes("s")) {
          // Make notes sharp.
          tempNote = noteInfo.substring(3, 4) + "#" + noteInfo.substring(4, 5);
          $("#sharp" + noteNum).fadeIn(0);
        }
        var whole = desiredNotes[0].substring(2, 3) === "W" ? true : false; // Make notes whole
      }
      desiredNotes.shift(); // Remove pregenerated notes once used.
    } else {
      var noteInfo = noteMap[Math.floor(+minNote + Math.random() * (maxNote - minNote))]; // Decide which note to generate.
      var tempNote = noteInfo.substring(3, 5);
      if (noteInfo.substring(3, 4).match("[CDFGA]") && Math.random() > 0.5 && $("#_sharpcheckbox").prop("checked")) {
        // Make notes sharp.
        tempNote = noteInfo.substring(3, 4) + "#" + noteInfo.substring(4, 5);
        $("#sharp" + noteNum).fadeIn(0);
      }
      var whole = Math.random() > 0.5 && $("#wholecheckbox").prop("checked") ? true : false; // Make notes whole
    }
    staffNotes[noteNum] = tempNote;
    this.style.top = parseInt(noteInfo.substring(0, 3), 10) + "px";
    $("#sharp" + noteNum).css("top", parseInt(noteInfo.substring(0, 3)) - 12 + "px");
    if (whole) {
      this.height = 15;
      this.src = noteInfo.length === 7 ? "Images\\notewithline.png" : "Images\\note.png"; // length = 7 iff L is in noteInfo
      desiredNotes = [-1].concat(desiredNotes);
    } else {
      this.height = 70;
      if (noteInfo.substring(5, 6) === "U") {
        this.src = noteInfo.length === 7 ? "Images\\halfnoteupwithline.png" : "Images\\halfnoteupnoline.png";
        this.style.top = -54 + parseInt(noteInfo.substring(0, 3), 10) + "px";
      } else {
        this.src = noteInfo.length === 7 ? "Images\\halfnotedownwithline.png" : "Images\\halfnotedownnoline.png";
      }
    }
  });
  currentNote = staffNotes[0];
  if (barEnabled) {
    $("#bar")
      .delay(3000)
      .animate({ left: "855px" }, barDuration, "linear", startPractice);
  }
}

function continuePractice(success) {
  // success = true when note is played, false when bar passes over note without being played
  if (notesPlayed === 15 && !barEnabled) {
    startPractice();
  } else {
    var barLeniency = 216000 / barDuration;
    if (success && (!barEnabled || Math.abs(barPosition + barLeniency - currentNotePosition - 25) < 25)) {
      $("#note" + notesPlayed + ",#sharp" + notesPlayed).fadeOut(500);
      if (currentNote !== "") {
        $("#loading").text("Successfully played " + currentNote);
      }
    } else if (success) {
      return;
    } else {
      $("[id $=note" + notesPlayed + "]").prop(
        "src",
        $("[id $=note" + Math.min(notesPlayed, 15) + "]")
          .prop("src")
          .slice(0, -4) + "red.png"
      );
    }
    notesPlayed++; // Please note the order of these statements if you're going through the code in your head.
    currentNote = staffNotes[notesPlayed];
    currentNotePosition = parseInt(
      $("[id $=note" + Math.min(notesPlayed, 15) + "]")
        .css("left")
        .substring(0, 3)
    );
  }
}

$("[id$='note']").on("change", updateNoteRange);
async function updateNoteRange() {
  await new Promise(resolve => setTimeout(resolve, 5)); // Display glitches pop up if I don't wait a few milliseconds.
  minNote = $("#minnote").val();
  maxNote = $("#maxnote").val();
  if (+minNote > +maxNote) {
    $("#maxnote").val(+minNote + 1);
    updateNoteRange();
  }
  $("#minnotedisplay").text("Lowest note: " + noteMap[minNote].substring(3, 5));
  $("#maxnotedisplay").text("Highest note: E2"); // Displayed iff maxNote === 0
  $("#maxnotedisplay").text("Highest note: " + noteMap[maxNote - 1].substring(3, 5));
}

$("#barcheckbox").on("click", function() {
  if (!$("#barcheckbox").prop("checked")) {
    $("[id^='bpm']").fadeIn(0);
  } else {
    $("[id^='bpm']").fadeOut(0);
  }
});

$("#playmusic").on("click", function() {
  switch ($("#music").val()) {
    case "Random":
      desiredNotes = [];
      startPractice();
      break;
    case "Ode to Joy":
      desiredNotes = Object.assign(desiredNotes, window.odeToJoyConverted);
      startPractice();
      break;
    case "Fur Elise":
      desiredNotes = Object.assign(desiredNotes, window.furEliseConverted);
      startPractice();
      break;
    default:
      return;
  }
});
<commit_msg>bugfixes and unspaghettifying<commit_after>var AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = null;
var scriptProcessor = null;
const C2 = 65.41; // C2 note, in Hz.
const notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
const octaves = ["2", "3", "4", "5", "6", "7"];
var testFrequencies = [];
var ios = false;
for (var i = 0; i < 72; i++) {
  // Fill up the mapping between frequencies and notes
  var noteFrequency = C2 * Math.pow(2, i / 12);
  var noteName = notes[i % 12] + octaves[Math.floor(i / 12)];
  var note = { frequency: noteFrequency, name: noteName };
  testFrequencies = testFrequencies.concat([note]);
}
const noteMap = [
  "222E2UL",
  "214F2U",
  "206G2U",
  "198A2U",
  "190B2U",
  "182C3U",
  "174D3D",
  "166E3D",
  "158F3D",
  "150G3D",
  "143A3D",
  "135B3D",
  "127C4DL",
  "111C4UL",
  "103D4U",
  "095E4U",
  "087F4U",
  "080G4U",
  "072A4U",
  "064B4U",
  "056C5D",
  "048D5D",
  "040E5D",
  "032F5D",
  "024G5D",
  "016A5DL"
];
// The above encodes note info like so: first 3 digits represent y coord, letter represents note name
// next digit represents octave, U or D shows whether stem goes up or down, L is added at the end if a ledger line is needed.
var maxWhitenoise = 0;
var whitenoiseMeasurements = 0;
var currentNote = "";
var currentNotePosition = 175;
var notesPlayed = 0;
var staffNotes = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""];
var desiredNotes = [];
var minNote = 0;
var maxNote = 26;
var barEnabled = true; // bar in the code refers to the bar moving across the screen dictating when to play notes.
var barPosition = 135;
var barDuration = 30000;

$(window).on("load", function() {
  var getUserMedia = navigator.getUserMedia;
  getUserMedia = getUserMedia || navigator.webkitGetUserMedia;
  getUserMedia = getUserMedia || navigator.mozGetUserMedia;
  getUserMedia.call(navigator, { audio: true }, useAudioStream, function() {
    $("#loading").text("Error: No Microphone");
  });
  if ($("#barcheckbox").prop("checked")) {
    $("[id^='bpm']").fadeOut(0);
  }
  updateNoteRange(); // Because autocomplete exists
  useBar();
});

async function useBar() {
  while (true) {
    await new Promise(resolve => setTimeout(resolve, 1));
    barPosition = parseInt(
      $("#bar")
        .css("left")
        .substring(0, 3),
      10
    );
    if (barPosition > currentNotePosition + 25) {
      continuePractice(false);
    }
  }
}

function useAudioStream(stream) {
  audioContext = new AudioContext(); // These four lines set up microphone
  var microphone = audioContext.createMediaStreamSource(stream);
  scriptProcessor = audioContext.createScriptProcessor(1024, 1, 1); // In global namespace so Safari doesn't garbage-collect it
  scriptProcessor.connect(audioContext.destination);
  microphone.connect(scriptProcessor);
  var buffer = [];
  var sampleLengthMilliseconds = 50;
  var recording = true;
  scriptProcessor.onaudioprocess = function(event) {
    if (!recording) return;
    buffer = buffer.concat(Array.prototype.slice.call(event.inputBuffer.getChannelData(0)));
    if (buffer.length > sampleLengthMilliseconds * audioContext.sampleRate / 1000) {
      // Stop recording after sampleLengthMilliseconds.
      recording = false;
      interpretAudioStream(buffer, audioContext.sampleRate);
      buffer = [];
      setTimeout(function() {
        recording = true;
      }, 250);
    }
  };
}

$("#resume").on("click", function() {
  audioContext.resume(); // audioContext starts paused on iOS
  ios = true; // In case I need to design around iOS in the future
});

function interpretAudioStream(timeseries, sampleRate) {
  var scaleFactor = 2 * Math.PI / sampleRate; // 2pi * frequency gives the appropriate period to (co)sine.
  var frequencyAmplitudes = testFrequencies.map(function(f) {
    var frequency = f.frequency;
    var accumulator = [0, 0]; // Represent a complex number as a length-2 array [ real, imaginary ].
    for (var t = 0; t < timeseries.length; t++) {
      accumulator[0] += timeseries[t] * Math.cos(scaleFactor * frequency * t); // timeseries index / sampleRate gives the appropriate time coordinate.
      accumulator[1] += timeseries[t] * Math.sin(scaleFactor * frequency * t);
    }
    return accumulator;
  });
  var magnitudes = frequencyAmplitudes.map(function(z) {
    return z[0] * z[0] + z[1] * z[1]; // Compute the (squared) magnitudes of the complex amplitudes for each test frequency.
  });
  var maximumIndex = -1;
  var maximumMagnitude = 0;
  for (var i = 0; i < magnitudes.length; i++) {
    // Find the maximum in the list of magnitudes.
    if (magnitudes[i] <= maximumMagnitude) continue;
    maximumIndex = i;
    maximumMagnitude = magnitudes[i];
  }
  if (whitenoiseMeasurements < 5) {
    // The white noise measurements make sure that white noise doesn't register as a note.
    $("#loading").text("Calibrating microphone:" + (whitenoiseMeasurements + 1) * 100 / 5 + "%");
    whitenoiseMeasurements++;
    if (maxWhitenoise < maximumMagnitude) {
      maxWhitenoise = maximumMagnitude;
    }
  }
  if (whitenoiseMeasurements === 5) {
    // Once enough data on whitenoise is gathered, generate sheet music and start listening.
    $("#loading").text("");
    whitenoiseMeasurements++;
  }
  var average =
    magnitudes.reduce(function(a, b) {
      return a + b;
    }, 0) / magnitudes.length;
  var confidence = maximumMagnitude / average;
  var confidenceThreshold = 15; // empirical, arbitrary.
  if (confidence > confidenceThreshold && maximumMagnitude > maxWhitenoise * 3) {
    var dominantFrequency = testFrequencies[maximumIndex];
    var a = testFrequencies[maximumIndex + 12] || dominantFrequency; // The algorithm can be off by 1 octave, so need these as workarounds.
    var b = testFrequencies[maximumIndex - 12] || dominantFrequency; // The array indexes specified might not exist, or statement catches that.
    console.log("expected" + currentNote + "actual" + dominantFrequency.name);
    if (currentNote === "" || [dominantFrequency.name, a.name, b.name].indexOf(currentNote) > -1) {
      continuePractice(true);
    }
  }
}

function startPractice() {
  barEnabled = !$("#barcheckbox").prop("checked");
  if (parseFloat($("#bpm").val())) {
    barDuration = 970000 / $("#bpm").val();
  } // Conversion of user input to animation speed.
  notesPlayed = 0;
  currentNotePosition = 150;
  $("#bar").stop();
  $("#bar").css("left", "135px");
  $("[id^='note']").fadeIn(0);
  $("[id^='sharp']").fadeOut(0);
  $("#Extra").fadeOut(0);
  //if (!desiredNotes[1]) {
  generateRandomNotes(16);
  //}
  $("[id^='note']").each(function(noteNum) {
    if (desiredNotes[0] === -1) {
      // Only true when there should be a rest (no note)
      $("#note" + noteNum).fadeOut(0);
      var noteInfo = "127  L";
      var tempNote = "";
    } else {
      var noteInfo = noteMap[parseInt(desiredNotes[0].toString().substring(0, 2), 10)];
      var tempNote = noteInfo.substring(3, 5);
      if (desiredNotes[0].includes("s")) {
        // Make notes sharp.
        tempNote = noteInfo.substring(3, 4) + "#" + noteInfo.substring(4, 5);
        $("#sharp" + noteNum).fadeIn(0);
      }
      var whole = desiredNotes[0].substring(2, 3) === "W" ? true : false; // Make notes whole
    }
    desiredNotes.shift(); // Remove pregenerated notes once used.
    staffNotes[noteNum] = tempNote;
    this.style.top = parseInt(noteInfo.substring(0, 3), 10) + "px";
    $("#sharp" + noteNum).css("top", parseInt(noteInfo.substring(0, 3), 10) - 12 + "px");
    if (whole) {
      this.height = 15;
      this.src = noteInfo.length === 7 ? "Images\\notewithline.png" : "Images\\note.png"; // length = 7 iff L is in noteInfo
      desiredNotes = [-1].concat(desiredNotes);
    } else {
      this.height = 70;
      if (noteInfo.substring(5, 6) === "U") {
        this.src = noteInfo.length === 7 ? "Images\\halfnoteupwithline.png" : "Images\\halfnoteupnoline.png";
        this.style.top = -54 + parseInt(noteInfo.substring(0, 3), 10) + "px";
      } else {
        this.src = noteInfo.length === 7 ? "Images\\halfnotedownwithline.png" : "Images\\halfnotedownnoline.png";
      }
    }
    if (noteNum === 15) {
      if (!desiredNotes[0]) {
        desiredNotes[0] = Math.floor(+minNote + Math.random() * (maxNote - minNote)) + "H";
      }
      if (desiredNotes[0] !== -1) {
        // Code only runs if the next note is not a rest.
        $("#Extra").fadeIn(0);
        var extraNoteInfo = noteMap[parseInt(desiredNotes[0].toString().substring(0, 2), 10)];
        if (desiredNotes[0].includes("s")) {
          $("#sharpExtra").fadeIn(0);
        }
        $("#Extra").attr("height", 15);
        $("#Extra").css("top", parseInt(extraNoteInfo.substring(0, 3), 10) + "px");
        $("#sharpExtra").css("top", parseInt(extraNoteInfo.substring(0, 3), 10) - 12 + "px");
        $("#Extra").attr("src", extraNoteInfo.length === 7 ? "Images\\notewithline.png" : "Images\\note.png");
      }
    }
  });
  currentNote = staffNotes[0];
  if (barEnabled) {
    $("#bar")
      .delay(3000)
      .animate({ left: "855px" }, barDuration, "linear", startPractice);
  }
}

function continuePractice(success) {
  // success = true when note is played, false when bar passes over note without being played
  if (notesPlayed === 15 && !barEnabled) {
    startPractice();
  } else {
    var barLeniency = 216000 / barDuration;
    if (success && (!barEnabled || Math.abs(barPosition + barLeniency - currentNotePosition - 25) < 25)) {
      $("#note" + notesPlayed + ",#sharp" + notesPlayed).fadeOut(500);
      if (currentNote !== "") {
        $("#loading").text("Successfully played " + currentNote);
      }
    } else if (success) {
      return;
    } else {
      $("[id $=note" + notesPlayed + "]").prop(
        "src",
        $("[id $=note" + Math.min(notesPlayed, 15) + "]")
          .prop("src")
          .slice(0, -4) + "red.png"
      );
    }
    notesPlayed++; // Please note the order of these statements if you're going through the code in your head.
    currentNote = staffNotes[notesPlayed];
    currentNotePosition = parseInt(
      $("[id $=note" + Math.min(notesPlayed, 15) + "]")
        .css("left")
        .substring(0, 3),
      10
    );
  }
}

$("[id$='note']").on("change", updateNoteRange);
async function updateNoteRange() {
  await new Promise(resolve => setTimeout(resolve, 5)); // Display glitches pop up if I don't wait a few milliseconds.
  minNote = $("#minnote").val();
  maxNote = $("#maxnote").val();
  if (+minNote > +maxNote) {
    $("#maxnote").val(+minNote + 1);
    updateNoteRange();
  }
  $("#minnotedisplay").text("Lowest note: " + noteMap[minNote].substring(3, 5));
  $("#maxnotedisplay").text("Highest note: E2"); // Displayed iff maxNote === 0
  $("#maxnotedisplay").text("Highest note: " + noteMap[maxNote - 1].substring(3, 5));
}

$("#barcheckbox").on("click", function() {
  if (!$("#barcheckbox").prop("checked")) {
    $("[id^='bpm']").fadeIn(0);
  } else {
    $("[id^='bpm']").fadeOut(0);
  }
});

$("#playmusic").on("click", function() {
  switch ($("#music").val()) {
    case "Random":
      generateRandomNotes(16);
      startPractice();
      break;
    case "Ode to Joy":
      desiredNotes = Object.assign(desiredNotes, window.odeToJoyConverted);
      startPractice();
      break;
    case "Fur Elise":
      desiredNotes = Object.assign(desiredNotes, window.furEliseConverted);
      startPractice();
      break;
    default:
      return;
  }
});

function generateRandomNotes(size) {
  for (var i = 0; i < size; i++) {
    if (desiredNotes[i] === undefined) {
      desiredNotes[i] = Math.floor(+minNote + Math.random() * (maxNote - minNote));
      if (noteMap[desiredNotes[i]].substring(3, 4).match("[CDFGA]") && Math.random() > 0.5 && $("#_sharpcheckbox").prop("checked")) {
        desiredNotes[i] += "s";
      }
      desiredNotes[i] += Math.random() > 0.5 && $("#wholecheckbox").prop("checked") ? "H" : "W";
    }
  }
}
<|endoftext|>


<commit_before>var React = require('react');
var ReactDOM = require('react-dom');
var ReactRouter = require('react-router');
var PureRenderMixin = require('react-addons-pure-render-mixin');

var browserHistory = ReactRouter.browserHistory;
var Route = ReactRouter.Route;
var Router = ReactRouter.Router;
var Link = ReactRouter.Link;

var samples = require('./sample-data');

var App = React.createClass({
  getInitialState: function() {
    return {
      "humans": {},
      "stores": {}
     };
  },
  loadSampleData: function(){
    this.setState(samples);
  },
  // Handle when user navigates to a conversation directly without first loading the index...
  componentWillMount: function(){
    if('human' in this.props.params){
      this.loadSampleData();
    }
  },
  render: function() {
    return (

        <button onClick={this.loadSampleData}>Load Sample Data</button>

          <InboxPane humans={this.state.humans} />
          {this.props.children || "Select a Conversation from the Inbox"}
          <StorePane stores={this.state.stores} />

    )
  }
});

var InboxPane = React.createClass({
  renderConvoSum: function(human){
    return <InboxItem key={human} index={human} details={this.props.humans[human]} />;
  },
  render : function() {
    return (

Inbox

              Chat Received
              Name
              Status

            {Object.keys(this.props.humans).map(this.renderConvoSum)}

    )
  }
});

var InboxItem = React.createClass({
  mixins: [PureRenderMixin],

  sortByDate: function(a, b) {
    return a.time>b.time ? -1 : a.time<b.time ? 1 : 0;
  },
  messageSummary: function(conversations){
    var lastMessage = conversations.sort(this.sortByDate)[0];
    return lastMessage.who + ' said: "' + lastMessage.text + '" @ ' + lastMessage.time.toDateString();
  },
  render: function(){
    return (

        <Link to={'/conversation/' + encodeURIComponent(this.props.index)}>{this.messageSummary(this.props.details.conversations)}</Link>
        {this.props.index}
        {this.props.details.orders.sort(this.sortByDate)[0].status}

    )
  }
});

var ConversationPane = React.createClass({
  loadSampleData: function(human){
    this.setState({conversation: samples.humans[human].conversations});
  },
  // Handle when User navigates from / to /conversation/:human
  componentWillMount: function() {
    this.loadSampleData(this.props.params.human);
  },
  // Handle when User navigates between conversations
  componentWillReceiveProps: function(nextProps) {
    this.loadSampleData(nextProps.params.human);
  },
  renderMessage: function(val){
    return <Message who={val.who} text={val.text} key={val.time.getTime()} />;
  },
  render: function() {
    return (

Conversation

{this.props.params.human}

         {this.state.conversation.reverse().map(this.renderMessage)}

    )
  }
});

var Message = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return (

{this.props.who} said: "{this.props.text}"

    )
  }
});

var StorePane = React.createClass({
  renderStore: function(store){
    return <Store key={store} index={store} details={this.props.stores[store]} />;
  },
  render: function() {
    return (

Stores & Ovens

          {Object.keys(this.props.stores).map(this.renderStore)}

    )
  }
});

var Store = React.createClass({
  mixins: [PureRenderMixin],

  getCount: function(status){
    return this.props.details.orders.filter(function(n){ return n.status === status}).length;
  },
  render: function(){
    return (

{this.props.index}

Orders Confirmed: {this.getCount("Confirmed")}

Orders In The Oven: {this.getCount("In The Oven")}

Orders Delivered: {this.getCount("Delivered")}

    )
  }
});

ReactDOM.render((
  <Router history={browserHistory}>
    <Route path="/" component={App}>
      <Route path="/conversation/:human" component={ConversationPane}></Route>
    </Route>
  </Router>
), document.querySelector('#main'))
<commit_msg>change the way conversation messages are sorted<commit_after>var React = require('react');
var ReactDOM = require('react-dom');
var ReactRouter = require('react-router');
var PureRenderMixin = require('react-addons-pure-render-mixin');

var browserHistory = ReactRouter.browserHistory;
var Route = ReactRouter.Route;
var Router = ReactRouter.Router;
var Link = ReactRouter.Link;

var samples = require('./sample-data');

var App = React.createClass({
  getInitialState: function() {
    return {
      "humans": {},
      "stores": {}
     };
  },
  loadSampleData: function(){
    this.setState(samples);
  },
  // Handle when user navigates to a conversation directly without first loading the index...
  componentWillMount: function(){
    if('human' in this.props.params){
      this.loadSampleData();
    }
  },
  render: function() {
    return (

        <button onClick={this.loadSampleData}>Load Sample Data</button>

          <InboxPane humans={this.state.humans} />
          {this.props.children || "Select a Conversation from the Inbox"}
          <StorePane stores={this.state.stores} />

    )
  }
});

var InboxPane = React.createClass({
  renderConvoSum: function(human){
    return <InboxItem key={human} index={human} details={this.props.humans[human]} />;
  },
  render : function() {
    return (

Inbox

              Chat Received
              Name
              Status

            {Object.keys(this.props.humans).map(this.renderConvoSum)}

    )
  }
});

var InboxItem = React.createClass({
  mixins: [PureRenderMixin],

  sortByDate: function(a, b) {
    return a.time>b.time ? -1 : a.time<b.time ? 1 : 0;
  },
  messageSummary: function(conversations){
    var lastMessage = conversations.sort(this.sortByDate)[0];
    return lastMessage.who + ' said: "' + lastMessage.text + '" @ ' + lastMessage.time.toDateString();
  },
  render: function(){
    return (

        <Link to={'/conversation/' + encodeURIComponent(this.props.index)}>{this.messageSummary(this.props.details.conversations)}</Link>
        {this.props.index}
        {this.props.details.orders.sort(this.sortByDate)[0].status}

    )
  }
});

var ConversationPane = React.createClass({
  loadSampleData: function(human){
    this.setState({conversation: samples.humans[human].conversations});
  },
  // Handle when User navigates from / to /conversation/:human
  componentWillMount: function() {
    this.loadSampleData(this.props.params.human);
  },
  // Handle when User navigates between conversations
  componentWillReceiveProps: function(nextProps) {
    this.loadSampleData(nextProps.params.human);
  },

  sortByDateDesc: function(a, b) {
    return a.time  b.time ? 1 : 0;
  },

  renderMessage: function(val){
    return <Message who={val.who} text={val.text} key={val.time.getTime()} />;
  },
  render: function() {
    return (

Conversation

{this.props.params.human}

         {this.state.conversation.sort(this.sortByDateDesc).map(this.renderMessage)}

    )
  }
});

var Message = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return (

{this.props.who} said: "{this.props.text}"

    )
  }
});

var StorePane = React.createClass({
  renderStore: function(store){
    return <Store key={store} index={store} details={this.props.stores[store]} />;
  },
  render: function() {
    return (

Stores & Ovens

          {Object.keys(this.props.stores).map(this.renderStore)}

    )
  }
});

var Store = React.createClass({
  mixins: [PureRenderMixin],

  getCount: function(status){
    return this.props.details.orders.filter(function(n){ return n.status === status}).length;
  },
  render: function(){
    return (

{this.props.index}

Orders Confirmed: {this.getCount("Confirmed")}

Orders In The Oven: {this.getCount("In The Oven")}

Orders Delivered: {this.getCount("Delivered")}

    )
  }
});

ReactDOM.render((
  <Router history={browserHistory}>
    <Route path="/" component={App}>
      <Route path="/conversation/:human" component={ConversationPane}></Route>
    </Route>
  </Router>
), document.querySelector('#main'))
<|endoftext|>


<commit_before>module.exports = function(build) {
	// set basic info about the repo
	build.setNameVersion("classify", "0.10.0");

	// set the url of this repo
	build.setRepoName("https://github.com/weikinhuang/Classify");

	// adds a list of files that will be parsed
	build.addSourceFile("core.js", "create.js", "mutator.static.js", "mutator.nowrap.js", "mutator.alias.js", "mutator.bind.js", "observer.js", "mutator.observable.js", "namespace.js", "export.js");

	// adds a list of unit tests files that will be run
	build.addUnitTestFile("core.js", "create.js", "mutator.static.js", "mutator.nowrap.js", "mutator.alias.js", "mutator.bind.js", "observer.js", "mutator.observable.js", "namespace.js", "export.js");

	// adds a list of benchmark tests that will be run
	build.addBenchmarkFile("create.js");

	// adds any dependencies that are required
	build.addExternalFile();

	// adds any copy, headers, footers to the js file
	build.addCopyright("copyright.js");
	build.addSourceWrap("wrap.js");

	// sets the list of environments that this code can run against
	build.enableEnvironment("node", "web");

	// set the default set of tasks that should be run by default when called with no build args
	build.setDefaultTasks("lint", "unit", "size", "clean", "concat", "min");

	// set linting options
	build.addTaskOptions("lint", {
		// run the linter on a per file basis
		perFile : false,
		// the options to run the linter with
		options : {
			latedef : true,
			noempty : true,
			undef : true,
			strict : true,
			node : true,
			browser : true,
			predef : []
		}
	});

	// set uglify minification options
	build.addTaskOptions("min", {
		strict_semicolons : false,
		unsafe : true,
		lift_vars : false,
		consolidate : false,
		mangle : {
			toplevel : false,
			defines : {},
			except : [],
			no_functions : false
		},
		squeeze : {
			make_seqs : true,
			dead_code : true
		},
		generate : {
			ascii_only : false,
			beautify : false,
			indent_level : 4,
			indent_start : 0,
			quote_keys : false,
			space_colon : false,
			inline_script : false
		},
		// function to run to modify any code before the minification process
		preparse : function(src) {
			// Previously done in sed but reimplemented here due to portability issues
			src = src.replace(/^(\s*\*\/)(.+)/m, "$1\n$2");

			var proto = (/(\w+)\s*=\s*"prototype"/).exec(src);
			if (proto) {
				src = src.replace(/\.prototype\b/g, "[" + proto[1] + "]");
			}

			return src;
		}
	});

	// set options for the documentation generator
	build.addTaskOptions("doc", {
		markdown : "README",
		html : "classifyjs.com",
		files : [ "classify.docs.js" ]
	});

	// set options for the package file generator
	build.addTaskOptions("pkg", {
		file : "package.json",
		desc : {
			name : "classifyjs",
			description : "Classify.js is a library that allows for cross platform and cross browser Object Oriented Javascript class definitions using classical inheritance and namespaces behind the prototype syntax in an easy to use interface function.",
			keywords : [ "util", "functional", "server", "client", "browser", "prototype", "object-oriented", "class", "classes", "inheritance", "abstraction" ],
			author : "Wei Kin Huang <wei@closedinterval.com>",
			version : "@VERSION",
			homepage : "http://classifyjs.com",
			repository : {
				type : "git",
				url : "https://github.com/weikinhuang/Classify.git"
			},
			bugs : {
				url : "https://github.com/weikinhuang/Classify/issues"
			},
			licenses : [ {
				type : "MIT",
				url : "https://github.com/weikinhuang/Classify/blob/master/MIT-LICENSE.txt"
			} ],
			main : "dist/classify"
		}
	});

	// set the options for running unit tests against browserstack
	build.addTaskOptions("browserstack", {
		browsers : [
		            // win - ie
		            { browser : "ie", version : "7.0", os : "win" },
		            { browser : "ie", version : "8.0", os : "win" },
		            { browser : "ie", version : "9.0", os : "win" },
		            { browser : "ie", version : "10.0", os : "win" },
		            // win - chrome
		            { browser : "chrome", version : "14.0", os : "win" },
		            { browser : "chrome", version : "17.0", os : "win" },
		            { browser : "chrome", version : "20.0", os : "win" },
		            // win - firefox
		            { browser : "firefox", version : "3.0", os : "win" },
		            { browser : "firefox", version : "3.6", os : "win" },
		            { browser : "firefox", version : "4.0", os : "win" },
		            { browser : "firefox", version : "13.0", os : "win" },
		            // win - opera
		            { browser : "opera", version : "10.0", os : "win" },
		            { browser : "opera", version : "11.6", os : "win" },
		            // win - safari
		            { browser : "safari", version : "4.0", os : "win" },
		            { browser : "safari", version : "5.1", os : "win" },
		            // mac - safari
		            { browser : "safari", version : "4.0", os : "mac" },
		            { browser : "safari", version : "5.1", os : "mac" },
		            // mac - chrome
		            { browser : "chrome", version : "19.0", os : "mac" },
		            // mac - firefox
		            { browser : "firefox", version : "5.0", os : "mac" },
		            { browser : "firefox", version : "13.0", os : "mac" },
		            // mac - opera
		            { browser : "opera", version : "11.6", os : "mac" },
		            { browser : "opera", version : "12.0", os : "mac" }
		            ]
	});
};
<commit_msg>Updated options for uglify for smaller filesize<commit_after>module.exports = function(build) {
	// set basic info about the repo
	build.setNameVersion("classify", "0.10.0");

	// set the url of this repo
	build.setRepoName("https://github.com/weikinhuang/Classify");

	// adds a list of files that will be parsed
	build.addSourceFile("core.js", "create.js", "mutator.static.js", "mutator.nowrap.js", "mutator.alias.js", "mutator.bind.js", "observer.js", "mutator.observable.js", "namespace.js", "export.js");

	// adds a list of unit tests files that will be run
	build.addUnitTestFile("core.js", "create.js", "mutator.static.js", "mutator.nowrap.js", "mutator.alias.js", "mutator.bind.js", "observer.js", "mutator.observable.js", "namespace.js", "export.js");

	// adds a list of benchmark tests that will be run
	build.addBenchmarkFile("create.js");

	// adds any dependencies that are required
	build.addExternalFile();

	// adds any copy, headers, footers to the js file
	build.addCopyright("copyright.js");
	build.addSourceWrap("wrap.js");

	// sets the list of environments that this code can run against
	build.enableEnvironment("node", "web");

	// set the default set of tasks that should be run by default when called with no build args
	build.setDefaultTasks("lint", "unit", "size", "clean", "concat", "min");

	// set linting options
	build.addTaskOptions("lint", {
		// run the linter on a per file basis
		perFile : false,
		// the options to run the linter with
		options : {
			latedef : true,
			noempty : true,
			undef : true,
			strict : true,
			node : true,
			browser : true,
			predef : []
		}
	});

	// set uglify minification options
	build.addTaskOptions("min", {
		strict_semicolons : true,
		unsafe : true,
		lift_vars : true,
		consolidate : false,
		mangle : {
			toplevel : false,
			defines : {},
			except : [],
			no_functions : false
		},
		squeeze : {
			make_seqs : true,
			dead_code : true
		},
		generate : {
			ascii_only : false,
			beautify : false,
			indent_level : 4,
			indent_start : 0,
			quote_keys : false,
			space_colon : false,
			inline_script : false
		},
		// function to run to modify any code before the minification process
		preparse : function(src) {
			// Previously done in sed but reimplemented here due to portability issues
			src = src.replace(/^(\s*\*\/)(.+)/m, "$1\n$2");

			var proto = (/(\w+)\s*=\s*"prototype"/).exec(src);
			if (proto) {
				src = src.replace(/\.prototype\b/g, "[" + proto[1] + "]");
			}

			return src;
		}
	});

	// set options for the documentation generator
	build.addTaskOptions("doc", {
		markdown : "README",
		html : "classifyjs.com",
		files : [ "classify.docs.js" ]
	});

	// set options for the package file generator
	build.addTaskOptions("pkg", {
		file : "package.json",
		desc : {
			name : "classifyjs",
			description : "Classify.js is a library that allows for cross platform and cross browser Object Oriented Javascript class definitions using classical inheritance and namespaces behind the prototype syntax in an easy to use interface function.",
			keywords : [ "util", "functional", "server", "client", "browser", "prototype", "object-oriented", "class", "classes", "inheritance", "abstraction" ],
			author : "Wei Kin Huang <wei@closedinterval.com>",
			version : "@VERSION",
			homepage : "http://classifyjs.com",
			repository : {
				type : "git",
				url : "https://github.com/weikinhuang/Classify.git"
			},
			bugs : {
				url : "https://github.com/weikinhuang/Classify/issues"
			},
			licenses : [ {
				type : "MIT",
				url : "https://github.com/weikinhuang/Classify/blob/master/MIT-LICENSE.txt"
			} ],
			main : "dist/classify"
		}
	});

	// set the options for running unit tests against browserstack
	build.addTaskOptions("browserstack", {
		browsers : [
		            // win - ie
		            { browser : "ie", version : "7.0", os : "win" },
		            { browser : "ie", version : "8.0", os : "win" },
		            { browser : "ie", version : "9.0", os : "win" },
		            { browser : "ie", version : "10.0", os : "win" },
		            // win - chrome
		            { browser : "chrome", version : "14.0", os : "win" },
		            { browser : "chrome", version : "17.0", os : "win" },
		            { browser : "chrome", version : "20.0", os : "win" },
		            // win - firefox
		            { browser : "firefox", version : "3.0", os : "win" },
		            { browser : "firefox", version : "3.6", os : "win" },
		            { browser : "firefox", version : "4.0", os : "win" },
		            { browser : "firefox", version : "13.0", os : "win" },
		            // win - opera
		            { browser : "opera", version : "10.0", os : "win" },
		            { browser : "opera", version : "11.6", os : "win" },
		            // win - safari
		            { browser : "safari", version : "4.0", os : "win" },
		            { browser : "safari", version : "5.1", os : "win" },
		            // mac - safari
		            { browser : "safari", version : "4.0", os : "mac" },
		            { browser : "safari", version : "5.1", os : "mac" },
		            // mac - chrome
		            { browser : "chrome", version : "19.0", os : "mac" },
		            // mac - firefox
		            { browser : "firefox", version : "5.0", os : "mac" },
		            { browser : "firefox", version : "13.0", os : "mac" },
		            // mac - opera
		            { browser : "opera", version : "11.6", os : "mac" },
		            { browser : "opera", version : "12.0", os : "mac" }
		            ]
	});
};
<|endoftext|>


<commit_before>var beautify,
	globalBeautify = global.js_beautify;

/* istanbul ignore next */
////#include ../node_modules/js-beautify/js/lib/beautify.js

if (IS_NODE) {
	beautify = exports.js_beautify;
	delete exports.js_beautify;

} else {
	beautify = global.js_beautify;
	global.js_beautify = globalBeautify;
}

var esprima,
	globalEsprima = global.esprima;

/* istanbul ignore next */
////#include ../node_modules/esprima/esprima.js

if (IS_NODE) {
	esprima = exports;
	module.exports =
		exports = root;

} else {
	esprima = global.esprima;
	global.esprima = globalEsprima;
}

var Escaper,
	globalEscaper = global.Escaper;

/* istanbul ignore next */
////#include ../node_modules/escaper/dist/escaper.js

if (IS_NODE) {
	Escaper = exports;
	module.exports =
		exports = root;

} else {
	Escaper = global.Escaper;
	global.Escaper = globalEscaper;
}

<commit_msg>Fixed bug with Escaper importing<commit_after>var beautify,
	globalBeautify = global.js_beautify;

/* istanbul ignore next */
////#include ../node_modules/js-beautify/js/lib/beautify.js

if (IS_NODE) {
	beautify = exports.js_beautify;
	delete exports.js_beautify;

} else {
	beautify = global.js_beautify;
	global.js_beautify = globalBeautify;
}

var esprima,
	globalEsprima = global.esprima;

/* istanbul ignore next */
////#include ../node_modules/esprima/esprima.js

if (IS_NODE) {
	esprima = exports;
	module.exports =
		exports = root;

} else {
	esprima = global.esprima;
	global.esprima = globalEsprima;
}

var Escaper,
	globalEscaper = global.Escaper;

/* istanbul ignore next */
////#include ../node_modules/escaper/dist/escaper.js

if (IS_NODE) {
	Escaper = module.exports;
	module.exports =
		exports = root;

} else {
	Escaper = global.Escaper;
	global.Escaper = globalEscaper;
}

<|endoftext|>


<commit_before>/*trying to revive it*/
var elems =
[
    {
        id : 0,
        image : "img/1-milk.png",
        price : 1,
        name : "Espresso",
        isEdit : false
    },
    {
        id : 1,
        image : "img/2-espresso.png",
        price : 1.2,
        name : "Espresso Macchiato",
        isEdit : false
    },
    {
        id : 2,
        image : "img/3-steamed-milk.png",
        price : 1.2,
        name : "Espresso con Panna",
        isEdit : false
    },
    {
        id : 3,
        image : "img/4-hot-water-espresso.png",
        price : 1.2,
        name : "Caffe Latte",
        isEdit : false
    },
    {
        id : 4,
        image : "img/5-whipped-cream-milk-syrup-espresso.png",
        price : 1.2,
        name : "Flat White",
        isEdit : false
    },
    {
        id : 5,
        image : "img/6-milk-foam-steamed.png",
        price : 1.2,
        name : "Caffe Breve",
        isEdit : false
    }
];

var Buttons = React.createClass({
    getInitialState: function(){
        return {
            EditButtonIsEnable: true,
            DoneButtonIsEnable: false,
            AddButtonIsEnable: false,
            RemoveAllButtonIsEnable: false,
            LoadTestButtonIsEnable: false
        }
    },
    handleClickEditButton: function(event)
    {
        this.setState( {
            EditButtonIsEnable: false,
            DoneButtonIsEnable: true,
            AddButtonIsEnable: true,
            RemoveAllButtonIsEnable: true,
            LoadTestButtonIsEnable: true
         } );
    },
    handleClickDoneButton: function(event)
    {
        this.setState( {
            EditButtonIsEnable: true,
            DoneButtonIsEnable: false,
            AddButtonIsEnable: false,
            RemoveAllButtonIsEnable: false,
            LoadTestButtonIsEnable: false
         } );
    },
    handleClickAddButton: function(event)
    {

    },
    handleClickRemoveAllButton: function(event)
    {

    },
    handleClickLoadTestButton: function(event)
    {

    },
   render: function() {
       return (

        <button type="button" id="EditButton"
        className={this.state.EditButtonIsEnable ? "btn btn-default navbar-btn" :"btn btn-default navbar-btn hidden"}
        onClick={this.handleClickEditButton}>Edit</button>

        <button type="button" id="DoneButton"
        className={this.state.DoneButtonIsEnable ? "btn btn-default navbar-btn" :"btn btn-default navbar-btn hidden"}
        onClick={this.handleClickDoneButton}>Done</button>

        <button type="button" id="AddButton"
        className={this.state.AddButtonIsEnable ? "btn btn-default navbar-btn" :"btn btn-default navbar-btn hidden"}
        onClick={this.handleClickAddButton}>Add</button>

        <button type="button" id="RemoveAllButton"
        className={this.state.RemoveAllButtonIsEnable ? "btn btn-default navbar-btn" :"btn btn-default navbar-btn hidden"}
        onClick={this.handleClickRemoveAllButton}>Remove all</button>

        <button type="button" id="LoadTestButton"
        className={this.state.LoadTestButtonIsEnable ? "btn btn-default navbar-btn" :"btn btn-default navbar-btn hidden"}
        onClick={this.handleClickLoadTestButton}>Load test arr</button>

    );
   }
});

var GridElem = React.createClass({

    handleNewPrice: function(event) {

    },
    render: function(image = "img/1-milk.png", price = 1, name = "Espresso", isEdit = false) {
        return (

            <button type="button" className="close hidden" aria-label="Close">×</button>

                        {this.props.name}

                        {this.props.price}
                        <input type="text" className="form-control" value={this.props.price} onChange={this.handleNewPrice}/>

        );
    }
});

var AllContent = React.createClass({
    render: function() {
        var GridElems = elems.map(elem => <GridElem key={elem.id} image={elem.image} price={elem.price} name={elem.name}/>);
        return (

            <input id="fileInput" type="file"  className="hidden" />

                    <Buttons/>

                    {GridElems}

        );
    }
});

ReactDOM.render(<AllContent/>, document.getElementById("contentSheet") );<commit_msg>add putting event in button callback<commit_after>/*trying to revive it*/
var elems =
[
    {
        id : 0,
        image : "img/1-milk.png",
        price : 1,
        name : "Espresso",
        isEdit : false
    },
    {
        id : 1,
        image : "img/2-espresso.png",
        price : 1.2,
        name : "Espresso Macchiato",
        isEdit : false
    },
    {
        id : 2,
        image : "img/3-steamed-milk.png",
        price : 1.2,
        name : "Espresso con Panna",
        isEdit : false
    },
    {
        id : 3,
        image : "img/4-hot-water-espresso.png",
        price : 1.2,
        name : "Caffe Latte",
        isEdit : false
    },
    {
        id : 4,
        image : "img/5-whipped-cream-milk-syrup-espresso.png",
        price : 1.2,
        name : "Flat White",
        isEdit : false
    },
    {
        id : 5,
        image : "img/6-milk-foam-steamed.png",
        price : 1.2,
        name : "Caffe Breve",
        isEdit : false
    }
];

var Buttons = React.createClass({
    getInitialState: function(){
        return {
            EditButtonIsEnable: true,
            DoneButtonIsEnable: false,
            AddButtonIsEnable: false,
            RemoveAllButtonIsEnable: false,
            LoadTestButtonIsEnable: false
        }
    },
    handleClickEditButton: function(event)
    {
        this.setState( {
            EditButtonIsEnable: false,
            DoneButtonIsEnable: true,
            AddButtonIsEnable: true,
            RemoveAllButtonIsEnable: true,
            LoadTestButtonIsEnable: true
         } );
    },
    handleClickDoneButton: function(event)
    {
        this.setState( {
            EditButtonIsEnable: true,
            DoneButtonIsEnable: false,
            AddButtonIsEnable: false,
            RemoveAllButtonIsEnable: false,
            LoadTestButtonIsEnable: false
         } );
    },
    handleClickAddButton: function(event)
    {

    },
    handleClickRemoveAllButton: function(event)
    {

    },
    handleClickLoadTestButton: function(event)
    {

    },
   render: function() {
       return (

        <button type="button" id="EditButton"
        className={this.state.EditButtonIsEnable ? "btn btn-default navbar-btn" :"btn btn-default navbar-btn hidden"}
        onClick={el => this.handleClickEditButton(el)}>Edit</button>

        <button type="button" id="DoneButton"
        className={this.state.DoneButtonIsEnable ? "btn btn-default navbar-btn" :"btn btn-default navbar-btn hidden"}
        onClick={el => this.handleClickDoneButton(el)}>Done</button>

        <button type="button" id="AddButton"
        className={this.state.AddButtonIsEnable ? "btn btn-default navbar-btn" :"btn btn-default navbar-btn hidden"}
        onClick={el => this.handleClickAddButton(el)}>Add</button>

        <button type="button" id="RemoveAllButton"
        className={this.state.RemoveAllButtonIsEnable ? "btn btn-default navbar-btn" :"btn btn-default navbar-btn hidden"}
        onClick={el => this.handleClickRemoveAllButton(el)}>Remove all</button>

        <button type="button" id="LoadTestButton"
        className={this.state.LoadTestButtonIsEnable ? "btn btn-default navbar-btn" :"btn btn-default navbar-btn hidden"}
        onClick={el => this.handleClickLoadTestButton(el)}>Load test arr</button>

    );
   }
});

var GridElem = React.createClass({

    handleNewPrice: function(event) {

    },
    render: function(image = "img/1-milk.png", price = 1, name = "Espresso", isEdit = false) {
        return (

            <button type="button" className="close hidden" aria-label="Close">×</button>

                        {this.props.name}

                        {this.props.price}
                        <input type="text" className="form-control" value={this.props.price} onChange={this.handleNewPrice}/>

        );
    }
});

var AllContent = React.createClass({
    render: function() {
        var GridElems = elems.map(elem => <GridElem key={elem.id} image={elem.image} price={elem.price} name={elem.name}/>);
        return (

            <input id="fileInput" type="file"  className="hidden" />

                    <Buttons/>

                    {GridElems}

        );
    }
});

ReactDOM.render(<AllContent/>, document.getElementById("contentSheet") );<|endoftext|>


<commit_before>'use strict';

// Declare app level module which depends on views, and components
var app = angular.module("NGPArchive", []);
app.controller("archiveController", function($scope) {
	$scope.tournamentList = [
	{
		title: "New Game Plus 67: Seltzer Edition",
		date: "August 23rd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1268663286479531/"
	},
	{
		title: "New Game Plus 66: T-10 Days",
		date: "August 16th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1262935230385670/"
	},
	{
		title: "New Game Plus 65: Rio Games",
		date: "August 9th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1257539087591951/"
	},
	{
		title: "New Game Plus: Teamwork Tuesday",
		date: "August 2nd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1252446108101249/"
	},
	{
		title: "New Game Plus 63: Impressionist Painters Edition",
		date: "July 26th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1247734015239125/"
	},
	{
		title: "New Game Plus 62: Gators win",
		date: "July 19th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1243261529019707/"
	},
	{
		title: "New Game Plus 61: Mystics get better seeds edition",
		date: "July 12th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1238499162829277/"
	},
	{
		title: "New Game Plus 60: America is older edition",
		date: "July 5th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1233805329965327/"
	},{
		title: "New Game Plus 59",
		date: "June 28th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1229426060403254/"
	},
	{
		title: "New Game Plus 58",
		date: "June 21st, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1224928324186361/"
	},
	{
		title: "New Game Plus 57",
		date: "June 14th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1220233234655870/"
	},
	{
		title: "New Game Plus 56",
		date: "June 7th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1215712608441266/"
	},
	{
		title: "New Game Plus 55",
		date: "May 31st, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1211045502241310/"
	},
	{
		title: "New Game Plus 54",
		date: "May 24th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1206662312679629/"
	},
	{
		title: "New Game Plus 53",
		date: "May 17th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1202045639807963/"
	},
	{
		title: "New Game Plus 52",
		date: "May 10th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1197338473612013/"
	},
	{
		title: "New Game Plus 51",
		date: "May 3rd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1192594967419697/"
	},
	{
		title: "New Game Plus 50",
		date: "April 26th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1188053421207185/"
	},
	{
		title: "New Game Plus 49",
		date: "April 12nd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1179118748767319/"
	},
	{
		title: "New Game Plus 48",
		date: "April 5th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1174331255912735/"
	},
	{
		title: "New Game Plus 47",
		date: "March 29th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1167647706581090/"
	},
	{
		title: "New Game Plus 46",
		date: "March 22nd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1159463550732839/"
	},
	{
		title: "New Game Plus 45",
		date: "March 15th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1153359794676548/"
	},
	{
		title: "New Game Plus 44",
		date: "March 8th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1148548335157694/"
	},
	{
		title: "New Game Plus 43",
		date: "March 1st, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1143930058952855/"
	},
	{
		title: "New Game Plus 42",
		date: "February 23rd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1139525522726642/"
	},
	{
		title: "New Game Plus 41 - NO COLIN POST",
		date: "February 16th, 2016",
		link: "#"
	},
	{
		title: "New Game Plus 40",
		date: "February 9th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1131327253546469/"
	},
	{
		title: "New Game Plus 39",
		date: "February 2nd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1127428363936358/"
	},
	{
		title: "New Game Plus 38",
		date: "January 26th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1123488934330301/"
	},];

    console.log($scope.tournamentList);
});
<commit_msg>New titles<commit_after>'use strict';

// Declare app level module which depends on views, and components
var app = angular.module("NGPArchive", []);
app.controller("archiveController", function($scope) {
	$scope.tournamentList = [
	{
		title: "New Game Plus 67: Seltzer Edition",
		date: "August 23rd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1268663286479531/"
	},
	{
		title: "New Game Plus 66: T-10 Days",
		date: "August 16th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1262935230385670/"
	},
	{
		title: "New Game Plus 65: Rio Games",
		date: "August 9th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1257539087591951/"
	},
	{
		title: "New Game Plus: Teamwork Tuesday",
		date: "August 2nd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1252446108101249/"
	},
	{
		title: "New Game Plus 63: Impressionist Painters Edition",
		date: "July 26th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1247734015239125/"
	},
	{
		title: "New Game Plus 62: Gators win",
		date: "July 19th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1243261529019707/"
	},
	{
		title: "New Game Plus 61: Mystics get better seeds edition",
		date: "July 12th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1238499162829277/"
	},
	{
		title: "New Game Plus 60: America is older edition",
		date: "July 5th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1233805329965327/"
	},{
		title: "New Game Plus 59: Burritos are good edition",
		date: "June 28th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1229426060403254/"
	},
	{
		title: "New Game Plus 58: Review us on Yelp!",
		date: "June 21st, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1224928324186361/"
	},
	{
		title: "New Game Plus 57: F'ing Flag Day Edition",
		date: "June 14th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1220233234655870/"
	},
	{
		title: "New Game Plus 56: Doublemint Gum!",
		date: "June 7th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1215712608441266/"
	},
	{
		title: "New Game Plus 55: Summer time and living is easy",
		date: "May 31st, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1211045502241310/"
	},
	{
		title: "New Game Plus 54: Icies rejoice; One less Peach player edition",
		date: "May 24th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1206662312679629/"
	},
	{
		title: "New Game Plus 53: Where have all the flowers gone?",
		date: "May 17th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1202045639807963/"
	},
	{
		title: "New Game Plus 52: Where's the beef?",
		date: "May 10th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1197338473612013/"
	},
	{
		title: "New Game Plus 51: It's MORPHIN TIME",
		date: "May 3rd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1192594967419697/"
	},
	{
		title: "New Game Plus 50: Let's go crazy",
		date: "April 26th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1188053421207185/"
	},
	{
		title: "New Game Plus 49: Do your taxes",
		date: "April 12nd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1179118748767319/"
	},
	{
		title: "New Game Plus 48: How do I Slox edition",
		date: "April 5th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1174331255912735/"
	},
	{
		title: "New Game Plus 47: Did France kill Mafia?",
		date: "March 29th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1167647706581090/"
	},
	{
		title: "New Game Plus 46: We love you New England Melee edition",
		date: "March 22nd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1159463550732839/"
	},
	{
		title: "New Game Plus 45 - Special Announcement Edition",
		date: "March 15th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1153359794676548/"
	},
	{
		title: "New Game Plus 44",
		date: "March 8th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1148548335157694/"
	},
	{
		title: "New Game Plus 43",
		date: "March 1st, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1143930058952855/"
	},
	{
		title: "New Game Plus 42",
		date: "February 23rd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1139525522726642/"
	},
	{
		title: "New Game Plus 41 - NO COLIN POST",
		date: "February 16th, 2016",
		link: "#"
	},
	{
		title: "New Game Plus 40",
		date: "February 9th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1131327253546469/"
	},
	{
		title: "New Game Plus 39",
		date: "February 2nd, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1127428363936358/"
	},
	{
		title: "New Game Plus 38",
		date: "January 26th, 2016",
		link: "https://www.facebook.com/groups/NewEnglandMelee/permalink/1123488934330301/"
	},];

    console.log($scope.tournamentList);
});
<|endoftext|>


<commit_before>module.exports = {
    irc: {
        server: 'irc.freenode.net',
        nickname: 'StgtJS',
        options: {
            userName: 'StgtJS',
            realName: 'StuttgartJS ircbot',
            port: 7070,
            debug: false,
            showErrors: false,
            autoRejoin: true,
            autoConnect: true,
            channels: ['#StuttgartJS', '#StuttgartJS-Links'],
            secure: true,
            selfSigned: false,
            certExpired: false,
            floodProtection: true,
            floodProtectionDelay: 1000,
            sasl: false,
            stripColors: false,
            channelPrefixes: "&#",
            messageSplit: 512
        }
    },

    plugins: {
        example: false, // disabled

        auth: {
            notify: false
        },
        cmd: true,

        help: true,

        hello: {
            salutation: 'Welcome, ',
            message: 'Send "!help" to get help'
        },

        meetup: {
            groupnames: ["stuttgartjs", "Web-Dev-BBQ-Stuttgart"],
            apiKey: '' // set -x IRCBOT_MEETUP_API_KEY 'CHANGE_IT' "
        },

        urls: {
            maxLimit: 42, // limit for rss latest
            defaultLimit: 1 // limit for rss latest
        },

        //* for #StuttgartJS
        rssStuttgartJS: {
            // only activ in this channels
            channels: ['#StuttgartJS'],
            //channels: ['#StuttgartJS', '#StuttgartJS-Links'],
            limit: 42, // limit for rss latest
            timer: 30, // after 30 pings check feeds ~60min
            feeds: [
                'http://echojs.com/rss',
                'http://feeds.feedburner.com/dailyjs?format=xml',
                'http://feeds.feedburner.com/html5rocks',
                'http://www.reddit.com/r/javascript/.rss',
                'http://howtonode.org/feed.xml',
                'http://www.planetnodejs.com/feed',
                'http://www.reddit.com/r/node/.rss',
                'https://www.joyent.com/blog/feed'
            ]
        },
        //*/

        rss: {
            // only activ in this channels, if empty than active in all channels
            channels: ['#StuttgartJS-Links'],
            maxLimit: 42, // limit for rss latest
            defaultLimit: 3, // limit for rss latest
            timer: 30, // after 120 pings check feeds  ~60min
            feeds: [
                'http://echojs.com/rss',
                'http://www.heise.de/open/news/news-atom.xml',
                'http://www.heise.de/security/news/news-atom.xml',
                'http://www.techstage.de/rss.xml',
                'http://www.heise.de/developer/rss/news-atom.xml',
                'http://feeds.feedburner.com/dailyjs?format=xml',
                'http://feeds.feedburner.com/aktuell/feeds/rss?format=xml',
                'http://feeds2.feedburner.com/codegeekz',
                'http://perfectionkills.com/feed.xml',
                'http://rss.golem.de/rss.php?feed=RSS1.0',
                'http://feeds.feedburner.com/html5rocks',
                'http://www.reddit.com/r/javascript/.rss',
                'http://www.2ality.com/feeds/posts/default',
                'https://hacks.mozilla.org/feed/',
                'http://www.smashingmagazine.com/feed/',
                'http://www.dezignmatterz.com/feed',
                'http://feeds.feedburner.com/HighScalability',
                'http://www.silicon.de/feed/',
                'http://www.drweb.de/magazin/feed/',
                'http://feeds.feedburner.com/CssTricks',
                'http://www.sitepoint.com/feed',
                'http://ariya.ofilabs.com/feed',
                'http://feeds.feedburner.com/ModernWebHQ',
                'http://feeds2.feedburner.com/tympanus',
                'http://news.centurylinklabs.com/rss',
                'http://howtonode.org/feed.xml',
                'http://marijnhaverbeke.nl/blog/feed.atom',
                'http://www.geek-week.de/feed/',
                'http://googlewebmastercentral.blogspot.com/atom.xml',
                'http://www.seo-united.de/blog/feed',
                'http://davidwalsh.name/feed',
                'http://feeds.feedburner.com/TechCrunch/',
                'http://ponyfoo.com/articles/feed',
                'http://www.planetnodejs.com/feed',
                'http://www.reddit.com/r/node/.rss',
                'http://readwrite.com/rss.xml',
                'http://www.bhorowitz.com/blog.rss',
                'http://scotch.io/feed',
                'http://www.onlinemarketingrockstars.de/feed/',
                'http://www.netzaktiv.de/feed/',
                'http://eisenbergeffect.bluespire.com/rss/',
                'http://www.gizmodo.de/feed',
                'http://javascriptweekly.com/rss/18em492a',
                'http://mobilewebweekly.co/rss/1cd436ic',
                'http://jsforallof.us/feed.xml',
                'http://grochtdreis.de/weblog/feed/',
                'http://feeds.sidebar.io/SidebarFeed',
                'http://blog.millermedeiros.com/feed/',
                'http://www.merrickchristensen.com/atom.xml',
                'http://www.heydonworks.com/feed',
                'http://www.designmadeingermany.de/feed/',
                'http://www.talentbuddy.co/blog/rss/',
                'http://javascriptweekly.com/rss/2635acpd',
                'http://angularjs.de/feed',
                'http://blogs.msdn.com/b/eternalcoding/rss.aspx',
                'http://feeds.feedburner.com/bocoup',
                'http://feeds.feedburner.com/creativebloq/',
                'http://shitformakingwebsites.com/feed/',
                'http://feeds2.feedburner.com/webresourcesdepot',
                'http://rss.badassjs.com/',
                'https://www.seroundtable.com/index.rdf',
                'http://msdn.microsoft.com/de-de/magazine/cc194384.aspx',
                'http://feeds.feedblitz.com/derickbailey',
                'http://simpleprogrammer.com/feed/',
                'http://joshuaearl.com/feed/',
                'http://de.letsseewhatworks.com/feed/',
                'http://programmingpraxis.com/feed/',
                'http://xkcd.com/atom.xml',
                'http://feeds.feedburner.com/codinghorror',
                'http://feeds2.feedburner.com/thenextweb',
                'http://www.webmonkey.com/feed/',
                'http://feeds2.feedburner.com/Webappers',
                'http://feeds.feedburner.com/webresourcesdepot?format=xml',
                'http://ajaxian.com/index.xml',
                'http://www.designfloat.com/rss.php',
                'http://design.tutsplus.com/posts.atom',
                'http://designreviver.com/feed/',
                'http://feeds2.feedburner.com/SpoonGraphics',
                'http://boxesandarrows.com/home/feed/',
                'https://www.thebestdesigns.com/rss/feed.rss',
                'http://alistapart.com/site/rss',
                'http://webdesignfromscratch.com/category/html-css/feed/',
                'http://www.456bereastreet.com/feed.xml',
                'http://feeds2.feedburner.com/ProBlogDesign',
                'http://calendar.perfplanet.com/feed/',
                'http://entreprogrammers.com/feed/',
                'http://joshowens.me/rss/',
                'http://www.internetworld.de/INTERNET-WORLD-Business-Newsfeed.html',
                'http://developer.telerik.com/feed'

            ]
        }
    },

    // all nicknames lowerCase !!
    admins: {
        '_pid': false,
        '_pid_': false,
        '_pid1': false,
        '_pid2': false,

        'drmabuse': false,
        'drmabuse_': false,

        'dypsilon': false,
        'dypsilon_': false,

        'hellomichibye': false,
        'hellomichibye_': false,

        'hobbyquaker': false,
        'hobbyquaker_': false,

        'jorin': false,
        'jorin_': false,

        'markus-': false,
        'markus-_': false,

        'xat-': false,
        'xat-_': false,

        'xorrr': false,
        'xorrr_': false

    }

};
<commit_msg>add feeds<commit_after>module.exports = {
    irc: {
        server: 'irc.freenode.net',
        nickname: 'StgtJS',
        options: {
            userName: 'StgtJS',
            realName: 'StuttgartJS ircbot',
            port: 7070,
            debug: false,
            showErrors: false,
            autoRejoin: true,
            autoConnect: true,
            channels: ['#StuttgartJS', '#StuttgartJS-Links'],
            secure: true,
            selfSigned: false,
            certExpired: false,
            floodProtection: true,
            floodProtectionDelay: 1000,
            sasl: false,
            stripColors: false,
            channelPrefixes: "&#",
            messageSplit: 512
        }
    },

    plugins: {
        example: false, // disabled

        auth: {
            notify: false
        },
        cmd: true,

        help: true,

        hello: {
            salutation: 'Welcome, ',
            message: 'Send "!help" to get help'
        },

        meetup: {
            groupnames: ["stuttgartjs", "Web-Dev-BBQ-Stuttgart"],
            apiKey: '' // set -x IRCBOT_MEETUP_API_KEY 'CHANGE_IT' "
        },

        urls: {
            maxLimit: 42, // limit for rss latest
            defaultLimit: 1 // limit for rss latest
        },

        //* for #StuttgartJS
        rssStuttgartJS: {
            // only activ in this channels
            channels: ['#StuttgartJS'],
            //channels: ['#StuttgartJS', '#StuttgartJS-Links'],
            limit: 42, // limit for rss latest
            timer: 30, // after 30 pings check feeds ~60min
            feeds: [
                'http://echojs.com/rss',
                'http://feeds.feedburner.com/dailyjs?format=xml',
                'http://feeds.feedburner.com/html5rocks',
                'http://www.reddit.com/r/javascript/.rss',
                'http://howtonode.org/feed.xml',
                'http://www.planetnodejs.com/feed',
                'http://www.reddit.com/r/node/.rss',
                'https://www.joyent.com/blog/feed'
            ]
        },
        //*/

        rss: {
            // only activ in this channels, if empty than active in all channels
            channels: ['#StuttgartJS-Links'],
            maxLimit: 42, // limit for rss latest
            defaultLimit: 3, // limit for rss latest
            timer: 30, // after 120 pings check feeds  ~60min
            feeds: [
                'http://echojs.com/rss',
                'http://www.heise.de/open/news/news-atom.xml',
                'http://www.heise.de/security/news/news-atom.xml',
                'http://www.techstage.de/rss.xml',
                'http://www.heise.de/developer/rss/news-atom.xml',
                'http://feeds.feedburner.com/dailyjs?format=xml',
                'http://feeds.feedburner.com/aktuell/feeds/rss?format=xml',
                'http://feeds2.feedburner.com/codegeekz',
                'http://perfectionkills.com/feed.xml',
                'http://rss.golem.de/rss.php?feed=RSS1.0',
                'http://feeds.feedburner.com/html5rocks',
                'http://www.reddit.com/r/javascript/.rss',
                'http://www.2ality.com/feeds/posts/default',
                'https://hacks.mozilla.org/feed/',
                'http://www.smashingmagazine.com/feed/',
                'http://www.dezignmatterz.com/feed',
                'http://feeds.feedburner.com/HighScalability',
                'http://www.silicon.de/feed/',
                'http://www.drweb.de/magazin/feed/',
                'http://feeds.feedburner.com/CssTricks',
                'http://www.sitepoint.com/feed',
                'http://ariya.ofilabs.com/feed',
                'http://feeds.feedburner.com/ModernWebHQ',
                'http://feeds2.feedburner.com/tympanus',
                'http://news.centurylinklabs.com/rss',
                'http://howtonode.org/feed.xml',
                'http://marijnhaverbeke.nl/blog/feed.atom',
                'http://www.geek-week.de/feed/',
                'http://googlewebmastercentral.blogspot.com/atom.xml',
                'http://www.seo-united.de/blog/feed',
                'http://davidwalsh.name/feed',
                'http://feeds.feedburner.com/TechCrunch/',
                'http://ponyfoo.com/articles/feed',
                'http://www.planetnodejs.com/feed',
                'http://www.reddit.com/r/node/.rss',
                'http://readwrite.com/rss.xml',
                'http://www.bhorowitz.com/blog.rss',
                'http://scotch.io/feed',
                'http://www.onlinemarketingrockstars.de/feed/',
                'http://www.netzaktiv.de/feed/',
                'http://eisenbergeffect.bluespire.com/rss/',
                'http://www.gizmodo.de/feed',
                'http://javascriptweekly.com/rss/18em492a',
                'http://mobilewebweekly.co/rss/1cd436ic',
                'http://jsforallof.us/feed.xml',
                'http://grochtdreis.de/weblog/feed/',
                'http://feeds.sidebar.io/SidebarFeed',
                'http://blog.millermedeiros.com/feed/',
                'http://www.merrickchristensen.com/atom.xml',
                'http://www.heydonworks.com/feed',
                'http://www.designmadeingermany.de/feed/',
                'http://www.talentbuddy.co/blog/rss/',
                'http://javascriptweekly.com/rss/2635acpd',
                'http://angularjs.de/feed',
                'http://blogs.msdn.com/b/eternalcoding/rss.aspx',
                'http://feeds.feedburner.com/bocoup',
                'http://feeds.feedburner.com/creativebloq/',
                'http://shitformakingwebsites.com/feed/',
                'http://feeds2.feedburner.com/webresourcesdepot',
                'http://rss.badassjs.com/',
                'https://www.seroundtable.com/index.rdf',
                'http://msdn.microsoft.com/de-de/magazine/cc194384.aspx',
                'http://feeds.feedblitz.com/derickbailey',
                'http://simpleprogrammer.com/feed/',
                'http://joshuaearl.com/feed/',
                'http://de.letsseewhatworks.com/feed/',
                'http://programmingpraxis.com/feed/',
                'http://xkcd.com/atom.xml',
                'http://feeds.feedburner.com/codinghorror',
                'http://feeds2.feedburner.com/thenextweb',
                'http://www.webmonkey.com/feed/',
                'http://feeds2.feedburner.com/Webappers',
                'http://feeds.feedburner.com/webresourcesdepot?format=xml',
                'http://ajaxian.com/index.xml',
                'http://www.designfloat.com/rss.php',
                'http://design.tutsplus.com/posts.atom',
                'http://designreviver.com/feed/',
                'http://feeds2.feedburner.com/SpoonGraphics',
                'http://boxesandarrows.com/home/feed/',
                'https://www.thebestdesigns.com/rss/feed.rss',
                'http://alistapart.com/site/rss',
                'http://webdesignfromscratch.com/category/html-css/feed/',
                'http://www.456bereastreet.com/feed.xml',
                'http://feeds2.feedburner.com/ProBlogDesign',
                'http://calendar.perfplanet.com/feed/',
                'http://entreprogrammers.com/feed/',
                'http://joshowens.me/rss/',
                'http://www.internetworld.de/INTERNET-WORLD-Business-Newsfeed.html',
                'http://developer.telerik.com/feed',
                'http://isomorphic.net/feeds/rss',
                'http://colintoh.com/blog/feed'

            ]
        }
    },

    admins: {
        '_pid': false,
        '_pid_': false,
        '_pid1': false,
        '_pid2': false,

        'drmabuse': false,
        'drmabuse_': false,

        'dypsilon': false,
        'dypsilon_': false,

        'hellomichibye': false,
        'hellomichibye_': false,

        'hobbyquaker': false,
        'hobbyquaker_': false,

        'jorin': false,
        'jorin_': false,

        'markus-': false,
        'markus-_': false,

        'xat-': false,
        'xat-_': false,

        'xorrr': false,
        'xorrr_': false

    }

};
<|endoftext|>


<commit_before>var fs        = require('fs');
var os        = require('os');
var path      = require('path');
var readline  = require('readline');

var BLAKE2s   = require('blake2s-js');
var Base58    = require('bs58');
var nacl      = require('tweetnacl');
var scrypt    = require('scrypt-async');
var zxcvbn    = require('zxcvbn');

var help = 'usage: mlck id <email> [--passphrase=<passphrase>]\n';

function sliceArguments(begin, end) {
  return Array.prototype.slice.call(sliceArguments.caller.arguments,
      begin, end);
}

function async(func) {
  var args = sliceArguments(1);
  process.nextTick(function () {
    func.apply(null, args);
  });
}

function die() {
  if (arguments.length > 0) {
    console.error.apply(console, arguments);
  }

  process.exit(1);
}

function logError(error) {
  if (error) {
    console.error(error.toString());
  }
}

function parseArgs(args) {
  // This is another cool function. It parses command line arguments of two
  // kinds: '--long-name[=<value>]' and '-n [<value>]'
  //
  // If the value is omitted, it's assumed to be a boolean true.
  //
  // You can pass in default values and a mapping of short names to long names
  // as the first and second arguments respectively.

  var rest = sliceArguments(1);

  var defaultOptions  = typeof rest[0] === 'object' && rest.shift() || {};
  var shortcuts       = typeof rest[0] === 'object' && rest.shift() || {};

  var expect = null;
  var stop = false;

  var obj = Object.create(defaultOptions);

  obj = Object.defineProperty(obj, '...', { value: [] });
  obj = Object.defineProperty(obj, '!?',  { value: [] });

  // Preprocessing.
  args = args.reduce(function (newArgs, arg) {
    if (!stop) {
      if (arg === '--') {
        stop = true;

      // Split '-xyz' into '-x', '-y', '-z'.
      } else if (arg.length > 2 && arg[0] === '-' && arg[1] !== '-') {
        arg = arg.slice(1).split('').map(function (v) { return '-' + v });
      }
    }

    return newArgs.concat(arg);
  },
  []);

  stop = false;

  return args.reduce(function (obj, arg, index) {
    var single = !stop && arg[0] === '-' && arg[1] !== '-';

    if (!(single && !(arg = shortcuts[arg]))) {
      if (!stop && arg.slice(0, 2) === '--') {
        if (arg.length > 2) {
          var eq = arg.indexOf('=');

          if (eq === -1) {
            eq = arg.length;
          }

          var name = arg.slice(2, eq);

          if (!single && !defaultOptions.hasOwnProperty(name)) {
            obj['!?'].push(arg.slice(0, eq));

            return obj;
          }

          if (single && eq === arg.length - 1) {
            obj[expect = name] = '';

            return obj;
          }

          obj[name] = typeof defaultOptions[name] === 'boolean'
              && eq === arg.length
              || arg.slice(eq + 1);

        } else {
          stop = true;
        }
      } else if (expect) {
        obj[expect] = arg;

      } else if (rest.length > 0) {
        obj[rest.shift()] = arg;

      } else {
        obj['...'].push(arg);
      }

    } else if (single) {
      obj['!?'].push(args[index]);
    }

    expect = null;

    return obj;
  },
  obj);
}

function prompt(label, quiet, callback) {
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
    throw new Error('No TTY.');
  }

  if (arguments.length > 0) {
    callback = arguments[arguments.length - 1];
    if (typeof callback !== 'function') {
      callback = null;
    }
  }

  if (typeof quiet !== 'boolean') {
    quiet = false;
  }

  if (typeof label === 'string') {
    process.stdout.write(label);
  }

  var rl = readline.createInterface({
    input: process.stdin,
    // The quiet argument is for things like passwords. It turns off standard
    // output so nothing is displayed.
    output: !quiet && process.stdout || null,
    terminal: true
  });

  rl.on('line', function (line) {
    rl.close();

    if (quiet) {
      process.stdout.write(os.EOL);
    }

    if (callback) {
      callback(null, line);
    }
  });
}

function printUsage() {
  console.error(help);
}

function checkKeyStrength(key) {
  return zxcvbn(key).entropy > 100;
}

function getScryptKey(key, salt, callback) {
  scrypt(key, salt, 17, 8, 32, 1000, function (keyBytes) {
    return callback(nacl.util.decodeBase64(keyBytes));
  },
  'base64');
}

function getKeyPair(key, salt, callback) {
  var keyHash = new BLAKE2s(32);
  keyHash.update(nacl.util.decodeUTF8(key));

  getScryptKey(keyHash.digest(), nacl.util.decodeUTF8(salt),
      function(keyBytes) {
    callback(nacl.box.keyPair.fromSecretKey(keyBytes));
  });
}

function miniLockId(publicKey) {
  var id = new Uint8Array(33);

  for (var i = 0; i < publicKey.length; i++) {
    id[i] = publicKey[i];
  }

  var hash = new BLAKE2s(1);
  hash.update(publicKey);

  id[32] = hash.digest()[0];

  return Base58.encode(id);
}

function readPassphrase(passphrase, callback) {
  if (typeof passphrase === 'function') {
    callback = passphrase;
    passphrase = null;
  }

  if (typeof passphrase === 'string') {
    async(function () {
      callback(null, passphrase);
    });
  } else {
    prompt('Passphrase: ', true, function (error, passphrase) {
      callback(error, passphrase);
    });
  }
}

function generateId(email, passphrase, callback) {
  if (!checkKeyStrength(passphrase)) {
    async(function () {
      callback('Passphrase too weak!');
    });
  }

  getKeyPair(passphrase, email, function (keyPair) {
    callback(null, miniLockId(keyPair.publicKey));
  });
}

function handleId() {
  var defaultOptions = {
    'passphrase':      null,
  };

  var shortcuts = {};

  var options = parseArgs(process.argv.slice(3), defaultOptions, shortcuts);

  if (options['!?'].length > 0) {
    die("Unknown option '" + options['!?'][0] + "'.");
  }

  var email = options['...'][0];
  var passphrase = options.passphrase;

  if (email === undefined) {
    printUsage();
    die();
  }

  readPassphrase(passphrase, function (error, passphrase) {
    if (error) {
      logError(error);
      die();
    }

    generateId(email, passphrase, function (error, id) {
      if (error) {
        logError(error);
        die();
      }

      console.log(id);
    });
  });
}

function run() {
  switch (process.argv[2]) {
  case 'id':
    handleId();
    break;
  default:
    printUsage();
    die();
  }
}

function main() {
  run();
}

if (require.main === module) {
  main();
}

exports.run = run;

// vim: et ts=2 sw=2
<commit_msg>File encryption<commit_after>var fs        = require('fs');
var os        = require('os');
var path      = require('path');
var readline  = require('readline');

var BLAKE2s   = require('blake2s-js');
var Base58    = require('bs58');
var nacl      = require('tweetnacl');
var nacl_     = require('nacl-stream');
var scrypt    = require('scrypt-async');
var zxcvbn    = require('zxcvbn');

var help = 'usage: mlck id <email> [--passphrase=<passphrase>]\n'
         + '       mlck encrypt [<id> ...]\n'
         + '                    --email=<email> [--passphrase=<passphrase>]\n'
         + '                    --file=<file>\n';

function sliceArguments(begin, end) {
  return Array.prototype.slice.call(sliceArguments.caller.arguments,
      begin, end);
}

function async(func) {
  var args = sliceArguments(1);
  process.nextTick(function () {
    func.apply(null, args);
  });
}

function die() {
  if (arguments.length > 0) {
    console.error.apply(console, arguments);
  }

  process.exit(1);
}

function logError(error) {
  if (error) {
    console.error(error.toString());
  }
}

function parseArgs(args) {
  // This is another cool function. It parses command line arguments of two
  // kinds: '--long-name[=<value>]' and '-n [<value>]'
  //
  // If the value is omitted, it's assumed to be a boolean true.
  //
  // You can pass in default values and a mapping of short names to long names
  // as the first and second arguments respectively.

  var rest = sliceArguments(1);

  var defaultOptions  = typeof rest[0] === 'object' && rest.shift() || {};
  var shortcuts       = typeof rest[0] === 'object' && rest.shift() || {};

  var expect = null;
  var stop = false;

  var obj = Object.create(defaultOptions);

  obj = Object.defineProperty(obj, '...', { value: [] });
  obj = Object.defineProperty(obj, '!?',  { value: [] });

  // Preprocessing.
  args = args.reduce(function (newArgs, arg) {
    if (!stop) {
      if (arg === '--') {
        stop = true;

      // Split '-xyz' into '-x', '-y', '-z'.
      } else if (arg.length > 2 && arg[0] === '-' && arg[1] !== '-') {
        arg = arg.slice(1).split('').map(function (v) { return '-' + v });
      }
    }

    return newArgs.concat(arg);
  },
  []);

  stop = false;

  return args.reduce(function (obj, arg, index) {
    var single = !stop && arg[0] === '-' && arg[1] !== '-';

    if (!(single && !(arg = shortcuts[arg]))) {
      if (!stop && arg.slice(0, 2) === '--') {
        if (arg.length > 2) {
          var eq = arg.indexOf('=');

          if (eq === -1) {
            eq = arg.length;
          }

          var name = arg.slice(2, eq);

          if (!single && !defaultOptions.hasOwnProperty(name)) {
            obj['!?'].push(arg.slice(0, eq));

            return obj;
          }

          if (single && eq === arg.length - 1) {
            obj[expect = name] = '';

            return obj;
          }

          obj[name] = typeof defaultOptions[name] === 'boolean'
              && eq === arg.length
              || arg.slice(eq + 1);

        } else {
          stop = true;
        }
      } else if (expect) {
        obj[expect] = arg;

      } else if (rest.length > 0) {
        obj[rest.shift()] = arg;

      } else {
        obj['...'].push(arg);
      }

    } else if (single) {
      obj['!?'].push(args[index]);
    }

    expect = null;

    return obj;
  },
  obj);
}

function slurpFile(filename, encoding, callback) {
  if (typeof encoding === 'function') {
    callback = encoding;
    encoding = null;
  }

  fs.readFile(filename, { encoding: encoding }, callback);
}

function prompt(label, quiet, callback) {
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
    throw new Error('No TTY.');
  }

  if (arguments.length > 0) {
    callback = arguments[arguments.length - 1];
    if (typeof callback !== 'function') {
      callback = null;
    }
  }

  if (typeof quiet !== 'boolean') {
    quiet = false;
  }

  if (typeof label === 'string') {
    process.stdout.write(label);
  }

  var rl = readline.createInterface({
    input: process.stdin,
    // The quiet argument is for things like passwords. It turns off standard
    // output so nothing is displayed.
    output: !quiet && process.stdout || null,
    terminal: true
  });

  rl.on('line', function (line) {
    rl.close();

    if (quiet) {
      process.stdout.write(os.EOL);
    }

    if (callback) {
      callback(null, line);
    }
  });
}

function printUsage() {
  console.error(help);
}

function checkKeyStrength(key) {
  return zxcvbn(key).entropy > 100;
}

function getScryptKey(key, salt, callback) {
  scrypt(key, salt, 17, 8, 32, 1000, function (keyBytes) {
    return callback(nacl.util.decodeBase64(keyBytes));
  },
  'base64');
}

function getKeyPair(key, salt, callback) {
  var keyHash = new BLAKE2s(32);
  keyHash.update(nacl.util.decodeUTF8(key));

  getScryptKey(keyHash.digest(), nacl.util.decodeUTF8(salt),
      function(keyBytes) {
    callback(nacl.box.keyPair.fromSecretKey(keyBytes));
  });
}

function miniLockId(publicKey) {
  var id = new Uint8Array(33);

  for (var i = 0; i < publicKey.length; i++) {
    id[i] = publicKey[i];
  }

  var hash = new BLAKE2s(1);
  hash.update(publicKey);

  id[32] = hash.digest()[0];

  return Base58.encode(id);
}

function readInput(filename, callback) {
  slurpFile(filename, callback);
}

function writeOutput(contents, filename) {
  if (contents != null) {
    fs.writeFileSync(filename, contents);
  }
}

function readPassphrase(passphrase, callback) {
  if (typeof passphrase === 'function') {
    callback = passphrase;
    passphrase = null;
  }

  if (typeof passphrase === 'string') {
    async(function () {
      callback(null, passphrase);
    });
  } else {
    prompt('Passphrase: ', true, function (error, passphrase) {
      callback(error, passphrase);
    });
  }
}

function generateId(email, passphrase, callback) {
  if (!checkKeyStrength(passphrase)) {
    async(function () {
      callback('Passphrase too weak!');
    });
  }

  getKeyPair(passphrase, email, function (keyPair) {
    callback(null, miniLockId(keyPair.publicKey), keyPair);
  });
}

function makeHeader(ids, senderInfo, fileInfo) {
  var ephemeral = nacl.box.keyPair();
  var header = {
    version: 1,
    ephemeral: nacl.util.encodeBase64(ephemeral.publicKey),
    decryptInfo: {}
  };

  ids.forEach(function (id, index) {
    var nonce = nacl.randomBytes(24);
    var publicKey = new Uint8Array(Base58.decode(id).slice(0, 32));

    var decryptInfo = {
      senderID: senderInfo.id,
      recipientID: id,
      fileInfo: fileInfo
    };

    decryptInfo.fileInfo = nacl.util.encodeBase64(nacl.box(
      nacl.util.decodeUTF8(JSON.stringify(decryptInfo.fileInfo)),
      nonce,
      publicKey,
      senderInfo.secretKey
    ));

    decryptInfo = nacl.util.encodeBase64(nacl.box(
      nacl.util.decodeUTF8(JSON.stringify(decryptInfo)),
      nonce,
      publicKey,
      ephemeral.secretKey
    ));

    header.decryptInfo[nacl.util.encodeBase64(nonce)] = decryptInfo;
  });

  return JSON.stringify(header);
}

function encryptFile(ids, email, passphrase, file, callback) {
  generateId(email, passphrase, function (error, fromId, keyPair) {
    if (error) {
      callback(error);
      return;
    }

    var senderInfo = {
      id: fromId,
      secretKey: keyPair.secretKey
    };

    readInput(file, function (error, contents) {
      if (error) {
        callback(error);
        return;
      }

      var fileKey   = nacl.randomBytes(32);
      var fileNonce = nacl.randomBytes(16);

      var chunkSize = Math.max(256, contents.length);

      var encryptor = nacl_.stream.createEncryptor(fileKey, fileNonce,
          chunkSize);
      var hashObject = new BLAKE2s(32);

      var encryptedChunk = encryptor.encryptChunk(new Uint8Array(contents),
          true);
      encryptor.clean();

      hashObject.update(encryptedChunk);

      var fileInfo = {
        fileKey: nacl.util.encodeBase64(fileKey),
        fileNonce: nacl.util.encodeBase64(fileNonce),
        fileHash: nacl.util.encodeBase64(hashObject.digest())
      };

      var header = makeHeader(ids, senderInfo, fileInfo);

      var headerLength = new Buffer(4);
      headerLength.writeUInt32LE(header.length);

      var output = [
        'miniLock',
        headerLength,
        header,
        encryptedChunk
      ].reduce(function (output, chunk) {
        return Buffer.concat([ output, new Buffer(chunk, 'utf8') ]);
      },
      new Buffer(0));

      writeOutput(output, file + '.minilock');

      callback(null, output.length);
    });
  });
}

function handleIdCommand() {
  var defaultOptions = {
    'passphrase':      null,
  };

  var shortcuts = {};

  var options = parseArgs(process.argv.slice(3), defaultOptions, shortcuts);

  if (options['!?'].length > 0) {
    die("Unknown option '" + options['!?'][0] + "'.");
  }

  var email = options['...'][0];
  var passphrase = options.passphrase;

  if (email === undefined) {
    printUsage();
    die();
  }

  readPassphrase(passphrase, function (error, passphrase) {
    if (error) {
      logError(error);
      die();
    }

    generateId(email, passphrase, function (error, id) {
      if (error) {
        logError(error);
        die();
      }

      console.log(id);
    });
  });
}

function handleEncryptCommand() {
  var defaultOptions = {
    'email':           null,
    'passphrase':      null,
    'file':            null,
  };

  var shortcuts = {};

  var options = parseArgs(process.argv.slice(3), defaultOptions, shortcuts);

  if (options['!?'].length > 0) {
    die("Unknown option '" + options['!?'][0] + "'.");
  }

  var ids = options['...'].slice();

  var email = options.email;
  var passphrase = options.passphrase;

  var file = options.file;

  if (typeof email !== 'string' || typeof file !== 'string') {
    printUsage();
    die();
  }

  readPassphrase(passphrase, function (error, passphrase) {
    if (error) {
      logError(error);
      die();
    }

    encryptFile(ids, email, passphrase, file, function (error, length) {
      if (error) {
        logError(error);
        die();
      }

      if (!isNaN(length)) {
        console.log(length + ' bytes');
      }
    });
  });
}

function run() {
  switch (process.argv[2]) {
  case 'id':
    handleIdCommand();
    break;
  case 'encrypt':
    handleEncryptCommand();
    break;
  default:
    printUsage();
    die();
  }
}

function main() {
  run();
}

if (require.main === module) {
  main();
}

exports.run = run;

// vim: et ts=2 sw=2
<|endoftext|>


<commit_before>'use strict';

// Declare app level module which depends on views, and components
angular.module('myApp', [
  'ngRoute',
  'myApp.view1',
  'myApp.view2',
  'myApp.version'
]).
config(['$routeProvider', function($routeProvider) {
  $routeProvider.otherwise({redirectTo: '/view1'});
}]);
<commit_msg>adding my modules, routes, a couple rootScope vars, and white listing youtube.com for videos<commit_after>'use strict';

// declare app
var app = angular.module('app', ['ngRoute',

	// all my modules
	'app.template',
	'app.offcanvasnav',
	'app.nav',
	'app.footer',
	'app.home',
	'app.web',
	'app.print',
	'app.video',
	'app.social',

	// directives
	'app.contactgroup',
	'app.flexslider',
	'app.youtubeiframe',

	// services

	// filters
	'app.stringFilters'

]);

// config
app.config(function($routeProvider, $locationProvider, $sceDelegateProvider){

	// WHITELIST domains
	$sceDelegateProvider.resourceUrlWhitelist([
		// Allow same origin resource loads.
		'self',
		// Allow loading from our assets domain.  Notice the difference between * and **.
		'http://www.youtube.com/**'
	]);

	// BLACKLIST domains
	// The blacklist overrides the whitelist so the open redirect here is blocked.
	$sceDelegateProvider.resourceUrlBlacklist([
		'http://myapp.example.com/clickThru**'
	]);

	// routes
	$routeProvider
	.when('/', {
		controller : 'homeController',
		templateUrl : '/components/home/homeView.htm'
	})
	.when('/template', {
		controller : 'templateController',
		templateUrl : '/components/_template/templateView.htm'
	})
	.when('/web', {
		controller : 'webController',
		templateUrl : '/components/web/webView.htm'
	})
	.when('/print', {
		controller : 'printController',
		templateUrl : '/components/print/printView.htm'
	})
	.when('/video', {
		controller : 'videoController',
		templateUrl : '/components/video/videoView.htm'
	})
	.when('/social', {
		controller : 'socialController',
		templateUrl : '/components/social/socialView.htm'
	})
	.otherwise({redirectTo : '/'});

	// allow for URLs without #! (requires .htaccess file to rewrite URLs)
	$locationProvider.html5Mode({
		enabled: true,
		requireBase: false
	});

});

app.run(function($rootScope){

	$rootScope.contactData = {
		phone 	: '909-224-0798',
		mobile 	: '909-224-0798',
		email 	: 'pedro@madwebdesigns.net '
	}

	// static meta data
	$rootScope.meta = {};
	$rootScope.meta.title = "VanityApp.net";
});<|endoftext|>