<commit_before>//Context class for Noodles
//otherwise just make sure that the browser version loads before this file.
if(typeof process !== "undefined"){
	var requirejs = require('requirejs');
	var define = requirejs.define;
}

define(function(require, exports, module){
var _Template = require('./template').Template;
/**--Noodles--
name:Context
description: Template execution
@param {Noodles.Template}
@param {object}
@param {boolean=}
*/
var Context = exports.Context = function(Template,obj,debugMode){
	if(typeof _Template === "undefined") _Template = require('./template').Template;
	this._others = obj;
	this._metaData = Template._metaData;
	this._metaSkip = {};
	if(debugMode){
		this.debugMode = true;
		this.errors = [];
	}
	else{
		this.debugMode = false;
	}
};
/**--Noodles.Context--
name:getObject
description: gets an object from the current Context
@param {Noodles.Template}
@param {string | array}
*/
Context.prototype.getObject = function(Template,key,override){
	key = typeof key !== "object" ? [key] : key;

	var keyTemp = key[0].toLowerCase(),
		obj,keys,keyIndex;
	if(!this._metaSkip[keyTemp] && this._metaData.hasOwnProperty(keyTemp)){
		return this._metaData[keyTemp].execute(Template,this);
	}
	obj = this._others;

	for(var i = 0, l = key.length; i < l; i++){
		keyTemp = typeof key[0].execute !== "undefined" ? key[0].execute(Template,this).toLowerCase() : key[0];
		if(typeof obj[keyTemp] !== "undefined"){
			obj = obj[keyTemp];
		}
		else{
			keys = ',' + Object.keys(obj).join()+ ',';
			keyIndex = keys.toLowerCase().indexOf(',' + keyTemp +',');
			if(keyIndex > -1){
				keyTemp = keys.slice(keyindex + 1, keyindex + 1 + keyTemp.length);
				obj[keyTemp.toLowerCase()] = obj[keyTemp];
				obj = obj[keyTemp];
			}
			else{
				obj[keyTemp] = '';
		 		return '';
			}

		}
	}
	return typeof obj === "object" && !override ? ' ' : obj;
};
/**--Noodles.Context--
name:setObject
description: sets an object for the current Context
@param {Noodle.Context}
@param {array}
@param {*}
*/
Context.prototype.setObject = function(Template, key,value){
	key = typeof key !== "object" ? [key] : key;

	var obj = this._others,
		keyTemp = key[0].toLowerCase(),
		obj,keys,keyIndex;
	if(!this._metaSkip[keyTemp] && this._metaData.hasOwnProperty(keyTemp)){
		if(this.debugMode) this.error(Template,'Meta Data variable cannot be set at run time');
	}
	for(var i = 0, l = key.length - 1; i < l; i++){
		keyTemp = typeof key[0].execute !== "undefined" ? key[0].execute(Template,this).toLowerCase() : key[0];
		if(typeof obj[keyTemp] !== "undefined"){
			obj = obj[keyTemp];
		}
		else{
			keys = ',' + Object.keys(obj).join()+ ',';
			keyIndex = keys.toLowerCase().indexOf(',' + tmp +',');
			if(keyIndex > -1){
				keyTemp = keys.slice(keyindex + 1, keyindex + 1 + keyTemp.length);
				obj[keyTemp.toLowerCase()] = obj[keyTemp];
				obj = obj[keyTemp];
			}
			else{
		 		return '';
			}

		}
	}
	obj[(typeof key[l].execute !== "undefined" ? key[l].execute(Template,this) : key[l]).toLowerCase()] = typeof value.execute !== "undefined" ? value.execute(Template,this) : value;
};
/**--Noodles.Context--
name:deleteObject
description: deletes an object for the current Context
@param {Noodle.Context}
@param {array}
@param {*}
*/
Context.prototype.deleteObject = function(Template, key){
	key = typeof key !== "object" ? [key] : key;

	var obj = this._others,
		keyTemp = key[0].toLowerCase(),
		obj,keys,keyIndex;
	if(this._metaData.hasOwnProperty(keyTemp)){
		if(this.debugMode) this.error(Template,'Meta Data variable cannot be deleted at run time');
	}
	for(var i = 0, l = key.length - 1; i < l; i++){
		keyTemp = typeof key[0].execute !== "undefined" ? key[0].execute(Template,this).toLowerCase() : key[0];
		if(typeof obj[keyTemp] !== "undefined"){
			obj = obj[keyTemp];
		}
		else{
			keys = ',' + Object.keys(obj).join()+ ',';
			keyIndex = keys.toLowerCase().indexOf(',' + tmp +',');
			if(keyIndex > -1){
				keyTemp = keys.slice(keyindex + 1, keyindex + 1 + keyTemp.length);
				obj[keyTemp.toLowerCase()] = obj[keyTemp];
				obj = obj[keyTemp];
			}
			else{
		 		return '';
			}

		}
	}
	delete obj[(typeof key[l].execute !== "undefined" ? key[l].execute(Template,this) : key[l]).toLowerCase()];
};
/**--Noodles.Context--
name:error
description: sets an error for the current context.
@param {Noodle.Template}
@param {string}
@param {*}
*/
Context.prototype.error = function(Template,error){
	var lineNumber = Template._executionStack[Context.current].lineStart;
	this.errors.push({
		error:Template.language.error(error + 'on line ' + lineNumber + '.'),
		lineNumber:lineNumber
	});
};

});<commit_msg>fixed object access code<commit_after>//Context class for Noodles
//otherwise just make sure that the browser version loads before this file.
if(typeof process !== "undefined"){
	var requirejs = require('requirejs');
	var define = requirejs.define;
}

define(function(require, exports, module){
var _Template = require('./template').Template;
/**--Noodles--
name:Context
description: Template execution
@param {Noodles.Template}
@param {object}
@param {boolean=}
*/
var Context = exports.Context = function(Template,obj,debugMode){
	if(typeof _Template === "undefined") _Template = require('./template').Template;
	this._others = obj;
	this._metaData = Template._metaData;
	this._metaSkip = {};
	if(debugMode){
		this.debugMode = true;
		this.errors = [];
	}
	else{
		this.debugMode = false;
	}
};
/**--Noodles.Context--
name:getObject
description: gets an object from the current Context
@param {Noodles.Template}
@param {string | array}
*/
Context.prototype.getObject = function(Template,key,override){
	key = typeof key !== "object" ? [key] : key;

	var keyTemp = key[0].toLowerCase(),
		obj,keys,keyIndex;
	if(!this._metaSkip[keyTemp] && this._metaData.hasOwnProperty(keyTemp)){
		return this._metaData[keyTemp].execute(Template,this);
	}
	obj = this._others;

	for(var i = 0, l = key.length; i < l; i++){
		keyTemp = typeof key[i].execute !== "undefined" ? key[i].execute(Template,this).toLowerCase() : key[i];
		if(typeof obj[keyTemp] !== "undefined"){
			obj = obj[keyTemp];
		}
		else{
			keys = ',' + Object.keys(obj).join()+ ',';
			keyIndex = keys.toLowerCase().indexOf(',' + keyTemp +',');
			if(keyIndex > -1){
				keyTemp = keys.slice(keyindex + 1, keyindex + 1 + keyTemp.length);
				obj[keyTemp.toLowerCase()] = obj[keyTemp];
				obj = obj[keyTemp];
			}
			else{
				obj[keyTemp] = '';
		 		return '';
			}

		}
	}
	return typeof obj.execute !== "undefined" ? obj.execute(Template,this) : typeof obj === "object" && !override ? ' ' : obj;
};
/**--Noodles.Context--
name:setObject
description: sets an object for the current Context
@param {Noodle.Context}
@param {array}
@param {*}
*/
Context.prototype.setObject = function(Template, key,value){
	key = typeof key !== "object" ? [key] : key;

	var obj = this._others,
		keyTemp = key[0].toLowerCase(),
		obj,keys,keyIndex;
	if(!this._metaSkip[keyTemp] && this._metaData.hasOwnProperty(keyTemp)){
		if(this.debugMode) this.error(Template,'Meta Data variable cannot be set at run time');
	}
	for(var i = 0, l = key.length - 1; i < l; i++){
		keyTemp = typeof key[i].execute !== "undefined" ? key[0].execute(Template,this).toLowerCase() : key[i];
		if(typeof obj[keyTemp] !== "undefined"){
			obj = obj[keyTemp];
		}
		else{
			keys = ',' + Object.keys(obj).join()+ ',';
			keyIndex = keys.toLowerCase().indexOf(',' + tmp +',');
			if(keyIndex > -1){
				keyTemp = keys.slice(keyindex + 1, keyindex + 1 + keyTemp.length);
				obj[keyTemp.toLowerCase()] = obj[keyTemp];
				obj = obj[keyTemp];
			}
			else{
		 		return '';
			}

		}
	}
	obj[(typeof key[l].execute !== "undefined" ? key[l].execute(Template,this) : key[l]).toLowerCase()] = typeof value.execute !== "undefined" ? value.execute(Template,this) : value;
};
/**--Noodles.Context--
name:deleteObject
description: deletes an object for the current Context
@param {Noodle.Context}
@param {array}
@param {*}
*/
Context.prototype.deleteObject = function(Template, key){
	key = typeof key !== "object" ? [key] : key;

	var obj = this._others,
		keyTemp = key[0].toLowerCase(),
		obj,keys,keyIndex;
	if(this._metaData.hasOwnProperty(keyTemp)){
		if(this.debugMode) this.error(Template,'Meta Data variable cannot be deleted at run time');
	}
	for(var i = 0, l = key.length - 1; i < l; i++){
		keyTemp = typeof key[i].execute !== "undefined" ? key[i].execute(Template,this).toLowerCase() : key[i];
		if(typeof obj[keyTemp] !== "undefined"){
			obj = obj[keyTemp];
		}
		else{
			keys = ',' + Object.keys(obj).join()+ ',';
			keyIndex = keys.toLowerCase().indexOf(',' + tmp +',');
			if(keyIndex > -1){
				keyTemp = keys.slice(keyindex + 1, keyindex + 1 + keyTemp.length);
				obj[keyTemp.toLowerCase()] = obj[keyTemp];
				obj = obj[keyTemp];
			}
			else{
		 		return '';
			}

		}
	}
	delete obj[(typeof key[l].execute !== "undefined" ? key[l].execute(Template,this) : key[l]).toLowerCase()];
};
/**--Noodles.Context--
name:error
description: sets an error for the current context.
@param {Noodle.Template}
@param {string}
@param {*}
*/
Context.prototype.error = function(Template,error){
	var lineNumber = Template._executionStack[Context.current].lineStart;
	this.errors.push({
		error:Template.language.error(error + 'on line ' + lineNumber + '.'),
		lineNumber:lineNumber
	});
};

});<|endoftext|>


<commit_before>const _ = require("lodash");

const conveyorAreaSettings = require("./game-settings/conveyor_area_settings");
const Lane = require("./lane");

const getLaneStarts = require("./util/get_lane_starts");
const getLaneHeight = require("./util/get_lane_height");

function ConveyorArea(settings) {
  this.settings = settings || conveyorAreaSettings();
  this.state = { };
  this.laneStarts = getLaneStarts(this.settings.laneCount, this.settings.height);
  this.laneHeight = getLaneHeight(this.settings.laneCount, this.settings.height);
  this.lanes = this.getLanes(this.settings.laneCount);
}

