<commit_before>
// for template rendering in the views below
_.templateSettings = {
  interpolate : /\{\{(.+?)\}\}/g
};

function listsAreEqual(a, b) {
  if (a.length !== b.length) return false;
  for (var i=0; i<a.length; i++) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}

var Suggestion = Backbone.Model.extend({});

var SuggestionView = Backbone.View.extend({
  model: Suggestion,

  tagName: "li",

  className: "suggestion",

  template: _.template( $('#suggestion-template').html() ),

  initialize: function() {
    _.bindAll(this, 'render');
  },

  render: function() {
    $(this.el).html(this.template(this.model.toJSON()));
    return this;
  }

});

var Response = Backbone.Model.extend({
  defaults: {
    score: 0,
    parentCommentId: null
  },

  // When we save a comment, we let the server take care
  // of folding it into the Wish model and saving the whole
  // thing.
  url: function() {
    if (this.isNew) {
      return '/response';
    } else {
      return '/response/' + this.get('_id');
    }
  },
});

var ResponseView = Backbone.View.extend({
  model: Response,

  tagName: "div",

  template: _.template( $('#response-template').html() ),

  initialize: function() {
    _.bindAll(this, 'render');
    this.model.bind('change', this.render);
    this.model.view = this;
  },

  render: function() {
    $(this.el).html(this.template(this.model.toJSON()));
    return this;
  }
});

var ResponseCollection = Backbone.Collection.extend({
  model: Response
})

// ----------------------------------------------------------------------
// Comments.
//
// Comments are children of a Wish.
// Each comment can have a collection of Responses to it

var Comment = Backbone.Model.extend({
  defaults: {
    score: 0,
    parentWishId: null
  },

  // When we save a comment, we let the server take care
  // of folding it into the Wish model and saving the whole
  // thing.
  url: function() {
    if (this.isNew) {
      return '/comment';
    } else {
      return '/comment/' + this.get('_id');
    }
  },

  initialize: function() {
    if (! this.get('created') ) {
      this.set({created: new Date});
    }

    this.responses = new ResponseCollection;
    this.responses.refresh(this.get('responses'));
  },

  voteFor: function() {
    now.voteForComment(this.get('_id'));
  }
});

var CommentView = Backbone.View.extend({
  model: Comment,

  tagName: "div",

  template: _.template( $('#comment-template').html() ),

  events: {
    'click .new-response': 'new_response'
  },

  initialize: function() {
    _.bindAll(this, 'render');
    this.model.bind('change', this.render);
    this.model.view = this;
  },

  new_response: function(event) {
    event.stopPropagation();
    event.preventDefault();

    var textarea = $(event.currentTarget).closest('.addResponse').find('textarea');
    var text = textarea.val();
    textarea.val("");
    console.log("got text: " + text);

    text = text.trim();
    if (! text) {
      return;
    }

    var response = new Response({
      parentWishId: this.model.get('parentWishId'),
      parentCommentId: this.model.get('_id'),
      text: text,
      whose: this.model.get('whose')});
    this.model.responses.add(response);
    console.log("adding: " + response);
    response.save();
    this.render();
  },

  render: function() {
    var self = this;
    $(this.el).html(this.template(this.model.toJSON()));

    this.model.responses.each( function(response) {
      var responseView = new ResponseView({model: response});
      self.$('.responses').append(responseView.render().el);
    });
    return this;
  }
});

var CommentCollection = Backbone.Collection.extend({
  model: Comment
});

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

var Wish = Backbone.Model.extend({
  url: function() {
    if (this.id && this.id.match(/random.json.*/)) {
      return '/wish/' + this.id;
    } else if (this.isNew) {
      return '/wish';
    } else {
      return '/wish/' + this.get('_id');
    }
  },

  initialize: function() {
    if (! this.get('created') ) {
      this.set({created: new Date});
    }

    this.comments = new CommentCollection;
    this.comments.refresh(this.get('comments'));
  },

  voteFor: function() {
    now.voteForId(this.get('_id'));
  }

});

var WishView = Backbone.View.extend({
  model: Wish,

  tagName: "div",

  template: _.template( $('#wish-template').html() ),

  events: {
    'click .new-comment': 'new_comment',
    'click .more': 'more',
    'click .flag': 'flag'
  },

  initialize: function() {
    _.bindAll(this, 'render');
    this.model.bind('change', this.render);
    this.model.view = this;
    this.viewer = null;
  },

  setViewer: function(username) {
    this.viewer = username;
  },

  more: function(event) {
    // When somebody clicks the 'more' button on an item,
    // hide all the other items.  (The view for the clicked
    // item itself deals with toggling itself open/closed.)
    var button = $(event.currentTarget);
    var wishElem = button.closest('.wish');

    if  (button.text() === 'show discussion') {
      button.text("hide discussion");
    } else {
      button.text("show discussion");
    }

    this.$('.comments-container').toggle();

    // bug - this can move the location of the button in the flow
    // with no mouseout event, so the button will remain highlighted
    $('#application .wish').not(wishElem).toggle();
  },

  flag: function(event) {
    // flag as inappropriate
    console.log('flagged by ' + this.viewer);
  },

  new_comment: function(event) {
    event.stopPropagation();
    event.preventDefault();

    // refactor w/ new_response
    var textarea = $(event.currentTarget).closest('.addComment').find('textarea');
    var text = textarea.val();
    textarea.val("");

    text = text.trim();
    if (! text) {
      return;
    }

    var comment = new Comment({
      parentWishId: this.model.get('_id'),
      text: text,
      whose: this.model.get('whose')});
    this.model.comments.add(comment);
    comment.save();
    // add a view
    commentView = new CommentView({model: comment});
    self.$('.comments').append(commentView.render().el);
  },

  edit: function() {
    $(this.el).addClass("editing");
    // noodly oodly oodly
    this.input.focus();
  },

  render: function() {
    var self = this;
    $(this.el).html(this.template(this.model.toJSON()));

    this.model.comments.each( function(comment) {
      comment.set({'parentWishId': self.model.get('_id')});
      commentView = new CommentView({model: comment});
      self.$('.comments').append(commentView.render().el);
    });

    return this;
  }
});

var WishCollection = Backbone.Collection.extend({ model: Wish });

// ----------------------------------------------------------------------
// the view for the vote page - the main application view

var NewWishApplication = Backbone.Model.extend({});

var NewWishApplicationView = Backbone.View.extend({
  model: Wish,

  el: $('#wish-application'),

  initialize: function() {
    this.currentCompletions = [];
  },

  events: {
    'click .submit': 'commit',
    'keydown .newWish': 'searchKeydown',
    'click .newWish': 'cancelSearch'
  },

  cancelSearch: function(event) {
    this.$('li.suggestion').remove();
  },

  searchKeydown: function(event) {
    // grab the existing text, and the key just pressed
    var self = this;
    var text = $('.newWish textarea').val();
    text += String.fromCharCode(event.which);

    // bug - doesn't catch select-all + delete
    // doesn't catch ctrl-a ctrl-k
    if (text.trim() === "") {
      return this.$('li.suggestion').remove();
    }

    // replace existing suggestion list with
    // results from completer search
    now.search(text, 10, function(err, results) {
      if (!listsAreEqual(results, self.currentCompletions)) {
        self.$('li.suggestion').remove();
        _.each(results, function(result) {
          // results are lists of [docid:text, ...]
          // so split the id and the text apart
          var sep = result.match(":").index;
          var id = result.slice(0, sep);
          var text = result.slice(sep+1);

          var suggestion = new Suggestion({_id: id, text: text});
          var view = new SuggestionView({model:suggestion});

          self.$('.suggestions').append(view.render().el);
        });
        self.currentCompletions = results;
      }
    });

  },

  commit: function(event) {
    //var wish = new Wish();
    var comment = new Comment;
    var commentCollection = new CommentCollection;

    comment.set({
        text: this.$('.newWishComment textarea').val(),
        whose: this.model.get('whose')});
    commentCollection.add(comment);

    this.model.set({
        text: this.$('.newWish textarea').val(),
        comments: commentCollection});

    this.model.save();
    this.el.fadeOut(200);

    // having made a wish, go compare with others
    location.replace('/vote/'+this.model.get('_id'))
  }
});

var ListApplication = Backbone.Model.extend({});
var ListApplicationView = Backbone.View.extend({
  model: ListApplication,

  el: $("#list-application"),

  initialize: function() {
    _.bindAll(this, 'addOne', 'render');
  },

  addOne: function(wish) {
    var view = new WishView({model: wish});
    $(this.el).append(view.render().el);
  }
});

// ----------------------------------------------------------------------
// voting for one wish over another

var VoteApplication = Backbone.Model.extend({});

var VoteApplicationView = Backbone.View.extend({
  model: VoteApplication,

  el: $("#vote-application"),

  events: {
    'click .vote': 'vote',
  },

  initialize: function() {
    this.views = [];
    _.bindAll(this, 'addOne', 'render');
    // we would fetch() here, except that the stuff's already in the dom
    // via the server template.
  },

  vote: function(event) {
    var self = this;
    var notIds = _.map(self.views, function(view) { return view.model.get('_id')} ).join(',');

    var toRemove = [];
    _.each(this.views, function(view) {
      if (!view.el.contains(event.currentTarget)) {
        // mark me for removal
        toRemove.unshift(view);
      } else {
        // vote for me!
        view.model.voteFor();
      }
    });

    // remove views that weren't voted for
    _.each(toRemove, function(r) { self.removeView(r)});

    var wish = new Wish({id: 'random.json/not/'+notIds});
    wish.fetch({
      error: function(resp) {
        console.error(resp);
      },
      success: function(model, resp) {
        self.addOne(wish);
      }
    });
  },

  removeView: function(view) {
    this.views.splice(this.views.indexOf(view), 1);
    view.remove();
  },

  addOne: function(wish) {
    var view = new WishView({model: wish});
    view.setViewer(this.model.get('username'));
    $(this.el).append(view.render().el);
    this.views.unshift(view);
  },
});

<commit_msg>added karma on votes/upvotes<commit_after>
// for template rendering in the views below
_.templateSettings = {
  interpolate : /\{\{(.+?)\}\}/g
};

function listsAreEqual(a, b) {
  if (a.length !== b.length) return false;
  for (var i=0; i<a.length; i++) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}

var Suggestion = Backbone.Model.extend({});

var SuggestionView = Backbone.View.extend({
  model: Suggestion,

  tagName: "li",

  className: "suggestion",

  template: _.template( $('#suggestion-template').html() ),

  initialize: function() {
    _.bindAll(this, 'render');
  },

  render: function() {
    $(this.el).html(this.template(this.model.toJSON()));
    return this;
  }

});

var Response = Backbone.Model.extend({
  defaults: {
    score: 0,
    parentCommentId: null
  },

  // When we save a comment, we let the server take care
  // of folding it into the Wish model and saving the whole
  // thing.
  url: function() {
    if (this.isNew) {
      return '/response';
    } else {
      return '/response/' + this.get('_id');
    }
  },

  upVote: function(username) {
    now.upVoteResponse(this.get('_id'), username);
  }

});

var ResponseView = Backbone.View.extend({
  model: Response,

  tagName: "div",

  template: _.template( $('#response-template').html() ),

  initialize: function() {
    _.bindAll(this, 'render');
    this.model.bind('change', this.render);
    this.model.view = this;
  },

  render: function() {
    $(this.el).html(this.template(this.model.toJSON()));
    return this;
  }
});

