<commit_before>// test
var React = require('react');
var PaginationNumberItem = React.createClass({
  clickPageNum: function(newPage) {
    this.props.onPageNumberChanged(newPage);
  },
  render: function() {
    if (this.props.pagenum) {
      var className = this.props.pagenum == this.props.currentPage ? "page_num on" : "page_num";
      return (

          {this.props.pagenum}

      );
    } else {
      return (

          ...

      );
    }
  }
});
var PaginationSelectControlOption = React.createClass({
  render: function() {
    return (
      <option value={this.props.value}>{this.props.value}</option>
    );
  }
});
var Pagination = React.createClass({
  getInitialState: function() {
    return Object.assign({}, {
      total: 1,
      pageList: [10, 20, 30, 50],
      pageSize: 10,
      pageNumber: 1,
      loading: false,
      onChangePageSize: function(pageSize) {
      },
      onSelectPage: function(pageNumber, pageSize) {

}    }, this.props);
  },
  buildPageNumberElements: function() {
    var pageNumberElements = [];
    var pages = Math.ceil(this.state.total / this.state.pageSize);
    var currentPage = this.state.pageNumber;
    if (pages <= 6) {
      for(var i = 0; i < pages; i++) {
        var page = i + 1;
        pageNumberElements.push(<PaginationNumberItem onPageNumberChanged={this.changePageNum} currentPage={this.state.pageNumber} key={page} pagenum={page} />);
      }
    } else {
      if (currentPage <= 3 || currentPage >= pages - 2) {
        for(var i = 0; i < 3; i++) {
          var page = i + 1;
          pageNumberElements.push(<PaginationNumberItem onPageNumberChanged={this.changePageNum} currentPage={this.state.pageNumber} key={page} pagenum={page} />);
        }
        pageNumberElements.push(<PaginationNumberItem />);
      } else {
        for(var i = currentPage - 3; i < currentPage; i++) {
          var page = i + 1;
          pageNumberElements.push(<PaginationNumberItem onPageNumberChanged={this.changePageNum} currentPage={this.state.pageNumber} key={page} pagenum={page} />);
        }
        if (currentPage + 3 != pages) {
          pageNumberElements.push(<PaginationNumberItem />);
        }
      }
      for(var i = pages - 3; i < pages; i++) {
        var page = i + 1;
        pageNumberElements.push(<PaginationNumberItem onPageNumberChanged={this.changePageNum} currentPage={this.state.pageNumber} key={page} pagenum={page} />);
      }
    }
    return pageNumberElements;
  },
  changePageNum: function(newPage) {
    console.log('newpage:', newPage);
    this.setState({
      pageNumber: newPage
    });
  },
  changePageSize: function(event) {
    this.setState({
      pageSize: event.target.value
    });
  },
  prev: function() {
    this.setState(function(prevState, props) {
      this.gotoPage(prevState.pageNumber - 1);
    });
  },
  next: function() {
    this.setState(function(prevState, props) {
      this.gotoPage(prevState.pageNumber + 1);
    });
  },
  handleGoBtn: function() {
    var inputVal = this.pagenumInput.value;
    if (isNaN(inputVal)) {
      return false;
    }
    inputVal = parseInt(inputVal);
    this.gotoPage(inputVal);
  },
  gotoPage: function(newPage) {
    newPage = parseInt(newPage);
    if (isNaN(newPage)) return false;
    var pages = Math.ceil(this.state.total / this.state.pageSize);
    if (newPage > 0 && newPage <= pages) {
      this.setState({
        pageNumber: newPage
      });
    }
  },
  render: function() {
    var pages = Math.ceil(this.state.total / this.state.pageSize);
    var pageNumberList = this.buildPageNumberElements();
    var paginationSelectOptions = this.state.pageList.map(function(v) {
      return <PaginationSelectControlOption key={v} value={v} />;
    });
    var prevBtnCls = this.state.pageNumber < 2 ? "page_prev border disable" : "page_prev border";
    var nextBtnCls = this.state.pageNumber == pages ? "page_next border disable" : "page_next border";
    return (

          共{this.state.total}条记录，显示行数
          <select name="" onChange={this.changePageSize}>
            {paginationSelectOptions}
          </select>
          页

          {pageNumberList}

转到

<input ref={(input) => { this.pagenumInput = input; }} type="text" name="page_num" />

页

<button>go</button>

    );
  }
});

module.exports = Pagination;<commit_msg>Update paginationComponent.js<commit_after>// test
var React = require('react');
var PaginationNumberItem = React.createClass({
  clickPageNum: function(newPage) {
    this.props.onPageNumberChanged(newPage);
  },
  render: function() {
    if (this.props.pagenum) {
      var className = this.props.pagenum == this.props.currentPage ? "page_num on" : "page_num";
      return (

          {this.props.pagenum}

      );
    } else {
      return (

          ...

      );
    }
  }
});
var PaginationSelectControlOption = React.createClass({
  render: function() {
    return (
      <option value={this.props.value}>{this.props.value}</option>
    );
  }
});
var Pagination = React.createClass({
  getInitialState: function() {
    return Object.assign({}, {
      total: 1,
      pageList: [10, 20, 30, 50],
      pageSize: 10,
      pageNumber: 1,
      loading: false,
      onChangePageSize: function(pageSize) {
      },
      onSelectPage: function(pageNumber, pageSize) {

}    }, this.props);
  },
  buildPageNumberElements: function() {
    var pageNumberElements = [];
    var pages = Math.ceil(this.state.total / this.state.pageSize);
    var currentPage = this.state.pageNumber;
    if (pages <= 6) {
      for(var i = 0; i < pages; i++) {
        var page = i + 1;
        pageNumberElements.push(<PaginationNumberItem onPageNumberChanged={this.changePageNum} currentPage={this.state.pageNumber} key={page} pagenum={page} />);
      }
    } else {
      if (currentPage <= 3 || currentPage >= pages - 2) {
        for(var i = 0; i < 3; i++) {
          var page = i + 1;
          pageNumberElements.push(<PaginationNumberItem onPageNumberChanged={this.changePageNum} currentPage={this.state.pageNumber} key={page} pagenum={page} />);
        }
        pageNumberElements.push(<PaginationNumberItem />);
      } else {
        for(var i = currentPage - 3; i < currentPage; i++) {
          var page = i + 1;
          pageNumberElements.push(<PaginationNumberItem onPageNumberChanged={this.changePageNum} currentPage={this.state.pageNumber} key={page} pagenum={page} />);
        }
        if (currentPage + 3 != pages) {
          pageNumberElements.push(<PaginationNumberItem />);
        }
      }
      for(var i = pages - 3; i < pages; i++) {
        var page = i + 1;
        pageNumberElements.push(<PaginationNumberItem onPageNumberChanged={this.changePageNum} currentPage={this.state.pageNumber} key={page} pagenum={page} />);
      }
    }
    return pageNumberElements;
  },
  changePageNum: function(newPage) {
    console.log('newpage:', newPage);
    this.setState({
      pageNumber: newPage
    });
  },
  changePageSize: function(event) {
    var newPageSize = event.target.value;
    this.setState(function(prevState, props) {
      var newStates = {
        pageSize: newPageSize
      };
      var pages = Math.ceil(props.total / newPageSize);
      if (prevState.pageNumber > pages) {
        newStates.pageNumber = pages;
      }
      return newStates;
    });
  },
  prev: function() {
    this.setState(function(prevState, props) {
      this.gotoPage(prevState.pageNumber - 1);
    });
  },
  next: function() {
    this.setState(function(prevState, props) {
      this.gotoPage(prevState.pageNumber + 1);
    });
  },
  handleGoBtn: function() {
    var inputVal = this.pagenumInput.value;
    if (isNaN(inputVal)) {
      return false;
    }
    inputVal = parseInt(inputVal);
    this.gotoPage(inputVal);
  },
  gotoPage: function(newPage) {
    newPage = parseInt(newPage);
    if (isNaN(newPage)) return false;
    var pages = Math.ceil(this.state.total / this.state.pageSize);
    if (newPage > 0 && newPage <= pages) {
      this.setState({
        pageNumber: newPage
      });
    }
  },
  render: function() {
    var pages = Math.ceil(this.state.total / this.state.pageSize);
    var pageNumberList = this.buildPageNumberElements();
    var paginationSelectOptions = this.state.pageList.map(function(v) {
      return <PaginationSelectControlOption key={v} value={v} />;
    });
    var prevBtnCls = this.state.pageNumber < 2 ? "page_prev border disable" : "page_prev border";
    var nextBtnCls = this.state.pageNumber == pages ? "page_next border disable" : "page_next border";
    return (

          共{this.state.total}条记录，显示行数
          <select name="" onChange={this.changePageSize}>
            {paginationSelectOptions}
          </select>
          页

          {pageNumberList}

转到

<input ref={(input) => { this.pagenumInput = input; }} type="text" name="page_num" />

页

<button>go</button>

    );
  }
});

