<commit_before>//-------------------------------------------------------------------------------
// Copyright IBM Corp. 2015
//
// Licensed under the Apache License, Version 2.0 (the 'License');
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-------------------------------------------------------------------------------

'use strict';

var request = require('request');
var _ = require('lodash');
var async = require('async');
var pipesSDK = require.main.require('simple-data-pipe-sdk');
var connectorExt = pipesSDK.connectorExt;
var bluemixHelperConfig = require.main.require('bluemix-helper-config');
var configManager = bluemixHelperConfig.configManager;
var vcapServices = bluemixHelperConfig.vcapServices;
var util = require('util');

var concurrency = 20;	//Async queue concurrency
/**
 * Pipes Connector for Reddit
 */
function redditConnector( parentDirPath ){

	//Call constructor from super class
	connectorExt.call(this, 'reddit', 'Reddit AMA', {
		extraRequiredFields: 'amaURL',
		useOAuth: false,
		useCustomTables: true
	});

	this.getTablePrefix = function(){
		return 'reddit';
	}

	this.getCloudantDbName = function(pipe, table){
		return pipe.name + '_' + table.name;
	}

	var watsonToneAnalyzerService = vcapServices.getService( configManager.get('WATSON_TONE_ANALYZER') || 'tone analyzer' );

	this.fetchRecords = function( table, pushRecordFn, done, pipeRunStep, pipeRunStats, logger, pipe, pipeRunner ){

		// TODO set log level
		logger.level('info');

		if ( !watsonToneAnalyzerService ){
			var msg = 'Unable to find Watson Tone Analyzer Service';
			logger.error( msg );
			return done( msg );
		}

		if (( !pipe.amaURL ) || (pipe.amaURL.length < 1)){
			return done('Missing or empty field amaURL');
		}

		var amaJsonURL = '';
		// append json suffix to amaURL
		// input: https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us.json or
		//        https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us or
		//        https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us/
		// output https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us.json

        if(pipe.amaURL.match(/\.json$/)) {
        	amaJsonURL = pipe.amaURL;
        }
        else {
			if(pipe.amaURL.charAt(pipe.amaURL.length-1) == '/') {
				amaJsonURL = pipe.amaURL.replace(/\/+$/,'.json');
			}
			else {
				amaJsonURL = pipe.amaURL + '.json';
			}
		}

		logger.info('Connecting to AMA with url ' + amaJsonURL);

		request.get(amaJsonURL, {'json': true},
			function( err, response, body ){
				if ( err ){
					logger.error('Unable to fetch AMA: ' + err );
					return done( err );
				}

				logger.debug('Reddit API response: ' + response);

				// Create an async queue to process the record with Watson Tone Analyzer
				var q = async.queue( function( post, callback ){

					logger.debug(util.inspect(post));

					var msg = '';

					// Call Tone analyzer to get sentiments from the post
					// https://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/tone-analyzer/output.shtml
					request.post( watsonToneAnalyzerService.credentials.url + '/v3/tone?version=2016-02-11',{
						'auth': {
						  'user': watsonToneAnalyzerService.credentials.username,
						  'pass': watsonToneAnalyzerService.credentials.password,
						  'sendImmediately': true
						},
						'json': {
							'text': post.selftext || post.body
						}
					}, function( err, response, body ){

						if ( err ){
							msg = 'Error querying Watson Tone Analyzer service: ' + err;
							logger.error(msg);
							return callback( msg );
						}

						logger.debug('WTA response: ' + util.inspect(response));
						logger.debug('WTA body: ' + util.inspect(body));

						if(response.statusCode >= 300) {
							msg = 'Call to Watson Tone Analyzer URL ' + response.request.uri.href + ' returned status ' + response.statusCode + ' (' + response.body.error + ')';
							logger.error(msg);
							return callback(msg);
						}

						var sentiments = {
											author: post.author,
											created: post.created_utc,
											edited: post.edited,
											id: post.id,
											num_comments: post.num_comments,
											title: post.title || '',
											text: post.selftext || post.body
                                         };

                        if(body.document_tone) {

                        	/*

                        	Tone Analyzer API v3 output

							{
							    document_tone: {

												tone_categories: [
																  	{
																  	  tones: [ [Object], [Object], [Object], [Object], [Object] ],
																  	  category_id: 'emotion_tone',
																      category_name: 'Emotion Tone'
																    },
																    {
																      tones: [ [Object], [Object], [Object] ],
																      category_id: 'writing_tone',
																      category_name: 'Writing Tone'
																    },
																    {
																      tones: [ [Object], [Object], [Object], [Object], [Object] ],
																      category_id: 'social_tone',
																      category_name: 'Social Tone'
																    }
															      ]
										        },
							    sentences_tone: ...

							}

                        	*/

							logger.debug('Document tone categories: ' + util.inspect(body.document_tone.tone_categories));

							_.forEach(body.document_tone.tone_categories, function(tone_category) {
								sentiments[tone_category.category_id] = {
									                                      category_name : tone_category.category_name,
									                                      tones: tone_category.tones
									                                    };
							});

                        	// save in Cloudant
                            pushRecordFn(sentiments);

                        }
                        else {
                        	// No tone analyzer results were returned
                        	// Don't store post in Cloudant
                        	logger.warn('No Tone Analyzer results were returned for ' + sentiments.title + '.');
                        }

   						return callback();

                    }); // post
				}, concurrency ); // async

				_.forEach( body, function( listing ){
					if ( listing.kind == 'Listing' && listing.hasOwnProperty('data' ) ){
						if ( listing.data.hasOwnProperty('children') ){
							//Get the children from the data fields, only process the top posts for now
							_.forEach( listing.data.children, function( post ){
								if ( post.hasOwnProperty('data') ){
									// add post to queue only if it contains text
									if((post.data.hasOwnProperty('selftext')) || (post.data.hasOwnProperty('body'))) {
										q.push( post.data );
									}
								}
							});
						}
					}
				});

				// Drain function is invoked after all posts have been processed
				q.drain = function(){
					// pipe processing complete
					return done();
				}

				// if the queue is empty asynchronous processing has already completed (or there was nothing to process)
				if(q.idle()) {
					return done();
				}

			}
		);
	};
}

//Extend event Emitter
require('util').inherits(redditConnector, connectorExt);

module.exports = new redditConnector();
<commit_msg>add normalized score<commit_after>//-------------------------------------------------------------------------------
// Copyright IBM Corp. 2015
//
// Licensed under the Apache License, Version 2.0 (the 'License');
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//-------------------------------------------------------------------------------

'use strict';

var request = require('request');
var _ = require('lodash');
var async = require('async');
var pipesSDK = require.main.require('simple-data-pipe-sdk');
var connectorExt = pipesSDK.connectorExt;
var bluemixHelperConfig = require.main.require('bluemix-helper-config');
var configManager = bluemixHelperConfig.configManager;
var vcapServices = bluemixHelperConfig.vcapServices;
var util = require('util');

var concurrency = 20;	//Async queue concurrency
/**
 * Pipes Connector for Reddit
 */
function redditConnector( parentDirPath ){

	//Call constructor from super class
	connectorExt.call(this, 'reddit', 'Reddit AMA', {
		extraRequiredFields: 'amaURL',
		useOAuth: false,
		useCustomTables: true
	});

	this.getTablePrefix = function(){
		return 'reddit';
	}

	this.getCloudantDbName = function(pipe, table){
		return pipe.name + '_' + table.name;
	}

	var watsonToneAnalyzerService = vcapServices.getService( configManager.get('WATSON_TONE_ANALYZER') || 'tone analyzer' );

	this.fetchRecords = function( table, pushRecordFn, done, pipeRunStep, pipeRunStats, logger, pipe, pipeRunner ){

		// TODO set log level
		logger.level('info');

		if ( !watsonToneAnalyzerService ){
			var msg = 'Unable to find Watson Tone Analyzer Service';
			logger.error( msg );
			return done( msg );
		}

		if (( !pipe.amaURL ) || (pipe.amaURL.length < 1)){
			return done('Missing or empty field amaURL');
		}

		var amaJsonURL = '';
		// append json suffix to amaURL
		// input: https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us.json or
		//        https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us or
		//        https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us/
		// output https://www.reddit.com/r/IAmA/comments/3ilzey/were_a_bunch_of_developers_from_ibm_ask_us.json

        if(pipe.amaURL.match(/\.json$/)) {
        	amaJsonURL = pipe.amaURL;
        }
        else {
			if(pipe.amaURL.charAt(pipe.amaURL.length-1) == '/') {
				amaJsonURL = pipe.amaURL.replace(/\/+$/,'.json');
			}
			else {
				amaJsonURL = pipe.amaURL + '.json';
			}
		}

		logger.info('Connecting to AMA with url ' + amaJsonURL);

		request.get(amaJsonURL, {'json': true},
			function( err, response, body ){
				if ( err ){
					logger.error('Unable to fetch AMA: ' + err );
					return done( err );
				}

				logger.debug('Reddit API response: ' + response);

				// Create an async queue to process the record with Watson Tone Analyzer
				var q = async.queue( function( post, callback ){

					logger.debug(util.inspect(post));

					var msg = '';

					// Call Tone analyzer to get sentiments from the post
					// https://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/tone-analyzer/output.shtml
					request.post( watsonToneAnalyzerService.credentials.url + '/v3/tone?version=2016-02-11',{
						'auth': {
						  'user': watsonToneAnalyzerService.credentials.username,
						  'pass': watsonToneAnalyzerService.credentials.password,
						  'sendImmediately': true
						},
						'json': {
							'text': post.selftext || post.body
						}
					}, function( err, response, body ){

						if ( err ){
							msg = 'Error querying Watson Tone Analyzer service: ' + err;
							logger.error(msg);
							return callback( msg );
						}

						logger.debug('WTA response: ' + util.inspect(response));
						logger.debug('WTA body: ' + util.inspect(body));

						if(response.statusCode >= 300) {
							msg = 'Call to Watson Tone Analyzer URL ' + response.request.uri.href + ' returned status ' + response.statusCode + ' (' + response.body.error + ')';
							logger.error(msg);
							return callback(msg);
						}

						var sentiments = {
											author: post.author,
											created: post.created_utc,
											edited: post.edited,
											id: post.id,
											num_comments: post.num_comments,
											title: post.title || '',
											text: post.selftext || post.body
                                         };

                        if(body.document_tone) {

                        	/*

                        	Tone Analyzer API v3 output

							{
							    document_tone: {

												tone_categories: [
																  	{
																  	  tones: [ [Object], [Object], [Object], [Object], [Object] ],
																  	  category_id: 'emotion_tone',
																      category_name: 'Emotion Tone'
																    },
																    {
																      tones: [ [Object], [Object], [Object] ],
																      category_id: 'writing_tone',
																      category_name: 'Writing Tone'
																    },
																    {
																      tones: [ [Object], [Object], [Object], [Object], [Object] ],
																      category_id: 'social_tone',
																      category_name: 'Social Tone'
																    }
															      ]
										        },
							    sentences_tone: ...

							}

                        	*/

							logger.debug('Document tone categories: ' + util.inspect(body.document_tone.tone_categories));

							_.forEach(body.document_tone.tone_categories, function(tone_category) {
								sentiments[tone_category.category_id] = {
									                                      category_name : tone_category.category_name,
									                                      tones: tone_category.tones
									                                    };
								// add normalized score (between 0 and 100, two decimal places)
								_.forEach(sentiments[tone_category.category_id].tones, function(tone){
									// Sample tone definition: { score: 0.10796, tone_id: 'anger', tone_name: 'Anger' }
									tone.normalized_score = (parseFloat(tone.score * 100)).toFixed(2);
								});
							});

                        	// save in Cloudant
                            pushRecordFn(sentiments);

                        }
                        else {
                        	// No tone analyzer results were returned
                        	// Don't store post in Cloudant
                        	logger.warn('No Tone Analyzer results were returned for ' + sentiments.title + '.');
                        }

   						return callback();

                    }); // post
				}, concurrency ); // async

				_.forEach( body, function( listing ){
					if ( listing.kind == 'Listing' && listing.hasOwnProperty('data' ) ){
						if ( listing.data.hasOwnProperty('children') ){
							//Get the children from the data fields, only process the top posts for now
							_.forEach( listing.data.children, function( post ){
								if ( post.hasOwnProperty('data') ){
									// add post to queue only if it contains text
									if((post.data.hasOwnProperty('selftext')) || (post.data.hasOwnProperty('body'))) {
										q.push( post.data );
									}
								}
							});
						}
					}
				});

				// Drain function is invoked after all posts have been processed
				q.drain = function(){
					// pipe processing complete
					return done();
				}

				// if the queue is empty asynchronous processing has already completed (or there was nothing to process)
				if(q.idle()) {
					return done();
				}

			}
		);
	};
}