var ResponseCollection = Backbone.Collection.extend({
  model: Response
})

// ----------------------------------------------------------------------
// Comments.
//
// Comments are children of a Wish.
// Each comment can have a collection of Responses to it

var Comment = Backbone.Model.extend({
  defaults: {
    score: 0,
    parentWishId: null
  },

  // When we save a comment, we let the server take care
  // of folding it into the Wish model and saving the whole
  // thing.
  url: function() {
    if (this.isNew) {
      return '/comment';
    } else {
      return '/comment/' + this.get('_id');
    }
  },

  initialize: function() {
    if (! this.get('created') ) {
      this.set({created: new Date});
    }

    this.responses = new ResponseCollection;
    this.responses.refresh(this.get('responses'));
  },

  upVote: function(username) {
    now.upVoteComment(this.get('_id'), username);
  }
});

var CommentView = Backbone.View.extend({
  model: Comment,

  tagName: "div",

  template: _.template( $('#comment-template').html() ),

  events: {
    'click .new-response': 'new_response'
  },

  initialize: function() {
    _.bindAll(this, 'render');
    this.model.bind('change', this.render);
    this.model.view = this;
  },

  new_response: function(event) {
    event.stopPropagation();
    event.preventDefault();

    var textarea = $(event.currentTarget).closest('.addResponse').find('textarea');
    var text = textarea.val();
    textarea.val("");
    console.log("got text: " + text);

    text = text.trim();
    if (! text) {
      return;
    }

    var response = new Response({
      parentWishId: this.model.get('parentWishId'),
      parentCommentId: this.model.get('_id'),
      text: text,
      whose: this.model.get('whose')});
    this.model.responses.add(response);
    console.log("adding: " + response);
    response.save();
    this.render();
  },

  render: function() {
    var self = this;
    $(this.el).html(this.template(this.model.toJSON()));

    this.model.responses.each( function(response) {
      var responseView = new ResponseView({model: response});
      self.$('.responses').append(responseView.render().el);
    });
    return this;
  }
});

var CommentCollection = Backbone.Collection.extend({
  model: Comment
});

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

var Wish = Backbone.Model.extend({
  url: function() {
    if (this.id && this.id.match(/random.json.*/)) {
      return '/wish/' + this.id;
    } else if (this.isNew) {
      return '/wish';
    } else {
      return '/wish/' + this.get('_id');
    }
  },

  initialize: function() {
    if (! this.get('created') ) {
      this.set({created: new Date});
    }

    this.comments = new CommentCollection;
    this.comments.refresh(this.get('comments'));
  },

  voteFor: function(username) {
    now.voteForWish(this.get('_id'), username);
  }

});

var WishView = Backbone.View.extend({
  model: Wish,

  tagName: "div",

  template: _.template( $('#wish-template').html() ),

  events: {
    'click .new-comment': 'new_comment',
    'click .more': 'more',
    'click .flag': 'flag'
  },

  initialize: function() {
    _.bindAll(this, 'render');
    this.model.bind('change', this.render);
    this.model.view = this;
    this.viewer = null;
  },

  setViewer: function(username) {
    this.viewer = username;
  },

  more: function(event) {
    // When somebody clicks the 'more' button on an item,
    // hide all the other items.  (The view for the clicked
    // item itself deals with toggling itself open/closed.)
    var button = $(event.currentTarget);
    var wishElem = button.closest('.wish');

    if  (button.text() === 'show discussion') {
      button.text("hide discussion");
    } else {
      button.text("show discussion");
    }

    this.$('.comments-container').toggle();

    // bug - this can move the location of the button in the flow
    // with no mouseout event, so the button will remain highlighted
    $('#application .wish').not(wishElem).toggle();
  },

  flag: function(event) {
    // flag as inappropriate
    console.log('flagged by ' + this.viewer);
  },

  new_comment: function(event) {
    event.stopPropagation();
    event.preventDefault();

    // refactor w/ new_response
    var textarea = $(event.currentTarget).closest('.addComment').find('textarea');
    var text = textarea.val();
    textarea.val("");

    text = text.trim();
    if (! text) {
      return;
    }

    var comment = new Comment({
      parentWishId: this.model.get('_id'),
      text: text,
      whose: this.model.get('whose')});
    this.model.comments.add(comment);
    comment.save();
    // add a view
    commentView = new CommentView({model: comment});
    self.$('.comments').append(commentView.render().el);
  },

  edit: function() {
    $(this.el).addClass("editing");
    // noodly oodly oodly
    this.input.focus();
  },

  render: function() {
    var self = this;
    $(this.el).html(this.template(this.model.toJSON()));

    this.model.comments.each( function(comment) {
      comment.set({'parentWishId': self.model.get('_id')});
      commentView = new CommentView({model: comment});
      self.$('.comments').append(commentView.render().el);
    });

    return this;
  }
});

var WishCollection = Backbone.Collection.extend({ model: Wish });

// ----------------------------------------------------------------------
// the view for the vote page - the main application view

var NewWishApplication = Backbone.Model.extend({});

var NewWishApplicationView = Backbone.View.extend({
  model: Wish,

  el: $('#wish-application'),

  initialize: function() {
    this.currentCompletions = [];
  },

  events: {
    'click .submit': 'commit',
    'keydown .newWish': 'searchKeydown',
    'click .newWish': 'cancelSearch'
  },

  cancelSearch: function(event) {
    this.$('li.suggestion').remove();
  },

  searchKeydown: function(event) {
    // grab the existing text, and the key just pressed
    var self = this;
    var text = $('.newWish textarea').val();
    text += String.fromCharCode(event.which);

    // bug - doesn't catch select-all + delete
    // doesn't catch ctrl-a ctrl-k
    if (text.trim() === "") {
      return this.$('li.suggestion').remove();
    }

    // replace existing suggestion list with
    // results from completer search
    now.search(text, 10, function(err, results) {
      if (!listsAreEqual(results, self.currentCompletions)) {
        self.$('li.suggestion').remove();
        _.each(results, function(result) {
          // results are lists of [docid:text, ...]
          // so split the id and the text apart
          var sep = result.match(":").index;
          var id = result.slice(0, sep);
          var text = result.slice(sep+1);

          var suggestion = new Suggestion({_id: id, text: text});
          var view = new SuggestionView({model:suggestion});

          self.$('.suggestions').append(view.render().el);
        });
        self.currentCompletions = results;
      }
    });

  },

  commit: function(event) {
    //var wish = new Wish();
    var comment = new Comment;
    var commentCollection = new CommentCollection;

    comment.set({
        text: this.$('.newWishComment textarea').val(),
        whose: this.model.get('whose')});
    commentCollection.add(comment);

    this.model.set({
        text: this.$('.newWish textarea').val(),
        comments: commentCollection});

    this.model.save();
    this.el.fadeOut(200);

    // having made a wish, go compare with others
    location.replace('/vote/'+this.model.get('_id'))
  }
});

var ListApplication = Backbone.Model.extend({});
var ListApplicationView = Backbone.View.extend({
  model: ListApplication,

  el: $("#list-application"),

  initialize: function() {
    _.bindAll(this, 'addOne', 'render');
  },

  addOne: function(wish) {
    var view = new WishView({model: wish});
    $(this.el).append(view.render().el);
  }
});

// ----------------------------------------------------------------------
// voting for one wish over another

var VoteApplication = Backbone.Model.extend({});

var VoteApplicationView = Backbone.View.extend({
  model: VoteApplication,

  el: $("#vote-application"),

  events: {
    'click .vote': 'vote',
  },

  initialize: function() {
    this.views = [];
    _.bindAll(this, 'addOne', 'render');
    // we would fetch() here, except that the stuff's already in the dom
    // via the server template.
  },

  vote: function(event) {
    var self = this;
    var notIds = _.map(self.views, function(view) { return view.model.get('_id')} ).join(',');

    var toRemove = [];

    _.each(this.views, function(view) {
      if (! view.el.contains(event.currentTarget)) {
        toRemove.unshift(view);
      } else {
        view.model.voteFor(self.model.get('username'));
      }
    });

    // remove views that weren't voted for
    _.each(toRemove, function(r) { self.removeView(r)});

    // replace views that weren't voted for
    _.each(toRemove, function() {
      var wish = new Wish({id: 'random.json/not/'+notIds});
      wish.fetch({
        error: function(resp) {
          console.error(resp);
        },
        success: function(model, resp) {
          self.addOne(wish);
        }
      });
    });
  },

  removeView: function(view) {
    this.views.splice(this.views.indexOf(view), 1);
    view.remove();
  },

  addOne: function(wish) {
    var view = new WishView({model: wish});
    view.setViewer(this.model.get('username'));
    var newEl = view.render().el;
    $(this.el).append(newEl);
    this.views.unshift(view);
  },
});

<|endoftext|>


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

  $('.talk-type').on('change', function(){
    var showAll = 0;
    $('.talk-type').each(function(){
      if($(this).is(':checked')) {
        $('.row.' + $(this).val()).show();
      } else {
        $('.row.' + $(this).val()).hide();
        showAll++;
      }
    });
    if (showAll == $('.talk-type').length) {
      $('.talk-type').each(function(){
        $('.row.' + $(this).val()).show();
      });
    }
  });

});
<commit_msg>Fix linting issues<commit_after>$(document).ready(function() {

  $('.talk-type').on('change', function() {
    var showAll = 0;
    $('.talk-type').each(function() {
      if ($(this).is(':checked')) {
        $('.row.' + $(this).val()).show();
      } else {
        $('.row.' + $(this).val()).hide();
        showAll++;
      }
    });

    if (showAll == $('.talk-type').length) {
      $('.talk-type').each(function() {
        $('.row.' + $(this).val()).show();
      });
    }
  });

});
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Miquel Sabaté Solà <mikisabate@gmail.com>
 * This file is licensed under the MIT license.
 * See the LICENSE file.
 */

function cancelTextArea()
{
    var body = $('#contents .body');
    body.find('.contents-edit').hide();
    body.find('.contents-body').show();
}

jQuery(function() {
    $('#list button').click(function() {
        $(this).hide();

        var form = $(this).closest('.create').find('form');
        form.show();
        form.find('.tiny-text').focus();
    });

    $('#contents .cancel-btn').click(function(e) {
        e.preventDefault();
        cancelTextArea();
    });

    $('#contents .edit').click(function(e) {
        e.preventDefault();

        var body = $('#contents .body');
        body.find('.contents-body').hide();
        body.find('.contents-edit').show();
        $('textarea').focus();
    });

    $('#contents .rename').click(function(e) {
        e.preventDefault();

        var f = $('#contents .header').find('.rename-form');
        f.show();
        f.find('.tiny-text').focus();
    });

    $('#contents .delete').click(function(e) {
        e.preventDefault();
        $(this).hide();
        $('#contents .confirmation').css('display', 'inline');
    });

    $('#contents .yes').click(function(e) {
        e.preventDefault();
        $('#contents .delete-form').submit();
    });

    $('#contents .no').click(function(e) {
        e.preventDefault();
        $('#contents .confirmation').hide();
        $('#contents .delete').css('display', 'inline');
    });

    // TODO: proper fix.
    //$('#contents textarea').focusout(cancelTextArea);
});

