<commit_before>'use strict';
var core = require("../soajs.core");
var Mongo = require("../soajs.mongo");
var async = require("async");
var mongo;

var config = require("./config");
function generateError(errorCode) {
	var error = new Error();
	error.code = errorCode;
	error.message = config.errors[errorCode];
	return error;
}

function ContentBuilder(config, callback) {

	if(!config.name) {
		return callback(generateError(190));
	}

	if(!config.version || typeof(config.version) !== 'number') {
		return callback(generateError(191));
	}

	core.registry.profile(function(registry) {
		if(!registry) {
			return callback(generateError(192));
		}

		//connect to mongo
		mongo = new Mongo(registry.coreDB.provision);

		//get the gc schema
		mongo.findOne("gc", {"name": config.name, "v": config.version}, function(error, Schema) {
			if(error) { return callback(error); }

			mongo.find("hosts",{"name": config.name},function(error, hosts){
				if(error){ return callback(error); }

				Schema.hosts = hosts;

				var envs = Object.keys(Schema.soajsService.db.config);
				async.mapLimit(envs, envs.length, addDbinEnv, function(error) {
					if(error){ return callback(error); }
					return callback(null, Schema);
				});
			});

			function addDbinEnv(envCode, cb) {
				var dbName = Object.keys(Schema.soajsService.db.config[envCode])[0];
				var updateOptions = {
					'$set': {}
				};
				updateOptions['$set']["dbs.databases." + dbName] = Schema.soajsService.db.config[envCode][dbName];
				mongo.update("environment", {"code": envCode}, updateOptions, {"safe": true}, cb);
			}
		});

	});
}

module.exports = ContentBuilder;<commit_msg>added extra assurance when loading contentbuilder schema.<commit_after>'use strict';
var core = require("../soajs.core");
var Mongo = require("../soajs.mongo");
var async = require("async");
var mongo;

var config = require("./config");
function generateError(errorCode) {
	var error = new Error();
	error.code = errorCode;
	error.message = config.errors[errorCode];
	return error;
}

function ContentBuilder(config, callback) {

	if(!config.name) {
		return callback(generateError(190));
	}

	if(!config.version || typeof(config.version) !== 'number') {
		return callback(generateError(191));
	}

	core.registry.profile(function(registry) {
		if(!registry) {
			return callback(generateError(192));
		}

		//connect to mongo
		mongo = new Mongo(registry.coreDB.provision);

		//get the gc schema
		mongo.findOne("gc", {"name": config.name, "v": config.version}, function(error, Schema) {
			if(error || !Schema) { return callback(error); }

			mongo.find("hosts",{"name": config.name},function(error, hosts){
				if(error || !hosts){ return callback(error); }

				Schema.hosts = hosts;

				var envs = Object.keys(Schema.soajsService.db.config);
				async.mapLimit(envs, envs.length, addDbinEnv, function(error) {
					if(error){ return callback(error); }
					return callback(null, Schema);
				});
			});

			function addDbinEnv(envCode, cb) {
				var dbName = Object.keys(Schema.soajsService.db.config[envCode])[0];
				var updateOptions = {
					'$set': {}
				};
				updateOptions['$set']["dbs.databases." + dbName] = Schema.soajsService.db.config[envCode][dbName];
				mongo.update("environment", {"code": envCode}, updateOptions, {"safe": true}, cb);
			}
		});

	});
}

module.exports = ContentBuilder;<|endoftext|>


<commit_before>(function(){

  function ParameterMissing(message) {
   this.message = message;
  }
  ParameterMissing.prototype = new Error();

  var defaults = {
    prefix: 'PREFIX',
    format: 'DEFAULT_FORMAT'
  };

  var NodeTypes = NODE_TYPES

  var Utils = {

    serialize: function(obj){
      if (!obj) {return '';}
      if (window.jQuery) {
        var result = window.jQuery.param(obj);
        return !result ? "" : "?" + result
      }
      var s = [];
      for (prop in obj){
        if (obj[prop]) {
          if (obj[prop] instanceof Array) {
            for (var i=0; i < obj[prop].length; i++) {
              key = prop + encodeURIComponent("[]");
              s.push(key + "=" + encodeURIComponent(obj[prop][i].toString()));
            }
          } else {
            s.push(prop + "=" + encodeURIComponent(obj[prop].toString()));
          }
        }
      }
      if (s.length === 0) {
        return '';
      }
      return "?" + s.join('&');
    },

    clean_path: function(path) {
      path = path.split("://");
      var last_index = path.length - 1;
      path[last_index] = path[last_index].replace(/\/+/g, "/").replace(/\/$/m, '');
      return path.join("://");
    },

    set_default_format: function(options) {
      if (!options.hasOwnProperty("format") && defaults.format) options.format = defaults.format;
    },

    extract_anchor: function(options) {
      var anchor = options.hasOwnProperty("anchor") ? options.anchor : null;
      delete options.anchor;
      return anchor ? "#" + anchor : "";
    },

    extract_options: function(number_of_params, args) {
      if (args.length > number_of_params) {
        return typeof(args[args.length-1]) == "object" ?  args.pop() : {};
      } else {
        return {};
      }
    },

    path_identifier: function(object) {
      if (object === 0) {
	return '0';
      }

      if (! object) { // null, undefined, false or ''
	return '';
      }

      if (typeof(object) == "object") {
        var property = object.to_param || object.id || object;
        if (typeof(property) == "function") {
          property = property.call(object)
        }
        return property.toString();
      } else {
        return object.toString();
      }
    },

    clone: function (obj) {
      if (null == obj || "object" != typeof obj) return obj;
      var copy = obj.constructor();
      for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
      }
      return copy;
    },

    prepare_parameters: function(required_parameters, actual_parameters, options) {
      var result = this.clone(options) || {};
      for (var i=0; i < required_parameters.length; i++) {
        result[required_parameters[i]] = actual_parameters[i];
      }
      return result;
    },

    smartIndexOf: function(array, item){
      if (Array.prototype.indexOf && array.indexOf === Array.prototype.indexOf) return array.indexOf(item);
      for (var i = 0; i < array.length; i++) if (i in array && array[i] === item) return i;
      return -1;
    },

    build_path: function(required_parameters, optional_parts, route, args) {
      args = Array.prototype.slice.call(args);
      var opts = this.extract_options(required_parameters.length, args);
      if (args.length > required_parameters.length) {
        throw new Error("Too many parameters provided for path");
      }

      var parameters = this.prepare_parameters(required_parameters, args, opts);
      // Array#indexOf is not supported by IE <= 8, so we use custom method
      if (Utils.smartIndexOf(optional_parts, 'format') !== -1) {
        this.set_default_format(parameters);
      }
      var result = Utils.get_prefix();
      var anchor = Utils.extract_anchor(parameters);

      result += this.visit(route, parameters)
      return Utils.clean_path(result + anchor) + Utils.serialize(parameters);
    },

    /*
     * This function is JavaScript impelementation of the
     * Journey::Visitors::Formatter that builds route by given parameters
     * and parsed route binary tree.
     * Binary tree is serialized in the following way:
     * [node type, left node, right node ]
     *
     *@param  {Boolean} optional  Marks the currently visited branch as optional. If set to `true`, this method will not throw when encountering a missing parameter (used in recursive calls).
     */
    visit: function(route, options, optional) {
      var type = route[0];
      var left = route[1];
      var right = route[2];
      switch (type) {
        case NodeTypes.GROUP:
          return this.visit(left, options, true)
        case NodeTypes.STAR:
          return this.visit(left, options, true)
        case NodeTypes.CAT:
          var leftPart = this.visit(left, options, optional),
              rightPart = this.visit(right, options, optional);

          if (optional && ! (leftPart && rightPart))
            return '';

          return leftPart + rightPart;
        case NodeTypes.LITERAL:
          return left;
        case NodeTypes.SLASH:
          return left;
        case NodeTypes.DOT:
          return left;
        case NodeTypes.SYMBOL:
          var value = options[left];

          if (value || value === 0) {
            delete options[left];
            return this.path_identifier(value);
          }

          if (optional) {
            return '';  // missing parameter
          } else {
            throw new ParameterMissing("Route parameter missing: " + left);
          }
        /*
         * I don't know what is this node type
         * Please send your PR if you do
         */
        //case NodeTypes.OR:
        default:
          throw new Error("Unknown Rails node type");
      }
    },

    get_prefix: function(){
      var prefix = defaults.prefix;

      if( prefix !== "" ){
        prefix = prefix.match('\/$') ? prefix : ( prefix + '/');
      }

      return prefix;
    },

    namespace: function (root, namespaceString) {
        var parts = namespaceString ? namespaceString.split('.') : [];
        if (parts.length > 0) {
            current = parts.shift();
            root[current] = root[current] || {};
            Utils.namespace(root[current], parts.join('.'));
        }
    }
  };

  Utils.namespace(window, 'NAMESPACE');
  window.NAMESPACE = ROUTES;
  window.NAMESPACE.options = defaults;
})();
<commit_msg>Improve code comments<commit_after>(function(){

  function ParameterMissing(message) {
   this.message = message;
  }
  ParameterMissing.prototype = new Error();

  var defaults = {
    prefix: 'PREFIX',
    format: 'DEFAULT_FORMAT'
  };

  var NodeTypes = NODE_TYPES

  var Utils = {

    serialize: function(obj){
      if (!obj) {return '';}
      if (window.jQuery) {
        var result = window.jQuery.param(obj);
        return !result ? "" : "?" + result
      }
      var s = [];
      for (prop in obj){
        if (obj[prop]) {
          if (obj[prop] instanceof Array) {
            for (var i=0; i < obj[prop].length; i++) {
              key = prop + encodeURIComponent("[]");
              s.push(key + "=" + encodeURIComponent(obj[prop][i].toString()));
            }
          } else {
            s.push(prop + "=" + encodeURIComponent(obj[prop].toString()));
          }
        }
      }
      if (s.length === 0) {
        return '';
      }
      return "?" + s.join('&');
    },

    clean_path: function(path) {
      path = path.split("://");
      var last_index = path.length - 1;
      path[last_index] = path[last_index].replace(/\/+/g, "/").replace(/\/$/m, '');
      return path.join("://");
    },

    set_default_format: function(options) {
      if (!options.hasOwnProperty("format") && defaults.format) options.format = defaults.format;
    },

    extract_anchor: function(options) {
      var anchor = options.hasOwnProperty("anchor") ? options.anchor : null;
      delete options.anchor;
      return anchor ? "#" + anchor : "";
    },

    extract_options: function(number_of_params, args) {
      if (args.length > number_of_params) {
        return typeof(args[args.length-1]) == "object" ?  args.pop() : {};
      } else {
        return {};
      }
    },

    path_identifier: function(object) {
      if (object === 0) {
	return '0';
      }

      if (! object) { // null, undefined, false or ''
	return '';
      }

      if (typeof(object) == "object") {
        var property = object.to_param || object.id || object;
        if (typeof(property) == "function") {
          property = property.call(object)
        }
        return property.toString();
      } else {
        return object.toString();
      }
    },

    clone: function (obj) {
      if (null == obj || "object" != typeof obj) return obj;
      var copy = obj.constructor();
      for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
      }
      return copy;
    },

    prepare_parameters: function(required_parameters, actual_parameters, options) {
      var result = this.clone(options) || {};
      for (var i=0; i < required_parameters.length; i++) {
        result[required_parameters[i]] = actual_parameters[i];
      }
      return result;
    },

    smartIndexOf: function(array, item){
      if (Array.prototype.indexOf && array.indexOf === Array.prototype.indexOf) return array.indexOf(item);
      for (var i = 0; i < array.length; i++) if (i in array && array[i] === item) return i;
      return -1;
    },

    build_path: function(required_parameters, optional_parts, route, args) {
      args = Array.prototype.slice.call(args);
      var opts = this.extract_options(required_parameters.length, args);
      if (args.length > required_parameters.length) {
        throw new Error("Too many parameters provided for path");
      }

      var parameters = this.prepare_parameters(required_parameters, args, opts);
      // Array#indexOf is not supported by IE <= 8, so we use custom method
      if (Utils.smartIndexOf(optional_parts, 'format') !== -1) {
        this.set_default_format(parameters);
      }
      var result = Utils.get_prefix();
      var anchor = Utils.extract_anchor(parameters);

      result += this.visit(route, parameters)
      return Utils.clean_path(result + anchor) + Utils.serialize(parameters);
    },

    /*
     * This function is JavaScript impelementation of the
     * Journey::Visitors::Formatter that builds route by given parameters
     * from route binary tree.
     * Binary tree is serialized in the following way:
     * [node type, left node, right node ]
     *
     * @param  {Boolean} optional  Marks the currently visited branch as optional.
     *   If set to `true`, this method will not throw when encountering
     *   a missing parameter (used in recursive calls).
     */
    visit: function(route, options, optional) {
      var type = route[0];
      var left = route[1];
      var right = route[2];
      switch (type) {
        case NodeTypes.GROUP:
          return this.visit(left, options, true)
        case NodeTypes.STAR:
          return this.visit(left, options, true)
        case NodeTypes.CAT:
          var leftPart = this.visit(left, options, optional),
              rightPart = this.visit(right, options, optional);

          if (optional && ! (leftPart && rightPart))
            return '';

          return leftPart + rightPart;
        case NodeTypes.LITERAL:
          return left;
        case NodeTypes.SLASH:
          return left;
        case NodeTypes.DOT:
          return left;
        case NodeTypes.SYMBOL:
          var value = options[left];

          if (value || value === 0) {
            delete options[left];
            return this.path_identifier(value);
          }

          if (optional) {
            return '';  // missing parameter
          } else {
            throw new ParameterMissing("Route parameter missing: " + left);
          }
        /*
         * I don't know what is this node type
         * Please send your PR if you do
         */
        //case NodeTypes.OR:
        default:
          throw new Error("Unknown Rails node type");
      }
    },

    get_prefix: function(){
      var prefix = defaults.prefix;

      if( prefix !== "" ){
        prefix = prefix.match('\/$') ? prefix : ( prefix + '/');
      }

      return prefix;
    },

    namespace: function (root, namespaceString) {
        var parts = namespaceString ? namespaceString.split('.') : [];
        if (parts.length > 0) {
            current = parts.shift();
            root[current] = root[current] || {};
            Utils.namespace(root[current], parts.join('.'));
        }
    }
  };

  Utils.namespace(window, 'NAMESPACE');
  window.NAMESPACE = ROUTES;
  window.NAMESPACE.options = defaults;
})();
<|endoftext|>