//Extend event Emitter
require('util').inherits(redditConnector, connectorExt);

module.exports = new redditConnector();
<|endoftext|>


<commit_before>/**
 * React Static Boilerplate
 * https://github.com/koistya/react-static-boilerplate
 * Copyright (c) Konstantin Tarkus (@koistya) | MIT license
 */

import React, {PropTypes} from 'react';
import config from '../../config';
var Chart = require('../Charts/Chart');
// require('../Utils')
import * as utils from '../Utils';
import ReactDOM from 'react-dom';
var $ = require("jquery");
// require("jquery-ui/autocomplete");
if (typeof document !== 'undefined') {
  require("jquery-ui");
}

var Menu = React.createClass({
  getInitialState: function () {
    return {activeMenu: ""};
  },
  updateMenu: function () {
    console.log("updateMenu");
  },
  render: function () {
    var rowsgroup = [];
    // var items = categories.hello;
    var items = cats;
    var this_ = this;
    items.forEach(function (item) {
      item.color = "white";
      rowsgroup.push(<MenuRowGroup item={item} updateMenu={this_.updateMenu}/>);
    });
    return (

                  {rowsgroup}

    );
  }
});

Menu.propTypes = {
  // children: PropTypes.element.isRequired,
};

var MenuRowGroup = React.createClass({
  render: function () {
    var rows = [];
    // var items = categories.hello;
    var charts = this.props.item.charts;
    var this_ = this;
    charts.forEach(function (item) {
      rows.push(<MenuRow item={item} updateMenu={this_.props.updateMenu}/>);
    });
    return (

        {this.props.item.name}
        {rows}

    );
  }
});

var callback = function (data) {
  console.log("entered callback");
  // console.log(this.chart);
  // console.log("DATA");
  // console.log(data);
  var chart_id = this.chart;

  if (chart_id == "17") {
    utils.setup_chart_special(data);
  }
  else if (chart_id == "10" || chart_id == "9" || chart_id == "4") {
    utils.setup_top_chart(data);
  }
  else {
    $("#chart-config").hide();
    var opts = utils.charts[chart_id];
    var series = utils.chart_series[chart_id];
    // console.log("SERIES:");
    // console.log(series);
    var queryResult = data;
    var opts_series = [];
    for (var i = 0; i < series.length; i++) {
      if (!series[i]["not-in-chart"]) {
        var attr = series[i]["attribute"];
        var qr = queryResult[attr];
        if (qr != null) {
          series[i]["data"] = [];
          for (var j = 0; j < qr.length; j++) {
            var num = Number(qr[j]);
            if (num != 0) {
              series[i]["data"].push([j, num]);
            }
          }
          opts_series.push(series[i]);
        }
      }
    }
    // console.log("OPTS SERIES");
    console.log(opts_series);

    opts.series = opts_series;
    // console.log("options");
    // console.log(opts);
    var element = React.createElement(Chart, {container: 'chart', options: opts});

    if (typeof window !== 'undefined') {
      ReactDOM.render(element, document.getElementById('chart'));
    }
  }
  if (typeof window != 'undefined') {
    $.get(config.server_url + '/index.php/jobs/UserList', {
        user: "",
        application: "null"
      },
      function (data) {
        var users = data;
        $.get(config.server_url + '/index.php/jobs/ApplicationList', {
            application: "",
            user: "null"
          },
          function (data) {
            var apps = data;
            // $("#user-typeahead").typeahead({source:users});
            // $("#application-typeahead").typeahead({source: apps});

            $("#user-typeahead").autocomplete({
              source: users,
              messages: {
                noResults: '',
                results: function () {
                }
              }
            });
            $("#application-typeahead").autocomplete({
              source: apps,
              messages: {
                noResults: '',
                results: function () {
                }
              }
            });
          });
      });

  }

};