<commit_msg>topics: cleaning up the JS.<commit_after>/*
 * Copyright (C) 2014 Miquel Sabaté Solà <mikisabate@gmail.com>
 * This file is licensed under the MIT license.
 * See the LICENSE file.
 */

jQuery(function() {
    $('#list button').click(function() {
        $(this).hide();

        var form = $(this).closest('.create').find('form');
        form.show();
        form.find('.tiny-text').focus();
    });

    $('#contents .cancel-btn').click(function(e) {
        e.preventDefault();
        var body = $('#contents .body');
        body.find('.contents-edit').hide();
        body.find('.contents-body').show();
    });

    $('#contents .edit').click(function(e) {
        e.preventDefault();

        var body = $('#contents .body');
        body.find('.contents-body').hide();
        body.find('.contents-edit').show();
        $('textarea').focus();
    });

    $('#contents .rename').click(function(e) {
        e.preventDefault();

        var f = $('#contents .header').find('.rename-form');
        f.show();
        f.find('.tiny-text').focus();
    });

    $('#contents .delete').click(function(e) {
        e.preventDefault();
        $(this).hide();
        $('#contents .confirmation').css('display', 'inline');
    });

    $('#contents .yes').click(function(e) {
        e.preventDefault();
        $('#contents .delete-form').submit();
    });

    $('#contents .no').click(function(e) {
        e.preventDefault();
        $('#contents .confirmation').hide();
        $('#contents .delete').css('display', 'inline');
    });
});

<|endoftext|>


<commit_before>$(function () {
	change_layout();
});<commit_msg>put comment<commit_after>$(function () {
	// set fixed menu
	change_layout();
});<|endoftext|>


<commit_before>/*

 usage:

 p = new Player({
 useWorker: <bool>,
 workerFile: <defaults to "Decoder.js"> // give path to Decoder.js
 webgl: true | false | "auto" // defaults to "auto"
 });

 // canvas property represents the canvas node
 // put it somewhere in the dom
 p.canvas;

 p.webgl; // contains the used rendering mode. if you pass auto to webgl you can see what auto detection resulted in

 p.decode(<binary>);

 */

// universal module definition
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(["./Decoder", "./YUVCanvas"], factory);
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory(require("./Decoder"), require("./YUVCanvas"));
  } else {
    // Browser globals (root is window)
    root.Player = factory(root.Decoder, root.YUVCanvas);
  }
}(this, function (Decoder, WebGLCanvas) {
  "use strict";

  var nowValue = Decoder.nowValue;

  var Player = function(parOptions){
    var self = this;
    this._config = parOptions || {};

    this.render = true;
    if (this._config.render === false){
      this.render = false;
    };

    this.nowValue = nowValue;

    this._config.workerFile = this._config.workerFile || "Decoder.js";
    if (this._config.preserveDrawingBuffer){
      this._config.contextOptions = this._config.contextOptions || {};
      this._config.contextOptions.preserveDrawingBuffer = true;
    };

    var webgl = "auto";
    if (this._config.webgl === true){
      webgl = true;
    }else if (this._config.webgl === false){
      webgl = false;
    };

    if (webgl == "auto"){
      webgl = true;
      try{
        if (!window.WebGLRenderingContext) {
          // the browser doesn't even know what WebGL is
          webgl = false;
        } else {
          var canvas = document.createElement('canvas');
          var ctx = canvas.getContext("webgl");
          if (!ctx) {
            // browser supports WebGL but initialization failed.
            webgl = false;
          };
        };
      }catch(e){
        webgl = false;
      };
    };

    this.webgl = webgl;

    // choose functions
    if (this.webgl){
      this.createCanvasObj = this.createCanvasWebGL;
      this.renderFrame = this.renderFrameWebGL;
    }else{
      this.createCanvasObj = this.createCanvasRGB;
      this.renderFrame = this.renderFrameRGB;
    };

    var lastWidth;
    var lastHeight;
    const UserAgent = window.navigator.userAgent.toLowerCase();
    const isInternet = checkIsIE();
    function checkIsIE() {
      var isIE = (UserAgent.indexOf('msie') != -1);
      if (isIE == false && window.navigator.appName == 'Netscape') {

        var re  = new RegExp("trident/.*rv:([0-9]{1,}[\.0-9]{0,})");  //for IE 11
        if (re.exec(UserAgent) != null)
          isIE = true;
      }
      return isIE;
    }

    var onPictureDecoded = function(buffer, width, height, infos) {
      self.onPictureDecoded(buffer, width, height, infos);

      var startTime = nowValue();

      if (!buffer || !self.render) {
        return;
      };

      self.renderFrame({
        canvasObj: self.canvasObj,
        data: buffer,
        width: width,
        height: height
      });

      if (self.onRenderFrameComplete){
        self.onRenderFrameComplete({
          data: buffer,
          width: width,
          height: height,
          infos: infos,
          canvasObj: self.canvasObj
        });
      };

    };

    // provide size

    if (!this._config.size){
      this._config.size = {};
    };
    this._config.size.width = this._config.size.width || 200;
    this._config.size.height = this._config.size.height || 200;

    if (this._config.useWorker){
      var worker = new Worker(this._config.workerFile);
      this.worker = worker;
      worker.addEventListener('message', function(e) {
        var data = e.data;
        if (data.consoleLog){
          console.log(data.consoleLog);
          return;
        };

        onPictureDecoded.call(self, new Uint8Array(data.buf, 0, data.length), data.width, data.height, data.infos);

      }, false);

      worker.postMessage({type: "Broadway.js - Worker init", options: {
        rgb: !webgl,
        memsize: this.memsize,
        reuseMemory: this._config.reuseMemory ? true : false,
        isInternet: isInternet
      }});

      if (this._config.transferMemory){
        this.decode = function(parData, parInfo){
          // no copy
          // instead we are transfering the ownership of the buffer
          // dangerous!!!

          worker.postMessage({buf: parData.buffer, offset: parData.byteOffset, length: parData.length, info: parInfo}, [parData.buffer]); // Send data to our worker.
        };

      }else{
        this.decode = function(parData, parInfo){
          if (!parInfo) {
            parInfo = {};
          }
          // Copy the sample so that we only do a structured clone of the
          // region of interest
          if (isInternet == true) {
            parInfo["ts"] = new Date().getTime();
            worker.postMessage({buf: "base64", data:parData, offset: 0, length: parData.length, info: parInfo}); // Send data to our worker.
          }else {
            parInfo["ts"] = new Date().getTime();
            var copyU8 = new Uint8Array(parData.length);
            copyU8.set( parData, 0, parData.length );
            worker.postMessage({buf: copyU8.buffer, offset: 0, length: parData.length, info: parInfo}, [copyU8.buffer]); // Send data to our worker.
          }
        };

      };

      if (this._config.reuseMemory){
        this.recycleMemory = function(parArray){
          //this.beforeRecycle();
          worker.postMessage({reuse: parArray.buffer}, [parArray.buffer]); // Send data to our worker.
          //this.afterRecycle();
        };
      }

    }else{

      this.decoder = new Decoder({
        rgb: !webgl
      });
      this.decoder.onPictureDecoded = onPictureDecoded;

      this.decode = function(parData, parInfo){
        self.decoder.decode(parData, parInfo);
      };

    };

    if (this.render){
      this.canvasObj = this.createCanvasObj({
        contextOptions: this._config.contextOptions
      });
      this.canvas = this.canvasObj.canvas;
    };

    this.domNode = this.canvas;

    lastWidth = this._config.size.width;
    lastHeight = this._config.size.height;

  };

  Player.prototype = {

    onPictureDecoded: function(buffer, width, height, infos){},

    // call when memory of decoded frames is not used anymore
    recycleMemory: function(buf){
    },
    /*beforeRecycle: function(){},
     afterRecycle: function(){},*/

    // for both functions options is:
    //
    //  width
    //  height
    //  enableScreenshot
    //
    // returns a object that has a property canvas which is a html5 canvas
    createCanvasWebGL: function(options){
      var canvasObj = this._createBasicCanvasObj(options);
      canvasObj.contextOptions = options.contextOptions;
      return canvasObj;
    },

    createCanvasRGB: function(options){
      var canvasObj = this._createBasicCanvasObj(options);
      return canvasObj;
    },

    // part that is the same for webGL and RGB
    _createBasicCanvasObj: function(options){
      options = options || {};

      var obj = {};
      var width = options.width;
      if (!width){
        width = this._config.size.width;
      };
      var height = options.height;
      if (!height){
        height = this._config.size.height;
      };
      obj.canvas = document.createElement('canvas');
      obj.canvas.width = width;
      obj.canvas.height = height;
      obj.canvas.style.backgroundColor = "#0D0E1B";

      return obj;
    },

    // options:
    //
    // canvas
    // data
    renderFrameWebGL: function(options){

      var canvasObj = options.canvasObj;

      var width = options.width || canvasObj.canvas.width;
      var height = options.height || canvasObj.canvas.height;

      if (canvasObj.canvas.width !== width || canvasObj.canvas.height !== height || !canvasObj.webGLCanvas){
        canvasObj.canvas.width = width;
        canvasObj.canvas.height = height;
        canvasObj.webGLCanvas = new WebGLCanvas({
          canvas: canvasObj.canvas,
          contextOptions: canvasObj.contextOptions,
          width: width,
          height: height
        });
      };

      var ylen = width * height;
      var uvlen = (width / 2) * (height / 2);

      canvasObj.webGLCanvas.drawNextOutputPicture({
        yData: options.data.subarray(0, ylen),
        uData: options.data.subarray(ylen, ylen + uvlen),
        vData: options.data.subarray(ylen + uvlen, ylen + uvlen + uvlen)
      });

      var self = this;
      self.recycleMemory(options.data);

    },
    renderFrameRGB: function(options){
      var canvasObj = options.canvasObj;

      var width = options.width || canvasObj.canvas.width;
      var height = options.height || canvasObj.canvas.height;

      if (canvasObj.canvas.width !== width || canvasObj.canvas.height !== height){
        canvasObj.canvas.width = width;
        canvasObj.canvas.height = height;
      };

      var ctx = canvasObj.ctx;
      var imgData = canvasObj.imgData;

      if (!ctx){
        canvasObj.ctx = canvasObj.canvas.getContext('2d');
        ctx = canvasObj.ctx;

        canvasObj.imgData = ctx.createImageData(width, height);
        imgData = canvasObj.imgData;
      };

      imgData.data.set(options.data);
      ctx.putImageData(imgData, 0, 0);
      var self = this;
      self.recycleMemory(options.data);

    }

  };

  return Player;

}));
<commit_msg>fix IE<commit_after>/*

 usage:

 p = new Player({
 useWorker: <bool>,
 workerFile: <defaults to "Decoder.js"> // give path to Decoder.js
 webgl: true | false | "auto" // defaults to "auto"
 });

 // canvas property represents the canvas node
 // put it somewhere in the dom
 p.canvas;

 p.webgl; // contains the used rendering mode. if you pass auto to webgl you can see what auto detection resulted in

 p.decode(<binary>);

 */

