<commit_before>var _ = require( "lodash" );
var when = require( "when" );
var open = require( "open" );
var path = require( "path" );
var mocha = require( "gulp-spawn-mocha" );
var processhost = require( "processhost" )();
var cmdPostfix = process.platform === "win32" ? ".cmd" : "";
var defaults = {
	allSpecPaths: [ "./spec" ],
	behaviorSpecPaths: [ "./spec/behavior" ],
	integrationSpecPaths: [ "./spec/integration" ],
	specs: [ "**/*.spec.js" ],
	watchPaths: [ "./src/**/*", "./spec/**/*", "./resource/**/*" ],
	sources: [ "*.js", "{resource,src,spec}/**/*.js" ],
	coverageHtml: "./coverage/lcov-report/index.html",
	jscsCfgPath: ".jscsrc"
};
var jshint = require( "gulp-jshint" );
var jscs = require( "gulp-jscs" );
var gutil = require( "gulp-util" );
var gulpChanged = require( "gulp-changed" );
var stylish = require( "jshint-stylish" );

function permuPath( dirs, globs ) {
	return _.reduce( globs, function( accum, glb ) {
		Array.prototype.push.apply(
			accum,
			_.map( dirs, function( dir ) {
				return path.join( dir, glb );
			} )
		);
		return accum;
	}, [] );
}