<commit_before>/* @flow */

export default {
  root: {
    margin: 0,
    position: 'relative',
    display: 'block',
  },
  removeButton: {
    backgroundColor: '#FB4F4F',
    color: 'white',
    margin: 0,
    padding: '0.5em',
    border: 'none',
    borderRadius: '50%',
    lineHeight: '0.75em',
    position: 'absolute',
    fontSize: '0.75em',
    marginLeft: '-0.825em',
    marginTop: '-0.825em',
  },
};
<commit_msg>improve remove button styling<commit_after>/* @flow */

export default {
  root: {
    margin: 0,
    position: 'relative',
    display: 'block',
  },
  removeButton: {
    backgroundColor: '#D6D6D6',
    color: 'white',
    margin: 0,
    padding: '0.5em',
    border: 'none',
    borderRadius: '50%',
    lineHeight: '0.75em',
    position: 'absolute',
    fontSize: '0.62em',
    marginLeft: '-0.825em',
    marginTop: '-0.825em',
  },
};
<|endoftext|>


<commit_before>'use strict';

import React from 'react';
import Snackbar from 'material-ui/Snackbar';
import Swipeable from 'react-swipeable';

require('styles//IframeLocker.scss');

class IframeLockerComponent extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      open: false
    }
  }

  handleTouchTap = () => {
    this.setState({
      open: true
    })
  }

  handleRequestClose = () => {
    this.setState({
      open: false
    })
  }

  render() {
    return (
    <Swipeable className="iframelocker-component"
      onSwipedRight={this.props.next}
      onSwipedLeft={this.props.prev}
      preventDefaultTouchmoveEvent={true}>
      <div
        onTouchTap={this.handleTouchTap}
      >
        <Snackbar
          open={this.state.open}
          message="This app runs in read only mode! You cannot interact with the websites that are shown!"
          autoHideDuration={6000}
          onRequestClose={this.handleRequestClose}
        />
      </div>
    </Swipeable>
    );
  }
}

IframeLockerComponent.displayName = 'IframeLockerComponent';
IframeLockerComponent.propTypes = {
  next: React.PropTypes.func.isRequired,
  prev: React.PropTypes.func.isRequired
};

export default IframeLockerComponent;
<commit_msg>Fixes the trigger of the iframe ocker snackbar<commit_after>'use strict';

import React from 'react';
import Snackbar from 'material-ui/Snackbar';
import Swipeable from 'react-swipeable';

require('styles//IframeLocker.scss');

class IframeLockerComponent extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      open: false
    }
  }

  handleTouchTap = () => {
    this.setState({
      open: true
    })
  }

  handleRequestClose = () => {
    this.setState({
      open: false
    })
  }

  render() {
    return (
    <Swipeable className="iframelocker-component"
      onSwipedRight={this.props.next}
      onSwipedLeft={this.props.prev}
      preventDefaultTouchmoveEvent={true}
      onTouchTap={this.handleTouchTap}
     >
        <Snackbar
          open={this.state.open}
          message="This app runs in read only mode! You cannot interact with the websites that are shown!"
          autoHideDuration={6000}
          onRequestClose={this.handleRequestClose}
        />
    </Swipeable>
    );
  }
}

IframeLockerComponent.displayName = 'IframeLockerComponent';
IframeLockerComponent.propTypes = {
  next: React.PropTypes.func.isRequired,
  prev: React.PropTypes.func.isRequired
};

export default IframeLockerComponent;
<|endoftext|>


<commit_before>//
// lib/runner.js
//
// Copyright (c) 2012 Lee Olayvar <leeolayvar@gmail.com>
// MIT Licensed
//
/*jshint asi: true, laxcomma: true*/
var utils = require('./utils')

// (fn) -> object
//
// Params:
//  fn: The function this runner will.. run.
//
// Returns:
//  A new instance of a runner.
//
// Desc:
//  Create a runner instance.
exports.create = function (fn, timeout) {
  var runner = {}

  utils.merge(runner, proto)
  runner.init(fn)
  return runner
}

// The 'prototype' for our object
var proto = exports.proto = {}

// (fn) -> undefined
//
// Params:
//  fn: The function this runner instance will run.
//
// Desc:
//  Initialize the data for this object instance.
proto.init = function (fn) {
  // The function this object will eventually run.
  this.fn = fn

  // An informative var. If function has defined the async 1st argument
  // callback, this will be true. Otherwise it will be false.
  this.sync = fn.length !== 1 ? true : false
}

// (callback) -> undefined
//
// Params:
//  callback: A callback which will called upon completion of this test. It
//    will be given a report object filled with information from the test.
//
// Desc:
//  Run this runner.
proto.run = function (callback) {
}<commit_msg>Added the contents of the run method.<commit_after>//
// lib/runner.js
//
// Copyright (c) 2012 Lee Olayvar <leeolayvar@gmail.com>
// MIT Licensed
//
/*jshint asi: true, laxcomma: true*/
var utils = require('./utils')

// (fn) -> object
//
// Params:
//  fn: The function this runner will.. run.
//
// Returns:
//  A new instance of a runner.
//
// Desc:
//  Create a runner instance.
exports.create = function (fn, timeout) {
  var runner = {}

  utils.merge(runner, proto)
  runner.init(fn)
  return runner
}

// The 'prototype' for our object
var proto = exports.proto = {}

// (fn) -> undefined
//
// Params:
//  fn: The function this runner instance will run.
//
// Desc:
//  Initialize the data for this object instance.
proto.init = function (fn) {
  // The function this object will eventually run.
  this._fn = fn

  // An informative var. If function has defined the async 1st argument
  // callback, this will be true. Otherwise it will be false.
  this.sync = fn.length !== 1 ? true : false
}

// (callback) -> undefined
//
// Params:
//  callback: A callback which will called upon completion of this test. It
//    will be given a report object filled with information from the test.
//
// Desc:
//  Run this runner.
proto.run = function (callback) {
  var self = this

  // If the fn was not given, callback and return immediately.
  if (this._fn === undefined) {
    callback({
        'description': this.description
      , 'success': true
    })
    return undefined
  }

  // Our `this._fn` callback
  var done = function () {
    callback({
        'description': this.description
      , 'success': true
    })
  }

  try {
    this._fn(done)
  } catch (error) {
    callback({
        'description': this.description
      , 'error': error
      , 'stack': error.stack
      , 'success': false
    })
    return undefined
  }

  // This is commented out because for now, we are not supporting Async in
  // these tests yet.
  //if (this.fn.length === 0)
  done()
}<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';

import {List, ListItem} from 'material-ui/List';
import {lightGreen500} from 'material-ui/styles/colors';
import IconButton from 'material-ui/IconButton';
import ContentAddBox from 'material-ui/svg-icons/content/add-box';
import {Toolbar, ToolbarGroup, ToolbarSeparator, ToolbarTitle} from 'material-ui/Toolbar'
import AutoComplete from 'material-ui/AutoComplete';

import s from './ModuleList.css';

class ModuleList extends Component {

    handleUpdateInput = (value) => {
        this.setState({
          dataSource: [
            value,
            value + value,
            value + value + value,
          ],
        });
     };