var MenuRow = React.createClass({

  handleClick: function (e) {
    console.log("Hello handleClick");
    if (typeof window !== 'undefined') {
      console.log("before updatemenu");
      this.props.updateMenu();
      console.log("after udatemenu");

      console.log("handle click");
      var chart_id = this.props.item.id;
      $("#chart").html("
Loading...
");
      $("#chart_id_storage").val(chart_id);
      var data = {
        url: "test",
        chart: chart_id
      }

      $.ajax({
        url: config.server_url + '/index.php/jobs/filter',
        // url: "http://localhost/index.php/jobs/filter",
        dataType: 'json',
        type: 'POST',
        data: JSON.stringify(data),
        chart: chart_id,
        success: callback,
        error: function (xhr, status, err) {
          console.log("ERROR");
          console.log(xhr);
          console.log(status);
          console.log(err);
        }
      });
    }
  },
  render: function () {
    return (

        {this.props.item.title}

    );
  }
});

var cats_all = [
  {
    "id": 2,
    "name": "Analyze Application I/O Behavior",
    "charts": [
      {
        "id": 17,
        "title": "Overview of I/O characteristics"
      },
      {
        "id": 12,
        "title": "Time Breakdown"
      }

    ]
  },
  {
    "id": 1,
    "name": "Analyze Platform I/O Workload",
    "charts": [
      {
        "id": 8,
        "title": "I/O Throughput of All Apps"
      },
      {
        "id": 18,
        "title": "Cumulative Usage of I/O Time of Apps"
      },
      {
        "id": 999,
        "title": "Top Apps",
        "subcats": [
          {
            "id": 9,
            "title": "with Highest I/O Time"
          },
          {
            "id": 4,
            "title": "with Highest Run Time"
          },
          {
            "id": 10,
            "title": "with Highest Amount of Data Accessed"
          }
        ]
      },
      {
        "id": 15,
        "title": "Application's Data Size Distribution"
      }
    ]
  }
];

var cats = [
  {
    "id": 2,
    "name": "Analyze Application I/O Behavior",
    "charts": [
      {
        "id": 17,
        "title": "Overview of I/O characteristics"
      },
      {
        "id": 12,
        "title": "Time Breakdown"
      }

    ]
  }, {
    "id": 5,
    "name": "Analyze Platform I/O Workload",
    "charts": [
      {
        "id": 10,
        "title": "Top Applications with Highest Amount of Data Read/Written"
      },
      {
        "id": 9,
        "title": "Top Applications with Highest I/O Time",
      },
      {
        "id": 4,
        "title": "Top Applications with Highest Runtime",
      },
    ]
  }
];

export default Menu;
<commit_msg>fix color change for menu, consider categories as menu's state<commit_after>/**
 * React Static Boilerplate
 * https://github.com/koistya/react-static-boilerplate
 * Copyright (c) Konstantin Tarkus (@koistya) | MIT license
 */

import React, {PropTypes} from 'react';
import config from '../../config';
var Chart = require('../Charts/Chart');
// require('../Utils')
import * as utils from '../Utils';
import ReactDOM from 'react-dom';
var $ = require("jquery");
// require("jquery-ui/autocomplete");
if (typeof document !== 'undefined') {
  require("jquery-ui");
}

var Menu = React.createClass({
  getInitialState: function () {
    return {items: cats};
  },
  componentDidMount: function () {
    // this.state.items.forEach(function (subcat) {
    //   subcat.charts.forEach(function (item) {
    //     item.color = "white";
    //   });
    // }).bind(this);
  },
  updateMenu: function (itemId) {
    console.log("updateMenu");
    console.log(this.state.items);
    var i,j;
    for (i in this.state.items) {
      for (j in this.state.items[i].charts) {
        if (this.state.items[i].charts[j].id == itemId) {
          this.state.items[i].charts[j].color = "#C5BFC7";
          console.log("chage to red for " + this.state.items[i].charts[j].id);
        } else {
          this.state.items[i].charts[j].color = "white";
        }
      }
    }
    this.forceUpdate();
  },
  render: function () {
    var rowsgroup = [];
    // var items = categories.hello;
    var this_ = this;
    this.state.items.forEach(function (item) {
      // console.log(item);
      rowsgroup.push(<MenuRowGroup item={item} updateMenu={this_.updateMenu}/>);
    });
    return (

                  {rowsgroup}

    );
  }
});

Menu.propTypes = {
  // children: PropTypes.element.isRequired,
};

var MenuRowGroup = React.createClass({
  render: function () {
    var rows = [];
    // var items = categories.hello;
    var charts = this.props.item.charts;
    var this_ = this;
    charts.forEach(function (item) {
      console.log(item);
      rows.push(<MenuRow item={item} updateMenu={this_.props.updateMenu}/>);
    });
    return (

        {this.props.item.name}
        {rows}

    );
  }
});

var callback = function (data) {
  console.log("entered callback");
  // console.log(this.chart);
  // console.log("DATA");
  // console.log(data);
  var chart_id = this.chart;

  if (chart_id == "17") {
    utils.setup_chart_special(data);
  }
  else if (chart_id == "10" || chart_id == "9" || chart_id == "4") {
    utils.setup_top_chart(data);
  }
  else {
    $("#chart-config").hide();
    var opts = utils.charts[chart_id];
    var series = utils.chart_series[chart_id];
    // console.log("SERIES:");
    // console.log(series);
    var queryResult = data;
    var opts_series = [];
    for (var i = 0; i < series.length; i++) {
      if (!series[i]["not-in-chart"]) {
        var attr = series[i]["attribute"];
        var qr = queryResult[attr];
        if (qr != null) {
          series[i]["data"] = [];
          for (var j = 0; j < qr.length; j++) {
            var num = Number(qr[j]);
            if (num != 0) {
              series[i]["data"].push([j, num]);
            }
          }
          opts_series.push(series[i]);
        }
      }
    }
    // console.log("OPTS SERIES");
    console.log(opts_series);

    opts.series = opts_series;
    // console.log("options");
    // console.log(opts);
    var element = React.createElement(Chart, {container: 'chart', options: opts});

    if (typeof window !== 'undefined') {
      ReactDOM.render(element, document.getElementById('chart'));
    }
  }
  if (typeof window != 'undefined') {
    $.get(config.server_url + '/index.php/jobs/UserList', {
        user: "",
        application: "null"
      },
      function (data) {
        var users = data;
        $.get(config.server_url + '/index.php/jobs/ApplicationList', {
            application: "",
            user: "null"
          },
          function (data) {
            var apps = data;
            // $("#user-typeahead").typeahead({source:users});
            // $("#application-typeahead").typeahead({source: apps});

            $("#user-typeahead").autocomplete({
              source: users,
              messages: {
                noResults: '',
                results: function () {
                }
              }
            });
            $("#application-typeahead").autocomplete({
              source: apps,
              messages: {
                noResults: '',
                results: function () {
                }
              }
            });
          });
      });

  }

};

var MenuRow = React.createClass({

  handleClick: function (e) {
    if (typeof window !== 'undefined') {
      this.props.updateMenu(this.props.item.id);
      console.log("handle click");
      var chart_id = this.props.item.id;
      $("#chart").html("
Loading...
");
      $("#chart_id_storage").val(chart_id);
      var data = {
        url: "test",
        chart: chart_id
      }

      $.ajax({
        url: config.server_url + '/index.php/jobs/filter',
        // url: "http://localhost/index.php/jobs/filter",
        dataType: 'json',
        type: 'POST',
        data: JSON.stringify(data),
        chart: chart_id,
        success: callback,
        error: function (xhr, status, err) {
          console.log("ERROR");
          console.log(xhr);
          console.log(status);
          console.log(err);
        }
      });
    }
  },
  render: function () {
    return (

        {this.props.item.title}

    );
  }
});

var cats_all = [
  {
    "id": 2,
    "name": "Analyze Application I/O Behavior",
    "charts": [
      {
        "id": 17,
        "title": "Overview of I/O characteristics"
      },
      {
        "id": 12,
        "title": "Time Breakdown"
      }

    ]
  },
  {
    "id": 1,
    "name": "Analyze Platform I/O Workload",
    "charts": [
      {
        "id": 8,
        "title": "I/O Throughput of All Apps"
      },
      {
        "id": 18,
        "title": "Cumulative Usage of I/O Time of Apps"
      },
      {
        "id": 999,
        "title": "Top Apps",
        "subcats": [
          {
            "id": 9,
            "title": "with Highest I/O Time"
          },
          {
            "id": 4,
            "title": "with Highest Run Time"
          },
          {
            "id": 10,
            "title": "with Highest Amount of Data Accessed"
          }
        ]
      },
      {
        "id": 15,
        "title": "Application's Data Size Distribution"
      }
    ]
  }
];

var cats = [
  {
    "id": 2,
    "name": "Analyze Application I/O Behavior",
    "charts": [
      {
        "id": 17,
        "title": "Overview of I/O characteristics"
      },
      {
        "id": 12,
        "title": "Time Breakdown"
      }

    ]
  }, {
    "id": 5,
    "name": "Analyze Platform I/O Workload",
    "charts": [
      {
        "id": 10,
        "title": "Top Applications with Highest Amount of Data Read/Written"
      },
      {
        "id": 9,
        "title": "Top Applications with Highest I/O Time",
      },
      {
        "id": 4,
        "title": "Top Applications with Highest Runtime",
      },
    ]
  }
];

export default Menu;
<|endoftext|>


<commit_before>/**
 * Created by sbardian on 5/18/17.
 */

const openTriviaAPI = require('opentriviaapi');

const utils = {
  getToken() {
    return openTriviaAPI.getToken();
  },
  getQuestions(options) {
    if (options.getToken) {
      utils.getToken()
          .then((data) => {
            options.token = data.token;
          });
      return openTriviaAPI.getQuestions(options)
          .then((data) => {
            return data.results;
          });
    }
  }
};

module.exports = utils;<commit_msg>Logic for only getting a token onces. .  more to come.<commit_after>/**
 * Created by sbardian on 5/18/17.
 */

const openTriviaAPI = require('opentriviaapi');
let token = null;

const utils = {
  getToken() {
    return openTriviaAPI.getToken();
  },
  getQuestions(options) {
    if (options.getToken && !token) {
      utils.getToken()
          .then((data) => {
            token = data.token;
            options.token = data.token;
          });
      return openTriviaAPI.getQuestions(options)
          .then((data) => {
            return data.results;
          });
      // TODO: deal with token needing reset.
    } else {
      options.token = token;
      return openTriviaAPI.getQuestions(options);
    }
  }
};

module.exports = utils;<|endoftext|>


<commit_before>"use strict";

const readJson = require("r-json")
    , writeJson = require("w-json")
    , abs = require("abs")
    , path = require("path")
    , EnginePaths = require("engine-paths")
    , CompositionCrud = require("engine-composition-crud")
    ;

class EngineApp {
    /**
     * EngineApp
     * Creates a new instance of `EngineApp`.
     *
     * @name EngineApp
     * @function
     * @param {String} appPath The app path.
     */
    constructor (appPath, compositionCrud) {
        if (typeof appPath !== "string" || !appPath) {
            throw new TypeError("The app parameter should be a string.");
        }
        this.paths = new EnginePaths(appPath);
        this.crud = compositionCrud || new CompositionCrud(this.paths);
    }

    /**
     * getPackage
     * Gets the package.json content.
     *
     * @name getPackage
     * @function
     * @param {Function} cb The callback function.
     * @return {Object} The `package.json` content as json (if called without a callback function).
     */
    getPackage (cb) {
        return readJson(this.paths.package, cb);
    }

    /**
     * setPackage
     * Sets the package.json content.
     *
     * @name setPackage
     * @function
     * @param {Object} data The data to set in the file.
     * @param {Function} cb The callback function.
     */
    setPackage (data, cb) {
        return writeJson(this.paths.package, data, cb);
    }

    /**
     * createInstance
     * Creates a new instance.
     *
     * @name createInstance
     * @function
     * @param {String} name The instance name.
     * @param {Object} data The instance content.
     * @param {Function} cb The callback function.
     */
    createInstance (name, data, cb) {
        return this.crud.create(name, data, cb);
    }

    /**
     * readInstance
     * Gets the instance content.
     *
     * @name readInstance
     * @function
     * @param {String} name The instance name.
     * @param {Function} cb The callback function.
     */
    readInstance (name, cb) {
        this.crud.read(name, cb);
    }

    /**
     * updateInstance
     * Updates an instance.
     *
     * @name updateInstance
     * @function
     * @param {String} name The instance name.
     * @param {Object} data The instance content.
     * @param {Function} cb The callback function.
     */
    updateInstance (name, data, cb) {
        return this.crud.update(name, data, cb);
    }

    /**
     * removeInstance
     * Removes an instance.
     *
     * @name removeInstance
     * @function
     * @param {String} name The instance name.
     * @param {Function} cb The callback function.
     */
    removeInstance (name, cb) {
        return this.crud.remove(name, cb);
    }

    /**
     * listInstances
     * List instances.
     *
     * @name listInstance
     * @function
     * @param {Function} cb The callback function.
     */
    listInstances (cb) {
        return this.crud.list(cb);
    }

    /**
     * getAllInstances
     * Read all instances.
     *
     * @name getAllnstances
     * @function
     * @param {Function} cb The callback function.
     */
    getAllInstances (cb) {
        return this.crud.readAll(cb);
    }

    /**
     * renameInstance
     * Renames the specified instance.
     *
     * @name renameInstance
     * @function
     * @param {String} oldName The old instance name.
     * @param {String} newName The new instance name.
     * @param {Function} cb The callback function.
     */
    renameInstance (oldName, newName, cb) {
        return this.crud.rename(oldName, newName, cb);
    }

    /**
     * upsertInstance
     * Creates or updates the specified instance.
     *
     * @name upsertInstance
     * @function
     * @param {String} name The instance name.
     * @param {Object} data The instance content.
     * @param {Function} cb The callback function.
     */
    upsertInstance (name, data, cb) {
        return this.crud.upsert(name, data, cb);
    }
}

module.exports = EngineApp;
<commit_msg>Set and get the module package.json<commit_after>"use strict";

const readJson = require("r-json")
    , writeJson = require("w-json")
    , abs = require("abs")
    , path = require("path")
    , EnginePaths = require("engine-paths")
    , CompositionCrud = require("engine-composition-crud")
    ;

class EngineApp {
    /**
     * EngineApp
     * Creates a new instance of `EngineApp`.
     *
     * @name EngineApp
     * @function
     * @param {String} appPath The app path.
     */
    constructor (appPath, compositionCrud) {
        if (typeof appPath !== "string" || !appPath) {
            throw new TypeError("The app parameter should be a string.");
        }
        this.paths = new EnginePaths(appPath);
        this.crud = compositionCrud || new CompositionCrud(this.paths);
    }

    /**
     * getPackage
     * Gets the package.json content.
     *
     * @name getPackage
     * @function
     * @param {Function} cb The callback function.
     * @return {Object} The `package.json` content as json (if called without a callback function).
     */
    getPackage (cb) {
        return readJson(this.paths.package, cb);
    }

    /**
     * setPackage
     * Sets the package.json content.
     *
     * @name setPackage
     * @function
     * @param {Object} data The data to set in the file.
     * @param {Function} cb The callback function.
     */
    setPackage (data, cb) {
        return writeJson(this.paths.package, data, cb);
    }

    /**
     * getModulePackage
     * Reads the module `package.json` file.
     *
     * @name getModulePackage
     * @function
     * @param {String} name The module name.
     * @return {Object} The `package.json` content as json (if called without a callback function).
     */
    getModulePackage (name, cb) {
        return readJson(this.paths.modulePack(name), cb);
    }

    /**
     * setModulePackage
     * Writes the module `package.json` file.
     *
     * @name setModulePackage
     * @function
     * @param {String} name The module name.
     * @param {Object} data The data to set in the file.
     */
    setModulePackage (name, data, cb) {
        return writeJson(this.paths.modulePack(name), data, cb);
    }

    /**
     * createInstance
     * Creates a new instance.
     *
     * @name createInstance
     * @function
     * @param {String} name The instance name.
     * @param {Object} data The instance content.
     * @param {Function} cb The callback function.
     */
    createInstance (name, data, cb) {
        return this.crud.create(name, data, cb);
    }

    /**
     * readInstance
     * Gets the instance content.
     *
     * @name readInstance
     * @function
     * @param {String} name The instance name.
     * @param {Function} cb The callback function.
     */
    readInstance (name, cb) {
        this.crud.read(name, cb);
    }

    /**
     * updateInstance
     * Updates an instance.
     *
     * @name updateInstance
     * @function
     * @param {String} name The instance name.
     * @param {Object} data The instance content.
     * @param {Function} cb The callback function.
     */
    updateInstance (name, data, cb) {
        return this.crud.update(name, data, cb);
    }

    /**
     * removeInstance
     * Removes an instance.
     *
     * @name removeInstance
     * @function
     * @param {String} name The instance name.
     * @param {Function} cb The callback function.
     */
    removeInstance (name, cb) {
        return this.crud.remove(name, cb);
    }

    /**
     * listInstances
     * List instances.
     *
     * @name listInstance
     * @function
     * @param {Function} cb The callback function.
     */
    listInstances (cb) {
        return this.crud.list(cb);
    }

    /**
     * getAllInstances
     * Read all instances.
     *
     * @name getAllnstances
     * @function
     * @param {Function} cb The callback function.
     */
    getAllInstances (cb) {
        return this.crud.readAll(cb);
    }

    /**
     * renameInstance
     * Renames the specified instance.
     *
     * @name renameInstance
     * @function
     * @param {String} oldName The old instance name.
     * @param {String} newName The new instance name.
     * @param {Function} cb The callback function.
     */
    renameInstance (oldName, newName, cb) {
        return this.crud.rename(oldName, newName, cb);
    }

    /**
     * upsertInstance
     * Creates or updates the specified instance.
     *
     * @name upsertInstance
     * @function
     * @param {String} name The instance name.
     * @param {Object} data The instance content.
     * @param {Function} cb The callback function.
     */
    upsertInstance (name, data, cb) {
        return this.crud.upsert(name, data, cb);
    }
}

module.exports = EngineApp;
<|endoftext|>


<commit_before>import { EOL } from 'os'
import React from 'react'
import { NativeTypes } from 'react-dnd-html5-backend'
import { DropTarget } from 'react-dnd'
import domtoimage from 'dom-to-image'

const padding = '50px 50px'

const DEFAULT_CODE = `
const pluckDeep = key => obj => key.split('.').reduce((accum, key) => accum[key], obj)

const compose = (...fns) => res => fns.reduce((accum, next) => next(accum), res)

const unfold = (f, seed) => {
  const go = (f, seed, acc) => {
    const res = f(seed)
    return res ? go(f, res[1], acc.concat([res[0]])) : acc
  }
  return go(f, seed, [])
}`

const MAX_LINES = 40

class CodeImage extends React.Component {
  constructor () {
    super()
    this.state = {}
    this.save = this.save.bind(this)
  }

  save () {
    // save
    domtoimage.toJpeg(this.container)
      .then((dataUrl) => {
        const link = document.createElement('a')
        link.download = 'my-image-name.jpeg'
        link.href = dataUrl
        link.click()
      })
  }

  render () {
    let code = this.props.children || this.state.droppedContent || DEFAULT_CODE
    const split = code.split(EOL)
    if (split.length > MAX_LINES) code = [...split.slice(0, MAX_LINES - 1), '', '...'].join(EOL)

    return this.props.connectDropTarget(

 { this.container = container }}>

              {code}

    )
  }
}

const drop = (props, monitor, component) => {
  const bundle = monitor.getItem()
  const file = bundle.files[0]
  const reader = new FileReader()
  reader.onload = function(event) {
    component.setState({
      droppedContent: event.target.result
    })
  };
  reader.readAsText(file, "UTF-8");
}

export default DropTarget(NativeTypes.FILE, { drop }, (connect, monitor) => ({
  connectDropTarget: connect.dropTarget(),
  isOver: monitor.isOver(),
  canDrop: monitor.canDrop(),
  item: monitor.getItem()
}))(CodeImage)
<commit_msg>Change something<commit_after>import { EOL } from 'os'
import React from 'react'
import { NativeTypes } from 'react-dnd-html5-backend'
import { DropTarget } from 'react-dnd'
import domtoimage from 'dom-to-image'

const padding = '50px 50px'

const DEFAULT_CODE = `
const pluckDeep = key => obj => key.split('.').reduce((accum, key) => accum[key], obj)

const compose = (...fns) => res => fns.reduce((accum, next) => next(accum), res)

const unfold = (f, seed) => {
  const go = (f, seed, acc) => {
    const res = f(seed)
    return res ? go(f, res[1], acc.concat([res[0]])) : acc
  }
  return go(f, seed, [])
}`

const MAX_LINES = 40

class CodeImage extends React.Component {
  constructor () {
    super()
    this.state = {}
    this.save = this.save.bind(this)
  }

  save () {
    // save
    domtoimage.toJpeg(this.container)
      .then((dataUrl) => {
        const link = document.createElement('a')
        link.download = 'my-image-name.jpeg'
        link.href = dataUrl
        link.click()
      })
  }

  render () {
    let code = this.state.droppedContent || this.props.children || DEFAULT_CODE
    const split = code.split(EOL)
    if (split.length > MAX_LINES) code = [...split.slice(0, MAX_LINES - 1), '', '...'].join(EOL)

    return this.props.connectDropTarget(

 { this.container = container }}>

              {code}

    )
  }
}