module.exports = function( gulpRef, cfg ) {
	var gulp = require( "gulp-help" )( gulpRef, {
		aliases: [ "?" ]
	} );
	var options = _.defaults( cfg || {}, defaults );
	var processesDefined = false;

	function runSpecs( testCfg ) {
		var mochaOpts = {
			R: "spec",
			istanbul: testCfg.coverage ? { x: testCfg.coverageExclude } : false
		};
		if ( options.esnext ) {
			mochaOpts.r = "babel/register";
		}
		return gulp.src( testCfg.specs, { read: false } )
			.pipe( mocha( mochaOpts ) );
	}

	function test( specs ) {
		specs = specs || defaults.specs;
		return runSpecs( {
			specs: _.isArray( specs ) ? specs : [ specs ]
		} );
	}

	function testOnce( specs ) {
		return test( specs )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testAll( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.allSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} ).on( "error", _.noop );
	}

	function testAllAndExit( opt ) {
		return testAll( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testBehavior( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.behaviorSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} );
	}

	function testBehaviorAndExit( opt ) {
		return testBehavior( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testIntegration( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.integrationSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} );
	}

	function testIntegrationAndExit( opt ) {
		return testIntegration( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function cover( opt ) {
		var _opt = opt || _.clone( options );
		_opt.coverage = true;
		return testAll( _opt );
	}

	function showCoverage( opt ) {
		var _opt = opt || _.clone( options );
		_opt.coverage = true;
		return testAll( opt ).on( "end", function() {
			open( _opt.coverageHtml );
			process.exit();
		} );
	}

	function setupProcess( processName, opts ) {
		processesDefined = true;
		return processhost.start( processName, {
			command: opts.command || opts.cmd || "node" + cmdPostfix,
			args: opts.arguments || opts.args || [],
			stdio: opts.stdio || "inherits",
			restart: opts.restart
		} );
	}

	function setupProcesses( opts ) {
		processesDefined = true;
		return processhost.setup( opts );
	}

	function groklate( ngrok, opts ) {
		if ( !opts && !options.ngrok ) {
			throw new Error( "To use ngrok you must supply an options argument containing port, subdomain and token" );
		}
		var _opt = opts || options.ngrok;
		return when.promise( function( resolve, reject ) {
			ngrok.connect( {
				port: _opt.port,
				subdomain: _opt.subdomain,
				authtoken: _opt.token
			}, function( err, url ) {
					if ( err ) {
						reject( err );
					} else {
						resolve( url );
					}
				} );
		} );
	}

	function watch( opt, tasks ) {
		var _tasks;
		var _opt;
		if ( arguments.length === 1 ) {
			_opt = options;
			_tasks = opt;
		} else {
			_opt = opt;
			_tasks = tasks;
		}
		if ( processesDefined ) {
			_tasks.concat( "restartProcesses" );
		}
		return gulp.watch( _opt.watchPaths, _tasks );
	}

	function format( opt ) {
		var _opt = opt || options;
		return gulp.src( _opt.sources )
			.pipe( jscs( {
				configPath: _opt.jscsCfgPath,
				fix: true
			} ) )
			.on( "error", function( error ) {
				gutil.log( gutil.colors.red( error.message ) );
				this.end();
			} )
			.pipe( gulpChanged( ".", { hasChanged: gulpChanged.compareSha1Digest } ) )
			.pipe( gulp.dest( "." ) );
	}

	function lint( opt ) {
		var _opt = opt || options;
		return gulp.src( _opt.sources )
			.on( "error", function( error ) {
				gutil.log( gutil.colors.red( error.message + " in " + error.fileName ) );
				this.end();
			} )
			.pipe( jshint() )
			.pipe( jshint.reporter( stylish ) )
			.pipe( jshint.reporter( "fail" ) );
	}

	gulp.task( "restartProcesses", function( cb ) {
		processhost.restart()
			.then( function() {
				cb();
			}, function( err ) {
				cb( err );
			} );
	} );

	return {
		cover: cover,
		ngrok: groklate,
		process: setupProcess,
		setupProcesses: setupProcesses,
		showCoverage: showCoverage,
		test: test,
		testOnce: testOnce,
		testAll: testAll,
		testAllOnce: testAllAndExit,
		testBehavior: testBehavior,
		testBehaviorOnce: testBehaviorAndExit,
		testIntegration: testIntegration,
		testIntegrationOnce: testIntegrationAndExit,
		watch: watch,
		withCoverage: cover,
		format: format,
		lint: lint
	};
};
<commit_msg>Added option for setting istanbul options<commit_after>var _ = require( "lodash" );
var when = require( "when" );
var open = require( "open" );
var path = require( "path" );
var mocha = require( "gulp-spawn-mocha" );
var processhost = require( "processhost" )();
var cmdPostfix = process.platform === "win32" ? ".cmd" : "";
var defaults = {
	allSpecPaths: [ "./spec" ],
	behaviorSpecPaths: [ "./spec/behavior" ],
	integrationSpecPaths: [ "./spec/integration" ],
	specs: [ "**/*.spec.js" ],
	watchPaths: [ "./src/**/*", "./spec/**/*", "./resource/**/*" ],
	sources: [ "*.js", "{resource,src,spec}/**/*.js" ],
	coverageHtml: "./coverage/lcov-report/index.html",
	jscsCfgPath: ".jscsrc"
};
var jshint = require( "gulp-jshint" );
var jscs = require( "gulp-jscs" );
var gutil = require( "gulp-util" );
var gulpChanged = require( "gulp-changed" );
var stylish = require( "jshint-stylish" );

function permuPath( dirs, globs ) {
	return _.reduce( globs, function( accum, glb ) {
		Array.prototype.push.apply(
			accum,
			_.map( dirs, function( dir ) {
				return path.join( dir, glb );
			} )
		);
		return accum;
	}, [] );
}

module.exports = function( gulpRef, cfg ) {
	var gulp = require( "gulp-help" )( gulpRef, {
		aliases: [ "?" ]
	} );
	var options = _.defaults( cfg || {}, defaults );
	var processesDefined = false;

	function runSpecs( testCfg ) {
		var mochaOpts = {
			R: "spec",
			istanbul: testCfg.coverage ? _.extend( {
				x: testCfg.coverageExclude
			}, options.istanbul || {} ) : false
		};
		if ( options.esnext ) {
			mochaOpts.r = "babel/register";
		}
		return gulp.src( testCfg.specs, { read: false } )
			.pipe( mocha( mochaOpts ) );
	}

	function test( specs ) {
		specs = specs || defaults.specs;
		return runSpecs( {
			specs: _.isArray( specs ) ? specs : [ specs ]
		} );
	}

	function testOnce( specs ) {
		return test( specs )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testAll( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.allSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} ).on( "error", _.noop );
	}

	function testAllAndExit( opt ) {
		return testAll( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testBehavior( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.behaviorSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} );
	}

	function testBehaviorAndExit( opt ) {
		return testBehavior( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testIntegration( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.integrationSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} );
	}

	function testIntegrationAndExit( opt ) {
		return testIntegration( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function cover( opt ) {
		var _opt = opt || _.clone( options );
		_opt.coverage = true;
		return testAll( _opt );
	}

	function showCoverage( opt ) {
		var _opt = opt || _.clone( options );
		_opt.coverage = true;
		return testAll( opt ).on( "end", function() {
			open( _opt.coverageHtml );
			process.exit();
		} );
	}

	function setupProcess( processName, opts ) {
		processesDefined = true;
		return processhost.start( processName, {
			command: opts.command || opts.cmd || "node" + cmdPostfix,
			args: opts.arguments || opts.args || [],
			stdio: opts.stdio || "inherits",
			restart: opts.restart
		} );
	}

	function setupProcesses( opts ) {
		processesDefined = true;
		return processhost.setup( opts );
	}

	function groklate( ngrok, opts ) {
		if ( !opts && !options.ngrok ) {
			throw new Error( "To use ngrok you must supply an options argument containing port, subdomain and token" );
		}
		var _opt = opts || options.ngrok;
		return when.promise( function( resolve, reject ) {
			ngrok.connect( {
				port: _opt.port,
				subdomain: _opt.subdomain,
				authtoken: _opt.token
			}, function( err, url ) {
					if ( err ) {
						reject( err );
					} else {
						resolve( url );
					}
				} );
		} );
	}

	function watch( opt, tasks ) {
		var _tasks;
		var _opt;
		if ( arguments.length === 1 ) {
			_opt = options;
			_tasks = opt;
		} else {
			_opt = opt;
			_tasks = tasks;
		}
		if ( processesDefined ) {
			_tasks.concat( "restartProcesses" );
		}
		return gulp.watch( _opt.watchPaths, _tasks );
	}

	function format( opt ) {
		var _opt = opt || options;
		return gulp.src( _opt.sources )
			.pipe( jscs( {
				configPath: _opt.jscsCfgPath,
				fix: true
			} ) )
			.on( "error", function( error ) {
				gutil.log( gutil.colors.red( error.message ) );
				this.end();
			} )
			.pipe( gulpChanged( ".", { hasChanged: gulpChanged.compareSha1Digest } ) )
			.pipe( gulp.dest( "." ) );
	}

	function lint( opt ) {
		var _opt = opt || options;
		return gulp.src( _opt.sources )
			.on( "error", function( error ) {
				gutil.log( gutil.colors.red( error.message + " in " + error.fileName ) );
				this.end();
			} )
			.pipe( jshint() )
			.pipe( jshint.reporter( stylish ) )
			.pipe( jshint.reporter( "fail" ) );
	}

	gulp.task( "restartProcesses", function( cb ) {
		processhost.restart()
			.then( function() {
				cb();
			}, function( err ) {
				cb( err );
			} );
	} );

	return {
		cover: cover,
		ngrok: groklate,
		process: setupProcess,
		setupProcesses: setupProcesses,
		showCoverage: showCoverage,
		test: test,
		testOnce: testOnce,
		testAll: testAll,
		testAllOnce: testAllAndExit,
		testBehavior: testBehavior,
		testBehaviorOnce: testBehaviorAndExit,
		testIntegration: testIntegration,
		testIntegrationOnce: testIntegrationAndExit,
		watch: watch,
		withCoverage: cover,
		format: format,
		lint: lint
	};
};
<|endoftext|>


<commit_before>
var toposort = require('toposort')

/**
 * graph
 *
 * @param {Object} graph
 * @return {Function}
 */

module.exports = function(graph){
	var deps = toposort(makeEdges(graph))
	return compile(graph, deps)
}

function compile(graph, deps){
	var i = deps.length
	var src = ''
	var input = []
	var last = ''
	while (i--) {
		var dep = deps[i]
		if (dep in graph) {
			var fn = graph[dep].toString()
			var params = fn.match(/\((.*)\)/)[1]
			if (usesThis(fn)) {
				src += '  var '+dep+' = $'+dep+'.call(this'
				if ((/\w/).test(params)) {
					src += ',' + params
				}
				src += ')\n'
			} else {
				src += '  var '+dep+' = $'+dep+'('+params+')\n'
			}
			last = dep
		} else {
			input.push(dep)
		}
	}
	src += '  return '+last+'\n'
	src = 'function('+input.join()+'){\n'+src+'}'
	return eval(vars(graph) + '('+src+')')
}

function usesThis(fn){
	return (/\bthis\b/).test(fn)
}

function vars(graph){
	var src = ''
	for (var p in graph) {
		src += 'var $'+p+' = graph["'+p+'"];\n'
	}
	return src
}

function makeEdges(graph){
	var edges = []
	for (var p in graph) {
		params(graph[p]).forEach(function(dep){
			edges.push([p, dep])
		})
	}
	return edges
}

function params(fn){
	return fn.toString()
		.match(/\((.*)\)/)[1]
		.split(/ *, */)
}
<commit_msg>fix arg ordering issue<commit_after>
var toposort = require('toposort')

/**
 * graph
 *
 * @param {Object} graph
 * @return {Function}
 */

module.exports = function(graph){
	var deps = toposort(makeEdges(graph))
	return compile(graph, deps.reverse())
}

/**
 * compile to a function that computes each value of
 * the graph in the order specified by toposort
 *
 * @param {Object} graph
 * @param {Array} deps
 * @return {Function}
 */

function compile(graph, deps){
	var src = ''
	var input = []
	var last = ''
	deps.forEach(function(dep){
		if (dep in graph) {
			var fn = graph[dep].toString()
			var params = fn.match(/\((.*)\)/)[1]
			if (usesThis(fn)) {
				src += '  var '+dep+' = $'+dep+'.call(this'
				if ((/\w/).test(params)) {
					src += ',' + params
				}
				src += ')\n'
			} else {
				src += '  var '+dep+' = $'+dep+'('+params+')\n'
			}
			last = dep
		} else {
			input.unshift(dep)
		}
	})
	src += '  return '+last+'\n'
	src = 'function('+input.join()+'){\n'+src+'}'
	return eval(vars(graph) + '('+src+')')
}

function usesThis(fn){
	return (/\bthis\b/).test(fn)
}

/**
 * make graph keys accessable as variables
 *
 * @param {Object} graph
 * @return {String}
 */

function vars(graph){
	var src = ''
	for (var p in graph) {
		src += 'var $'+p+' = graph["'+p+'"];\n'
	}
	return src
}

/**
 * generate edges that toposort understands
 *
 * @param {Object} graph
 * @return {Array}
 */

function makeEdges(graph){
	var edges = []
	for (var p in graph) {
		params(graph[p]).forEach(function(dep){
			edges.push([p, dep])
		})
	}
	return edges
}

/**
 * extract a functions parameter list
 *
 * @param {Function} fn
 * @return {Array}
 */

function params(fn){
	return fn.toString()
		.match(/\((.*)\)/)[1]
		.split(/ *, */)
}
<|endoftext|>


<commit_before>"use strict"; // catch errors easier

// requirements
const client = require("./client.js");
const express = require("express");
const bodyParser = require("body-parser");
const issues = require("./issues.js");
const pullRequests = require("./pullRequests.js");
const travis = require("./travis.js");
const checkInactivity = require("./automations/checkInactivity.js");
const push = require("./push.js");

// server
const app = express(); // initialize express app
const port = process.env.PORT || 8080; // set post to 8080

app.listen(port, () => {
  console.log("Website is running on http://localhost:" + port); // localhost website testing
});

app.set("view engine", "ejs"); // set rendering engine

app.get("/", (req, res) => {
  res.redirect("https://github.com/zulip/zulipbot"); // redirect GET requests to GitHub repo
});

// parse JSON
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

// handle POST requests
app.post("/", (req, res) => {
  res.render("index"); // Send contents of index.ejs
  // check if event is for an issue opening or issue comment creation
  if (req.get("X-GitHub-Event") && req.get("X-GitHub-Event").includes("issue")) {
    issues.run(client, req.body); // send parsed payload to issues.js
  } else if (req.get("X-GitHub-Event") && req.get("X-GitHub-Event").includes("pull_request")) {
    pullRequests.run(client, req.body); // send parsed payload to pullRequests.js
  } else if (req.get("X-GitHub-Event") && req.get("X-GitHub-Event") === "push") {
    push.run(client, req.body);
  } else if (req.get("user-agent") && req.get("user-agent") === "Travis CI Notifications") {
    travis.run(client, JSON.parse(req.body.payload));
  }
});

process.on("unhandledRejection", promise => console.log("An unhandled promise rejection was detected!\nPromise ", promise));

if (client.cfg.checkInactivityTimeout) setInterval(() => checkInactivity.run(client), client.cfg.checkInactivityTimeout * 1000);
<commit_msg>bot: Improve unhandled promise rejection errors.<commit_after>"use strict"; // catch errors easier

// requirements
const client = require("./client.js");
const express = require("express");
const bodyParser = require("body-parser");
const issues = require("./issues.js");
const pullRequests = require("./pullRequests.js");
const travis = require("./travis.js");
const checkInactivity = require("./automations/checkInactivity.js");
const push = require("./push.js");

// server
const app = express(); // initialize express app
const port = process.env.PORT || 8080; // set post to 8080

app.listen(port, () => {
  console.log("Website is running on http://localhost:" + port); // localhost website testing
});

app.set("view engine", "ejs"); // set rendering engine

app.get("/", (req, res) => {
  res.redirect("https://github.com/zulip/zulipbot"); // redirect GET requests to GitHub repo
});

// parse JSON
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

// handle POST requests
app.post("/", (req, res) => {
  res.render("index"); // Send contents of index.ejs
  // check if event is for an issue opening or issue comment creation
  if (req.get("X-GitHub-Event") && req.get("X-GitHub-Event").includes("issue")) {
    issues.run(client, req.body); // send parsed payload to issues.js
  } else if (req.get("X-GitHub-Event") && req.get("X-GitHub-Event").includes("pull_request")) {
    pullRequests.run(client, req.body); // send parsed payload to pullRequests.js
  } else if (req.get("X-GitHub-Event") && req.get("X-GitHub-Event") === "push") {
    push.run(client, req.body);
  } else if (req.get("user-agent") && req.get("user-agent") === "Travis CI Notifications") {
    travis.run(client, JSON.parse(req.body.payload));
  }
});

process.on("unhandledRejection", (error, promise) => console.error("An unhandled promise rejection was detected at:", promise));

if (client.cfg.checkInactivityTimeout) setInterval(() => checkInactivity.run(client), client.cfg.checkInactivityTimeout * 1000);
<|endoftext|>


<commit_before>import { extend } from '../util';

/**
 * Check if two nodes are equivalent.
 *
 * @param {Element} node the element node
 *
 * @param {VNode} vnode the virtual node
 *
 * @param hyrdating
 *
 * @private
 */
export function isSameNodeType(node, vnode, hydrating) {
	if (typeof vnode==='string' || typeof vnode==='number') {
		return node.splitText!==undefined;
	}
	if (typeof vnode.nodeName==='string') {
		return !node._componentConstructor && isNamedNode(node, vnode.nodeName);
	}
	return hydrating || node._componentConstructor===vnode.nodeName;
}

/**
 * Check if an Element has a given normalized name.
 *
 * @param {Element} node the Element to check name for
 *
 * @param {String} nodeName the normalized name
 */
export function isNamedNode(node, nodeName) {
	return node.normalizedNodeName===nodeName || node.nodeName.toLowerCase()===nodeName.toLowerCase();
}

/**
 * Reconstruct Component-style `props` from a VNode.
 * Ensures default/fallback values from `defaultProps`:
 * Own-properties of `defaultProps` not present in `vnode.attributes` are added.
 *
 * @param {VNode} vnode
 *
 * @returns {Object} props
 */
export function getNodeProps(vnode) {
	let props = extend({}, vnode.attributes);
	props.children = vnode.children;

	let defaultProps = vnode.nodeName.defaultProps;
	if (defaultProps!==undefined) {
		for (let i in defaultProps) {
			if (props[i]===undefined) {
				props[i] = defaultProps[i];
			}
		}
	}

	return props;
}
<commit_msg>Update index.js<commit_after>import { extend } from '../util';

/**
 * Check if two nodes are equivalent.
 *
 * @param {Node} node			DOM Node to compare
 * @param {VNode} vnode			Virtual DOM node to compare
 * @param {boolean} [hyrdating=false]	If true, ignores component constructors when comparing.
 * @private
 */
export function isSameNodeType(node, vnode, hydrating) {
	if (typeof vnode==='string' || typeof vnode==='number') {
		return node.splitText!==undefined;
	}
	if (typeof vnode.nodeName==='string') {
		return !node._componentConstructor && isNamedNode(node, vnode.nodeName);
	}
	return hydrating || node._componentConstructor===vnode.nodeName;
}

/**
 * Check if an Element has a given nodeName, case-insensitively.
 *
 * @param {Element} node	A DOM Element to inspect the name of.
 * @param {String} nodeName	Unnormalized name to compare against.
 */
export function isNamedNode(node, nodeName) {
	return node.normalizedNodeName===nodeName || node.nodeName.toLowerCase()===nodeName.toLowerCase();
}

/**
 * Reconstruct Component-style `props` from a VNode.
 * Ensures default/fallback values from `defaultProps`:
 * Own-properties of `defaultProps` not present in `vnode.attributes` are added.
 *
 * @param {VNode} vnode
 * @returns {Object} props
 */
export function getNodeProps(vnode) {
	let props = extend({}, vnode.attributes);
	props.children = vnode.children;

	let defaultProps = vnode.nodeName.defaultProps;
	if (defaultProps!==undefined) {
		for (let i in defaultProps) {
			if (props[i]===undefined) {
				props[i] = defaultProps[i];
			}
		}
	}

	return props;
}
<|endoftext|>


<commit_before>"use strict";

const config = { region: process.env.SERVERLESS_REGION }

// Common
const Rx  = require('rx')
const AWS = require('aws-sdk')

const dynamodb = new AWS.DynamoDB.DocumentClient(config)

// TODO:
// -----
// Improve this module functionality.
// The default functionality should require the inclusion of
// only the Item or Keys being modified. It should provide some
// default DynamoDB default keys, which should be modifiable
// using the options object.
function DynamoDBObservablesConstructor() {
	/**
	 * Returns a function that returns an observable
	 * from a DynamoDB Document client method
	 * @param  {String} method  DynamoDB document client method name
	 * @return {Function}       Function that returns an observable from a DynamoDB method
	 */
	const observableFromDynamodbDocumentClient = (method) => (params, options) => {
	 	// @param  {Object} params  Full DynamoDB document client object or Item if options.default === true
	 	// @param  {Object} options Options to configure the method call
		options      || (options = {})      // options default value
		options.item || (options.item = {}) // options.item default value
		// If default === true, we merge the default Dynamo options
		// with default options.
		if (options.default === true) {
			// If options.table is undefined throw
			if (!options.table) throw new Error('"options.table" is not defined')
			const table    = options.table
			const _params  = options.params || {}
			const defaults = defaultParams[method](params, table)
			// if _params.Item exists it will override the defauls
			params = Object.assign({}, defaults, _params)
		}
		return callDynamodbDocumentClientMethod(method, params)
	}
	/**
	 * Calls the apropiate DynamoDB Document Client method
	 * @param  {String} method Method name
	 * @param  {Object} params Params object
	 * @return {Observer}      DynamoDB document client method observable
	 */
	const callDynamodbDocumentClientMethod = (method, params) => Rx.Observable
		.create(observer => {
			try {
				dynamodb[method](params, (err, data) => {
					if (err) return observer.onError(err)
					observer.onNext(data)
					observer.onCompleted()
				})
			} catch (error) {
				observer.onError(error)
			}
		})
	/**
	 * Returns the params of a basic session
	 * @param  {Object} data Event data
	 * @param  {Date}   date Current date
	 * @return {Object}      Session Initialization params
	 */
	const putParams = (item, table) => ({
		TableName: table,
		Item: item,
		ReturnConsumedCapacity: 'NONE',
	  ReturnItemCollectionMetrics: 'NONE',
	  ReturnValues: 'NONE'
	})
	const defaultParams = Object.freeze({
		put: putParams
	})
	return Object.freeze({
		getItem   : observableFromDynamodbDocumentClient('get'),
		updateItem: observableFromDynamodbDocumentClient('update'),
		putItem   : observableFromDynamodbDocumentClient('put'),
		queryItem : observableFromDynamodbDocumentClient('query'),
		scam      : observableFromDynamodbDocumentClient('scan'),
	})
}

const DynamodbObs = new DynamoDBObservablesConstructor()

exports = module.exports = DynamodbObs<commit_msg>fixed a typo on the main file<commit_after>"use strict";

const config = { region: process.env.SERVERLESS_REGION }

// Common
const Rx  = require('rx')
const AWS = require('aws-sdk')

const dynamodb = new AWS.DynamoDB.DocumentClient(config)

// TODO:
// -----
// Improve this module functionality.
// The default functionality should require the inclusion of
// only the Item or Keys being modified. It should provide some
// default DynamoDB default keys, which should be modifiable
// using the options object.
function DynamoDBObservablesConstructor() {
	/**
	 * Returns a function that returns an observable
	 * from a DynamoDB Document client method
	 * @param  {String} method  DynamoDB document client method name
	 * @return {Function}       Function that returns an observable from a DynamoDB method
	 */
	const observableFromDynamodbDocumentClient = (method) => (params, options) => {
	 	// @param  {Object} params  Full DynamoDB document client object or Item if options.default === true
	 	// @param  {Object} options Options to configure the method call
		options      || (options = {})      // options default value
		options.item || (options.item = {}) // options.item default value
		// If default === true, we merge the default Dynamo options
		// with default options.
		if (options.default === true) {
			// If options.table is undefined throw
			if (!options.table) throw new Error('"options.table" is not defined')
			const table    = options.table
			const _params  = options.params || {}
			const defaults = defaultParams[method](params, table)
			// if _params.Item exists it will override the defauls
			params = Object.assign({}, defaults, _params)
		}
		return callDynamodbDocumentClientMethod(method, params)
	}
	/**
	 * Calls the apropiate DynamoDB Document Client method
	 * @param  {String} method Method name
	 * @param  {Object} params Params object
	 * @return {Observer}      DynamoDB document client method observable
	 */
	const callDynamodbDocumentClientMethod = (method, params) => Rx.Observable
		.create(observer => {
			try {
				dynamodb[method](params, (err, data) => {
					if (err) return observer.onError(err)
					observer.onNext(data)
					observer.onCompleted()
				})
			} catch (error) {
				observer.onError(error)
			}
		})
	/**
	 * Returns the params of a basic session
	 * @param  {Object} data Event data
	 * @param  {Date}   date Current date
	 * @return {Object}      Session Initialization params
	 */
	const putParams = (item, table) => ({
		TableName: table,
		Item: item,
		ReturnConsumedCapacity: 'NONE',
	  ReturnItemCollectionMetrics: 'NONE',
	  ReturnValues: 'NONE'
	})
	const defaultParams = Object.freeze({
		put: putParams
	})
	return Object.freeze({
		getItem   : observableFromDynamodbDocumentClient('get'),
		updateItem: observableFromDynamodbDocumentClient('update'),
		putItem   : observableFromDynamodbDocumentClient('put'),
		queryItem : observableFromDynamodbDocumentClient('query'),
		scan      : observableFromDynamodbDocumentClient('scan'),
	})
}

const DynamodbObs = new DynamoDBObservablesConstructor()

exports = module.exports = DynamodbObs<|endoftext|>


<commit_before>import {Parser} from './parser';

let defaultOptions = {
  path: './',
  file: 'aurelia.env'
};

export function load(options) {
  window.env = {};
  let _options = Object.assign({}, options, defaultOptions);

  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', _options.path + _options.file);
    xhr.onload = function() {
      if (this.status >= 200 && this.status < 300) {
        let parsedObject = Parser.parse(xhr.response);
        Object.keys(parsedObject).forEach(key => {
          window.env[key] = parsedObject[key];
        });
        resolve();
      } else {
        reject({
          status: this.status,
          statusText: xhr.statusText
        });
      }
    };

    xhr.onerror = function() {
      reject({
        status: this.status,
        statusText: xhr.statusText
      });
    };
    xhr.send();
  });
}
<commit_msg>fix(options): switch default options with custom<commit_after>import {Parser} from './parser';