    render() {
        const rightIconButton = (
            <IconButton><ContentAddBox color={lightGreen500} /></IconButton>
        );

        var listItems = this.props.modules.map(function(module, i) {
            return (
                <ListItem
                key={i}
                primaryText={module.code + i}
                secondaryText={module.name}
                rightIconButton={rightIconButton}
                />
            );
        });

        return (

                    <AutoComplete
                      hintText="Search for modules..."
                      dataSource={this.props.modules}
                      onUpdateInput={this.handleUpdateInput}
                      floatingLabelText="Module Search"
                      fullWidth={true}
                    />

                <List style={{position: 'fixed', width: '100%', height: '80%', overflow: 'scroll'}}>
                    {listItems}
                </List>

        );
    }
}

export default withStyles(s)(ModuleList);
<commit_msg>Add dialog to show module info<commit_after>import React, { Component, PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';

import {List, ListItem} from 'material-ui/List';
import {lightGreen500} from 'material-ui/styles/colors';
import IconButton from 'material-ui/IconButton';
import ContentAddBox from 'material-ui/svg-icons/content/add-box';
import {Toolbar, ToolbarGroup, ToolbarSeparator, ToolbarTitle} from 'material-ui/Toolbar'
import AutoComplete from 'material-ui/AutoComplete';
import Dialog from 'material-ui/Dialog';
import FlatButton from 'material-ui/FlatButton';

import s from './ModuleList.css';

class ModuleList extends Component {
    constructor(props) {
        super(props);

        this.state = {
            open: false,
        };
    }

    handleOpen = (module) => {
        var title = module.code + ' ' + module.name;
        this.setState({open: true, dialogTitle: title});
    };

    handleClose = () => {
        this.setState({open: false});
    };

    handleListButtonTouch = (module, e) => {
        e.stopPropagation();
        // TODO handle list button touch
    };

    handleUpdateInput = (value) => {
        this.setState({
          dataSource: [
            value,
            value + value,
            value + value + value,
          ],
        });
     };

    render() {
        // Actions shown on the dialog
        const actions = [
            <FlatButton
            label="Add to Timetable"
            primary={true}
            onTouchTap={this.handleClose}
            />,
        ];

        // Create the list of module cells
        var listItems = this.props.modules.map(function(module, i) {
            return (
                <ListItem
                key={i}
                primaryText={module.code + i}
                secondaryText={module.name}
                rightIconButton={
                    <IconButton onClick={(e) => this.handleListButtonTouch(module, e)}>
                        <ContentAddBox color={lightGreen500} />
                    </IconButton>
                }
                onClick={() => this.handleOpen(module)}
                />
            );
        }, this);

        return (

                    <AutoComplete
                      hintText="Search for modules..."
                      dataSource={this.props.modules}
                      onUpdateInput={this.handleUpdateInput}
                      floatingLabelText="Module Search"
                      fullWidth={true}
                    />

                <List style={{position: 'fixed', width: '100%', height: '80%', overflow: 'scroll'}}>
                    {listItems}
                </List>
                <Dialog
                  title={this.state.dialogTitle}
                  actions={actions}
                  modal={false}
                  open={this.state.open}
                  onRequestClose={this.handleClose}
                  autoScrollBodyContent={true}
                >

Dont panic, the module codes shown in the list are combined with their key but the dialog just gets the module code only.

                </Dialog>

        );
    }
}

export default withStyles(s)(ModuleList);
<|endoftext|>


<commit_before>'use strict';

const argv          = require('yargs').argv;
const fs            = require('co-fs-extra');
const path          = require('path');
const co            = require('co');
const VError        = require('verror');
const sprintf       = require('extsprintf').sprintf;
const Logger        = require('shark-logger');
const Storage       = require('./storage');
const expand        = require('expand');
const chokidar      = require('chokidar');
const util          = require('util');

process.on('uncaughtException', function(error) {
	console.error(sprintf('%r', new VError(error, 'global uncaughtException')));
	process.exit(1);
});

function SharkRunner(options) {
	this.tasks = {};
	this.wasTasksCollected = false;
	this.isWatcherRunning = false;
	this.storage = new Storage();
	this.setStorageValues(options.storageValues);
	this.logger = Logger({
		name: 'SharkRunner',
		level: process.argv[2] === 'completion' ? 100 : Logger.TRACE,
		deepLevel: 1
	});

	var time = this.logger.time();
	this.logger.trace({ opType: this.logger.OP_TYPE.STARTED }, 'SharkRunner');

	process.on('exit', function() {
		this.logger.trace({
			duration: time.delta(),
			opType: this.logger.OP_TYPE.FINISHED
		}, 'SharkRunner')
	}.bind(this));
}

SharkRunner.prototype = {
	constructor: SharkRunner,

	getStorageValue: function() {
		return this.storage.getValue.apply(this.storage, arguments);
	},

	setStorageValue: function() {
		return this.storage.setValue.apply(this.storage, arguments);
	},

	setStorageValues: function() {
		return this.storage.setValues.apply(this.storage, arguments);
	},

	collectTasksByDirPath: function *(tasksPath) {
		var time = this.logger.time();
		this.logger.trace({ opType: this.logger.OP_TYPE.STARTED }, 'collectTasks', tasksPath);
		try {
			var files = yield expand([
				'./*/*.js',
				'./*/*/*.js'
			], {
				cwd: this.getStorageValue('tasksPath')
			});

			files.filter(function(filePath) {
				var fileName = path.basename(filePath, '.js');
				var dirName = path.basename(path.dirname(filePath));
				var parentDirName = path.basename(path.dirname(path.dirname(filePath)));
				var isTask = fileName === dirName;

				if (isTask) {
					var fullFilePath = path.join(this.getStorageValue('tasksPath'), filePath);
					var taskName;

					if (parentDirName === '.') {
						taskName = fileName;
					}
					else {
						taskName = path.join(parentDirName, fileName);
					}

					this.tasks[taskName] = fullFilePath;
				}
			}.bind(this));
		}
		catch (error) {
			throw new VError(error, 'collectTasksByDirPath error');
		}
		this.logger.trace({ duration: time.delta(), opType: this.logger.OP_TYPE.FINISHED }, 'collectTasksByDirPath');
	},

	collectTasks: function *() {
		if (!this.wasTasksCollected) {
			yield this.collectTasksByDirPath(this.getStorageValue('tasksPath'));
			this.wasTasksCollected = true;
		}
	},

	getTaskList: function *() {
		yield this.collectTasks();
		return this.tasks;
	},

	runRequestedTasks: function* () {
		yield this.collectTasks();

		var taskName = argv._[0];

		return yield this.runTask(taskName, this.logger.fields.deepLevel, {});
	},

	runTask: function *(taskName, deepLevel, options) {
		yield this.collectTasks();

		var taskPath = this.tasks[taskName];
		if (!taskPath) {
			this.logger.warn({
				opType: Logger.OP_TYPE.ERROR,
				opName: taskName
			}, 'task "%s" not found', taskName);
			return;
		}

		var time = this.logger.time();

		this.logger.info({
			opType: Logger.OP_TYPE.STARTED,
			opName: taskName,
			deepLevel: deepLevel
		});

		try {
			var taskRunner = require(taskPath);
			var taskRunnerResult = yield taskRunner.call(
				this.getTaskInternalMethods.apply(this, arguments)
			);
		}
		catch (error) {
			throw new VError(error, 'runTask error');
		}

		this.logger.info({
			opType: Logger.OP_TYPE.FINISHED,
			opName: taskName,
			duration: time.delta(),
			deepLevel: deepLevel
		});

		return taskRunnerResult;
	},

	getTaskInternalMethods: function(taskName, deepLevel, options) {
		return {
			getStorageValue: this.getStorageValue.bind(this),
			taskDeepLevel: deepLevel,
			options: options || {},
			logger: this.logger.child({
				subName: taskName,
				deepLevel: deepLevel + 1
			}),
			runTask: function *(taskName, options) {
				try {
					return yield this.runTask(taskName, deepLevel, options);
				}
				catch (error) {
					throw new VError(error, 'runner#getTaskInternalMethods runTask error');
				}
			}.bind(this),
			runChildTask: function *(taskName, options) {
				try {
					return yield this.runTask(taskName, deepLevel + 1, options);
				}
				catch (error) {
					throw new VError(error, 'runner#getTaskInternalMethods runChildTask error');
				}
			}.bind(this)
		};
	},

	runWatcher: function *() {
		if (this.isWatcherRunning) {
			this.logger.trace('Watcher already run');
			return;
		}

		this.isWatcherRunning = true;

		var tasksPath = this.getStorageValue('tasksPath');

		var files = yield expand([
			'./*/watcher.js',
			'./*/*/watcher.js'
		]
			.map(function(filePath) {
				return path.join(this.getStorageValue('tasksPath'), filePath)
			}, this)
		);

		for (var i = 0, len = files.length; i < len; i += 1) {
			var watcherDataGetter = require(files[i]);
			var watcherData = yield watcherDataGetter.call(
				this.getTaskInternalMethods.apply(this, arguments)
			);

			if (!util.isArray(watcherData.paths)) {
				throw new VError(files[i] + ' watcherData.paths must be array')
			}

			if (!util.isObject(watcherData.events)) {
				throw new VError(files[i] + ' watcherData.event must be object')
			}

			var watcher = chokidar.watch(watcherData.paths, {ignored: /[\/\\]\./, persistent: true});

			(function(watcherData, watcherPath) {
				Object.keys(watcherData.events).forEach(function(eventName) {
					var eventCallback = watcherData.events[eventName];

					this.logger.info('running watcher', watcherPath);
					watcher.on(eventName, function() {
						var args = [].slice.call(arguments);
						co(function *() {
							yield eventCallback.call(this, args);
						}).catch(function(error) {
							console.error(sprintf('%r', error));
						});
					}.bind(this));
				}, this);
			}).call(this, watcherData, files[i]);
		}
	},

	watchRequested: function() {
		return !!argv.watch;
	}
};

module.exports = function(config) {
	if (!config || !config.tasksPath) {
		throw new VError('config.tasksPath not defined');
	}

	var shark = new SharkRunner({
		storageValues: config
	});

	var errorHandler = function(error) {
		console.error(sprintf('%r', error));
		process.exit(1);
	};

	var promisify = function(genFunc, thisArg) {
		return function() {
			var args = [].slice.call(arguments, 0);
			return new Promise(function(fulfill, reject) {
				co(function *() {
					var result = yield genFunc.apply(thisArg, args);
					fulfill(result);
				}).catch(function(error) {
					reject(error);
				});
			});
		};
	};

	return {
		setStorageValue:    shark.setStorageValue.bind(shark),
		getStorageValue:    shark.getStorageValue.bind(shark),
		setStorageValues:   shark.setStorageValues.bind(shark),

		runTask:            promisify(shark.runTask, shark),
		runRequestedTask:   promisify(shark.runRequestedTask, shark),

		getTaskList:        promisify(shark.getTaskList, shark),

		runWatcher:         promisify(shark.runWatcher, shark),

		run: function() {
			co(function *sharkfileSharkRunner() {
				yield shark.runRequestedTasks();
				if (shark.watchRequested()) {
					yield shark.runWatcher();
				}
			}).catch(errorHandler);
		}
	};
};
<commit_msg>FIx watcher event args apply<commit_after>'use strict';

const argv          = require('yargs').argv;
const fs            = require('co-fs-extra');
const path          = require('path');
const co            = require('co');
const VError        = require('verror');
const sprintf       = require('extsprintf').sprintf;
const Logger        = require('shark-logger');
const Storage       = require('./storage');
const expand        = require('expand');
const chokidar      = require('chokidar');
const util          = require('util');

process.on('uncaughtException', function(error) {
	console.error(sprintf('%r', new VError(error, 'global uncaughtException')));
	process.exit(1);
});

function SharkRunner(options) {
	this.tasks = {};
	this.wasTasksCollected = false;
	this.isWatcherRunning = false;
	this.storage = new Storage();
	this.setStorageValues(options.storageValues);
	this.logger = Logger({
		name: 'SharkRunner',
		level: process.argv[2] === 'completion' ? 100 : Logger.TRACE,
		deepLevel: 1
	});

	var time = this.logger.time();
	this.logger.trace({ opType: this.logger.OP_TYPE.STARTED }, 'SharkRunner');

	process.on('exit', function() {
		this.logger.trace({
			duration: time.delta(),
			opType: this.logger.OP_TYPE.FINISHED
		}, 'SharkRunner')
	}.bind(this));
}

SharkRunner.prototype = {
	constructor: SharkRunner,

	getStorageValue: function() {
		return this.storage.getValue.apply(this.storage, arguments);
	},

	setStorageValue: function() {
		return this.storage.setValue.apply(this.storage, arguments);
	},

	setStorageValues: function() {
		return this.storage.setValues.apply(this.storage, arguments);
	},

	collectTasksByDirPath: function *(tasksPath) {
		var time = this.logger.time();
		this.logger.trace({ opType: this.logger.OP_TYPE.STARTED }, 'collectTasks', tasksPath);
		try {
			var files = yield expand([
				'./*/*.js',
				'./*/*/*.js'
			], {
				cwd: this.getStorageValue('tasksPath')
			});

			files.filter(function(filePath) {
				var fileName = path.basename(filePath, '.js');
				var dirName = path.basename(path.dirname(filePath));
				var parentDirName = path.basename(path.dirname(path.dirname(filePath)));
				var isTask = fileName === dirName;

				if (isTask) {
					var fullFilePath = path.join(this.getStorageValue('tasksPath'), filePath);
					var taskName;

					if (parentDirName === '.') {
						taskName = fileName;
					}
					else {
						taskName = path.join(parentDirName, fileName);
					}

					this.tasks[taskName] = fullFilePath;
				}
			}.bind(this));
		}
		catch (error) {
			throw new VError(error, 'collectTasksByDirPath error');
		}
		this.logger.trace({ duration: time.delta(), opType: this.logger.OP_TYPE.FINISHED }, 'collectTasksByDirPath');
	},

	collectTasks: function *() {
		if (!this.wasTasksCollected) {
			yield this.collectTasksByDirPath(this.getStorageValue('tasksPath'));
			this.wasTasksCollected = true;
		}
	},

	getTaskList: function *() {
		yield this.collectTasks();
		return this.tasks;
	},

	runRequestedTasks: function* () {
		yield this.collectTasks();

		var taskName = argv._[0];

		return yield this.runTask(taskName, this.logger.fields.deepLevel, {});
	},

	runTask: function *(taskName, deepLevel, options) {
		yield this.collectTasks();

		var taskPath = this.tasks[taskName];
		if (!taskPath) {
			this.logger.warn({
				opType: Logger.OP_TYPE.ERROR,
				opName: taskName
			}, 'task "%s" not found', taskName);
			return;
		}

		var time = this.logger.time();

		this.logger.info({
			opType: Logger.OP_TYPE.STARTED,
			opName: taskName,
			deepLevel: deepLevel
		});

		try {
			var taskRunner = require(taskPath);
			var taskRunnerResult = yield taskRunner.call(
				this.getTaskInternalMethods.apply(this, arguments)
			);
		}
		catch (error) {
			throw new VError(error, 'runTask error');
		}

		this.logger.info({
			opType: Logger.OP_TYPE.FINISHED,
			opName: taskName,
			duration: time.delta(),
			deepLevel: deepLevel
		});

		return taskRunnerResult;
	},

	getTaskInternalMethods: function(taskName, deepLevel, options) {
		return {
			getStorageValue: this.getStorageValue.bind(this),
			taskDeepLevel: deepLevel,
			options: options || {},
			logger: this.logger.child({
				subName: taskName,
				deepLevel: deepLevel + 1
			}),
			runTask: function *(taskName, options) {
				try {
					return yield this.runTask(taskName, deepLevel, options);
				}
				catch (error) {
					throw new VError(error, 'runner#getTaskInternalMethods runTask error');
				}
			}.bind(this),
			runChildTask: function *(taskName, options) {
				try {
					return yield this.runTask(taskName, deepLevel + 1, options);
				}
				catch (error) {
					throw new VError(error, 'runner#getTaskInternalMethods runChildTask error');
				}
			}.bind(this)
		};
	},

	runWatcher: function *() {
		if (this.isWatcherRunning) {
			this.logger.trace('Watcher already run');
			return;
		}

		this.isWatcherRunning = true;

		var tasksPath = this.getStorageValue('tasksPath');

		var files = yield expand([
			'./*/watcher.js',
			'./*/*/watcher.js'
		]
			.map(function(filePath) {
				return path.join(this.getStorageValue('tasksPath'), filePath)
			}, this)
		);

		for (var i = 0, len = files.length; i < len; i += 1) {
			var watcherDataGetter = require(files[i]);
			var watcherData = yield watcherDataGetter.call(
				this.getTaskInternalMethods.apply(this, arguments)
			);

			if (!util.isArray(watcherData.paths)) {
				throw new VError(files[i] + ' watcherData.paths must be array')
			}

			if (!util.isObject(watcherData.events)) {
				throw new VError(files[i] + ' watcherData.event must be object')
			}

			var watcher = chokidar.watch(watcherData.paths, {ignored: /[\/\\]\./, persistent: true});

			(function(watcherData, watcherPath) {
				Object.keys(watcherData.events).forEach(function(eventName) {
					var eventCallback = watcherData.events[eventName];

					this.logger.info('running watcher', watcherPath);
					watcher.on(eventName, function() {
						var args = [].slice.call(arguments);
						co(function *() {
							yield eventCallback.apply(this, args);
						}).catch(function(error) {
							console.error(sprintf('%r', error));
						});
					}.bind(this));
				}, this);
			}).call(this, watcherData, files[i]);
		}
	},

	watchRequested: function() {
		return !!argv.watch;
	}
};

module.exports = function(config) {
	if (!config || !config.tasksPath) {
		throw new VError('config.tasksPath not defined');
	}

	var shark = new SharkRunner({
		storageValues: config
	});

	var errorHandler = function(error) {
		console.error(sprintf('%r', error));
		process.exit(1);
	};

	var promisify = function(genFunc, thisArg) {
		return function() {
			var args = [].slice.call(arguments, 0);
			return new Promise(function(fulfill, reject) {
				co(function *() {
					var result = yield genFunc.apply(thisArg, args);
					fulfill(result);
				}).catch(function(error) {
					reject(error);
				});
			});
		};
	};

	return {
		setStorageValue:    shark.setStorageValue.bind(shark),
		getStorageValue:    shark.getStorageValue.bind(shark),
		setStorageValues:   shark.setStorageValues.bind(shark),

		runTask:            promisify(shark.runTask, shark),
		runRequestedTask:   promisify(shark.runRequestedTask, shark),

		getTaskList:        promisify(shark.getTaskList, shark),

		runWatcher:         promisify(shark.runWatcher, shark),

		run: function() {
			co(function *sharkfileSharkRunner() {
				yield shark.runRequestedTasks();
				if (shark.watchRequested()) {
					yield shark.runWatcher();
				}
			}).catch(errorHandler);
		}
	};
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import './PatchCollection.css';
import Modal from 'react-modal';
import {ROOT_URL} from '../../RootURL';

const signupStyle = {
  content: {
    top: '50%',
    left: '50%',
    right: 'auto',
    bottom: 'auto',
    marginRight: '-50%',
    transform: 'translate(-50%, -50%)',
    backgroundColor: '#6c2505',
    backgroundSize: '40px 160px, 60px 29px, 27px 27px',
    backgroundImage: 'linear-gradient(94deg, rgba(91, 33, 5, 0.1) 0%, rgba(83, 29, 4, 0.32) 23%, rgba(74, 24, 3, 0.41) 47%, rgba(80, 27, 5, 0.44) 70%, rgba(81, 27, 5, 0.59) 74%, rgba(93, 33, 4, 0.2) 83%, rgba(115, 43, 3, 0.5) 100%), linear-gradient(90deg, #541c09 50%, transparent 50%), linear-gradient(90deg, #7a2e00 50%, #632401 50%)',
    width: '400px',
    borderRadius: '5%',
    zIndex: '1'
  }
}

class PatchCollection extends Component {
	constructor(props) {
	  super(props);

		this.state = {
      modalIsOpen: false,
			newPatch: {}
    };

    this.openModal = this.openModal.bind(this);
    this.afterOpenModal = this.afterOpenModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
		this.savePatch = this.savePatch.bind(this);

	}

	openModal() {
    this.setState({modalIsOpen: true});
  }

  afterOpenModal() {
    // this.subtitle.style.color = '#f00';
  }

  closeModal() {
    this.setState({modalIsOpen: false});
  }

	savePatch(e) {
		e.preventDefault();
		const typeInput = document.querySelector('#patch-type')
    const nameInput = document.querySelector('#patch-name')
		let newSettings = {...this.props.patch};
		newSettings.type = typeInput.value;
    newSettings.name = nameInput.value;

    console.log(this.state.newPatch);

		fetch(`${ROOT_URL}/patches`, {
      method: "POST",
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
        body: JSON.stringify(newSettings),
        mode: "cors",
        credentials: "omit"
    })
		.then(res => {
      console.log(res);
    })
	}

	render() {
		let options = false
		if(this.props.selectValues !== undefined) {
			options = this.props.selectValues.map((patch, index) => {
				return (<option key={index} value={patch.id}>{patch.name} | {patch.type}</option>);
			});
		}
		return(

				<select className="patch-selection" onChange={(event) => this.props.setPatchFromCollection(event.target.value)}>
					{options && options}
				</select>
				<Modal
					isOpen={this.state.modalIsOpen}
					onAfterOpen={this.afterOpenModal}
					onRequestClose={this.closeModal}
					style={signupStyle}
    contentLabel="Example Modal">

						<form
							onSubmit={this.savePatch}>
							<input
								id="patch-name"
								className="modal"
								type="text"
								name="patch-name"
								placeholder="Patch Name"
       />

							<input
								id="patch-type"
								className="modal"
								type="text"
								name="patch-type"
								placeholder="type"
       />

							<button className="btn modal" type="submit">SUBMIT</button>
						</form>
						<button
							className="btn modal"
							onClick={this.closeModal}>CLOSE</button>

				</Modal>
				<button className="btn save-patch" onClick={this.openModal}>Save Patch</button>

		);
	}
}

export default PatchCollection;
<commit_msg>can save patches<commit_after>import React, { Component } from 'react';
import './PatchCollection.css';
import Modal from 'react-modal';
import {ROOT_URL} from '../../RootURL';

const signupStyle = {
  content: {
    top: '50%',
    left: '50%',
    right: 'auto',
    bottom: 'auto',
    marginRight: '-50%',
    transform: 'translate(-50%, -50%)',
    backgroundColor: '#6c2505',
    backgroundSize: '40px 160px, 60px 29px, 27px 27px',
    backgroundImage: 'linear-gradient(94deg, rgba(91, 33, 5, 0.1) 0%, rgba(83, 29, 4, 0.32) 23%, rgba(74, 24, 3, 0.41) 47%, rgba(80, 27, 5, 0.44) 70%, rgba(81, 27, 5, 0.59) 74%, rgba(93, 33, 4, 0.2) 83%, rgba(115, 43, 3, 0.5) 100%), linear-gradient(90deg, #541c09 50%, transparent 50%), linear-gradient(90deg, #7a2e00 50%, #632401 50%)',
    width: '400px',
    borderRadius: '5%',
    zIndex: '1'
  }
}

class PatchCollection extends Component {
	constructor(props) {
	  super(props);

		this.state = {
      modalIsOpen: false,
			newPatch: {}
    };

    this.openModal = this.openModal.bind(this);
    this.afterOpenModal = this.afterOpenModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
		this.savePatch = this.savePatch.bind(this);

	}

	openModal() {
    this.setState({modalIsOpen: true});
  }

  afterOpenModal() {
    // this.subtitle.style.color = '#f00';
  }

  closeModal() {
    this.setState({modalIsOpen: false});
  }

	savePatch(e) {
		e.preventDefault();
		const typeInput = document.querySelector('#patch-type')
    const nameInput = document.querySelector('#patch-name')
		let newSettings = {...this.props.patch};
		newSettings.type = typeInput.value;
    newSettings.name = nameInput.value;
    delete newSettings['_id'];

    console.log(this.state.newPatch);

		fetch(`${ROOT_URL}/patches`, {
      method: "POST",
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
        body: JSON.stringify(newSettings),
        mode: "cors",
        credentials: "omit"
    })
		.then(res => {
      console.log(res);
    })
	}

	render() {
		let options = false
		if(this.props.selectValues !== undefined) {
			options = this.props.selectValues.map((patch, index) => {
				return (<option key={index} value={patch.id}>{patch.name} | {patch.type}</option>);
			});
		}
		return(

				<select className="patch-selection" onChange={(event) => this.props.setPatchFromCollection(event.target.value)}>
					{options && options}
				</select>
				<Modal
					isOpen={this.state.modalIsOpen}
					onAfterOpen={this.afterOpenModal}
					onRequestClose={this.closeModal}
					style={signupStyle}
    contentLabel="Example Modal">

						<form
							onSubmit={this.savePatch}>
							<input
								id="patch-name"
								className="modal"
								type="text"
								name="patch-name"
								placeholder="Patch Name"
       />

							<input
								id="patch-type"
								className="modal"
								type="text"
								name="patch-type"
								placeholder="type"
       />

							<button className="btn modal" type="submit">SUBMIT</button>
						</form>
						<button
							className="btn modal"
							onClick={this.closeModal}>CLOSE</button>

				</Modal>
				<button className="btn save-patch" onClick={this.openModal}>Save Patch</button>

		);
	}
}

export default PatchCollection;
<|endoftext|>


<commit_before>var Queue        = require( './utils/queue' );
var WPT          = require( 'webpagetest' );
var _            = require( 'lodash' );
var EventEmitter = require( 'events' ).EventEmitter;
var util         = require( 'util' );

var Runner = function( options ) {
  this.emit(
    'msg',
    'Initialized Runner'
  );

  this.options = options;
  this.wpt = new WPT( this.options.wpt.server );

  this.data  = {};
  this.queue = new Queue();

  EventEmitter.call( this );
};

util.inherits( Runner, EventEmitter );

/**
 * [run description]
 * @param  {Function} callback [description]
 * @return {[type]}            [description]
 */
Runner.prototype.run = function( callback ) {
  // store the callback to not pass it around the whole time
  this.done = callback;

  this.emit(
    'msg',
    ' (╯°□°)╯  Starting to call WPT to evaluate all 3rd party requests '
  );

  this.emit(
    'msg',
    'Running with following configuration options:' +
    JSON.stringify( this.options, null, 2 )
  );

  // evaluate all 3rd parties
  this._get3rdParties( function( err, src, thirdParties ) {
    if ( err ) {
      this.done( err );

      return;
    }

    var numberOfRequests = thirdParties.length;

    thirdParties = _.reduce( thirdParties, function( thirdParties, domain ) {
      if ( thirdParties.indexOf( domain ) === -1 ) {
        thirdParties.push( domain );
      }

      return thirdParties;
    }, [] );

    this.thirdPartyDomains = thirdParties;

    this.emit( 'evaluated3rdParties', thirdParties );

    this._runAll();
  }.bind( this ) );
};

Runner.prototype._emitData = function( data ) {
  this.emit( 'data', {
    allowedUrls : data.allowedUrls,
    blockedUrls : data.blockedUrls,
    firstView   : {
      bytesDocComplete : data.response.data.median.firstView.bytesInDoc,
      bytesDocLoad     : data.response.data.median.firstView.bytesIn,
      domElements      : data.response.data.median.firstView.domElements,
      loadEnd          : data.response.data.median.firstView.domContentLoadedEventEnd,
      loadTime         : data.response.data.median.firstView.loadTime,
      render           : data.response.data.median.firstView.render,
      requests         : data.response.data.median.firstView.requests[ 0 ]

    },
    repeatView  : {
      bytesDocComplete : data.response.data.median.repeatView.bytesInDoc,
      bytesDocLoad     : data.response.data.median.repeatView.bytesIn,
      domElements      : data.response.data.median.repeatView.domElements,
      loadEnd          : data.response.data.median.repeatView.domContentLoadedEventEnd,
      loadTime         : data.response.data.median.repeatView.loadTime,
      render           : data.response.data.median.repeatView.render,
      requests         : data.response.data.median.repeatView.requests[ 0 ]
    },
    summary : data.response.data.summary
  } );
}

/**
 * [_get3rdParties description]
 * @param  {Function} callback [description]
 */
Runner.prototype._get3rdParties = function( callback ) {
  var options = _.clone( this.options.wpt );

  // set number of runs to 1
  options.runs = 1;

  this.emit(
    'msg',
    'Calling api with following options : ' + JSON.stringify( this.options.wpt, null, 2 )
  );
  this.wpt.runTest(
    this.options.runner.url,
    options,
    function( error, data ) {
      if ( error ) {
        this.emit(
          'error',
          error
        );
      }

      data.allowedUrls = '*';
      data.blockedUrls = 'none';

      this._emitData( data );

      // reduce and filter third parties
      var thirdParties = _.reduce(
        data.response.data.median.firstView.requests[ 1 ].request,
        function( thirdParties, request ) {
          // console.log( request );
          var isAllowed    = false;
          var i            = 0;
          var length       = this.options.runner.allowedDomains.length;

          for( ; i < length; ++ i ) {
            // TODO put a regex thing in here
            if (
              !isAllowed &&
              request.host.indexOf( this.options.runner.allowedDomains[ i ] ) !== -1
            ) {
              isAllowed = true;
            }
          }

          if ( !isAllowed ) {
            thirdParties.push( request.host );
          }

          return thirdParties;
        },
        [],
        this
      );

      callback( error, data.response.data.summary, thirdParties );
    }.bind( this )
  );
};

Runner.prototype._run = function( options ) {
  options = options || {};

  this.emit(
    'msg',
    options.allowedThirdPartyDomain ?
    ' -> Starting to evaluate metrics for included ' + options.allowedThirdPartyDomain :
    ' -> Starting to evaluate metrics for all blocked 3rd parties'
  );

  var wptOptions = _.clone( this.options.wpt );

  wptOptions.block = _.reduce( this.thirdPartyDomains, function( block, domain ) {
    if ( domain !== options.allowedThirdPartyDomain ) {
      block.push( domain );
    }

    return block;
  }, [] ).join( ' ' );

  this.emit(
    'msg',
    'Calling api with following options : ' + JSON.stringify( wptOptions, null, 2 )
  );

  this.wpt.runTest(
    this.options.runner.url,
    wptOptions,
    function( error, data ) {
      if ( error ) {
        this.emit( 'error', error );
      } else {
        data.allowedUrls = options.allowedThirdPartyDomain;
        data.blockedUrls = wptOptions.block;

        this._emitData( data );
      }

      this.queue.pop();

      // yeah we're done!!! 8-)
      if ( this.queue.isEmpty() ) {
        this.done();
      }
    }.bind( this )
  );
};

/**
 * done
 * @return {[type]} [description]
 */
Runner.prototype._runAll = function() {
  this.emit(
    'msg',
    ' (╯°□°)╯  Starting to call WPT to evaluate load times and request counts '
  );

  var i      = 0;
  var length = this.thirdPartyDomains.length;

  this.queue.push( function( i ) {
    this._run();
  }.bind( this, [ i ] ) );

  for ( ; i < length; ++i ) {
    this.queue.push( function( i ) {
      this._run( {
        allowedThirdPartyDomain : this.thirdPartyDomains[ i ]
      } );
    }.bind( this, [ i ] ) );
  }
};

module.exports = Runner;
<commit_msg>fixed for data handling in case that no url is allowed<commit_after>var Queue        = require( './utils/queue' );
var WPT          = require( 'webpagetest' );
var _            = require( 'lodash' );
var EventEmitter = require( 'events' ).EventEmitter;
var util         = require( 'util' );

var Runner = function( options ) {
  this.emit(
    'msg',
    'Initialized Runner'
  );

  this.options = options;
  this.wpt = new WPT( this.options.wpt.server );

  this.data  = {};
  this.queue = new Queue();

  EventEmitter.call( this );
};

util.inherits( Runner, EventEmitter );

/**
 * [run description]
 * @param  {Function} callback [description]
 * @return {[type]}            [description]
 */
Runner.prototype.run = function( callback ) {
  // store the callback to not pass it around the whole time
  this.done = callback;

  this.emit(
    'msg',
    ' (╯°□°)╯  Starting to call WPT to evaluate all 3rd party requests '
  );

  this.emit(
    'msg',
    'Running with following configuration options:' +
    JSON.stringify( this.options, null, 2 )
  );

  // evaluate all 3rd parties
  this._get3rdParties( function( err, src, thirdParties ) {
    if ( err ) {
      this.done( err );

      return;
    }

    var numberOfRequests = thirdParties.length;

    thirdParties = _.reduce( thirdParties, function( thirdParties, domain ) {
      if ( thirdParties.indexOf( domain ) === -1 ) {
        thirdParties.push( domain );
      }

      return thirdParties;
    }, [] );

    this.thirdPartyDomains = thirdParties;

    this.emit( 'evaluated3rdParties', thirdParties );

    this._runAll();
  }.bind( this ) );
};

Runner.prototype._emitData = function( data ) {
  this.emit( 'data', {
    allowedUrls : data.allowedUrls,
    blockedUrls : data.blockedUrls,
    firstView   : {
      bytesDocComplete : data.response.data.median.firstView.bytesInDoc,
      bytesDocLoad     : data.response.data.median.firstView.bytesIn,
      domElements      : data.response.data.median.firstView.domElements,
      loadEnd          : data.response.data.median.firstView.domContentLoadedEventEnd,
      loadTime         : data.response.data.median.firstView.loadTime,
      render           : data.response.data.median.firstView.render,
      requests         : data.response.data.median.firstView.requests[ 0 ]

    },
    repeatView  : {
      bytesDocComplete : data.response.data.median.repeatView.bytesInDoc,
      bytesDocLoad     : data.response.data.median.repeatView.bytesIn,
      domElements      : data.response.data.median.repeatView.domElements,
      loadEnd          : data.response.data.median.repeatView.domContentLoadedEventEnd,
      loadTime         : data.response.data.median.repeatView.loadTime,
      render           : data.response.data.median.repeatView.render,
      requests         : data.response.data.median.repeatView.requests[ 0 ]
    },
    summary : data.response.data.summary
  } );
}

/**
 * [_get3rdParties description]
 * @param  {Function} callback [description]
 */
Runner.prototype._get3rdParties = function( callback ) {
  var options = _.clone( this.options.wpt );

  // set number of runs to 1
  options.runs = 1;

  this.emit(
    'msg',
    'Calling api with following options : ' + JSON.stringify( this.options.wpt, null, 2 )
  );
  this.wpt.runTest(
    this.options.runner.url,
    options,
    function( error, data ) {
      if ( error ) {
        this.emit(
          'error',
          error
        );
      }

      data.allowedUrls = '*';
      data.blockedUrls = 'none';

      this._emitData( data );

      // reduce and filter third parties
      var thirdParties = _.reduce(
        data.response.data.median.firstView.requests[ 1 ].request,
        function( thirdParties, request ) {
          // console.log( request );
          var isAllowed    = false;
          var i            = 0;
          var length       = this.options.runner.allowedDomains.length;

          for( ; i < length; ++ i ) {
            // TODO put a regex thing in here
            if (
              !isAllowed &&
              request.host.indexOf( this.options.runner.allowedDomains[ i ] ) !== -1
            ) {
              isAllowed = true;
            }
          }

          if ( !isAllowed ) {
            thirdParties.push( request.host );
          }

          return thirdParties;
        },
        [],
        this
      );

      callback( error, data.response.data.summary, thirdParties );
    }.bind( this )
  );
};

Runner.prototype._run = function( options ) {
  options = options || {};

  this.emit(
    'msg',
    options.allowedThirdPartyDomain ?
    ' -> Starting to evaluate metrics for included ' + options.allowedThirdPartyDomain :
    ' -> Starting to evaluate metrics for all blocked 3rd parties'
  );

  var wptOptions = _.clone( this.options.wpt );

  wptOptions.block = _.reduce( this.thirdPartyDomains, function( block, domain ) {
    if ( domain !== options.allowedThirdPartyDomain ) {
      block.push( domain );
    }

    return block;
  }, [] ).join( ' ' );

  this.emit(
    'msg',
    'Calling api with following options : ' + JSON.stringify( wptOptions, null, 2 )
  );

  this.wpt.runTest(
    this.options.runner.url,
    wptOptions,
    function( error, data ) {
      if ( error ) {
        this.emit( 'error', error );
      } else {
        data.allowedUrls = options.allowedThirdPartyDomain || 'none';
        data.blockedUrls = wptOptions.block;

        this._emitData( data );
      }

      this.queue.pop();

      // yeah we're done!!! 8-)
      if ( this.queue.isEmpty() ) {
        this.done();
      }
    }.bind( this )
  );
};

/**
 * done
 * @return {[type]} [description]
 */
Runner.prototype._runAll = function() {
  this.emit(
    'msg',
    ' (╯°□°)╯  Starting to call WPT to evaluate load times and request counts '
  );

  var i      = 0;
  var length = this.thirdPartyDomains.length;

  this.queue.push( function( i ) {
    this._run();
  }.bind( this, [ i ] ) );

  for ( ; i < length; ++i ) {
    this.queue.push( function( i ) {
      this._run( {
        allowedThirdPartyDomain : this.thirdPartyDomains[ i ]
      } );
    }.bind( this, [ i ] ) );
  }
};

module.exports = Runner;
<|endoftext|>


<commit_before>require('sugar');
var express = require('express'),
	path = require('path'),
	fs = require('fs'),
	http = require('http'),
	async = require('async'),
	consolidate = require('consolidate'),
	winston = require('winston');

var logger = new winston.Logger({
	transports: [
		new winston.transports.Console({ colorize: true })
	]
});

process.on('uncaughtException', function(err) {
	logger.error(err.stack, function() {
		process.exit(-1);
	});
});

function scarab(rootDir) {
	var app = express();
	app.config = require('./defaults');
	app.config.rootDir = rootDir;

	app.middleware = express;
	app.logger = logger;
	app.winston = winston;

	var Routing = require('./routing')(app);
	var DB = require('./db')(app);

	function readConfigFiles(configDir) {
		if (fs.existsSync(configDir)) {
			var configFiles = fs.readdirSync(configDir);
			configFiles.forEach(function(configFile) {
				var filePath = path.join(configDir, configFile);
				var stats = fs.statSync(filePath);
				try {
					if (stats.isFile())
						Object.merge(app.config, require(filePath), true);
				} catch(e) {
					logger.warn('Unable to read config file ' + filePath);
				}
			});
		}
	}
	// read config files
	var configDir = path.join(rootDir, app.config.paths.config);
	var environmentConfigDir = path.join(configDir, app.get('env'));
	readConfigFiles(configDir);
	readConfigFiles(environmentConfigDir);
	app.set('port', process.env.PORT || app.config.port);

	app.init = function(callback) {
		logger.info('initializing application...');
		app.db = {};
		app.models = {};
		app.controllers = {};

		if (app.config.logFile && !logger.transports['file']) {
			logger.add(winston.transports.File, {
				filename: app.config.logFile,
				json: false
			});
		}

		// setup view engines
		app.set('views', path.join(rootDir, app.config.paths.views));
		for (var extension in app.config.viewEngines) {
			var engine = app.config.viewEngines[extension];
			app.engine(extension, consolidate[engine]);
		}

		app.use(express.cookieParser());
		app.use(express.bodyParser());

		var winstonStream = {
			write: function(message) {
				logger.info(message);
			}
		};
		app.use(express.logger({
			stream: winstonStream
		}));

		// setup custom middleware
		app.config.middleware(app);

		// setup routing
		app.use(app.router);
		Routing.init();

		app.use(function(err, req, res, next) {
			if (err.name === 'NoSuchThingError') {
				err.status = 404;
			}
			next(err);
		});

		if ('development' === app.get('env')) {
			app.use(express.errorHandler());
		}

		// setup db
		DB.init(function(err) {
			if (err) return callback(err);

			// run init files
			var initDir = path.join(rootDir, app.config.paths.init);
			var initFiles = fs.readdirSync(initDir);
			async.each(initFiles, function(initFile, cb) {
				var initFunc = require(path.join(initDir, initFile));
				if (initFunc.length <= 1) {
					initFunc(app);
					cb();
				} else {
					initFunc(app, cb);
				}
			}, function(err) {
				if (callback)
					callback(err);
			});
		});

	};

	app.teardown = function(cb) {
		logger.info('shutting down...');
		DB.disconnect(function(err) {
			cb(err);
		});
	};

	app.scarab = scarab;
	return app;
}

scarab.run = function(app, cb) {
	scarab.server = http.createServer();
	scarab.server.listen(app.get('port'), function() {
		if (app.config.group)
			process.setgid(app.config.group);
		if (app.config.user)
			process.setuid(app.config.user);
		app.init(function(err) {
			if (err) throw err;

			scarab.server.on('request', app);
			scarab.server.app = app;

			logger.info('scarab server listening on port ' + app.get('port') + ' in ' + app.get('env') + ' mode.');
			if (cb) cb(scarab.server);
		});
	});

	var quit = function() {
		scarab.server.app.teardown(function(err) {
			if (err) throw err;
			process.exit();
		});
	};
	process.on('SIGTERM', quit);
	process.on('SIGINT', quit);
	process.on('SIGHUP', scarab.reload);
};

scarab.uncache = function(app) {
	var serverPath = path.resolve(app.config.rootDir);
	for (var file in require.cache) {
		if (file.indexOf(serverPath) === 0) {
			delete require.cache[file];
		}
	}
};

scarab.replaceApp = function(app, cb) {
	if (!(scarab.server && scarab.server.app))
		return cb(new Error('No server running'));

	var oldApp = scarab.server.app;
	oldApp.teardown(function() {
		scarab.uncache(oldApp);
		app.init(function(err) {
			if (err) return cb(err);
			scarab.server.removeAllListeners('request');
			scarab.server.on('request', app);
			scarab.server.app = app;
			cb();
		});
	});
};

scarab.reload = function(cb) {
	logger.info('reloading server...');
	var app = scarab(scarab.server.app.config.rootDir);
	scarab.replaceApp(app, function(err) {
		if (err) {
			if (cb) return cb(err);
			else throw err;
		}
		return cb && cb(null, app);
	});
};
module.exports = scarab;<commit_msg>fix reload: uncache everything, not just the app dir<commit_after>require('sugar');
var express = require('express'),
	path = require('path'),
	fs = require('fs'),
	http = require('http'),
	async = require('async'),
	consolidate = require('consolidate'),
	winston = require('winston');

var logger = new winston.Logger({
	transports: [
		new winston.transports.Console({ colorize: true })
	]
});

process.on('uncaughtException', function(err) {
	logger.error(err.stack, function() {
		process.exit(-1);
	});
});

function scarab(rootDir) {
	var app = express();
	app.config = require('./defaults');
	app.config.rootDir = rootDir;

	app.middleware = express;
	app.logger = logger;
	app.winston = winston;

	var Routing = require('./routing')(app);
	var DB = require('./db')(app);

	function readConfigFiles(configDir) {
		if (fs.existsSync(configDir)) {
			var configFiles = fs.readdirSync(configDir);
			configFiles.forEach(function(configFile) {
				var filePath = path.join(configDir, configFile);
				var stats = fs.statSync(filePath);
				try {
					if (stats.isFile())
						Object.merge(app.config, require(filePath), true);
				} catch(e) {
					logger.warn('Unable to read config file ' + filePath);
				}
			});
		}
	}
	// read config files
	var configDir = path.join(rootDir, app.config.paths.config);
	var environmentConfigDir = path.join(configDir, app.get('env'));
	readConfigFiles(configDir);
	readConfigFiles(environmentConfigDir);
	app.set('port', process.env.PORT || app.config.port);

	app.init = function(callback) {
		logger.info('initializing application...');
		app.db = {};
		app.models = {};
		app.controllers = {};

		if (app.config.logFile && !logger.transports['file']) {
			logger.add(winston.transports.File, {
				filename: app.config.logFile,
				json: false
			});
		}

		// setup view engines
		app.set('views', path.join(rootDir, app.config.paths.views));
		for (var extension in app.config.viewEngines) {
			var engine = app.config.viewEngines[extension];
			app.engine(extension, consolidate[engine]);
		}

		app.use(express.cookieParser());
		app.use(express.bodyParser());

		var winstonStream = {
			write: function(message) {
				logger.info(message);
			}
		};
		app.use(express.logger({
			stream: winstonStream
		}));

		// setup custom middleware
		app.config.middleware(app);

		// setup routing
		app.use(app.router);
		Routing.init();

		app.use(function(err, req, res, next) {
			if (err.name === 'NoSuchThingError') {
				err.status = 404;
			}
			next(err);
		});

		if ('development' === app.get('env')) {
			app.use(express.errorHandler());
		}

		// setup db
		DB.init(function(err) {
			if (err) return callback(err);

			// run init files
			var initDir = path.join(rootDir, app.config.paths.init);
			var initFiles = fs.readdirSync(initDir);
			async.each(initFiles, function(initFile, cb) {
				var initFunc = require(path.join(initDir, initFile));
				if (initFunc.length <= 1) {
					initFunc(app);
					cb();
				} else {
					initFunc(app, cb);
				}
			}, function(err) {
				if (callback)
					callback(err);
			});
		});

	};

	app.teardown = function(cb) {
		logger.info('shutting down...');
		DB.disconnect(function(err) {
			cb(err);
		});
	};

	app.scarab = scarab;
	return app;
}

scarab.run = function(app, cb) {
	scarab.server = http.createServer();
	scarab.server.listen(app.get('port'), function() {
		if (app.config.group)
			process.setgid(app.config.group);
		if (app.config.user)
			process.setuid(app.config.user);
		app.init(function(err) {
			if (err) throw err;

			scarab.server.on('request', app);
			scarab.server.app = app;

			logger.info('scarab server listening on port ' + app.get('port') + ' in ' + app.get('env') + ' mode.');
			if (cb) cb(scarab.server);
		});
	});

	var quit = function() {
		scarab.server.app.teardown(function(err) {
			if (err) throw err;
			process.exit();
		});
	};
	process.on('SIGTERM', quit);
	process.on('SIGINT', quit);
	process.on('SIGHUP', scarab.reload);
};

scarab.uncache = function() {
	for (var file in require.cache) {
		delete require.cache[file];
	}
};

scarab.replaceApp = function(app, cb) {
	if (!(scarab.server && scarab.server.app))
		return cb(new Error('No server running'));

	var oldApp = scarab.server.app;
	oldApp.teardown(function() {
		scarab.uncache();
		app.init(function(err) {
			if (err) return cb(err);
			scarab.server.removeAllListeners('request');
			scarab.server.on('request', app);
			scarab.server.app = app;
			cb();
		});
	});
};

scarab.reload = function(cb) {
	logger.info('reloading server...');
	var app = scarab(scarab.server.app.config.rootDir);
	scarab.replaceApp(app, function(err) {
		if (err) {
			if (cb) return cb(err);
			else throw err;
		}
		return cb && cb(null, app);
	});
};
module.exports = scarab;<|endoftext|>


<commit_before>import React from 'react';
import ErrorTryAgain from '../common/ErrorTryAgain';
import LoadingSpinner from '../common/LoadingSpinner';
import * as fetchConstants from '../../lib/fetchConstants';

// pass this in as the second arg to not show a spinner
export const NO_SPINNER = 0;

/**
 * Use this with the JS Composition pattern to make a Container do an async fetch for you.
 * The container MUST expose a `asyncFetch` method that takes no arguments. Most likely that
 * method will call out to a fetchData property that reads the params to use from the state
 * (via mergeProps).
 * Pass in a loadingSpinnerSize of 0 to not display it at all.
 */
export const asyncContainerize = (ChildComponent, loadingSpinnerSize) => {
  const spinnerSize = (loadingSpinnerSize !== undefined) ? loadingSpinnerSize : null;
  class ComposedAsyncContainer extends React.Component {
    state = {
      asyncFetchResult: undefined,
      hasShowResults: false,
    };
    componentDidMount() {
      const { asyncFetch } = this.props;
      const asyncFetchResult = asyncFetch();
      this.state = { asyncFetchResult };
    }
    componentWillReceiveProps(nextProps) {
      if (nextProps.fetchStatus === fetchConstants.FETCH_SUCCEEDED) {
        this.setState({ hasShowResults: true });
      }
    }
    render() {
      const { fetchStatus, asyncFetch } = this.props;
      if (asyncFetch === undefined) {
        const error = { message: 'No asyncFetch defined for your container!', child: ChildComponent };
        throw error;
      }
      let content = null;
      if (this.state.asyncFetchResult === 'hide') {
        content = null;
      } else {
        switch (fetchStatus) {
          case fetchConstants.FETCH_ONGOING:
            if (this.state.hasShowResults) {
              content = (

                  <ChildComponent {...this.props} />

                      <LoadingSpinner size={spinnerSize} />

              );
            } else if (loadingSpinnerSize !== 0) {
              content = <LoadingSpinner size={spinnerSize} />;
            }
            break;
          case fetchConstants.FETCH_SUCCEEDED:
            content = <ChildComponent {...this.props} />;
            break;
          case fetchConstants.FETCH_FAILED:
            content = (

                <ChildComponent {...this.props} />

                    <ErrorTryAgain onTryAgain={asyncFetch} />;

            );
            break;
          default:
            break;
        }
      }
      return content;
    }
  }
  ComposedAsyncContainer.propTypes = {
    fetchStatus: React.PropTypes.string.isRequired,
    asyncFetch: React.PropTypes.func.isRequired,
  };
  return ComposedAsyncContainer;
};

const composeAsyncContainer = asyncContainerize;  // the method can't be used as the name of the default import

export default composeAsyncContainer;

<commit_msg>remove spurious semicolon<commit_after>import React from 'react';
import ErrorTryAgain from '../common/ErrorTryAgain';
import LoadingSpinner from '../common/LoadingSpinner';
import * as fetchConstants from '../../lib/fetchConstants';

// pass this in as the second arg to not show a spinner
export const NO_SPINNER = 0;

/**
 * Use this with the JS Composition pattern to make a Container do an async fetch for you.
 * The container MUST expose a `asyncFetch` method that takes no arguments. Most likely that
 * method will call out to a fetchData property that reads the params to use from the state
 * (via mergeProps).
 * Pass in a loadingSpinnerSize of 0 to not display it at all.
 */
export const asyncContainerize = (ChildComponent, loadingSpinnerSize) => {
  const spinnerSize = (loadingSpinnerSize !== undefined) ? loadingSpinnerSize : null;
  class ComposedAsyncContainer extends React.Component {
    state = {
      asyncFetchResult: undefined,
      hasShowResults: false,
    };
    componentDidMount() {
      const { asyncFetch } = this.props;
      const asyncFetchResult = asyncFetch();
      this.state = { asyncFetchResult };
    }
    componentWillReceiveProps(nextProps) {
      if (nextProps.fetchStatus === fetchConstants.FETCH_SUCCEEDED) {
        this.setState({ hasShowResults: true });
      }
    }
    render() {
      const { fetchStatus, asyncFetch } = this.props;
      if (asyncFetch === undefined) {
        const error = { message: 'No asyncFetch defined for your container!', child: ChildComponent };
        throw error;
      }
      let content = null;
      if (this.state.asyncFetchResult === 'hide') {
        content = null;
      } else {
        switch (fetchStatus) {
          case fetchConstants.FETCH_ONGOING:
            if (this.state.hasShowResults) {
              content = (

                  <ChildComponent {...this.props} />

                      <LoadingSpinner size={spinnerSize} />

              );
            } else if (loadingSpinnerSize !== 0) {
              content = <LoadingSpinner size={spinnerSize} />;
            }
            break;
          case fetchConstants.FETCH_SUCCEEDED:
            content = <ChildComponent {...this.props} />;
            break;
          case fetchConstants.FETCH_FAILED:
            content = (

                <ChildComponent {...this.props} />

                    <ErrorTryAgain onTryAgain={asyncFetch} />

            );
            break;
          default:
            break;
        }
      }
      return content;
    }
  }
  ComposedAsyncContainer.propTypes = {
    fetchStatus: React.PropTypes.string.isRequired,
    asyncFetch: React.PropTypes.func.isRequired,
  };
  return ComposedAsyncContainer;
};

const composeAsyncContainer = asyncContainerize;  // the method can't be used as the name of the default import

export default composeAsyncContainer;

<|endoftext|>


<commit_before>(function() {
  /**
   * @constructor OctoBacon
   * Class for a text-editor
   * @param {string} querySelectorString The query selector string for the
   *   container div.
   * @param {object} syntaxHighlightingLanguage The language to use syntax
   *   highlighting for.
   * @param {object} styleClasses The class names for elements to be assigned.
   */
  function OctoBacon(querySelectorString, syntaxHighlighter, styleClasses) {
    this.container_ = document.querySelector(querySelectorString);
    this.styles = styleClasses;
    this.createAndSetUpElements_();

    var lang = syntaxHighlighter.language;
    var interval = syntaxHighlighter.interval;
    if (lang in OctoBacon.highlighters && interval > 0) {
      this.highlighterIntervalId = window.setInterval(function() {
        OctoBacon.highlighters[lang].highlight(this);
      }, interval);
    }
  }

  /**
   * @function Creates the elements needed for the text editor, excluding style
   *   sheets.
   */
   OctoBacon.prototype.createAndSetUpElements_ = function() {
     var textarea = document.createElement('textarea');
     var div = document.createElement('div');

     textarea.width = this.container_.width;
     textarea.height = this.container_.height;
     textarea.classList.add(this.styles.taClass);
     div.width = this.container_.width;
     div.height = this.container_.height;
     div.classList.add(this.styles.divClass);

     textarea.addEventListener('scroll', function() {
       div.scrollTop = textarea.scrollTop;
     });

     this.textarea = textarea;
     this.div = div;
   };

    function OctoBaconSyntaxHighlighter(styles, highlight) {
      var style = document.createElement('style');
      var css = '';
      for (var htmlClass in styles) {
        var color = styles[htmlClass];
        css += ('.' + htmlClass + '{' + 'color: ' + color + ';}\n');
      }
      style.innerHTML = css;
      document.getElementsByTagName('head')[0].appendChild(style);

      this.stylesObj = styles;
      this.highlight = function(octoBaconInstance) {
        var highlightedText = highlight(octoBaconInstance.textarea.value);
        octoBaconInstance.div.innerHTML = highlightedText;
      };
    }

    OctoBacon.highlighters = {};

    OctoBacon.highlighters.js = new OctoBaconSyntaxHighlighter({
      'ob-js-kw': 'purple', // keywords
      'ob-js-bnun': 'cyan', // booleans, null, undefined, numbers
      'ob-js-str': 'blue', // strings
      'ob-js-fm': 'magenta', // function or method
    }, function(text) {
      var strReg = /'[^']*'/g;
      var strReg2 = /"[^"]*"/g;
      var bnunReg = /\b(\d|true|false|null|undefined)\b/g;
      var keywordReg = /\b(var|let|const|function|class|if|else|while|for|in|of|switch|case|try|catch|throw|finally|void|continue|break|return|do)\b/g;
      var funcReg = /\b(\w*())\b/g;

      return text.replace(strReg, '$&').
        replace(strReg2, '$&').
        replace(bnunReg, '$1').
        replace(keywordReg, '$1').
        replace(funcReg, '$1');
    });

  window['OctoBacon'] = OctoBacon;
})();
<commit_msg>Appends child elements to bacon container<commit_after>(function() {
  /**
   * @constructor OctoBacon
   * Class for a text-editor
   * @param {string} querySelectorString The query selector string for the
   *   container div.
   * @param {object} syntaxHighlightingLanguage The language to use syntax
   *   highlighting for.
   * @param {object} styleClasses The class names for elements to be assigned.
   */
  function OctoBacon(querySelectorString, syntaxHighlighter, styleClasses) {
    this.container_ = document.querySelector(querySelectorString);
    this.styles = styleClasses;
    this.createAndSetUpElements_();

    var lang = syntaxHighlighter.language;
    var interval = syntaxHighlighter.interval;
    if (lang in OctoBacon.highlighters && interval > 0) {
      this.highlighterIntervalId = window.setInterval(function() {
        OctoBacon.highlighters[lang].highlight(this);
      }, interval);
    }
  }

  /**
   * @function Creates the elements needed for the text editor, excluding style
   *   sheets.
   */
   OctoBacon.prototype.createAndSetUpElements_ = function() {
     var textarea = document.createElement('textarea');
     var div = document.createElement('div');

     textarea.width = this.container_.width;
     textarea.height = this.container_.height;
     textarea.classList.add(this.styles.taClass);
     div.width = this.container_.width;
     div.height = this.container_.height;
     div.classList.add(this.styles.divClass);

     textarea.addEventListener('scroll', function() {
       div.scrollTop = textarea.scrollTop;
     });
     this.container_.appendChild(textarea);
     this.container_.appendChild(div);

     this.textarea = textarea;
     this.div = div;
   };

    function OctoBaconSyntaxHighlighter(styles, highlight) {
      var style = document.createElement('style');
      var css = '';
      for (var htmlClass in styles) {
        var color = styles[htmlClass];
        css += ('.' + htmlClass + '{' + 'color: ' + color + ';}\n');
      }
      style.innerHTML = css;
      document.getElementsByTagName('head')[0].appendChild(style);

      this.stylesObj = styles;
      this.highlight = function(octoBaconInstance) {
        var highlightedText = highlight(octoBaconInstance.textarea.value);
        octoBaconInstance.div.innerHTML = highlightedText;
      };
    }

    OctoBacon.highlighters = {};

    OctoBacon.highlighters.js = new OctoBaconSyntaxHighlighter({
      'ob-js-kw': 'purple', // keywords
      'ob-js-bnun': 'cyan', // booleans, null, undefined, numbers
      'ob-js-str': 'blue', // strings
      'ob-js-fm': 'magenta', // function or method
    }, function(text) {
      var strReg = /'[^']*'/g;
      var strReg2 = /"[^"]*"/g;
      var bnunReg = /\b(\d|true|false|null|undefined)\b/g;
      var keywordReg = /\b(var|let|const|function|class|if|else|while|for|in|of|switch|case|try|catch|throw|finally|void|continue|break|return|do)\b/g;
      var funcReg = /\b(\w*())\b/g;

      return text.replace(strReg, '$&').
        replace(strReg2, '$&').
        replace(bnunReg, '$1').
        replace(keywordReg, '$1').
        replace(funcReg, '$1');
    });

  window['OctoBacon'] = OctoBacon;
})();
<|endoftext|>