ConveyorArea.prototype.render = function (canvas) {
  //get a hold of the canvas
  //read some things from our state
  //draw our state to the canvas
  //return the gamestate even though it hasn't changed
  this.renderBase(canvas);
  this.renderLanes(canvas);
  return this.state;
};

ConveyorArea.prototype.getLanes = function (laneCount) {
  var lanes = [];
  _.times((laneCount) ,function() {
    lanes.push(new Lane());
  });
  return lanes;
};

ConveyorArea.prototype.renderBase = function (canvas) {
  var context = canvas[0].getContext("2d");
  context.clearRect(this.settings.x, this.settings.y, this.settings.width, this.settings.height);
  context.fillStyle = this.settings.bgColor;
  context.fillRect(this.settings.x, this.settings.y, this.settings.width, this.settings.height);

  // context.beginPath();
  //     context.rect(this.settings.x, this.settings.y, this.settings.width, this.settings.height);
  //     context.fillStyle = 'yellow';
  //     context.fill();
  //     context.lineWidth = 7;
  //     context.strokeStyle = 'black';
  //     context.stroke();
  return this.state;
};

ConveyorArea.prototype.renderLanes = function (canvas) {
  var context = canvas[0].getContext("2d");
  _.forEach(this.lanes, function(lane, index) {
    lane.render();
    var currentLaneStart = this.laneStarts[index];
    // console.log("LANE! "+ lane)
    context.beginPath();
        context.rect(this.settings.x, currentLaneStart, this.settings.width, this.settings.height);
        context.fillStyle = this.settings.bgColor;
        context.fill();
        context.lineWidth = 2;
        context.strokeStyle = 'black';
        context.stroke();
  }.bind(this));
  return this.state;
};

module.exports = ConveyorArea;
<commit_msg>removed old comments and references to utility modules for lane starts and lane height<commit_after>const _ = require("lodash");

const conveyorAreaSettings = require("./game-settings/conveyor_area_settings");
const Lane = require("./lane");

function ConveyorArea(settings) {
  this.state = {};
  this.settings = settings || conveyorAreaSettings();
  this.lanes = this.getLanes(this.settings.laneCount);
}

ConveyorArea.prototype.render = function (canvas) {
  //get a hold of the canvas
  //read some things from our state
  //draw our state to the canvas
  //return the gamestate even though it hasn't changed
  this.renderBase(canvas);
  this.renderLanes(canvas);
  return this.state;
};

ConveyorArea.prototype.getLanes = function (laneCount) {
  var lanes = [];
  _.times((laneCount) ,function() {
    lanes.push(new Lane());
  });
  return lanes;
};

ConveyorArea.prototype.renderBase = function (canvas) {
  var context = canvas[0].getContext("2d");
  context.clearRect(this.settings.x, this.settings.y, this.settings.width, this.settings.height);
  context.fillStyle = this.settings.bgColor;
  context.fillRect(this.settings.x, this.settings.y, this.settings.width, this.settings.height);

  return this.state;
};

ConveyorArea.prototype.renderLanes = function (canvas) {
  var context = canvas[0].getContext("2d");
  _.forEach(this.lanes, function(lane, index) {
    lane.render();
    var currentLaneStart = this.settings.vLaneStarts[index];
    // console.log("LANE! "+ lane)
    context.beginPath();
        context.rect(this.settings.x, currentLaneStart, this.settings.width, this.settings.height);
        context.fillStyle = this.settings.bgColor;
        context.fill();
        context.lineWidth = 2;
        context.strokeStyle = 'black';
        context.stroke();
  }.bind(this));
  return this.state;
};

module.exports = ConveyorArea;
<|endoftext|>


<commit_before>/*
 * post-hover.js
 * https://github.com/savetheinternet/Tinyboard/blob/master/js/post-hover.js
 *
 * Released under the MIT license
 * Copyright (c) 2012 Michael Save <savetheinternet@tinyboard.org>
 *
 * Usage:
 *   $config['additional_javascript'][] = 'js/jquery.min.js';
 *   $config['additional_javascript'][] = 'js/post-hover.js';
 *
 */