let defaultOptions = {
  path: './',
  file: 'aurelia.env'
};

export function load(options) {
  window.env = {};
  let _options = Object.assign({}, defaultOptions, options);

  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', _options.path + _options.file);
    xhr.onload = function() {
      if (this.status >= 200 && this.status < 300) {
        let parsedObject = Parser.parse(xhr.response);
        Object.keys(parsedObject).forEach(key => {
          window.env[key] = parsedObject[key];
        });
        resolve();
      } else {
        reject({
          status: this.status,
          statusText: xhr.statusText
        });
      }
    };

    xhr.onerror = function() {
      reject({
        status: this.status,
        statusText: xhr.statusText
      });
    };
    xhr.send();
  });
}
<|endoftext|>


<commit_before>'use strict';
var Alexa = require("alexa-sdk");
var request = require("request");
var APP_ID = "amzn1.ask.skill.c958f220-e3fb-4d54-876a-f9bf0e7bf43c"

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.registerHandlers(handlers);
    alexa.execute();
};

var handlers = {
    'LaunchRequest': function () {
        this.emit('SayLunch');
    },
    'unhandled': function () {
        this.emit('SayLunch');
    },
    'LunchIntent': function () {
        this.emit('SayLunch');
    },
    'SayLunch': function () {
        var dateSlot = this.event.request.intent.slots.Date
        if (dateSlot && dateSlot.value) {
            var dateRequested = getDateFromSlot(dateSlot.value);
            console.log('Date specified.');
        }
        else {
            var dateRequested=new Date();
            console.log('No date in slot.');
        }
        console.log('The date requested is', dateRequested.toString());

        var ical = require('ical');
        ical.fromURL('http://www.chapin.edu/data/calendar/rsscache/calendar_282.ics', {}, function(err, data) {
        for (var k in data){
            if (data.hasOwnProperty(k)) {
              var ev = data[k]
//              console.log(ev.start.toString());
              if (dateRequested.getDate() == ev.start.getDate() && dateRequested.getMonth() == ev.start.getMonth())  {
                    console.log("Lunch is", ev.summary, 'on ', ev.start.getDate());
                    var speechOutput = "Lunch is" + ev.summary + 'on ' + ev.start.getDate();
                    this.emit(':tell', speechOutput);

              }

            }
          }
        }); //ical

    } //saylunch
}; //handlers

// Given an AMAZON.DATE slot value parse out to usable JavaScript Date object
// Utterances that map to the weekend for a specific week (such as �this weekend�) convert to a date indicating the week number and weekend: 2015-W49-WE.
// Utterances that map to a month, but not a specific day (such as �next month�, or �December�) convert to a date with just the year and month: 2015-12.
// Utterances that map to a year (such as �next year�) convert to a date containing just the year: 2016.
// Utterances that map to a decade convert to a date indicating the decade: 201X.
// Utterances that map to a season (such as �next winter�) convert to a date with the year and a season indicator: winter: WI, spring: SP, summer: SU, fall: FA)
function getDateFromSlot(rawDate) {
    // try to parse data
    var date = new Date(Date.parse(rawDate));
    return date;
    var result;
    // create an empty object to use later
    var eventDate = {

    };

    // if could not parse data must be one of the other formats
    if (isNaN(date)) {
        // to find out what type of date this is, we can split it and count how many parts we have see comments above.
        var res = rawDate.split("-");
        // if we have 2 bits that include a 'W' week number
        if (res.length === 2 && res[1].indexOf('W') > -1) {
            var dates = getWeekData(res);
            eventDate["startDate"] = new Date(dates.startDate);
            eventDate["endDate"] = new Date(dates.endDate);
            // if we have 3 bits, we could either have a valid date (which would have parsed already) or a weekend
        } else if (res.length === 3) {
            var dates = getWeekendData(res);
            eventDate["startDate"] = new Date(dates.startDate);
            eventDate["endDate"] = new Date(dates.endDate);
            // anything else would be out of range for this skill
        } else {
            eventDate["error"] = dateOutOfRange;
        }
        // original slot value was parsed correctly
    } else {
        eventDate["startDate"] = new Date(date).setUTCHours(0, 0, 0, 0);
        eventDate["endDate"] = new Date(date).setUTCHours(24, 0, 0, 0);
    }
    return eventDate;
}
<commit_msg>Update index.js<commit_after>'use strict';
var Alexa = require("alexa-sdk");
var request = require("request");
var APP_ID = "amzn1.ask.skill.c958f220-e3fb-4d54-876a-f9bf0e7bf43c"

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.registerHandlers(handlers);
    alexa.execute();
};