const drop = (props, monitor, component) => {
  const bundle = monitor.getItem()
  const file = bundle.files[0]
  const reader = new FileReader()
  reader.onload = function(event) {
    component.setState({
      droppedContent: event.target.result
    })
  };
  reader.readAsText(file, "UTF-8");
}

export default DropTarget(NativeTypes.FILE, { drop }, (connect, monitor) => ({
  connectDropTarget: connect.dropTarget(),
  isOver: monitor.isOver(),
  canDrop: monitor.canDrop(),
  item: monitor.getItem()
}))(CodeImage)
<|endoftext|>


<commit_before>'use strict';

var async = require('async');
var tenantsColName = 'tenants';

module.exports = {

	/**
	 * Check if error is available and return it in response, else return callback function
	 *
	 * @param {Object} soajs
	 * @param {Callback Function} mainCb
	 * @param {Object} data
	 * @param {Callback Function} cb
	 */
	checkErrorReturn: function (soajs, mainCb, data, cb) {
		if (data.error) {
			if (typeof (data.error) === 'object') {
				soajs.log.error(data.error);
			}

			if (data.error.source === 'driver') {
				return mainCb({"code": data.error.code, "msg": data.error.msg});
			}

			return mainCb({"code": data.code, "msg": data.config.errors[data.code]});
		} else {
			if (cb) {
				return cb();
			}
		}
	},

    /**
     * Build an object that contains required values to be included when calling a soajs.core.drivers function
     *
     * @param {Object} envRecord
     * @param {Object} soajs
     * @returns {Object} options
     */
    buildDeployerOptions: function (envRecord, soajs, BL) {
        var options = {};
        var envDeployer = envRecord.deployer;

        if (!envDeployer) return null;
        if (Object.keys(envDeployer).length === 0) return null;
        if (!envDeployer.type || !envDeployer.selected) return null;
        if (envDeployer.type === 'manual') return null;

        var selected = envDeployer.selected.split('.');

        options.strategy = selected[1];
        options.driver = selected[1] + '.' + selected[2];
        options.env = envRecord.code.toLowerCase();

		options.registry = envRecord; //NOTE: might switch to registry instead of envRecord

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

        options.deployerConfig = envDeployer;
        options.soajs = { registry: soajs.registry };
        options.model = BL.model;

        //switch strategy name to follow drivers convention
        if (options.strategy === 'docker') options.strategy = 'swarm';

        return options;
    },

    /**
     * Get an evironment record from data store
     *
     * @param {Object} soajs
     * @param {String} code
     * @param {Object} BL
     * @param {Callback Function} cb
     */
    getEnvironment: function (soajs, model, code, cb) {
        var opts = {
            collection: 'environment',
            conditions: { code: code.toUpperCase() }
        };

        model.findEntry(soajs, opts, cb);
    },

	/**
	 * Function that replaces characters in object keys with alternatives
	 * @param  {Object}   record            The record that will be manipulated
	 * @param  {String}   regex             String used to build the regex
	 * @param  {String}   replacementString Replacement string
	 * @param  {Function} cb                Callback function
	 * @return {void}
	 */
	normalizeKeyValues: function (record, regex, replacementString, cb) {
		var updatedRecord = {};
		var replacementRegex = new RegExp(regex, 'g');
		async.eachOf(record, function (oneRecordEntry, key, callback) {
			if(key.match(replacementRegex)) {
				updatedRecord[key.replace(replacementRegex, replacementString)] = oneRecordEntry;
			}
			else {
				updatedRecord[key] = oneRecordEntry;
			}

			return callback();
		}, function () {
			return cb(null, updatedRecord);
		});
	},

	/**
	 * Function that checks if current logged in user belongs to group owner
	 * @param  {Object}   soajs
	 * @param  {Function} cb
	 * @return {void}
	 */
	checkIfOwner: function(soajs, model, cb) {
		var uracRecord = soajs.urac;
		var opts = {
			collection: tenantsColName,
			conditions: {
				code: uracRecord.tenant.code.toUpperCase()
			}
		};

		model.findEntry(soajs, opts, function (error, tenantRecord) {
			if(error) return cb(error);

			if(tenantRecord && tenantRecord.locked && uracRecord.groups.indexOf('owner') !== -1) {
				return cb(null, true);
			}

			return cb(null, false);
		});
	}
};
<commit_msg>Updated buildDeployerOptions() to work with envRecord<commit_after>'use strict';

var async = require('async');
var tenantsColName = 'tenants';