onready(function(){
	var dont_fetch_again = [];
	init_hover = function() {
		var $link = $(this);

		var id;

		if(id = $link.text().match(/^>>(\d+)$/)) {
			id = id[1];
		}

		var $post = false;
		var hovering = false;
		var hovered_at;
		$link.hover(function(e) {
			hovering = true;
			hovered_at = {'x': e.pageX, 'y': e.pageY};

			var start_hover = function($link) {
				if($post.is(':visible') &&
						$post.offset().top + $post.height() >= $(window).scrollTop() &&
						$post.offset().top <= $(window).scrollTop() + $(window).height()
						) {
					// post is in view
					$post.attr('style', 'border-style: none dashed dashed none; background: ' + $post.css('border-right-color'));
				} else {
					var $newPost = $post.clone();
					$newPost.find('span.mentioned').remove();
					$newPost
						.attr('id', 'post-hover-' + id)
						.addClass('post-hover')
						.css('position', 'absolute')
						.css('border-style', 'solid')
						.css('box-shadow', '1px 1px 1px #999')
						.css('display', 'block')
						.insertAfter($link.parent());
					$link.trigger('mousemove');
				}
			};

			$post = $('div.post#reply_' + id);
			if($post.length > 0) {
				start_hover($(this));
			} else {
				var url = $link.attr('href').replace(/#.*$/, '');

				if($.inArray(url, dont_fetch_again) != -1) {
					return;
				}
				dont_fetch_again.push(url);

				$.ajax({
					url: url,
					context: document.body,
					success: function(data) {
						$(data).find('div.post.reply').each(function() {
							if($('#' + $(this).attr('id')).length == 0)
								$('div.post:first').prepend($(this).css('display', 'none').addClass('hidden'));

						});

						$post = $('div.post#reply_' + id);
						if(hovering && $post.length > 0) {
							start_hover($link);
						}
					}
				});
			}
		}, function() {
			hovering = false;
			if(!$post)
				return;

			$post.attr('style', '');
			if($post.hasClass('hidden'))
				$post.css('display', 'none');
			$('.post-hover').remove();
		}).mousemove(function(e) {
			if(!$post)
				return;

			var $hover = $('#post-hover-' + id);
			if($hover.length == 0)
				return;

			var top = (e.pageY ? e.pageY : hovered_at['y']) - 10;

			if(e.pageY < $(window).scrollTop() + 15) {
				top = $(window).scrollTop();
			} else if(e.pageY > $(window).scrollTop() + $(window).height() - $hover.height() - 15) {
				top = $(window).scrollTop() + $(window).height() - $hover.height() - 15;
			}

			$hover.css('left', (e.pageX ? e.pageX : hovered_at['x'])).css('top', top);
		});
	};

	$('div.body a:not([rel="nofollow"])').each(init_hover);

	// allow to work with auto-reload.js, etc.
	$(document).bind('new_post', function(e, post) {
		$(post).find('div.body a:not([rel="nofollow"])').each(init_hover);
	});
});

<commit_msg>Fix #71.<commit_after>/*
 * post-hover.js
 * https://github.com/savetheinternet/Tinyboard/blob/master/js/post-hover.js
 *
 * Released under the MIT license
 * Copyright (c) 2012 Michael Save <savetheinternet@tinyboard.org>
 *
 * Usage:
 *   $config['additional_javascript'][] = 'js/jquery.min.js';
 *   $config['additional_javascript'][] = 'js/post-hover.js';
 *
 */

onready(function(){
	var dont_fetch_again = [];
	init_hover = function() {
		var $link = $(this);

		var id;

		if(id = $link.text().match(/^>>(\d+)$/)) {
			id = id[1];
		} else {
			return;
		}

		var $post = false;
		var hovering = false;
		var hovered_at;
		$link.hover(function(e) {
			hovering = true;
			hovered_at = {'x': e.pageX, 'y': e.pageY};

			var start_hover = function($link) {
				if($post.is(':visible') &&
						$post.offset().top + $post.height() >= $(window).scrollTop() &&
						$post.offset().top <= $(window).scrollTop() + $(window).height()
						) {
					// post is in view
					$post.attr('style', 'border-style: none dashed dashed none; background: ' + $post.css('border-right-color'));
				} else {
					var $newPost = $post.clone();
					$newPost.find('span.mentioned').remove();
					$newPost
						.attr('id', 'post-hover-' + id)
						.addClass('post-hover')
						.css('position', 'absolute')
						.css('border-style', 'solid')
						.css('box-shadow', '1px 1px 1px #999')
						.css('display', 'block')
						.insertAfter($link.parent());
					$link.trigger('mousemove');
				}
			};

			$post = $('div.post#reply_' + id);
			if($post.length > 0) {
				start_hover($(this));
			} else {
				var url = $link.attr('href').replace(/#.*$/, '');

				if($.inArray(url, dont_fetch_again) != -1) {
					return;
				}
				dont_fetch_again.push(url);

				$.ajax({
					url: url,
					context: document.body,
					success: function(data) {
						$(data).find('div.post.reply').each(function() {
							if($('#' + $(this).attr('id')).length == 0)
								$('div.post:first').prepend($(this).css('display', 'none').addClass('hidden'));

						});

						$post = $('div.post#reply_' + id);
						if(hovering && $post.length > 0) {
							start_hover($link);
						}
					}
				});
			}
		}, function() {
			hovering = false;
			if(!$post)
				return;

			$post.attr('style', '');
			if($post.hasClass('hidden'))
				$post.css('display', 'none');
			$('.post-hover').remove();
		}).mousemove(function(e) {
			if(!$post)
				return;

			var $hover = $('#post-hover-' + id);
			if($hover.length == 0)
				return;

			var top = (e.pageY ? e.pageY : hovered_at['y']) - 10;

			if(e.pageY < $(window).scrollTop() + 15) {
				top = $(window).scrollTop();
			} else if(e.pageY > $(window).scrollTop() + $(window).height() - $hover.height() - 15) {
				top = $(window).scrollTop() + $(window).height() - $hover.height() - 15;
			}

			$hover.css('left', (e.pageX ? e.pageX : hovered_at['x'])).css('top', top);
		});
	};

	$('div.body a:not([rel="nofollow"])').each(init_hover);

	// allow to work with auto-reload.js, etc.
	$(document).bind('new_post', function(e, post) {
		$(post).find('div.body a:not([rel="nofollow"])').each(init_hover);
	});
});

<|endoftext|>


<commit_before>import {Button} from 'widget/button'
import {Context} from './context'
import PropTypes from 'prop-types'
import React from 'react'
import styles from './toolbar.module.css'

export class ToolbarButton extends React.Component {
    render() {
        const {className, icon, label, tooltip, disabled, selected, onClick} = this.props
        return (
            <Context.Consumer>
                {({horizontal, panel}) =>
                    <Button
                        className={[selected && !disabled ? styles.selected : null, panel ? styles.panel : null, className].join(' ')}
                        icon={icon}
                        label={label}
                        disabled={disabled}
                        onClick={e => onClick(e)}
                        tooltip={tooltip}
                        tooltipPlacement={horizontal ? 'top' : 'left'}
                        tooltipDisabled={!!(disabled || (panel && selected))}
                    />
                }
            </Context.Consumer>
        )
    }
}

ToolbarButton.propTypes = {
    className: PropTypes.string,
    disabled: PropTypes.any,
    icon: PropTypes.string,
    label: PropTypes.string,
    selected: PropTypes.any,
    tooltip: PropTypes.string,
    onClick: PropTypes.func
}
<commit_msg>Added ToolbarButton tooltipDelay prop.<commit_after>import {Button} from 'widget/button'
import {Context} from './context'
import PropTypes from 'prop-types'
import React from 'react'
import styles from './toolbar.module.css'

export class ToolbarButton extends React.Component {
    render() {
        const {className, icon, label, tooltip, tooltipDelay, disabled, selected, onClick} = this.props
        return (
            <Context.Consumer>
                {({horizontal, panel}) =>
                    <Button
                        className={[selected && !disabled ? styles.selected : null, panel ? styles.panel : null, className].join(' ')}
                        icon={icon}
                        label={label}
                        disabled={disabled}
                        onClick={e => onClick(e)}
                        tooltip={tooltip}
                        tooltipPlacement={horizontal ? 'top' : 'left'}
                        tooltipDisabled={!!(disabled || (panel && selected))}
                        tooltipDelay={tooltipDelay}
                    />
                }
            </Context.Consumer>
        )
    }
}

ToolbarButton.propTypes = {
    className: PropTypes.string,
    disabled: PropTypes.any,
    icon: PropTypes.string,
    label: PropTypes.string,
    selected: PropTypes.any,
    tooltip: PropTypes.string,
    tooltipDelay: PropTypes.number,
    onClick: PropTypes.func
}
<|endoftext|>


<commit_before>/*global define*/
define([
        '../../Core/Cartesian3',
        '../../Core/defaultValue',
        '../../Core/defined',
        '../../Core/defineProperties',
        '../../Core/DeveloperError',
        '../../Core/Ellipsoid',
        '../../Core/Extent',
        '../../Core/Math',
        '../../Core/Matrix4',
        '../../Scene/Camera',
        '../../Scene/CameraColumbusViewMode',
        '../../Scene/CameraFlightPath',
        '../../Scene/PerspectiveFrustum',
        '../../Scene/SceneMode',
        '../createCommand',
        '../../ThirdParty/knockout'
    ], function(
        Cartesian3,
        defaultValue,
        defined,
        defineProperties,
        DeveloperError,
        Ellipsoid,
        Extent,
        CesiumMath,
        Matrix4,
        Camera,
        CameraColumbusViewMode,
        CameraFlightPath,
        PerspectiveFrustum,
        SceneMode,
        createCommand,
        knockout) {
    "use strict";

    function viewHome(scene, ellipsoid, transitioner, flightDuration) {
        var mode = scene.mode;

        var camera = scene.getCamera();
        camera.controller.constrainedAxis = Cartesian3.UNIT_Z;

        var controller = scene.getScreenSpaceCameraController();

        controller.setEllipsoid(ellipsoid);
        controller.columbusViewMode = CameraColumbusViewMode.FREE;

        var canvas = scene.getCanvas();
        if (defined(transitioner) && mode === SceneMode.MORPHING) {
            transitioner.completeMorph();
        }
        var flight;
        var description;

        if (mode === SceneMode.SCENE2D) {
            camera.transform = new Matrix4(0, 0, 1, 0,
                                           1, 0, 0, 0,
                                           0, 1, 0, 0,
                                           0, 0, 0, 1);
            description = {
                destination : Extent.MAX_VALUE,
                duration : flightDuration
            };
            flight = CameraFlightPath.createAnimationExtent(scene.getFrameState(), description);
            scene.getAnimations().add(flight);
        } else if (mode === SceneMode.SCENE3D) {
            Cartesian3.add(camera.position, Matrix4.getTranslation(camera.transform), camera.position);
            var rotation = Matrix4.getRotation(camera.transform);
            rotation.multiplyByVector(camera.direction, camera.direction);
            rotation.multiplyByVector(camera.up, camera.up);
            rotation.multiplyByVector(camera.right, camera.right);
            camera.transform = Matrix4.IDENTITY.clone();
            var defaultCamera = new Camera(canvas);
            description = {
                destination : defaultCamera.position,
                duration : flightDuration,
                up : defaultCamera.up,
                direction : defaultCamera.direction,
                onComplete : onComplete
            };
            flight = CameraFlightPath.createAnimation(scene.getFrameState(), description);
            scene.getAnimations().add(flight);
        } else if (mode === SceneMode.COLUMBUS_VIEW) {
            camera.transform = new Matrix4(0.0, 0.0, 1.0, 0.0,
                                           1.0, 0.0, 0.0, 0.0,
                                           0.0, 1.0, 0.0, 0.0,
                                           0.0, 0.0, 0.0, 1.0);
            var maxRadii = ellipsoid.getMaximumRadius();
            var position = new Cartesian3(0.0, -1.0, 1.0).normalize().multiplyByScalar(5.0 * maxRadii);
            var direction = Cartesian3.ZERO.subtract(position).normalize();
            var right = direction.cross(Cartesian3.UNIT_Z);
            var up = right.cross(direction);

            description = {
                destination : position,
                duration : flightDuration,
                up : up,
                direction : direction,
                onComplete : onComplete
            };

            flight = CameraFlightPath.createAnimation(scene.getFrameState(), description);
            scene.getAnimations().add(flight);
        }
    }

    /**
     * The view model for {@link HomeButton}.
     * @alias HomeButtonViewModel
     * @constructor
     *
     * @param {Scene} scene The scene instance to use.
     * @param {SceneTransitioner} [transitioner] The scene transitioner instance to use.
     * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to be viewed when in home position.
     * @param {Number} [flightDuration] The duration of the camera flight in milliseconds
     *
     * @exception {DeveloperError} scene is required.
     */
    var HomeButtonViewModel = function(scene, transitioner, ellipsoid, flightDuration) {
        if (!defined(scene)) {
            throw new DeveloperError('scene is required.');
        }

        ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);
        flightDuration = defaultValue(flightDuration, 1500);

        this._scene = scene;
        this._ellipsoid = ellipsoid;
        this._transitioner = transitioner;
        this._flightDuration = flightDuration;

        var that = this;
        this._command = createCommand(function() {
            viewHome(that._scene, that._ellipsoid, that._transitioner, that._flightDuration);
        });

        /**
         * Gets or sets the tooltip.  This property is observable.
         *
         * @type {String}
         */
        this.tooltip = 'View Home';

        knockout.track(this, ['tooltip']);
    };

    defineProperties(HomeButtonViewModel.prototype, {
        /**
         * Gets the scene transitioner being used by the scene.
         * If a transitioner is assigned, any running morphs will be completed
         * when the home button is pressed.  The transitioner must be using
         * the same Scene instance as the scene property.
         * @memberof HomeButtonViewModel.prototype
         *
         * @type {SceneTransitioner}
         */
        sceneTransitioner : {
            get : function() {
                return this._transitioner;
            }
        },

        /**
         * Gets the scene to control.
         * @memberof HomeButtonViewModel.prototype
         *
         * @type {Scene}
         */
        scene : {
            get : function() {
                return this._scene;
            }
        },

        /**
         * Gets the ellipsoid to be viewed when in home position.
         * @memberof HomeButtonViewModel.prototype
         *
         * @type {Ellipsoid}
         */
        ellipsoid : {
            get : function() {
                return this._ellipsoid;
            }
        },

        /**
         * Gets the Command that is executed when the button is clicked.
         * @memberof HomeButtonViewModel.prototype
         *
         * @type {Command}
         */
        command : {
            get : function() {
                return this._command;
            }
        },

        /**
         * Gets or sets the the duration of the camera flight in milliseconds.
         * A value of zero causes the camera to instantly switch to home view.
         * @memberof HomeButtonViewModel.prototype
         *
         * @type {Number}
         */
        flightDuration : {
            get : function() {
                return this._flightDuration;
            },
            set : function(value) {
                if (value < 0) {
                    throw new DeveloperError('value must be positive.');
                }
                this._flightDuration = value;
            }
        }
    });

    return HomeButtonViewModel;
});
<commit_msg>Remove references to unexisting onComplete function<commit_after>/*global define*/
define([
        '../../Core/Cartesian3',
        '../../Core/defaultValue',
        '../../Core/defined',
        '../../Core/defineProperties',
        '../../Core/DeveloperError',
        '../../Core/Ellipsoid',
        '../../Core/Extent',
        '../../Core/Math',
        '../../Core/Matrix4',
        '../../Scene/Camera',
        '../../Scene/CameraColumbusViewMode',
        '../../Scene/CameraFlightPath',
        '../../Scene/PerspectiveFrustum',
        '../../Scene/SceneMode',
        '../createCommand',
        '../../ThirdParty/knockout'
    ], function(
        Cartesian3,
        defaultValue,
        defined,
        defineProperties,
        DeveloperError,
        Ellipsoid,
        Extent,
        CesiumMath,
        Matrix4,
        Camera,
        CameraColumbusViewMode,
        CameraFlightPath,
        PerspectiveFrustum,
        SceneMode,
        createCommand,
        knockout) {
    "use strict";

    function viewHome(scene, ellipsoid, transitioner, flightDuration) {
        var mode = scene.mode;

        var camera = scene.getCamera();
        camera.controller.constrainedAxis = Cartesian3.UNIT_Z;

        var controller = scene.getScreenSpaceCameraController();

        controller.setEllipsoid(ellipsoid);
        controller.columbusViewMode = CameraColumbusViewMode.FREE;

        var canvas = scene.getCanvas();
        if (defined(transitioner) && mode === SceneMode.MORPHING) {
            transitioner.completeMorph();
        }
        var flight;
        var description;

        if (mode === SceneMode.SCENE2D) {
            camera.transform = new Matrix4(0, 0, 1, 0,
                                           1, 0, 0, 0,
                                           0, 1, 0, 0,
                                           0, 0, 0, 1);
            description = {
                destination : Extent.MAX_VALUE,
                duration : flightDuration
            };
            flight = CameraFlightPath.createAnimationExtent(scene.getFrameState(), description);
            scene.getAnimations().add(flight);
        } else if (mode === SceneMode.SCENE3D) {
            Cartesian3.add(camera.position, Matrix4.getTranslation(camera.transform), camera.position);
            var rotation = Matrix4.getRotation(camera.transform);
            rotation.multiplyByVector(camera.direction, camera.direction);
            rotation.multiplyByVector(camera.up, camera.up);
            rotation.multiplyByVector(camera.right, camera.right);
            camera.transform = Matrix4.IDENTITY.clone();
            var defaultCamera = new Camera(canvas);
            description = {
                destination : defaultCamera.position,
                duration : flightDuration,
                up : defaultCamera.up,
                direction : defaultCamera.direction
            };
            flight = CameraFlightPath.createAnimation(scene.getFrameState(), description);
            scene.getAnimations().add(flight);
        } else if (mode === SceneMode.COLUMBUS_VIEW) {
            camera.transform = new Matrix4(0.0, 0.0, 1.0, 0.0,
                                           1.0, 0.0, 0.0, 0.0,
                                           0.0, 1.0, 0.0, 0.0,
                                           0.0, 0.0, 0.0, 1.0);
            var maxRadii = ellipsoid.getMaximumRadius();
            var position = new Cartesian3(0.0, -1.0, 1.0).normalize().multiplyByScalar(5.0 * maxRadii);
            var direction = Cartesian3.ZERO.subtract(position).normalize();
            var right = direction.cross(Cartesian3.UNIT_Z);
            var up = right.cross(direction);

            description = {
                destination : position,
                duration : flightDuration,
                up : up,
                direction : direction
            };

            flight = CameraFlightPath.createAnimation(scene.getFrameState(), description);
            scene.getAnimations().add(flight);
        }
    }

    /**
     * The view model for {@link HomeButton}.
     * @alias HomeButtonViewModel
     * @constructor
     *
     * @param {Scene} scene The scene instance to use.
     * @param {SceneTransitioner} [transitioner] The scene transitioner instance to use.
     * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to be viewed when in home position.
     * @param {Number} [flightDuration] The duration of the camera flight in milliseconds
     *
     * @exception {DeveloperError} scene is required.
     */
    var HomeButtonViewModel = function(scene, transitioner, ellipsoid, flightDuration) {
        if (!defined(scene)) {
            throw new DeveloperError('scene is required.');
        }

        ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);
        flightDuration = defaultValue(flightDuration, 1500);

        this._scene = scene;
        this._ellipsoid = ellipsoid;
        this._transitioner = transitioner;
        this._flightDuration = flightDuration;

        var that = this;
        this._command = createCommand(function() {
            viewHome(that._scene, that._ellipsoid, that._transitioner, that._flightDuration);
        });

        /**
         * Gets or sets the tooltip.  This property is observable.
         *
         * @type {String}
         */
        this.tooltip = 'View Home';

        knockout.track(this, ['tooltip']);
    };

    defineProperties(HomeButtonViewModel.prototype, {
        /**
         * Gets the scene transitioner being used by the scene.
         * If a transitioner is assigned, any running morphs will be completed
         * when the home button is pressed.  The transitioner must be using
         * the same Scene instance as the scene property.
         * @memberof HomeButtonViewModel.prototype
         *
         * @type {SceneTransitioner}
         */
        sceneTransitioner : {
            get : function() {
                return this._transitioner;
            }
        },

        /**
         * Gets the scene to control.
         * @memberof HomeButtonViewModel.prototype
         *
         * @type {Scene}
         */
        scene : {
            get : function() {
                return this._scene;
            }
        },

        /**
         * Gets the ellipsoid to be viewed when in home position.
         * @memberof HomeButtonViewModel.prototype
         *
         * @type {Ellipsoid}
         */
        ellipsoid : {
            get : function() {
                return this._ellipsoid;
            }
        },

        /**
         * Gets the Command that is executed when the button is clicked.
         * @memberof HomeButtonViewModel.prototype
         *
         * @type {Command}
         */
        command : {
            get : function() {
                return this._command;
            }
        },

        /**
         * Gets or sets the the duration of the camera flight in milliseconds.
         * A value of zero causes the camera to instantly switch to home view.
         * @memberof HomeButtonViewModel.prototype
         *
         * @type {Number}
         */
        flightDuration : {
            get : function() {
                return this._flightDuration;
            },
            set : function(value) {
                if (value < 0) {
                    throw new DeveloperError('value must be positive.');
                }
                this._flightDuration = value;
            }
        }
    });

    return HomeButtonViewModel;
});
<|endoftext|>