var handlers = {
    'LaunchRequest': function () {
        this.emit('SayLunch');
    },
    'unhandled': function () {
        this.emit('SayLunch');
    },
    'LunchIntent': function () {
        this.emit('SayLunch');
    },
    'SayLunch': function () {
        var speechOutput = "I am having trouble getting the lunch menu.";

        var dateSlot = this.event.request.intent.slots.Date
        if (dateSlot && dateSlot.value) {
            var dateRequested = getDateFromSlot(dateSlot.value);
            console.log('Date specified.');
        }
        else {
            var dateRequested=new Date();
            console.log('No date in slot.');
        }
        console.log('The date requested is', dateRequested.toString());

        var ical = require('ical');
        ical.fromURL('http://www.chapin.edu/data/calendar/rsscache/calendar_282.ics', {}, function(err, data) {
        for (var k in data){
            if (data.hasOwnProperty(k)) {
              var ev = data[k]
//              console.log(ev.start.toString());
              if (dateRequested.getDate() == ev.start.getDate() && dateRequested.getMonth() == ev.start.getMonth())  {
                    speechOutput = "Lunch is" + ev.summary + 'on ' + ev.start.getDate();
                    console.log(speechOutput);

              }

            }
          }
          this.emit(':tell', speechOutput);
        }); //ical

    } //saylunch
}; //handlers

// Given an AMAZON.DATE slot value parse out to usable JavaScript Date object
// Utterances that map to the weekend for a specific week (such as �this weekend�) convert to a date indicating the week number and weekend: 2015-W49-WE.
// Utterances that map to a month, but not a specific day (such as �next month�, or �December�) convert to a date with just the year and month: 2015-12.
// Utterances that map to a year (such as �next year�) convert to a date containing just the year: 2016.
// Utterances that map to a decade convert to a date indicating the decade: 201X.
// Utterances that map to a season (such as �next winter�) convert to a date with the year and a season indicator: winter: WI, spring: SP, summer: SU, fall: FA)
function getDateFromSlot(rawDate) {
    // try to parse data
    var date = new Date(Date.parse(rawDate));
    return date;
    var result;
    // create an empty object to use later
    var eventDate = {

    };

    // if could not parse data must be one of the other formats
    if (isNaN(date)) {
        // to find out what type of date this is, we can split it and count how many parts we have see comments above.
        var res = rawDate.split("-");
        // if we have 2 bits that include a 'W' week number
        if (res.length === 2 && res[1].indexOf('W') > -1) {
            var dates = getWeekData(res);
            eventDate["startDate"] = new Date(dates.startDate);
            eventDate["endDate"] = new Date(dates.endDate);
            // if we have 3 bits, we could either have a valid date (which would have parsed already) or a weekend
        } else if (res.length === 3) {
            var dates = getWeekendData(res);
            eventDate["startDate"] = new Date(dates.startDate);
            eventDate["endDate"] = new Date(dates.endDate);
            // anything else would be out of range for this skill
        } else {
            eventDate["error"] = dateOutOfRange;
        }
        // original slot value was parsed correctly
    } else {
        eventDate["startDate"] = new Date(date).setUTCHours(0, 0, 0, 0);
        eventDate["endDate"] = new Date(date).setUTCHours(24, 0, 0, 0);
    }
    return eventDate;
}
<|endoftext|>


<commit_before>var PluginError = require('gulp-util').PluginError;
var assign      = require('lodash.assign');
var fm          = require('front-matter');
var isEqual     = require('lodash.isequal');
var path        = require('path');
var through     = require('through2');
var yaml        = require('js-yaml');

var parse = require('./parse');

module.exports = function(options) {

  options = assign({
    defaultLocale:  null,
    locales:        null,
    site:           null,
    templateEngine: require('./engines/nunjucks')(),
    draft:          false,
    dataExtensions: ['yml', 'yaml', 'json'],
  }, options);

  // ===
  // ===

  var vinyls = [];

  // transform
  // =========

  var transform = function(vinyl, _, done) {
    if (vinyl.isNull()) {
      return done(null, vinyl);
    }
    if (vinyl.isStream()) {
      return done(new PluginError('gulp-minisite', 'Streaming not supported'));
    }

    vinyls.push(vinyl);
    return done();
  };

  // flush
  // =====

  var flush = function(done) {
    if (!vinyls.length) {
      return done();
    }

    // common data
    // -----------

    vinyls = vinyls
      .map(function(vinyl) {
        var data = vinyl.data = parse(vinyl.relative, {locales: options.locales});

        // locale
        data.locale || (data.locale = options.defaultLocale);

        // document
        if (options.dataExtensions && ~options.dataExtensions.indexOf(data.extname)) {
          data.document = 'data';
        } else if (fm.test(vinyl.contents.toString())) {
          data.document = 'text';
        } else {
          data.document = false;
        }

        // filepaths
        data.filepaths = [];
        data.filepaths.push(data.locale === options.defaultLocale ? null : data.locale);
        data.filepaths.push.apply(data.filepaths, data.dirnames);
        if (data.document) {
          data.filepaths.push(data.index ? null : data.slug);
          data.filepaths.push('index.html');
        } else {
          data.filepaths.push(data.slug + '.' + data.extname);
        }
        data.filepaths = data.filepaths.filter(function(x) { return x });

        // filepath
        data.filepath = path.join.apply(path, data.filepaths);

        // filepath
        vinyl.path = path.join(vinyl.base, data.filepath);

        return vinyl;
      })
      .filter(function(vinyl) { return !vinyl.data.draft || options.draft });

    // check error
    // -----------

    vinyls
      .reduce(function(paths, vinyl) {
        if (vinyl.path in paths) {
          done(new PluginError('gulp-minisite', [
            'creating two files into the same path: ' + vinyl.path,
            'file 1: ' + paths[vinyl.path].data.source,
            'file 2: ' + vinyl.data.source,
          ].join('\n')));
        }
        paths[vinyl.path] = vinyl;
        return paths;
      }, {});

    // document data
    // -------------

    var docs = vinyls.filter(function(vinyl) { return vinyl.data.document });

    docs
      .map(function(vinyl) {
        var data = vinyl.data;

        // resourceId
        data.resourceId = data.dirnames.concat(data.index ? [] : [data.slug]).join('/');

        // collectionId
        data.collectionId = data.dirnames.join('/');

        // paths
        data.paths = data.filepaths.slice(0, -1);
        data.paths.unshift('/');

        // path
        data.path = path.join.apply(path, data.paths);

        // locales
        data.locales = {};

        // data & body
        if (data.document === 'data') {
          data.data = yaml.safeLoad(vinyl.contents.toString());
          (data.data === undefined) && (data.data = {});
          data.body = '';
        } else if (data.document === 'text') {
          var fmData = fm(vinyl.contents.toString());
          data.data  = fmData.attributes;
          data.body  = fmData.body;
        }

        return data;
      })
      .forEach(function(data, i, dataList) {
        dataList
          .filter(function(d) { return d.resourceId === data.resourceId })
          .forEach(function(d) { data.locales[d.locale] = d });
      });

    // site
    // ----

    var site;
    if (
      options.locales &&
      options.locales.length &&
      isEqual(
        Object.keys(options.site || {})
          .filter(function(x) { return x }).sort(),
        (options.locales || []).slice().sort()
      )
    ) {
      site = options.site;
    } else {
      site = (options.locales || [])
        .reduce(function(site, locale) {
          site[locale] = options.site;
          return site;
        }, {'': options.site});
    }

    // pages
    // -----

    var pages = docs
      .reduce(function(pages, vinyl) {
        var locale = vinyl.data.locale || '';
        pages[locale] || (pages[locale] = []);
        pages[locale].push(vinyl.data);
        return pages;
      }, {});

    // document collections
    // --------------------

    var sortees = [];
    var collections = docs
      .filter(function(vinyl) { return !vinyl.data.index })
      .reduce(function(collections, vinyl) {
        var locale = vinyl.data.locale || '';
        var id     = vinyl.data.collectionId;
        collections[locale]     || (collections[locale] = {});
        collections[locale][id] || sortees.push(collections[locale][id] = []);
        collections[locale][id].push(vinyl.data);
        return collections;
      }, {});

    // sort collections

    sortees.forEach(function(collection) {
      collection.sort(function(a, b) {
        var aOrder = a.order;
        var bOrder = b.order;

        if (aOrder !== undefined && bOrder !== undefined) {
          if (aOrder < bOrder) { return -1 }
          if (aOrder > bOrder) { return 1 }
        } else if (aOrder !== undefined) {
          return 1;
        } else if (bOrder !== undefined) {
          return -1;
        }

        var aSlug = a.slug;
        var bSlug = b.slug;

        if (aSlug < bSlug) { return -1 }
        if (aSlug > bSlug) { return 1 }

        return 0;
      });
    });

    // indexes to have collections

    docs
      .filter(function(vinyl) { return vinyl.data.index })
      .forEach(function(vinyl) {
        var locale = vinyl.data.locale || '';
        var id     = vinyl.data.collectionId;
        if (collections[locale] && collections[locale][id]) {
          vinyl.data.collection = collections[locale][id];
        } else {
          vinyl.data.collection = [];
        }
      });

    // references
    // ----------

    var references = docs
      .reduce(function(references, vinyl) {
        var locale = vinyl.data.locale || '';
        var id     = vinyl.data.resourceId;
        references[locale] || (references[locale] = {});
        references[locale][id] = vinyl.data;
        return references;
      }, {});

    // shallow attribute access
    // ------------------------

    docs
      .forEach(function(vinyl) {
        for (var key in vinyl.data.data) {
          if (key in vinyl.data) {
            continue;
          }
          vinyl.data[key] = vinyl.data.data[key];
        }
      });

    // document rendering
    // ------------------

    docs
      .forEach(function(vinyl) {
        if (vinyl.data.template) {
          var locale   = vinyl.data.locale || '';
          var tmplName = vinyl.data.template;
          var tmplData = {
            site:        site[locale],
            page:        vinyl.data,
            pages:       pages[locale],
            collections: collections[locale],
            references:  references[locale],
            global:      {
              site:        site,
              pages:       pages,
              collections: collections,
              references:  references,
            },
          };
          vinyl.contents = new Buffer(options.templateEngine(tmplName, tmplData), 'utf8');
        } else {
          vinyl.contents = new Buffer(vinyl.data.body, 'utf8');
        }
      });

    // pipe
    // ----

    vinyls
      .forEach(this.push.bind(this));

    // done
    // ----

    return done();
  };

  // through
  // =======

  return through.obj(transform, flush);
};
<commit_msg>Tidy code<commit_after>var PluginError = require('gulp-util').PluginError;
var assign      = require('lodash.assign');
var fm          = require('front-matter');
var isEqual     = require('lodash.isequal');
var path        = require('path');
var through     = require('through2');
var yaml        = require('js-yaml');

var parse = require('./parse');