module.exports = {

	/**
	 * Check if error is available and return it in response, else return callback function
	 *
	 * @param {Object} soajs
	 * @param {Callback Function} mainCb
	 * @param {Object} data
	 * @param {Callback Function} cb
	 */
	checkErrorReturn: function (soajs, mainCb, data, cb) {
		if (data.error) {
			if (typeof (data.error) === 'object') {
				soajs.log.error(data.error);
			}

			if (data.error.source === 'driver') {
				return mainCb({"code": data.error.code, "msg": data.error.msg});
			}

			return mainCb({"code": data.code, "msg": data.config.errors[data.code]});
		} else {
			if (cb) {
				return cb();
			}
		}
	},

    /**
     * Build an object that contains required values to be included when calling a soajs.core.drivers function
     *
     * @param {Object} envRecord
     * @param {Object} soajs
     * @returns {Object} options
     */
    buildDeployerOptions: function (envRecord, soajs, BL) {
        var options = {};
        var envDeployer = envRecord.deployer;

        if (!envDeployer) return null;
        if (Object.keys(envDeployer).length === 0) return null;
        if (!envDeployer.type || !envDeployer.selected) return null;
        if (envDeployer.type === 'manual') return null;

        var selected = envDeployer.selected.split('.');

        options.strategy = selected[1];
        options.driver = selected[1] + '.' + selected[2];
        options.env = envRecord.code.toLowerCase();

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

        options.deployerConfig = envDeployer;
        // options.soajs = { registry: soajs.registry };
		//soajs.registry refers to dashboard env registry, using envRecord instead
		//normalizing serviceConfig object between registry and environment record
		if(envRecord.services && envRecord.services.config) {
			envRecord.serviceConfig = envRecord.services.config;
		}

		options.soajs = { registry: envRecord };
        options.model = BL.model;

        //switch strategy name to follow drivers convention
        if (options.strategy === 'docker') options.strategy = 'swarm';

        return options;
    },

    /**
     * Get an evironment record from data store
     *
     * @param {Object} soajs
     * @param {String} code
     * @param {Object} BL
     * @param {Callback Function} cb
     */
    getEnvironment: function (soajs, model, code, cb) {
        var opts = {
            collection: 'environment',
            conditions: { code: code.toUpperCase() }
        };

        model.findEntry(soajs, opts, cb);
    },

	/**
	 * Function that replaces characters in object keys with alternatives
	 * @param  {Object}   record            The record that will be manipulated
	 * @param  {String}   regex             String used to build the regex
	 * @param  {String}   replacementString Replacement string
	 * @param  {Function} cb                Callback function
	 * @return {void}
	 */
	normalizeKeyValues: function (record, regex, replacementString, cb) {
		var updatedRecord = {};
		var replacementRegex = new RegExp(regex, 'g');
		async.eachOf(record, function (oneRecordEntry, key, callback) {
			if(key.match(replacementRegex)) {
				updatedRecord[key.replace(replacementRegex, replacementString)] = oneRecordEntry;
			}
			else {
				updatedRecord[key] = oneRecordEntry;
			}

			return callback();
		}, function () {
			return cb(null, updatedRecord);
		});
	},

	/**
	 * Function that checks if current logged in user belongs to group owner
	 * @param  {Object}   soajs
	 * @param  {Function} cb
	 * @return {void}
	 */
	checkIfOwner: function(soajs, model, cb) {
		var uracRecord = soajs.urac;
		var opts = {
			collection: tenantsColName,
			conditions: {
				code: uracRecord.tenant.code.toUpperCase()
			}
		};

		model.findEntry(soajs, opts, function (error, tenantRecord) {
			if(error) return cb(error);

			if(tenantRecord && tenantRecord.locked && uracRecord.groups.indexOf('owner') !== -1) {
				return cb(null, true);
			}

			return cb(null, false);
		});
	}
};
<|endoftext|>


<commit_before>/**
 * Extend Handlebars to support generator helper
 *
 *
 * @author: Jingwei "John" Liu <liujingwei@gmail.com>
 **/

var Wrapper = require("./wrapper");
var compose = require("./compose");
var handlebars = require("handlebars");
// the callee may have null as prototype
var has = Function.call.bind(Object.prototype.hasOwnProperty);

var Q = "__GeneratorHelperQueue__";

// export a new instance of Handgrip
module.exports = Handgrip();
// mock handlebars.create
module.exports.create = Handgrip;

/**
 * Augment Handlebars
 **/
function Handgrip() {
    // always create a new instance of Handlebars
    var hbs = handlebars.create();

    // create a new instance of Handgrip
    hbs.create = Handgrip;

    hbs.registerGeneratorHelper = registerGeneratorHelper;
    hbs.render = render;
    hbs.createRenderer = createRenderer;

    // export a method to retrive the raw handlebars
    hbs.createHandlebars = handlebars.create();

    return hbs;
}

/**
 * Register generator helpers
 * does not support object input
 **/
function registerGeneratorHelper(fnName, fn) {
    var hbs = this;
    if (typeof fnName === "object") {
        Object.keys(fnName).forEach(function(n) {
            hbs.registerGeneratorHelper(n, fnName[n]);
        });

        return;
    }

    return hbs.registerHelper(fnName, function() {
        // execute helper to examine
        // whether it is generatorHelper or not
        var tuple = fn.apply(this, arguments);

        // compatible with traditional `registerHelper` calls
        if (!isGeneratorFunction(tuple)) return tuple;

        // wrap generate function in a data structure
        tuple = Wrapper.wrap(tuple);

        if (Q in this) {
            // each order level has its own spliceOffset
            if (!has(this, "spliceOffset")) this.spliceOffset = 0;
            this[Q].splice(this[Q].index + this.spliceOffset, 0, tuple);
            this.spliceOffset++;
        }

        var placeholder = Wrapper.toPlaceholder(tuple);

        return new hbs.SafeString(placeholder);
    });
}

/**
 * Compile method for page(root scope) rendering only
 * does not apply to rendering in generator helper
 * use traditional handlebars.compile/tpl() inside generator helpers
 **/
function render() {
    var compiled = this.compile.apply(this, arguments);
    return createRenderer(compiled);
}

/**
 * Adapt normal handlebars compiled template
 * by filling placeholder created by generatorHelper
 **/
function createRenderer(compiled) {
    return function*(context) {
        // create a safe copy of the context
        // so that all each layer has its own generator helpers queue
        context = Object.create(context || null);

        context[Q] = context[Q] || [];
        // execution index;
        context[Q].index = context[Q].index || 0;

        var args = Array.prototype.slice.call(arguments);
        args[0] = context;

        var out = compiled.apply(null, args);

        return yield replace.call(context, context[Q], out);
    };
}

/**
 * Replace generator helper placeholder with compiled content
 * requires valid context from its caller (hbs.render)
 **/
function *replace(fnArr, str) {
    // parse generator queue from leaft to right
    // this could mutate fnArr if new generator helpers are found
    var ret = yield compose.call(this, fnArr, Wrapper.unwrap);

    var retObj = {};
    fnArr.forEach(function(item, i) {
        retObj[item.toString()] = ret[i];
    });

    // create an array of uuid from generator queue
    var gidRegExp = Wrapper.toRegExp( Object.keys(retObj) );

    function strReplace(match, gid) {
        return retObj[gid];
    }

    // replace all generator helper placeholder
    var maxExecutionCount = 9999;
    do {
        str = str.replace(gidRegExp, strReplace);
    } while (gidRegExp.test(str) && maxExecutionCount--);

    return str;
}

/**
 * Check if function is generator function
 **/
function isGeneratorFunction(fn) {
    return fn && fn.constructor && fn.constructor.name === "GeneratorFunction";
}
<commit_msg>Avoid memory leak by cloning arguments<commit_after>/**
 * Extend Handlebars to support generator helper
 *
 *
 * @author: Jingwei "John" Liu <liujingwei@gmail.com>
 **/

var Wrapper = require("./wrapper");
var compose = require("./compose");
var handlebars = require("handlebars");
// the callee may have null as prototype
var has = Function.call.bind(Object.prototype.hasOwnProperty);

var Q = "__GeneratorHelperQueue__";

// export a new instance of Handgrip
module.exports = Handgrip();
// mock handlebars.create
module.exports.create = Handgrip;

/**
 * Augment Handlebars
 **/
function Handgrip() {
    // always create a new instance of Handlebars
    var hbs = handlebars.create();

    // create a new instance of Handgrip
    hbs.create = Handgrip;

    hbs.registerGeneratorHelper = registerGeneratorHelper;
    hbs.render = render;
    hbs.createRenderer = createRenderer;

    // export a method to retrive the raw handlebars
    hbs.createHandlebars = handlebars.create();

    return hbs;
}

/**
 * Register generator helpers
 * does not support object input
 **/
function registerGeneratorHelper(fnName, fn) {
    var hbs = this;
    if (typeof fnName === "object") {
        Object.keys(fnName).forEach(function(n) {
            hbs.registerGeneratorHelper(n, fnName[n]);
        });

        return;
    }

    return hbs.registerHelper(fnName, function() {
        // avoid memory leak by cloning arguments
        var len = arguments.length;
        var args = Array(len);
        while (len--) args[len] = arguments[len];

        // execute helper to examine
        // whether it is generatorHelper or not
        var tuple = fn.apply(this, args);

        // compatible with traditional `registerHelper` calls
        if (!isGeneratorFunction(tuple)) return tuple;

        // wrap generate function in a data structure
        tuple = Wrapper.wrap(tuple);

        if (Q in this) {
            // each order level has its own spliceOffset
            if (!has(this, "spliceOffset")) this.spliceOffset = 0;
            this[Q].splice(this[Q].index + this.spliceOffset, 0, tuple);
            this.spliceOffset++;
        }

        var placeholder = Wrapper.toPlaceholder(tuple);

        return new hbs.SafeString(placeholder);
    });
}

/**
 * Compile method for page(root scope) rendering only
 * does not apply to rendering in generator helper
 * use traditional handlebars.compile/tpl() inside generator helpers
 **/
function render() {
    // avoid memory leak by cloning arguments
    var len = arguments.length;
    var args = Array(len);
    while (len--) args[len] = arguments[len];

    var compiled = this.compile.apply(this, args);
    return createRenderer(compiled);
}

/**
 * Adapt normal handlebars compiled template
 * by filling placeholder created by generatorHelper
 **/
function createRenderer(compiled) {
    return function*(context) {
        // create a safe copy of the context
        // so that all each layer has its own generator helpers queue
        context = Object.create(context || null);

        context[Q] = context[Q] || [];
        // execution index;
        context[Q].index = context[Q].index || 0;

        var args = Array.prototype.slice.call(arguments);
        args[0] = context;

        var out = compiled.apply(null, args);

        return yield replace.call(context, context[Q], out);
    };
}

/**
 * Replace generator helper placeholder with compiled content
 * requires valid context from its caller (hbs.render)
 **/
function *replace(fnArr, str) {
    // parse generator queue from leaft to right
    // this could mutate fnArr if new generator helpers are found
    var ret = yield compose.call(this, fnArr, Wrapper.unwrap);

    var retObj = {};
    fnArr.forEach(function(item, i) {
        retObj[item.toString()] = ret[i];
    });

    // create an array of uuid from generator queue
    var gidRegExp = Wrapper.toRegExp( Object.keys(retObj) );

    function strReplace(match, gid) {
        return retObj[gid];
    }

    // replace all generator helper placeholder
    var maxExecutionCount = 9999;
    do {
        str = str.replace(gidRegExp, strReplace);
    } while (gidRegExp.test(str) && maxExecutionCount--);

    return str;
}

/**
 * Check if function is generator function
 **/
function isGeneratorFunction(fn) {
    return fn && fn.constructor && fn.constructor.name === "GeneratorFunction";
}
<|endoftext|>


<commit_before>// Dependencies
var Pty = require("pty.js")
  , SocketIoClient = require("socket.io-client")
  ;

function ShareTerm(options) {
    this.host = options.host;
}

ShareTerm.prototype.connected = function () {
    // Create the bash session
    var term = this.term = Pty.spawn("bash", [], {
       name: "xterm-color",
       cols: process.stdout.columns,
       rows: process.stdout.rows,
       cwd: ".",
       env: process.env
    });

    // Pipe standard input and output
    term.pipe(process.stdout);
    process.stdin.pipe(term);

    // Listen for Pty data
    term.on("data", function (data) {
        this.socket.emit("_terminalData", data);
    }.bind(this));

};

ShareTerm.prototype.connect = function (callback) {
    this.socket = SocketIoClient(this.host)

    // Welcome
    this.socket.on("welcome", function (sock) {
        this.connected();
        callback(null, sock);
    }.bind(this));

    // Connect error
    this.socket.on("connect_error", function (err) {
        callback(err);
    });

};