<commit_before>// StackOverflow: https://stackoverflow.com/questions/8844256/split-string-including-regular-expression-match

function map(str, regexp, matchMapper, differMapper, flag) {
	let nRegexp = new RegExp(regexp, flag || true ? 'g' : '');

	let test,
		lastIndex = 0;

	let result = [];

	while (test = nRegexp.exec(str)) {
		const start = lastIndex,
			pivot = nRegexp.lastIndex - test[0].length,
			end = nRegexp.lastIndex;

		result.push(
			differMapper(str.slice(start, pivot), start, pivot, str),
			matchMapper(test[0], pivot, end, str)
		);

		lastIndex = nRegexp.lastIndex;
	}

	const start = lastIndex,
		pivot = str.length;

	result.push(
		differMapper(str.slice(lastIndex), start, pivot, str)
	)

	return result;
}

module.exports = map;
<commit_msg>fix: map default callback<commit_after>// StackOverflow: https://stackoverflow.com/questions/8844256/split-string-including-regular-expression-match

function map(str, regexp, mapper, otherwise = () => null, flag) {
	let nRegexp = new RegExp(regexp, flag || true ? 'g' : '');

	let test,
		lastIndex = 0;

	let result = [];

	while (test = nRegexp.exec(str)) {
		const start = lastIndex,
			pivot = nRegexp.lastIndex - test[0].length,
			end = nRegexp.lastIndex;

		result.push(
			otherwise(str.slice(start, pivot), start, pivot, str),
			mapper(test[0], pivot, end, str)
		);

		lastIndex = nRegexp.lastIndex;
	}

	const start = lastIndex,
		pivot = str.length;

	result.push(
		otherwise(str.slice(lastIndex), start, pivot, str)
	)

	return result;
}

module.exports = map;
<|endoftext|>


<commit_before>// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt

frappe.ui.form.on('Exercise Type', {
	refresh: function(frm) {
		let wrapper = frm.fields_dict.steps_html.wrapper;

		frm.ExerciseEditor = new erpnext.ExerciseEditor(frm, wrapper);
	}
});