module.exports = function(options) {

  options = assign({
    defaultLocale:  null,
    locales:        null,
    site:           null,
    templateEngine: require('./engines/nunjucks')(),
    draft:          false,
    dataExtensions: ['yml', 'yaml', 'json'],
  }, options);

  // ===
  // ===

  var vinyls = [];

  // transform
  // =========

  var transform = function(vinyl, _, done) {
    if (vinyl.isNull()) {
      return done(null, vinyl);
    }
    if (vinyl.isStream()) {
      return done(new PluginError('gulp-minisite', 'Streaming not supported'));
    }

    vinyls.push(vinyl);
    return done();
  };

  // flush
  // =====

  var flush = function(done) {
    if (!vinyls.length) {
      return done();
    }

    // common data
    // -----------

    vinyls = vinyls
      .map(function(vinyl) {
        var data = vinyl.data = parse(vinyl.relative, {locales: options.locales});

        // locale
        data.locale || (data.locale = options.defaultLocale);

        // document
        if (options.dataExtensions && ~options.dataExtensions.indexOf(data.extname)) {
          data.document = 'data';
        } else if (fm.test(vinyl.contents.toString())) {
          data.document = 'text';
        } else {
          data.document = false;
        }

        // filepaths
        data.filepaths = [];
        data.filepaths.push(data.locale === options.defaultLocale ? null : data.locale);
        data.filepaths.push.apply(data.filepaths, data.dirnames);
        if (data.document) {
          data.filepaths.push(data.index ? null : data.slug);
          data.filepaths.push('index.html');
        } else {
          data.filepaths.push(data.slug + '.' + data.extname);
        }
        data.filepaths = data.filepaths.filter(function(x) { return x });

        // filepath
        data.filepath = path.join.apply(path, data.filepaths);

        // filepath
        vinyl.path = path.join(vinyl.base, data.filepath);

        return vinyl;
      })
      .filter(function(vinyl) { return !vinyl.data.draft || options.draft });

    // check error
    // -----------

    vinyls
      .reduce(function(paths, vinyl) {
        if (vinyl.path in paths) {
          done(new PluginError('gulp-minisite', [
            'creating two files into the same path: ' + vinyl.path,
            'file 1: ' + paths[vinyl.path].data.source,
            'file 2: ' + vinyl.data.source,
          ].join('\n')));
        }
        paths[vinyl.path] = vinyl;
        return paths;
      }, {});

    // document data
    // -------------

    var docs = vinyls.filter(function(vinyl) { return vinyl.data.document });

    docs
      .map(function(vinyl) {
        var data = vinyl.data;

        // resourceId
        data.resourceId = data.dirnames.concat(data.index ? [] : [data.slug]).join('/');

        // collectionId
        data.collectionId = data.dirnames.join('/');

        // paths
        data.paths = data.filepaths.slice(0, -1);
        data.paths.unshift('/');

        // path
        data.path = path.join.apply(path, data.paths);

        // locales
        data.locales = {};

        // data & body
        if (data.document === 'data') {
          data.data = yaml.safeLoad(vinyl.contents.toString());
          (data.data === undefined) && (data.data = {});
          data.body = '';
        } else if (data.document === 'text') {
          var fmData = fm(vinyl.contents.toString());
          data.data  = fmData.attributes;
          data.body  = fmData.body;
        }

        return data;
      })
      .forEach(function(data, i, dataList) {
        dataList
          .filter(function(d) { return d.resourceId === data.resourceId })
          .forEach(function(d) { data.locales[d.locale] = d });
      });

    // site
    // ----

    var site;
    if (
      options.locales &&
      options.locales.length &&
      isEqual(
        Object.keys(options.site || {})
          .filter(function(x) { return x }).sort(),
        (options.locales || []).slice().sort()
      )
    ) {
      site = options.site;
    } else {
      site = (options.locales || [])
        .reduce(function(site, locale) {
          site[locale] = options.site;
          return site;
        }, {'': options.site});
    }

    // pages
    // -----

    var pages = docs
      .reduce(function(pages, vinyl) {
        var locale = vinyl.data.locale || '';
        pages[locale] || (pages[locale] = []);
        pages[locale].push(vinyl.data);
        return pages;
      }, {});

    // document collections
    // --------------------

    var sortees = [];
    var collections = docs
      .filter(function(vinyl) { return !vinyl.data.index })
      .reduce(function(collections, vinyl) {
        var locale = vinyl.data.locale || '';
        var id     = vinyl.data.collectionId;
        collections[locale]     || (collections[locale] = {});
        collections[locale][id] || sortees.push(collections[locale][id] = []);
        collections[locale][id].push(vinyl.data);
        return collections;
      }, {});

    // sort collections

    sortees.forEach(function(collection) {
      collection.sort(function(a, b) {
        var aOrder = a.order;
        var bOrder = b.order;

        if (aOrder !== undefined && bOrder !== undefined) {
          if (aOrder < bOrder) { return -1 }
          if (aOrder > bOrder) { return 1 }
        } else if (aOrder !== undefined) {
          return 1;
        } else if (bOrder !== undefined) {
          return -1;
        }

        var aSlug = a.slug;
        var bSlug = b.slug;

        if (aSlug < bSlug) { return -1 }
        if (aSlug > bSlug) { return 1 }

        return 0;
      });
    });

    // indexes to have collections

    docs
      .filter(function(vinyl) { return vinyl.data.index })
      .forEach(function(vinyl) {
        var locale = vinyl.data.locale || '';
        var id     = vinyl.data.collectionId;
        if (collections[locale] && collections[locale][id]) {
          vinyl.data.collection = collections[locale][id];
        } else {
          vinyl.data.collection = [];
        }
      });

    // references
    // ----------

    var references = docs
      .reduce(function(references, vinyl) {
        var locale = vinyl.data.locale || '';
        var id     = vinyl.data.resourceId;
        references[locale] || (references[locale] = {});
        references[locale][id] = vinyl.data;
        return references;
      }, {});

    // shallow attribute access
    // ------------------------

    docs
      .forEach(function(vinyl) {
        for (var key in vinyl.data.data) {
          if (key in vinyl.data) {
            continue;
          }
          vinyl.data[key] = vinyl.data.data[key];
        }
      });

    // document rendering
    // ------------------

    docs
      .forEach(function(vinyl) {
        if (vinyl.data.template) {
          var locale   = vinyl.data.locale || '';
          var tmplName = vinyl.data.template;
          var tmplData = {
            site:        site[locale],
            page:        vinyl.data,
            pages:       pages[locale],
            collections: collections[locale],
            references:  references[locale],
            global:      {
              site:        site,
              pages:       pages,
              collections: collections,
              references:  references,
            },
          };
          vinyl.contents = new Buffer(options.templateEngine(tmplName, tmplData), 'utf8');
        } else {
          vinyl.contents = new Buffer(vinyl.data.body, 'utf8');
        }
      });

    // pipe
    // ----

    vinyls.forEach(this.push, this);

    // done
    // ----

    return done();
  };

  // through
  // =======

  return through.obj(transform, flush);
};
<|endoftext|>


<commit_before>/* eslint import/prefer-default-export: 0 */
import { setStubbingMode as _setStubbingMode } from 'react-stubber';
import _compose from './compose';

export const setStubbingMode = _setStubbingMode;
export const compose = _compose;

export function setDefaults(mainOptions = {}) {
  return function (dataLoader, otherOptions = {}) {
    const options = {
      ...mainOptions,
      ...otherOptions,
    };

    return _compose(dataLoader, options);
  };
}

export function merge(...enhancers) {
  // TODO: Try to get a single HOC merging all the composers together
  return function (Child) {
    return enhancers.reduce((C, enhancer) => {
      return enhancer(C);
    }, Child);
  };
}

export const composeAll = merge;
<commit_msg>Expose the stub api.<commit_after>/* eslint import/prefer-default-export: 0 */
import {
  setStubbingMode as _setStubbingMode,
  stub as _stub,
} from 'react-stubber';
import _compose from './compose';

export const setStubbingMode = _setStubbingMode;
export const stub = _stub;
export const compose = _compose;

export function setDefaults(mainOptions = {}) {
  return function (dataLoader, otherOptions = {}) {
    const options = {
      ...mainOptions,
      ...otherOptions,
    };

    return _compose(dataLoader, options);
  };
}

export function merge(...enhancers) {
  // TODO: Try to get a single HOC merging all the composers together
  return function (Child) {
    return enhancers.reduce((C, enhancer) => {
      return enhancer(C);
    }, Child);
  };
}

export const composeAll = merge;
<|endoftext|>


<commit_before>import fs from 'fs';
import path from 'path';
import Map from 'es6-map';
import assign from 'object-assign';
import npmResolve from 'resolve';
import bowerResolve from 'resolve-bower';

let options;

/**
 * Check for the "main" field to see if it contains any css/scss/sass
 * If not, try to use the "style" field from package.json - and if that fails
 * too, defaults to "index.css"
 */
const filter = (pkg) => {
  if (!pkg.main || (pkg.main && !pkg.main.match(/\.s?[c|a]ss$/g))) {
    pkg.main = pkg.style || pkg['main.scss'] || pkg['main.sass'] || 'index.css';
  }
  return pkg;
};

/**
 * Simple Promise wrapper to resolve the npm/bower modules
 */
const find = (resolver, { url, prev, resolved }) => new Promise((resolve) => {
  if (resolved) {
    resolve({ url, prev, resolved });
  } else {
    resolver(url, options, (err, res) => {
      resolve({ url: (err ? url : res), prev, resolved: !err });
    });
  }
});

const npm = (file) => find(npmResolve, file);

const bower = (file) => find(bowerResolve, file);

/**
 * Read file's content
 */
const read = ({ url, prev, resolved }) => new Promise((resolve, reject) => {
  if (url.match(/\.css$/g)) {
    fs.readFile(url, 'utf8', (err, contents) => err ? reject(err) : resolve({ contents }));
  } else {
    let resolvedURL = url;
    if (!resolved && prev && prev !== 'stdin' && !path.isAbsolute(url)) {
      resolvedURL = path.resolve(path.dirname(prev), url);
    }
    resolve({ file: resolvedURL });
  }
});

/**
 * Look for Sass files installed through npm
 * @param opts {Object}       Options to be passed to the resolver module
 *
 * @return {Function}         Function to be used by node-sass importer
 */
export default function (opts) {
  options = assign({}, { packageFilter: filter }, opts);

  const aliases = new Map();

  return (url, prev, done) => {
    if (aliases.has(url)) {
      done(aliases.get(url));
    } else {
      npm({ url, prev }).then(bower).then(read).then((res) => {
        aliases.set(url, res);
        done(res);
      });
    }
  };
}
<commit_msg>Fix ESLint errors<commit_after>import fs from 'fs';
import path from 'path';
import Map from 'es6-map';
import assign from 'object-assign';
import npmResolve from 'resolve';
import bowerResolve from 'resolve-bower';

let options;

/**
 * Check for the "main" field to see if it contains any css/scss/sass
 * If not, try to use the "style" field from package.json - and if that fails
 * too, defaults to "index.css"
 */
const filter = (pkg) => {
  if (!pkg.main || (pkg.main && !pkg.main.match(/\.s?[c|a]ss$/g))) {
    pkg.main = pkg.style || pkg['main.scss'] || pkg['main.sass'] || 'index.css';
  }
  return pkg;
};

/**
 * Simple Promise wrapper to resolve the npm/bower modules
 */
const find = (resolver, { url, prev, resolved }) => new Promise((resolve) => {
  if (resolved) {
    resolve({ url, prev, resolved });
  } else {
    resolver(url, options, (err, res) => {
      resolve({ url: (err ? url : res), prev, resolved: !err });
    });
  }
});

const npm = (file) => find(npmResolve, file);

const bower = (file) => find(bowerResolve, file);

/**
 * Read file's content
 */
const read = ({ url, prev, resolved }) => new Promise((resolve, reject) => {
  if (url.match(/\.css$/g)) {
    fs.readFile(url, 'utf8', (err, contents) => {
      if (err) {
        reject(err);
      } else {
        resolve({ contents });
      }
    });
  } else {
    let resolvedURL = url;
    if (!resolved && prev && prev !== 'stdin' && !path.isAbsolute(url)) {
      resolvedURL = path.resolve(path.dirname(prev), url);
    }
    resolve({ file: resolvedURL });
  }
});