// universal module definition
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(["./Decoder", "./YUVCanvas"], factory);
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory(require("./Decoder"), require("./YUVCanvas"));
  } else {
    // Browser globals (root is window)
    root.Player = factory(root.Decoder, root.YUVCanvas);
  }
}(this, function (Decoder, WebGLCanvas) {
  "use strict";

  var nowValue = Decoder.nowValue;

  var Player = function(parOptions){
    var self = this;
    this._config = parOptions || {};

    this.render = true;
    if (this._config.render === false){
      this.render = false;
    };

    this.nowValue = nowValue;

    this._config.workerFile = this._config.workerFile || "Decoder.js";
    if (this._config.preserveDrawingBuffer){
      this._config.contextOptions = this._config.contextOptions || {};
      this._config.contextOptions.preserveDrawingBuffer = true;
    };

    var webgl = "auto";
    if (this._config.webgl === true){
      webgl = true;
    }else if (this._config.webgl === false){
      webgl = false;
    };

    if (webgl == "auto"){
      webgl = true;
      try{
        if (!window.WebGLRenderingContext) {
          // the browser doesn't even know what WebGL is
          webgl = false;
        } else {
          var canvas = document.createElement('canvas');
          var ctx = canvas.getContext("webgl");
          if (!ctx) {
            // browser supports WebGL but initialization failed.
            webgl = false;
          };
        };
      }catch(e){
        webgl = false;
      };
    };

    this.webgl = webgl;

    // choose functions
    if (this.webgl){
      this.createCanvasObj = this.createCanvasWebGL;
      this.renderFrame = this.renderFrameWebGL;
    }else{
      this.createCanvasObj = this.createCanvasRGB;
      this.renderFrame = this.renderFrameRGB;
    };

    var lastWidth;
    var lastHeight;
    const UserAgent = window.navigator.userAgent.toLowerCase();
    const isInternet = checkIsIE();
    function checkIsIE() {
      var isIE = (UserAgent.indexOf('msie') != -1);
      if (isIE == false && window.navigator.appName == 'Netscape') {

        var re  = new RegExp("trident/.*rv:([0-9]{1,}[\.0-9]{0,})");  //for IE 11
        if (re.exec(UserAgent) != null)
          isIE = true;
      }
      return isIE;
    }
    var toUint8Array = function(parStr){
      var raw = atob(parStr);
      var rawLength = raw.length;
      var array = new Uint8Array(new ArrayBuffer(rawLength));

      var i;
      for(i = 0; i < rawLength; i++) {
        array[i] = raw.charCodeAt(i);
      }
      return array;
    };

    var onPictureDecoded = function(buffer, width, height, infos) {
      self.onPictureDecoded(buffer, width, height, infos);

      var startTime = nowValue();

      if (!buffer || !self.render) {
        return;
      };

      self.renderFrame({
        canvasObj: self.canvasObj,
        data: buffer,
        width: width,
        height: height
      });

      if (self.onRenderFrameComplete){
        self.onRenderFrameComplete({
          data: buffer,
          width: width,
          height: height,
          infos: infos,
          canvasObj: self.canvasObj
        });
      };

    };

    // provide size

    if (!this._config.size){
      this._config.size = {};
    };
    this._config.size.width = this._config.size.width || 200;
    this._config.size.height = this._config.size.height || 200;

    if (this._config.useWorker){
      var worker = new Worker(this._config.workerFile);
      this.worker = worker;
      worker.addEventListener('message', function(e) {
        var data = e.data;
        if (data.consoleLog){
          console.log(data.consoleLog);
          return;
        };
        if (isInternet) {
          var bin = toUint8Array(data.data);
          onPictureDecoded.call(self, new Uint8Array(bin, 0, data.length), data.width, data.height, data.infos);
        }
        else
          onPictureDecoded.call(self, new Uint8Array(data.buf, 0, data.length), data.width, data.height, data.infos);

      }, false);

      worker.postMessage({type: "Broadway.js - Worker init", options: {
        rgb: !webgl,
        memsize: this.memsize,
        reuseMemory: this._config.reuseMemory ? true : false,
        isInternet: isInternet
      }});

      if (this._config.transferMemory){
        this.decode = function(parData, parInfo){
          // no copy
          // instead we are transfering the ownership of the buffer
          // dangerous!!!

          worker.postMessage({buf: parData.buffer, offset: parData.byteOffset, length: parData.length, info: parInfo}, [parData.buffer]); // Send data to our worker.
        };

      }else{
        this.decode = function(parData, parInfo){
          if (!parInfo) {
            parInfo = {};
          }
          // Copy the sample so that we only do a structured clone of the
          // region of interest
          if (isInternet == true) {
            parInfo["ts"] = new Date().getTime();
            worker.postMessage({buf: "base64", data:parData, offset: 0, length: parData.length, info: parInfo}); // Send data to our worker.
          }else {
            parInfo["ts"] = new Date().getTime();
            var copyU8 = new Uint8Array(parData.length);
            copyU8.set( parData, 0, parData.length );
            worker.postMessage({buf: copyU8.buffer, offset: 0, length: parData.length, info: parInfo}, [copyU8.buffer]); // Send data to our worker.
          }
        };

      };

      if (this._config.reuseMemory){
        this.recycleMemory = function(parArray){
          //this.beforeRecycle();
          worker.postMessage({reuse: parArray.buffer}, [parArray.buffer]); // Send data to our worker.
          //this.afterRecycle();
        };
      }

    }else{

      this.decoder = new Decoder({
        rgb: !webgl
      });
      this.decoder.onPictureDecoded = onPictureDecoded;

      this.decode = function(parData, parInfo){
        self.decoder.decode(parData, parInfo);
      };

    };

    if (this.render){
      this.canvasObj = this.createCanvasObj({
        contextOptions: this._config.contextOptions
      });
      this.canvas = this.canvasObj.canvas;
    };

    this.domNode = this.canvas;

    lastWidth = this._config.size.width;
    lastHeight = this._config.size.height;

  };

  Player.prototype = {

    onPictureDecoded: function(buffer, width, height, infos){},

    // call when memory of decoded frames is not used anymore
    recycleMemory: function(buf){
    },
    /*beforeRecycle: function(){},
     afterRecycle: function(){},*/

    // for both functions options is:
    //
    //  width
    //  height
    //  enableScreenshot
    //
    // returns a object that has a property canvas which is a html5 canvas
    createCanvasWebGL: function(options){
      var canvasObj = this._createBasicCanvasObj(options);
      canvasObj.contextOptions = options.contextOptions;
      return canvasObj;
    },

    createCanvasRGB: function(options){
      var canvasObj = this._createBasicCanvasObj(options);
      return canvasObj;
    },

    // part that is the same for webGL and RGB
    _createBasicCanvasObj: function(options){
      options = options || {};

      var obj = {};
      var width = options.width;
      if (!width){
        width = this._config.size.width;
      };
      var height = options.height;
      if (!height){
        height = this._config.size.height;
      };
      obj.canvas = document.createElement('canvas');
      obj.canvas.width = width;
      obj.canvas.height = height;
      obj.canvas.style.backgroundColor = "#0D0E1B";

      return obj;
    },

    // options:
    //
    // canvas
    // data
    renderFrameWebGL: function(options){

      var canvasObj = options.canvasObj;

      var width = options.width || canvasObj.canvas.width;
      var height = options.height || canvasObj.canvas.height;

      if (canvasObj.canvas.width !== width || canvasObj.canvas.height !== height || !canvasObj.webGLCanvas){
        canvasObj.canvas.width = width;
        canvasObj.canvas.height = height;
        canvasObj.webGLCanvas = new WebGLCanvas({
          canvas: canvasObj.canvas,
          contextOptions: canvasObj.contextOptions,
          width: width,
          height: height
        });
      };

      var ylen = width * height;
      var uvlen = (width / 2) * (height / 2);

      canvasObj.webGLCanvas.drawNextOutputPicture({
        yData: options.data.subarray(0, ylen),
        uData: options.data.subarray(ylen, ylen + uvlen),
        vData: options.data.subarray(ylen + uvlen, ylen + uvlen + uvlen)
      });

      var self = this;
      self.recycleMemory(options.data);

    },
    renderFrameRGB: function(options){
      var canvasObj = options.canvasObj;

      var width = options.width || canvasObj.canvas.width;
      var height = options.height || canvasObj.canvas.height;

      if (canvasObj.canvas.width !== width || canvasObj.canvas.height !== height){
        canvasObj.canvas.width = width;
        canvasObj.canvas.height = height;
      };

      var ctx = canvasObj.ctx;
      var imgData = canvasObj.imgData;

      if (!ctx){
        canvasObj.ctx = canvasObj.canvas.getContext('2d');
        ctx = canvasObj.ctx;

        canvasObj.imgData = ctx.createImageData(width, height);
        imgData = canvasObj.imgData;
      };

      imgData.data.set(options.data);
      ctx.putImageData(imgData, 0, 0);
      var self = this;
      self.recycleMemory(options.data);

    }

  };

  return Player;

}));
<|endoftext|>


<commit_before>import React from 'react';
import {connect} from 'react-redux';
import Select from 'react-select';
import Switch from 'react-ios-switch';
import {FormControl, OverlayTrigger, Tooltip} from 'react-bootstrap';

import RepositoryBox from 'components/RepositoryBox';
import ForkAllBox from 'components/ForkAllBox';
import BoxProperties from 'components/BoxProperties';
import AddNewBox from 'components/AddNewBox';
import enableDisableLink from 'actions/enableDisableLink';
import changeLinkName from 'actions/changeLinkName';
import isDeletingLink from 'actions/isDeletingLink';
import deleteLink from 'actions/deleteLink';
import changePushUsers from 'actions/changePushUsers';

import linkSave from 'actions/linkSave';

export function isRepoValid(repo, type) {
  return (
    repo.type === 'repo' &&
    repo.provider &&
    repo.name &&
    repo.name.length > 0 &&
    repo.name.indexOf('/') !== -1 &&
    repo.branch && repo.branch.length > 0 &&
    (type === 'to' ? repo.fork : true) // to must be a fork
  ) || (
    repo.type === 'fork-all' &&
    repo.provider && repo.provider.length > 0
  );
}

export function isLinkValid(link) {
  return (
    link.name && link.name.length > 0 &&
    link.to && link.to.type && link.to.provider &&
    link.from && link.from.type && link.from.provider &&
    isRepoValid(link.to, 'to') && isRepoValid(link.from, 'from')
  )
}