<commit_before>import React from 'react';

import { Navigation, NavigationItem,  NavigationLink } from '~/components/navigation';

export default (props) => (<Navigation {...props}>
      <NavigationItem>
          <NavigationLink exact to="/">Home</NavigationLink>
      </NavigationItem>
      <NavigationItem>
          <NavigationLink to="/services">Services</NavigationLink>
      </NavigationItem>
      <NavigationItem>
          <NavigationLink to="/visas">Visas</NavigationLink>
      </NavigationItem>
      <NavigationItem>
          <NavigationLink to="/contact">Contact</NavigationLink>
      </NavigationItem>
      <NavigationItem>
          <NavigationLink to="/news">News</NavigationLink>
      </NavigationItem>
</Navigation>)
<commit_msg>feat(navigation): add citizenship link<commit_after>import React from 'react';

import { Navigation, NavigationItem,  NavigationLink } from '~/components/navigation';

export default (props) => (<Navigation {...props}>
      <NavigationItem>
          <NavigationLink exact to="/">Home</NavigationLink>
      </NavigationItem>
      <NavigationItem>
          <NavigationLink to="/services">Services</NavigationLink>
      </NavigationItem>
      <NavigationItem>
          <NavigationLink to="/visas">Visas</NavigationLink>
      </NavigationItem>
      <NavigationItem>
          <NavigationLink to="/citizenship">Visas</NavigationLink>
      </NavigationItem>
      <NavigationItem>
          <NavigationLink to="/contact">Contact</NavigationLink>
      </NavigationItem>
      <NavigationItem>
          <NavigationLink to="/news">News</NavigationLink>
      </NavigationItem>
</Navigation>)
<|endoftext|>