/**
 * Look for Sass files installed through npm
 * @param opts {Object}       Options to be passed to the resolver module
 *
 * @return {Function}         Function to be used by node-sass importer
 */
export default function (opts) {
  options = assign({}, { packageFilter: filter }, opts);

  const aliases = new Map();

  return (url, prev, done) => {
    if (aliases.has(url)) {
      done(aliases.get(url));
    } else {
      npm({ url, prev }).then(bower).then(read).then((res) => {
        aliases.set(url, res);
        done(res);
      });
    }
  };
}
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import clamp from 'clamp'

import {
  TextInput,
  Keyboard,
  BackHandler,
  Animated,
  PanResponder,
  Platform
} from 'react-native'

import closest from './libs/closest'
import measureElement from './libs/measureElement'
import FlickAnimation from './libs/FlickAnimation'
import {statusBarHeight, visibleHeight} from './libs/layout'
import * as Constants from './libs/constants'
import styles from './libs/styles'

const keyboardShowEvent = Platform.select({
  android: 'keyboardDidShow',
  ios: 'keyboardWillShow'
})

const keyboardHideEvent = Platform.select({
  android: 'keyboardDidHide',
  ios: 'keyboardWillHide'
})

class SlidingUpPanel extends React.PureComponent {
  static propTypes = {
    height: PropTypes.number,
    animatedValue: PropTypes.instanceOf(Animated.Value),
    draggableRange: PropTypes.shape({
      top: PropTypes.number,
      bottom: PropTypes.number
    }),
    snappingPoints: PropTypes.arrayOf(PropTypes.number),
    minimumVelocityThreshold: PropTypes.number,
    minimumDistanceThreshold: PropTypes.number,
    avoidKeyboard: PropTypes.bool,
    onBackButtonPress: PropTypes.func,
    onDragStart: PropTypes.func,
    onDragEnd: PropTypes.func,
    onMomentumDragStart: PropTypes.func,
    onMomentumDragEnd: PropTypes.func,
    onClose: PropTypes.func,
    allowMomentum: PropTypes.bool,
    allowDragging: PropTypes.bool,
    showBackdrop: PropTypes.bool,
    backdropOpacity: PropTypes.number,
    friction: PropTypes.number,
    children: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
  }

  static defaultProps = {
    height: visibleHeight - statusBarHeight,
    animatedValue: new Animated.Value(0),
    draggableRange: {top: visibleHeight - statusBarHeight, bottom: 0},
    snappingPoints: [],
    minimumVelocityThreshold: Constants.DEFAULT_MINIMUM_VELOCITY_THRESHOLD,
    minimumDistanceThreshold: Constants.DEFAULT_MINIMUM_DISTANCE_THRESHOLD,
    avoidKeyboard: true,
    onBackButtonPress: null,
    onDragStart: () => {},
    onDragEnd: () => {},
    onMomentumDragStart: () => {},
    onMomentumDragEnd: () => {},
    allowMomentum: true,
    allowDragging: true,
    showBackdrop: true,
    backdropOpacity: 0.75,
    friction: Constants.DEFAULT_FRICTION,
    onClose: () => null,
  }

  // eslint-disable-next-line react/sort-comp
  _panResponder = PanResponder.create({
    onStartShouldSetPanResponder: () => this.props.allowDragging,
    onMoveShouldSetPanResponder: this._onMoveShouldSetPanResponder.bind(this),
    onPanResponderStart: this._onPanResponderStart.bind(this),
    onPanResponderMove: this._onPanResponderMove.bind(this),
    onPanResponderRelease: this._onPanResponderRelease.bind(this),
    onPanResponderTerminate: this._onPanResponderTerminate.bind(this),
    onShouldBlockNativeResponder: () => false,
    onPanResponderTerminationRequest: () => false
  })

  _keyboardShowListener = Keyboard.addListener(
    keyboardShowEvent,
    this._onKeyboardShown.bind(this)
  )

  _keyboardHideListener = Keyboard.addListener(
    keyboardHideEvent,
    this._onKeyboardHiden.bind(this)
  )

  _backButtonListener = BackHandler.addEventListener(
    'hardwareBackPress',
    this._onBackButtonPress.bind(this)
  )

  constructor(props) {
    super(props)

    this._storeKeyboardPosition = this._storeKeyboardPosition.bind(this)
    this._isInsideDraggableRange = this._isInsideDraggableRange.bind(this)
    this._triggerAnimation = this._triggerAnimation.bind(this)
    this._renderContent = this._renderContent.bind(this)
    this._renderBackdrop = this._renderBackdrop.bind(this)

    this.show = this.show.bind(this)
    this.hide = this.hide.bind(this)
    this.scrollIntoView = this.scrollIntoView.bind(this)

    const {top, bottom} = this.props.draggableRange
    const animatedValue = this.props.animatedValue.__getValue()
    const initialValue = clamp(animatedValue, bottom, top)

    // Ensure the animation are within draggable range
    this.props.animatedValue.setValue(initialValue)

    this._backdropPointerEvents = this._isAtBottom(initialValue) ? 'none' : 'box-only' // prettier-ignore
    this._flick = new FlickAnimation({max: top, min: bottom})

    this._flickAnimationListener = this._flick.onUpdate(value => {
      this.props.animatedValue.setValue(value)
    })

    this._animatedValueListener = this.props.animatedValue.addListener(
      this._onAnimatedValueChange.bind(this)
    )
  }

  componentDidUpdate(prevProps) {
    if (
      prevProps.draggableRange.top !== this.props.draggableRange.top ||
      prevProps.draggableRange.bottom !== this.props.draggableRange.bottom
    ) {
      const {top, bottom} = this.props.draggableRange
      const animatedValue = this.props.animatedValue.__getValue()

      this._flick.setMax(top)
      this._flick.setMin(bottom)

      // If the panel is below the new 'bottom'
      if (animatedValue < bottom || animatedValue > top) {
        const newValue = clamp(animatedValue, bottom, top)
        this.props.animatedValue.setValue(newValue)
      }
    }
  }

  componentWillUnmount() {
    if (this._animatedValueListener != null) {
      this.props.animatedValue.removeListener(this._animatedValueListener)
    }

    if (this._keyboardShowListener != null) {
      this._keyboardShowListener.remove()
    }

    if (this._keyboardHideListener != null) {
      this._keyboardHideListener.remove()
    }

    if (this._flickAnimationListener != null) {
      this._flickAnimationListener.remove()
    }

    if (this._backButtonListener != null) {
      this._backButtonListener.remove()
    }
  }

  _onMoveShouldSetPanResponder(evt, gestureState) {
    if (!this.props.allowDragging) {
      return false
    }

    const animatedValue = this.props.animatedValue.__getValue()

    return (
      this._isInsideDraggableRange(animatedValue, gestureState) &&
      Math.abs(gestureState.dy) > this.props.minimumDistanceThreshold
    )
  }

  _onPanResponderStart(evt, gestureState) {
    this._flick.stop()

    const value = this.props.animatedValue.__getValue()

    this._initialDragPosition = value
    this.props.onDragStart(value, gestureState)
  }

  _onPanResponderMove(evt, gestureState) {
    const {top, bottom} = this.props.draggableRange
    const delta = this._initialDragPosition - gestureState.dy
    const newValue = clamp(delta, top, bottom)

    this.props.animatedValue.setValue(newValue)
  }

  // Trigger when you release your finger
  _onPanResponderRelease(evt, gestureState) {
    const animatedValue = this.props.animatedValue.__getValue()

    if (!this._isInsideDraggableRange(animatedValue, gestureState)) {
      return
    }

    this._initialDragPosition = animatedValue
    this.props.onDragEnd(animatedValue, gestureState)

    if (!this.props.allowMomentum) {
      return
    }

    if (this.props.snappingPoints.length > 0) {
      this.props.onMomentumDragStart(animatedValue)

      const {top, bottom} = this.props.draggableRange
      const nextPoint = this._flick.predictNextPosition({
        fromValue: animatedValue,
        velocity: gestureState.vy,
        friction: this.props.friction
      })

      const closestPoint = closest(nextPoint, [
        bottom,
        ...this.props.snappingPoints,
        top
      ])

      const remainingDistance = animatedValue - closestPoint
      const velocity = remainingDistance / Constants.TIME_CONSTANT

      this._flick.start({
        velocity,
        toValue: closestPoint,
        fromValue: animatedValue,
        friction: this.props.friction,
        onMomentumEnd: this.props.onMomentumDragEnd
      })
      return
    }

    if (Math.abs(gestureState.vy) > this.props.minimumVelocityThreshold) {
      this.props.onMomentumDragStart(animatedValue)

      this._flick.start({
        velocity: gestureState.vy,
        fromValue: animatedValue,
        friction: this.props.friction,
        onMomentumEnd: this.props.onMomentumDragEnd
      })
    }
  }

  _onPanResponderTerminate(evt, gestureState) {
    const animatedValue = this.props.animatedValue.__getValue()

    if (!this._isInsideDraggableRange(animatedValue, gestureState)) {
      return
    }

    this._initialDragPosition = animatedValue
    this.props.onDragEnd(animatedValue, gestureState)
  }

  _onAnimatedValueChange({value}) {
    const isAtBottom = this._isAtBottom(value)

    if (isAtBottom) {
      Keyboard.dismiss()
    }

    if (this._backdrop == null) {
      return
    }

    // @TODO: Find a better way to update pointer events when animated value changed

    if (isAtBottom && this._backdropPointerEvents === 'box-only') {
      this.props.onClose();
      this._backdropPointerEvents = 'none'
      this._backdrop.setNativeProps({pointerEvents: 'none'})
    }

    if (!isAtBottom && this._backdropPointerEvents === 'none') {
      this._backdropPointerEvents = 'box-only'
      this._backdrop.setNativeProps({pointerEvents: 'box-only'})
    }
  }

  _onKeyboardShown(event) {
    if (!this.props.avoidKeyboard) {
      return
    }

    this._storeKeyboardPosition(event.endCoordinates.screenY)

    const node = TextInput.State.currentlyFocusedField()

    if (node != null) {
      this.scrollIntoView(node)
    }
  }

  _onKeyboardHiden() {
    this._storeKeyboardPosition(0)

    const animatedValue = this.props.animatedValue.__getValue()

    // Restore last position
    if (this._lastPosition != null && !this._isAtBottom(animatedValue)) {
      Animated.timing(this.props.animatedValue, {
        toValue: this._lastPosition,
        duration: Constants.KEYBOARD_TRANSITION_DURATION
      }).start()
    }

    this._lastPosition = null
  }

  _onBackButtonPress() {
    if (this.props.onBackButtonPress !== null) {
      return this.props.onBackButtonPress()
    }

    const value = this.props.animatedValue.__getValue()

    if (this._isAtBottom(value)) {
      return false
    }

    this.hide()

    return true
  }

  _isInsideDraggableRange(value, gestureState) {
    const {top, bottom} = this.props.draggableRange

    if (gestureState.dy > 0) {
      return value > bottom
    }

    return value < top
  }

  _isAtBottom(value) {
    const {bottom} = this.props.draggableRange
    return value <= bottom
  }

  _storeKeyboardPosition(value) {
    this._keyboardYPosition = value
  }

