<commit_before>var files_added = 0; /* Track files added to the upload. */
var files_processed = 0; /* Track files that are processed.*/
var files_uploaded = 0; /* Track successful uploads. */

function closeForm() {
  $('#fileForm').foundation(
    {reveal: {close_on_background_click: true, close_on_esc: true}}
  );

  setTimeout(function () {
    $('#fileForm').foundation('reveal', 'close');
    setTimeout(function () {
      $('#preloadmsg').show();
      $('.fileupload-progress').hide();
      $('#start-upload').addClass('disabled');
      $('#cancel-upload').addClass('disabled');
      $('#close-upload').on('click', function () {
        $('#fileForm').foundation('reveal', 'close');
      }).removeClass('disabled');
    }, 500);
  }, 250);

  if (files_uploaded > 0) {
    $('#messages').html(
      '
' +
        '
' +
        '
' +
        'Success. ' + files_uploaded +
        ' files were added. ×' +
        '
' +
        '
' +
        '
'
    );
  }
  files_uploaded = 0;
  files_added = 0;
  files_processed = 0;
}

$('#close-upload').on('click', function () {
  $('#fileForm').foundation('reveal', 'close');
});

$(function () {
  'use strict';

  /*
      Initialize the jQuery File Upload widget.

      Default options are defined by the package,
      however users may extend and define their
      own options.
  */

  var formData = $('#fileupload').serializeArray();
  formData.push(
    {name: "redirect", value: ""}
  );
  /*jslint unparam: true*/
  $('#fileupload').fileupload({
    formData: formData,
    url: $(this).attr('action'),
    method: 'POST',
    dataType: 'text',
    sequentialUploads: true,
    recalculateProgress: false,
    previewMaxWidth: 100,
    previewMaxHeight: 100,
    maxFileSize: $('#fileupload input[name=max_file_size]').val()
  })

    // Keep a counter of files as they are added.
    .bind('fileuploadadd', function () {
      files_added += 1;
      if ($('#fileForm').hasClass('open') === false) {
        $('#fileForm').foundation('reveal', 'open');
      }
    })

    .bind('fileuploaddone', function () {
      files_uploaded += 1;
    })

    .bind('fileuploadprocessstart', function () {
      $('#preloadmsg').hide();
      $('.fileupload-progress').show();
      $('#start-upload').removeClass('disabled');
      $('#cancel-upload').removeClass('disabled');
    })

    .bind('fileuploadprocessdone', function () {
      if (files_added > 1) {
        $('.file-progress').show();
      }
    })

    .bind('fileuploadsend', function (e, data) {
      /*global Foundation: true*/
      Foundation.libs.reveal.settings.close_on_background_click = false;
      $('#close-upload').off().addClass('disabled');
      $.each(data.files, function () {
        $('#fileForm').foundation(
          {
            reveal: {close_on_background_click: false, close_on_esc: false}
          }
        );
      });
    })

    // This is called when an item in the form is cancelled or removed.
    .bind('fileuploadfail', function () {
      files_added -= 1;
      if (files_added === 0) {
        $('#preloadmsg').show();
        $('.fileupload-progress').hide();
      }
    })

    // Keep a counter of files as they are processed.
    .bind('fileuploadalways', function () {
      files_processed += 1;

      // If all files have been processed, close the form.
      if (files_processed > files_added) {
        closeForm();
        angular.element("#objecttable").scope().refreshObjectTable();
        files_added = 0;
        files_processed = 0;
        files_uploaded = 0;
        $(".crumb-row.fixed").remove();
      }
    })

    .addClass('fileupload-processing');
  /*jslint unparam: false*/

});

$('#cancel-upload').click(function () {
  $('#fileForm').foundation(
    {reveal: {close_on_background_click: true, close_on_esc: true}}
  );
  $('#preloadmsg').show();
  $('.fileupload-progress').hide();
  files_uploaded = 0;
  files_added = 0;
  files_processed = 0;
  $('#start-upload').addClass('disabled');
  $('#cancel-upload').addClass('disabled');
  $('#close-upload').on('click', function () {
    $('#fileForm').foundation('reveal', 'close');
  }).removeClass('disabled');
});

//Add a special class for chrome
/*global navigator: true*/
if (navigator.userAgent.toLowerCase().match('chrome')) {
  $("body").addClass("chrome");
}

/*global File: true*/
/*
    Modify jquery fileupload's onAdd method. This method recreates
    the file object pointer and changes the name. The name change allows
    users to drag and drop directories and those directories are
    recreated on swift.
*/
$.blueimp.fileupload.prototype._onAdd = function (e, data) {
  var that = this,
    result = true,
    options = $.extend({}, this.options, data),
    files = data.files,
    filesLength = files.length,
    limit = options.limitMultiFileUploads,
    limitSize = options.limitMultiFileUploadSize,
    overhead = options.limitMultiFileUploadSizeOverhead,
    batchSize = 0,
    paramName = this._getParamName(options),
    paramNameSet,
    paramNameSlice,
    fileSet,
    i,
    j = 0;
  if (limitSize && (!filesLength || files[0].size === undefined)) {
    limitSize = undefined;
  }
  if (!(options.singleFileUploads || limit || limitSize) ||
          !this._isXHRUpload(options)) {
    fileSet = [files];
    paramNameSet = [paramName];
  } else if (!(options.singleFileUploads || limitSize) && limit) {
    fileSet = [];
    paramNameSet = [];
    for (i = 0; i < filesLength; i += limit) {
      fileSet.push(files.slice(i, i + limit));
      paramNameSlice = paramName.slice(i, i + limit);
      if (!paramNameSlice.length) {
        paramNameSlice = paramName;
      }
      paramNameSet.push(paramNameSlice);
    }
  } else if (!options.singleFileUploads && limitSize) {
    fileSet = [];
    paramNameSet = [];
    for (i = 0; i < filesLength; i = i + 1) {
      batchSize += files[i].size + overhead;
      if (i + 1 === filesLength ||
            ((batchSize + files[i + 1].size + overhead) > limitSize) ||
            (limit && i + 1 - j >= limit)) {
        fileSet.push(files.slice(j, i + 1));
        paramNameSlice = paramName.slice(j, i + 1);
        if (!paramNameSlice.length) {
          paramNameSlice = paramName;
        }
        paramNameSet.push(paramNameSlice);
        j = i + 1;
        batchSize = 0;
      }
    }
  } else {
    paramNameSet = paramName;
  }
  data.originalFiles = files;
  $.each(fileSet || files, function (index, element) {

    /****************** Swift browser edits here ******************/
    /*
        A new File object is created using "element". This new file
        has a different ".name". This new name allows swift to
        create pseudo folders. The end result is the file structure
        that is dragged and dropped in swiftbrowser is preserved on
        swift.
    */

    if (element.relativePath) {
      element = new File([element], element.relativePath + element.name, {type: "text/plain"});

    } else if (element.webkitRelativePath) {
      element = new File([element], element.webkitRelativePath, {type: "text/plain"});

    }
    var newData = $.extend({}, data);
    newData.files = fileSet ? element : [element];
    newData.paramName = paramNameSet[index];
    that._initResponseObject(newData);
    that._initProgressObject(newData);
    that._addConvenienceMethods(e, newData);
    result = that._trigger(
      'add',
      $.Event('add', {delegatedEvent: e}),
      newData
    );
    return result;
  });
  return result;
};
<commit_msg>bug fix: properly counting uploads added, aborted and processed.<commit_after>var files_added = 0; /* Track files added to the upload. */
var files_processed = 0; /* Track files that are processed.*/
var files_uploaded = 0; /* Track successful uploads. */

function closeForm() {
  $('#fileForm').foundation(
    {reveal: {close_on_background_click: true, close_on_esc: true}}
  );

  setTimeout(function () {
    $('#fileForm').foundation('reveal', 'close');
    setTimeout(function () {
      $('#preloadmsg').show();
      $('.fileupload-progress').hide();
      $('#start-upload').addClass('disabled');
      $('#cancel-upload').addClass('disabled');
      $('#close-upload').on('click', function () {
        $('#fileForm').foundation('reveal', 'close');
      }).removeClass('disabled');
    }, 500);
  }, 250);

  if (files_uploaded > 0) {
    $('#messages').html(
      '
' +
        '
' +
        '
' +
        'Success. ' + files_uploaded +
        ' files were added. ×' +
        '
' +
        '
' +
        '
'
    );
  }
  files_uploaded = 0;
  files_added = 0;
  files_processed = 0;
}

$('#close-upload').on('click', function () {
  $('#fileForm').foundation('reveal', 'close');
});

$(function () {
  'use strict';

  /*
      Initialize the jQuery File Upload widget.

      Default options are defined by the package,
      however users may extend and define their
      own options.
  */

  var formData = $('#fileupload').serializeArray();
  formData.push(
    {name: "redirect", value: ""}
  );
  /*jslint unparam: true*/
  $('#fileupload').fileupload({
    formData: formData,
    url: $(this).attr('action'),
    method: 'POST',
    dataType: 'text',
    sequentialUploads: true,
    recalculateProgress: false,
    previewMaxWidth: 100,
    previewMaxHeight: 100,
    maxFileSize: $('#fileupload input[name=max_file_size]').val()
  })

    // Keep a counter of files as they are added.
    .bind('fileuploadadd', function () {
      files_added += 1;
      if ($('#fileForm').hasClass('open') === false) {
        $('#fileForm').foundation('reveal', 'open');
      }
    })

    //Called on successful file upload
    .bind('fileuploaddone', function () {
      files_uploaded += 1;
    })

    .bind('fileuploadprocessstart', function () {
      $('#preloadmsg').hide();
      $('.fileupload-progress').show();
      $('#start-upload').removeClass('disabled');
      $('#cancel-upload').removeClass('disabled');
    })

    .bind('fileuploadprocessdone', function () {
      if (files_added > 1) {
        $('.file-progress').show();
      }
    })

    .bind('fileuploadsend', function (e, data) {
      /*global Foundation: true*/
      Foundation.libs.reveal.settings.close_on_background_click = false;
      $('#close-upload').off().addClass('disabled');
      $.each(data.files, function () {
        $('#fileForm').foundation(
          {
            reveal: {close_on_background_click: false, close_on_esc: false}
          }
        );
      });
    })

    // This is called when an item in the form is cancelled, files removed and
    // when files fail.
    .bind('fileuploadfail', function (e, data) {
      if (data.errorThrown === "abort") {
        files_added -= 1;
      }
      if (files_added === 0) {
        $('#preloadmsg').show();
        $('.fileupload-progress').hide();
      }
    })

    // Keep a counter of files as they are processed.
    .bind('fileuploadalways', function () {
      files_processed += 1;

      // If all files have been processed, close the form.
      if (files_processed === files_added) {
        closeForm();
        angular.element("#objecttable").scope().refreshObjectTable();
        files_added = 0;
        files_processed = 0;
        files_uploaded = 0;
        $(".crumb-row.fixed").remove();
      }
    })

    .addClass('fileupload-processing');
  /*jslint unparam: false*/

});