<commit_before>/**
 * Search term in array
 * @param  {Array} items Array of items
 * @param  {String} term Search term
 * @param  {Function} toString Function that converts item from array to string
 * @return {Array}
 */
export default (items, term, toString = (item) => item) => {
  const searchTerm = term.toLowerCase();
  return items.filter(item =>
    // TODO: fuzzy-search instead of simple search here
    toString(item).toLowerCase().indexOf(searchTerm) !== -1
  );
};
<commit_msg>Improved search<commit_after>import lowerCase from 'lodash/lowerCase';
import memoize from 'memoizee';
import escapeStringRegexp from 'escape-string-regexp';

/**
 * Convert string to searchable lower-case string prepared for regexp search of search term
 * NOTE: lodash lowerCase convers `AppName` to `app name` (that we need),
 *       when standard js `.toLowerCase` converts it to `appname`.
 *
 * @param  {String} string
 * @return {String}
 */
const toSearchString = memoize((string) => lowerCase(string));

/**
 * Get regexp for search term
 *
 * @param  {String} term
 * @return {Regexp}
 */
const toSearchRegexp = memoize((term) => new RegExp(`(^|\\s)${escapeStringRegexp(toSearchString(term))}`));

/**
 * Search term in array
 * @param  {Array} items Array of items
 * @param  {String} term Search term
 * @param  {Function} toString Function that converts item from array to string
 * @return {Array}
 */