  _triggerAnimation(options = {}) {
    const animatedValue = this.props.animatedValue.__getValue()
    const remainingDistance = animatedValue - options.toValue
    const velocity = options.velocity || remainingDistance / Constants.TIME_CONSTANT // prettier-ignore

    this._flick.start({
      velocity,
      toValue: options.toValue,
      fromValue: animatedValue,
      friction: this.props.friction
    })
  }

  _renderBackdrop() {
    if (!this.props.showBackdrop) {
      return null
    }

    const {top, bottom} = this.props.draggableRange

    const backdropOpacity = this.props.animatedValue.interpolate({
      inputRange: [bottom, top],
      outputRange: [0, this.props.backdropOpacity],
      extrapolate: 'clamp'
    })

    return (
      <Animated.View
        key="backdrop"
        pointerEvents={this._backdropPointerEvents}
        ref={c => (this._backdrop = c)}
        onTouchStart={() => this._flick.stop()}
        onTouchEnd={() => this.hide()}
        style={[styles.backdrop, {opacity: backdropOpacity}]}
      />
    )
  }

  _renderContent() {
    const {
      height,
      draggableRange: {top, bottom}
    } = this.props

    const translateY = this.props.animatedValue.interpolate({
      inputRange: [bottom, top],
      outputRange: [-bottom, -top],
      extrapolate: 'clamp'
    })

    const transform = {transform: [{translateY}]}

    const animatedContainerStyles = [
      styles.animatedContainer,
      transform,
      {height, bottom: -height}
    ]

    if (typeof this.props.children === 'function') {
      return (
        <Animated.View
          key="content"
          pointerEvents="box-none"
          style={animatedContainerStyles}>
          {this.props.children(this._panResponder.panHandlers)}
        </Animated.View>
      )
    }

    return (
      <Animated.View
        key="content"
        pointerEvents="box-none"
        style={animatedContainerStyles}
        {...this._panResponder.panHandlers}>
        {this.props.children}
      </Animated.View>
    )
  }

  render() {
    return [this._renderBackdrop(), this._renderContent()]
  }

  show(mayBeValueOrOptions) {
    if (!mayBeValueOrOptions) {
      const {top} = this.props.draggableRange
      return this._triggerAnimation({toValue: top})
    }

    if (typeof mayBeValueOrOptions === 'object') {
      return this._triggerAnimation(mayBeValueOrOptions)
    }

    return this._triggerAnimation({toValue: mayBeValueOrOptions})
  }

  hide() {
    const {bottom} = this.props.draggableRange
    this._triggerAnimation({toValue: bottom})
  }

  async scrollIntoView(node, options = {}) {
    if (!this._keyboardYPosition) {
      return
    }

    // Stop any animation when the keyboard starts showing
    this._flick.stop()

    const {y} = await measureElement(node)
    const extraMargin = options.keyboardExtraMargin || Constants.KEYBOARD_EXTRA_MARGIN // prettier-ignore
    const keyboardActualPos = this._keyboardYPosition - extraMargin

    if (y > keyboardActualPos) {
      this._lastPosition = this.props.animatedValue.__getValue()

      const fromKeyboardToElement = y - keyboardActualPos
      const transitionDistance = this._lastPosition + fromKeyboardToElement

      Animated.timing(this.props.animatedValue, {
        toValue: transitionDistance,
        duration: Constants.KEYBOARD_TRANSITION_DURATION
      }).start()
    }
  }
}

export default SlidingUpPanel
<commit_msg>move onclose callback<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import clamp from 'clamp'

import {
  TextInput,
  Keyboard,
  BackHandler,
  Animated,
  PanResponder,
  Platform
} from 'react-native'

import closest from './libs/closest'
import measureElement from './libs/measureElement'
import FlickAnimation from './libs/FlickAnimation'
import {statusBarHeight, visibleHeight} from './libs/layout'
import * as Constants from './libs/constants'
import styles from './libs/styles'

const keyboardShowEvent = Platform.select({
  android: 'keyboardDidShow',
  ios: 'keyboardWillShow'
})

const keyboardHideEvent = Platform.select({
  android: 'keyboardDidHide',
  ios: 'keyboardWillHide'
})

class SlidingUpPanel extends React.PureComponent {
  static propTypes = {
    height: PropTypes.number,
    animatedValue: PropTypes.instanceOf(Animated.Value),
    draggableRange: PropTypes.shape({
      top: PropTypes.number,
      bottom: PropTypes.number
    }),
    snappingPoints: PropTypes.arrayOf(PropTypes.number),
    minimumVelocityThreshold: PropTypes.number,
    minimumDistanceThreshold: PropTypes.number,
    avoidKeyboard: PropTypes.bool,
    onBackButtonPress: PropTypes.func,
    onDragStart: PropTypes.func,
    onDragEnd: PropTypes.func,
    onMomentumDragStart: PropTypes.func,
    onMomentumDragEnd: PropTypes.func,
    onClose: PropTypes.func,
    allowMomentum: PropTypes.bool,
    allowDragging: PropTypes.bool,
    showBackdrop: PropTypes.bool,
    backdropOpacity: PropTypes.number,
    friction: PropTypes.number,
    children: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
  }

  static defaultProps = {
    height: visibleHeight - statusBarHeight,
    animatedValue: new Animated.Value(0),
    draggableRange: {top: visibleHeight - statusBarHeight, bottom: 0},
    snappingPoints: [],
    minimumVelocityThreshold: Constants.DEFAULT_MINIMUM_VELOCITY_THRESHOLD,
    minimumDistanceThreshold: Constants.DEFAULT_MINIMUM_DISTANCE_THRESHOLD,
    avoidKeyboard: true,
    onBackButtonPress: null,
    onDragStart: () => {},
    onDragEnd: () => {},
    onMomentumDragStart: () => {},
    onMomentumDragEnd: () => {},
    allowMomentum: true,
    allowDragging: true,
    showBackdrop: true,
    backdropOpacity: 0.75,
    friction: Constants.DEFAULT_FRICTION,
    onClose: () => null,
  }

  // eslint-disable-next-line react/sort-comp
  _panResponder = PanResponder.create({
    onStartShouldSetPanResponder: () => this.props.allowDragging,
    onMoveShouldSetPanResponder: this._onMoveShouldSetPanResponder.bind(this),
    onPanResponderStart: this._onPanResponderStart.bind(this),
    onPanResponderMove: this._onPanResponderMove.bind(this),
    onPanResponderRelease: this._onPanResponderRelease.bind(this),
    onPanResponderTerminate: this._onPanResponderTerminate.bind(this),
    onShouldBlockNativeResponder: () => false,
    onPanResponderTerminationRequest: () => false
  })

  _keyboardShowListener = Keyboard.addListener(
    keyboardShowEvent,
    this._onKeyboardShown.bind(this)
  )

  _keyboardHideListener = Keyboard.addListener(
    keyboardHideEvent,
    this._onKeyboardHiden.bind(this)
  )

  _backButtonListener = BackHandler.addEventListener(
    'hardwareBackPress',
    this._onBackButtonPress.bind(this)
  )

  constructor(props) {
    super(props)

    this._storeKeyboardPosition = this._storeKeyboardPosition.bind(this)
    this._isInsideDraggableRange = this._isInsideDraggableRange.bind(this)
    this._triggerAnimation = this._triggerAnimation.bind(this)
    this._renderContent = this._renderContent.bind(this)
    this._renderBackdrop = this._renderBackdrop.bind(this)

    this.show = this.show.bind(this)
    this.hide = this.hide.bind(this)
    this.scrollIntoView = this.scrollIntoView.bind(this)

    const {top, bottom} = this.props.draggableRange
    const animatedValue = this.props.animatedValue.__getValue()
    const initialValue = clamp(animatedValue, bottom, top)

    // Ensure the animation are within draggable range
    this.props.animatedValue.setValue(initialValue)

    this._backdropPointerEvents = this._isAtBottom(initialValue) ? 'none' : 'box-only' // prettier-ignore
    this._flick = new FlickAnimation({max: top, min: bottom})

    this._flickAnimationListener = this._flick.onUpdate(value => {
      this.props.animatedValue.setValue(value)
    })

    this._animatedValueListener = this.props.animatedValue.addListener(
      this._onAnimatedValueChange.bind(this)
    )
  }

  componentDidUpdate(prevProps) {
    if (
      prevProps.draggableRange.top !== this.props.draggableRange.top ||
      prevProps.draggableRange.bottom !== this.props.draggableRange.bottom
    ) {
      const {top, bottom} = this.props.draggableRange
      const animatedValue = this.props.animatedValue.__getValue()

      this._flick.setMax(top)
      this._flick.setMin(bottom)

      // If the panel is below the new 'bottom'
      if (animatedValue < bottom || animatedValue > top) {
        const newValue = clamp(animatedValue, bottom, top)
        this.props.animatedValue.setValue(newValue)
      }
    }
  }

  componentWillUnmount() {
    if (this._animatedValueListener != null) {
      this.props.animatedValue.removeListener(this._animatedValueListener)
    }

    if (this._keyboardShowListener != null) {
      this._keyboardShowListener.remove()
    }

    if (this._keyboardHideListener != null) {
      this._keyboardHideListener.remove()
    }

    if (this._flickAnimationListener != null) {
      this._flickAnimationListener.remove()
    }

    if (this._backButtonListener != null) {
      this._backButtonListener.remove()
    }
  }

  _onMoveShouldSetPanResponder(evt, gestureState) {
    if (!this.props.allowDragging) {
      return false
    }

    const animatedValue = this.props.animatedValue.__getValue()

    return (
      this._isInsideDraggableRange(animatedValue, gestureState) &&
      Math.abs(gestureState.dy) > this.props.minimumDistanceThreshold
    )
  }

  _onPanResponderStart(evt, gestureState) {
    this._flick.stop()

    const value = this.props.animatedValue.__getValue()

    this._initialDragPosition = value
    this.props.onDragStart(value, gestureState)
  }

  _onPanResponderMove(evt, gestureState) {
    const {top, bottom} = this.props.draggableRange
    const delta = this._initialDragPosition - gestureState.dy
    const newValue = clamp(delta, top, bottom)

    this.props.animatedValue.setValue(newValue)
  }

  // Trigger when you release your finger
  _onPanResponderRelease(evt, gestureState) {
    const animatedValue = this.props.animatedValue.__getValue()

    if (!this._isInsideDraggableRange(animatedValue, gestureState)) {
      return
    }

    this._initialDragPosition = animatedValue
    this.props.onDragEnd(animatedValue, gestureState)

    if (!this.props.allowMomentum) {
      return
    }

    if (this.props.snappingPoints.length > 0) {
      this.props.onMomentumDragStart(animatedValue)

      const {top, bottom} = this.props.draggableRange
      const nextPoint = this._flick.predictNextPosition({
        fromValue: animatedValue,
        velocity: gestureState.vy,
        friction: this.props.friction
      })

      const closestPoint = closest(nextPoint, [
        bottom,
        ...this.props.snappingPoints,
        top
      ])

      const remainingDistance = animatedValue - closestPoint
      const velocity = remainingDistance / Constants.TIME_CONSTANT

      this._flick.start({
        velocity,
        toValue: closestPoint,
        fromValue: animatedValue,
        friction: this.props.friction,
        onMomentumEnd: this.props.onMomentumDragEnd
      })
      return
    }

    if (Math.abs(gestureState.vy) > this.props.minimumVelocityThreshold) {
      this.props.onMomentumDragStart(animatedValue)

      this._flick.start({
        velocity: gestureState.vy,
        fromValue: animatedValue,
        friction: this.props.friction,
        onMomentumEnd: this.props.onMomentumDragEnd
      })
    }
  }