export function Link({
  link,
  user,
  children,

  onLinkSave,
  onLinkEnable,
  onChangeLinkName,
  onDeleteLink,
  onIsDeletingLink,
  onChangePushUsers,
}) {
  if (link) {
    // fetch branches, if required
    if (link.from && link.from.branches) {
      let fromBranchOptions = link.from.branches.map(branch => {
        return {value: branch, label: branch};
      });
    }
    if (link.to && link.to.branches) {
      let toBranchOptions = link.to.branches.map(branch => {
        return {value: branch, label: branch};
      });
    }

    return

        <OverlayTrigger placement="bottom" overlay={
          <Tooltip id="link-state">
            {link.enabled ? 'Disable' : 'Enable'} this link
          </Tooltip>
        }>
           {/* Required to let react-bootstrap bind to the switch */}
            <Switch
              onChange={onLinkEnable.bind(null, link, !link.enabled)}
              checked={link.enabled}
              disabled={link._pending}
            />

        </OverlayTrigger>

        {/* The name of the link */}
        <FormControl
          type="text"
          className="link-name"
          value={link.name || ""}
          onChange={onChangeLinkName}
          placeholder="Enter a link name"
        />

      {/* Errors in the save process */}
      {link._saveError ? {link._saveError} : null}

From

          <RepoWrapper
            slot="from"
            repository={link.from}
            branch={link.from && link.from.branch}
          />

To

          <RepoWrapper
            slot="to"
            repository={link.to}
            branch={link.to && link.to.branch}
            from={link.from}
          />

Webhook URL

        {/* The webhook url */}
        <FormControl
          type="text"
          onFocus={event => event.target.select()}
          readOnly={true}
          value={`${process.env.BACKSTROKE_SERVER}/_${link._id}`}
        />

          Every time this url is visited, we'll make sure that any new changes are
          synced according to what's been configured above.

      {/*

Other

          Create a temporary repo to fix merge conflicts

          Who can push to the temporary repo?
          <input
            type="text"
            value={link.pushUsers.join(' ')}
            onChange={onChangePushUsers}
          />

 */}

      {
        link._saveInProgress ?
        <button className="btn btn-primary disabled">Loading</button> :
        <button
          className="btn btn-primary"
          onClick={onLinkSave.bind(null, link)}
          disabled={!isLinkValid(link)}
        >Save</button>
      }

      {
        link._deleting ?
        <button
          className="btn btn-danger btn-del"
          onClick={onDeleteLink.bind(null, link._id)}
        >Sure?</button> :
        <button className="btn btn-danger btn-del" onClick={onIsDeletingLink}>Delete</button>
      }

      {children}

;
  } else if (user && !user._auth) {
    return <UserNotAuthenticated />;
  } else {
    return

      Loading link...
      {children}

;
  }
}

export function RepoWrapper({repository, branch, from, slot}) {
  if (repository && repository.type === 'repo') {
    // A bare repository / branch combo
    return <BoxProperties repository={repository}>
      <RepositoryBox repository={repository} branch={branch} type={slot} />
    </BoxProperties>;
  } else if (repository && repository.type === 'fork-all') {
    // All forks for the upstream
    return <BoxProperties repository={repository}>
      <ForkAllBox repository={repository} from={from} />
    </BoxProperties>;
  } else {
    // add a new item
    return <AddNewBox type={slot} />;
  }
}

export default connect((state, props) => {
  return {
    link: state.activeLink,
    user: state.user,
  };
}, dispatch => {
  return {
    onLinkSave(link) {
      link.enabled = true;
      dispatch(linkSave(link));
    },
    onLinkEnable(link, enabled) {
      dispatch(enableDisableLink(link, enabled));
    },
    onChangeLinkName(event) {
      dispatch(changeLinkName(event.target.value));
    },
    onIsDeletingLink() {
      dispatch(isDeletingLink());
    },
    onDeleteLink(linkId) {
      dispatch(deleteLink(linkId));
    },
    onChangePushUsers(event) {
      dispatch(changePushUsers(event.target.value));
    },
  };
})(Link);
<commit_msg>code: valid repos need to have at least one branch closes #16<commit_after>import React from 'react';
import {connect} from 'react-redux';
import Select from 'react-select';
import Switch from 'react-ios-switch';
import {FormControl, OverlayTrigger, Tooltip} from 'react-bootstrap';

import RepositoryBox from 'components/RepositoryBox';
import ForkAllBox from 'components/ForkAllBox';
import BoxProperties from 'components/BoxProperties';
import AddNewBox from 'components/AddNewBox';
import enableDisableLink from 'actions/enableDisableLink';
import changeLinkName from 'actions/changeLinkName';
import isDeletingLink from 'actions/isDeletingLink';
import deleteLink from 'actions/deleteLink';
import changePushUsers from 'actions/changePushUsers';

import linkSave from 'actions/linkSave';

export function isRepoValid(repo, type) {
  return (
    repo.type === 'repo' &&
    repo.provider &&
    repo.name &&
    repo.name.length > 0 &&
    repo.name.indexOf('/') !== -1 &&
    repo.branch && repo.branch.length > 0 &&
    repo.branches.length > 0 && // must have al teast 1 branch
    (type === 'to' ? repo.fork : true) // to must be a fork
  ) || (
    repo.type === 'fork-all' &&
    repo.provider && repo.provider.length > 0
  );
}

export function isLinkValid(link) {
  return (
    link.name && link.name.length > 0 &&
    link.to && link.to.type && link.to.provider &&
    link.from && link.from.type && link.from.provider &&
    isRepoValid(link.to, 'to') && isRepoValid(link.from, 'from')
  )
}

export function Link({
  link,
  user,
  children,

  onLinkSave,
  onLinkEnable,
  onChangeLinkName,
  onDeleteLink,
  onIsDeletingLink,
  onChangePushUsers,
}) {
  if (link) {
    // fetch branches, if required
    if (link.from && link.from.branches) {
      let fromBranchOptions = link.from.branches.map(branch => {
        return {value: branch, label: branch};
      });
    }
    if (link.to && link.to.branches) {
      let toBranchOptions = link.to.branches.map(branch => {
        return {value: branch, label: branch};
      });
    }

    return

        <OverlayTrigger placement="bottom" overlay={
          <Tooltip id="link-state">
            {link.enabled ? 'Disable' : 'Enable'} this link
          </Tooltip>
        }>
           {/* Required to let react-bootstrap bind to the switch */}
            <Switch
              onChange={onLinkEnable.bind(null, link, !link.enabled)}
              checked={link.enabled}
              disabled={link._pending}
            />

        </OverlayTrigger>

        {/* The name of the link */}
        <FormControl
          type="text"
          className="link-name"
          value={link.name || ""}
          onChange={onChangeLinkName}
          placeholder="Enter a link name"
        />

      {/* Errors in the save process */}
      {link._saveError ? {link._saveError} : null}

From

          <RepoWrapper
            slot="from"
            repository={link.from}
            branch={link.from && link.from.branch}
          />

To

          <RepoWrapper
            slot="to"
            repository={link.to}
            branch={link.to && link.to.branch}
            from={link.from}
          />

Webhook URL

        {/* The webhook url */}
        <FormControl
          type="text"
          onFocus={event => event.target.select()}
          readOnly={true}
          value={`${process.env.BACKSTROKE_SERVER}/_${link._id}`}
        />

          Every time this url is visited, we'll make sure that any new changes are
          synced according to what's been configured above.

      {/*

Other

          Create a temporary repo to fix merge conflicts

          Who can push to the temporary repo?
          <input
            type="text"
            value={link.pushUsers.join(' ')}
            onChange={onChangePushUsers}
          />

 */}

      {
        link._saveInProgress ?
        <button className="btn btn-primary disabled">Loading</button> :
        <button
          className="btn btn-primary"
          onClick={onLinkSave.bind(null, link)}
          disabled={!isLinkValid(link)}
        >Save</button>
      }

      {
        link._deleting ?
        <button
          className="btn btn-danger btn-del"
          onClick={onDeleteLink.bind(null, link._id)}
        >Sure?</button> :
        <button className="btn btn-danger btn-del" onClick={onIsDeletingLink}>Delete</button>
      }

      {children}

;
  } else if (user && !user._auth) {
    return <UserNotAuthenticated />;
  } else {
    return

      Loading link...
      {children}

;
  }
}

export function RepoWrapper({repository, branch, from, slot}) {
  if (repository && repository.type === 'repo') {
    // A bare repository / branch combo
    return <BoxProperties repository={repository}>
      <RepositoryBox repository={repository} branch={branch} type={slot} />
    </BoxProperties>;
  } else if (repository && repository.type === 'fork-all') {
    // All forks for the upstream
    return <BoxProperties repository={repository}>
      <ForkAllBox repository={repository} from={from} />
    </BoxProperties>;
  } else {
    // add a new item
    return <AddNewBox type={slot} />;
  }
}

export default connect((state, props) => {
  return {
    link: state.activeLink,
    user: state.user,
  };
}, dispatch => {
  return {
    onLinkSave(link) {
      link.enabled = true;
      dispatch(linkSave(link));
    },
    onLinkEnable(link, enabled) {
      dispatch(enableDisableLink(link, enabled));
    },
    onChangeLinkName(event) {
      dispatch(changeLinkName(event.target.value));
    },
    onIsDeletingLink() {
      dispatch(isDeletingLink());
    },
    onDeleteLink(linkId) {
      dispatch(deleteLink(linkId));
    },
    onChangePushUsers(event) {
      dispatch(changePushUsers(event.target.value));
    },
  };
})(Link);
<|endoftext|>


<commit_before>function PlayField() {

    this.playController;

    this.setPlayController = function(playController) {
        this.playController = playController;
    }

    this.onTouchEvent = function(x, y) {
        x = 100*x/PlayField.dimensions.x;
        y = 100*y/PlayField.dimensions.y;
        //console.log(x, y);
        this.playController.onTargetSelected(new Target(x, y));
    }

    this.onDraw = function(canvas, width, height) {
        PlayField.dimensions.x = width;
        PlayField.dimensions.y = height;
        //canvas.drawColor(Color.BLACK);
        if (this.playController != null) {
            var bos = this.playController.getAll();
            for (var i=0; i<bos.length; i++) {
                bos[i].basicObject.getBasicObjectDrawer().onDraw(canvas);
            }
        }
    }

}

PlayField.dimensions = new Point(1, 1);

PlayField.getAbsolutePosition = function(position) {
    return new Point(PlayField.dimensions.x * (position.x / 100), PlayField.dimensions.y * (position.y / 100));
}
<commit_msg>asdds<commit_after>function PlayField() {

    this.playController;

    this.setPlayController = function(playController) {
        this.playController = playController;
    }

    this.onTouchEvent = function(x, y) {
        x = 100*x/PlayField.dimensions.x;
        y = 100*y/PlayField.dimensions.y;
        //console.log(x, y);
        this.playController.onTargetSelected(new Target(x, y));
    }

    this.onDraw = function(canvas, width, height) {
        var ctx = canvas.getContext("2d");
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        PlayField.dimensions.x = width;
        PlayField.dimensions.y = height;
        //canvas.drawColor(Color.BLACK);

        if (this.playController != null) {
            var bos = this.playController.getAll();
            for (var i=0; i<bos.length; i++) {
                bos[i].basicObject.getBasicObjectDrawer().onDraw(canvas);
            }
        }
    }

}

PlayField.dimensions = new Point(1, 1);

PlayField.getAbsolutePosition = function(position) {
    return new Point(PlayField.dimensions.x * (position.x / 100), PlayField.dimensions.y * (position.y / 100));
}
<|endoftext|>