erpnext.ExerciseEditor = Class.extend({
	init: function(frm, wrapper) {
		this.wrapper = wrapper;
		this.frm = frm;
		this.make(frm, wrapper);
	},

	make: function(frm, wrapper) {
		$(this.wrapper).empty();

		this.exercise_toolbar = $('
\
		<button class="btn btn-default btn-add btn-xs" style="margin-left: 10px;"></button>').appendTo(this.wrapper);

		this.exercise_cards = $('

').appendTo(this.wrapper);

		this.row = $('

').appendTo(this.exercise_cards);

		let me = this;

		this.exercise_toolbar.find(".btn-add")
			.html(__('Add'))
			.on("click", function() {
				me.show_add_card_dialog(frm);
			});

		if (frm.doc.steps_table && frm.doc.steps_table.length > 0) {
			this.make_cards(frm);
			this.make_buttons(frm);
		}
	},

	make_cards: function(frm) {
		var me = this;
		$(me.exercise_cards).empty();

		$.each(frm.doc.steps_table, function(i, step) {
			$(repl(`

%(title)s

%(description)s

							<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"></button>
							<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"></button>

`, {image_src: step.image, title: step.title, description: step.description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row);
		});
	},

	make_buttons: function(frm) {
		let me = this;
		$('.btn-edit').on('click', function() {
			let id = $(this).attr('data-id');
			me.show_edit_card_dialog(frm, id);
		});

		$('.btn-del').on('click', function() {
			let id = $(this).attr('data-id');
			$('#card-'+id).addClass("zoomOutDelete");

			setTimeout(() => {
				// not using grid_rows[id].remove because
				// grid_rows is not defined when the table is hidden
				frm.doc.steps_table.pop(id);
				frm.refresh_field('steps_table');
				$('#col-'+id).remove();
				frm.dirty();
			}, 300);
		});
	},

	show_add_card_dialog: function(frm) {
		let me = this;
		let d = new frappe.ui.Dialog({
			title: __('Add Exercise Step'),
			fields: [
				{
					"label": "Title",
					"fieldname": "title",
					"fieldtype": "Data",
					"reqd": 1
				},
				{
					"label": "Attach Image",
					"fieldname": "image",
					"fieldtype": "Attach Image"
				},
				{
					"label": "Step Description",
					"fieldname": "step_description",
					"fieldtype": "Long Text"
				}
			],
			primary_action: function() {
				let data = d.get_values();
				let i = 0;
				if (frm.doc.steps_table) {
					i = frm.doc.steps_table.length;
				}
				$(repl(`

%(title)s

%(description)s

								<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"></button>
								<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"></button>

`, {image_src: data.image, title: data.title, description: data.step_description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row);
				let step = frappe.model.add_child(frm.doc, 'Exercise Type Step', 'steps_table');
				step.title = data.title;
				step.image = data.image;
				step.description = data.step_description;
				me.make_buttons(frm);
				frm.refresh_field('steps_table');
				d.hide();
			},
			primary_action_label: __('Add')
		});
		d.show();
	},

	show_edit_card_dialog: function(frm, id) {
		let new_dialog = new frappe.ui.Dialog({
			title: __("Edit Exercise Step"),
			fields: [
				{
					"label": "Title",
					"fieldname": "title",
					"fieldtype": "Data",
					"reqd": 1
				},
				{
					"label": "Attach Image",
					"fieldname": "image",
					"fieldtype": "Attach Image"
				},
				{
					"label": "Step Description",
					"fieldname": "step_description",
					"fieldtype": "Long Text"
				}
			],
			primary_action: () => {
				let data = new_dialog.get_values();
				$('#card-'+id).find('.card-title').html(data.title);
				$('#card-'+id).find('img').attr('src', data.image);
				$('#card-'+id).find('.card-text').html(data.step_description);

				frm.doc.steps_table[id].title = data.title;
				frm.doc.steps_table[id].image = data.image;
				frm.doc.steps_table[id].description = data.step_description;
				refresh_field('steps_table');
				frm.dirty();
				new_dialog.hide();
			},
			primary_action_label: __("Edit"),
		});

		new_dialog.set_values({
			title: frm.doc.steps_table[id].title,
			image: frm.doc.steps_table[id].image,
			step_description: frm.doc.steps_table[id].description
		});
		new_dialog.show();
	}
});
<commit_msg>fix: exercise type<commit_after>// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt

frappe.ui.form.on('Exercise Type', {
	refresh: function(frm) {
		let wrapper = frm.fields_dict.steps_html.wrapper;

		frm.ExerciseEditor = new erpnext.ExerciseEditor(frm, wrapper);
	}
});

erpnext.ExerciseEditor = Class.extend({
	init: function(frm, wrapper) {
		this.wrapper = wrapper;
		this.frm = frm;
		this.make(frm, wrapper);
	},

	make: function(frm, wrapper) {
		$(this.wrapper).empty();

		this.exercise_toolbar = $('
\
		<button class="btn btn-default btn-add btn-xs" style="margin-left: 10px;"></button>').appendTo(this.wrapper);

		this.exercise_cards = $('

').appendTo(this.wrapper);

		this.row = $('

').appendTo(this.wrapper);

		let me = this;

		this.exercise_toolbar.find(".btn-add")
			.html(__('Add'))
			.on("click", function() {
				me.show_add_card_dialog(frm);
			});

		if (frm.doc.steps_table && frm.doc.steps_table.length > 0) {
			this.make_cards(frm);
			this.make_buttons(frm);
		}
	},

	make_cards: function(frm) {
		var me = this;
		$(me.exercise_cards).empty();

		$.each(frm.doc.steps_table, function(i, step) {
			$(repl(`

%(title)s

%(description)s

							<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"></button>
							<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"></button>

`, {image_src: step.image, title: step.title, description: step.description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row);
		});
	},

	make_buttons: function(frm) {
		let me = this;
		$('.btn-edit').on('click', function() {
			let id = $(this).attr('data-id');
			me.show_edit_card_dialog(frm, id);
		});

		$('.btn-del').on('click', function() {
			let id = $(this).attr('data-id');
			$('#card-'+id).addClass("zoomOutDelete");

			setTimeout(() => {
				// not using grid_rows[id].remove because
				// grid_rows is not defined when the table is hidden
				frm.doc.steps_table.pop(id);
				frm.refresh_field('steps_table');
				$('#col-'+id).remove();
				frm.dirty();
			}, 300);
		});
	},

	show_add_card_dialog: function(frm) {
		let me = this;
		let d = new frappe.ui.Dialog({
			title: __('Add Exercise Step'),
			fields: [
				{
					"label": "Title",
					"fieldname": "title",
					"fieldtype": "Data",
					"reqd": 1
				},
				{
					"label": "Attach Image",
					"fieldname": "image",
					"fieldtype": "Attach Image"
				},
				{
					"label": "Step Description",
					"fieldname": "step_description",
					"fieldtype": "Long Text"
				}
			],
			primary_action: function() {
				let data = d.get_values();
				let i = 0;
				if (frm.doc.steps_table) {
					i = frm.doc.steps_table.length;
				}
				$(repl(`

%(title)s

%(description)s

								<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"></button>
								<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"></button>

`, {image_src: data.image, title: data.title, description: data.step_description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row);
				let step = frappe.model.add_child(frm.doc, 'Exercise Type Step', 'steps_table');
				step.title = data.title;
				step.image = data.image;
				step.description = data.step_description;
				me.make_buttons(frm);
				frm.refresh_field('steps_table');
				d.hide();
			},
			primary_action_label: __('Add')
		});
		d.show();
	},

	show_edit_card_dialog: function(frm, id) {
		let new_dialog = new frappe.ui.Dialog({
			title: __("Edit Exercise Step"),
			fields: [
				{
					"label": "Title",
					"fieldname": "title",
					"fieldtype": "Data",
					"reqd": 1
				},
				{
					"label": "Attach Image",
					"fieldname": "image",
					"fieldtype": "Attach Image"
				},
				{
					"label": "Step Description",
					"fieldname": "step_description",
					"fieldtype": "Long Text"
				}
			],
			primary_action: () => {
				let data = new_dialog.get_values();
				$('#card-'+id).find('.card-title').html(data.title);
				$('#card-'+id).find('img').attr('src', data.image);
				$('#card-'+id).find('.card-text').html(data.step_description);

				frm.doc.steps_table[id].title = data.title;
				frm.doc.steps_table[id].image = data.image;
				frm.doc.steps_table[id].description = data.step_description;
				refresh_field('steps_table');
				frm.dirty();
				new_dialog.hide();
			},
			primary_action_label: __("Edit"),
		});

		new_dialog.set_values({
			title: frm.doc.steps_table[id].title,
			image: frm.doc.steps_table[id].image,
			step_description: frm.doc.steps_table[id].description
		});
		new_dialog.show();
	}
});
<|endoftext|>


<commit_before>var Ignore = require("fstream-ignore")
, inherits = require("inherits")
, path = require("path")
, fs = require("fs")

module.exports = Packer

inherits(Packer, Ignore)

function Packer (props) {
  if (!(this instanceof Packer)) {
    return new Packer(props)
  }

  if (typeof props === "string") {
    props = { path: props }
  }

  props.ignoreFiles = [ ".npmignore",
                        ".gitignore",
                        "package.json" ]

  Ignore.call(this, props)

  this.bundled = props.bundled
  this.bundleLinks = props.bundleLinks
  this.package = props.package

  // only do the magic bundling stuff for the node_modules folder that
  // lives right next to a package.json file.
  this.bundleMagic = this.parent &&
                     this.parent.packageRoot &&
                     this.basename === "node_modules"

  // in a node_modules folder, resolve symbolic links to
  // bundled dependencies when creating the package.
  props.follow = this.follow = this.bundleMagic
  // console.error("follow?", this.path, props.follow)

  if (this === this.root ||
      this.parent &&
      this.parent.bundleMagic &&
      this.basename.charAt(0) !== ".") {
    this.readBundledLinks()
  }

  this.on("entryStat", function (entry, props) {
    // files should *always* get into tarballs
    // in a user-writable state, even if they're
    // being installed from some wackey vm-mounted
    // read-only filesystem.
    entry.mode = props.mode = props.mode | 0200
  })
}

Packer.prototype.readBundledLinks = function () {
  if (this._paused) {
    this.once("resume", this.addIgnoreFiles)
    return
  }

  this.pause()
  fs.readdir(this.path + "/node_modules", function (er, list) {
    // no harm if there's no bundle
    var l = list && list.length
    if (er || l === 0) return this.resume()

    var errState = null
    , then = function then (er) {
      if (errState) return
      if (er) return errState = er, this.resume()
      if (-- l === 0) return this.resume()
    }.bind(this)

    list.forEach(function (pkg) {
      if (pkg.charAt(0) === ".") return then()
      var pd = this.path + "/node_modules/" + pkg
      fs.realpath(pd, function (er, rp) {
        if (er) return then()
        this.bundleLinks = this.bundleLinks || {}
        this.bundleLinks[pkg] = rp
        then()
      }.bind(this))
    }, this)
  }.bind(this))
}

Packer.prototype.applyIgnores = function (entry, partial, entryObj) {
  // package.json files can never be ignored.
  if (entry === "package.json") return true

  // readme files should never be ignored.
  if (entry.match(/^readme(\.[^\.]*)$/i)) return true

  // special rules.  see below.
  if (entry === "node_modules" && this.packageRoot) return true

  // some files are *never* allowed under any circumstances
  if (entry === ".git" ||
      entry === ".lock-wscript" ||
      entry.match(/^\.wafpickle-[0-9]+$/) ||
      entry === "CVS" ||
      entry === ".svn" ||
      entry === ".hg" ||
      entry.match(/^\..*\.swp$/) ||
      entry === ".DS_Store" ||
      entry.match(/^\._/) ||
      entry === "npm-debug.log"
    ) {
    return false
  }

  // in a node_modules folder, we only include bundled dependencies
  // also, prevent packages in node_modules from being affected
  // by rules set in the containing package, so that
  // bundles don't get busted.
  // Also, once in a bundle, everything is installed as-is
  // To prevent infinite cycles in the case of cyclic deps that are
  // linked with npm link, even in a bundle, deps are only bundled
  // if they're not already present at a higher level.
  if (this.bundleMagic) {
    // bubbling up.  stop here and allow anything the bundled pkg allows
    if (entry.indexOf("/") !== -1) return true

    // never include the .bin.  It's typically full of platform-specific
    // stuff like symlinks and .cmd files anyway.
    if (entry === ".bin") return false

    var shouldBundle = false
    // the package root.
    var p = this.parent
    // the package before this one.
    var pp = p && p.parent

    // if this entry has already been bundled, and is a symlink,
    // and it is the *same* symlink as this one, then exclude it.
    if (pp && pp.bundleLinks && this.bundleLinks &&
        pp.bundleLinks[entry] &&
        pp.bundleLinks[entry] === this.bundleLinks[entry]) {
      return false
    }

    // since it's *not* a symbolic link, if we're *already* in a bundle,
    // then we should include everything.
    if (pp && pp.package) {
      return true
    }

    // only include it at this point if it's a bundleDependency
    var bd = this.package && this.package.bundleDependencies
    var shouldBundle = bd && bd.indexOf(entry) !== -1
    // if we're not going to bundle it, then it doesn't count as a bundleLink
    // if (this.bundleLinks && !shouldBundle) delete this.bundleLinks[entry]
    return shouldBundle
  }
  // if (this.bundled) return true

  return Ignore.prototype.applyIgnores.call(this, entry, partial, entryObj)
}

Packer.prototype.addIgnoreFiles = function () {
  var entries = this.entries
  // if there's a .npmignore, then we do *not* want to
  // read the .gitignore.
  if (-1 !== entries.indexOf(".npmignore")) {
    var i = entries.indexOf(".gitignore")
    if (i !== -1) {
      entries.splice(i, 1)
    }
  }

  this.entries = entries

  Ignore.prototype.addIgnoreFiles.call(this)
}

Packer.prototype.readRules = function (buf, e) {
  if (e !== "package.json") {
    return Ignore.prototype.readRules.call(this, buf, e)
  }

  buf = buf.toString().trim()

  if (buf.length === 0) return []

  try {
    var p = this.package = JSON.parse(buf)
  } catch (er) {
    er.file = path.resolve(this.path, e)
    this.error(er)
    return
  }

  if (this === this.root) {
    this.bundleLinks = this.bundleLinks || {}
    this.bundleLinks[p.name] = this._path
  }

  this.packageRoot = true
  this.emit("package", p)

  // make bundle deps predictable
  if (p.bundledDependencies && !p.bundleDependencies) {
    p.bundleDependencies = p.bundledDependencies
    delete p.bundledDependencies
  }

  if (!p.files || !Array.isArray(p.files)) return []

  // ignore everything except what's in the files array.
  return ["*"].concat(p.files.map(function (f) {
    return "!" + f
  })).concat(p.files.map(function (f) {
    return "!" + f.replace(/\/+$/, "") + "/**"
  }))
}

Packer.prototype.getChildProps = function (stat) {
  var props = Ignore.prototype.getChildProps.call(this, stat)

  props.package = this.package

  props.bundled = this.bundled && this.bundled.slice(0)
  props.bundleLinks = this.bundleLinks &&
    Object.create(this.bundleLinks)

  // Directories have to be read as Packers
  // otherwise fstream.Reader will create a DirReader instead.
  if (stat.isDirectory()) {
    props.type = this.constructor
  }

  // only follow symbolic links directly in the node_modules folder.
  props.follow = false
  return props
}

var order =
  [ "package.json"
  , ".npmignore"
  , ".gitignore"
  , /^README(\.md)?$/
  , "LICENCE"
  , "LICENSE"
  , /\.js$/ ]

Packer.prototype.sort = function (a, b) {
  for (var i = 0, l = order.length; i < l; i ++) {
    var o = order[i]
    if (typeof o === "string") {
      if (a === o) return -1
      if (b === o) return 1
    } else {
      if (a.match(o)) return -1
      if (b.match(o)) return 1
    }
  }

  // deps go in the back
  if (a === "node_modules") return 1
  if (b === "node_modules") return -1

  return Ignore.prototype.sort.call(this, a, b)
}

Packer.prototype.emitEntry = function (entry) {
  if (this._paused) {
    this.once("resume", this.emitEntry.bind(this, entry))
    return
  }

  // if there is a .gitignore, then we're going to
  // rename it to .npmignore in the output.
  if (entry.basename === ".gitignore") {
    entry.basename = ".npmignore"
    entry.path = path.resolve(entry.dirname, entry.basename)
  }

  // all *.gyp files are renamed to binding.gyp for node-gyp
  // but only when they are in the same folder as a package.json file.
  if (entry.basename.match(/\.gyp$/) &&
      this.entries.indexOf("package.json") !== -1) {
    entry.basename = "binding.gyp"
    entry.path = path.resolve(entry.dirname, entry.basename)
  }

  // skip over symbolic links
  if (entry.type === "SymbolicLink") {
    entry.abort()
    return
  }

  if (entry.type !== "Directory") {
    // make it so that the folder in the tarball is named "package"
    var h = path.dirname((entry.root || entry).path)
    , t = entry.path.substr(h.length + 1).replace(/^[^\/\\]+/, "package")
    , p = h + "/" + t

    entry.path = p
    entry.dirname = path.dirname(p)
    return Ignore.prototype.emitEntry.call(this, entry)
  }

  // we don't want empty directories to show up in package
  // tarballs.
  // don't emit entry events for dirs, but still walk through
  // and read them.  This means that we need to proxy up their
  // entry events so that those entries won't be missed, since
  // .pipe() doesn't do anythign special with "child" events, on
  // with "entry" events.
  var me = this
  entry.on("entry", function (e) {
    if (e.parent === entry) {
      e.parent = me
      me.emit("entry", e)
    }
  })
  entry.on("package", this.emit.bind(this, "package"))
}
<commit_msg>Make ignore files configurable<commit_after>var Ignore = require("fstream-ignore")
, inherits = require("inherits")
, path = require("path")
, fs = require("fs")

module.exports = Packer

inherits(Packer, Ignore)

function Packer (props) {
  if (!(this instanceof Packer)) {
    return new Packer(props)
  }

  if (typeof props === "string") {
    props = { path: props }
  }

  props.ignoreFiles = props.ignoreFiles || [ ".npmignore",
                                             ".gitignore",
                                             "package.json" ]

  Ignore.call(this, props)

  this.bundled = props.bundled
  this.bundleLinks = props.bundleLinks
  this.package = props.package

  // only do the magic bundling stuff for the node_modules folder that
  // lives right next to a package.json file.
  this.bundleMagic = this.parent &&
                     this.parent.packageRoot &&
                     this.basename === "node_modules"

  // in a node_modules folder, resolve symbolic links to
  // bundled dependencies when creating the package.
  props.follow = this.follow = this.bundleMagic
  // console.error("follow?", this.path, props.follow)

  if (this === this.root ||
      this.parent &&
      this.parent.bundleMagic &&
      this.basename.charAt(0) !== ".") {
    this.readBundledLinks()
  }

  this.on("entryStat", function (entry, props) {
    // files should *always* get into tarballs
    // in a user-writable state, even if they're
    // being installed from some wackey vm-mounted
    // read-only filesystem.
    entry.mode = props.mode = props.mode | 0200
  })
}

Packer.prototype.readBundledLinks = function () {
  if (this._paused) {
    this.once("resume", this.addIgnoreFiles)
    return
  }

  this.pause()
  fs.readdir(this.path + "/node_modules", function (er, list) {
    // no harm if there's no bundle
    var l = list && list.length
    if (er || l === 0) return this.resume()

    var errState = null
    , then = function then (er) {
      if (errState) return
      if (er) return errState = er, this.resume()
      if (-- l === 0) return this.resume()
    }.bind(this)

    list.forEach(function (pkg) {
      if (pkg.charAt(0) === ".") return then()
      var pd = this.path + "/node_modules/" + pkg
      fs.realpath(pd, function (er, rp) {
        if (er) return then()
        this.bundleLinks = this.bundleLinks || {}
        this.bundleLinks[pkg] = rp
        then()
      }.bind(this))
    }, this)
  }.bind(this))
}

Packer.prototype.applyIgnores = function (entry, partial, entryObj) {
  // package.json files can never be ignored.
  if (entry === "package.json") return true

  // readme files should never be ignored.
  if (entry.match(/^readme(\.[^\.]*)$/i)) return true

  // special rules.  see below.
  if (entry === "node_modules" && this.packageRoot) return true

  // some files are *never* allowed under any circumstances
  if (entry === ".git" ||
      entry === ".lock-wscript" ||
      entry.match(/^\.wafpickle-[0-9]+$/) ||
      entry === "CVS" ||
      entry === ".svn" ||
      entry === ".hg" ||
      entry.match(/^\..*\.swp$/) ||
      entry === ".DS_Store" ||
      entry.match(/^\._/) ||
      entry === "npm-debug.log"
    ) {
    return false
  }

  // in a node_modules folder, we only include bundled dependencies
  // also, prevent packages in node_modules from being affected
  // by rules set in the containing package, so that
  // bundles don't get busted.
  // Also, once in a bundle, everything is installed as-is
  // To prevent infinite cycles in the case of cyclic deps that are
  // linked with npm link, even in a bundle, deps are only bundled
  // if they're not already present at a higher level.
  if (this.bundleMagic) {
    // bubbling up.  stop here and allow anything the bundled pkg allows
    if (entry.indexOf("/") !== -1) return true

    // never include the .bin.  It's typically full of platform-specific
    // stuff like symlinks and .cmd files anyway.
    if (entry === ".bin") return false

    var shouldBundle = false
    // the package root.
    var p = this.parent
    // the package before this one.
    var pp = p && p.parent

    // if this entry has already been bundled, and is a symlink,
    // and it is the *same* symlink as this one, then exclude it.
    if (pp && pp.bundleLinks && this.bundleLinks &&
        pp.bundleLinks[entry] &&
        pp.bundleLinks[entry] === this.bundleLinks[entry]) {
      return false
    }

    // since it's *not* a symbolic link, if we're *already* in a bundle,
    // then we should include everything.
    if (pp && pp.package) {
      return true
    }

    // only include it at this point if it's a bundleDependency
    var bd = this.package && this.package.bundleDependencies
    var shouldBundle = bd && bd.indexOf(entry) !== -1
    // if we're not going to bundle it, then it doesn't count as a bundleLink
    // if (this.bundleLinks && !shouldBundle) delete this.bundleLinks[entry]
    return shouldBundle
  }
  // if (this.bundled) return true

  return Ignore.prototype.applyIgnores.call(this, entry, partial, entryObj)
}

Packer.prototype.addIgnoreFiles = function () {
  var entries = this.entries
  // if there's a .npmignore, then we do *not* want to
  // read the .gitignore.
  if (-1 !== entries.indexOf(".npmignore")) {
    var i = entries.indexOf(".gitignore")
    if (i !== -1) {
      entries.splice(i, 1)
    }
  }

  this.entries = entries

  Ignore.prototype.addIgnoreFiles.call(this)
}

Packer.prototype.readRules = function (buf, e) {
  if (e !== "package.json") {
    return Ignore.prototype.readRules.call(this, buf, e)
  }

  buf = buf.toString().trim()

  if (buf.length === 0) return []

  try {
    var p = this.package = JSON.parse(buf)
  } catch (er) {
    er.file = path.resolve(this.path, e)
    this.error(er)
    return
  }

  if (this === this.root) {
    this.bundleLinks = this.bundleLinks || {}
    this.bundleLinks[p.name] = this._path
  }

  this.packageRoot = true
  this.emit("package", p)

  // make bundle deps predictable
  if (p.bundledDependencies && !p.bundleDependencies) {
    p.bundleDependencies = p.bundledDependencies
    delete p.bundledDependencies
  }

  if (!p.files || !Array.isArray(p.files)) return []

  // ignore everything except what's in the files array.
  return ["*"].concat(p.files.map(function (f) {
    return "!" + f
  })).concat(p.files.map(function (f) {
    return "!" + f.replace(/\/+$/, "") + "/**"
  }))
}

Packer.prototype.getChildProps = function (stat) {
  var props = Ignore.prototype.getChildProps.call(this, stat)

  props.package = this.package

  props.bundled = this.bundled && this.bundled.slice(0)
  props.bundleLinks = this.bundleLinks &&
    Object.create(this.bundleLinks)

  // Directories have to be read as Packers
  // otherwise fstream.Reader will create a DirReader instead.
  if (stat.isDirectory()) {
    props.type = this.constructor
  }

  // only follow symbolic links directly in the node_modules folder.
  props.follow = false
  return props
}

var order =
  [ "package.json"
  , ".npmignore"
  , ".gitignore"
  , /^README(\.md)?$/
  , "LICENCE"
  , "LICENSE"
  , /\.js$/ ]

Packer.prototype.sort = function (a, b) {
  for (var i = 0, l = order.length; i < l; i ++) {
    var o = order[i]
    if (typeof o === "string") {
      if (a === o) return -1
      if (b === o) return 1
    } else {
      if (a.match(o)) return -1
      if (b.match(o)) return 1
    }
  }

  // deps go in the back
  if (a === "node_modules") return 1
  if (b === "node_modules") return -1

  return Ignore.prototype.sort.call(this, a, b)
}

Packer.prototype.emitEntry = function (entry) {
  if (this._paused) {
    this.once("resume", this.emitEntry.bind(this, entry))
    return
  }

  // if there is a .gitignore, then we're going to
  // rename it to .npmignore in the output.
  if (entry.basename === ".gitignore") {
    entry.basename = ".npmignore"
    entry.path = path.resolve(entry.dirname, entry.basename)
  }

  // all *.gyp files are renamed to binding.gyp for node-gyp
  // but only when they are in the same folder as a package.json file.
  if (entry.basename.match(/\.gyp$/) &&
      this.entries.indexOf("package.json") !== -1) {
    entry.basename = "binding.gyp"
    entry.path = path.resolve(entry.dirname, entry.basename)
  }

  // skip over symbolic links
  if (entry.type === "SymbolicLink") {
    entry.abort()
    return
  }

  if (entry.type !== "Directory") {
    // make it so that the folder in the tarball is named "package"
    var h = path.dirname((entry.root || entry).path)
    , t = entry.path.substr(h.length + 1).replace(/^[^\/\\]+/, "package")
    , p = h + "/" + t

    entry.path = p
    entry.dirname = path.dirname(p)
    return Ignore.prototype.emitEntry.call(this, entry)
  }

  // we don't want empty directories to show up in package
  // tarballs.
  // don't emit entry events for dirs, but still walk through
  // and read them.  This means that we need to proxy up their
  // entry events so that those entries won't be missed, since
  // .pipe() doesn't do anythign special with "child" events, on
  // with "entry" events.
  var me = this
  entry.on("entry", function (e) {
    if (e.parent === entry) {
      e.parent = me
      me.emit("entry", e)
    }
  })
  entry.on("package", this.emit.bind(this, "package"))
}
<|endoftext|>


<commit_before>var middlewares = require('../src/middlewares');
var AppCache = require('../src/cache').AppCache;

describe('middlewares', () => {

  var fakeReq, fakeRes;

  beforeEach(() => {
    fakeReq = {
      originalUrl: 'http://example.com/parse/',
      url: 'http://example.com/',
      body: {
        _ApplicationId: 'FakeAppId'
      },
      headers: {},
      get: (key) => {
        return fakeReq.headers[key.toLowerCase()]
      }
    };
    fakeRes = jasmine.createSpyObj('fakeRes', ['end', 'status']);
    AppCache.put(fakeReq.body._ApplicationId, {});
  });

  afterEach(() => {
    AppCache.del(fakeReq.body._ApplicationId);
  });

  it('should use _ContentType if provided', (done) => {
    expect(fakeReq.headers['content-type']).toEqual(undefined);
    var contentType = 'image/jpeg';
    fakeReq.body._ContentType = contentType;
    middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
      expect(fakeReq.headers['content-type']).toEqual(contentType);
      expect(fakeReq.body._ContentType).toEqual(undefined);
      done()
    });
  });

  it('should give invalid response when keys are configured but no key supplied', () => {
    AppCache.put(fakeReq.body._ApplicationId, {
      masterKey: 'masterKey',
      restAPIKey: 'restAPIKey'
    });
    middlewares.handleParseHeaders(fakeReq, fakeRes);
    expect(fakeRes.status).toHaveBeenCalledWith(403);
  });

  it('should give invalid response when keys are configured but supplied key is incorrect', () => {
    AppCache.put(fakeReq.body._ApplicationId, {
      masterKey: 'masterKey',
      restAPIKey: 'restAPIKey'
    });
    fakeReq.headers['x-parse-rest-api-key'] = 'wrongKey';
    middlewares.handleParseHeaders(fakeReq, fakeRes);
    expect(fakeRes.status).toHaveBeenCalledWith(403);
  });

  it('should give invalid response when keys are configured but different key is supplied', () => {
    AppCache.put(fakeReq.body._ApplicationId, {
      masterKey: 'masterKey',
      restAPIKey: 'restAPIKey'
    });
    fakeReq.headers['x-parse-client-key'] = 'clientKey';
    middlewares.handleParseHeaders(fakeReq, fakeRes);
    expect(fakeRes.status).toHaveBeenCalledWith(403);
  });

  it('should succeed when any one of the configured keys supplied', (done) => {
    AppCache.put(fakeReq.body._ApplicationId, {
      clientKey: 'clientKey',
      masterKey: 'masterKey',
      restAPIKey: 'restAPIKey'
    });
    fakeReq.headers['x-parse-rest-api-key'] = 'restAPIKey';
    middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
      expect(fakeRes.status).not.toHaveBeenCalled();
      done();
    });
  });

  it('should succeed when no keys are configured and none supplied', (done) => {
    AppCache.put(fakeReq.body._ApplicationId, {
      masterKey: 'masterKey'
    });
    middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
      expect(fakeRes.status).not.toHaveBeenCalled();
      done();
    });
  });

  const BodyParams = {
    clientVersion: '_ClientVersion',
    installationId: '_InstallationId',
    sessionToken: '_SessionToken',
    masterKey: '_MasterKey',
    javascriptKey: '_JavaScriptKey'
  };

  const BodyKeys = Object.keys(BodyParams);

  BodyKeys.forEach((infoKey) => {
    const bodyKey = BodyParams[infoKey];
    const keyValue = 'Fake' + bodyKey;
        // javascriptKey is the only one that gets defaulted,
    const otherKeys = BodyKeys.filter((otherKey) => otherKey !== infoKey && otherKey !== 'javascriptKey');

    it(`it should pull ${bodyKey} into req.info`, (done) => {
      fakeReq.body[bodyKey] = keyValue;

      middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
        expect(fakeReq.body[bodyKey]).toEqual(undefined);
        expect(fakeReq.info[infoKey]).toEqual(keyValue);

        otherKeys.forEach((otherKey) => {
          expect(fakeReq.info[otherKey]).toEqual(undefined);
        });

        done();
      });
    });
  });
});
<commit_msg>Add a unit test to fail when clientKey=''<commit_after>var middlewares = require('../src/middlewares');
var AppCache = require('../src/cache').AppCache;

describe('middlewares', () => {

  var fakeReq, fakeRes;

  beforeEach(() => {
    fakeReq = {
      originalUrl: 'http://example.com/parse/',
      url: 'http://example.com/',
      body: {
        _ApplicationId: 'FakeAppId'
      },
      headers: {},
      get: (key) => {
        return fakeReq.headers[key.toLowerCase()]
      }
    };
    fakeRes = jasmine.createSpyObj('fakeRes', ['end', 'status']);
    AppCache.put(fakeReq.body._ApplicationId, {});
  });

  afterEach(() => {
    AppCache.del(fakeReq.body._ApplicationId);
  });

  it('should use _ContentType if provided', (done) => {
    expect(fakeReq.headers['content-type']).toEqual(undefined);
    var contentType = 'image/jpeg';
    fakeReq.body._ContentType = contentType;
    middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
      expect(fakeReq.headers['content-type']).toEqual(contentType);
      expect(fakeReq.body._ContentType).toEqual(undefined);
      done()
    });
  });

  it('should give invalid response when keys are configured but no key supplied', () => {
    AppCache.put(fakeReq.body._ApplicationId, {
      masterKey: 'masterKey',
      restAPIKey: 'restAPIKey'
    });
    middlewares.handleParseHeaders(fakeReq, fakeRes);
    expect(fakeRes.status).toHaveBeenCalledWith(403);
  });

  it('should give invalid response when keys are configured but supplied key is incorrect', () => {
    AppCache.put(fakeReq.body._ApplicationId, {
      masterKey: 'masterKey',
      restAPIKey: 'restAPIKey'
    });
    fakeReq.headers['x-parse-rest-api-key'] = 'wrongKey';
    middlewares.handleParseHeaders(fakeReq, fakeRes);
    expect(fakeRes.status).toHaveBeenCalledWith(403);
  });

  it('should give invalid response when keys are configured but different key is supplied', () => {
    AppCache.put(fakeReq.body._ApplicationId, {
      masterKey: 'masterKey',
      restAPIKey: 'restAPIKey'
    });
    fakeReq.headers['x-parse-client-key'] = 'clientKey';
    middlewares.handleParseHeaders(fakeReq, fakeRes);
    expect(fakeRes.status).toHaveBeenCalledWith(403);
  });

  it('should succeed when any one of the configured keys supplied', (done) => {
    AppCache.put(fakeReq.body._ApplicationId, {
      clientKey: 'clientKey',
      masterKey: 'masterKey',
      restAPIKey: 'restAPIKey'
    });
    fakeReq.headers['x-parse-rest-api-key'] = 'restAPIKey';
    middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
      expect(fakeRes.status).not.toHaveBeenCalled();
      done();
    });
  });

  it('should succeed when client key supplied but empty', (done) => {
    AppCache.put(fakeReq.body._ApplicationId, {
      clientKey: '',
      masterKey: 'masterKey',
      restAPIKey: 'restAPIKey'
    });
    fakeReq.headers['x-parse-client-key'] = '';
    middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
      expect(fakeRes.status).not.toHaveBeenCalled();
      done();
    });
  });

  it('should succeed when no keys are configured and none supplied', (done) => {
    AppCache.put(fakeReq.body._ApplicationId, {
      masterKey: 'masterKey'
    });
    middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
      expect(fakeRes.status).not.toHaveBeenCalled();
      done();
    });
  });

  const BodyParams = {
    clientVersion: '_ClientVersion',
    installationId: '_InstallationId',
    sessionToken: '_SessionToken',
    masterKey: '_MasterKey',
    javascriptKey: '_JavaScriptKey'
  };

  const BodyKeys = Object.keys(BodyParams);

  BodyKeys.forEach((infoKey) => {
    const bodyKey = BodyParams[infoKey];
    const keyValue = 'Fake' + bodyKey;
        // javascriptKey is the only one that gets defaulted,
    const otherKeys = BodyKeys.filter((otherKey) => otherKey !== infoKey && otherKey !== 'javascriptKey');

    it(`it should pull ${bodyKey} into req.info`, (done) => {
      fakeReq.body[bodyKey] = keyValue;

      middlewares.handleParseHeaders(fakeReq, fakeRes, () => {
        expect(fakeReq.body[bodyKey]).toEqual(undefined);
        expect(fakeReq.info[infoKey]).toEqual(keyValue);

        otherKeys.forEach((otherKey) => {
          expect(fakeReq.info[otherKey]).toEqual(undefined);
        });

        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>
;(function(win,undefined) {
	"use strict";

	var CC={},
	// this is typically window
	root = win || window || this,
	con = root.console,
	aps = Array.prototype.slice,
	lsKeys = ['CC.filter','CC.history'],

    // make sure we can save history, or don't save it at all
    persist = (root.localStorage && root.JSON);

    // inherit the console prototype
    if(con) {
    	CC = Object.create(con);
    }

	if (typeof module !== 'undefined') {
        module.exports = CC;
    } else {
        root.cconsole = CC;
    }

    // Default settings, console does not have a prototype
    CC.settings = {
    	persistConfig: {
    		filter: lsKeys[0],
    		history: lsKeys[1]
    	},
		standBy: false,
		timestamp: true,
		debug: true,
		environment : "development", // production || development
		history: persist ? JSON.parse(root.localStorage.getItem(lsKeys[1])) || [] : [],
		// limit the size of the array to 100
		maxHistory: 100,
		filter: persist ? root.localStorage.getItem(lsKeys[0]) || false: false,
		notify: function(error, identifier) { return; } // un-implemented, meant to be replaced by developer code.
    };

    // Add the ability to override the settings
    CC.set = function(settings) {
    	if(typeof settings === "undefined" ||
    		typeof settings !== "object" ||
    		settings instanceof String ||
    		settings instanceof Array) {
    		throw Error("You must pass an plain object to set settings. EG: { }");
    	}
    	// allow the setting of settings in a much easier way
    	// hasOwnProperty is to avoid times where you may have passed an odd function with inherited props
    	for(var setting in settings) if(settings.hasOwnProperty(setting)) {
    		CC.settings[setting] = settings[setting];
    	}
    };
    CC.clearFilter = function() {
    	CC.settings.filter = false;
		if( persist ) {
			root.localStorage.setItem(CC.settings.persistConfig.filter,false);
		}
    };
    CC.setFilter = function(string) {
    	// if not string, don't do it
    	if(typeof string !== "string" && !(string instanceof String)) {
    		throw new Error("Filters must be of type string");
    	}

    	CC.settings.filter = string;

		if( persist ) {
			root.localStorage.setItem(CC.settings.persistConfig.filter,string);
		}
    };

	// we intend to overwrite these methods
	var trace_methods = [
		'error',
		'warn',
		'info',
		'debug',
		'log'
	],
	// these methods will just 'pass through' to the original console or use console.log if it doesn't support them
	pass_methods = [
		'assert',
		'clear',
		'count',
		'dir',
		'dirxml',
		'exception',
		'group',
		'groupCollapsed',
		'groupEnd',
		'markTimeline',
		'profile',
		'profileEnd',
		'table',
		'time',
		'timeEnd',
		'timeStamp',
		'trace',
		'memory',
		'profiles'
	],
	idx = pass_methods.length,
	handleCircularReferences = function() {
		var circularKeys = []; // resetting the brains

		return function(key, value) {
			if( !!key && !!value && ['[object Object]','[object Array]'].indexOf(Object.prototype.toString.call(value)) > -1) {
				// an array or object
				if( circularKeys.indexOf(value) > -1 ){
					// already seen value
					return "<Circular Reference>";
				}
				circularKeys.push(value);
			} else if (!!key && !!value && Object.prototype.toString.call(value) !== '[object String]') {
				return value.toString();
			}
			return value;
		}
	},
	updateHistory = function(msg) {
		var stringify;
		// push to the beginning, not the end
		CC.settings.history.unshift( msg );
		// make sure we aren't running out of memory here
		if(CC.settings.history.length > CC.settings.maxHistory) {
			// drop the most recent off the top
			CC.settings.history.pop();
		}
		if( persist ) {
			root.localStorage.setItem(CC.settings.persistConfig.history,root.JSON.stringify( CC.settings.history, handleCircularReferences(), ""));
		}
	},
	loadPassMethods = function(method){
		CC[method]=function() {
			var args = aps.call(arguments);

			try {
				// if standBy, just ignore anything and output right away
				if(CC.settings.standBy){
					con.firebug ? con[method].apply(root, args) :
						con[method] ? con[method].apply(con,args) :
						con.log.apply(con,args);
					return;
				}

				// when we are in production mode, nothing should go through
				if(CC.settings.environment === "production" ) {
					return;
				}

				// everything past this point is not in production code

				// if no console
				// or debug is false
				// or the filter is on and doesn't match anything
				// return as nothing should go out
				if ( !con || !CC.settings.debug || (CC.settings.filter && args[0].indexOf(CC.settings.filter) < 0  )) {
					return;
				}

				// if a timestamp is needing to be set, push it in
				if(CC.settings.timestamp) {
					args.unshift(new Date().toISOString());
				}

				// push this command into the history
				updateHistory([method].concat( args ));

				// call the command that should be available or log it
				con.firebug ? con[method].apply(root, args) :
					con[method] ? con[method].apply(con,args) :
					con.log.apply(con,args);
			} catch(e) {
				// ignore errors we may throw unless debugging
				if(CC.settings.debug) {
					throw new Error(e);
				}
			}
		};
	},
	loadTraceMethods = function(idx,method){
		CC[method] = function() {
			var args = aps.call(arguments);

			try {
				// if standBy, just ignore anything and output right away
				if(CC.settings.standBy) {
					con.firebug ? con[method].apply(root, args) :
						con[method] ? con[method].apply(con,args) :
						con.log.apply(con,args);
					return;
				}

				// when we are in production mode, only allow errors to go through
				if(method !== 'error' && CC.settings.environment === "production" ) {
					return;
				}

				// everything past this point is not in production code, unless it is an error

				var log_arr,
					error = new Error(),
					stackError = error && error.stack,
					trace, line_trace,identifier="", re = /\//g,
					alwaysShow = ['error','warn'];

				// Sometimes when we try to get the stack trace,
				// things go poorly. We still want to continue on
				// our merry way however. We've noticed this
				// behavior particularly when highcharts is involved
				if (stackError && typeof stackError === 'string') {
					try {
						trace = stackError.split(/\r\n|\r|\n/);
						trace = trace[trace.length-1].split(/\//);
					}catch (ignore){
						trace = ['Failed to retrieve stack trace.'];
					}
				}

				line_trace = trace[trace.length-1].split(/:/);

				if(method!=='debug') {
					args.push(line_trace[0] + " Line "+line_trace[1]);
					identifier = line_trace[0].replace(re,"~")+":"+line_trace[1];
				} else {
					args.push(((new Error() && new Error().stack)?new Error().stack:'').split(/\r\n|\r|\n/));
				}

				// if no console
				// or the method is not an alwaysShow method and
				// 		debug is false
				// 		or the filter is on and doesn't match anything
				// return as nothing should go out
				if ( !con || ( alwaysShow.indexOf(method) < 0 && ( !CC.settings.debug || (CC.settings.filter && args[0].indexOf(CC.settings.filter) < 0  )))) {
					return;
				}

				if(CC.settings.timestamp) {
					args.unshift(new Date().toISOString());
				}

				log_arr = [method].concat( args );
				updateHistory(log_arr);

				// the method must be an error becaue of previous if statement
				if(CC.settings.environment === 'production') {
					CC.settings.notify( log_arr,  identifier);
					return;
				}

				// push to the actual console
				con.firebug ? con[method].apply(root, args) :
					con[method] ? con[method].apply(con,args) :
					con.log.apply(con,args);

			} catch(e){
				// ignore errors we may throw unless debugging
				if(CC.settings.debug) {
					throw new Error(e);
				}}
		};
	};

	// Add CC as the console
	root.console = CC;

	/* passthrough any console methods */
	while(--idx >= 0){
		loadPassMethods(pass_methods[idx]);
	}

	// reuse the vars
	idx = trace_methods.length;

	while(--idx >= 0){
		loadTraceMethods(idx,trace_methods[idx]);
	}

})(this);<commit_msg>Wrong defaults<commit_after>
;(function(win,undefined) {
	"use strict";

	var CC={},
	// this is typically window
	root = win || window || this,
	con = root.console,
	aps = Array.prototype.slice,
	lsKeys = ['CC.filter','CC.history'],

    // make sure we can save history, or don't save it at all
    persist = (root.localStorage && root.JSON);

    // inherit the console prototype
    if(con) {
    	CC = Object.create(con);
    }

	if (typeof module !== 'undefined') {
        module.exports = CC;
    } else {
        root.cconsole = CC;
    }

    // Default settings, console does not have a prototype
    CC.settings = {
    	persistConfig: {
    		filter: lsKeys[0],
    		history: lsKeys[1]
    	},
		standBy: false,
		timestamp: true,
		debug: false,
		environment : "production", // production || development
		history: persist ? JSON.parse(root.localStorage.getItem(lsKeys[1])) || [] : [],
		// limit the size of the array to 100
		maxHistory: 100,
		filter: persist ? root.localStorage.getItem(lsKeys[0]) || false: false,
		notify: function(error, identifier) { return; } // un-implemented, meant to be replaced by developer code.
    };

    // Add the ability to override the settings
    CC.set = function(settings) {
    	if(typeof settings === "undefined" ||
    		typeof settings !== "object" ||
    		settings instanceof String ||
    		settings instanceof Array) {
    		throw Error("You must pass an plain object to set settings. EG: { }");
    	}
    	// allow the setting of settings in a much easier way
    	// hasOwnProperty is to avoid times where you may have passed an odd function with inherited props
    	for(var setting in settings) if(settings.hasOwnProperty(setting)) {
    		CC.settings[setting] = settings[setting];
    	}
    };
    CC.clearFilter = function() {
    	CC.settings.filter = false;
		if( persist ) {
			root.localStorage.setItem(CC.settings.persistConfig.filter,false);
		}
    };
    CC.setFilter = function(string) {
    	// if not string, don't do it
    	if(typeof string !== "string" && !(string instanceof String)) {
    		throw new Error("Filters must be of type string");
    	}

    	CC.settings.filter = string;

		if( persist ) {
			root.localStorage.setItem(CC.settings.persistConfig.filter,string);
		}
    };

	// we intend to overwrite these methods
	var trace_methods = [
		'error',
		'warn',
		'info',
		'debug',
		'log'
	],
	// these methods will just 'pass through' to the original console or use console.log if it doesn't support them
	pass_methods = [
		'assert',
		'clear',
		'count',
		'dir',
		'dirxml',
		'exception',
		'group',
		'groupCollapsed',
		'groupEnd',
		'markTimeline',
		'profile',
		'profileEnd',
		'table',
		'time',
		'timeEnd',
		'timeStamp',
		'trace',
		'memory',
		'profiles'
	],
	idx = pass_methods.length,
	handleCircularReferences = function() {
		var circularKeys = []; // resetting the brains

		return function(key, value) {
			if( !!key && !!value && ['[object Object]','[object Array]'].indexOf(Object.prototype.toString.call(value)) > -1) {
				// an array or object
				if( circularKeys.indexOf(value) > -1 ){
					// already seen value
					return "<Circular Reference>";
				}
				circularKeys.push(value);
			} else if (!!key && !!value && Object.prototype.toString.call(value) !== '[object String]') {
				return value.toString();
			}
			return value;
		}
	},
	updateHistory = function(msg) {
		var stringify;
		// push to the beginning, not the end
		CC.settings.history.unshift( msg );
		// make sure we aren't running out of memory here
		if(CC.settings.history.length > CC.settings.maxHistory) {
			// drop the most recent off the top
			CC.settings.history.pop();
		}
		if( persist ) {
			root.localStorage.setItem(CC.settings.persistConfig.history,root.JSON.stringify( CC.settings.history, handleCircularReferences(), ""));
		}
	},
	loadPassMethods = function(method){
		CC[method]=function() {
			var args = aps.call(arguments);

			try {
				// if standBy, just ignore anything and output right away
				if(CC.settings.standBy){
					con.firebug ? con[method].apply(root, args) :
						con[method] ? con[method].apply(con,args) :
						con.log.apply(con,args);
					return;
				}

				// when we are in production mode, nothing should go through
				if(CC.settings.environment === "production" ) {
					return;
				}

				// everything past this point is not in production code

				// if no console
				// or debug is false
				// or the filter is on and doesn't match anything
				// return as nothing should go out
				if ( !con || !CC.settings.debug || (CC.settings.filter && args[0].indexOf(CC.settings.filter) < 0  )) {
					return;
				}

				// if a timestamp is needing to be set, push it in
				if(CC.settings.timestamp) {
					args.unshift(new Date().toISOString());
				}

				// push this command into the history
				updateHistory([method].concat( args ));

				// call the command that should be available or log it
				con.firebug ? con[method].apply(root, args) :
					con[method] ? con[method].apply(con,args) :
					con.log.apply(con,args);
			} catch(e) {
				// ignore errors we may throw unless debugging
				if(CC.settings.debug) {
					throw new Error(e);
				}
			}
		};
	},
	loadTraceMethods = function(idx,method){
		CC[method] = function() {
			var args = aps.call(arguments);

			try {
				// if standBy, just ignore anything and output right away
				if(CC.settings.standBy) {
					con.firebug ? con[method].apply(root, args) :
						con[method] ? con[method].apply(con,args) :
						con.log.apply(con,args);
					return;
				}

				// when we are in production mode, only allow errors to go through
				if(method !== 'error' && CC.settings.environment === "production" ) {
					return;
				}

				// everything past this point is not in production code, unless it is an error

				var log_arr,
					error = new Error(),
					stackError = error && error.stack,
					trace, line_trace,identifier="", re = /\//g,
					alwaysShow = ['error','warn'];

				// Sometimes when we try to get the stack trace,
				// things go poorly. We still want to continue on
				// our merry way however. We've noticed this
				// behavior particularly when highcharts is involved
				if (stackError && typeof stackError === 'string') {
					try {
						trace = stackError.split(/\r\n|\r|\n/);
						trace = trace[trace.length-1].split(/\//);
					}catch (ignore){
						trace = ['Failed to retrieve stack trace.'];
					}
				}

				line_trace = trace[trace.length-1].split(/:/);

				if(method!=='debug') {
					args.push(line_trace[0] + " Line "+line_trace[1]);
					identifier = line_trace[0].replace(re,"~")+":"+line_trace[1];
				} else {
					args.push(((new Error() && new Error().stack)?new Error().stack:'').split(/\r\n|\r|\n/));
				}

				// if no console
				// or the method is not an alwaysShow method and
				// 		debug is false
				// 		or the filter is on and doesn't match anything
				// return as nothing should go out
				if ( !con || ( alwaysShow.indexOf(method) < 0 && ( !CC.settings.debug || (CC.settings.filter && args[0].indexOf(CC.settings.filter) < 0  )))) {
					return;
				}

				if(CC.settings.timestamp) {
					args.unshift(new Date().toISOString());
				}

				log_arr = [method].concat( args );
				updateHistory(log_arr);

				// the method must be an error becaue of previous if statement
				if(CC.settings.environment === 'production') {
					CC.settings.notify( log_arr,  identifier);
					return;
				}

				// push to the actual console
				con.firebug ? con[method].apply(root, args) :
					con[method] ? con[method].apply(con,args) :
					con.log.apply(con,args);

			} catch(e){
				// ignore errors we may throw unless debugging
				if(CC.settings.debug) {
					throw new Error(e);
				}}
		};
	};

	// Add CC as the console
	root.console = CC;

	/* passthrough any console methods */
	while(--idx >= 0){
		loadPassMethods(pass_methods[idx]);
	}

	// reuse the vars
	idx = trace_methods.length;

	while(--idx >= 0){
		loadTraceMethods(idx,trace_methods[idx]);
	}

})(this);<|endoftext|>