  _onPanResponderTerminate(evt, gestureState) {
    const animatedValue = this.props.animatedValue.__getValue()

    if (!this._isInsideDraggableRange(animatedValue, gestureState)) {
      return
    }

    this._initialDragPosition = animatedValue
    this.props.onDragEnd(animatedValue, gestureState)
  }

  _onAnimatedValueChange({value}) {
    const isAtBottom = this._isAtBottom(value)

    if (isAtBottom) {
      this.props.onClose();
      Keyboard.dismiss()
    }

    if (this._backdrop == null) {
      return
    }

    // @TODO: Find a better way to update pointer events when animated value changed

    if (isAtBottom && this._backdropPointerEvents === 'box-only') {
      this._backdropPointerEvents = 'none'
      this._backdrop.setNativeProps({pointerEvents: 'none'})
    }

    if (!isAtBottom && this._backdropPointerEvents === 'none') {
      this._backdropPointerEvents = 'box-only'
      this._backdrop.setNativeProps({pointerEvents: 'box-only'})
    }
  }

  _onKeyboardShown(event) {
    if (!this.props.avoidKeyboard) {
      return
    }

    this._storeKeyboardPosition(event.endCoordinates.screenY)

    const node = TextInput.State.currentlyFocusedField()

    if (node != null) {
      this.scrollIntoView(node)
    }
  }

  _onKeyboardHiden() {
    this._storeKeyboardPosition(0)

    const animatedValue = this.props.animatedValue.__getValue()

    // Restore last position
    if (this._lastPosition != null && !this._isAtBottom(animatedValue)) {
      Animated.timing(this.props.animatedValue, {
        toValue: this._lastPosition,
        duration: Constants.KEYBOARD_TRANSITION_DURATION
      }).start()
    }

    this._lastPosition = null
  }

  _onBackButtonPress() {
    if (this.props.onBackButtonPress !== null) {
      return this.props.onBackButtonPress()
    }

    const value = this.props.animatedValue.__getValue()

    if (this._isAtBottom(value)) {
      return false
    }

    this.hide()

    return true
  }

  _isInsideDraggableRange(value, gestureState) {
    const {top, bottom} = this.props.draggableRange

    if (gestureState.dy > 0) {
      return value > bottom
    }

    return value < top
  }

  _isAtBottom(value) {
    const {bottom} = this.props.draggableRange
    return value <= bottom
  }

  _storeKeyboardPosition(value) {
    this._keyboardYPosition = value
  }

  _triggerAnimation(options = {}) {
    const animatedValue = this.props.animatedValue.__getValue()
    const remainingDistance = animatedValue - options.toValue
    const velocity = options.velocity || remainingDistance / Constants.TIME_CONSTANT // prettier-ignore

    this._flick.start({
      velocity,
      toValue: options.toValue,
      fromValue: animatedValue,
      friction: this.props.friction
    })
  }

  _renderBackdrop() {
    if (!this.props.showBackdrop) {
      return null
    }

    const {top, bottom} = this.props.draggableRange

    const backdropOpacity = this.props.animatedValue.interpolate({
      inputRange: [bottom, top],
      outputRange: [0, this.props.backdropOpacity],
      extrapolate: 'clamp'
    })

    return (
      <Animated.View
        key="backdrop"
        pointerEvents={this._backdropPointerEvents}
        ref={c => (this._backdrop = c)}
        onTouchStart={() => this._flick.stop()}
        onTouchEnd={() => this.hide()}
        style={[styles.backdrop, {opacity: backdropOpacity}]}
      />
    )
  }

  _renderContent() {
    const {
      height,
      draggableRange: {top, bottom}
    } = this.props

    const translateY = this.props.animatedValue.interpolate({
      inputRange: [bottom, top],
      outputRange: [-bottom, -top],
      extrapolate: 'clamp'
    })

    const transform = {transform: [{translateY}]}

    const animatedContainerStyles = [
      styles.animatedContainer,
      transform,
      {height, bottom: -height}
    ]

    if (typeof this.props.children === 'function') {
      return (
        <Animated.View
          key="content"
          pointerEvents="box-none"
          style={animatedContainerStyles}>
          {this.props.children(this._panResponder.panHandlers)}
        </Animated.View>
      )
    }

    return (
      <Animated.View
        key="content"
        pointerEvents="box-none"
        style={animatedContainerStyles}
        {...this._panResponder.panHandlers}>
        {this.props.children}
      </Animated.View>
    )
  }

  render() {
    return [this._renderBackdrop(), this._renderContent()]
  }

  show(mayBeValueOrOptions) {
    if (!mayBeValueOrOptions) {
      const {top} = this.props.draggableRange
      return this._triggerAnimation({toValue: top})
    }

    if (typeof mayBeValueOrOptions === 'object') {
      return this._triggerAnimation(mayBeValueOrOptions)
    }

    return this._triggerAnimation({toValue: mayBeValueOrOptions})
  }

  hide() {
    const {bottom} = this.props.draggableRange
    this._triggerAnimation({toValue: bottom})
  }

  async scrollIntoView(node, options = {}) {
    if (!this._keyboardYPosition) {
      return
    }

    // Stop any animation when the keyboard starts showing
    this._flick.stop()

    const {y} = await measureElement(node)
    const extraMargin = options.keyboardExtraMargin || Constants.KEYBOARD_EXTRA_MARGIN // prettier-ignore
    const keyboardActualPos = this._keyboardYPosition - extraMargin

    if (y > keyboardActualPos) {
      this._lastPosition = this.props.animatedValue.__getValue()

      const fromKeyboardToElement = y - keyboardActualPos
      const transitionDistance = this._lastPosition + fromKeyboardToElement

      Animated.timing(this.props.animatedValue, {
        toValue: transitionDistance,
        duration: Constants.KEYBOARD_TRANSITION_DURATION
      }).start()
    }
  }
}

export default SlidingUpPanel
<|endoftext|>


<commit_before>const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const fs = require('fs');
app.use(bodyParser.urlencoded({ extended: true }));
const HashMap = require('hashmap');

var teams = new HashMap();
var js_files = [];

// read all files in js subfolder and set names in js_files array
fs.readdirSync('js').forEach(file => {
        js_files.push(file);
});

js_files.forEach(function (filename) {
    app.get('/js/' + filename, function (req, res) {
        res.sendFile(__dirname + '/js/' + filename);
    });
});

app.get('/', function (req, res) {
    res.sendFile(__dirname + "/index.htm");
});

app.get('/teams', function (req, res) {
    res.sendFile(__dirname + "/teamPage.html");
});

app.post('/sessioncreate/', function (req, res) {
    let teamname = req.body.teamname;
    if (teamname != undefined) {
        console.log('Creating team ' + teamname);
        let data = {
            teamsize: {
                number: 0,
                type: 'Not defined'
            }
        };
        teams.set(teamname, data);
        res.status(200).sendFile(__dirname + '/js/teamPage.js');
        res.redirect(302, '/teams/?teamname=' + teamname);
        res.status(200).end(JSON.stringify({ teamname: teamname }));
    } else {
        console.log('Creating Team: Failure because of undefined teamname!');
        res.sendStatus(400);
    }
});

app.post('/teams/teamsize/', function (req, res) {
    let count = req.body.count;
    let type = req.body.type;
    let teamname = req.body.teamname;
    if (count != undefined && type != undefined && teamname != undefined) {
        console.log('Update team size for team' + teamname);
        // TODO calc pizza number and add to data
        let data = {
            teamsize: {
                number: count,
                type: type
            }
        };
        teams.set(teamname, data);
        res.redirect(302, '/teams/?teamname=' + teamname);
        res.status(200).end(JSON.stringify({ teamname: teamname, data : data }));
    } else {
        console.log('Update team size failed');
        res.sendStatus(400);
    }
});

function computeNumberOfPizzas(number, type) {
    return 4; // TODO
};

function saveToFile(data, filename = "tfmap.log", exitOnWrite = false) {
    let folderName = "results";
    if (!fs.existsSync(folderName)) {
        fs.mkdirSync(folderName);
    }
    fs.writeFileSync('results/' + filename, data);
    console.log("The file was saved!");
    if (exitOnWrite) {
        process.exit(0);
    }
}

var server = app.listen(8081, function () {
    var host = server.address().address;
    var port = server.address().port;
    console.log("REST server listening at http://%s:%s", host, port);
});<commit_msg>Fix path for locating javascript files<commit_after>const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const fs = require('fs');
app.use(bodyParser.urlencoded({ extended: true }));
const HashMap = require('hashmap');

var teams = new HashMap();
var js_files = [];

// read all files in js subfolder and set names in js_files array
fs.readdirSync('src/js').forEach(file => {
        js_files.push(file);
});

js_files.forEach(function (filename) {
    app.get('/js/' + filename, function (req, res) {
        res.sendFile(__dirname + '/js/' + filename);
    });
});

app.get('/', function (req, res) {
    res.sendFile(__dirname + "/index.htm");
});

app.get('/teams', function (req, res) {
    res.sendFile(__dirname + "/teamPage.html");
});

app.post('/sessioncreate/', function (req, res) {
    let teamname = req.body.teamname;
    if (teamname != undefined) {
        console.log('Creating team ' + teamname);
        let data = {
            teamsize: {
                number: 0,
                type: 'Not defined'
            }
        };
        teams.set(teamname, data);
        res.status(200).sendFile(__dirname + '/js/teamPage.js');
        res.redirect(302, '/teams/?teamname=' + teamname);
        res.status(200).end(JSON.stringify({ teamname: teamname }));
    } else {
        console.log('Creating Team: Failure because of undefined teamname!');
        res.sendStatus(400);
    }
});

app.post('/teams/teamsize/', function (req, res) {
    let count = req.body.count;
    let type = req.body.type;
    let teamname = req.body.teamname;
    if (count != undefined && type != undefined && teamname != undefined) {
        console.log('Update team size for team' + teamname);
        // TODO calc pizza number and add to data
        let data = {
            teamsize: {
                number: count,
                type: type
            }
        };
        teams.set(teamname, data);
        res.redirect(302, '/teams/?teamname=' + teamname);
        res.status(200).end(JSON.stringify({ teamname: teamname, data : data }));
    } else {
        console.log('Update team size failed');
        res.sendStatus(400);
    }
});

function computeNumberOfPizzas(number, type) {
    return 4; // TODO
};

function saveToFile(data, filename = "tfmap.log", exitOnWrite = false) {
    let folderName = "results";
    if (!fs.existsSync(folderName)) {
        fs.mkdirSync(folderName);
    }
    fs.writeFileSync('results/' + filename, data);
    console.log("The file was saved!");
    if (exitOnWrite) {
        process.exit(0);
    }
}

var server = app.listen(8081, function () {
    var host = server.address().address;
    var port = server.address().port;
    console.log("REST server listening at http://%s:%s", host, port);
});<|endoftext|>