$('#cancel-upload').click(function () {
  $('#fileForm').foundation(
    {reveal: {close_on_background_click: true, close_on_esc: true}}
  );
  $('#preloadmsg').show();
  $('.fileupload-progress').hide();
  files_uploaded = 0;
  files_added = 0;
  files_processed = 0;
  $('#start-upload').addClass('disabled');
  $('#cancel-upload').addClass('disabled');
  $('#close-upload').on('click', function () {
    $('#fileForm').foundation('reveal', 'close');
  }).removeClass('disabled');
});

//Add a special class for chrome
/*global navigator: true*/
if (navigator.userAgent.toLowerCase().match('chrome')) {
  $("body").addClass("chrome");
}

/*global File: true*/
/*
    Modify jquery fileupload's onAdd method. This method recreates
    the file object pointer and changes the name. The name change allows
    users to drag and drop directories and those directories are
    recreated on swift.
*/
$.blueimp.fileupload.prototype._onAdd = function (e, data) {
  var that = this,
    result = true,
    options = $.extend({}, this.options, data),
    files = data.files,
    filesLength = files.length,
    limit = options.limitMultiFileUploads,
    limitSize = options.limitMultiFileUploadSize,
    overhead = options.limitMultiFileUploadSizeOverhead,
    batchSize = 0,
    paramName = this._getParamName(options),
    paramNameSet,
    paramNameSlice,
    fileSet,
    i,
    j = 0;
  if (limitSize && (!filesLength || files[0].size === undefined)) {
    limitSize = undefined;
  }
  if (!(options.singleFileUploads || limit || limitSize) ||
          !this._isXHRUpload(options)) {
    fileSet = [files];
    paramNameSet = [paramName];
  } else if (!(options.singleFileUploads || limitSize) && limit) {
    fileSet = [];
    paramNameSet = [];
    for (i = 0; i < filesLength; i += limit) {
      fileSet.push(files.slice(i, i + limit));
      paramNameSlice = paramName.slice(i, i + limit);
      if (!paramNameSlice.length) {
        paramNameSlice = paramName;
      }
      paramNameSet.push(paramNameSlice);
    }
  } else if (!options.singleFileUploads && limitSize) {
    fileSet = [];
    paramNameSet = [];
    for (i = 0; i < filesLength; i = i + 1) {
      batchSize += files[i].size + overhead;
      if (i + 1 === filesLength ||
            ((batchSize + files[i + 1].size + overhead) > limitSize) ||
            (limit && i + 1 - j >= limit)) {
        fileSet.push(files.slice(j, i + 1));
        paramNameSlice = paramName.slice(j, i + 1);
        if (!paramNameSlice.length) {
          paramNameSlice = paramName;
        }
        paramNameSet.push(paramNameSlice);
        j = i + 1;
        batchSize = 0;
      }
    }
  } else {
    paramNameSet = paramName;
  }
  data.originalFiles = files;
  $.each(fileSet || files, function (index, element) {

    /****************** Swift browser edits here ******************/
    /*
        A new File object is created using "element". This new file
        has a different ".name". This new name allows swift to
        create pseudo folders. The end result is the file structure
        that is dragged and dropped in swiftbrowser is preserved on
        swift.
    */

    if (element.relativePath) {
      element = new File([element], element.relativePath + element.name, {type: "text/plain"});

    } else if (element.webkitRelativePath) {
      element = new File([element], element.webkitRelativePath, {type: "text/plain"});

    }
    var newData = $.extend({}, data);
    newData.files = fileSet ? element : [element];
    newData.paramName = paramNameSet[index];
    that._initResponseObject(newData);
    that._initProgressObject(newData);
    that._addConvenienceMethods(e, newData);
    result = that._trigger(
      'add',
      $.Event('add', {delegatedEvent: e}),
      newData
    );
    return result;
  });
  return result;
};
<|endoftext|>


<commit_before>var State = require('ampersand-state');
var View = require('ampersand-view');

var Numbers = require('./numbers.js');

//------------------------------------------------------------------------------