module.exports = ShareTerm;
<commit_msg>Added the create and get function.<commit_after>// Dependencies
var Pty = require("pty.js")
  , SocketIoClient = require("socket.io-client")
  , Ul = require("ul")
  ;

function ShareTerm(options) {
    this.host = options.host;
}

ShareTerm.prototype.connected = function () {
    // Create the bash session
    var term = this.term = Pty.spawn("bash", [], {
       name: "xterm-color",
       cols: process.stdout.columns,
       rows: process.stdout.rows,
       cwd: ".",
       env: process.env
    });

    // Pipe standard input and output
    term.pipe(process.stdout);
    process.stdin.pipe(term);

    // Listen for Pty data
    term.on("data", function (data) {
        this.socket.emit("_termData", data);
    }.bind(this));

    // Listen for Pty data
    term.on("close", function (data) {
        this.socket.emit("_termClosed", data);
    }.bind(this));

};

ShareTerm.prototype.connect = function (options, callback) {

    if (typeof options === "function") {
        callback = options;
        options = {};
    }

    this.socket = SocketIoClient(this.host)

    // Welcome
    this.socket.on("welcome", function (sock) {
        if (options.createPty !== false) {
            this.connected();
        }
        callback(null, sock);
    }.bind(this));

    // Connect error
    this.socket.on("connect_error", function (err) {
        callback(err);
    });
};

ShareTerm.prototype.create = function (callback) {
    this.connect(function (err, data) {
        if (err) { return callback(err); }
        this.socket.emit("createTerm");
        callback(null, data);
    }.bind(this));
};

ShareTerm.prototype.get = function (options, callback) {
    this.socket = SocketIoClient(this.host)

    Ul.merge(options, {
        stdout: process.stdout
    });

    this.connect({ createPty: false }, function (err, data) {
        if (err) { return callback(err); }

        this.socket.on("_termData", function (data) {
            options.stdout.write(data);
        }.bind(this));

        this.socket.on("_termClosed", function () {
            callback();
        });

        this.socket.emit("getTerm", { id: options.id });
    }.bind(this));

};

module.exports = ShareTerm;
<|endoftext|>


<commit_before>import Overlay from 'substance/packages/overlay/OverlayContainer'
import getRelativeBoundingRect from 'substance/util/getRelativeBoundingRect'

import TextToolset from './TextToolset'
import BlockToolset from './BlockToolset'

/**
 * Overlay toolsets over the current slection
 *
 * This is derived from Substance `Overlay` to implement
 * alternative positioning. Instead of using the Substance class `DefaultOverlay`
 * this class renders toolsets directly within the overlay element
 *
 * @class      Overlayer (name)
 */
class Overlayer extends Overlay {

  constructor (...args) {
    super(...args)

    /**
     * Keep track of position because this can be lost
     * when this overlay is rerendered but without `position()`
     * being called for certain documents events.
     */
    this.top = 0
    this.left = 0
  }

  render ($$) {
    var el = $$('div')
      .addClass('sc-overlay')
      .css('top', this.top + 'px')
      .css('left', this.left + 'px')
    el.append(
      $$(TextToolset).ref('textToolset'),
      $$(BlockToolset).ref('blockToolset')
    )
    return el
  }

  isVisible () {
    return true
  }

  // Override of `position()` method to determin a position for this overlay
  position (hints) {
    // Get selection rectangle so that overlay can be positioned relative to it
    // At time of writing `Surface.getBoundingRectangleForSelection` was experimental and
    // sometimes created a hints.rectangle that was an empty object (e.g. for node selections). This checks for that
    // and if necessary tries to work out it's own selection rectangle
    var selected = null
    if (hints) {
      if (hints.rectangle) {
        if (hints.rectangle.top) {
          selected = hints.rectangle
        }
      }
    }
    if (!selected) {
      var surface = this.context.surfaceManager.getFocusedSurface()
      var selection = surface.getSelection()
      if (selection) {
        if (selection.isNodeSelection()) {
          var nodeId = selection.getNodeId()
          console.warn('No selection rectangle provided for {' + nodeId + '}, attempting to get one')
          var componentEl = document.querySelector('[data-id=' + nodeId + ']')
          var containerEl = this.context.scrollPane.refs.content.el.el
          if (componentEl && containerEl) {
            selected = getRelativeBoundingRect(componentEl, containerEl)
          }
        }
      }
    }

    if (selected) {
      var overlay = {
        height: this.el.htmlProp('offsetHeight'),
        width: this.el.htmlProp('offsetWidth')
      }

      // By default, aligned top/center to the selected
      var top = selected.top - overlay.height - 3
      var left = selected.left + selected.width / 2 - overlay.width / 2
      // Must not exceed left bound
      left = Math.max(left, 0)
      // Must not exceed right bound
      var maxLeftPos = selected.left + selected.width + selected.right - overlay.width
      left = Math.min(left, maxLeftPos)

      // Change position
      this.el.css('top', top)
      this.el.css('left', left)

      // Store position for next rendering
      this.top = top
      this.left = left
    } else {
      console.warn('No selection rectangle to position overlay')
    }
  }
}

export default Overlayer
<commit_msg>Deal with Substance OverlayContainer -> Overlay<commit_after>import Overlay from 'substance/packages/overlay/Overlay'
import getRelativeBoundingRect from 'substance/util/getRelativeBoundingRect'

import TextToolset from './TextToolset'
import BlockToolset from './BlockToolset'

/**
 * Overlay toolsets over the current slection
 *
 * This is derived from Substance `Overlay` to implement
 * alternative positioning. Instead of using the Substance class `DefaultOverlay`
 * this class renders toolsets directly within the overlay element
 *
 * @class      Overlayer (name)
 */
class Overlayer extends Overlay {

  constructor (...args) {
    super(...args)

    /**
     * Keep track of position because this can be lost
     * when this overlay is rerendered but without `position()`
     * being called for certain documents events.
     */
    this.top = 0
    this.left = 0
  }

  render ($$) {
    var el = $$('div')
      .addClass('sc-overlay')
      .css('top', this.top + 'px')
      .css('left', this.left + 'px')
    el.append(
      $$(TextToolset).ref('textToolset'),
      $$(BlockToolset).ref('blockToolset')
    )
    return el
  }

  isVisible () {
    return true
  }

  // Override of `position()` method to determin a position for this overlay
  position (hints) {
    // Get selection rectangle so that overlay can be positioned relative to it
    // At time of writing `Surface.getBoundingRectangleForSelection` was experimental and
    // sometimes created a hints.rectangle that was an empty object (e.g. for node selections). This checks for that
    // and if necessary tries to work out it's own selection rectangle
    var selected = null
    if (hints) {
      if (hints.rectangle) {
        if (hints.rectangle.top) {
          selected = hints.rectangle
        }
      }
    }
    if (!selected) {
      var surface = this.context.surfaceManager.getFocusedSurface()
      var selection = surface.getSelection()
      if (selection) {
        if (selection.isNodeSelection()) {
          var nodeId = selection.getNodeId()
          console.warn('No selection rectangle provided for {' + nodeId + '}, attempting to get one')
          var componentEl = document.querySelector('[data-id=' + nodeId + ']')
          var containerEl = this.context.scrollPane.refs.content.el.el
          if (componentEl && containerEl) {
            selected = getRelativeBoundingRect(componentEl, containerEl)
          }
        }
      }
    }

    if (selected) {
      var overlay = {
        height: this.el.htmlProp('offsetHeight'),
        width: this.el.htmlProp('offsetWidth')
      }

      // By default, aligned top/center to the selected
      var top = selected.top - overlay.height - 3
      var left = selected.left + selected.width / 2 - overlay.width / 2
      // Must not exceed left bound
      left = Math.max(left, 0)
      // Must not exceed right bound
      var maxLeftPos = selected.left + selected.width + selected.right - overlay.width
      left = Math.min(left, maxLeftPos)

      // Change position
      this.el.css('top', top)
      this.el.css('left', left)

      // Store position for next rendering
      this.top = top
      this.left = left
    } else {
      console.warn('No selection rectangle to position overlay')
    }
  }
}

export default Overlayer
<|endoftext|>


<commit_before>require('../style.css');
require('jquery');
require('bootstrap-webpack');

const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const World = require('./world');
const HealthFood = require('./health-food');
const RandomHealthFood = require('./random-health-food');
const Overlord = require('./overlord');
const JunkFood = require('./junk-food');
const RandomJunkFood = require('./random-junk-food');
const Gallery = require('./gallery');
const ScoreBoard = require('./score-board');
const TrayCollision = require('./tray-collision');

var gallery;
var world;
var overlord;
var overlordImage;
var trayCollision;
// can add new game stuff into world or a renamed world (as game.js)
function makeNewGame(){
  gallery = new Gallery();
  world = new World(canvas.width, canvas.height, ctx);
  overlord = new Overlord();
  overlordImage = new Image();
  trayCollision = new TrayCollision(world.tray);
  gallery.start();
  gameRunning = true;
  canvas.style.display = 'block';
  startButton.style.display = 'none';
}

var healthFoods = [];
var junkFoods = [];
var scoreBoard = '';
var startButton = document.getElementById('start');
var reqAnimFrameID = 0;
var gameRunning = false;

// can move event listener to score-board
document.addEventListener('DOMContentLoaded', function(){
  var list = document.getElementById('high-scores');
  scoreBoard = new ScoreBoard(list);
  scoreBoard.loadStoredScores();
});

function toggleStartScreen(){
  canvas.style.display = 'none';
  startButton.style.display = 'block';
}
//game loop- can be stripped but mostly stay in index. Take out what we can to modules.
startButton.addEventListener('click', function(){
  var gameAudio = document.createElement("audio");
  gameAudio.src = "Get_Outside.mp3";
  gameAudio.play();
  gameAudio.pause();
  document.getElementById('instructions').style = "display: none";
  document.getElementById('score-title').style = "display: block";
  document.getElementById('high-scores').style = "display: block";
  document.getElementById('level').innerHTML = "
Level 1
";
  makeNewGame();
  requestAnimationFrame(function gameLoop(){
    checkGameEnders();
    beginGame();
    checkLevel();
    reqAnimFrameID = requestAnimationFrame(gameLoop);
  });
  //pull this into a function
  document.addEventListener('keydown', function(event){
    if (event.keyCode === 39) { world.rightArrow();}
    if (event.keyCode === 37) { world.leftArrow();}
  });
  window.setInterval(createHealthFood, 1500);
  increaseDifficulty(overlord, world);
});
//pull this into a level.js or game.js
function increaseDifficulty(overlord, world){
  var interval = 500;
  function oscillate(overlord, world){
    interval = interval - 2;
    if(overlord.x < 0 || overlord.x > world.width - overlord.width){
      overlord.speed = -overlord.speed;
    }
    overlord.x += overlord.speed;

    if(overlord.x%(Math.floor(Math.random() * 100)) === 0){
      createJunkFood(overlord);
    }
    if (interval >= 50){
      window.setTimeout(oscillate, interval, overlord, world);
    } else if (interval < 75){
      window.setTimeout(oscillate, 75, overlord, world);
    }
  }
  oscillate(overlord, world);
}
//pull this into level or game
function checkLevel(){
  var level = document.getElementById('level');
  if(trayCollision.total >= 200 && trayCollision.total < 400 ){
    level.innerHTML = "
Level 2
";
  } else if (trayCollision.total >= 400 && trayCollision.total < 600 ){
    level.innerHTML = "
Level 3
";
  }
}
function checkGameEnders(){
  if(trayCollision.total < 0 && gameRunning || trayCollision.total >= 600 && gameRunning || !gameRunning){
    endGame();
  }
}