<commit_before>requirejs.config({
    paths: {
        columnfilter: 'DataTables/extras/ColumnFilterWidgets'
    },
    shim: {
        columnfilter: [ "jquery.DataTables" ]
    }
})
define(['jquery', 'underscore', 'jquery.dataTables', 'columnfilter'],
    function ($, _) {
    function Table(options) {
        var self = this;
        options = options ? _.clone(options) : {};
        options.scrollY = options.scrollY || 300;
        var filterExclude = [];
        var $element = $(options.element);
        var elementOffset = $element.offset();
        self.setData = function (data) {
            self.data = data;
            data.filter = data.filter || [];
            for (var i = 0; i < data.columns.length; i++) {
                if (!_.contains(data.filter, data.columns[i])) {
                    filterExclude.push(i);
                }
            }
        };
        self.display = function () {
            var $table = $("
").attr("cellpadding", 0)
                .attr("cellspacing",0).attr("border", 0)
                .addClass('table table-striped table-bordered');
            $element.empty().append($table);
            var cols = _.map(self.data.columns, function (d) {
                return { sTitle: d };
            })
            $table.dataTable({
                sInfo: "muted",
                aaData: self.data.data,
                aoColumns: cols,
        		sPaginationType: "bootstrap",
                sScrollY: options.scrollY,
                bPaginate: false,
        		oLanguage: {
        			sLengthMenu: "_MENU_ per page"
        		},
                oColumnFilterWidgets: {
                    aiExclude: filterExclude,
                    bGroupTerms: true
                }
            });
            adjustHeight('.dataTables_wrapper');
            adjustHeight('.table-wrapper');
            $(".column-filter-widget").find("select").addClass("mini");
            $element.offset({
                top: elementOffset.top, left: elementOffset.left
            });
            // $(".dataTable .sorting_asc").each(function () {
            //     $(this).html(
            //         $(this).html() + "");
            // });
            // $(".dataTable .sorting_desc").each(function () {
            //     $(this).html(
            //         $(this).html() + "");
            // });

        };
        function adjustHeight(selector) {
            $(selector).each(function () {
                var w = $(this);
                var p = w.parent();
                var totalHeight = 0;
                p.children().each(function () {
                    totalHeight += $(this).outerHeight(true)
                });
                w.height(p.height() + w.outerHeight(true) - totalHeight);
            });
        }
    }
    /* Set the defaults for DataTables initialization */
    $.extend(true, $.fn.dataTable.defaults, {
    	sDom: "<'dt-top row'<'span6'Wl><'span6'fr>>" +
             "<'table-wrapper't><'dt-bottom'ip>",
        fnInitComplete: function (table) {
            $('.dataTables_length').find("select").addClass("span2");
            $('.dataTables_filter').find(":input")
                .addClass("input-small search-query")
                .attr("placeholder", "Search");
            $('.dataTables_length > label').contents().filter(function() {
                return this.nodeType != 1;
            }).wrap("");
        },
        sPaginationType: "bootstrap",
    	oLanguage: {
    		sLengthMenu: "_MENU_ records per page",
            sInfo: "_START_-_END_ of _TOTAL_ entries",
            sSearch: ""
    	}
    });

    /* Default class modification */
    $.extend($.fn.dataTableExt.oStdClasses, {
    	sWrapper: "dataTables_wrapper form-inline",
        sInfo: "mini muted dt-info"
    });

    /* API method to get paging information */
    $.fn.dataTableExt.oApi.fnPagingInfo = function (opts) {
    	return {
    		iStart:         opts._iDisplayStart,
    		iEnd:           opts.fnDisplayEnd(),
    		iLength:        opts._iDisplayLength,
    		iTotal:         opts.fnRecordsTotal(),
    		iFilteredTotal: opts.fnRecordsDisplay(),
    		iPage:
                Math.ceil(opts._iDisplayStart / opts._iDisplayLength),
    		iTotalPages:
                Math.ceil(opts.fnRecordsDisplay() / opts._iDisplayLength)
    	};
    };

    /* Bootstrap style pagination control */
    $.extend($.fn.dataTableExt.oPagination, {
    	bootstrap: {
    		fnInit: function (opts, nPaging, fnDraw) {
    			var oLang = opts.oLanguage.oPaginate;
    			var fnClickHandler = function (e) {
    				e.preventDefault();
    				if (opts.oApi._fnPageChange(opts, e.data.action)) {
    					fnDraw(opts);
    				}
    			};
    			$(nPaging).addClass('pagination pagination-mini').append(_.template(
    				'
' +
                        '
' +
                        '←
'+
    					'
'+
                        '→
'+
    				'
', { prev: oLang.sPrevious, next: oLang.sNext })
    			);
    			var els = $('a', nPaging);
    			$(els[0]).bind('click.DT',
                    { action: "previous" }, fnClickHandler);
    			$(els[1]).bind('click.DT',
                    { action: "next" }, fnClickHandler);
    		},
    		fnUpdate: function (opts, fnDraw) {
    			var iListLength = 5;
    			var oPaging = opts.oInstance.fnPagingInfo();
    			var an = opts.aanFeatures.p;
    			var i, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);

    			if ( oPaging.iTotalPages < iListLength) {
    				iStart = 1;
    				iEnd = oPaging.iTotalPages;
    			}
    			else if (oPaging.iPage <= iHalf) {
    				iStart = 1;
    				iEnd = iListLength;
    			} else if (oPaging.iPage >= (oPaging.iTotalPages-iHalf)) {
    				iStart = oPaging.iTotalPages - iListLength + 1;
    				iEnd = oPaging.iTotalPages;
    			} else {
    				iStart = oPaging.iPage - iHalf + 1;
    				iEnd = iStart + iListLength - 1;
    			}

    			for (i=0, iLen=an.length ; i<iLen ; i++) {
    				// Remove the middle elements
    				$('li:gt(0)', an[i]).filter(':not(:last)').remove();

    				// Add the new list items and their event handlers
    				for (j=iStart ;j<=iEnd ;j++) {
    					sClass = (j==oPaging.iPage+1) ? 'class="active"' : '';
    					$('
'+j+'
')
    						.insertBefore($('li:last', an[i])[0])
    						.bind('click', function (e) {
    							e.preventDefault();
    							opts._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;
    							fnDraw(opts);
    						} );
    				}

    				// Add / remove disabled classes from the static elements
    				if (oPaging.iPage === 0) {
    					$('li:first', an[i]).addClass('disabled');
    				} else {
    					$('li:first', an[i]).removeClass('disabled');
    				}

    				if (oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0) {
    					$('li:last', an[i]).addClass('disabled');
    				} else {
    					$('li:last', an[i]).removeClass('disabled');
    				}
    			}
    		}
    	}
    });

    /*
     * TableTools Bootstrap compatibility
     * Required TableTools 2.1+
     */
    if ($.fn.DataTable.TableTools) {
    	// Set the classes that TableTools uses to something suitable for Bootstrap
    	$.extend(true, $.fn.DataTable.TableTools.classes, {
    		container: "DTTT btn-group",
    		buttons: {
    			normal: "btn",
    			disabled: "disabled"
    		},
    		collection: {
    			container: "DTTT_dropdown dropdown-menu",
    			buttons: {
    				normal: "",
    				disabled: "disabled"
    			}
    		},
    		print: {
    			info: "DTTT_print_info modal"
    		},
    		select: {
    			row: "active"
    		}
    	});

    	// Have the collection use a bootstrap compatible dropdown
    	$.extend(true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
    		collection: {
    			container: "ul",
    			button: "li",
    			liner: "a"
    		}
    	});
    }

    return Table;
});<commit_msg>Yet another MacOS case-sensitive bug.<commit_after>requirejs.config({
    paths: {
        columnfilter: 'DataTables/extras/ColumnFilterWidgets'
    },
    shim: {
        columnfilter: [ "jquery.dataTables" ]
    }
})
define(['jquery', 'underscore', 'jquery.dataTables', 'columnfilter'],
    function ($, _) {
    function Table(options) {
        var self = this;
        options = options ? _.clone(options) : {};
        options.scrollY = options.scrollY || 300;
        var filterExclude = [];
        var $element = $(options.element);
        var elementOffset = $element.offset();
        self.setData = function (data) {
            self.data = data;
            data.filter = data.filter || [];
            for (var i = 0; i < data.columns.length; i++) {
                if (!_.contains(data.filter, data.columns[i])) {
                    filterExclude.push(i);
                }
            }
        };
        self.display = function () {
            var $table = $("
").attr("cellpadding", 0)
                .attr("cellspacing",0).attr("border", 0)
                .addClass('table table-striped table-bordered');
            $element.empty().append($table);
            var cols = _.map(self.data.columns, function (d) {
                return { sTitle: d };
            })
            $table.dataTable({
                sInfo: "muted",
                aaData: self.data.data,
                aoColumns: cols,
        		sPaginationType: "bootstrap",
                sScrollY: options.scrollY,
                bPaginate: false,
        		oLanguage: {
        			sLengthMenu: "_MENU_ per page"
        		},
                oColumnFilterWidgets: {
                    aiExclude: filterExclude,
                    bGroupTerms: true
                }
            });
            adjustHeight('.dataTables_wrapper');
            adjustHeight('.table-wrapper');
            $(".column-filter-widget").find("select").addClass("mini");
            $element.offset({
                top: elementOffset.top, left: elementOffset.left
            });
            // $(".dataTable .sorting_asc").each(function () {
            //     $(this).html(
            //         $(this).html() + "");
            // });
            // $(".dataTable .sorting_desc").each(function () {
            //     $(this).html(
            //         $(this).html() + "");
            // });

        };
        function adjustHeight(selector) {
            $(selector).each(function () {
                var w = $(this);
                var p = w.parent();
                var totalHeight = 0;
                p.children().each(function () {
                    totalHeight += $(this).outerHeight(true)
                });
                w.height(p.height() + w.outerHeight(true) - totalHeight);
            });
        }
    }
    /* Set the defaults for DataTables initialization */
    $.extend(true, $.fn.dataTable.defaults, {
    	sDom: "<'dt-top row'<'span6'Wl><'span6'fr>>" +
             "<'table-wrapper't><'dt-bottom'ip>",
        fnInitComplete: function (table) {
            $('.dataTables_length').find("select").addClass("span2");
            $('.dataTables_filter').find(":input")
                .addClass("input-small search-query")
                .attr("placeholder", "Search");
            $('.dataTables_length > label').contents().filter(function() {
                return this.nodeType != 1;
            }).wrap("");
        },
        sPaginationType: "bootstrap",
    	oLanguage: {
    		sLengthMenu: "_MENU_ records per page",
            sInfo: "_START_-_END_ of _TOTAL_ entries",
            sSearch: ""
    	}
    });

    /* Default class modification */
    $.extend($.fn.dataTableExt.oStdClasses, {
    	sWrapper: "dataTables_wrapper form-inline",
        sInfo: "mini muted dt-info"
    });

    /* API method to get paging information */
    $.fn.dataTableExt.oApi.fnPagingInfo = function (opts) {
    	return {
    		iStart:         opts._iDisplayStart,
    		iEnd:           opts.fnDisplayEnd(),
    		iLength:        opts._iDisplayLength,
    		iTotal:         opts.fnRecordsTotal(),
    		iFilteredTotal: opts.fnRecordsDisplay(),
    		iPage:
                Math.ceil(opts._iDisplayStart / opts._iDisplayLength),
    		iTotalPages:
                Math.ceil(opts.fnRecordsDisplay() / opts._iDisplayLength)
    	};
    };

    /* Bootstrap style pagination control */
    $.extend($.fn.dataTableExt.oPagination, {
    	bootstrap: {
    		fnInit: function (opts, nPaging, fnDraw) {
    			var oLang = opts.oLanguage.oPaginate;
    			var fnClickHandler = function (e) {
    				e.preventDefault();
    				if (opts.oApi._fnPageChange(opts, e.data.action)) {
    					fnDraw(opts);
    				}
    			};
    			$(nPaging).addClass('pagination pagination-mini').append(_.template(
    				'
' +
                        '
' +
                        '←
'+
    					'
'+
                        '→
'+
    				'
', { prev: oLang.sPrevious, next: oLang.sNext })
    			);
    			var els = $('a', nPaging);
    			$(els[0]).bind('click.DT',
                    { action: "previous" }, fnClickHandler);
    			$(els[1]).bind('click.DT',
                    { action: "next" }, fnClickHandler);
    		},
    		fnUpdate: function (opts, fnDraw) {
    			var iListLength = 5;
    			var oPaging = opts.oInstance.fnPagingInfo();
    			var an = opts.aanFeatures.p;
    			var i, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);

    			if ( oPaging.iTotalPages < iListLength) {
    				iStart = 1;
    				iEnd = oPaging.iTotalPages;
    			}
    			else if (oPaging.iPage <= iHalf) {
    				iStart = 1;
    				iEnd = iListLength;
    			} else if (oPaging.iPage >= (oPaging.iTotalPages-iHalf)) {
    				iStart = oPaging.iTotalPages - iListLength + 1;
    				iEnd = oPaging.iTotalPages;
    			} else {
    				iStart = oPaging.iPage - iHalf + 1;
    				iEnd = iStart + iListLength - 1;
    			}

    			for (i=0, iLen=an.length ; i<iLen ; i++) {
    				// Remove the middle elements
    				$('li:gt(0)', an[i]).filter(':not(:last)').remove();

    				// Add the new list items and their event handlers
    				for (j=iStart ;j<=iEnd ;j++) {
    					sClass = (j==oPaging.iPage+1) ? 'class="active"' : '';
    					$('
'+j+'
')
    						.insertBefore($('li:last', an[i])[0])
    						.bind('click', function (e) {
    							e.preventDefault();
    							opts._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;
    							fnDraw(opts);
    						} );
    				}

    				// Add / remove disabled classes from the static elements
    				if (oPaging.iPage === 0) {
    					$('li:first', an[i]).addClass('disabled');
    				} else {
    					$('li:first', an[i]).removeClass('disabled');
    				}

    				if (oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0) {
    					$('li:last', an[i]).addClass('disabled');
    				} else {
    					$('li:last', an[i]).removeClass('disabled');
    				}
    			}
    		}
    	}
    });

    /*
     * TableTools Bootstrap compatibility
     * Required TableTools 2.1+
     */
    if ($.fn.DataTable.TableTools) {
    	// Set the classes that TableTools uses to something suitable for Bootstrap
    	$.extend(true, $.fn.DataTable.TableTools.classes, {
    		container: "DTTT btn-group",
    		buttons: {
    			normal: "btn",
    			disabled: "disabled"
    		},
    		collection: {
    			container: "DTTT_dropdown dropdown-menu",
    			buttons: {
    				normal: "",
    				disabled: "disabled"
    			}
    		},
    		print: {
    			info: "DTTT_print_info modal"
    		},
    		select: {
    			row: "active"
    		}
    	});

    	// Have the collection use a bootstrap compatible dropdown
    	$.extend(true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
    		collection: {
    			container: "ul",
    			button: "li",
    			liner: "a"
    		}
    	});
    }

    return Table;
});<|endoftext|>


<commit_before>(function () {
    "use strict";

    // Globally (to this module) listen for mouse down so we can check later if the mouse is depressed :
    var _down = false;
    $(document).mousedown(function(e) {
        _down = true;
    }).mouseup(function(e) {
        _down = false;
    }).mouseleave(function(e) {
        _down = false;
    });

    app.DiaryView = BBC.BaseView.extend({

        template : _.template($('#Diary-template').html(), null, {variable : 'data'}),

        render : function () {
            var self = this;

            this.collection.each(function (dayModel) {
                var newView = self.subViews.add(app.DiaryRowView, {
                    model : dayModel
                }).render();

                self.$el.append(newView.$el);
            });

            return this;
        }

    });

    /**
     * Row view represents each day model. For each day you can click on the time slots to indicate your sleep patterns.
     * This view has as it's sub views a collection of DiaryTimeViews (below)
     * @type {void|*}
     */
    app.DiaryRowView = BBC.BaseView.extend({

        className : 'diary-row',

        template : _.template($('#DiaryRow-template').html(), null, {variable : 'data'}),

        _timeout : null,
        _currContainer : null,
        _amPm : 'AM : ',

        initialize : function () {
            this.on('changeSleepState', this.changeSleepState);
        },

        render : function () {
            this.$el.html(this.template(this.model.toJSON()));
            this.renderTimes();
            return this;
        },

        renderTimes : function () {
            var am = this._getTimeRange(true, 1, 12);
            var pm = this._getTimeRange(false, 1, 12);

            this._addDivider('PM :');
            this._addTimes(pm);

            this._addDivider('AM :');
            this._addTimes(am);
        },

        /**
         * Helper function to get keys in a given time range.
         * @param am
         * @param lowerBound
         * @param upperBound
         * @returns {Array}
         * @private
         */
        _getTimeRange : function (am, lowerBound, upperBound) {

            var out = [];
            for (var i=lowerBound; i<=upperBound; i++) {
                for (var j=0; j<=3; j++) {
                    var mins = j * 15;
                    mins = mins == 0 ? '00' : mins;
                    out.push(i + ':' + mins + (am ? 'am' : 'pm'));
                }
            }
            return out;
        },

        /**
         * Helper function to get times in a given range.
         * Takes the upper bound, lower bound, and am boolean.
         * @param am <bool>
         * @param lowerBound <number>
         * @param upperBound <number>
         * @private
         */
        _filterTimes : function (am, lowerBound, upperBound) {
            return _.filter(_.keys(this.model.toJSON()), function (timeKey) {
                if (!this._isTimeKey(timeKey)) {
                    return false;
                }

                var hour = parseInt(timeKey.split(':')[0], 10);
                var isAm = timeKey.match(/[a-z]{2}/)[0] === 'am';
                var inRange = ((lowerBound <= hour) && ( hour <= upperBound)) && (isAm === am);

                return inRange;

            }, this);
        },

        /**
         * Helper function to add a divider between the sub-views. Divides the rows into day / night.
         * @param label
         * @private
         */
        _addDivider : function(label) {
            this._currContainer = $('<div>').addClass('time-container');
            this._currContainer.prepend($('<div>').addClass('time-ampm').html(label));
            this.$el.append(this._currContainer);
        },

        /**
         * Helper function to add another time sub-views. Takes an array of times, for each 4 sub-views that are added
         * this method adds a time marker to the view.
         * @param timeArr
         * @private
         */
        _addTimes : function (timeArr) {
            _.each(timeArr, function (fullTime) {

                var val = this.model.get(fullTime);
                var currLen = this.subViews.length;
                var hour = fullTime.split(':')[0];

                var timeView = this.subViews.add(app.DiaryTimeView, {
                    model : new Backbone.Model({
                        displayTime : (currLen % 4 === 0) ? hour : '',
                        time : fullTime,
                        state : val
                    })
                }).render();

                this._currContainer.append(timeView.$el);

            }, this);
        },

        _isTimeKey : function (str) {
            return str.indexOf(':') !== -1;
        },

        /**
         * Saves the day model with the udpated sleep state. Waits for a timeout in case the user is multi-selecting
         * many sleep "squares"
         * @param time
         * @param state
         */
        changeSleepState : function (time, state) {
            this.model.set(time, state);
            clearTimeout(this._timeout);
            this._timeout = setTimeout(function () {
                this.model.save();
            }.bind(this), 1000);
        }

    });

    app.DiaryTimeView = BBC.BaseView.extend({

        className : 'time',

        template : _.template($('#DiaryRowTime-template').html(), null, {variable : 'data'}),

        events : {
            'mousedown' : 'checkToggleDozing',
            'mouseenter' : 'checkToggleSleep'
        },

        /**
         * On mouse enter, check if the mouse is depressed. If so then toggle the sleep position :
         * @param e
         */
        checkToggleSleep : function () {
            if (_down) {
                return this.toggleSleep();
            }
        },

        toggleSleep : function (e) {
            var currState = this.model.get('state');
            var newState = currState === 'AWAKE' ? 'ASLEEP' : 'AWAKE';
            return this._setState(newState);
        },

        checkToggleDozing : function (e) {
            if (e.shiftKey || e.ctrlKey) {
                return this._setState('DOZING');
            } else {
                return this.toggleSleep();
            }
        },

        _setState : function (newState) {
            var states = ['ASLEEP', 'AWAKE', 'DOZING'];
            _.each(states, function (val) {
                this.$('.time-hour').removeClass(val);
            }, this);

            this.$('.time-hour').addClass(newState);

            this.model.set('state', newState);

            this.parentView.trigger('changeSleepState', this.model.get('time'), newState);
        }
    });

})();
<commit_msg>Re-organized teh times again.<commit_after>(function () {
    "use strict";

    // Globally (to this module) listen for mouse down so we can check later if the mouse is depressed :
    var _down = false;
    $(document).mousedown(function(e) {
        _down = true;
    }).mouseup(function(e) {
        _down = false;
    }).mouseleave(function(e) {
        _down = false;
    });

    app.DiaryView = BBC.BaseView.extend({

        template : _.template($('#Diary-template').html(), null, {variable : 'data'}),

        render : function () {
            var self = this;

            this.collection.each(function (dayModel) {
                var newView = self.subViews.add(app.DiaryRowView, {
                    model : dayModel
                }).render();

                self.$el.append(newView.$el);
            });

            return this;
        }

    });

    /**
     * Row view represents each day model. For each day you can click on the time slots to indicate your sleep patterns.
     * This view has as it's sub views a collection of DiaryTimeViews (below)
     * @type {void|*}
     */
    app.DiaryRowView = BBC.BaseView.extend({

        className : 'diary-row',

        template : _.template($('#DiaryRow-template').html(), null, {variable : 'data'}),

        _timeout : null,
        _currContainer : null,
        _amPm : 'AM : ',

        initialize : function () {
            this.on('changeSleepState', this.changeSleepState);
        },

        render : function () {
            this.$el.html(this.template(this.model.toJSON()));
            this.renderTimes();
            return this;
        },

        renderTimes : function () {

            var midnight = this._getTimeRange(true, 12, 12);

            var morning = this._getTimeRange(true, 1, 11);

            var noon = this._getTimeRange(false, 12, 12);
            var night = this._getTimeRange(false, 1, 11);

            this._addDivider('AM :');
            this._addTimes(midnight);
            this._addTimes(morning);

            this._addDivider('PM :');
            this._addTimes(noon);
            this._addTimes(night);
        },

        /**
         * Helper function to get keys in a given time range.
         * @param am
         * @param lowerBound
         * @param upperBound
         * @returns {Array}
         * @private
         */
        _getTimeRange : function (am, lowerBound, upperBound) {

            var out = [];
            for (var i=lowerBound; i<=upperBound; i++) {
                for (var j=0; j<=3; j++) {
                    var mins = j * 15;
                    mins = mins == 0 ? '00' : mins;
                    out.push(i + ':' + mins + (am ? 'am' : 'pm'));
                }
            }
            return out;
        },

        /**
         * Helper function to get times in a given range.
         * Takes the upper bound, lower bound, and am boolean.
         * @param am <bool>
         * @param lowerBound <number>
         * @param upperBound <number>
         * @private
         */
        _filterTimes : function (am, lowerBound, upperBound) {
            return _.filter(_.keys(this.model.toJSON()), function (timeKey) {
                if (!this._isTimeKey(timeKey)) {
                    return false;
                }

                var hour = parseInt(timeKey.split(':')[0], 10);
                var isAm = timeKey.match(/[a-z]{2}/)[0] === 'am';
                var inRange = ((lowerBound <= hour) && ( hour <= upperBound)) && (isAm === am);

                return inRange;

            }, this);
        },

        /**
         * Helper function to add a divider between the sub-views. Divides the rows into day / night.
         * @param label
         * @private
         */
        _addDivider : function(label) {
            this._currContainer = $('<div>').addClass('time-container');
            this._currContainer.prepend($('<div>').addClass('time-ampm').html(label));
            this.$el.append(this._currContainer);
        },

        /**
         * Helper function to add another time sub-views. Takes an array of times, for each 4 sub-views that are added
         * this method adds a time marker to the view.
         * @param timeArr
         * @private
         */
        _addTimes : function (timeArr) {
            _.each(timeArr, function (fullTime) {

                var val = this.model.get(fullTime);
                var currLen = this.subViews.length;
                var hour = fullTime.split(':')[0];

                var timeView = this.subViews.add(app.DiaryTimeView, {
                    model : new Backbone.Model({
                        displayTime : (currLen % 4 === 0) ? hour : '',
                        time : fullTime,
                        state : val
                    })
                }).render();

                this._currContainer.append(timeView.$el);

            }, this);
        },

        _isTimeKey : function (str) {
            return str.indexOf(':') !== -1;
        },

        /**
         * Saves the day model with the udpated sleep state. Waits for a timeout in case the user is multi-selecting
         * many sleep "squares"
         * @param time
         * @param state
         */
        changeSleepState : function (time, state) {
            this.model.set(time, state);
            clearTimeout(this._timeout);
            this._timeout = setTimeout(function () {
                this.model.save();
            }.bind(this), 1000);
        }

    });

    app.DiaryTimeView = BBC.BaseView.extend({

        className : 'time',

        template : _.template($('#DiaryRowTime-template').html(), null, {variable : 'data'}),

        events : {
            'mousedown' : 'checkToggleDozing',
            'mouseenter' : 'checkToggleSleep'
        },

        /**
         * On mouse enter, check if the mouse is depressed. If so then toggle the sleep position :
         * @param e
         */
        checkToggleSleep : function () {
            if (_down) {
                return this.toggleSleep();
            }
        },

        toggleSleep : function (e) {
            var currState = this.model.get('state');
            var newState = currState === 'AWAKE' ? 'ASLEEP' : 'AWAKE';
            return this._setState(newState);
        },

        checkToggleDozing : function (e) {
            if (e.shiftKey || e.ctrlKey) {
                return this._setState('DOZING');
            } else {
                return this.toggleSleep();
            }
        },

        _setState : function (newState) {
            var states = ['ASLEEP', 'AWAKE', 'DOZING'];
            _.each(states, function (val) {
                this.$('.time-hour').removeClass(val);
            }, this);

            this.$('.time-hour').addClass(newState);

            this.model.set('state', newState);

            this.parentView.trigger('changeSleepState', this.model.get('time'), newState);
        }
    });

})();
<|endoftext|>


<commit_before><commit_msg>message onhide bug fix<commit_after><|endoftext|>


<commit_before>var Catalog = angular.module('catalog', []);

Catalog.config([ '$compileProvider', function($compileProvider) {
	$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|stremio):/);
}]);