module.exports = Pagination;<|endoftext|>


<commit_before>/*
 * Ludum Dare 29
 * Tustin2121 & MaverickLoneshark
 */

/* Canvas Manager Object */
(function(){
	/*-- "Private" Variables --*/
	/*-- Constants --*/
	var CANVAS_WIDTH = 1024;
	var CANVAS_HEIGHT = 256;

	//Constructor
	function CanvasManager(){}

	/*-- "Private" Methods --*/

	//class definition
	CanvasManager.fn = CanvasManager.prototype = {
		/*-- "Public" Variables --*/
		canvases : [],
		contexts : [],

		/*-- "Public" Methods --*/
		//addCanvas() :
		addCanvas : function() {
			var canvas = $("<canvas width='"+CANVAS_WIDTH+"' height='"+CANVAS_HEIGHT+"'>");
			var index = this.canvases.length;
			canvas.css("top", index * CANVAS_HEIGHT);

			canvas[0].onmouseup = function(event)
			{
				var x = event.pageX - canvas.offset().left;
				var y = event.pageY;
				ldGame.projectile_manager.initializeProjectile(0, x, y, (Math.random() * 10) - 5, (Math.random() * 10) - 5);

				return;
			};

			this.contexts[index] = canvas[0].getContext("2d");

			this.canvases.push(canvas);

			$("#sky").append(canvas);
		},

		// redrawAll() : redraws all canvases registered in the canvas manager
		redrawAll : function() {
			for (var i = 0; i < this.contexts.length; i++) {
				this.redraw(i);
			}
		},

		// redraw() : draws a given canvas
		redraw : function(index) {
			var context = this.contexts[index];

			var dirty = false;

			//draw contained projectiles
			var projectiles = ldGame.projectile_manager.projectiles;

			for(var p = 0; p < projectiles.length; p++)
			{
				var offheight =  (index * CANVAS_HEIGHT);
				if(projectiles[p].active &&
					(projectiles[p].x[0] >= 0) && (projectiles[p].x[0] < CANVAS_WIDTH) &&
					(projectiles[p].y[0] >= offheight) && (projectiles[p].y[0] < (offheight + CANVAS_HEIGHT)))
				{
					if(!dirty)
					{
						context.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
						dirty = true;
					}

					context.beginPath();

					context.moveTo(projectiles[p].x[0], projectiles[p].y[0] - offheight);
					for(var i = 1; i < projectiles[p].x.length; i++)
					{
						context.lineTo(projectiles[p].x[i], projectiles[p].y[i] - offheight);
						context.moveTo(projectiles[p].x[i], projectiles[p].y[i] - offheight);
					}

					context.fillStyle="#FFFFFF";
					context.fillRect(projectiles[p].x[0] - 4, projectiles[p].y[0] - offheight - 4, 8, 8);

					switch(projectiles[p].type)
					{
						case 0:
							context.strokeStyle="#FF0000";
						break;

						default:
							context.strokeStyle="#FF0000";
						break;
					}
					context.lineWidth=5;
					context.stroke();
				}
			}
		},

		toString : function(){ return "[CanvasManager: "+this.canvases.length+" canvases]"}
	};

	CanvasManager.prototype.CANVAS_WIDTH = CANVAS_WIDTH;
	CanvasManager.prototype.CANVAS_HEIGHT = CANVAS_HEIGHT;

	//expose the CanvasManager class
	window.CanvasManager = CanvasManager;
})();
<commit_msg>Attempting Merge<commit_after>/*
 * Ludum Dare 29
 * Tustin2121 & MaverickLoneshark
 */