// //refactor into functions but mostly stay here
function endGame(){
  if(trayCollision.total >= 600){
    addScore(trayCollision.total);
    alert("You won! Your score was " + trayCollision.total + " points.");
    document.getElementById('instructions').style = "display: block";
    document.getElementById('start-btn').style = "display: block";
    document.getElementById('score-title').style = "display: none";
    document.getElementById('high-scores').style = "display: none";
  } else if (trayCollision.total < 0){
    alert("You lost! Eat more vegetables next time to defeat the Empty Calorie Overlord.");
    document.getElementById('instructions').style = "display: block";
    document.getElementById('start-btn').style = "display: block";
    document.getElementById('score-title').style = "display: none";
    document.getElementById('high-scores').style = "display: none";
  }
  for (var i = 0; i < 1000; i++) {
    window.clearInterval(i);
  }
  healthFoods = [];
  junkFoods = [];
  trayCollision.total = 0;
  document.getElementById('score-game').innerHTML = "Score: " + trayCollision.total;
  toggleStartScreen();
  return gameRunning = false;
}
//add this to score board
function addScore(winningScore){
  if(scoreBoard.scores[0] && trayCollision.total > Math.min.apply(Math, scoreBoard.scores)){
    scoreBoard.addHighScoreToPage(winningScore);
  } else {
    scoreBoard.addHighScoreToPage(winningScore);
  }
}

function beginGame(){
  world.draw();
  overlord.draw(overlordImage, ctx);
  drawFoods(healthFoods);
  drawFoods(junkFoods);
  updateAllFoods(healthFoods);
  updateAllFoods(junkFoods);
  trayCollision.check(healthFoods, trayCollision, reqAnimFrameID);
  trayCollision.check(junkFoods, trayCollision, reqAnimFrameID);
  document.getElementById('score-game').innerHTML = "Score: " + trayCollision.total;
}

//move to master food class
function drawFoods(foods){
  for (var i = 0; i < foods.length; i++){
    foodDraw(foods[i]);
  }
}
//move to food class
function updateAllFoods(foods){
  for (var i = 0; i < foods.length; i++) {
    foods[i].move();
    if(foods[i].y > 599){
      foods.shift();
    }
  }
}
//move to health food
function createHealthFood(){
  var randomHealthFoodAttributes = new RandomHealthFood();
  var healthFood = new HealthFood(randomHealthFoodAttributes);
  healthFood.ctx = ctx;
  healthFoods.push(healthFood);
}
//move to food class
function foodDraw(food){
  var foodImage = food.type + 'Image';
  ctx.drawImage(gallery.images[foodImage], food.x, food.y, food.width, food.height);
}
//move to junk food or overlord depending (probably overlord)
function createJunkFood(overlord){
  var overlordMouth = Math.floor(overlord.x + (overlord.width/2));
  var randomJunkFoodAttributes = new RandomJunkFood(overlordMouth);
  var junkFood = new JunkFood(randomJunkFoodAttributes);
  junkFood.ctx = ctx;
  junkFoods.push(junkFood);
}
<commit_msg>breaks apart game play into more functions to be moved out of index<commit_after>require('../style.css');
require('jquery');
require('bootstrap-webpack');

const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const World = require('./world');
const HealthFood = require('./health-food');
const RandomHealthFood = require('./random-health-food');
const Overlord = require('./overlord');
const JunkFood = require('./junk-food');
const RandomJunkFood = require('./random-junk-food');
const Gallery = require('./gallery');
const ScoreBoard = require('./score-board');
const TrayCollision = require('./tray-collision');

var gallery;
var world;
var overlord;
var overlordImage;
var trayCollision;
// can add new game stuff into world or a renamed world (as game.js)
function makeNewGame(){
  gallery = new Gallery();
  world = new World(canvas.width, canvas.height, ctx);
  overlord = new Overlord();
  overlordImage = new Image();
  trayCollision = new TrayCollision(world.tray);
  gallery.start();
  gameRunning = true;
  canvas.style.display = 'block';
  startButton.style.display = 'none';
  window.setInterval(createHealthFood, 1500);
}

var healthFoods = [];
var junkFoods = [];
var scoreBoard = '';
var startButton = document.getElementById('start');
var reqAnimFrameID = 0;
var gameRunning = false;

// can move event listener to score-board
document.addEventListener('DOMContentLoaded', function(){
  var list = document.getElementById('high-scores');
  scoreBoard = new ScoreBoard(list);
  scoreBoard.loadStoredScores();
});

//game loop- can be stripped but mostly stay in index. Take out what we can to modules.
startButton.addEventListener('click', function(){
  audioOn();
  setGameStyling();
  makeNewGame();
  masterGameLoop();
  userInput();
  increaseDifficulty(overlord, world);
});

function userInput(){
  document.addEventListener('keydown', function(event){
    if (event.keyCode === 39) { world.rightArrow();}
    if (event.keyCode === 37) { world.leftArrow();}
  });
}
function masterGameLoop(){
  requestAnimationFrame(function gameLoop(){
    checkGameEnders();
    beginGame();
    checkLevel();
  reqAnimFrameID = requestAnimationFrame(gameLoop);
  });
}
  //pull this into a function

function audioOn(){
  var gameAudio = document.createElement("audio");
  gameAudio.src = "Get_Outside.mp3";
  gameAudio.play();
  gameAudio.pause();
}

function setGameStyling(){
  document.getElementById('instructions').style = "display: none";
  document.getElementById('score-title').style = "display: block";
  document.getElementById('high-scores').style = "display: block";
  document.getElementById('level').innerHTML = "
Level 1
";
}

//pull this into a level.js or game.js
function increaseDifficulty(overlord, world){
  var interval = 500;
  function oscillate(overlord, world){
    interval = interval - 2;
    if(overlord.x < 0 || overlord.x > world.width - overlord.width){
      overlord.speed = -overlord.speed;
    }
    overlord.x += overlord.speed;

    if(overlord.x%(Math.floor(Math.random() * 100)) === 0){
      createJunkFood(overlord);
    }
    if (interval >= 50){
      window.setTimeout(oscillate, interval, overlord, world);
    } else if (interval < 75){
      window.setTimeout(oscillate, 75, overlord, world);
    }
  }
  oscillate(overlord, world);
}
//pull this into level or game
function checkLevel(){
  var level = document.getElementById('level');
  if(trayCollision.total >= 200 && trayCollision.total < 400 ){
    level.innerHTML = "
Level 2
";
  } else if (trayCollision.total >= 400 && trayCollision.total < 600 ){
    level.innerHTML = "
Level 3
";
  }
}
function checkGameEnders(){
  if(trayCollision.total < 0 && gameRunning || trayCollision.total >= 600 && gameRunning || !gameRunning){
    endGame();
  }
}

// //refactor into functions but mostly stay here
function endGame(){
  if(trayCollision.total >= 600){
    addScore(trayCollision.total);
    alert("You won! Your score was " + trayCollision.total + " points.");
    endGameStyling();
  } else if (trayCollision.total < 0){
    alert("You lost! Eat more vegetables next time to defeat the Empty Calorie Overlord.");
    endGameStyling();
  }
  stopGameMovement();
  resetGame();
  document.getElementById('score-game').innerHTML = "Score: " + trayCollision.total;
  return gameRunning = false;
}

function resetGame(){
  healthFoods = [];
  junkFoods = [];
  trayCollision.total = 0;
}

function endGameStyling(){
  document.getElementById('instructions').style = "display: block";
  document.getElementById('start-btn').style = "display: block";
  document.getElementById('score-title').style = "display: none";
  document.getElementById('high-scores').style = "display: none";
  canvas.style.display = 'none';
  startButton.style.display = 'block';
}

function stopGameMovement(){
  for (var i = 0; i < 1000; i++) {
    window.clearInterval(i);
  }
}
//add this to score board
function addScore(winningScore){
  if(scoreBoard.scores[0] && trayCollision.total > Math.min.apply(Math, scoreBoard.scores)){
    scoreBoard.addHighScoreToPage(winningScore);
  } else {
    scoreBoard.addHighScoreToPage(winningScore);
  }
}

function beginGame(){
  world.draw();
  overlord.draw(overlordImage, ctx);
  drawFoods(healthFoods);
  drawFoods(junkFoods);
  updateAllFoods(healthFoods);
  updateAllFoods(junkFoods);
  trayCollision.check(healthFoods, trayCollision, reqAnimFrameID);
  trayCollision.check(junkFoods, trayCollision, reqAnimFrameID);
  document.getElementById('score-game').innerHTML = "Score: " + trayCollision.total;
}

//move to master food class
function drawFoods(foods){
  for (var i = 0; i < foods.length; i++){
    foodDraw(foods[i]);
  }
}
//move to food class
function updateAllFoods(foods){
  for (var i = 0; i < foods.length; i++) {
    foods[i].move();
    if(foods[i].y > 599){
      foods.shift();
    }
  }
}
//move to health food
function createHealthFood(){
  var randomHealthFoodAttributes = new RandomHealthFood();
  var healthFood = new HealthFood(randomHealthFoodAttributes);
  healthFood.ctx = ctx;
  healthFoods.push(healthFood);
}
//move to food class
function foodDraw(food){
  var foodImage = food.type + 'Image';
  ctx.drawImage(gallery.images[foodImage], food.x, food.y, food.width, food.height);
}
//move to junk food or overlord depending (probably overlord)
function createJunkFood(overlord){
  var overlordMouth = Math.floor(overlord.x + (overlord.width/2));
  var randomJunkFoodAttributes = new RandomJunkFood(overlordMouth);
  var junkFood = new JunkFood(randomJunkFoodAttributes);
  junkFood.ctx = ctx;
  junkFoods.push(junkFood);
}
<|endoftext|>


<commit_before>import { green, yellow, red } from 'chalk';

import buildDocumentationObject, { sortOnProperty } from '../buildDocumentationObject';
import generateTable from '../generateTable';
import getDefaultValue from '../helpers/getDefaultValue';

/**
 * Generates plain text documentation for the provided configuration object.
 *
 * @param {rocConfig} config - The configuration object to generate documentation for.
 * @param {rocMetaConfig} metaConfig - The meta configuration object that has information about the config object.
 * @param {string[]} [filter=[]] - The groups that should be includes, by default all will be used.
 *
 * @returns {string} - A table as a string.
 */