export default (items, term, toString = (item) => item) => {
  const searchRegexp = toSearchRegexp(term);
  return items.filter(item =>
    toSearchString(toString(item)).match(searchRegexp)
  );
};
<|endoftext|>


<commit_before>import React, { Component } from "react";
import { Col } from "reactstrap";

class StoryIcon extends Component {
  render() {
    return (
      <Col xs={2} md={4} className="text-center">
        {this.props.children}
      </Col>
    );
  }
}

export default StoryIcon;
<commit_msg>convert StoryIcon to functional component<commit_after>import React from "react";
import { Col } from "reactstrap";

const StoryIcon = props => {
  return (
    <Col xs={2} md={4} className="text-center">
      {props.children}
    </Col>
  );
};

export default StoryIcon;
<|endoftext|>


<commit_before>"use strict"

const fs = require("fs");
const Path = require("path");
const HANDLERS_PATH = Path.join(__dirname, "lib/handlers");

exprots.find = () => {};
exports.buildSchemaObject = (path) => {

    // check if schema object reached
    if (path.indexOf('.json') > -1) {
        return require(path);
    }

    if (!fs.lstatSync(path).isDirectory()) {
        return;
    }

    let obj = {};
    let files = fs.readdirSync(path);
    for (let i = 0; i < files.length; ++i) {
        if (files[i].indexOf('.') === 0) {
            continue;
        }

        let file = buildSchemaObject(Path.join(path, files[i]));
        if (!file) {
            continue
        }

        obj[files[i]] = file;
    }
    return obj;
};
<commit_msg>fix typo<commit_after>"use strict"

const fs = require("fs");
const Path = require("path");
const HANDLERS_PATH = Path.join(__dirname, "lib/handlers");

exports.find = () => {};
exports.buildSchemaObject = (path) => {

    // check if schema object reached
    if (path.indexOf('.json') > -1) {
        return require(path);
    }

    if (!fs.lstatSync(path).isDirectory()) {
        return;
    }

    let obj = {};
    let files = fs.readdirSync(path);
    for (let i = 0; i < files.length; ++i) {
        if (files[i].indexOf('.') === 0) {
            continue;
        }

        let file = buildSchemaObject(Path.join(path, files[i]));
        if (!file) {
            continue
        }

        obj[files[i]] = file;
    }
    return obj;
};
<|endoftext|>