/* Canvas Manager Object */
(function(){
	/*-- "Private" Variables --*/
	/*-- Constants --*/
	var CANVAS_WIDTH = 1024;
	var CANVAS_HEIGHT = 256;
	var CANVAS_DRAW_BUFFER = 32;

	//Constructor
	function CanvasManager(){}

	/*-- "Private" Methods --*/

	//class definition
	CanvasManager.fn = CanvasManager.prototype = {
		/*-- "Public" Variables --*/
		canvases : [],
		contexts : [],

		/*-- "Public" Methods --*/
		//addCanvas() :
		addCanvas : function() {
			var canvas = $("<canvas width='"+CANVAS_WIDTH+"' height='"+CANVAS_HEIGHT+"'>");
			var index = this.canvases.length;
			canvas.css("top", index * CANVAS_HEIGHT);

			canvas[0].onmouseup = function(event)
			{
				var x = event.pageX - canvas.offset().left;
				var y = event.pageY;
				ldGame.projectile_manager.initializeProjectile(0, x, y, (Math.random() * 10) - 5, (Math.random() * 10) - 5);

				return;
			};

			this.contexts[index] = canvas[0].getContext("2d");

			this.canvases.push(canvas);

			$("#sky").append(canvas);
		},

		// redrawAll() : redraws all canvases registered in the canvas manager
		redrawAll : function() {
			for (var i = 0; i < this.contexts.length; i++) {
				this.redraw(i);
			}
		},

		// redraw() : draws a given canvas
		redraw : function(index) {
			var context = this.contexts[index];

			var dirty = false;

			//draw contained projectiles
			var projectiles = ldGame.projectile_manager.projectiles;

			for(var p = 0; p < projectiles.length; p++)
			{
				var offheight =  (index * CANVAS_HEIGHT);
<<<<<<< HEAD
				if(projectiles[p].active &&
					(projectiles[p].x[0] >= 0) && (projectiles[p].x[0] < CANVAS_WIDTH) &&
					(projectiles[p].y[0] >= offheight) && (projectiles[p].y[0] < (offheight + CANVAS_HEIGHT)))
				{
=======
				if (    projectiles[p].active
					&& (projectiles[p].y[0] >= offheight - CANVAS_DRAW_BUFFER)
					&& (projectiles[p].y[0] < offheight + CANVAS_HEIGHT + CANVAS_DRAW_BUFFER)
					&& (projectiles[p].y[ldGame.projectile_manager.TRAIL_LENGTH - 1] >= offheight - CANVAS_DRAW_BUFFER)
					&& (projectiles[p].y[ldGame.projectile_manager.TRAIL_LENGTH - 1] < offheight + CANVAS_HEIGHT + CANVAS_DRAW_BUFFER)
				) {
>>>>>>> 28e95eab0f2ac075d158104c165a7a2a7dbdb610
					if(!dirty)
					{
						context.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
						dirty = true;
					}

					context.beginPath();

					context.moveTo(projectiles[p].x[0], projectiles[p].y[0] - offheight);
					for(var i = 1; i < projectiles[p].x.length; i++)
					{
						context.lineTo(projectiles[p].x[i], projectiles[p].y[i] - offheight);
						context.moveTo(projectiles[p].x[i], projectiles[p].y[i] - offheight);
					}

					context.fillStyle="#FFFFFF";
					context.fillRect(projectiles[p].x[0] - 4, projectiles[p].y[0] - offheight - 4, 8, 8);

					switch(projectiles[p].type)
					{
						case 0:
							context.strokeStyle="#FF0000";
						break;

						default:
							context.strokeStyle="#FF0000";
						break;
					}
					context.lineWidth=5;
					context.stroke();
				}
			}
		},

		toString : function(){ return "[CanvasManager: "+this.canvases.length+" canvases]"}
	};

	CanvasManager.prototype.CANVAS_WIDTH = CANVAS_WIDTH;
	CanvasManager.prototype.CANVAS_HEIGHT = CANVAS_HEIGHT;

	//expose the CanvasManager class
	window.CanvasManager = CanvasManager;
})();
<|endoftext|>


<commit_before>import { PompeiError, WebGLSupportError } from './utils/errors';

export default class Device {
  constructor(canvas, options) {
    if (!(canvas && typeof canvas.getContext === 'function')) {
      throw new PompeiError('Bad Parameters');
    }
    this._options = options || {};

    try {
      this._gl = (
        canvas.getContext('webgl', options) ||
        canvas.getContext('experimental-webgl', options)
      );
    } catch (e) {
      throw new WebGLSupportError();
    }

    if (!this._gl) {
      throw new WebGLSupportError();
    }
  }
}
<commit_msg>Device is not responsible for drawing, the renderer is<commit_after>import Renderer from './Renderer';

import { PompeiError, WebGLSupportError } from './utils/errors';

export default class Device {
  constructor(canvas, options) {
    if (!(canvas && typeof canvas.getContext === 'function')) {
      throw new PompeiError('Bad Parameters');
    }
    this._options = options || {};

    try {
      this._gl = (
        canvas.getContext('webgl', options) ||
        canvas.getContext('experimental-webgl', options)
      );
    } catch (e) {
      throw new WebGLSupportError();
    }

    if (!this._gl) {
      throw new WebGLSupportError();
    }

    this._renderer = new Renderer(this._gl, options);
    this._scene = new Scene(this._renderer, options);
  }

  getRenderer() {
    return this._renderer;
  }
}
<|endoftext|>


<commit_before>(function($, window, document) {
    var $body;

    function shareOnFacebook(url, title, text) {
        var data = {
            app_id: window.appId,
            link: url,
            name: title,
            description: text,
            method: 'feed'
        };

        FB.ui(data);
    }

    function share(type, url, description) {
        var data = {
            url: url,
            text: 'Check this quote!'
        };

        switch (type) {
            case 'share_fb':
                shareOnFacebook(url, data.text, description);
                return;
            case 'share_tw':
                url = 'https://twitter.com/intent/tweet?' + $.param(data);
            break;
            case 'share_gp':
                url = 'https://plus.google.com/share?' + $.param(data);
            break;
        }

        window.open(url, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');
    }

    function setSharing() {
        $('.share').each(function() {
            var $$ = $(this);
            var url = $$.data('url');
            var description = $$.data('description');

            $$.on('click', '.share_buttons a', function(e) {
                e.preventDefault();
                share($(this).attr('class'), url, description);
            });
        });

        var vote = $('.vote').each(function() {
            var $$ = $(this);

            var id = $$.data('id');
            var token = $$.find('[name=csrfmiddlewaretoken]').val();

            var addLikeUrl = $$.data('add');
            var deleteLikeUrl = $$.data('delete');

            $$.on('click', 'a:not(.disabled)', function(e) {
                var $$ = $(this);
                e.preventDefault();

                var url = addLikeUrl;
                if ($$.hasClass('liked')) {
                    url = deleteLikeUrl;
                }

                $$.text('Liking...');

                $.ajax({
                    type: 'post',
                    data: {
                        id: id,
                        csrfmiddlewaretoken: token
                    },
                    url: url
                }).success(function(data) {
                    if (data !== 1) {
                        //already voted
                        return;
                    }
                    var vote = 1;

                    if ($$.hasClass('liked')) {
                        $$.removeClass('liked');
                        $$.text('liked');
                        vote = -1;
                    } else {
                        $$.addClass('liked');
                        $$.text('like');
                    }

                    var $votes = $('.quote[data-id='+ id +'] .votes').each(function() {
                        var $$ = $(this);
                        $$.text(parseInt($$.text(), 10) + vote);
                    });

                }).fail(function(data) {
                    $$.text('Error!!1').addClass('disabled');
                });
            });
        });

        if ($body.attr('id') === 'home') {
            vote.on('click', 'a.login.disabled', function(e) {
                e.preventDefault();
                $('.write-your-dixit').trigger('click');
                var $c = $('#right_column').addClass('mini');

                window.setTimeout(function() {
                    $c.on('mouseout mouseover', function() {
                        $(this).off().removeClass('mini');
                    });
                }, 200);
            });
        }
    }

    function setLogin() {
        var $form_signin = $('#form_signin');
        var $form_register = $('#form_register');

        $('.signup_list').on('click', 'a.login, a.register', function(e) {
            e.preventDefault();
            var $$ = $(this);

            if ($$.attr('class') === 'login') {
                $form_register.fadeOut('fast', function() {
                    $form_signin.fadeIn('fast');
                });
            } else {
                $form_signin.fadeOut('fast', function() {
                    $form_register.fadeIn('fast');
                });
            }
        });
    }

    function setNextPrev() {
        if ($body.attr('id') !== 'home') {
            return;
        }

        var $column = $('#right_column');
        var $wrapper = $column.find('.wrapper');
        var $prev = $column.find('.prev');
        var $next = $column.find('.next');

        var current = 0;
        var lastId = 0;
        var url = window.prevQuoteUrl;
        var quotes = $column.find('.wrapper .quote');

        if (quotes.length < 2) {
            $column.find('.prev_next a').addClass('disabled');
            return;
        } else {
            lastId = quotes.eq(quotes.length - 1).data('id');
        }

        $column.on('click', '.prev_next a:not(.disabled)', function(e) {
            e.preventDefault();

            var $$ = $(this);

            var ajaxPromise;

            if ($$.attr('class') === 'next') {
                current += 1;

                ajaxPromise = $.ajax({
                    url: url,
                    type: 'get',
                    data: {
                        id: lastId,
                        limit: 1
                    }
                }).success(function(data) {
                    var $li = $('<li />');
                    var $quote = $(data).appendTo($li);

                    lastId = $quote.data('id');
                    console.log(lastId);
                    $wrapper.append($li);
                }).fail(function() {
                    if (current >= $wrapper.find('li .quote').length - 1) {
                        $next.addClass('disabled');
                    }
                });

            } else {
                current -= 1;
                $next.removeClass('disabled');
            }

            $.when(ajaxPromise, $column.animate({
                scrollTop: $column.height() * current
            }, 500)).done(function() {
                if (current === 0) {
                    $prev.addClass('disabled');
                } else {
                    $prev.removeClass('disabled');
                }
            });
        });
    }

    function setMiddleColumn() {
        if ($body.attr('id') !== 'home') {
            return;
        }

        var $column = $('#middle_column');
        var $prev = $column.find('.prev');
        var $next = $column.find('.next');

        $('.write-your-dixit').on('click', function(e) {
            e.preventDefault();
            $next.trigger('click');
        });

        $('.about-the-project').on('click', function(e) {
            e.preventDefault();
            $prev.trigger('click');
        });

        $next.on('click', function(e) {
            e.preventDefault();
            $column.animate({
                scrollLeft: $column.width()
            }, 500, function() {
                $next.addClass('disabled');
                $prev.removeClass('disabled');
            });
        });

        $prev.on('click', function(e) {
            e.preventDefault();
            $column.animate({
                scrollLeft: 0
            }, 500, function() {
                $prev.addClass('disabled');
                $next.removeClass('disabled');
            });
        });
    }

    $(function() {
        $body = $('body');
        setLogin();
        setMiddleColumn();
        setNextPrev();
        setSharing();

        $('select').customSelect();
    });
})(jQuery, window, document);
<commit_msg>Keyboard navigation<commit_after>(function($, window, document) {
    var $body;

    function shareOnFacebook(url, title, text) {
        var data = {
            app_id: window.appId,
            link: url,
            name: title,
            description: text,
            method: 'feed'
        };

        FB.ui(data);
    }

    function share(type, url, description) {
        var data = {
            url: url,
            text: 'Check this quote!'
        };

        switch (type) {
            case 'share_fb':
                shareOnFacebook(url, data.text, description);
                return;
            case 'share_tw':
                url = 'https://twitter.com/intent/tweet?' + $.param(data);
            break;
            case 'share_gp':
                url = 'https://plus.google.com/share?' + $.param(data);
            break;
        }

        window.open(url, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');
    }

    function setSharing() {
        $('.share').each(function() {
            var $$ = $(this);
            var url = $$.data('url');
            var description = $$.data('description');

            $$.on('click', '.share_buttons a', function(e) {
                e.preventDefault();
                share($(this).attr('class'), url, description);
            });
        });

        var vote = $('.vote').each(function() {
            var $$ = $(this);

            var id = $$.data('id');
            var token = $$.find('[name=csrfmiddlewaretoken]').val();

            var addLikeUrl = $$.data('add');
            var deleteLikeUrl = $$.data('delete');

            $$.on('click', 'a:not(.disabled)', function(e) {
                var $$ = $(this);
                e.preventDefault();

                var url = addLikeUrl;
                if ($$.hasClass('liked')) {
                    url = deleteLikeUrl;
                }

                $$.text('Liking...');

                $.ajax({
                    type: 'post',
                    data: {
                        id: id,
                        csrfmiddlewaretoken: token
                    },
                    url: url
                }).success(function(data) {
                    var vote = 1;

                    if ($$.hasClass('liked')) {
                        $$.removeClass('liked');
                        $$.text('liked');
                        vote = -1;
                    } else {
                        $$.addClass('liked');
                        $$.text('like');
                    }

                    var $votes = $('.quote[data-id='+ id +'] .votes').each(function() {
                        var $$ = $(this);
                        $$.text(parseInt($$.text(), 10) + vote);
                    });

                }).fail(function(data) {
                    $$.text('Error!!1').addClass('disabled');
                });
            });
        });

        if ($body.attr('id') === 'home') {
            vote.on('click', 'a.login.disabled', function(e) {
                e.preventDefault();
                $('.write-your-dixit').trigger('click');
                var $c = $('#right_column').addClass('mini');

                window.setTimeout(function() {
                    $c.on('mouseout mouseover', function() {
                        $(this).off().removeClass('mini');
                    });
                }, 200);
            });
        }
    }

    function setLogin() {
        var $form_signin = $('#form_signin');
        var $form_register = $('#form_register');

        $('.signup_list').on('click', 'a.login, a.register', function(e) {
            e.preventDefault();
            var $$ = $(this);

            if ($$.attr('class') === 'login') {
                $form_register.fadeOut('fast', function() {
                    $form_signin.fadeIn('fast');
                });
            } else {
                $form_signin.fadeOut('fast', function() {
                    $form_register.fadeIn('fast');
                });
            }
        });
    }

    function setNextPrev() {
        if ($body.attr('id') !== 'home') {
            return;
        }

        var $column = $('#right_column');
        var $wrapper = $column.find('.wrapper');
        var $prev = $column.find('.prev');
        var $next = $column.find('.next');

        var current = 0;
        var lastId = 0;
        var url = window.prevQuoteUrl;
        var quotes = $column.find('.wrapper .quote');

        if (quotes.length < 2) {
            $column.find('.prev_next a').addClass('disabled');
            return;
        } else {
            lastId = quotes.eq(quotes.length - 1).data('id');
        }

        $column.on('click', '.prev_next a:not(.disabled)', function(e) {
            e.preventDefault();

            var $$ = $(this);

            var ajaxPromise;

            if ($$.attr('class') === 'next') {
                current += 1;

                ajaxPromise = $.ajax({
                    url: url,
                    type: 'get',
                    data: {
                        id: lastId,
                        limit: 1
                    }
                }).success(function(data) {
                    var $li = $('<li />');
                    var $quote = $(data).appendTo($li);

                    lastId = $quote.data('id');

                    $wrapper.append($li);
                }).fail(function() {
                    if (current >= $wrapper.find('li .quote').length - 1) {
                        $next.addClass('disabled');
                    }
                });

            } else {
                current -= 1;
                $next.removeClass('disabled');
            }

            $.when(ajaxPromise, $column.animate({
                scrollTop: $column.height() * current
            }, 500)).done(function() {
                if (current === 0) {
                    $prev.addClass('disabled');
                } else {
                    $prev.removeClass('disabled');
                }
            });
        });
    }

    function setMiddleColumn() {
        if ($body.attr('id') !== 'home') {
            return;
        }

        var $column = $('#middle_column');
        var $prev = $column.find('.prev');
        var $next = $column.find('.next');

        $('.write-your-dixit').on('click', function(e) {
            e.preventDefault();
            $next.trigger('click');
        });

        $('.about-the-project').on('click', function(e) {
            e.preventDefault();
            $prev.trigger('click');
        });

        $next.on('click', function(e) {
            e.preventDefault();
            $column.animate({
                scrollLeft: $column.width()
            }, 500, function() {
                $next.addClass('disabled');
                $prev.removeClass('disabled');
            });
        });

        $prev.on('click', function(e) {
            e.preventDefault();
            $column.animate({
                scrollLeft: 0
            }, 500, function() {
                $prev.addClass('disabled');
                $next.removeClass('disabled');
            });
        });
    }

    function setKeyboardNavigation() {
        if ($body.attr('id') !== 'home') {
            return;
        }

        var $left = $('#middle_column .prev');
        var $right = $('#middle_column .next');
        var $up = $('#right_column .prev');
        var $down = $('#right_column .next');

        $(document).on('keyup', function(e) {
            switch (e.keyCode) {
                case 37:
                    $left.trigger('click');
                break;
                case 38:
                    $up.trigger('click');
                break;
                case 39:
                    $right.trigger('click');
                break;
                case 40:
                    $down.trigger('click');
                break;
                default:
                return;
            }

            e.preventDefault();
        });
    }

    $(function() {
        $body = $('body');
        setLogin();
        setMiddleColumn();
        setNextPrev();
        setSharing();
        setKeyboardNavigation();

        $('select').customSelect();
    });
})(jQuery, window, document);
<|endoftext|>


<commit_before>"use strict";

var React       = require('react');
var Environment = require('./environment');
var matchRoutes   = require('./matchRoutes');

/**
 * A container component which captures <a> clicks and, if there's a matching
 * route defined, routes them.
 */
var CaptureClicks = React.createClass({
  displayName: 'CaptureClicks',

  propTypes: {
    component: React.PropTypes.func.isRequired,
    environment: React.PropTypes.object
  },

  getDefaultProps: function() {
    return {
      component: React.DOM.div,
      environment: Environment.defaultEnvironment
    }
  },

  onClick: function(event) {
    if (this.props.onClick) {
      this.props.onClick(event);
    }

    // Ignore canceled events, modified clicks, and right clicks.
    if (event.defaultPrevented) { return; }
    if (event.metaKey || event.ctrlKey || event.shiftKey) { return; }
    if (event.button !== 0) { return; }

    // Get the <a> element.
    var el = event.target;
    while (el && el.nodeName !== 'A') {
      el = el.parentNode;
    }

    // Ignore clicks from non-a elements.
    if (!el) { return; }

    // Ignore the click if the element has a target.
    if (el.target && el.target !== '_self') { return; }

    // Ignore links that don't share a protocol and host with ours.
    if (el.protocol !== location.protocol) { return; }
    if (el.host !== location.host) { return; }

    var pathname = el.pathname;
    if (el.pathname.charAt(0) !== '/') {
      // Make sure IE has a leading slash.
      pathname = '/' + pathname;
    }

    // Try to find a matching path in available routes.
    var environment = this.props.environment;
    var match = this.findMatch(pathname, environment);
    if (match) {
      event.preventDefault();

      // Route the request.
      environment.navigate(pathname, function(err) {
        if (err) {
          throw err;
        }
      });
    }
  },

  findMatch: function(path, environment) {
    var routers = environment.routers;
    var match, router;
    for (var i = 0; i < routers.length; i++) {
      var router = routers[i];
      match = matchRoutes(router.getRoutes(router.props), path);
      if (match && match.match) {
        // TODO: Recurse into child routers to handle match.unmatchedPath
        return match;
      }
    }
  },

  render: function() {
    var props = {
      onClick: this.onClick
    };
    return this.transferPropsTo(this.props.component(props, this.props.children));
  }

});

module.exports = CaptureClicks;
<commit_msg>Ignore download links<commit_after>"use strict";

var React       = require('react');
var Environment = require('./environment');
var matchRoutes   = require('./matchRoutes');

/**
 * A container component which captures <a> clicks and, if there's a matching
 * route defined, routes them.
 */
var CaptureClicks = React.createClass({
  displayName: 'CaptureClicks',

  propTypes: {
    component: React.PropTypes.func.isRequired,
    environment: React.PropTypes.object
  },

  getDefaultProps: function() {
    return {
      component: React.DOM.div,
      environment: Environment.defaultEnvironment
    }
  },

  onClick: function(event) {
    if (this.props.onClick) {
      this.props.onClick(event);
    }

    // Ignore canceled events, modified clicks, and right clicks.
    if (event.defaultPrevented) { return; }
    if (event.metaKey || event.ctrlKey || event.shiftKey) { return; }
    if (event.button !== 0) { return; }

    // Get the <a> element.
    var el = event.target;
    while (el && el.nodeName !== 'A') {
      el = el.parentNode;
    }

    // Ignore clicks from non-a elements.
    if (!el) { return; }

    // Ignore the click if the element has a target.
    if (el.target && el.target !== '_self') { return; }

    // Ignore the click if it's a download link. (We use this method of
    // detecting the precense of the attribute for old IE versions.)
    if (!!el.attributes.download) { return; }

    // Ignore links that don't share a protocol and host with ours.
    if (el.protocol !== location.protocol) { return; }
    if (el.host !== location.host) { return; }

    var pathname = el.pathname;
    if (el.pathname.charAt(0) !== '/') {
      // Make sure IE has a leading slash.
      pathname = '/' + pathname;
    }

    // Try to find a matching path in available routes.
    var environment = this.props.environment;
    var match = this.findMatch(pathname, environment);
    if (match) {
      event.preventDefault();

      // Route the request.
      environment.navigate(pathname, function(err) {
        if (err) {
          throw err;
        }
      });
    }
  },

  findMatch: function(path, environment) {
    var routers = environment.routers;
    var match, router;
    for (var i = 0; i < routers.length; i++) {
      var router = routers[i];
      match = matchRoutes(router.getRoutes(router.props), path);
      if (match && match.match) {
        // TODO: Recurse into child routers to handle match.unmatchedPath
        return match;
      }
    }
  },

  render: function() {
    var props = {
      onClick: this.onClick
    };
    return this.transferPropsTo(this.props.component(props, this.props.children));
  }

});

module.exports = CaptureClicks;
<|endoftext|>


<commit_before>var Botkit = require(__dirname + '/CoreBot.js');
var request = require('request');
var express = require('express');
var bodyParser = require('body-parser');
var url = require('url');
var crypto = require('crypto');

function Sparkbot(configuration) {

    // Create a core botkit bot
    var controller = Botkit(configuration || {});

    if (!controller.config.ciscospark_access_token) {
        throw new Error('ciscospark_access_token required to create controller');
    } else {
        controller.api = require('ciscospark').init({
            credentials: {
                authorization: {
                    access_token: controller.config.ciscospark_access_token
                }
            }
        });

        if (!controller.api) {
            throw new Error('Could not create Cisco Spark API');
        }

        controller.api.people.get('me').then(function(identity) {
            console.log('Cisco Spark: My identity is', identity);
            controller.identity = identity;
        }).catch(function(err) {
            throw new Error(err);
        });
    }

    if (!controller.config.public_address) {
        throw new Error('public_address parameter required to receive webhooks');
    } else {

        var endpoint = url.parse(controller.config.public_address);
        if (!endpoint.hostname) {
            throw new Error('Could not determine hostname of public address: ' + controller.config.public_address);
        } else if (endpoint.protocol != 'https:') {
            throw new Error('Please specify an SSL-enabled url for your public address: ' + controller.config.public_address);
        } else {
            controller.config.public_address = endpoint.hostname + (endpoint.port ? ':' + endpoint.port : '');
        }

    }

    if (!controller.config.secret) {
        console.log('WARNING: No secret specified. Source of incoming webhooks will not be validated. https://developer.ciscospark.com/webhooks-explained.html#auth');
        // throw new Error('secret parameter required to secure webhooks');
    }

    controller.resetWebhookSubscriptions = function() {
        controller.api.webhooks.list().then(function(list) {
            for (var i = 0; i < list.items.length; i++) {
                controller.api.webhooks.remove(list.items[i]).then(function(res) {
                    console.log('Removed subscription: ' + list.items[i].name);
                }).catch(function(err) {
                    console.log('Error removing subscription:', err);
                });
            }
        });
    };

    // set up a web route for receiving outgoing webhooks and/or slash commands
    controller.createWebhookEndpoints = function(webserver, bot, cb) {

        var webhook_name = controller.config.webhook_name || 'Botkit Firehose';

        controller.log(
            '** Serving webhook endpoints for Cisco Spark Platform at: ' +
            'http://' + controller.config.hostname + ':' + controller.config.port + '/ciscospark/receive');
        webserver.post('/ciscospark/receive', function(req, res) {
            res.sendStatus(200);
            controller.handleWebhookPayload(req, res, bot);

        });

        var list = controller.api.webhooks.list().then(function(list) {
            var hook_id = null;

            for (var i = 0; i < list.items.length; i++) {
                if (list.items[i].name == webhook_name) {
                    hook_id = list.items[i].id;
                }
            }

            var hook_url = 'https://' + controller.config.public_address + '/ciscospark/receive';

            console.log('Cisco Spark: incoming webhook url is ', hook_url);

            if (hook_id) {
                controller.api.webhooks.update({
                    id: hook_id,
                    resource: 'all',
                    targetUrl: hook_url,
                    event: 'all',
                    secret: controller.config.secret,
                    name: webhook_name,
                }).then(function(res) {
                    console.log('Cisco Spark: SUCCESSFULLY UPDATED CISCO SPARK WEBHOOKS');
                    if (cb) cb();
                }).catch(function(err) {
                    console.log('FAILED TO REGISTER WEBHOOK', err);
                    throw new Error(err);
                });

            } else {
                controller.api.webhooks.create({
                    resource: 'all',
                    targetUrl: hook_url,
                    event: 'all',
                    secret: controller.config.secret,
                    name: webhook_name,
                }).then(function(res) {

                    console.log('Cisco Spark: SUCCESSFULLY REGISTERED CISCO SPARK WEBHOOKS');
                    if (cb) cb();
                }).catch(function(err) {
                    console.log('FAILED TO REGISTER WEBHOOK', err);
                    throw new Error(err);
                });

            }
        });
    };

    controller.on('message_received', function(bot, message) {

        if (controller.config.limit_to_org) {
            console.log('limit to org', controller.config.limit_to_org,  message.original_message.orgId);
            if (!message.original_message.orgId || message.original_message.orgId != controller.config.limit_to_org) {
                // this message is from a user outside of the proscribed org
                return false;
            }
        }

        if (controller.config.limit_to_domain) {
            var domains = [];
            if (typeof(controller.config.limit_to_domain) == 'string') {
                domains = [controller.config.limit_to_domain];
            } else {
                domains = controller.config.limit_to_domain;
            }

            var allowed = false;
            for (var d = 0; d < domains.length; d++) {
                if (message.user.toLowerCase().indexOf(domains[d]) >= 0) {
                    allowed = true;
                }
            }

            if (!allowed) {
                // this message came from a domain that is outside of the allowed list.
                return false;
            }
        }

        if (message.user === controller.identity.emails[0]) {
            controller.trigger('self_message', [bot, message]);
            return false;
        } else if (message.original_message.roomType == 'direct') {
            controller.trigger('direct_message', [bot, message]);
            return false;
        } else {

            controller.trigger('direct_mention', [bot, message]);
            return false;
        }
    });

    controller.handleWebhookPayload = function(req, res, bot) {

        if (controller.config.secret) {
            var signature = req.headers['x-spark-signature'];
            var hash = crypto.createHmac('sha1', controller.config.secret).update(JSON.stringify(req.body)).digest('hex');

            if (signature != hash) {
                console.error('WARNING: Webhook received message with invalid signature. Potential malicious behavior!');
                return false;
            }
        }

        if (req.body.resource == 'messages' && req.body.event == 'created') {

            // console.log('RAW MESSAGE',req.body);
            controller.api.messages.get(req.body.data).then(function(message) {

                // console.log('DECRYPTED MESSAGE', message);
                // copy some fields from req.body that aren't in the new message
                message.orgId = req.body.orgId;

                var message = {
                    user: message.personEmail,
                    channel: message.roomId,
                    text: message.text,
                    id: message.id,
                    original_message: message,
                };

                // remove @mentions of the bot from the source text before we ingest it
                if (message.original_message.html) {

                    // strip the mention & HTML from the message
                    var pattern = new RegExp('^\<p\>\<spark\-mention .*?data\-object\-id\=\"' + controller.identity.id + '\".*\>.*?\<\/spark\-mention\>');
                    var action = message.original_message.html.replace(pattern, '');

                    // strip the remaining HTML tags
                    action = action.replace(/\<.*?\>/img, '');

                    // strip remaining whitespace
                    action = action.trim();

                    // replace the message text with the the HTML version
                    message.text = action;

                } else {
                    var pattern = new RegExp('^' + controller.identity.displayName + '\\s+', 'i');
                    if (message.text) {
                        message.text = message.text.replace(pattern, '');
                    }
                }
                controller.receiveMessage(bot, message);

            }).catch(function(err) {
                console.error('Could not get message', err);
            });
        } else {

            var event = req.body.resource + '.' + req.body.event;

            var message = {
                user: req.body.data.personEmail,
                channel: req.body.data.roomId,
                id: req.body.data.id,
                original_message: req.body,
                type: event,
            };

            switch (event) {
                case 'memberships.deleted':
                    if (message.user === controller.identity.emails[0]) {
                        controller.trigger('bot_space_leave', [bot, message]);
                    } else {
                        controller.trigger('user_space_leave', [bot, message]);
                    }
                    break;
                case 'memberships.created':
                    if (message.user === controller.identity.emails[0]) {
                        controller.trigger('bot_space_join', [bot, message]);
                    } else {
                        controller.trigger('user_space_join', [bot, message]);
                    }
                    break;
            }

            controller.trigger(event, [bot, message]);
        }
    };

    controller.setupWebserver = function(port, cb) {

        if (!port) {
            throw new Error('Cannot start webserver without a port');
        }

        var static_dir =  __dirname + '/public';

        if (controller.config && controller.config.webserver && controller.config.webserver.static_dir)
            static_dir = controller.config.webserver.static_dir;

        controller.config.port = port;

        controller.webserver = express();
        controller.webserver.use(bodyParser.json());
        controller.webserver.use(bodyParser.urlencoded({ extended: true }));
        controller.webserver.use(express.static(static_dir));

        var server = controller.webserver.listen(
            controller.config.port,
            controller.config.hostname,
            function() {
                controller.log('** Starting webserver on port ' +
                    controller.config.port);
                if (cb) { cb(null, controller.webserver); }
            });

        return controller;

    };

    // customize the bot definition, which will be used when new connections
    // spawn!
    controller.defineBot(function(botkit, config) {

        var bot = {
            type: 'ciscospark',
            botkit: botkit,
            config: config || {},
            utterances: botkit.utterances,
        };

        bot.startConversation = function(message, cb) {
            botkit.startConversation(this, message, cb);
        };

        bot.createConversation = function(message, cb) {
            botkit.createConversation(this, message, cb);
        };

        /**
         * Convenience method for creating a DM convo.
         */
        bot.startPrivateConversation = function(message, cb) {

            var message_options = {};

            message_options.toPersonEmail = message.user;

            botkit.startTask(bot, message_options, function(task, convo) {
                convo.on('sent', function(sent_message) {
                    // update this convo so that future messages will match
                    // since the source message did not have this info in it.
                    convo.source_message.user = message.user;
                    convo.source_message.channel = sent_message.roomId;
                });
                cb(null, convo);
            });
        };

        /**
         * Convenience method for creating a DM based on a personId instead of email
         */
        bot.startPrivateConversationWithPersonId = function(personId, cb) {

            var message_options = {};

            message_options.toPersonId = personId;

            botkit.startTask(bot, message_options, function(task, convo) {
                convo.on('sent', function(sent_message) {
                    // update this convo so that future messages will match
                    // since the source message did not have this info in it.
                    convo.source_message.user = message.user;
                    convo.source_message.channel = sent_message.roomId;
                });
                cb(null, convo);
            });
        };

        /**
         * Convenience method for creating a DM convo with the `actor`, not the sender
         * this applies to events like channel joins, where the actor may be the user who sent the invite
         */
        bot.startPrivateConversationWithActor = function(message, cb) {
            bot.startPrivateConversationWithPersonId(message.original_message.actorId, cb);
        };

        bot.send = function(message, cb) {

            // clone the incoming message
            var ciscospark_message = {};
            for (var k in message) {
                ciscospark_message[k] = message[k];
            }

            // mutate the message into proper spark format
            ciscospark_message.roomId = message.channel;
            delete ciscospark_message.channel;

            // default the markdown field to be the same as tex.
            if (ciscospark_message.text && !ciscospark_message.markdown) {
                ciscospark_message.markdown = ciscospark_message.text;
            }

            controller.api.messages.create(ciscospark_message).then(function(message) {
                if (cb) cb(null, message);
            }).catch(function(err) {
                if (cb) cb(err);
            });

        };

        bot.reply = function(src, resp, cb) {
            var msg = {};

            if (typeof(resp) == 'string') {
                msg.text = resp;
            } else {
                msg = resp;
            }

            if (src.channel) {
                msg.channel = src.channel;
            } else if (src.toPersonEmail) {
                msg.toPersonEmail = src.toPersonEmail;
            } else if (src.toPersonId) {
                msg.toPersonId = src.toPersonId;
            }

            bot.say(msg, cb);
        };

        bot.findConversation = function(message, cb) {
            botkit.debug('CUSTOM FIND CONVO', message.user, message.channel);
            for (var t = 0; t < botkit.tasks.length; t++) {
                for (var c = 0; c < botkit.tasks[t].convos.length; c++) {
                    if (
                        botkit.tasks[t].convos[c].isActive() &&
                        botkit.tasks[t].convos[c].source_message.user == message.user &&
                        botkit.tasks[t].convos[c].source_message.channel == message.channel
                    ) {
                        botkit.debug('FOUND EXISTING CONVO!');
                        cb(botkit.tasks[t].convos[c]);
                        return;
                    }
                }
            }

            cb();
        };

        bot.retrieveFileInfo = function(url, cb) {
            request.head({
                url: url,
                headers: {
                    'Authorization': 'Bearer ' + controller.config.ciscospark_access_token
                },
            }, function(err, response, body) {

                if (!err) {
                    var obj = response.headers;
                    if (obj['content-disposition']) {
                        obj.filename = obj['content-disposition'].replace(/.*filename=\"(.*)\".*/gi, '$1');
                    }
                    cb(null, obj);
                } else {
                    cb(err);
                }

            });
        };

        bot.retrieveFile = function(url, cb) {

            request({
                url: url,
                headers: {
                    'Authorization': 'Bearer ' + controller.config.ciscospark_access_token
                },
                encoding: 'binary',
            }, function(err, response, body) {

                cb(err, body);

            });

        };

        return bot;

    });

    controller.startTicking();

    return controller;

}

module.exports = Sparkbot;
<commit_msg>CiscoSpark version : inform when message come from not authorized domain or org Useful for debug<commit_after>var Botkit = require(__dirname + '/CoreBot.js');
var request = require('request');
var express = require('express');
var bodyParser = require('body-parser');
var url = require('url');
var crypto = require('crypto');

function Sparkbot(configuration) {

    // Create a core botkit bot
    var controller = Botkit(configuration || {});

    if (!controller.config.ciscospark_access_token) {
        throw new Error('ciscospark_access_token required to create controller');
    } else {
        controller.api = require('ciscospark').init({
            credentials: {
                authorization: {
                    access_token: controller.config.ciscospark_access_token
                }
            }
        });

        if (!controller.api) {
            throw new Error('Could not create Cisco Spark API');
        }

        controller.api.people.get('me').then(function(identity) {
            console.log('Cisco Spark: My identity is', identity);
            controller.identity = identity;
        }).catch(function(err) {
            throw new Error(err);
        });
    }

    if (!controller.config.public_address) {
        throw new Error('public_address parameter required to receive webhooks');
    } else {

        var endpoint = url.parse(controller.config.public_address);
        if (!endpoint.hostname) {
            throw new Error('Could not determine hostname of public address: ' + controller.config.public_address);
        } else if (endpoint.protocol != 'https:') {
            throw new Error('Please specify an SSL-enabled url for your public address: ' + controller.config.public_address);
        } else {
            controller.config.public_address = endpoint.hostname + (endpoint.port ? ':' + endpoint.port : '');
        }

    }

    if (!controller.config.secret) {
        console.log('WARNING: No secret specified. Source of incoming webhooks will not be validated. https://developer.ciscospark.com/webhooks-explained.html#auth');
        // throw new Error('secret parameter required to secure webhooks');
    }

    controller.resetWebhookSubscriptions = function() {
        controller.api.webhooks.list().then(function(list) {
            for (var i = 0; i < list.items.length; i++) {
                controller.api.webhooks.remove(list.items[i]).then(function(res) {
                    console.log('Removed subscription: ' + list.items[i].name);
                }).catch(function(err) {
                    console.log('Error removing subscription:', err);
                });
            }
        });
    };

    // set up a web route for receiving outgoing webhooks and/or slash commands
    controller.createWebhookEndpoints = function(webserver, bot, cb) {

        var webhook_name = controller.config.webhook_name || 'Botkit Firehose';

        controller.log(
            '** Serving webhook endpoints for Cisco Spark Platform at: ' +
            'http://' + controller.config.hostname + ':' + controller.config.port + '/ciscospark/receive');
        webserver.post('/ciscospark/receive', function(req, res) {
            res.sendStatus(200);
            controller.handleWebhookPayload(req, res, bot);

        });

        var list = controller.api.webhooks.list().then(function(list) {
            var hook_id = null;

            for (var i = 0; i < list.items.length; i++) {
                if (list.items[i].name == webhook_name) {
                    hook_id = list.items[i].id;
                }
            }

            var hook_url = 'https://' + controller.config.public_address + '/ciscospark/receive';

            console.log('Cisco Spark: incoming webhook url is ', hook_url);

            if (hook_id) {
                controller.api.webhooks.update({
                    id: hook_id,
                    resource: 'all',
                    targetUrl: hook_url,
                    event: 'all',
                    secret: controller.config.secret,
                    name: webhook_name,
                }).then(function(res) {
                    console.log('Cisco Spark: SUCCESSFULLY UPDATED CISCO SPARK WEBHOOKS');
                    if (cb) cb();
                }).catch(function(err) {
                    console.log('FAILED TO REGISTER WEBHOOK', err);
                    throw new Error(err);
                });

            } else {
                controller.api.webhooks.create({
                    resource: 'all',
                    targetUrl: hook_url,
                    event: 'all',
                    secret: controller.config.secret,
                    name: webhook_name,
                }).then(function(res) {

                    console.log('Cisco Spark: SUCCESSFULLY REGISTERED CISCO SPARK WEBHOOKS');
                    if (cb) cb();
                }).catch(function(err) {
                    console.log('FAILED TO REGISTER WEBHOOK', err);
                    throw new Error(err);
                });

            }
        });
    };

    controller.on('message_received', function(bot, message) {

        if (controller.config.limit_to_org) {
            console.log('limit to org', controller.config.limit_to_org,  message.original_message.orgId);
            if (!message.original_message.orgId || message.original_message.orgId != controller.config.limit_to_org) {
                // this message is from a user outside of the proscribed org
                console.log('WARNING: this message is from a user outside of the proscribed org', controller.config.limit_to_org);
                return false;
            }
        }

        if (controller.config.limit_to_domain) {
            var domains = [];
            if (typeof(controller.config.limit_to_domain) == 'string') {
                domains = [controller.config.limit_to_domain];
            } else {
                domains = controller.config.limit_to_domain;
            }

            var allowed = false;
            for (var d = 0; d < domains.length; d++) {
                if (message.user.toLowerCase().indexOf(domains[d]) >= 0) {
                    allowed = true;
                }
            }

            if (!allowed) {
                console.log('WARNING: this message came from a domain that is outside of the allowed list', controller.config.limit_to_domain);
                // this message came from a domain that is outside of the allowed list.
                return false;
            }
        }

        if (message.user === controller.identity.emails[0]) {
            controller.trigger('self_message', [bot, message]);
            return false;
        } else if (message.original_message.roomType == 'direct') {
            controller.trigger('direct_message', [bot, message]);
            return false;
        } else {

            controller.trigger('direct_mention', [bot, message]);
            return false;
        }
    });

    controller.handleWebhookPayload = function(req, res, bot) {

        if (controller.config.secret) {
            var signature = req.headers['x-spark-signature'];
            var hash = crypto.createHmac('sha1', controller.config.secret).update(JSON.stringify(req.body)).digest('hex');

            if (signature != hash) {
                console.error('WARNING: Webhook received message with invalid signature. Potential malicious behavior!');
                return false;
            }
        }

        if (req.body.resource == 'messages' && req.body.event == 'created') {

            // console.log('RAW MESSAGE',req.body);
            controller.api.messages.get(req.body.data).then(function(message) {

                // console.log('DECRYPTED MESSAGE', message);
                // copy some fields from req.body that aren't in the new message
                message.orgId = req.body.orgId;

                var message = {
                    user: message.personEmail,
                    channel: message.roomId,
                    text: message.text,
                    id: message.id,
                    original_message: message,
                };

                // remove @mentions of the bot from the source text before we ingest it
                if (message.original_message.html) {

                    // strip the mention & HTML from the message
                    var pattern = new RegExp('^\<p\>\<spark\-mention .*?data\-object\-id\=\"' + controller.identity.id + '\".*\>.*?\<\/spark\-mention\>');
                    var action = message.original_message.html.replace(pattern, '');

                    // strip the remaining HTML tags
                    action = action.replace(/\<.*?\>/img, '');

                    // strip remaining whitespace
                    action = action.trim();

                    // replace the message text with the the HTML version
                    message.text = action;

                } else {
                    var pattern = new RegExp('^' + controller.identity.displayName + '\\s+', 'i');
                    if (message.text) {
                        message.text = message.text.replace(pattern, '');
                    }
                }
                controller.receiveMessage(bot, message);

            }).catch(function(err) {
                console.error('Could not get message', err);
            });
        } else {

            var event = req.body.resource + '.' + req.body.event;

            var message = {
                user: req.body.data.personEmail,
                channel: req.body.data.roomId,
                id: req.body.data.id,
                original_message: req.body,
                type: event,
            };

            switch (event) {
                case 'memberships.deleted':
                    if (message.user === controller.identity.emails[0]) {
                        controller.trigger('bot_space_leave', [bot, message]);
                    } else {
                        controller.trigger('user_space_leave', [bot, message]);
                    }
                    break;
                case 'memberships.created':
                    if (message.user === controller.identity.emails[0]) {
                        controller.trigger('bot_space_join', [bot, message]);
                    } else {
                        controller.trigger('user_space_join', [bot, message]);
                    }
                    break;
            }

            controller.trigger(event, [bot, message]);
        }
    };

    controller.setupWebserver = function(port, cb) {

        if (!port) {
            throw new Error('Cannot start webserver without a port');
        }

        var static_dir =  __dirname + '/public';

        if (controller.config && controller.config.webserver && controller.config.webserver.static_dir)
            static_dir = controller.config.webserver.static_dir;

        controller.config.port = port;

        controller.webserver = express();
        controller.webserver.use(bodyParser.json());
        controller.webserver.use(bodyParser.urlencoded({ extended: true }));
        controller.webserver.use(express.static(static_dir));

        var server = controller.webserver.listen(
            controller.config.port,
            controller.config.hostname,
            function() {
                controller.log('** Starting webserver on port ' +
                    controller.config.port);
                if (cb) { cb(null, controller.webserver); }
            });

        return controller;

    };

    // customize the bot definition, which will be used when new connections
    // spawn!
    controller.defineBot(function(botkit, config) {

        var bot = {
            type: 'ciscospark',
            botkit: botkit,
            config: config || {},
            utterances: botkit.utterances,
        };

        bot.startConversation = function(message, cb) {
            botkit.startConversation(this, message, cb);
        };

        bot.createConversation = function(message, cb) {
            botkit.createConversation(this, message, cb);
        };

        /**
         * Convenience method for creating a DM convo.
         */
        bot.startPrivateConversation = function(message, cb) {

            var message_options = {};

            message_options.toPersonEmail = message.user;

            botkit.startTask(bot, message_options, function(task, convo) {
                convo.on('sent', function(sent_message) {
                    // update this convo so that future messages will match
                    // since the source message did not have this info in it.
                    convo.source_message.user = message.user;
                    convo.source_message.channel = sent_message.roomId;
                });
                cb(null, convo);
            });
        };

        /**
         * Convenience method for creating a DM based on a personId instead of email
         */
        bot.startPrivateConversationWithPersonId = function(personId, cb) {

            var message_options = {};

            message_options.toPersonId = personId;

            botkit.startTask(bot, message_options, function(task, convo) {
                convo.on('sent', function(sent_message) {
                    // update this convo so that future messages will match
                    // since the source message did not have this info in it.
                    convo.source_message.user = message.user;
                    convo.source_message.channel = sent_message.roomId;
                });
                cb(null, convo);
            });
        };

        /**
         * Convenience method for creating a DM convo with the `actor`, not the sender
         * this applies to events like channel joins, where the actor may be the user who sent the invite
         */
        bot.startPrivateConversationWithActor = function(message, cb) {
            bot.startPrivateConversationWithPersonId(message.original_message.actorId, cb);
        };

        bot.send = function(message, cb) {

            // clone the incoming message
            var ciscospark_message = {};
            for (var k in message) {
                ciscospark_message[k] = message[k];
            }

            // mutate the message into proper spark format
            ciscospark_message.roomId = message.channel;
            delete ciscospark_message.channel;

            // default the markdown field to be the same as tex.
            if (ciscospark_message.text && !ciscospark_message.markdown) {
                ciscospark_message.markdown = ciscospark_message.text;
            }

            controller.api.messages.create(ciscospark_message).then(function(message) {
                if (cb) cb(null, message);
            }).catch(function(err) {
                if (cb) cb(err);
            });

        };

        bot.reply = function(src, resp, cb) {
            var msg = {};

            if (typeof(resp) == 'string') {
                msg.text = resp;
            } else {
                msg = resp;
            }

            if (src.channel) {
                msg.channel = src.channel;
            } else if (src.toPersonEmail) {
                msg.toPersonEmail = src.toPersonEmail;
            } else if (src.toPersonId) {
                msg.toPersonId = src.toPersonId;
            }

            bot.say(msg, cb);
        };

        bot.findConversation = function(message, cb) {
            botkit.debug('CUSTOM FIND CONVO', message.user, message.channel);
            for (var t = 0; t < botkit.tasks.length; t++) {
                for (var c = 0; c < botkit.tasks[t].convos.length; c++) {
                    if (
                        botkit.tasks[t].convos[c].isActive() &&
                        botkit.tasks[t].convos[c].source_message.user == message.user &&
                        botkit.tasks[t].convos[c].source_message.channel == message.channel
                    ) {
                        botkit.debug('FOUND EXISTING CONVO!');
                        cb(botkit.tasks[t].convos[c]);
                        return;
                    }
                }
            }

            cb();
        };

        bot.retrieveFileInfo = function(url, cb) {
            request.head({
                url: url,
                headers: {
                    'Authorization': 'Bearer ' + controller.config.ciscospark_access_token
                },
            }, function(err, response, body) {

                if (!err) {
                    var obj = response.headers;
                    if (obj['content-disposition']) {
                        obj.filename = obj['content-disposition'].replace(/.*filename=\"(.*)\".*/gi, '$1');
                    }
                    cb(null, obj);
                } else {
                    cb(err);
                }

            });
        };

        bot.retrieveFile = function(url, cb) {

            request({
                url: url,
                headers: {
                    'Authorization': 'Bearer ' + controller.config.ciscospark_access_token
                },
                encoding: 'binary',
            }, function(err, response, body) {

                cb(err, body);

            });

        };

        return bot;

    });

    controller.startTicking();

    return controller;

}

module.exports = Sparkbot;
<|endoftext|>


<commit_before>require.config({
    baseUrl: '/jivox/assets/js/lib/',
	shim : {
        "jquery.form" 		 : { "deps" :['jquery'] },
		"notify" 			 : { "deps" :['jquery'] },
		"jquery-ui" 		 : { "deps" :['jquery'] },
		"idle-timer" 		 : { "deps" :['jquery'] },
		"jquery-editable" 	 : { "deps" :['jquery','jquery-ui'] },
		"datatables" 		 : { "deps" :['jquery'] },
		"sumoselect" 		 : { "deps" :['jquery'] },
		"Chart.HorizontalBar": { "deps" :['Chart.min'] }
    },
    paths: {
		"app"				: "../app",
        "jquery"    		: "jquery.min",
		"datatables"		: "jquery.dataTables",
		"sumoselect"		: "jquery.sumoselect.min"
    }
})

if (typeof r !== "undefined"){require(r)}
<commit_msg>Update main.js<commit_after>require.config({
    baseUrl: '/jivox/assets/js/lib/',
	shim : {
        "jquery.form" 		 : { "deps" :['jquery'] },
		"notify" 			 : { "deps" :['jquery'] },
		"jquery-ui" 		 : { "deps" :['jquery'] }
    },
    paths: {
		"app"				: "../app",
        "jquery"    		: "jquery.min"
    }
})

if (typeof r !== "undefined"){require(r)}
<|endoftext|>


<commit_before>$(function () {
    'use strict'; // Start of use strict

    var main_container = $('#main-container');
    var cannon = $('.cannon');
    var canvas = document.getElementById('main-container');

    // Reposition cannon to bottom left of screen (there must be a better way?)
    cannon.css({'position': 'absolute',
                        'left': '0px',
                        'top': canvas.scrollHeight + 300 + 'px'});

    var center_x    = 0;
    var center_y    = 0;
    var v_0         = 150;  // arbitrary initial velocity
    var theta       = 100;  // radians
    var degrees     = 0;
    var gravity     = 9.81;

    //TODO: Bugs everywhere. Fix glitchy animation (Matt).
    function fire_cannon(fire_event) {
        main_container.append('

');
        var time = 0;
        var cannon_ball = $('.cannon-ball');
        var v_x0 = v_0 * Math.cos(theta*-1); //Should theta have to be negated here?
        var v_y0 = v_0 * Math.sin(theta*-1); //Or here?

        // cannon_ball.offset({top: cannon_y, left: cannon_x});
        cannon_ball.css({ fontSize: 0 }).animate({
            fontSize: 45
        },{
            duration: 5000,
            easing: "swing",
            step: function(t, fx){
                time = time + .10;
                var x = (v_x0*time)
                var y = (((v_y0*time)) - (.5*gravity*(time*time)) );
                console.log(x + ' ' + y);
                $(this).css({ left: x, top: 1000 - y });
            }
        });
        cannon_ball.clearQueue();   // This needs to be called somewhere else to clear the animation queue
                                    // (Maybe detect ball collision with edge of screen, then clear queue?
        main_container.remove('.cannon-ball');
    }

    function get_mouse_coordinates(event) {
        var canvas = document.getElementById("main-container");
        var rectangle = canvas.getBoundingClientRect();
        return {
            x: event.clientX - rectangle.left,
            y: event.clientY - rectangle.top
        };
    }

    // theta should be in radians
    function calculate_velocities(radians) {
        return {
            v_x0: v_0*Math.cos(radians),
            v_y0: v_0*Math.sin(radians)
        };
    }

    // returns theta in radians
    function calculate_theta(event) {
        var cannon_offset   = cannon.offset();
        center_x        = (cannon_offset.left) + (cannon.width() / 2);
        center_y        = (cannon_offset.top) + (cannon.height() / 2);
        var event_x         = event.pageX;
        var event_y         = event.pageY;
        return Math.atan2( event_y - center_y, event_x - center_x );
    }

    function rotate_cannon(degrees) {
        cannon.css('-moz-transform', 'rotate(' + degrees + 'deg)');
        cannon.css('-webkit-transform', 'rotate(' + degrees + 'deg)');
        cannon.css('-o-transform', 'rotate(' + degrees + 'deg)');
        cannon.css('-ms-transform', 'rotate(' + degrees + 'deg)');
    }

    function mousemoved(event) {
        var radians = calculate_theta(event);
        var degree = (radians * (180 / Math.PI));
        degrees = degree;
        rotate_cannon(degree);
        theta = radians;
        var pageCoords = event.pageX + ', ' + event.pageY;
        var clientCoords = event.clientX + ', ' + event.clientY;
        $('#coords').text('( pageX, pageY ) : ' + pageCoords
            + ' ( clientX, clientY ) : ' + clientCoords);
    }

    // only moves the box when the mouse is held down
    $('html').mousedown(function () {
        $(document).mousemove(mousemoved);
    }).mouseup(function () {
        $(document).unbind();
    });

    document.addEventListener('mouseup', fire_cannon );
    $.mobile.loading().hide();
}); // end of document ready
<commit_msg>Remove unused functions<commit_after>$(function () {
    'use strict'; // Start of use strict

    var main_container = $('#main-container');
    var cannon = $('.cannon');
    var canvas = document.getElementById('main-container');

    // Reposition cannon to bottom left of screen (there must be a better way?)
    cannon.css({'position': 'absolute',
                        'left': '0px',
                        'top': canvas.scrollHeight + 300 + 'px'});

    var center_x    = 0;
    var center_y    = 0;
    var v_0         = 150;  // arbitrary initial velocity
    var theta       = 100;  // radians
    var degrees     = 0;
    var gravity     = 9.81;

    //TODO: Bugs everywhere. Fix glitchy animation (Matt).
    function fire_cannon(fire_event) {
        main_container.append('

');
        var time = 0;
        var cannon_ball = $('.cannon-ball');
        var v_x0 = v_0 * Math.cos(theta*-1); //Should theta have to be negated here?
        var v_y0 = v_0 * Math.sin(theta*-1); //Or here?

        cannon_ball.css({ fontSize: 0 }).animate({
            fontSize: 45
        },{
            duration: 5000,
            easing: "swing",
            step: function(t, fx){
                time = time + .10;
                var x = (v_x0*time)
                var y = (((v_y0*time)) - (.5*gravity*(time*time)) );
                console.log(x + ' ' + y);
                $(this).css({ left: x, top: 1000 - y });
            }
        });
        cannon_ball.clearQueue();   // This needs to be called somewhere else to clear the animation queue
                                    // (Maybe detect ball collision with edge of screen, then clear queue?
        main_container.remove('.cannon-ball');
    }

    // returns theta in radians
    function calculate_theta(event) {
        var cannon_offset   = cannon.offset();
        center_x        = (cannon_offset.left) + (cannon.width() / 2);
        center_y        = (cannon_offset.top) + (cannon.height() / 2);
        var event_x         = event.pageX;
        var event_y         = event.pageY;
        return Math.atan2( event_y - center_y, event_x - center_x );
    }

    function rotate_cannon(degrees) {
        cannon.css('-moz-transform', 'rotate(' + degrees + 'deg)');
        cannon.css('-webkit-transform', 'rotate(' + degrees + 'deg)');
        cannon.css('-o-transform', 'rotate(' + degrees + 'deg)');
        cannon.css('-ms-transform', 'rotate(' + degrees + 'deg)');
    }

    function mousemoved(event) {
        var radians = calculate_theta(event);
        var degree = (radians * (180 / Math.PI));
        degrees = degree;
        rotate_cannon(degree);
        theta = radians;
        var pageCoords = event.pageX + ', ' + event.pageY;
        var clientCoords = event.clientX + ', ' + event.clientY;
        $('#coords').text('( pageX, pageY ) : ' + pageCoords
            + ' ( clientX, clientY ) : ' + clientCoords);
    }

    // only moves the box when the mouse is held down
    $('html').mousedown(function () {
        $(document).mousemove(mousemoved);
    }).mouseup(function () {
        $(document).unbind();
    });

    document.addEventListener('mouseup', fire_cannon );
    $.mobile.loading().hide();
}); // end of document ready
<|endoftext|>