Catalog.factory("stremio", ["$http", function($http) {
	var self = {};

	$http.get("http://api9.strem.io/addons5").success(function(res) {
		console.log(res);
	});

	return self;
}]);

Catalog.factory('Items', [ 'stremio', '$rootScope', '$location', function(stremio, $scope, $location) {
	var Client = require("stremio-addons").Client;
	var addons = new Client();

	var self = { addons: addons };

	addons.add("http://cinemeta.strem.io/stremioget");
	addons.add("http://channels.strem.io/stremioget");

	var addonUrl = $location.search().addon;
	if (addonUrl) addons.add(addonUrl);

	var genres = self.genres = {};
	var items = [];

	addons.meta.find({ query: { }, limit: 500, skip: 0, complete: true, popular: true, projection: "lean" }, function(err, r) {
		if (!r) return;

		items = r;
		items.forEach(function(x) {
			if (! genres[x.type]) genres[x.type] = { };
			if (x.genre) x.genre.forEach(function(g) { genres[x.type][g] = 1 });
		});
		$scope.$apply();
	});

	self.all = function() { return items };

	return self;
}]);

Catalog.controller('CatalogController', ['Items', '$scope', '$timeout', '$window', '$q', function CatalogController(Items, $scope, $timeout, $window, $q) {
	var self = this;

	var imdb_proxy = '/poster/';

	self.loading = false;
	self.query = '';
	self.showType = 'movie';
	self.showGenre = '';
	self.catTypes = {
		movie: { name: 'Movies', genres: {} },
		series: { name: 'TV Shows', genres: {} }
	};
	self.genres = Items.genres;

	$scope.$watch(function() { return Items.loading }, function(loading) { self.loading = loading });
	$scope.$watchCollection(function() { return [self.showType, self.showGenre, Items.all().length] }, function() {
		self.items = Items.all().filter(function(x) {
			return (x.type == self.showType) &&
				(!self.showGenre || (x.genre.indexOf(self.showGenre) > -1))
		});
		self.selected = self.items[0];
	});
	$scope.$watch(function() { return self.selected && self.selected.imdb_id }, function() {
		if (! self.selected) return;
		Items.addons.stream.find({ query: { imdb_id: self.selected.imdb_id } }, function(err, res) {
			self.selected.streams = res;
			self.selected.stream = res[0]; // OBSOLETE
			$scope.$apply();
		});
	});

	self.formatImgURL = function formatImgURL(url, width, height) {
		if (!url || -1 === url.indexOf("imdb.com")) return url;

		var splitted = url.split("/").pop().split(".");

		if (1 === splitted.length) return url;

		return imdb_proxy + encodeURIComponent(url.split("/").slice(0,-1).join("/") + "/" + splitted[0] + "._V1._SX" + width + "_CR0,0," + width + "," + height + "_.jpg");
	};

	self.selectGenre = function selectGenre(genre) {
		if(self.showGenre === genre) return;
		self.showGenre = genre;
	};

	self.selectType = function selectType(type) {
		if (self.showType === type) return;
		self.showType = type;
		self.showGenre = '';
	};

	self.selectMovie = function selectMovie(movie) {
		self.selected = movie;
	};

	return self;
}]);