export default function settingsToText({ settings }, { settings: meta }, filter = []) {
    const documentationObject = sortOnProperty('name', buildDocumentationObject(settings, meta, filter));

    const header = {
        description: {
            name: 'Description',
            renderer: (input) => {
                if (input && input.length > 100) {
                    return `${input.substr(0, 100)}…`;
                }

                if (input) {
                    return input;
                }

                return undefined;
            },
        },
        path: {
            name: 'Path',
        },
        defaultValue: {
            name: 'Default',
            renderer: (input) => {
                const defaultValue = getDefaultValue(input);
                if (!defaultValue) {
                    return yellow('No default value');
                }
                return defaultValue;
            },
        },
        cli: {
            name: 'CLI option',
        },
        required: {
            name: 'Required',
            renderer: (input) => {
                if (input === true) {
                    return green('Yes');
                }
                return red('No');
            },
        },
        canBeEmpty: {
            name: 'Can be empty',
            renderer: (input) => {
                if (input === true) {
                    return green('Yes');
                } else if (input === false) {
                    return red('No');
                }

                return '';
            },
        },
    };

    const text = generateTable(documentationObject, header, {
        groupTitleWrapper: (name, level, parentNames) => parentNames.concat(name).join(' > '),
    });

    if (text.length === 0) {
        return 'No settings available.';
    }

    return text;
}
<commit_msg>Made sure that we do not truncate a description of 101 characters<commit_after>import { green, yellow, red } from 'chalk';

import buildDocumentationObject, { sortOnProperty } from '../buildDocumentationObject';
import generateTable from '../generateTable';
import getDefaultValue from '../helpers/getDefaultValue';

/**
 * Generates plain text documentation for the provided configuration object.
 *
 * @param {rocConfig} config - The configuration object to generate documentation for.
 * @param {rocMetaConfig} metaConfig - The meta configuration object that has information about the config object.
 * @param {string[]} [filter=[]] - The groups that should be includes, by default all will be used.
 *
 * @returns {string} - A table as a string.
 */
export default function settingsToText({ settings }, { settings: meta }, filter = []) {
    const documentationObject = sortOnProperty('name', buildDocumentationObject(settings, meta, filter));

    const header = {
        description: {
            name: 'Description',
            renderer: (input) => {
                if (input && input.length > 101) {
                    return `${input.substr(0, 100)}…`;
                }

                if (input) {
                    return input;
                }

                return undefined;
            },
        },
        path: {
            name: 'Path',
        },
        defaultValue: {
            name: 'Default',
            renderer: (input) => {
                const defaultValue = getDefaultValue(input);
                if (!defaultValue) {
                    return yellow('No default value');
                }
                return defaultValue;
            },
        },
        cli: {
            name: 'CLI option',
        },
        required: {
            name: 'Required',
            renderer: (input) => {
                if (input === true) {
                    return green('Yes');
                }
                return red('No');
            },
        },
        canBeEmpty: {
            name: 'Can be empty',
            renderer: (input) => {
                if (input === true) {
                    return green('Yes');
                } else if (input === false) {
                    return red('No');
                }

                return '';
            },
        },
    };

    const text = generateTable(documentationObject, header, {
        groupTitleWrapper: (name, level, parentNames) => parentNames.concat(name).join(' > '),
    });

    if (text.length === 0) {
        return 'No settings available.';
    }

    return text;
}
<|endoftext|>


<commit_before>import React from 'react';
import FlexView from '../flex/FlexView';

/**
 * ### Creates a full-page dimmed background for its children nodes
 */
export default class BackgroundDimmer extends React.Component {

  static propTypes = {
    /**
     * children nodes/elements
     */
    children: React.PropTypes.node.isRequired,
    /**
     * background-color
     */
    color: React.PropTypes.string,
    /**
     * opacity
     */
    alpha: React.PropTypes.number,
    /**
     * z-index (BackgroundDimmer has `position: fixed`)
     */
    zIndex: React.PropTypes.number,
    /**
     * avoid propagation for scroll events
     */
    stopScrollPropagation: React.PropTypes.bool,
    /**
     * called when user clicks outside children
     */
    onClickOutside: React.PropTypes.func,
    className: React.PropTypes.string,
    id: React.PropTypes.string,
    style: React.PropTypes.object
  }

  static defaultProps = {
    color: 'black',
    alpha: 0.5,
    zIndex: 99999
  }

  componentDidMount() {
    if (this.props.stopScrollPropagation) {
      this.disableScrollPropagation();
    }
  }

  enableScrollPropagation = () => {
    const dimmedBackground = React.findDOMNode(this.refs.dimmedBackground);
    const childrenWrapper = React.findDOMNode(this.refs.childrenWrapper);
    dimmedBackground.removeEventListener('wheel', this.stopScrollPropagation);
    dimmedBackground.removeEventListener('touchmove', this.stopScrollPropagation);
    childrenWrapper.removeEventListener('wheel', this.preventDefault);
    childrenWrapper.removeEventListener('touchmove', this.preventDefault);
  }

  disableScrollPropagation = () => {
    const dimmedBackground = React.findDOMNode(this.refs.dimmedBackground);
    const childrenWrapper = React.findDOMNode(this.refs.childrenWrapper);
    dimmedBackground.addEventListener('wheel', this.stopScrollPropagation);
    dimmedBackground.addEventListener('touchmove', this.stopScrollPropagation);
    childrenWrapper.addEventListener('wheel', this.preventDefault);
    childrenWrapper.addEventListener('touchmove', this.preventDefault);
  }

  isEventOutsideChildren = (e) => {
    const el = e.target || e.srcElement;
    return el === React.findDOMNode(this.refs.dimmedBackground);
  }

  onClick = (e) => {
    const { onClickOutside } = this.props;
    if (onClickOutside && this.isEventOutsideChildren(e)) {
      onClickOutside(e);
    }
  }

  preventDefault = (e) => e.preventDefault()

  stopScrollPropagation = (e) => {
    const { stopScrollPropagation } = this.props;
    if (stopScrollPropagation && this.isEventOutsideChildren(e)) {
      this.preventDefault(e);
    }
  }

  getDimmedBackground = () => {
    const { color, alpha, zIndex } = this.props;
    const style = {
      position: 'fixed',
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      backgroundColor: color,
      opacity: String(alpha),
      zIndex
    };
    return
;
  }

  render() {
    const { style, className, id, children, zIndex } = this.props;
    const props = {
      style: { position: 'relative', ...style },
      className,
      id
    };
    const flexViewProps = {
      style: {
        position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, zIndex: (zIndex + 1), pointerEvents: 'none'
      },
      vAlignContent: 'center',
      hAlignContent: 'center'
    };
    const childrenWrapperProps = {
      style: { pointerEvents: 'auto' },
      ref: 'childrenWrapper'
    };

    return (

        {this.getDimmedBackground()}
        <FlexView {...flexViewProps}>

            {children}

        </FlexView>

    );
  }

  componentWillReceiveProps(nextProps) {
    if (!nextProps.stopScrollPropagation && this.props.stopScrollPropagation) {
      this.enableScrollPropagation();
    } else if (nextProps.stopScrollPropagation && !this.props.stopScrollPropagation) {
      this.disableScrollPropagation();
    }
  }

  componentWillUnmount() {
    if (this.props.stopScrollPropagation) {
      this.enableScrollPropagation();
    }
  }

}
<commit_msg>update BackgroundDimmer<commit_after>import React from 'react';
import { props, t } from '../utils';
import FlexView from '../flex/FlexView';

/**
 * ### Creates a full-page dimmed background for its children nodes
 */
@props({
  /**
   * children nodes/elements
   */
  children: t.ReactNode,
  /**
   * background-color
   */
  color: t.maybe(t.String),
  /**
   * opacity
   */
  alpha: t.maybe(t.Number),
  /**
   * z-index (BackgroundDimmer has `position: fixed`)
   */
  zIndex: t.maybe(t.Number),
  /**
   * avoid propagation for scroll events
   */
  stopScrollPropagation: t.maybe(t.Boolean),
  /**
   * called when user clicks outside children
   */
  onClickOutside: t.maybe(t.Function),
  className: t.maybe(t.String),
  id: t.maybe(t.String),
  style: t.maybe(t.Object)
})
export default class BackgroundDimmer extends React.Component {

  static defaultProps = {
    color: 'black',
    alpha: 0.5,
    zIndex: 99999
  }

  componentDidMount() {
    if (this.props.stopScrollPropagation) {
      this.disableScrollPropagation();
    }
  }

  enableScrollPropagation = () => {
    const dimmedBackground = React.findDOMNode(this.refs.dimmedBackground);
    const childrenWrapper = React.findDOMNode(this.refs.childrenWrapper);
    dimmedBackground.removeEventListener('wheel', this.stopScrollPropagation);
    dimmedBackground.removeEventListener('touchmove', this.stopScrollPropagation);
    childrenWrapper.removeEventListener('wheel', this.preventDefault);
    childrenWrapper.removeEventListener('touchmove', this.preventDefault);
  }

  disableScrollPropagation = () => {
    const dimmedBackground = React.findDOMNode(this.refs.dimmedBackground);
    const childrenWrapper = React.findDOMNode(this.refs.childrenWrapper);
    dimmedBackground.addEventListener('wheel', this.stopScrollPropagation);
    dimmedBackground.addEventListener('touchmove', this.stopScrollPropagation);
    childrenWrapper.addEventListener('wheel', this.preventDefault);
    childrenWrapper.addEventListener('touchmove', this.preventDefault);
  }

  isEventOutsideChildren = (e) => {
    const el = e.target || e.srcElement;
    return el === React.findDOMNode(this.refs.dimmedBackground);
  }

  onClick = (e) => {
    const { onClickOutside } = this.props;
    if (onClickOutside && this.isEventOutsideChildren(e)) {
      onClickOutside(e);
    }
  }

  preventDefault = (e) => e.preventDefault()

  stopScrollPropagation = (e) => {
    const { stopScrollPropagation } = this.props;
    if (stopScrollPropagation && this.isEventOutsideChildren(e)) {
      this.preventDefault(e);
    }
  }

  getDimmedBackground = () => {
    const { color, alpha, zIndex } = this.props;
    const style = {
      position: 'fixed',
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      backgroundColor: color,
      opacity: String(alpha),
      zIndex
    };
    return
;
  }

  render() {
    const { style, className, id, children, zIndex } = this.props;
    const props = {
      style: { position: 'relative', ...style },
      className,
      id
    };
    const flexViewProps = {
      style: {
        position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, zIndex: (zIndex + 1), pointerEvents: 'none'
      },
      vAlignContent: 'center',
      hAlignContent: 'center'
    };
    const childrenWrapperProps = {
      style: { pointerEvents: 'auto' },
      ref: 'childrenWrapper'
    };

    return (

        {this.getDimmedBackground()}
        <FlexView {...flexViewProps}>

            {children}

        </FlexView>

    );
  }

  componentWillReceiveProps(nextProps) {
    if (!nextProps.stopScrollPropagation && this.props.stopScrollPropagation) {
      this.enableScrollPropagation();
    } else if (nextProps.stopScrollPropagation && !this.props.stopScrollPropagation) {
      this.disableScrollPropagation();
    }
  }

  componentWillUnmount() {
    if (this.props.stopScrollPropagation) {
      this.enableScrollPropagation();
    }
  }

}
<|endoftext|>