function ready(fn) {
  if (document.readyState != 'loading'){
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

//------------------------------------------------------------------------------

var colors = [
  "#ED2079",
  "#ED3E36",
  "#F76321",
  "#FFB73B",
  "#F5EC2B",
  "#8DC53A",
  "#37B347",
  "#00ABEE",
  "#283891",
  "#92278B"
];
var minWidth = 768;
var minRadius = 0.5;

var gridSpacing = 25;
var padding;
var alreadyWarned = false;

var radiusDensityToWidth = function(radius, cols) {
  return cols * gridSpacing + 2 * cols * radius + gridSpacing;
}

var widthRadiusToCols = function(width, radius) {
  // w = c *(g + 2 * r) + g
  // (w - g) / (g + 2 * r) = c
  return (width - gridSpacing) / (gridSpacing + 2 * radius);
}

//------------------------------------------------------------------------------

var StageView = View.extend({
  template: '<svg id="stage"></svg>',

  autoRender: true,

  bindings: {
    "model.width": {
      type: "attribute",
      name: "width"
    }
  },

  events: {
    'click': function() {
      this.model.cycleDisplayMode();
    }
  },

  svg: null,

  render: function() {
    if (!this.rendered) {
      View.prototype.render.apply(this, arguments);

      this.svg = d3.select(this.el);

      this.svg.append('defs').append('clipPath').attr({id: 'cstroke'}).
        append('circle');
      this.svg.append('g').classed('lines', true);
      this.svg.append('g').classed('circles', true);
    }

    var cols = this.model.densityValue;
    var displayMode = this.model.displayMode;
    var subject = this.model.subjectValue;

    var svg = this.svg;
    var limit = subject.length;
    var width = svg.attr("width");
    var heigth;
    var strokeWidth;
    var circlesData = [];
    var linesData = [];
    var thisDigit;
    var digitSW, digitW, digitNW, digitN;
    var iSW, iW, iNW, iN;
    var nextDigit = 3;
    var thisX, nextX, thisY, nextY;
    var thisColor;
    var firstCol, lastCol, firstRow, lastRow;
    var datum;
    var i, xIndex;
    var radius = this.model.dRadius;
    var xCoord = function(i) {
      return padding + (i % cols) * (gridSpacing + 2 * radius);
    }
    var yCoord = function(i) {
      return padding + Math.floor(i / cols) * (gridSpacing + 2 * radius);
    }
    var markEqualNeigbour = function(i) {
      if (typeof circlesData[i] !== 'undefined') {
        circlesData[i].hasEqualNeighbour = true;
      }
    };
    strokeWidth = radius / 2.5;
    padding = radius + gridSpacing;

    height = (2 * padding) + (limit / cols) * (2 * radius) + ((limit / cols) - 1) * gridSpacing;
    svg.attr("height", height);

    for (i = 0; i < limit; i++) {
      thisDigit = nextDigit;
      nextDigit = parseInt(subject.charAt(i + 1), 10);
      thisColor = colors[thisDigit];
      thisX = xCoord(i);
      thisY = yCoord(i);
      nextX = xCoord(i + 1);
      nextY = yCoord(i + 1);
      xIndex = i % cols;
      firstCol = xIndex === 0;
      lastCol = xIndex === cols - 1;
      firstRow = i <= cols;
      lastRow = i >= (limit - cols - 1);

      datum = {
        outerColor: thisColor,
        innerColor: colors[nextDigit],
        x: thisX,
        y: thisY,
        r: radius,
        hasEqualNeighbour: false
      };

      if (displayMode > 0) {
        if (!firstCol && !lastRow) {
          iSW = i + cols - 1;
          digitSW = parseInt(subject.charAt(iSW), 10);

          if (thisDigit === digitSW) {
            markEqualNeigbour(iSW);
            datum.hasEqualNeighbour = true;
            swX = xCoord(iSW);
            swY = yCoord(iSW);

            linesData.push({
              x1: thisX, x2: swX,
              y1: thisY, y2: swY,
              color: thisColor,
              "stroke-width": datum.r
            })
          }
        }

        if (!firstRow) { // second row and onwards
          iN = i - cols;
          digitN = parseInt(subject.charAt(iN), 10);
          nX = xCoord(iN);
          nY = yCoord(iN);

          if (thisDigit === digitN) {
            markEqualNeigbour(iN);
            datum.hasEqualNeighbour = true;

            linesData.push({
              x1: thisX, x2: nX,
              y1: thisY, y2: nY,
              color: thisColor,
              "stroke-width": datum.r
            })
          }

          if (!firstCol) {
            iW = i - 1;
            iNW = i - cols - 1;
            digitW = parseInt(subject.charAt(iW), 10);
            digitNW = parseInt(subject.charAt(iNW), 10);

            if (thisDigit === digitW) {
              markEqualNeigbour(iW);
              datum.hasEqualNeighbour = true;
              wX = xCoord(iW);
              wY = yCoord(iW);

              linesData.push({
                x1: thisX, x2: wX,
                y1: thisY, y2: wY,
                color: thisColor,
                "stroke-width": datum.r
              })
            }

            if (thisDigit === digitNW) {
              markEqualNeigbour(iNW);
              datum.hasEqualNeighbour = true;

              nwX = xCoord(iNW);
              nwY = yCoord(iNW);

              linesData.push({
                x1: thisX, x2: nwX,
                y1: thisY, y2: nwY,
                color: thisColor,
                "stroke-width": datum.r
              })
            }
          }
        }

        if (!lastCol) {
          // Special case because we can't "mark" neighbours ahead of them being
          // inserted into circlesData, which is the case of digitSW === thisDigit

          digitNE = parseInt(subject.charAt(i - cols + 1), 10);

          if (thisDigit === digitNE) {
            if (typeof circlesData[i - cols + 1] !== 'undefined') {
              circlesData[i - cols + 1].hasEqualNeighbour = true;
            }
            datum.hasEqualNeighbour = true;
          }
        }
      }

      circlesData.push(datum)
    }

    // Remove neighbourless circles in third display mode
    if (displayMode === 2) {
      for (i = circlesData.length - 1; i >= 0; i -= 1) {
        if (!circlesData[i].hasEqualNeighbour) {
          circlesData.splice(i, 1);
        }
      }
    }

    // CIRCLES

    var circlesGroup = svg.select('g.circles');
    var circlesSelection = circlesGroup.selectAll('g').data(circlesData);
    var clipStrokeCircle = svg.select('#cstroke circle');
    clipStrokeCircle.attr({ r: radius });

    var groupAttr = {
      transform: function(d) {
        return 'translate(' + d.x + ',' + d.y + ')';
      }
    }

    var colorValve = function(open, colorCode) {
      if (displayMode === 2) {
        if (open) {
          return colorCode;
        } else {
          return '#000';
        }
      } else {
        return colorCode;
      }
    };

    var circleAttr = {
      r: function(d) { return d.r },
      "stroke-width": function(d) { return d.r / 1.4 },
      "stroke": function(d) {
        return d.outerColor;
        //return colorValve(d.hasEqualNeighbour, d.outerColor);
      },
      "clip-path": "url(#cstroke)",
      "fill": function(d) {
        return d.innerColor;
        //return colorValve(d.hasEqualNeighbour, d.innerColor);
      }

    }

    // Enter
    var groups = circlesSelection.enter().append('g');
    var circle = groups.append('circle');

    // Enter + Update
    circlesSelection.attr(groupAttr).select('circle').attr(circleAttr);

    circlesSelection.exit().remove();

    // LINES

    var linesGroup = svg.select('g.lines');
    var linesSelection = linesGroup.selectAll('line').data(linesData);

    var linesAttr = {
      x1: function(d) { return d.x1; },
      y1: function(d) { return d.y1; },
      x2: function(d) { return d.x2; },
      y2: function(d) { return d.y2; },
      "stroke-width": function(d) { return d["stroke-width"]; },
      "stroke": function(d) { return d.color; }
    };

    // Enter
    linesSelection.enter().append('line');

    // Enter + Update
    linesSelection.attr(linesAttr);

    linesSelection.exit().remove();
  }
});

//------------------------------------------------------------------------------

ready(function() {
  var _densitySlider = d3.select("#density-slider");
  var _colsSlider = d3.select("#columns-slider");
  var minDensity = 1, maxDensity = 29;
  var minCols = 1, maxCols = 29, colsValue = 20;
  var numbers = new Numbers();

  var _phi = d3.select("#phi-link");
  var _pi = d3.select("#pi-link");
  var _e = d3.select("#e-link");

  var svg = d3.select("svg");

  //----------------------------------------------------------------------------

  var StageState = State.extend({
    props: {
      width: ['number', true, 768],
      displayMode: ['number', true, 0],
      subjectValue: ['string', true, numbers.subjectValue()],
      densityValue: ['number', true, 20],
      spacing: ['number', true, 25]
    },

    derived: {
      dRadius: {
        deps: ['width', 'densityValue', 'spacing'],
        fn: function() {
          // width: 2 * (gridSpacing + radius) + (cols - 1) * (2 * radius +
          // gridSpacing)
          // w = 2 * (g + r) + (c - 1) * (2 * r + g)
          // w = c * g + 2 * c * r + g
          // (w - (c * g) - g) / (2 * c) = r
          var tmp = (this.width - (this.densityValue * this.spacing) -
                    this.spacing) / (2 * this.densityValue);
          return tmp;
        }
      }
    },

    cycleDisplayMode: function() {
      this.displayMode = (this.displayMode + 1) % 3;
    }
  });

  var stageState = new StageState();

  var stageView = new StageView({
    model: stageState,
    el: svg[0][0]
  });

  stageState.on('change', function() {
    stageView.render();
  })

  //----------------------------------------------------------------------------

  _phi.on("click", function() {
    d3.event.preventDefault();

    _phi.classed("active", true);
    _pi.classed("active", false);
    _e.classed("active", false);

    numbers.setSubject(Numbers.PHI, function() {
      stageState.subjectValue = numbers.subjectValue();
    });
  });

  _pi.on("click", function() {
    d3.event.preventDefault();

    _phi.classed("active", false);
    _pi.classed("active", true);
    _e.classed("active", false);

    numbers.setSubject(Numbers.PI, function() {
      stageState.subjectValue = numbers.subjectValue();
    });
  });

  _e.on("click", function() {
    d3.event.preventDefault();

    _phi.classed("active", false);
    _pi.classed("active", false);
    _e.classed("active", true);

    numbers.setSubject(Numbers.E, function() {
      stageState.subjectValue = numbers.subjectValue();
    });
  });

  var updateDensitySlider = function(min, max, value) {
    _densitySlider.attr({ min: min, max: max, value: value });
    _densitySlider[0][0].value = value;
  }

  var updateColsSlider = function(min, max, value) {
    _colsSlider.attr({ min: min, max: max, value: value });
    _colsSlider[0][0].value = value;
  }

  var densityValueChanged =  function() {
    stageState.densityValue = +this.value;

    minCols = Math.max(Math.floor(widthRadiusToCols(minWidth, stageState.dRadius)), 1);
    maxCols = Math.floor(widthRadiusToCols(window.innerWidth, stageState.dRadius));
    updateColsSlider(minCols, maxCols, stageState.densityValue);
  };

  var columnsValueChanged = function() {
    var v = +this.value;

    stageState.set({
      densityValue: v,
      width: radiusDensityToWidth(stageState.dRadius,  v)
    });

    maxDensity = widthRadiusToCols(stageState.width, minRadius);
    updateDensitySlider(minDensity, maxDensity, v);
  };

  //----------------------------------------------------------------------------

  stageState.trigger('change'); // render

  maxCols = Math.floor(widthRadiusToCols(window.innerWidth, stageState.dRadius));
  minCols = stageState.densityValue;

  maxDensity = widthRadiusToCols(minWidth, minRadius);

  updateDensitySlider(minDensity, maxDensity, stageState.densityValue);
  updateColsSlider(minCols, maxCols, minCols);

  _densitySlider.on("change", densityValueChanged);
  _densitySlider.on("input", densityValueChanged);

  _colsSlider.on("change", columnsValueChanged);
  _colsSlider.on("input", columnsValueChanged);

  //----------------------------------------------------------------------------

  var digits = d3.selectAll('#digits-radio input');
  var onDigitsChange = function() {
    var value = +this.value;

    numbers.setDigits(+this.value, function() {
      stageState.subjectValue = numbers.subjectValue();
    });
  };

  digits.on('click', function() {
    var value = +this.value;
    var warning = 'Displaying 100k digits or more, can be very resource ' +
      'intensive, even on a powerfull computer. Are you sure you would like ' +
      'to proceed?';

    if (value > 4 && !alreadyWarned) {
      if (confirm(warning)) {
        alreadyWarned = true;
      } else {
        d3.event.preventDefault();
        return false;
      }
    }
  });

  digits.on('change', onDigitsChange);
});
<commit_msg>Moves global functions into StageState<commit_after>var State = require('ampersand-state');
var View = require('ampersand-view');

var Numbers = require('./numbers.js');

//------------------------------------------------------------------------------

function ready(fn) {
  if (document.readyState != 'loading'){
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

//------------------------------------------------------------------------------

var colors = [
  "#ED2079",
  "#ED3E36",
  "#F76321",
  "#FFB73B",
  "#F5EC2B",
  "#8DC53A",
  "#37B347",
  "#00ABEE",
  "#283891",
  "#92278B"
];
var minWidth = 768;
var minRadius = 0.5;

var padding;
var alreadyWarned = false;

//------------------------------------------------------------------------------

var StageView = View.extend({
  template: '<svg id="stage"></svg>',

  autoRender: true,

  bindings: {
    "model.width": {
      type: "attribute",
      name: "width"
    }
  },

  events: {
    'click': function() {
      this.model.cycleDisplayMode();
    }
  },

  svg: null,

  render: function() {
    if (!this.rendered) {
      View.prototype.render.apply(this, arguments);

      this.svg = d3.select(this.el);

      this.svg.append('defs').append('clipPath').attr({id: 'cstroke'}).
        append('circle');
      this.svg.append('g').classed('lines', true);
      this.svg.append('g').classed('circles', true);
    }

    var that = this;

    var cols = this.model.densityValue;
    var displayMode = this.model.displayMode;
    var subject = this.model.subjectValue;

    var svg = this.svg;
    var limit = subject.length;
    var width = svg.attr("width");
    var heigth;
    var strokeWidth;
    var circlesData = [];
    var linesData = [];
    var thisDigit;
    var digitSW, digitW, digitNW, digitN;
    var iSW, iW, iNW, iN;
    var nextDigit = 3;
    var thisX, nextX, thisY, nextY;
    var thisColor;
    var firstCol, lastCol, firstRow, lastRow;
    var datum;
    var i, xIndex;
    var radius = this.model.dRadius;
    var xCoord = function(i) {
      return padding + (i % cols) * (that.model.spacing + 2 * radius);
    }
    var yCoord = function(i) {
      return padding + Math.floor(i / cols) * (that.model.spacing + 2 * radius);
    }
    var markEqualNeigbour = function(i) {
      if (typeof circlesData[i] !== 'undefined') {
        circlesData[i].hasEqualNeighbour = true;
      }
    };
    strokeWidth = radius / 2.5;
    padding = radius + this.model.spacing;

    height = (2 * padding) + (limit / cols) * (2 * radius) + ((limit / cols) - 1) * this.model.spacing;
    svg.attr("height", height);

    for (i = 0; i < limit; i++) {
      thisDigit = nextDigit;
      nextDigit = parseInt(subject.charAt(i + 1), 10);
      thisColor = colors[thisDigit];
      thisX = xCoord(i);
      thisY = yCoord(i);
      nextX = xCoord(i + 1);
      nextY = yCoord(i + 1);
      xIndex = i % cols;
      firstCol = xIndex === 0;
      lastCol = xIndex === cols - 1;
      firstRow = i <= cols;
      lastRow = i >= (limit - cols - 1);

      datum = {
        outerColor: thisColor,
        innerColor: colors[nextDigit],
        x: thisX,
        y: thisY,
        r: radius,
        hasEqualNeighbour: false
      };

      if (displayMode > 0) {
        if (!firstCol && !lastRow) {
          iSW = i + cols - 1;
          digitSW = parseInt(subject.charAt(iSW), 10);

          if (thisDigit === digitSW) {
            markEqualNeigbour(iSW);
            datum.hasEqualNeighbour = true;
            swX = xCoord(iSW);
            swY = yCoord(iSW);

            linesData.push({
              x1: thisX, x2: swX,
              y1: thisY, y2: swY,
              color: thisColor,
              "stroke-width": datum.r
            })
          }
        }

        if (!firstRow) { // second row and onwards
          iN = i - cols;
          digitN = parseInt(subject.charAt(iN), 10);
          nX = xCoord(iN);
          nY = yCoord(iN);

          if (thisDigit === digitN) {
            markEqualNeigbour(iN);
            datum.hasEqualNeighbour = true;

            linesData.push({
              x1: thisX, x2: nX,
              y1: thisY, y2: nY,
              color: thisColor,
              "stroke-width": datum.r
            })
          }

          if (!firstCol) {
            iW = i - 1;
            iNW = i - cols - 1;
            digitW = parseInt(subject.charAt(iW), 10);
            digitNW = parseInt(subject.charAt(iNW), 10);

            if (thisDigit === digitW) {
              markEqualNeigbour(iW);
              datum.hasEqualNeighbour = true;
              wX = xCoord(iW);
              wY = yCoord(iW);

              linesData.push({
                x1: thisX, x2: wX,
                y1: thisY, y2: wY,
                color: thisColor,
                "stroke-width": datum.r
              })
            }

            if (thisDigit === digitNW) {
              markEqualNeigbour(iNW);
              datum.hasEqualNeighbour = true;

              nwX = xCoord(iNW);
              nwY = yCoord(iNW);

              linesData.push({
                x1: thisX, x2: nwX,
                y1: thisY, y2: nwY,
                color: thisColor,
                "stroke-width": datum.r
              })
            }
          }
        }

        if (!lastCol) {
          // Special case because we can't "mark" neighbours ahead of them being
          // inserted into circlesData, which is the case of digitSW === thisDigit

          digitNE = parseInt(subject.charAt(i - cols + 1), 10);

          if (thisDigit === digitNE) {
            if (typeof circlesData[i - cols + 1] !== 'undefined') {
              circlesData[i - cols + 1].hasEqualNeighbour = true;
            }
            datum.hasEqualNeighbour = true;
          }
        }
      }

      circlesData.push(datum)
    }

    // Remove neighbourless circles in third display mode
    if (displayMode === 2) {
      for (i = circlesData.length - 1; i >= 0; i -= 1) {
        if (!circlesData[i].hasEqualNeighbour) {
          circlesData.splice(i, 1);
        }
      }
    }

    // CIRCLES

    var circlesGroup = svg.select('g.circles');
    var circlesSelection = circlesGroup.selectAll('g').data(circlesData);
    var clipStrokeCircle = svg.select('#cstroke circle');
    clipStrokeCircle.attr({ r: radius });

    var groupAttr = {
      transform: function(d) {
        return 'translate(' + d.x + ',' + d.y + ')';
      }
    }

    var colorValve = function(open, colorCode) {
      if (displayMode === 2) {
        if (open) {
          return colorCode;
        } else {
          return '#000';
        }
      } else {
        return colorCode;
      }
    };

    var circleAttr = {
      r: function(d) { return d.r },
      "stroke-width": function(d) { return d.r / 1.4 },
      "stroke": function(d) {
        return d.outerColor;
        //return colorValve(d.hasEqualNeighbour, d.outerColor);
      },
      "clip-path": "url(#cstroke)",
      "fill": function(d) {
        return d.innerColor;
        //return colorValve(d.hasEqualNeighbour, d.innerColor);
      }

    }

    // Enter
    var groups = circlesSelection.enter().append('g');
    var circle = groups.append('circle');

    // Enter + Update
    circlesSelection.attr(groupAttr).select('circle').attr(circleAttr);

    circlesSelection.exit().remove();

    // LINES

    var linesGroup = svg.select('g.lines');
    var linesSelection = linesGroup.selectAll('line').data(linesData);

    var linesAttr = {
      x1: function(d) { return d.x1; },
      y1: function(d) { return d.y1; },
      x2: function(d) { return d.x2; },
      y2: function(d) { return d.y2; },
      "stroke-width": function(d) { return d["stroke-width"]; },
      "stroke": function(d) { return d.color; }
    };

    // Enter
    linesSelection.enter().append('line');

    // Enter + Update
    linesSelection.attr(linesAttr);

    linesSelection.exit().remove();
  }
});

//------------------------------------------------------------------------------

ready(function() {
  var _densitySlider = d3.select("#density-slider");
  var _colsSlider = d3.select("#columns-slider");
  var minDensity = 1, maxDensity = 29;
  var minCols = 1, maxCols = 29, colsValue = 20;
  var numbers = new Numbers();

  var _phi = d3.select("#phi-link");
  var _pi = d3.select("#pi-link");
  var _e = d3.select("#e-link");

  var svg = d3.select("svg");

  //----------------------------------------------------------------------------

  var StageState = State.extend({
    props: {
      width: ['number', true, 768],
      displayMode: ['number', true, 0],
      subjectValue: ['string', true, numbers.subjectValue()],
      densityValue: ['number', true, 20],
      spacing: ['number', true, 25]
    },

    derived: {
      dRadius: {
        deps: ['width', 'densityValue', 'spacing'],
        fn: function() {
          // width: 2 * (spacing + radius) + (cols - 1) * (2 * radius +
          // spacing)
          // w = 2 * (g + r) + (c - 1) * (2 * r + g)
          // w = c * g + 2 * c * r + g
          // (w - (c * g) - g) / (2 * c) = r
          var tmp = (this.width - (this.densityValue * this.spacing) -
                    this.spacing) / (2 * this.densityValue);
          return tmp;
        }
      }
    },

    widthRadiusToCols: function(width, radius) {
      // w = c *(g + 2 * r) + g
      // (w - g) / (g + 2 * r) = c
      return (width - this.spacing) / (this.spacing + 2 * radius);
    },

    radiusDensityToWidth: function(radius, density) {
      return density * this.spacing + 2 * density * radius + this.spacing;
    },

    cycleDisplayMode: function() {
      this.displayMode = (this.displayMode + 1) % 3;
    }
  });

  var stageState = new StageState();

  var stageView = new StageView({
    model: stageState,
    el: svg[0][0]
  });

  stageState.on('change', function() {
    stageView.render();
  })

  //----------------------------------------------------------------------------

  _phi.on("click", function() {
    d3.event.preventDefault();

    _phi.classed("active", true);
    _pi.classed("active", false);
    _e.classed("active", false);

    numbers.setSubject(Numbers.PHI, function() {
      stageState.subjectValue = numbers.subjectValue();
    });
  });

  _pi.on("click", function() {
    d3.event.preventDefault();

    _phi.classed("active", false);
    _pi.classed("active", true);
    _e.classed("active", false);

    numbers.setSubject(Numbers.PI, function() {
      stageState.subjectValue = numbers.subjectValue();
    });
  });

  _e.on("click", function() {
    d3.event.preventDefault();

    _phi.classed("active", false);
    _pi.classed("active", false);
    _e.classed("active", true);

    numbers.setSubject(Numbers.E, function() {
      stageState.subjectValue = numbers.subjectValue();
    });
  });

  var updateDensitySlider = function(min, max, value) {
    _densitySlider.attr({ min: min, max: max, value: value });
    _densitySlider[0][0].value = value;
  }

  var updateColsSlider = function(min, max, value) {
    _colsSlider.attr({ min: min, max: max, value: value });
    _colsSlider[0][0].value = value;
  }

  var densityValueChanged =  function() {
    stageState.densityValue = +this.value;

    minCols = Math.max(Math.floor(stageState.widthRadiusToCols(minWidth, stageState.dRadius)), 1);
    maxCols = Math.floor(stageState.widthRadiusToCols(window.innerWidth, stageState.dRadius));
    updateColsSlider(minCols, maxCols, stageState.densityValue);
  };

  var columnsValueChanged = function() {
    var v = +this.value;

    stageState.set({
      densityValue: v,
      width: stageState.radiusDensityToWidth(stageState.dRadius,  v)
    });

    maxDensity = stageState.widthRadiusToCols(stageState.width, minRadius);
    updateDensitySlider(minDensity, maxDensity, v);
  };

  //----------------------------------------------------------------------------

  stageState.trigger('change'); // render

  maxCols = Math.floor(stageState.widthRadiusToCols(window.innerWidth, stageState.dRadius));
  minCols = stageState.densityValue;

  maxDensity = stageState.widthRadiusToCols(minWidth, minRadius);

  updateDensitySlider(minDensity, maxDensity, stageState.densityValue);
  updateColsSlider(minCols, maxCols, minCols);

  _densitySlider.on("change", densityValueChanged);
  _densitySlider.on("input", densityValueChanged);

  _colsSlider.on("change", columnsValueChanged);
  _colsSlider.on("input", columnsValueChanged);

  //----------------------------------------------------------------------------

  var digits = d3.selectAll('#digits-radio input');
  var onDigitsChange = function() {
    var value = +this.value;

    numbers.setDigits(+this.value, function() {
      stageState.subjectValue = numbers.subjectValue();
    });
  };

  digits.on('click', function() {
    var value = +this.value;
    var warning = 'Displaying 100k digits or more, can be very resource ' +
      'intensive, even on a powerfull computer. Are you sure you would like ' +
      'to proceed?';

    if (value > 4 && !alreadyWarned) {
      if (confirm(warning)) {
        alreadyWarned = true;
      } else {
        d3.event.preventDefault();
        return false;
      }
    }
  });

  digits.on('change', onDigitsChange);
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import DS from 'ember-data';

var Copyable = Ember.Mixin.create({

  copyable: true,
  copy: function(options) {
    options = options || {};

    var _this = this;
    return new Ember.RSVP.Promise(function(resolve) {

      var model = _this.constructor;
      var copy = _this.get('store').createRecord(model.typeKey);
      var queue = [];

      model.eachAttribute(function(attr) {
        switch(Ember.typeOf(options[attr])) {
          case 'undefined':
              copy.set(attr, _this.get(attr));
              break;
          case 'null':
              copy.set(attr, null);
              break;
          default:
              copy.set(attr, options[attr]);
        }
      });

      model.eachRelationship(function(rel, meta) {
        if (!_this.get(rel)) {
          return;
        }

        var overwrite;
        var passedOptions = {};
        switch(Ember.typeOf(options[rel])) {
          case 'null':
              return;
          case 'instance':
              overwrite = options[rel];
              break;
          case 'object':
              passedOptions = options[rel];
              break;
          default:
        }

        if (_this.get(rel).constructor === DS.PromiseObject) {

          queue.pushObject(_this.get(rel).then(function(obj) {

            if (obj.get('copyable')) {
              return obj.copy(passedOptions).then(function(objCopy) {
                copy.set(rel, overwrite || objCopy);
              });

            } else {
              copy.set(rel, overwrite || obj);
            }

          }));

        } else if (_this.get(rel).constructor === DS.PromiseManyArray) {

          queue.pushObject(_this.get(rel).then(function(array) {

            array.forEach(function(obj) {
              if (obj.get('copyable')) {
                return obj.copy(passedOptions).then(function(objCopy) {
                  copy.get(rel).pushObject(objCopy);
                });

              } else {
                copy.get(rel).pushObject(obj);
              }
            });

          }));

        } else {

          if (meta.kind === 'belongsTo') {
            var obj = _this.get(rel);

            if (obj.get('copyable')) {
              queue.pushObject( obj.copy(passedOptions).then(function(objCopy) {
                copy.set(rel, overwrite || objCopy);
              }));

            } else {
              copy.set(rel, overwrite || obj);
            }

          } else {
            var objs = _this.get(rel);

            if (objs.get('firstObject.copyable')) {

              var copies = objs.map(function(obj) {
                return obj.copy(passedOptions);
              });

              queue.pushObject( Ember.RSVP.all(copies).then( function(resolvedCopies) {
                copy.get(rel).pushObjects(resolvedCopies);
              }));

            } else {
              copy.get(rel).pushObjects(objs);
            }
          }

        }
      });

      Ember.RSVP.all(queue).then(function() {
        resolve(copy);
      });
    });
  }
});

export default Copyable;
<commit_msg>work with hasMany arrays<commit_after>import Ember from 'ember';
import DS from 'ember-data';

var Copyable = Ember.Mixin.create({
  copyable: true,
  copy: function(options) {
    options = options || {};

    var _this = this;
    return new Ember.RSVP.Promise(function(resolve) {

      var model = _this.constructor;
      var copy = _this.get('store').createRecord(model.typeKey);
      var queue = [];

      model.eachAttribute(function(attr) {
        switch(Ember.typeOf(options[attr])) {
          case 'undefined':
              copy.set(attr, _this.get(attr));
              break;
          case 'null':
              copy.set(attr, null);
              break;
          default:
              copy.set(attr, options[attr]);
        }
      });

      model.eachRelationship(function(rel, meta) {
        if (!_this.get(rel)) {
          return;
        }

        var overwrite;
        var passedOptions = {};
        switch(Ember.typeOf(options[rel])) {
          case 'null':
              return;
          case 'instance':
              overwrite = options[rel];
              break;
          case 'object':
              passedOptions = options[rel];
              break;
          default:
        }

        if (_this.get(rel).constructor === DS.PromiseObject) {

          queue.pushObject(_this.get(rel).then(function(obj) {

            if (obj.get('copyable')) {
              return obj.copy(passedOptions).then(function(objCopy) {
                copy.set(rel, overwrite || objCopy);
              });

            } else {
              copy.set(rel, overwrite || obj);
            }

          }));

        } else if (_this.get(rel).constructor === DS.PromiseManyArray) {

          queue.pushObject(_this.get(rel).then(function(array) {

            array.forEach(function(obj) {
              if (obj.get('copyable')) {
                return obj.copy(passedOptions).then(function(objCopy) {
                  copy.get(rel).pushObject(objCopy);
                });

              } else {
                copy.get(rel).pushObject(obj);
              }
            });

          }));

        } else {

          if (meta.kind === 'belongsTo') {
            var obj = _this.get(rel);

            if (obj.get('copyable')) {
              queue.pushObject( obj.copy(passedOptions).then(function(objCopy) {
                copy.set(rel, overwrite || objCopy);
              }));

            } else {
              copy.set(rel, overwrite || obj);
            }

          } else {
            var objs = _this.get(rel);

            if (objs.get('content')) {
              objs = objs.get('content').compact();
            }

            if (objs.get('firstObject.copyable')) {

              var copies = objs.map(function(obj) {
                return obj.copy(passedOptions);
              });

              queue.pushObject( Ember.RSVP.all(copies).then( function(resolvedCopies) {
                copy.get(rel).pushObjects(resolvedCopies);
              }));

            } else {
              copy.get(rel).pushObjects(objs);
            }
          }

        }
      });

      Ember.RSVP.all(queue).then(function() {
        resolve(copy);
      });
    });
  }
});

export default Copyable;
<|endoftext|>


<commit_before>"use strict";
var quotes = [
    {
        story: '(while crying) "I\'ve never ridden a Unicorn!"',
        student: "Naomi",
        grade: 'Kindergarten'
    },
    {
        story: '"Mrs. Kelly, when will we learn how to make e into an mc?"',
        student: "Theresa",
        grade: 3
    },
    {
        story: '"I have a very close die date"... He wanted to say "I have a tight deadline"',
        student: 'Gonzalo',
        grade: 'Adult English Learner'
    },
    {
        story: '"Me to students: "no comments from the peanut gallery!" Matthew: "can I be in the cashew gallery instead? I love cashews!"',
        student: "Matthew",
        grade: 7
    },
    {
        story: 'I had to walk with a cane after injuring my knee. Student: "Mrs. Hamilton, don\'t you worry that this means you\'re getting older?" ',
        student: "Max",
        grade: 7
    },
    {
        story: ' I was copying a definition from Wikipedia and all my students said "Mrs. Hamilton you need to cite your sources, and you said never to use Wikipedia!"',
        student: "Andrew",
        grade: 8
    },
    {
        story: 'Student had a phone call from his mom saying he had lost his key, so she was picking him up after school. ' +
        'I relayed the message and then Max says "it\'s okay, you can use my key!" When the students all look at him funny he says ' +
        '"aren\'t all house keys the same? Like they open all houses?"',
        student: "Max",
        grade: 7
    },
    {
        story: 'I let the students have free time on Fridays as a reward for good behavior and getting homework done. ' +
        'Today a student walked up to me and held up his lttle project he was working on. He was so excited about it. ' +
        'He exclaimed "Mrs. Kelley I just invented paper underwear! " I didn\'t have the heart to point out the flaw in his design.',
        student: 'Jayden',
        grade: 2
    },
    {
        story: '"Ms. K, cats love me. They always come to my house when I\'m home and are like "Heeeey Vanessa what\'s up?"',
        student: "Vanessa",
        grade: "Kindergarten"
    },
    {
        story: 'Jake: "Ms. K!!! I think Josh is going to womit!" Me: "He\'s going to what?" Jake: "WOMIT!" I look over at Josh who is vomiting on the rug. Jake: "Ms. K I think he wommited already."Me: "Yes I think he did vomit Jake... Thank you."',
        student: "Jake",
        grade: "Kindergarten"
    },
    {
        story: 'Ray: "Ms. K I can see your pussy." Me: "You can see what?!?!?" Ray: "I can see your purse-y." As he points to my purse.',
        student: "Ray",
        grade: "Kindergarten"
    },
    {
        story: '"Teacher please tell me your secret, your secret is safe with me"',
        student: "Emmanuel",
        grade: "Preschool"
    },
    {
        story: ' I wasn\'t certain if the student understood the word when she used the vocabulary word embrace in the sentence..."The girl broke her leg so the doctor\'s gave her an embrace."',
        student: 'Amya',
        grade: 2
    },
    {
        story: 'I wore a shirt with a picture of a Jack-o-Lantern on it for Halloween. Myles: "Spooooooky!", he says as he reaches forward and firmly squeezes the Jack-o-Lantern',
        student: 'Myles',
        grade: 'Preschool'
    },
    {
        story: ' I hear from across the room: "I\'M RAISING MY HAND!!!" Kind of defeating the purpose of quietly raising his hand...',
        student: 'Tony',
        grade: 6
    },
    {
        story: 'Overheard after a game of dodgeball at recess: Abdul: "Wow! Max, you came up with a GREAT plan! What was it again?" Max: "To go out there and throw the balls!" Abdul: "Yeah, that was it! That was a great plan!"',
        student: "Abdul and Max",
        grade: 4
    }
];
(function () {
    var story = document.getElementById("story");
    var student = document.getElementById("student");
    var grade = document.getElementById("grade");

    function init() {
        document.getElementById("btn").addEventListener("click", studentSays);
        document.getElementById("tweet-quote").addEventListener("click", tweetThis);
        studentSays();

    }

    function studentSays() {
        var randomNum = Math.floor(Math.random() * quotes.length);
        var studentGrade = "  grade ";
        var studentNameAge = "- " + quotes[randomNum].student;
        //var hashtag = ' #studentSays';

        if (Number(quotes[randomNum].grade)) {
            studentGrade += quotes[randomNum].grade;
        } else {
            studentGrade = "  " + quotes[randomNum].grade;
        }
        studentGrade += "";

        story.innerHTML = quotes[randomNum].story;
        student.innerHTML = studentNameAge;
        grade.innerHTML = studentGrade;
    }

    function tweetThis() {
        var url = "https://twitter.com/intent/tweet?text=" + story.innerHTML + student.innerHTML + "&hashtags=studentSays";
        return window.open(url);
    }

    document.addEventListener("DOMContentLoaded", init);
})();<commit_msg>added stories<commit_after>"use strict";
var quotes = [
    {
        story: '(while crying) "I\'ve never ridden a Unicorn!"',
        student: "Naomi",
        grade: 'Kindergarten'
    },
    {
        story: '"Mrs. Kelly, when will we learn how to make e into an mc?"',
        student: "Theresa",
        grade: 3
    },
    {
        story: '"I have a very close die date"... He wanted to say "I have a tight deadline"',
        student: 'Gonzalo',
        grade: 'Adult English Learner'
    },
    {
        story: '"Me to students: "no comments from the peanut gallery!" Matthew: "can I be in the cashew gallery instead? I love cashews!"',
        student: "Matthew",
        grade: 7
    },
    {
        story: 'I had to walk with a cane after injuring my knee. Student: "Mrs. Hamilton, don\'t you worry that this means you\'re getting older?" ',
        student: "Max",
        grade: 7
    },
    {
        story: ' I was copying a definition from Wikipedia and all my students said "Mrs. Hamilton you need to cite your sources, and you said never to use Wikipedia!"',
        student: "Andrew",
        grade: 8
    },
    {
        story: 'Student had a phone call from his mom saying he had lost his key, so she was picking him up after school. ' +
        'I relayed the message and then Max says "it\'s okay, you can use my key!" When the students all look at him funny he says ' +
        '"aren\'t all house keys the same? Like they open all houses?"',
        student: "Max",
        grade: 7
    },
    {
        story: 'I let the students have free time on Fridays as a reward for good behavior and getting homework done. ' +
        'Today a student walked up to me and held up his lttle project he was working on. He was so excited about it. ' +
        'He exclaimed "Mrs. Kelley I just invented paper underwear! " I didn\'t have the heart to point out the flaw in his design.',
        student: 'Jayden',
        grade: 2
    },
    {
        story: '"Ms. K, cats love me. They always come to my house when I\'m home and are like "Heeeey Vanessa what\'s up?"',
        student: "Vanessa",
        grade: "Kindergarten"
    },
    {
        story: 'Jake: "Ms. K!!! I think Josh is going to womit!" Me: "He\'s going to what?" Jake: "WOMIT!" I look over at Josh who is vomiting on the rug. Jake: "Ms. K I think he wommited already."Me: "Yes I think he did vomit Jake... Thank you."',
        student: "Jake",
        grade: "Kindergarten"
    },
    {
        story: 'Ray: "Ms. K I can see your pussy." Me: "You can see what?!?!?" Ray: "I can see your purse-y." As he points to my purse.',
        student: "Ray",
        grade: "Kindergarten"
    },
    {
        story: '"Teacher please tell me your secret, your secret is safe with me"',
        student: "Emmanuel",
        grade: "Preschool"
    },
    {
        story: ' I wasn\'t certain if the student understood the word when she used the vocabulary word embrace in the sentence..."The girl broke her leg so the doctor\'s gave her an embrace."',
        student: 'Amya',
        grade: 2
    },
    {
        story: 'I wore a shirt with a picture of a Jack-o-Lantern on it for Halloween. Myles: "Spooooooky!", he says as he reaches forward and firmly squeezes the Jack-o-Lantern',
        student: 'Myles',
        grade: 'Preschool'
    },
    {
        story: ' I hear from across the room: "I\'M RAISING MY HAND!!!" Kind of defeating the purpose of quietly raising his hand...',
        student: 'Tony',
        grade: 6
    },
    {
        story: 'Overheard after a game of dodgeball at recess: Abdul: "Wow! Max, you came up with a GREAT plan! What was it again?" Max: "To go out there and throw the balls!" Abdul: "Yeah, that was it! That was a great plan!"',
        student: "Abdul and Max",
        grade: 4
    },
    {
        story: 'Teacher: "Don\'t steal my coffee or I\'ll become" Cathy: "-a raisin!" (I was going to say "cranky")',
        student: 'Cathy',
        grade: 'Kindergarten'
    },
    {
        story: 'We are studying figurative language and I was giving examples of similes. Mrs. Hamilton: "I\'m as cranky as a lion in a cage." Jenny: "Mrs. Hamilton, is this portable your cage?" Mrs. Hamilton: "Yes, yes it is..."',
        student: 'Jenny',
        grade: 7
    },
    {
        story: 'Mary(gestures wildly to group of three boys): "Look how many guy friends I have!" Teresa: "Wow! That\'s a lot!"',
        student: 'Mary',
        grade: 3
    },
    {
        story: 'An 8th grader poses for a picture wearing a tiny stick-on mustache and standing in the Nazi salute Teacher:"Your future self says not to post that picture anywhere" A look of horror and realization spread across his face... Austin:"Hey Reece! Come back here and delete that!"',
        student: 'Austin',
        grade: 8
    }
];
(function () {
    var story = document.getElementById("story");
    var student = document.getElementById("student");
    var grade = document.getElementById("grade");

    function init() {
        document.getElementById("btn").addEventListener("click", studentSays);
        document.getElementById("tweet-quote").addEventListener("click", tweetThis);
        studentSays();

    }

    function studentSays() {
        var randomNum = Math.floor(Math.random() * quotes.length);
        var studentGrade = "  grade ";
        var studentNameAge = "- " + quotes[randomNum].student;
        //var hashtag = ' #studentSays';

        if (Number(quotes[randomNum].grade)) {
            studentGrade += quotes[randomNum].grade;
        } else {
            studentGrade = "  " + quotes[randomNum].grade;
        }
        studentGrade += "";

        story.innerHTML = quotes[randomNum].story;
        student.innerHTML = studentNameAge;
        grade.innerHTML = studentGrade;
    }

    function tweetThis() {
        var url = "https://twitter.com/intent/tweet?text=" + story.innerHTML + student.innerHTML + "&hashtags=studentSays";
        return window.open(url);
    }

    document.addEventListener("DOMContentLoaded", init);
})();<|endoftext|>


<commit_before>Vue.use(VueMaterial);
const app = new Vue({
    el: "#app",
    data: {
        loglevel: "INFO",
        title: "Liquid Radio",
        repoLink: "https://github.com/Trikolon/liquidradio",
        version: "0.5",
        stream: {
            play: false,
            offline: false,
            loading: false,
            volume: 0.6,
            el: "streamEl",
            dom: undefined,
            currentStation: undefined,
            stations
        },
        notification: {
            message: "",
            duration: 4000,
            position: "bottom center",
            el: "notification-bar"
        },
        visualizer: true,
        storageSupported: typeof(Storage) !== "undefined",
        socialLinks: [
            {
                name: "Facebook",
                url: "https://facebook.com/liquidradio.pro"
            },
            {
                name: "Instagram",
                url: "https://instagram.com/liquidradio.pro"
            }
        ]
    },
    watch: {
        "stream.play" (state) {
            if (!state) {
                this.stream.loading = false;
            }
            this.updatePlayState(state);
        },
        "stream.offline" (state) {
            if (state) {
                log.debug("Stream went offline");
                this.stream.play = false;
            }
        },
        "stream.volume" () {
            this.$refs[this.stream.el].volume = this.stream.volume;
        },
        "visualizer" () {
            log.debug("visualizer watch, new value:", this.visualizer);
            if (this.storageSupported) {
                log.debug("Saving state to config");
                localStorage.setItem("visualizer", this.visualizer);
            }
        }
    },
    mounted() {
        this.stream.dom = this.$refs[this.stream.el];

        // Watch external changes
        this.stream.dom.addEventListener("play", () => {
            this.stream.play = true;
            this.stream.loading = true;
        });
        this.stream.dom.addEventListener("pause", () => {
            this.stream.play = false;
        });
        this.stream.dom.addEventListener("volumechange", () => {
            this.stream.volume = this.$refs[this.stream.el].volume;
        });
        this.stream.dom.addEventListener("stalled", () => {
            this.notify("Stream stalled, check your connection.");
        });

        // Audio stream has sufficiently buffered and starts playing
        this.stream.dom.addEventListener("playing", () => {
            this.stream.loading = false;
            this.notify(`Now playing ${this.stream.currentStation.title}`, 2000);
        });

        //Attach error handler to last source element
        const sources = Array.from(this.stream.dom.getElementsByTagName("source"));
        sources[sources.length - 1].addEventListener("error", this.streamError);

        //Attach error handler to audio stream element
        this.stream.dom.addEventListener("error", this.streamError);
    },
    beforeMount() {
        //Set default station to first in station list.
        //This has to be done after data init but before dom-bind.
        [this.stream.currentStation] = this.stream.stations;

        if (this.storageSupported) {
            let volume = localStorage.getItem("volume");
            if (volume) {
                volume = parseFloat(volume);
                this.stream.volume = volume;
            }

            let visualizer = localStorage.getItem("visualizer");
            log.debug("visualizer state", visualizer);
            if (visualizer !== null) {
                this.visualizer = visualizer === "true";
            }
        }
    },
    methods: {
        /**
         * Switches to a different station in stream object and changes play state to true.
         * No action if station id is invalid
         * @param id - Identifier of station to switch to.
         */
        switchStation(id) {
            if (id === this.stream.currentStation.id) return;
            for (let i = 0; i < this.stream.stations.length; i++) {
                if (this.stream.stations[i].id === id) {
                    this.stream.currentStation = this.stream.stations[i];
                    this.stream.currentStationSource = 0;
                    this.stream.play = false;
                    // Wait for vue to update src url in audio element before triggering play()
                    Vue.nextTick(() => {
                        this.catchUp();
                        // this.stream.offline = false;
                        // this.stream.play = true;
                    });
                    log.debug("Switched station to", this.stream.currentStation.title, this.stream.currentStation);
                    return;
                }
            }
            log.error("Attempted to switch to station with invalid station id", id);
        },
        /**
         * Modify stream volume by modifier value. Bounds of volume are 0 - 1
         * @param value - Positive or negative number that will be added.
         */
        changeVolume(value) {
            if (this.stream.volume + value > 1) {
                this.stream.volume = 1;
                log.debug("Hit upper bound for volume ctrl");
            }
            else if (this.stream.volume + value < 0) {
                this.stream.volume = 0;
                log.debug("Hit lower bound for volume ctrl");
            }
            else {
                this.stream.volume = Math.round((this.stream.volume + value) * 10) / 10;
                log.debug(`Modified volume by ${value} to ${this.stream.volume}`);
            }
            // Save volume setting to config
            if (this.storageSupported) {
                localStorage.setItem("volume", this.stream.volume);
            }
        },
        /**
         * Trigger play or pause for audio el depending on state.
         * @param state - true if play, false if pause.
         */
        updatePlayState(state) {
            const el = this.$refs[this.stream.el];
            log.debug("play state changed to", state);
            if (state) {
                el.play();
                log.debug("started stream");
            }
            else {
                el.pause();
                log.debug("stopped stream");
            }
        },
        /**
         * Reloads audio element to catch up in stream.
         */
        catchUp() {
            this.stream.dom.load();
            if (this.stream.play) {
                this.updatePlayState(true);
            }
            else {
                this.stream.play = true;
            }
            this.stream.offline = false;
        },
        /**
         * Error handler audio stream.
         * @param e - Event fired including error information.
         */
        streamError(e) {
            log.error("Error in stream", e);
            let msg = "Unknown Error";

            // Error from source tag
            if (e.target.nodeName === "SOURCE") {
                log.debug("Error originates from SOURCE tag");

                //NETWORK_NO_SOURCE
                if (this.stream.dom.networkState === 3) {
                    msg = "Stream offline"
                }
            }
            // Error from audio tag
            else if (e.target.nodeName === "AUDIO") {
                log.debug("Error originates from AUDIO tag");
                log.error(e.target.error.code, e.target.error.message);
                msg = "Error: ";

                switch (e.target.error.code) {
                    case e.target.error.MEDIA_ERR_ABORTED:
                        msg += "Playback aborted by user.";
                        break;
                    case e.target.error.MEDIA_ERR_NETWORK:
                        msg += "Network error. Check your connection.";
                        break;
                    case e.target.error.MEDIA_ERR_DECODE:
                        msg += "Decoding error.";
                        break;
                    default:
                        msg += `Unknown error code ${e.target.code}`;
                        break;
                }
            }
            this.stream.offline = true;
            this.notify(msg);
        },
        /**
         * Shows notification
         * @param message - Text for notification.
         * @param duration - Duration of visibility.
         */
        notify(message, duration) {
            const el = this.$refs[this.notification.el];
            if (duration) {
                this.notification.duration = duration;
            }
            this.notification.message = message;
            el.open();
        }
    }
});
log.setDefaultLevel(app.loglevel);<commit_msg>Update to app.js<commit_after>Vue.use(VueMaterial);
const app = new Vue({
    el: "#app",
    data: {
        loglevel: "INFO",
        title: "Liquid Radio",
        repoLink: "https://github.com/Trikolon/liquidradio",
        version: "0.5",
        stream: {
            play: false,
            offline: false,
            loading: false,
            volume: parseFloat(localStorage ? localStorage.getItem("volume") || "0.6" : "0.6"),
            el: "streamEl",
            dom: undefined,
            currentStation: undefined,
            stations
        },
        notification: {
            message: "",
            duration: 4000,
            position: "bottom center",
            el: "notification-bar"
        },
        visualizer: JSON.parse(localStorage ? localStorage.getItem("visualizer") || "true" : "true"),
        socialLinks: [
            {
                name: "Facebook",
                url: "https://facebook.com/liquidradio.pro"
            },
            {
                name: "Instagram",
                url: "https://instagram.com/liquidradio.pro"
            }
        ]
    },
    watch: {
        "stream.play" (state) {
            if (!state) {
                this.stream.loading = false;
            }
            this.updatePlayState(state);
        },
        "stream.offline" (state) {
            if (state) {
                log.debug("Stream went offline");
                this.stream.play = false;
            }
        },
        "stream.volume" () {
            this.$refs[this.stream.el].volume = this.stream.volume;
        },
        "visualizer" () {
            log.debug("visualizer watch, new value:", this.visualizer);
            localStorage ? localStorage.setItem("visualizer", this.visualizer) : null;
        }
    },
    mounted() {
        this.stream.dom = this.$refs[this.stream.el];

        // Watch external changes
        this.stream.dom.addEventListener("play", () => {
            this.stream.play = true;
            this.stream.loading = true;
        });
        this.stream.dom.addEventListener("pause", () => {
            this.stream.play = false;
        });
        this.stream.dom.addEventListener("volumechange", () => {
            this.stream.volume = this.$refs[this.stream.el].volume;
        });
        this.stream.dom.addEventListener("stalled", () => {
            this.notify("Stream stalled, check your connection.");
        });

        // Audio stream has sufficiently buffered and starts playing
        this.stream.dom.addEventListener("playing", () => {
            this.stream.loading = false;
            this.notify(`Now playing ${this.stream.currentStation.title}`, 2000);
        });

        //Attach error handler to last source element
        const sources = Array.from(this.stream.dom.getElementsByTagName("source"));
        sources[sources.length - 1].addEventListener("error", this.streamError);

        //Attach error handler to audio stream element
        this.stream.dom.addEventListener("error", this.streamError);
    },
    beforeMount() {
        //Set default station to first in station list.
        //This has to be done after data init but before dom-bind.
        [this.stream.currentStation] = this.stream.stations;

    },
    methods: {
        /**
         * Switches to a different station in stream object and changes play state to true.
         * No action if station id is invalid
         * @param id - Identifier of station to switch to.
         */
        switchStation(id) {
            if (id === this.stream.currentStation.id) return;
            for (let i = 0; i < this.stream.stations.length; i++) {
                if (this.stream.stations[i].id === id) {
                    this.stream.currentStation = this.stream.stations[i];
                    this.stream.currentStationSource = 0;
                    this.stream.play = false;
                    // Wait for vue to update src url in audio element before triggering play()
                    Vue.nextTick(() => {
                        this.catchUp();
                        // this.stream.offline = false;
                        // this.stream.play = true;
                    });
                    log.debug("Switched station to", this.stream.currentStation.title, this.stream.currentStation);
                    return;
                }
            }
            log.error("Attempted to switch to station with invalid station id", id);
        },
        /**
         * Modify stream volume by modifier value. Bounds of volume are 0 - 1
         * @param value - Positive or negative number that will be added.
         */
        changeVolume(value) {
            if (this.stream.volume + value > 1) {
                this.stream.volume = 1;
                log.debug("Hit upper bound for volume ctrl");
            }
            else if (this.stream.volume + value < 0) {
                this.stream.volume = 0;
                log.debug("Hit lower bound for volume ctrl");
            }
            else {
                this.stream.volume = Math.round((this.stream.volume + value) * 10) / 10;
                log.debug(`Modified volume by ${value} to ${this.stream.volume}`);
            }
            // Save volume setting to config
            localStorage ? localStorage.setItem("volume", this.stream.volume) : null;
        },
        /**
         * Trigger play or pause for audio el depending on state.
         * @param state - true if play, false if pause.
         */
        updatePlayState(state) {
            const el = this.$refs[this.stream.el];
            log.debug("play state changed to", state);
            if (state) {
                el.play();
                log.debug("started stream");
            }
            else {
                el.pause();
                log.debug("stopped stream");
            }
        },
        /**
         * Reloads audio element to catch up in stream.
         */
        catchUp() {
            this.stream.dom.load();
            if (this.stream.play) {
                this.updatePlayState(true);
            }
            else {
                this.stream.play = true;
            }
            this.stream.offline = false;
        },
        /**
         * Error handler audio stream.
         * @param e - Event fired including error information.
         */
        streamError(e) {
            log.error("Error in stream", e);
            let msg = "Unknown Error";

            // Error from source tag
            if (e.target.nodeName === "SOURCE") {
                log.debug("Error originates from SOURCE tag");

                //NETWORK_NO_SOURCE
                if (this.stream.dom.networkState === 3) {
                    msg = "Stream offline"
                }
            }
            // Error from audio tag
            else if (e.target.nodeName === "AUDIO") {
                log.debug("Error originates from AUDIO tag");
                log.error(e.target.error.code, e.target.error.message);
                msg = "Error: ";

                switch (e.target.error.code) {
                    case e.target.error.MEDIA_ERR_ABORTED:
                        msg += "Playback aborted by user.";
                        break;
                    case e.target.error.MEDIA_ERR_NETWORK:
                        msg += "Network error. Check your connection.";
                        break;
                    case e.target.error.MEDIA_ERR_DECODE:
                        msg += "Decoding error.";
                        break;
                    default:
                        msg += `Unknown error code ${e.target.code}`;
                        break;
                }
            }
            this.stream.offline = true;
            this.notify(msg);
        },
        /**
         * Shows notification
         * @param message - Text for notification.
         * @param duration - Duration of visibility.
         */
        notify(message, duration) {
            const el = this.$refs[this.notification.el];
            if (duration) {
                this.notification.duration = duration;
            }
            this.notification.message = message;
            el.open();
        }
    }
});
log.setDefaultLevel(app.loglevel);<|endoftext|>


<commit_before>"use strict"; // E C M A S C R I P T

//hardcoded streamlist
//2d array with name of stream and stream properties
var streamList = {
    "ESL_SC2": {},
    "nightblue3": {},
    "doublelift": {},
    "freecodecamp": {},
    "imaqtpie": {},
};

//onload
$(document).ready(function() {
    updateLists();
});

//gets dem channels J S O N
function getChannels(channel) {
    //api links used
    var channelApiLink = "https://wind-bow.gomix.me/twitch-api/channels/" + channel;
    var streamApiLink = "https://wind-bow.gomix.me/twitch-api/streams/" + channel;

    // return variables
    var returnObject = {};

    $.getJSON(streamApiLink).done(updateStream).fail(errStream); //JSON request

    // if JSON request goes through
    function updateStream(data) {
        var streamText = JSON.stringify(data["stream"]);

        //check if channel exists and is online.
        if (streamText === "null") { //if channel is offline or DNE
            $.getJSON(channelApiLink).done(updateChannel).fail(errChannel); //JSON request

            function updateChannel(channeldat) {
                var channelText = JSON.stringify(channeldat["status"]);
                if ($.isNumeric(channelText)) { //if DNE
                    returnObject = {
                        "streamName": null,
                        "message": null,
                        "game": null,
                        "imageLink": null,
                        "online": false
                    };
                } else { //if offline
                    returnObject = {
                        "streamName": JSON.stringify(channeldat["display_name"]).replace(/"/g, ""),
                        "message": JSON.stringify(channeldat["status"]).replace(/"/g, ""),
                        "game": JSON.stringify(channeldat["game"]).replace(/"/g, ""),
                        "imageLink": JSON.stringify(channeldat["logo"]).replace(/"/g, ""),
                        "online": false
                    }
                }
                console.log(returnObject);
                addToStreamList(channel, returnObject);
                populatePanels(channel);
            }

            function errChannel(jqxhr, textStatus, err) {
                console.log("Channel Request Failed: " + textStatus + ", " + err);
            }

        } else { //if channel is online
            returnObject = {
                "streamName": JSON.stringify(data["stream"]["channel"]["display_name"]).replace(/"/g, ""),
                "message": JSON.stringify(data["stream"]["channel"]["status"]).replace(/"/g, ""),
                "game": JSON.stringify(data["stream"]["game"]).replace(/"/g, ""),
                "imageLink": JSON.stringify(data["stream"]["channel"]["logo"]).replace(/"/g, ""),
                "online": true
            }
            console.log(returnObject);
            addToStreamList(channel, returnObject);
            populatePanels(channel);
        }
    }

    //if JSON request does not go through
    function errStream(jqxhr, textStatus, err) {
        console.log("Stream Request Failed: " + textStatus + ", " + err);
    }

}

//adds streaminfo to streamlist
function addToStreamList(channel, returnObject) {
    streamList[channel] = returnObject;
}

//pull stream data for each thing in streamlist
function updateLists() {
    for (var prop in streamList) {
        getChannels(prop);
    }
}

function populatePanels(prop) {
    let streamName = streamList[prop]["streamName"];
    let message = streamList[prop]["message"];
    let game = streamList[prop]["game"];
    let imageLink = streamList[prop]["imageLink"];
    let online = streamList[prop]["online"];
    let color = "";

    if (online) {
        color = "green";
    } else {
        color = "red";
    }

    //insert in housing panels
    $('
', {
        class: "panel-body",
        id: streamName,
        html: "
" + streamName + "
",
        style: "color:" + color
    }).insertAfter('#pan-head');

    $('
', {
        class: "message",
        id: prop + "message",
        html: "
" + message + "
"
    }).appendTo('#' + streamName);

    $('
', {
        class: "game",
        id: prop + "game",
        html: "
" + game + "
"
    }).insertAfter('#' + prop + "message");

    $('
', {
        class: "imageLink",
        id: prop + "imageLink",
        html: "
" + imageLink + "
"
    }).insertAfter('#' + prop + "game");
}

function removeItem() {

}

function addItem() {

}<commit_msg>got populating views to work<commit_after>"use strict"; // E C M A S C R I P T

//hardcoded streamlist
//2d array with name of stream and stream properties
var streamList = {
    "ESL_SC2": {},
    "nightblue3": {},
    "doublelift": {},
    "freecodecamp": {},
    "imaqtpie": {},
    "arumba07": {}
};

//onload
$(document).ready(function() {
    updateLists();
});

//gets dem channels J S O N
function getChannels(channel) {
    //api links used
    var channelApiLink = "https://wind-bow.gomix.me/twitch-api/channels/" + channel;
    var streamApiLink = "https://wind-bow.gomix.me/twitch-api/streams/" + channel;

    // return variables
    var returnObject = {};

    $.getJSON(streamApiLink).done(updateStream).fail(errStream); //JSON request

    // if JSON request goes through
    function updateStream(data) {
        var streamText = JSON.stringify(data["stream"]);

        //check if channel exists and is online.
        if (streamText === "null") { //if channel is offline or DNE
            $.getJSON(channelApiLink).done(updateChannel).fail(errChannel); //JSON request

            function updateChannel(channeldat) {
                var channelText = JSON.stringify(channeldat["status"]);
                if ($.isNumeric(channelText)) { //if DNE
                    returnObject = {
                        "streamName": null,
                        "message": null,
                        "game": null,
                        "imageLink": null,
                        "online": false
                    };
                } else { //if offline
                    returnObject = {
                        "streamName": JSON.stringify(channeldat["display_name"]).replace(/"/g, ""),
                        "message": JSON.stringify(channeldat["status"]).replace(/"/g, ""),
                        "game": JSON.stringify(channeldat["game"]).replace(/"/g, ""),
                        "imageLink": JSON.stringify(channeldat["logo"]).replace(/"/g, ""),
                        "online": false
                    }
                }
                console.log(returnObject);
                addToStreamList(channel, returnObject);
                populatePanels(channel);
            }

            function errChannel(jqxhr, textStatus, err) {
                console.log("Channel Request Failed: " + textStatus + ", " + err);
            }

        } else { //if channel is online
            returnObject = {
                "streamName": JSON.stringify(data["stream"]["channel"]["display_name"]).replace(/"/g, ""),
                "message": JSON.stringify(data["stream"]["channel"]["status"]).replace(/"/g, ""),
                "game": JSON.stringify(data["stream"]["game"]).replace(/"/g, ""),
                "imageLink": JSON.stringify(data["stream"]["channel"]["logo"]).replace(/"/g, ""),
                "online": true
            }
            console.log(returnObject);
            addToStreamList(channel, returnObject);
            populatePanels(channel);
        }
    }

    //if JSON request does not go through
    function errStream(jqxhr, textStatus, err) {
        console.log("Stream Request Failed: " + textStatus + ", " + err);
    }

}

//adds streaminfo to streamlist
function addToStreamList(channel, returnObject) {
    streamList[channel] = returnObject;
}

//pull stream data for each thing in streamlist
function updateLists() {
    for (var prop in streamList) {
        getChannels(prop);
    }
}

function populatePanels(prop) {
    let streamName = streamList[prop]["streamName"];
    let message = streamList[prop]["message"];
    let game = streamList[prop]["game"];
    let imageLink = streamList[prop]["imageLink"];
    let online = streamList[prop]["online"];
    let color = "";
    let datasrt = '0';

    if (online) {
        color = "green";
        datasrt = '1';
    } else {
        color = "red";
        datasrt = '2';
    }

    //insert in housing panels
    $('
', {
        class: "panel-body ",
        id: streamName,
        html: "
" + streamName + "
",
        style: "color:" + color,
        "data-sort": datasrt
    }).insertAfter('#pan-head');

    $('
', {
        class: "game",
        id: prop + "game",
        html: "
" + game + "
"
    }).appendTo('#' + streamName);

    $('
', {
        class: "message",
        id: prop + "message",
        html: "
" + message + "
"
    }).insertAfter('#' + prop + "game");

    $('
', {
        class: "imageLink",
        id: prop + "imageLink",
        html: "
" + imageLink + "
"
    }).insertAfter('#' + prop + "message");

    //sorts div to show online first - based off of http://stackoverflow.com/questions/17017148/ordering-divs-based-on-class-name-using-javascript-jquery
    /* $('div').sort(function(a, b) {
         var contentA = parseInt($(a).attr('data-sort'));
         var contentB = parseInt($(b).attr('data-sort'));
         return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0;
     }) */

    $('#' + streamName).sortDivs();
}

function removeItem() {

}

function addItem() {

}

jQuery.fn.sortDivs = function sortDivs() {
    $("> div", this[0]).sort(dec_sort).appendTo(this[0]);

    function dec_sort(a, b) {
        return ($(b).data("sort")) < ($(a).data("sort")) ? 1 : -1;
    }
}<|endoftext|>


<commit_before>(function($) {

	$.fn.druckerfreund = function(params) {
		var options = $.extend({
			data: 'data/printers.json',
			drivers: 'data/drivers.json'
		}, params);
		var printers = {};
		var driver = {};
		var Super = this;
		var def = '';
		var model = {
			printer: function(data){
				var o = def === data.qname ? '-d' : '';
				var name = data.name === '' ? data.qname : data.name;
				return '/usr/sbin/lpadmin -p ' + data.qname + o + ' -L "'
					+ data.location + '" -E -v ' + options.domain + data.name
					+ ' -P "/Library/Printers/PPDs/Contents/Resources/' + driver[data.driver] + '"'
					+ ' -D "' +  name + '"';
			}
		};
		$.getJSON( options.data, function( data ) {
			$.each( data, function( n, item ) {
				printers[item.qname] = item;
				var option = $('<option value=\"' + item.qname + '\">' + item.name + '</option>');
				if($("optgroup[label=\'" + item.group + "\']").html() == null ) $(Super).append('<optgroup label=\"' + item.group + '\"></optgroup>');
				$("optgroup[label=\'" + item.group + "\']").append(option);
			});
		});
		$.getJSON( options.drivers, function( data ) {
			driver = data;
		});
		options.thatbooton.click(function(){
			options.shell.html('');
			$('option:selected', $(Super)).each(function() {
				options.shell.append('
' + model.printer(printers[$(this).attr('value')]) + '
');
			});
			window.location.href = '#shell';
		});
		$(Super).change(function(){
			if($('option:selected', Super).length > 0){
				$(options.def_printer).html('<option></option>')
				$('option:selected', Super).each(function() {
					 $(options.def_printer).append('<option value=\"' + $(this).attr('value') + '\">' + $(this).attr('value') + '</option>');
				})
				$(options.def_printer).prop('disabled', false);
			}else{
				$(options.def_printer).html('<option></option>')
				$(options.def_printer).prop('disabled', true);
				def = '';
			}
		});
		$(options.def_printer).change(function(){
			$('option:selected', options.def_printer).each(function() {
				def = $(this).attr('value');
			})
		})
	};

}(jQuery));<commit_msg>Fixed set printer default bug<commit_after>(function($) {

	$.fn.druckerfreund = function(params) {
		var options = $.extend({
			data: 'data/printers.json',
			drivers: 'data/drivers.json'
		}, params);
		var printers = {};
		var driver = {};
		var Super = this;
		var def = '';
		var model = {
			printer: function(data){
				var o = def === data.qname ? ' -d ' : '';
				var name = data.name === '' ? data.qname : data.name;
				return '/usr/sbin/lpadmin -p ' + data.qname + o + '-L "'
					+ data.location + '" -E -v ' + options.domain + data.name
					+ ' -P "/Library/Printers/PPDs/Contents/Resources/' + driver[data.driver] + '"'
					+ ' -D "' +  name + '"';
			}
		};
		$.getJSON( options.data, function( data ) {
			$.each( data, function( n, item ) {
				printers[item.qname] = item;
				var option = $('<option value=\"' + item.qname + '\">' + item.name + '</option>');
				if($("optgroup[label=\'" + item.group + "\']").html() == null ) $(Super).append('<optgroup label=\"' + item.group + '\"></optgroup>');
				$("optgroup[label=\'" + item.group + "\']").append(option);
			});
		});
		$.getJSON( options.drivers, function( data ) {
			driver = data;
		});
		options.thatbooton.click(function(){
			options.shell.html('');
			$('option:selected', $(Super)).each(function() {
				options.shell.append('
' + model.printer(printers[$(this).attr('value')]) + '
');
			});
			window.location.href = '#shell';
		});
		$(Super).change(function(){
			if($('option:selected', Super).length > 0){
				$(options.def_printer).html('<option></option>')
				$('option:selected', Super).each(function() {
					 $(options.def_printer).append('<option value=\"' + $(this).attr('value') + '\">' + $(this).attr('value') + '</option>');
				})
				$(options.def_printer).prop('disabled', false);
			}else{
				$(options.def_printer).html('<option></option>')
				$(options.def_printer).prop('disabled', true);
				def = '';
			}
		});
		$(options.def_printer).change(function(){
			$('option:selected', options.def_printer).each(function() {
				def = $(this).attr('value');
			})
		})
	};

}(jQuery));
<|endoftext|>


<commit_before>function disableZoomHandlers(map) {
  map.touchZoom.disable();
  map.doubleClickZoom.disable();
  map.scrollWheelZoom.disable();
  if (map.tap) map.tap.disable();
}

//TODO
function resetColors() {
    for (var i = 0; i < geoJson.length; i++) {
        geoJson[i].properties['marker-color'] =
            geoJson[i].properties['old-color'] || geoJson[i].properties['marker-color'];
    }
    myLayer.setGeoJSON(geoJson);
}

function clone(o) {
  return jQuery.extend({}, o);
}
<commit_msg>Js code for hiding and showing elements.<commit_after>function disableZoomHandlers(map) {
  map.touchZoom.disable();
  map.doubleClickZoom.disable();
  map.scrollWheelZoom.disable();
  if (map.tap) map.tap.disable();
}

// TODO
function resetColors() {
    for (var i = 0; i < geoJson.length; i++) {
        geoJson[i].properties['marker-color'] =
            geoJson[i].properties['old-color'] || geoJson[i].properties['marker-color'];
    }
    myLayer.setGeoJSON(geoJson);
}

function clone(o) {
  return jQuery.extend({}, o);
}

function hideQuotes() {
  $('#quotes').fadeTo(2000, 0.0);
  $('#map').fadeTo(2000, 1.0);
}

function showQuotes() {
  $('#quotes').fadeTo(2000, 1.0);
  $('#map').fadeTo(2000, 0.3);
}

<|endoftext|>


<commit_before>$(document).ready(function() {

  $(".commentlist li").addClass("panel panel-default");
	$(".comment-reply-link").addClass("btn btn-default");

  	/*
	"Hovernav" navbar dropdown on hover
	Delete this segment if you don't want it, and delete the corresponding CSS in bst.css
	Uses jQuery Media Query - see http://www.sitepoint.com/javascript-media-queries/
	*/
	var mq = window.matchMedia('(min-width: 768px)');
  if (mq.matches) {
    $('ul.navbar-nav li').addClass('hovernav');
  } else {
  	$('ul.navbar-nav li').removeClass('hovernav');
  };
  	/*
	The addClass/removeClass also needs to be triggered on page resize <=> 768px
	*/
  if (matchMedia) {
    var mq = window.matchMedia('(min-width: 768px)');
    mq.addListener(WidthChange);
    WidthChange(mq);
  }
	function WidthChange(mq) {
    if (mq.matches) {
      $('ul.navbar-nav li').addClass('hovernav');
    } else {
      $('ul.navbar-nav li').removeClass('hovernav');
    }
  };

  	/*
	Woocommerce re-styling
	*/
  $('div.woocommerce').wrapInner('

');
  $('select, .input-text, textarea').addClass('form-control');

});
<commit_msg>Update bst.js<commit_after>$(document).ready(function() {

  $(".commentlist li").addClass("panel panel-default");
	$(".comment-reply-link").addClass("btn btn-default");

  	/*
	"Hovernav" navbar dropdown on hover
	Delete this segment if you don't want it, and delete the corresponding CSS in bst.css
	Uses jQuery Media Query - see http://www.sitepoint.com/javascript-media-queries/
	*/
	var mq = window.matchMedia('(min-width: 768px)');
  if (mq.matches) {
    $('ul.navbar-nav li').addClass('hovernav');
  } else {
  	$('ul.navbar-nav li').removeClass('hovernav');
  };
  	/*
	The addClass/removeClass also needs to be triggered on page resize <=> 768px
	*/
  if (matchMedia) {
    var mq = window.matchMedia('(min-width: 768px)');
    mq.addListener(WidthChange);
    WidthChange(mq);
  }
	function WidthChange(mq) {
    if (mq.matches) {
      $('ul.navbar-nav li').addClass('hovernav');
    } else {
      $('ul.navbar-nav li').removeClass('hovernav');
    }
  };
	/*
	Forms
	*/
  $('select, input[type=text], input[type=email], input[type=password], textarea').addClass('form-control');

  	/*
	Woocommerce re-styling
	*/
  $('div.woocommerce').wrapInner('

');

});
<|endoftext|>