<commit_msg>Load all add-ons from the tracker<commit_after>var Catalog = angular.module('catalog', []);

// Allow stremio:// protocol
Catalog.config([ '$compileProvider', function($compileProvider) {
	$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|stremio):/);
}]);

// Initiate the client to the add-ons
Catalog.factory("stremio", ["$http", function($http) {
	var Stremio = require("stremio-addons");
	var stremio = new Stremio.Client();

	stremio.official = ["http://cinemeta.strem.io", "http://guidebox.strem.io", "http://channels.strem.io", "http://filmon.strem.io"];
	stremio.thirdparty = [];

	var add = stremio.add.bind(stremio);
	stremio.official.forEach(add);

	// Load add-ons from tracker
	$http.get("http://api9.strem.io/addons5").success(function(res) {
		stremio.official = res.official;
		stremio.thirdparty = res.thirdparty;
		res.official.forEach(add); res.thirdparty.forEach(add);
	}).error(function(er) { console.error("add-ons tracker", er) });

	return stremio;
}]);

Catalog.factory('Items', [ 'stremio', '$rootScope', '$location', function(stremio, $scope, $location) {
	var self = { };

	var genres = self.genres = {};
	var items = [];

	stremio.meta.find({ query: { }, limit: 200, skip: 0, complete: true, popular: true, projection: "lean" }, function(err, r) {
		if (!r) return;

		items = r;
		items.forEach(function(x) {
			if (! genres[x.type]) genres[x.type] = { };
			if (x.genre) x.genre.forEach(function(g) { genres[x.type][g] = 1 });
		});
		$scope.$apply();
	});

	self.all = function() { return items };

	return self;
}]);

Catalog.controller('CatalogController', ['Items', 'stremio', '$scope', '$timeout', '$window', '$q', function CatalogController(Items, stremio, $scope, $timeout, $window, $q) {
	var self = this;

	var imdb_proxy = '/poster/';

	self.loading = false;
	self.query = '';
	self.showType = 'movie';
	self.showGenre = '';
	self.catTypes = {
		movie: { name: 'Movies', genres: {} },
		series: { name: 'TV Shows', genres: {} }
	};
	self.genres = Items.genres;

	$scope.$watch(function() { return Items.loading }, function(loading) { self.loading = loading });
	$scope.$watchCollection(function() { return [self.showType, self.showGenre, Items.all().length] }, function() {
		self.items = Items.all().filter(function(x) {
			return (x.type == self.showType) &&
				(!self.showGenre || (x.genre.indexOf(self.showGenre) > -1))
		});
		self.selected = self.items[0];
	});
	$scope.$watch(function() { return self.selected && self.selected.imdb_id }, function() {
		if (! self.selected) return;
		stremio.stream.find({ query: { imdb_id: self.selected.imdb_id } }, function(err, res) {
			self.selected.streams = res;
			self.selected.stream = res[0]; // OBSOLETE
			$scope.$apply();
		});
	});

	self.formatImgURL = function formatImgURL(url, width, height) {
		if (!url || -1 === url.indexOf("imdb.com")) return url;

		var splitted = url.split("/").pop().split(".");

		if (1 === splitted.length) return url;

		return imdb_proxy + encodeURIComponent(url.split("/").slice(0,-1).join("/") + "/" + splitted[0] + "._V1._SX" + width + "_CR0,0," + width + "," + height + "_.jpg");
	};

	self.selectGenre = function selectGenre(genre) {
		if(self.showGenre === genre) return;
		self.showGenre = genre;
	};

	self.selectType = function selectType(type) {
		if (self.showType === type) return;
		self.showType = type;
		self.showGenre = '';
	};

	self.selectMovie = function selectMovie(movie) {
		self.selected = movie;
	};

	return self;
}]);

<|endoftext|>


<commit_before>$(function(){
var textfield = $("input[name=user]");
            $('button[type="submit"]').click(function(e) {
                e.preventDefault();
                //little validation just to check username
                if (textfield.val() != "") {
                    //$("body").scrollTo("#output");
                    $("#output").addClass("alert alert-success animated fadeInUp").html("Welcome back " + "" + textfield.val() + "");
                    $("#output").removeClass(' alert-danger');
                    $("input").css({
                    "height":"0",
                    "padding":"0",
                    "margin":"0",
                    "opacity":"0"
                    });
                    //change button text
                    $('button[type="submit"]').html("continue")
                    .removeClass("btn-info")
                    .addClass("btn-default").click(function(){
                    $("input").css({
                    "height":"auto",
                    "padding":"10px",
                    "opacity":"1"
                    }).val("");
                    });

                    //show avatar
                    $(".avatar").css({
                        "background-image": "url('http://api.randomuser.me/0.3.2/portraits/women/35.jpg')"
                    });
                } else {
                    //remove success mesage replaced with error message
                    $("#output").removeClass(' alert alert-success');
                    $("#output").addClass("alert alert-danger animated fadeInUp").html("sorry enter a username ");
                }
                //console.log(textfield.val());

            });
});
<commit_msg>Removed unnecessary js file<commit_after><|endoftext|>