<commit_before>var chatPanel = document.getElementById("chatPanel");
var avatarBox = document.getElementById("imgAvatar");
var nameField = document.getElementById("ninjaName");
var mentorField = document.getElementById("mentorName");

var firstPhase = document.getElementById("chatFirstPhase");
var secondPhase = document.getElementById("chatSecondPhase");
var thirdPhase = document.getElementById("chatThirdPhase");

var opts = {};
opts.localCamBox = document.getElementById("localCamBox");
opts.remoteCamBox = document.getElementById("remoteCamBox");
opts.screenBox = document.getElementById("localScreenBox");

var firstPhaseButton = document.getElementById("firstPhaseButton");
var firstPhaseText = document.getElementById("firstPhaseText");

var secondPhaseButton = document.getElementById("secondPhaseButton");
var shareButton = document.getElementById("shareButton");
var finishButton = document.getElementById("finishButton");

var tempRoom;

var socket = io();
var webrtc;

/*
	Function to handle the receiving of ice server info.
	This the data packet should be exactly what is returned by xirsys concerning ICE connection details. Hence, all the data will be in the data.d field.
*/

function handleIceServers(data) {
	console.log(data);
	console.log(data.d);
	webrtc = webrtcInit(data.d, opts);
}

function firstPhaseClick() {
	socket.emit('requestHelp', {ninja: getParameterByName('user')});
	$(firstPhaseButton).hide();
	$(firstPhaseText).text('You are waiting in queue to be helped');
}

/*	Function to handle the changing of room.
	The data should include fields defining the name of the room and the name of ninja who will be joining
*/
function handleRoomChange (data) {
	console.log('Changing to room: ' + data.room);
	tempRoom = data.room;
	$(mentorField).text(data.mentor);
	$(firstPhase).hide();
	$(secondPhase).show();
	$(opts.localCamBox).empty();
	$(chatWindow).empty();
	webrtc.startLocalVideo();
}

function shareButtonClick() {

	webrtc.stopScreenShare();
	webrtc.shareScreen(function (err) {
		if (err)
			console.log('Share Screen Error: ',err);
	});
}

function secondPhaseClick() {
	$(firstPhase).hide();
	document.getElementById("localCamBox").childNodes[0].muted = true;
	room = tempRoom;
	webrtc.testReadiness();
	$(secondPhase).hide();
	$(thirdPhase).show();
}

function handleMentorDisconnect (data) {
	webrtc.leaveRoom();
	webrtc.stopLocalVideo();
	webrtc.stopScreenShare();
	$(firstPhase).show();
	$(secondPhase).hide();
	$(thirdPhase).hide();
	$(firstPhaseButton).show();
	$(firstPhaseText).text("To chat with the mentor, click on 'Chat' button");
	alert("The mentor you were working with disconnected");
}

function finishChatClick() {
	$(firstPhase).show();
	$(secondPhase).hide();
	$(thirdPhase).hide();
	$(firstPhaseButton).show();
	$(firstPhaseText).text("To chat with the mentor, click on 'Chat' button");
	webrtc.leaveRoom();
	webrtc.stopLocalVideo();
	webrtc.stopScreenShare();
	socket.emit('leaving', {});
}

socket.on('iceServers',handleIceServers);
firstPhaseButton.onclick = firstPhaseClick;
socket.on('changeRoom', handleRoomChange);
shareButton.onclick = shareButtonClick;
secondPhaseButton.onclick = secondPhaseClick;
socket.on('otherDisconnect', handleMentorDisconnect);
finishButton.onclick = finishChatClick;

$(localCamBox).hide();
$(firstPhase).show();
$(secondPhase).hide();
$(thirdPhase).hide();
$(nameField).text(getParameterByName('user'));
$('#collapseTwo').collapse("hide");
socket.emit('iceRequest', {ninja : getParameterByName('user')});

<commit_msg>Update ninja.js<commit_after>var chatPanel = document.getElementById("chatPanel");
var avatarBox = document.getElementById("imgAvatar");
var nameField = document.getElementById("ninjaName");
var mentorField = document.getElementById("mentorName");

var firstPhase = document.getElementById("chatFirstPhase");
var secondPhase = document.getElementById("chatSecondPhase");
var thirdPhase = document.getElementById("chatThirdPhase");

var opts = {};
opts.localCamBox = document.getElementById("localCamBox");
opts.remoteCamBox = document.getElementById("remoteCamBox");
opts.screenBox = document.getElementById("localScreenBox");

var firstPhaseButton = document.getElementById("firstPhaseButton");
var firstPhaseText = document.getElementById("firstPhaseText");

var secondPhaseButton = document.getElementById("secondPhaseButton");
var shareButton = document.getElementById("shareButton");
var finishButton = document.getElementById("finishButton");

var socket = io();
var webrtc;

/*
	Function to handle the receiving of ice server info.
	This the data packet should be exactly what is returned by xirsys concerning ICE connection details. Hence, all the data will be in the data.d field.
*/
function handleIceServers(data) {
	console.log(data);
	console.log(data.d);
	webrtc = webrtcInit(data.d, opts);
}

function firstPhaseClick() {
	socket.emit('requestHelp', {ninja: getParameterByName('user')});
	$(firstPhaseButton).hide();
	$(firstPhaseText).text('You are waiting in queue to be helped');
}

/*	Function to handle the changing of room.
	The data should include fields defining the name of the room and the name of ninja who will be joining
*/
function handleRoomChange (data) {
	console.log('Changing to room: ' + data.room);
	room = data.room;
	$(mentorField).text(data.mentor);
	$(firstPhase).hide();
	$(secondPhase).show();
	$(opts.localCamBox).empty();
	$(chatWindow).empty();
	webrtc.startLocalVideo();
}

function shareButtonClick() {

	webrtc.stopScreenShare();
	webrtc.shareScreen(function (err) {
		if (err)
			console.log('Share Screen Error: ',err);
	});
}

function secondPhaseClick() {
	$(firstPhase).hide();
	$(secondPhase).hide();
	$(thirdPhase).show();

}

function handleMentorDisconnect (data) {
	webrtc.leaveRoom();
	webrtc.stopLocalVideo();
	webrtc.stopScreenShare();
	$(firstPhase).show();
	$(secondPhase).hide();
	$(thirdPhase).hide();
	$(firstPhaseButton).show();
	$(firstPhaseText).text("To chat with the mentor, click on 'Chat' button");
	alert("The mentor you were working with disconnected");
}

function finishChatClick() {
	$(firstPhase).show();
	$(secondPhase).hide();
	$(thirdPhase).hide();
	$(firstPhaseButton).show();
	$(firstPhaseText).text("To chat with the mentor, click on 'Chat' button");
	webrtc.leaveRoom();
	webrtc.stopLocalVideo();
	webrtc.stopScreenShare();
	socket.emit('leaving', {});
}

socket.on('iceServers',handleIceServers);
firstPhaseButton.onclick = firstPhaseClick;
socket.on('changeRoom', handleRoomChange);
shareButton.onclick = shareButtonClick;
secondPhaseButton.onclick = secondPhaseClick;
socket.on('otherDisconnect', handleMentorDisconnect);
finishButton.onclick = finishChatClick;

$(localCamBox).hide();
$(firstPhase).show();
$(secondPhase).hide();
$(thirdPhase).hide();
$(nameField).text(getParameterByName('user'));
$('#collapseTwo').collapse("hide");
socket.emit('iceRequest', {ninja : getParameterByName('user')});

<|endoftext|>


<commit_before>dojo.provide("dijit._HasDropDown");

dojo.require("dijit._base.place");
dojo.require("dijit._Widget");

dojo.declare("dijit._HasDropDown",
	null,
	{
		// summary:
		//		Mixin for widgets that need drop down ability.

		// _buttonNode: [protected] DomNode
		//		The button/icon/node to click to display the drop down.
		//		Can be set via a dojoAttachPoint assignment.
		//		If missing, then either focusNode or domNode (if focusNode is also missing) will be used.
		_buttonNode: null,

		// _arrowWrapperNode: [protected] DomNode
		//		Will set CSS class dijitUpArrow, dijitDownArrow, dijitRightArrow etc. on this node depending
		//		on where the drop down is set to be positioned.
		//		Can be set via a dojoAttachPoint assignment.
		//		If missing, then _buttonNode will be used.
		_arrowWrapperNode: null,

		// _popupStateNode: [protected] DomNode
		//		The node to set the popupActive class on.
		//		Can be set via a dojoAttachPoint assignment.
		//		If missing, then focusNode or _buttonNode (if focusNode is missing) will be used.
		_popupStateNode: null,

		// _aroundNode: [protected] DomNode
		//		The node to display the popup around.
		//		Can be set via a dojoAttachPoint assignment.
		//		If missing, then domNode will be used.
		_aroundNode: null,

		// dropDown: [protected] Widget
		//		The widget to display as a popup.  This widget *must* be
		//		defined before the startup function is called.
		dropDown: null,

		// autoWidth: [protected] Boolean
		//		Set to true to make the drop down at least as wide as this
		//		widget.  Set to false if the drop down should just be its
		//		default width
		autoWidth: true,

		// forceWidth: [protected] Boolean
		//		Set to true to make the drop down exactly as wide as this
		//		widget.  Overrides autoWidth.
		forceWidth: false,

		// maxHeight: [protected] Integer
		//		The max height for our dropdown.  Set to 0 for no max height.
		//		any dropdown taller than this will have scrollbars
		maxHeight: 0,

		// dropDownPosition: [const] String[]
		//		This variable controls the position of the drop down.
		//		It's an array of strings with the following values:
		//
		//			* before: places drop down to the left of the target node/widget, or to the right in
		//			  the case of RTL scripts like Hebrew and Arabic
		//			* after: places drop down to the right of the target node/widget, or to the left in
		//			  the case of RTL scripts like Hebrew and Arabic
		//			* above: drop down goes above target node
		//			* below: drop down goes below target node
		//
		//		The list is positions is tried, in order, until a position is found where the drop down fits
		//		within the viewport.
		//
		dropDownPosition: ["below","above"],

		_onDropDownMouseDown: function(/*Event*/ e){
			// summary:
			//		Callback when the user mousedown's on the arrow icon

			if(this.disabled || this.readOnly){ return; }

			this._docHandler = this.connect(dojo.doc, "onmouseup", "_onDropDownMouseUp");

			this.toggleDropDown();
		},

		_onDropDownMouseUp: function(/*Event?*/ e){
			// summary:
			//		Callback when the user lifts their mouse after mouse down on the arrow icon.
			//		If the drop is a simple menu and the mouse is over the menu, we execute it, otherwise, we focus our
			//		dropDown node.  If the event is missing, then we are not
			//		a mouseup event.
			//
			//		This is useful for the common mouse movement pattern
			//		with native browser <select> nodes:
			//			1. mouse down on the select node (probably on the arrow)
			//			2. move mouse to a menu item while holding down the mouse button
			//			3. mouse up.  this selects the menu item as though the user had clicked it.
			if(e && this._docHandler){
				this.disconnect(this._docHandler);
			}
			var dropDown = this.dropDown, overMenu = false;

			if(e && this._opened){
				// This code deals with the corner-case when the drop down covers the original widget,
				// because it's so large.  In that case mouse-up shouldn't select a value from the menu.
				// Find out if our target is somewhere in our dropdown widget,
				// but not over our _buttonNode (the clickable node)
				var c = dojo.position(this._buttonNode, true);
				if(!(e.pageX >= c.x && e.pageX <= c.x + c.w) ||
					!(e.pageY >= c.y && e.pageY <= c.y + c.h)){
					var t = e.target;
					while(t && !overMenu){
						if(dojo.hasClass(t, "dijitPopup")){
							overMenu = true;
						}else{
							t = t.parentNode;
						}
					}
					if(overMenu){
						t = e.target;
						if(dropDown.onItemClick){
							var menuItem;
							while(t && !(menuItem = dijit.byNode(t))){
								t = t.parentNode;
							}
							if(menuItem && menuItem.onClick && menuItem.getParent){
								menuItem.getParent().onItemClick(menuItem, e);
							}
						}
						return;
					}
				}
			}
			if(this._opened && dropDown.focus){
				// Focus the dropdown widget - do it on a delay so that we
				// don't steal our own focus.
				window.setTimeout(dojo.hitch(dropDown, "focus"), 1);
			}
		},

		_setupDropdown: function(){
			// summary:
			//		set up nodes and connect our mouse and keypress events
			this._buttonNode = this._buttonNode || this.focusNode || this.domNode;
			this._popupStateNode = this._popupStateNode || this.focusNode || this._buttonNode;
			this._aroundNode = this._aroundNode || this.domNode;
			this.connect(this._buttonNode, "onmousedown", "_onDropDownMouseDown");
			this.connect(this._buttonNode, "onkeydown", "_onDropDownKeydown");
			this.connect(this._buttonNode, "onkeyup", "_onKey");

			// If we have a _setStateClass function (which happens when
			// we are a form widget), then we need to connect our open/close
			// functions to it
			if(this._setStateClass){
				this.connect(this, "openDropDown", "_setStateClass");
				this.connect(this, "closeDropDown", "_setStateClass");
			}

			// Add a class to the "dijitDownArrowButton" type class to _buttonNode so theme can set direction of arrow
			// based on where drop down will normally appear
			var defaultPos = {
					"after" : this.isLeftToRight() ? "Right" : "Left",
					"before" : this.isLeftToRight() ? "Left" : "Right",
					"above" : "Up",
					"below" : "Down",
					"left" : "Left",
					"right" : "Right"
			}[this.dropDownPosition[0]] || this.dropDownPosition[0] || "Down";
			dojo.addClass(this._arrowWrapperNode || this._buttonNode, "dijit" + defaultPos + "ArrowButton");
		},

		postCreate: function(){
			this._setupDropdown();
			this.inherited(arguments);
		},

		destroyDescendants: function(){
			if(this.dropDown){
				// Destroy the drop down, unless it's already been destroyed.  This can happen because
				// the drop down is a direct child of <body> even though it's logically my child.
				if(!this.dropDown._destroyed){
					this.dropDown.destroyRecursive();
				}
				delete this.dropDown;
			}
			this.inherited(arguments);
		},

		_onDropDownKeydown: function(/*Event*/ e){
			if(e.keyCode == dojo.keys.DOWN_ARROW || e.keyCode == dojo.keys.ENTER || e.keyCode == dojo.keys.SPACE){
				e.preventDefault();	// stop IE screen jump
			}
		},

		_onKey: function(/*Event*/ e){
			// summary:
			//		Callback when the user presses a key while focused on the button node

			if(this.disabled || this.readOnly){ return; }
			var d = this.dropDown;
			if(d && this._opened && d.handleKey){
				if(d.handleKey(e) === false){ return; }
			}
			if(d && this._opened && e.keyCode == dojo.keys.ESCAPE){
				this.toggleDropDown();
			}else if(d && !this._opened &&
					(e.keyCode == dojo.keys.DOWN_ARROW || e.keyCode == dojo.keys.ENTER || e.keyCode == dojo.keys.SPACE)){
				this.toggleDropDown();
				if(d.focus){
					setTimeout(dojo.hitch(d, "focus"), 1);
				}
			}
		},

		_onBlur: function(){
			// summary:
			//		Called magically when focus has shifted away from this widget and it's dropdown

			this.closeDropDown();
			// don't focus on button.  the user has explicitly focused on something else.
			this.inherited(arguments);
		},

		isLoaded: function(){
			// summary:
			//		Returns whether or not the dropdown is loaded.  This can
			//		be overridden in order to force a call to loadDropDown().
			// tags:
			//		protected

			return true;
		},

		loadDropDown: function(/* Function */ loadCallback){
			// summary:
			//		Loads the data for the dropdown, and at some point, calls
			//		the given callback
			// tags:
			//		protected

			loadCallback();
		},

		toggleDropDown: function(){
			// summary:
			//		Toggle the drop-down widget; if it is up, close it, if not, open it
			// tags:
			//		protected

			if(this.disabled || this.readOnly){ return; }
			this.focus();
			var dropDown = this.dropDown;
			if(!dropDown){ return; }
			if(!this._opened){
				// If we aren't loaded, load it first so there isn't a flicker
				if(!this.isLoaded()){
					this.loadDropDown(dojo.hitch(this, "openDropDown"));
					return;
				}else{
					this.openDropDown();
				}
			}else{
				this.closeDropDown();
			}
		},

		openDropDown: function(){
			// summary:
			//		Opens the dropdown for this widget - it returns the
			//		return value of dijit.popup.open
			// tags:
			//		protected

			var dropDown = this.dropDown;
			var ddNode = dropDown.domNode;
			var self = this;

			// Prepare our popup's height and honor maxHeight if it exists.

			// TODO: isn't maxHeight dependent on the return value from dijit.popup.open(),
			// ie, dependent on how much space is available (BK)

			if(!this._preparedNode){
				dijit.popup.moveOffScreen(ddNode);
				this._preparedNode = true;
				// Check if we have explicitly set width and height on the dropdown widget dom node
				if(ddNode.style.width){
					this._explicitDDWidth = true;
				}
				if(ddNode.style.height){
					this._explicitDDHeight = true;
				}
			}

			// Code for resizing dropdown (height limitation, or increasing width to match my width)
			if(this.maxHeight || this.forceWidth || this.autoWidth){
				var myStyle = {
					display: "",
					visibility: "hidden"
				};
				if(!this._explicitDDWidth){
					myStyle.width = "";
				}
				if(!this._explicitDDHeight){
					myStyle.height = "";
				}
				dojo.style(ddNode, myStyle);

				// Get size of drop down, and determine if vertical scroll bar needed
				var mb = dojo.marginBox(ddNode);
				var overHeight = (this.maxHeight && mb.h > this.maxHeight);
				dojo.style(ddNode, {
					overflowx: "hidden",
					overflowY: overHeight ? "auto" : "hidden"
				});
				if(overHeight){
					mb.h = this.maxHeight;
					if("w" in mb){
						mb.w += 16;	// room for vertical scrollbar
					}
				}else{
					delete mb.h;
				}
				delete mb.t;
				delete mb.l;

				// Adjust dropdown width to match or be larger than my width
				if(this.forceWidth){
					mb.w = this.domNode.offsetWidth;
				}else if(this.autoWidth){
					mb.w = Math.max(mb.w, this.domNode.offsetWidth);
				}else{
					delete mb.w;
				}

				// And finally, resize the dropdown to calculated height and width
				if(dojo.isFunction(dropDown.resize)){
					dropDown.resize(mb);
				}else{
					dojo.marginBox(ddNode, mb);
				}
			}

			var retVal = dijit.popup.open({
				parent: this,
				popup: dropDown,
				around: this._aroundNode,
				orient: dijit.getPopupAroundAlignment((this.dropDownPosition && this.dropDownPosition.length) ? this.dropDownPosition : ["below"],this.isLeftToRight()),
				onExecute: function(){
					self.closeDropDown(true);
				},
				onCancel: function(){
					self.closeDropDown(true);
				},
				onClose: function(){
					dojo.attr(self._popupStateNode, "popupActive", false);
					dojo.removeClass(self._popupStateNode, "dijitHasDropDownOpen");
					self._opened = false;
					self.state = "";
				}
			});
			dojo.attr(this._popupStateNode, "popupActive", "true");
			dojo.addClass(self._popupStateNode, "dijitHasDropDownOpen");
			this._opened=true;
			this.state="Opened";
			// TODO: set this.checked and call setStateClass(), to affect button look while drop down is shown
			return retVal;
		},

		closeDropDown: function(/*Boolean*/ focus){
			// summary:
			//		Closes the drop down on this widget
			// tags:
			//		protected

			if(this._opened){
				dijit.popup.close(this.dropDown);
				if(focus){ this.focus(); }
				this._opened = false;
				this.state = "";
			}
		}

	}
);
<commit_msg>[22001] shouldn't have removed the stopEvent() call on click, refs #11040<commit_after>dojo.provide("dijit._HasDropDown");

dojo.require("dijit._base.place");
dojo.require("dijit._Widget");

dojo.declare("dijit._HasDropDown",
	null,
	{
		// summary:
		//		Mixin for widgets that need drop down ability.

		// _buttonNode: [protected] DomNode
		//		The button/icon/node to click to display the drop down.
		//		Can be set via a dojoAttachPoint assignment.
		//		If missing, then either focusNode or domNode (if focusNode is also missing) will be used.
		_buttonNode: null,

		// _arrowWrapperNode: [protected] DomNode
		//		Will set CSS class dijitUpArrow, dijitDownArrow, dijitRightArrow etc. on this node depending
		//		on where the drop down is set to be positioned.
		//		Can be set via a dojoAttachPoint assignment.
		//		If missing, then _buttonNode will be used.
		_arrowWrapperNode: null,

		// _popupStateNode: [protected] DomNode
		//		The node to set the popupActive class on.
		//		Can be set via a dojoAttachPoint assignment.
		//		If missing, then focusNode or _buttonNode (if focusNode is missing) will be used.
		_popupStateNode: null,

		// _aroundNode: [protected] DomNode
		//		The node to display the popup around.
		//		Can be set via a dojoAttachPoint assignment.
		//		If missing, then domNode will be used.
		_aroundNode: null,

		// dropDown: [protected] Widget
		//		The widget to display as a popup.  This widget *must* be
		//		defined before the startup function is called.
		dropDown: null,

		// autoWidth: [protected] Boolean
		//		Set to true to make the drop down at least as wide as this
		//		widget.  Set to false if the drop down should just be its
		//		default width
		autoWidth: true,

		// forceWidth: [protected] Boolean
		//		Set to true to make the drop down exactly as wide as this
		//		widget.  Overrides autoWidth.
		forceWidth: false,

		// maxHeight: [protected] Integer
		//		The max height for our dropdown.  Set to 0 for no max height.
		//		any dropdown taller than this will have scrollbars
		maxHeight: 0,

		// dropDownPosition: [const] String[]
		//		This variable controls the position of the drop down.
		//		It's an array of strings with the following values:
		//
		//			* before: places drop down to the left of the target node/widget, or to the right in
		//			  the case of RTL scripts like Hebrew and Arabic
		//			* after: places drop down to the right of the target node/widget, or to the left in
		//			  the case of RTL scripts like Hebrew and Arabic
		//			* above: drop down goes above target node
		//			* below: drop down goes below target node
		//
		//		The list is positions is tried, in order, until a position is found where the drop down fits
		//		within the viewport.
		//
		dropDownPosition: ["below","above"],

		// _stopClickEvents: Boolean
		//		When set to false, the click events will not be stopped, in
		//		case you want to use them in your subwidget
		_stopClickEvents: true,

		_onDropDownMouseDown: function(/*Event*/ e){
			// summary:
			//		Callback when the user mousedown's on the arrow icon

			if(this.disabled || this.readOnly){ return; }

			this._docHandler = this.connect(dojo.doc, "onmouseup", "_onDropDownMouseUp");

			this.toggleDropDown();
		},

		_onDropDownMouseUp: function(/*Event?*/ e){
			// summary:
			//		Callback when the user lifts their mouse after mouse down on the arrow icon.
			//		If the drop is a simple menu and the mouse is over the menu, we execute it, otherwise, we focus our
			//		dropDown node.  If the event is missing, then we are not
			//		a mouseup event.
			//
			//		This is useful for the common mouse movement pattern
			//		with native browser <select> nodes:
			//			1. mouse down on the select node (probably on the arrow)
			//			2. move mouse to a menu item while holding down the mouse button
			//			3. mouse up.  this selects the menu item as though the user had clicked it.
			if(e && this._docHandler){
				this.disconnect(this._docHandler);
			}
			var dropDown = this.dropDown, overMenu = false;

			if(e && this._opened){
				// This code deals with the corner-case when the drop down covers the original widget,
				// because it's so large.  In that case mouse-up shouldn't select a value from the menu.
				// Find out if our target is somewhere in our dropdown widget,
				// but not over our _buttonNode (the clickable node)
				var c = dojo.position(this._buttonNode, true);
				if(!(e.pageX >= c.x && e.pageX <= c.x + c.w) ||
					!(e.pageY >= c.y && e.pageY <= c.y + c.h)){
					var t = e.target;
					while(t && !overMenu){
						if(dojo.hasClass(t, "dijitPopup")){
							overMenu = true;
						}else{
							t = t.parentNode;
						}
					}
					if(overMenu){
						t = e.target;
						if(dropDown.onItemClick){
							var menuItem;
							while(t && !(menuItem = dijit.byNode(t))){
								t = t.parentNode;
							}
							if(menuItem && menuItem.onClick && menuItem.getParent){
								menuItem.getParent().onItemClick(menuItem, e);
							}
						}
						return;
					}
				}
			}
			if(this._opened && dropDown.focus){
				// Focus the dropdown widget - do it on a delay so that we
				// don't steal our own focus.
				window.setTimeout(dojo.hitch(dropDown, "focus"), 1);
			}
		},

		_onDropDownClick: function(/*Event*/ e){
			// the drop down was already opened on mousedown/keydown; just need to call stopEvent()
			if(this._stopClickEvents){
				dojo.stopEvent(e);
			}
		},

		_setupDropdown: function(){
			// summary:
			//		set up nodes and connect our mouse and keypress events
			this._buttonNode = this._buttonNode || this.focusNode || this.domNode;
			this._popupStateNode = this._popupStateNode || this.focusNode || this._buttonNode;
			this._aroundNode = this._aroundNode || this.domNode;
			this.connect(this._buttonNode, "onmousedown", "_onDropDownMouseDown");
			this.connect(this._buttonNode, "onclick", "_onDropDownClick");
			this.connect(this._buttonNode, "onkeydown", "_onDropDownKeydown");
			this.connect(this._buttonNode, "onkeyup", "_onKey");

			// If we have a _setStateClass function (which happens when
			// we are a form widget), then we need to connect our open/close
			// functions to it
			if(this._setStateClass){
				this.connect(this, "openDropDown", "_setStateClass");
				this.connect(this, "closeDropDown", "_setStateClass");
			}

			// Add a class to the "dijitDownArrowButton" type class to _buttonNode so theme can set direction of arrow
			// based on where drop down will normally appear
			var defaultPos = {
					"after" : this.isLeftToRight() ? "Right" : "Left",
					"before" : this.isLeftToRight() ? "Left" : "Right",
					"above" : "Up",
					"below" : "Down",
					"left" : "Left",
					"right" : "Right"
			}[this.dropDownPosition[0]] || this.dropDownPosition[0] || "Down";
			dojo.addClass(this._arrowWrapperNode || this._buttonNode, "dijit" + defaultPos + "ArrowButton");
		},

		postCreate: function(){
			this._setupDropdown();
			this.inherited(arguments);
		},

		destroyDescendants: function(){
			if(this.dropDown){
				// Destroy the drop down, unless it's already been destroyed.  This can happen because
				// the drop down is a direct child of <body> even though it's logically my child.
				if(!this.dropDown._destroyed){
					this.dropDown.destroyRecursive();
				}
				delete this.dropDown;
			}
			this.inherited(arguments);
		},

		_onDropDownKeydown: function(/*Event*/ e){
			if(e.keyCode == dojo.keys.DOWN_ARROW || e.keyCode == dojo.keys.ENTER || e.keyCode == dojo.keys.SPACE){
				e.preventDefault();	// stop IE screen jump
			}
		},

		_onKey: function(/*Event*/ e){
			// summary:
			//		Callback when the user presses a key while focused on the button node

			if(this.disabled || this.readOnly){ return; }
			var d = this.dropDown;
			if(d && this._opened && d.handleKey){
				if(d.handleKey(e) === false){ return; }
			}
			if(d && this._opened && e.keyCode == dojo.keys.ESCAPE){
				this.toggleDropDown();
			}else if(d && !this._opened &&
					(e.keyCode == dojo.keys.DOWN_ARROW || e.keyCode == dojo.keys.ENTER || e.keyCode == dojo.keys.SPACE)){
				this.toggleDropDown();
				if(d.focus){
					setTimeout(dojo.hitch(d, "focus"), 1);
				}
			}
		},

		_onBlur: function(){
			// summary:
			//		Called magically when focus has shifted away from this widget and it's dropdown

			this.closeDropDown();
			// don't focus on button.  the user has explicitly focused on something else.
			this.inherited(arguments);
		},

		isLoaded: function(){
			// summary:
			//		Returns whether or not the dropdown is loaded.  This can
			//		be overridden in order to force a call to loadDropDown().
			// tags:
			//		protected

			return true;
		},

		loadDropDown: function(/* Function */ loadCallback){
			// summary:
			//		Loads the data for the dropdown, and at some point, calls
			//		the given callback
			// tags:
			//		protected

			loadCallback();
		},

		toggleDropDown: function(){
			// summary:
			//		Toggle the drop-down widget; if it is up, close it, if not, open it
			// tags:
			//		protected

			if(this.disabled || this.readOnly){ return; }
			this.focus();
			var dropDown = this.dropDown;
			if(!dropDown){ return; }
			if(!this._opened){
				// If we aren't loaded, load it first so there isn't a flicker
				if(!this.isLoaded()){
					this.loadDropDown(dojo.hitch(this, "openDropDown"));
					return;
				}else{
					this.openDropDown();
				}
			}else{
				this.closeDropDown();
			}
		},

		openDropDown: function(){
			// summary:
			//		Opens the dropdown for this widget - it returns the
			//		return value of dijit.popup.open
			// tags:
			//		protected

			var dropDown = this.dropDown;
			var ddNode = dropDown.domNode;
			var self = this;

			// Prepare our popup's height and honor maxHeight if it exists.

			// TODO: isn't maxHeight dependent on the return value from dijit.popup.open(),
			// ie, dependent on how much space is available (BK)

			if(!this._preparedNode){
				dijit.popup.moveOffScreen(ddNode);
				this._preparedNode = true;
				// Check if we have explicitly set width and height on the dropdown widget dom node
				if(ddNode.style.width){
					this._explicitDDWidth = true;
				}
				if(ddNode.style.height){
					this._explicitDDHeight = true;
				}
			}

			// Code for resizing dropdown (height limitation, or increasing width to match my width)
			if(this.maxHeight || this.forceWidth || this.autoWidth){
				var myStyle = {
					display: "",
					visibility: "hidden"
				};
				if(!this._explicitDDWidth){
					myStyle.width = "";
				}
				if(!this._explicitDDHeight){
					myStyle.height = "";
				}
				dojo.style(ddNode, myStyle);

				// Get size of drop down, and determine if vertical scroll bar needed
				var mb = dojo.marginBox(ddNode);
				var overHeight = (this.maxHeight && mb.h > this.maxHeight);
				dojo.style(ddNode, {
					overflowx: "hidden",
					overflowY: overHeight ? "auto" : "hidden"
				});
				if(overHeight){
					mb.h = this.maxHeight;
					if("w" in mb){
						mb.w += 16;	// room for vertical scrollbar
					}
				}else{
					delete mb.h;
				}
				delete mb.t;
				delete mb.l;

				// Adjust dropdown width to match or be larger than my width
				if(this.forceWidth){
					mb.w = this.domNode.offsetWidth;
				}else if(this.autoWidth){
					mb.w = Math.max(mb.w, this.domNode.offsetWidth);
				}else{
					delete mb.w;
				}

				// And finally, resize the dropdown to calculated height and width
				if(dojo.isFunction(dropDown.resize)){
					dropDown.resize(mb);
				}else{
					dojo.marginBox(ddNode, mb);
				}
			}

			var retVal = dijit.popup.open({
				parent: this,
				popup: dropDown,
				around: this._aroundNode,
				orient: dijit.getPopupAroundAlignment((this.dropDownPosition && this.dropDownPosition.length) ? this.dropDownPosition : ["below"],this.isLeftToRight()),
				onExecute: function(){
					self.closeDropDown(true);
				},
				onCancel: function(){
					self.closeDropDown(true);
				},
				onClose: function(){
					dojo.attr(self._popupStateNode, "popupActive", false);
					dojo.removeClass(self._popupStateNode, "dijitHasDropDownOpen");
					self._opened = false;
					self.state = "";
				}
			});
			dojo.attr(this._popupStateNode, "popupActive", "true");
			dojo.addClass(self._popupStateNode, "dijitHasDropDownOpen");
			this._opened=true;
			this.state="Opened";
			// TODO: set this.checked and call setStateClass(), to affect button look while drop down is shown
			return retVal;
		},

		closeDropDown: function(/*Boolean*/ focus){
			// summary:
			//		Closes the drop down on this widget
			// tags:
			//		protected

			if(this._opened){
				dijit.popup.close(this.dropDown);
				if(focus){ this.focus(); }
				this._opened = false;
				this.state = "";
			}
		}

	}
);
<|endoftext|>


<commit_before>dojo.provide("dijit._base.window");

dijit.getDocumentWindow = function(doc){
	//	summary
	// 	Get window object associated with document doc

	// With Safari, there is not way to retrieve the window from the document, so we must fix it.
	if(dojo.isSafari && !doc._parentWindow){
		/*
			This is a Safari specific function that fix the reference to the parent
			window from the document object.
		*/
		var fix=function(win){
			win.document._parentWindow=win;
			for(var i=0; i<win.frames.length; i++){
				fix(win.frames[i]);
			}
		}
		fix(window.top);
	}

	//In some IE versions (at least 6.0), document.parentWindow does not return a
	//reference to the real window object (maybe a copy), so we must fix it as well
	//We use IE specific execScript to attach the real window reference to
	//document._parentWindow for later use
	if(dojo.isIE && window !== document.parentWindow && !doc._parentWindow){
		/*
		In IE 6, only the variable "window" can be used to connect events (others
		may be only copies).
		*/
		doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
		//to prevent memory leak, unset it after use
		//another possibility is to add an onUnload handler which seems overkill to me (liucougar)
		var win = doc._parentWindow;
		doc._parentWindow = null;
		return win;	//	Window
	}

	return doc._parentWindow || doc.parentWindow || doc.defaultView;	//	Window
}
<commit_msg>Fixes #7498: dijit.getDocumentWindow() throws exception in Safari The safari-only code block is apparently no longer needed in safari 3, and it causes issues in some circumstances, so removing it.<commit_after>dojo.provide("dijit._base.window");

dijit.getDocumentWindow = function(doc){
	// summary:
	// 		Get window object associated with document doc

	// In some IE versions (at least 6.0), document.parentWindow does not return a
	// reference to the real window object (maybe a copy), so we must fix it as well
	// We use IE specific execScript to attach the real window reference to
	// document._parentWindow for later use
	if(dojo.isIE && window !== document.parentWindow && !doc._parentWindow){
		/*
		In IE 6, only the variable "window" can be used to connect events (others
		may be only copies).
		*/
		doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
		//to prevent memory leak, unset it after use
		//another possibility is to add an onUnload handler which seems overkill to me (liucougar)
		var win = doc._parentWindow;
		doc._parentWindow = null;
		return win;	//	Window
	}

	return doc._parentWindow || doc.parentWindow || doc.defaultView;	//	Window
}
<|endoftext|>


<commit_before>/* written in ECMAscript 6 */
/**
 * @fileoverview WAVE audio granular synthesis engine
 * @author Norbert.Schnell@ircam.fr, Victor.Saiz@ircam.fr, Karim.Barkati@ircam.fr
 */
"use strict";

var audioContext = require("audio-context");
var TimeEngine = require("time-engine");

/**
 * @class GranularEngine
 */
class GranularEngine extends TimeEngine {
  /**
   * @constructor
   * @param {AudioBuffer} buffer initial audio buffer for granular synthesis
   *
   * The engine implements the "scheduled" interface.
   * The grain position (grain onset or center time in the audio buffer) is optionally
   * determined by the engine's currentPosition attribute.
   */
  constructor(buffer = null) {
    super();

    /**
     * Audio buffer
     * @type {AudioBuffer}
     */
    this.buffer = buffer;

    /**
     * Absolute grain period in sec
     * @type {Number}
     */
    this.periodAbs = 0.01;

    /**
     * Grain period relative to absolute duration
     * @type {Number}
     */
    this.periodRel = 0;

    /**
     * Amout of random grain period variation relative to grain period
     * @type {Number}
     */
    this.periodVar = 0;

    /**
     * Grain position (onset time in audio buffer) in sec
     * @type {Number}
     */
    this.position = 0;

    /**
     * Amout of random grain position variation in sec
     * @type {Number}
     */
    this.positionVar = 0.003;

    /**
     * Absolute grain duration in sec
     * @type {Number}
     */
    this.durationAbs = 0.1; // absolute grain duration

    /**
     * Grain duration relative to grain period (overlap)
     * @type {Number}
     */
    this.durationRel = 0;

    /**
     * Absolute attack time in sec
     * @type {Number}
     */
    this.attackAbs = 0;

    /**
     * Attack time relative to grain duration
     * @type {Number}
     */
    this.attackRel = 0.5;

    /**
     * Absolute release time in sec
     * @type {Number}
     */
    this.releaseAbs = 0;

    /**
     * Release time relative to grain duration
     * @type {Number}
     */
    this.releaseRel = 0.5;

    /**
     * Grain resampling in cent
     * @type {Number}
     */
    this.resampling = 0;

    /**
     * Amout of random resampling variation in cent
     * @type {Number}
     */
    this.resamplingVar = 0;

    /**
     * Whether the grain position refers to the center of the grain (or the beginning)
     * @type {Bool}
     */
    this.centered = true;

    /**
     * Whether the audio buffer and grain position are considered as cyclic
     * @type {Bool}
     */
    this.cyclic = false;

    this.outputNode = this.__gainNode = audioContext.createGain();
  }

  get bufferDuration() {
    var bufferDuration = this.buffer.duration;

    if (this.buffer.wrapAroundExtention)
      bufferDuration -= this.buffer.wrapAroundExtention;

    return bufferDuration;
  }

  // TimeEngine method (scheduled interface)
  advanceTime(time) {
    return time + this.trigger(time);
  }

  get playbackLength() {
    return this.bufferDuration;
  }

  /**
   * Set gain
   * @param {Number} value linear gain factor
   */
  set gain(value) {
    this.__gainNode.gain.value = value;
  }

  /**
   * Get gain
   * @return {Number} current gain
   */
  get gain() {
    return this.__gainNode.gain.value;
  }

  /**
   * Trigger a grain
   * @param {Number} time grain synthesis audio time
   * @return {Number} period to next grain
   *
   * This function can be called at any time (whether the engine is scheduled or not)
   * to generate a single grain according to the current grain parameters.
   */
  trigger(time) {
    var grainTime = time || audioContext.currentTime;
    var grainPeriod = this.periodAbs;
    var grainPosition = this.position + this.currentPosition;
    var grainDuration = this.durationAbs;

    if (this.buffer) {
      var resamplingRate = 1.0;

      // calculate resampling
      if (this.resampling !== 0 || this.resamplingVar > 0) {
        var randomResampling = (Math.random() - 0.5) * 2.0 * this.resamplingVar;
        resamplingRate = Math.pow(2.0, (this.resampling + randomResampling) / 1200.0);
      }

      grainPeriod += this.periodRel * grainDuration;
      grainDuration += this.durationRel * grainPeriod;

      // grain period randon variation
      if (this.periodVar > 0.0)
        grainPeriod += 2.0 * (Math.random() - 0.5) * this.periodVar * grainPeriod;

      // center grain
      if (this.centered)
        grainPosition -= 0.5 * grainDuration;

      // randomize grain position
      if (this.positionVar > 0)
        grainPosition += (2.0 * Math.random() - 1) * this.positionVar;

      var bufferDuration = this.bufferDuration;

      // wrap or clip grain position and duration into buffer duration
      if (grainPosition < 0 || grainPosition >= bufferDuration) {
        if (this.cyclic) {
          var cycles = grainPosition / bufferDuration;
          grainPosition = (cycles - Math.floor(cycles)) * bufferDuration;

          if (grainPosition + grainDuration > this.buffer.duration)
            grainDuration = this.buffer.duration - grainPosition;
        } else {
          if (grainPosition < 0) {
            grainTime -= grainPosition;
            grainDuration += grainPosition;
            grainPosition = 0;
          }

          if (grainPosition + grainDuration > bufferDuration)
            grainDuration = bufferDuration - grainPosition;
        }
      }

      // make grain
      if (this.gain > 0 && grainDuration >= 0.001) {
        // make grain envelope
        var envelopeNode = audioContext.createGain();
        var attack = this.attackAbs + this.attackRel * grainDuration;
        var release = this.releaseAbs + this.releaseRel * grainDuration;

        if (attack + release > grainDuration) {
          var factor = grainDuration / (attack + release);
          attack *= factor;
          release *= factor;
        }

        var attackEndTime = grainTime + attack;
        var grainEndTime = grainTime + grainDuration;
        var releaseStartTime = grainEndTime - release;

        envelopeNode.gain.setValueAtTime(0.0, grainTime);
        envelopeNode.gain.linearRampToValueAtTime(1.0, attackEndTime);

        if (releaseStartTime > attackEndTime)
          envelopeNode.gain.setValueAtTime(1.0, releaseStartTime);

        envelopeNode.gain.linearRampToValueAtTime(0.0, grainEndTime);
        envelopeNode.connect(this.__gainNode);

        // make source
        var source = audioContext.createBufferSource();

        source.buffer = this.buffer;
        source.playbackRate.value = resamplingRate;
        source.connect(envelopeNode);
        envelopeNode.connect(this.__gainNode);

        source.start(grainTime, grainPosition);
        source.stop(grainTime + grainDuration / resamplingRate);
      }
    }

    return grainPeriod;
  }
}

module.exports = GranularEngine;<commit_msg> - overrode "this.position"<commit_after>/* written in ECMAscript 6 */
/**
 * @fileoverview WAVE audio granular synthesis engine
 * @author Norbert.Schnell@ircam.fr, Victor.Saiz@ircam.fr, Karim.Barkati@ircam.fr
 */
"use strict";

var audioContext = require("audio-context");
var TimeEngine = require("time-engine");

/**
 * @class GranularEngine
 */
class GranularEngine extends TimeEngine {
  /**
   * @constructor
   * @param {AudioBuffer} buffer initial audio buffer for granular synthesis
   *
   * The engine implements the "scheduled" interface.
   * The grain position (grain onset or center time in the audio buffer) is optionally
   * determined by the engine's currentPosition attribute.
   */
  constructor(buffer = null) {
    super();

    /**
     * Audio buffer
     * @type {AudioBuffer}
     */
    this.buffer = buffer;

    /**
     * Absolute grain period in sec
     * @type {Number}
     */
    this.periodAbs = 0.01;

    /**
     * Grain period relative to absolute duration
     * @type {Number}
     */
    this.periodRel = 0;

    /**
     * Amout of random grain period variation relative to grain period
     * @type {Number}
     */
    this.periodVar = 0;

    /**
     * Grain position (onset time in audio buffer) in sec
     * @type {Number}
     */
    this.position = 0;

    /**
     * Amout of random grain position variation in sec
     * @type {Number}
     */
    this.positionVar = 0.003;

    /**
     * Absolute grain duration in sec
     * @type {Number}
     */
    this.durationAbs = 0.1; // absolute grain duration

    /**
     * Grain duration relative to grain period (overlap)
     * @type {Number}
     */
    this.durationRel = 0;

    /**
     * Absolute attack time in sec
     * @type {Number}
     */
    this.attackAbs = 0;

    /**
     * Attack time relative to grain duration
     * @type {Number}
     */
    this.attackRel = 0.5;

    /**
     * Absolute release time in sec
     * @type {Number}
     */
    this.releaseAbs = 0;

    /**
     * Release time relative to grain duration
     * @type {Number}
     */
    this.releaseRel = 0.5;

    /**
     * Grain resampling in cent
     * @type {Number}
     */
    this.resampling = 0;

    /**
     * Amout of random resampling variation in cent
     * @type {Number}
     */
    this.resamplingVar = 0;

    /**
     * Whether the grain position refers to the center of the grain (or the beginning)
     * @type {Bool}
     */
    this.centered = true;

    /**
     * Whether the audio buffer and grain position are considered as cyclic
     * @type {Bool}
     */
    this.cyclic = false;

    this.outputNode = this.__gainNode = audioContext.createGain();
  }

  get bufferDuration() {
    var bufferDuration = this.buffer.duration;

    if (this.buffer.wrapAroundExtention)
      bufferDuration -= this.buffer.wrapAroundExtention;

    return bufferDuration;
  }

  // TimeEngine attribute
  get currentPosition() {
    return this.position;
  }

  // TimeEngine method (scheduled interface)
  advanceTime(time) {
    return time + this.trigger(time);
  }

  get playbackLength() {
    return this.bufferDuration;
  }

  /**
   * Set gain
   * @param {Number} value linear gain factor
   */
  set gain(value) {
    this.__gainNode.gain.value = value;
  }

  /**
   * Get gain
   * @return {Number} current gain
   */
  get gain() {
    return this.__gainNode.gain.value;
  }

  /**
   * Trigger a grain
   * @param {Number} time grain synthesis audio time
   * @return {Number} period to next grain
   *
   * This function can be called at any time (whether the engine is scheduled or not)
   * to generate a single grain according to the current grain parameters.
   */
  trigger(time) {
    var grainTime = time || audioContext.currentTime;
    var grainPeriod = this.periodAbs;
    var grainPosition = this.currentPosition;
    var grainDuration = this.durationAbs;

    if (this.buffer) {
      var resamplingRate = 1.0;

      // calculate resampling
      if (this.resampling !== 0 || this.resamplingVar > 0) {
        var randomResampling = (Math.random() - 0.5) * 2.0 * this.resamplingVar;
        resamplingRate = Math.pow(2.0, (this.resampling + randomResampling) / 1200.0);
      }

      grainPeriod += this.periodRel * grainDuration;
      grainDuration += this.durationRel * grainPeriod;

      // grain period randon variation
      if (this.periodVar > 0.0)
        grainPeriod += 2.0 * (Math.random() - 0.5) * this.periodVar * grainPeriod;

      // center grain
      if (this.centered)
        grainPosition -= 0.5 * grainDuration;

      // randomize grain position
      if (this.positionVar > 0)
        grainPosition += (2.0 * Math.random() - 1) * this.positionVar;

      var bufferDuration = this.bufferDuration;

      // wrap or clip grain position and duration into buffer duration
      if (grainPosition < 0 || grainPosition >= bufferDuration) {
        if (this.cyclic) {
          var cycles = grainPosition / bufferDuration;
          grainPosition = (cycles - Math.floor(cycles)) * bufferDuration;

          if (grainPosition + grainDuration > this.buffer.duration)
            grainDuration = this.buffer.duration - grainPosition;
        } else {
          if (grainPosition < 0) {
            grainTime -= grainPosition;
            grainDuration += grainPosition;
            grainPosition = 0;
          }

          if (grainPosition + grainDuration > bufferDuration)
            grainDuration = bufferDuration - grainPosition;
        }
      }

      // make grain
      if (this.gain > 0 && grainDuration >= 0.001) {
        // make grain envelope
        var envelopeNode = audioContext.createGain();
        var attack = this.attackAbs + this.attackRel * grainDuration;
        var release = this.releaseAbs + this.releaseRel * grainDuration;

        if (attack + release > grainDuration) {
          var factor = grainDuration / (attack + release);
          attack *= factor;
          release *= factor;
        }

        var attackEndTime = grainTime + attack;
        var grainEndTime = grainTime + grainDuration;
        var releaseStartTime = grainEndTime - release;

        envelopeNode.gain.setValueAtTime(0.0, grainTime);
        envelopeNode.gain.linearRampToValueAtTime(1.0, attackEndTime);

        if (releaseStartTime > attackEndTime)
          envelopeNode.gain.setValueAtTime(1.0, releaseStartTime);

        envelopeNode.gain.linearRampToValueAtTime(0.0, grainEndTime);
        envelopeNode.connect(this.__gainNode);

        // make source
        var source = audioContext.createBufferSource();

        source.buffer = this.buffer;
        source.playbackRate.value = resamplingRate;
        source.connect(envelopeNode);
        envelopeNode.connect(this.__gainNode);

        source.start(grainTime, grainPosition);
        source.stop(grainTime + grainDuration / resamplingRate);
      }
    }

    return grainPeriod;
  }
}

module.exports = GranularEngine;<|endoftext|>


<commit_before>'use strict';

var shell = require('shelljs');
var fs = require('fs');
var zlib = require('zlib');
var util = require('../util');
var regexDupLines = /^(.*)(\r?\n\1)+$/gm;
var regexKey = /(https?:\/\/|:)+(?=[^:]*$)[a-z0-9]+(@)/gmi;
var regexHost = /^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i;

/**
 * When a commit message contains "release v" followed by a version number
 * (major.minor.patch) a tagged release will be issued
 *
 * @param grunt
 *            the grunt instance
 */
module.exports = function(grunt) {

	var commit = null;

	grunt.registerTask('release',
			'Release bundle using commit message (if present)', function() {
				var options = this.options({
					src : process.cwd(),
					commitMessage : '',
					destBranch : 'gh-pages',
					destDir : 'dist',
					chgLog : 'HISTORY.md',
					authors : 'AUTHORS.md',
					distAsset : true
				});
				release.call(this, options);
			});

	/**
	 * Checks for release commit message and performs release
	 *
	 * @param options
	 *            the grunt options
	 */
	function release(options) {
		var chgLogRtn = '';
		var authorsRtn = '';

		// Capture commit message
		commit = util.getCommit(grunt, options.commitMessage);
		grunt.log.writeln('Commit message: ' + commit.message);
		if (!commit.version) {
			return;
		}

		// TODO : verify release version is less than last release version
		var lastVerTag = runCmd('git describe --abbrev=0 --tags');
		grunt.log.writeln('Preparing release: ' + commit.version
				+ ' (last release: ' + lastVerTag + ')');
		var relMsg = commit.message + ' ' + util.skipRef('ci');

		// Generate change log for release using all messages since last
		// tag/release
		var chgLogPath = options.destDir + '/' + options.chgLog;
		chgLogRtn = runCmd('git --no-pager log ' + lastVerTag
				+ '..HEAD --pretty=format:"  * %s" > ' + chgLogPath, null,
				false, true, chgLogPath);

		// Generate list of authors/contributors since last tag/release
		var authorsPath = options.destDir + '/' + options.authors;
		authorsRtn = runCmd('git log --all --format="%aN <%aE>" | sort -u > '
				+ authorsPath, null, true, false, authorsPath);

		// Setup
		var link = '${GH_TOKEN}@github.com/' + commit.slug + '.git';
		runCmd('git config --global user.email "travis@travis-ci.org"');
		runCmd('git config --global user.name "travis"');
		runCmd('git remote rm origin');
		runCmd('git remote add origin https://' + commit.username + ':' + link);
		runCmd('git checkout master');

		// Commit changes to master
		runCmd('git add --force ' + options.destDir);
		runCmd('git commit -m "' + relMsg + '"');
		// runCmd('git push -f origin master');

		// Create distribution assets
		var distAsset = commit.reponame + '-' + commit.version + '-dist.zip';
		runCmd('git archive -v -o ' + distAsset + ' --format=zip master '
				+ options.destDir);

		// Tag release
		runCmd('git tag -f -a ' + commit.versionTag + ' -m "' + chgLogRtn + '"');
		runCmd('git push -f origin ' + commit.versionTag);
		grunt.log.writeln('Released: ' + commit.version + ' in '
				+ options.destDir);

		// Distribute archive asset for tagged release
		var done = this.async();
		uploadDistAsset(distAsset, commit, options, function(json, e) {
			if (e) {
				grunt.log.error(grunt.util.error('Failed to upload asset '
						+ distAsset, e));
			} else if (cf.state != 'uploaded') {
				e = grunt.util.error('Asset upload failed with state: '
						+ cf.state);
				grunt.log.error(e);
			} else {
				grunt.log.writeln('Distributed/' + cf.state + ' ' + distAsset
						+ ' asset');
			}
			done(e);
		});

		// Publish site
		/*
		 * runCmd('cd ..'); runCmd('git clone --quiet --branch=' +
		 * options.destBranch + ' https://' + link + ' ' + options.destBranch + ' >
		 * /dev/null'); runCmd('cd ' + options.destBranch); runCmd('git ls-files |
		 * xargs rm'); // remove all tracked files runCmd('git commit -m "' +
		 * relMsg + '"');
		 *
		 * runCmd('cp -a ../' + commit.reponame + '/' + options.destBranch + '/*
		 * .'); // runCmd('git checkout master -- ' + options.destDir);
		 * runCmd('git add -A'); runCmd('git commit -m "' + relMsg + '"');
		 * runCmd('git push -f origin ' + options.destBranch + ' > /dev/null');
		 */
	}

	/**
	 * Executes a shell command
	 *
	 * @param cmd
	 *            the command string to execute
	 * @param wpath
	 *            the optional path/file to write the results to
	 * @param nofail
	 *            true to prevent throwing an error when the command fails to
	 *            execute
	 * @param shortlog
	 *            true to log only the length of the output
	 * @param dupsPath
	 *            path to the command output that will be read, duplicate entry
	 *            lines removed and re-written
	 */
	function runCmd(cmd, wpath, nofail, shortlog, dupsPath) {
		grunt.log.writeln(cmd);
		var rtn = null;
		if (typeof cmd === 'string') {
			rtn = shell.exec(cmd, {
				silent : true
			});
		} else {
			rtn = shell[cmd.shell].apply(shell, cmd.args);
		}
		if (rtn.code !== 0) {
			var e = 'Error "' + rtn.code + '" for commit number '
					+ commit.number + ' ' + rtn.output;
			if (nofail) {
				grunt.log.error(e);
				return;
			}
			throw grunt.util.error(e);
		}
		var output = rtn.output;
		if (dupsPath) {
			// remove duplicate lines
			output = grunt.file.read(dupsPath).replace(regexDupLines, '$1');
			grunt.file.write(dupsPath, output);
		}
		if (output && wpath) {
			grunt.file.write(wpath, output);
		}
		if (output) {
			grunt.log.writeln(output.replace(regexKey, '$1[SECURE]$2'));
		}
		return output;
	}

	/**
	 * Uploads the file asset and associates it with a specified tagged release
	 * see http://developer.github.com/v3/repos/releases/#upload-a-release-asset
	 *
	 * @param filePath
	 *            the path to the file that will be added
	 * @param commit
	 *            the commit the asset is for
	 * @param options
	 *            the task options
	 * @param cb
	 *            the call back function (passed parameters: JSON response,
	 *            error)
	 */
	function uploadDistAsset(filePath, commit, options, cb) {
		var https = require('https');
		var opts = {
			hostname : 'api.github.com',
			port : 443,
			path : '/repos/' + commit.slug + '/releases',
			method : 'GET'
		};
		var req = https.request(opts, function(res) {
			var sc = res.statusCode;
			res.on('data', function(d) {
				var rls = null, rl = null;
				try {
					rls = JSON.parse(d);
					for ( var i = 0; i < rls.length; i++) {
						if (rls[i].tag_name == commit.versionTag) {
							// upload asset
							rl = rls[i];
							opts.method = 'POST';
							opts.path = rl.upload_url.replace(regexHost,
									function(m, h) {
										opts.hostname = h;
										return '/';
									});
							opts.path = opts.path.replace(/{(\?.+)}/, '$1='
									+ commit.versionTag);
							opts.headers = {
								'Content-Type' : 'application/zip'
							};
							var req2 = https.request(opts, function(res2) {
								res.on('data', function(d2) {
									var cf = null;
									try {
										cf = JSON.parse(d2);
										try {
											cb(cf);
										} catch (e) {
											// consume
										}
									} catch (e) {
										cb(cf || rl, e);
									}
								});
							});
							req2.on('error', function(e) {
								cb(rl, e);
							});
							reqWrite(req2, filePath);
							break;
						}
					}
				} catch (e) {
					cb(rl || rls, e);
				}
			});
		});
		req.end();
		req.on('error', function(e) {
			cb(null, e);
		});
	}

	/**
	 * Writes file to the specified stream
	 *
	 * @param stream
	 *            the stream to write to
	 * @param filePath
	 *            the file path to read from
	 */
	function reqWrite(stream, filePath) {
		var chunkSize = 64 * 1024;
		var bufSize = 64 * 1024;
		var bufPos = 0;
		var buf = new Buffer(bufSize);
		fs.createReadStream(filePath, {
			'flags' : 'r',
			'encoding' : 'binary',
			'mode' : 438, /* 0666 */
			'bufferSize' : chunkSize
		}).addListener("data", function(chunk) {
			// Since this is binary data, we cat use String.prototype.length We
			// *WANT* the number of chars, since node uses UTF-16 for bin data
			// meaning one byte bin data = one char = two bytes.
			var bufNextPos = bufPos + chunk.length;
			if (bufNextPos == bufSize) {
				buf.write(chunk, 'binary', bufPos);
				stream.write(buf);
				bufPos = 0;
			} else {
				buf.write(chunk, 'binary', bufPos);
				bufPos = bufNextPos;
			}
		}).addListener("close", function() {
			if (bufPos != 0) {
				stream.write(buf.slice(0, bufPos));
				stream.end();
			} else {
				stream.close();
			}
		});
	}
};<commit_msg>Release v1.0.0-beta.4 [skip saucelabs-qunit]<commit_after>'use strict';

var shell = require('shelljs');
var fs = require('fs');
var zlib = require('zlib');
var util = require('../util');
var regexDupLines = /^(.*)(\r?\n\1)+$/gm;
var regexKey = /(https?:\/\/|:)+(?=[^:]*$)[a-z0-9]+(@)/gmi;
var regexHost = /^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i;

/**
 * When a commit message contains "release v" followed by a version number
 * (major.minor.patch) a tagged release will be issued
 *
 * @param grunt
 *            the grunt instance
 */
module.exports = function(grunt) {

	var commit = null;

	grunt.registerTask('release',
			'Release bundle using commit message (if present)', function() {
				var options = this.options({
					src : process.cwd(),
					commitMessage : '',
					destBranch : 'gh-pages',
					destDir : 'dist',
					chgLog : 'HISTORY.md',
					authors : 'AUTHORS.md',
					distAsset : true
				});
				release.call(this, options);
			});

	/**
	 * Checks for release commit message and performs release
	 *
	 * @param options
	 *            the grunt options
	 */
	function release(options) {
		var chgLogRtn = '';
		var authorsRtn = '';

		// Capture commit message
		commit = util.getCommit(grunt, options.commitMessage);
		grunt.log.writeln('Commit message: ' + commit.message);
		if (!commit.version) {
			return;
		}

		// TODO : verify release version is less than last release version
		var lastVerTag = runCmd('git describe --abbrev=0 --tags '
				+ commit.number);
		grunt.log.writeln('Preparing release: ' + commit.version
				+ ' (last release: ' + lastVerTag + ')');
		var relMsg = commit.message + ' ' + util.skipRef('ci');

		// Generate change log for release using all messages since last
		// tag/release
		var chgLogPath = options.destDir + '/' + options.chgLog;
		chgLogRtn = runCmd('git --no-pager log ' + lastVerTag
				+ '..HEAD --pretty=format:"  * %s" > ' + chgLogPath, null,
				false, true, chgLogPath);

		// Generate list of authors/contributors since last tag/release
		var authorsPath = options.destDir + '/' + options.authors;
		authorsRtn = runCmd('git log --all --format="%aN <%aE>" | sort -u > '
				+ authorsPath, null, true, false, authorsPath);

		// Setup
		var link = '${GH_TOKEN}@github.com/' + commit.slug + '.git';
		runCmd('git config --global user.email "travis@travis-ci.org"');
		runCmd('git config --global user.name "travis"');
		runCmd('git remote rm origin');
		runCmd('git remote add origin https://' + commit.username + ':' + link);
		runCmd('git checkout master');

		// Commit changes to master
		runCmd('git add --force ' + options.destDir);
		runCmd('git commit -m "' + relMsg + '"');
		// runCmd('git push -f origin master');

		// Create distribution assets
		var distAsset = commit.reponame + '-' + commit.version + '-dist.zip';
		runCmd('git archive -v -o ' + distAsset + ' --format=zip master '
				+ options.destDir);

		// Tag release
		runCmd('git tag -f -a ' + commit.versionTag + ' -m "' + chgLogRtn + '"');
		runCmd('git push -f origin ' + commit.versionTag);
		grunt.log.writeln('Released: ' + commit.version + ' in '
				+ options.destDir);

		// Distribute archive asset for tagged release
		var done = this.async();
		uploadDistAsset(distAsset, commit, options, function(json, e) {
			if (e) {
				grunt.log.error(grunt.util.error('Failed to upload asset '
						+ distAsset, e));
			} else if (cf.state != 'uploaded') {
				e = grunt.util.error('Asset upload failed with state: '
						+ cf.state);
				grunt.log.error(e);
			} else {
				grunt.log.writeln('Distributed/' + cf.state + ' ' + distAsset
						+ ' asset');
			}
			done(e);
		});

		// Publish site
		/*
		 * runCmd('cd ..'); runCmd('git clone --quiet --branch=' +
		 * options.destBranch + ' https://' + link + ' ' + options.destBranch + ' >
		 * /dev/null'); runCmd('cd ' + options.destBranch); runCmd('git ls-files |
		 * xargs rm'); // remove all tracked files runCmd('git commit -m "' +
		 * relMsg + '"');
		 *
		 * runCmd('cp -a ../' + commit.reponame + '/' + options.destBranch + '/*
		 * .'); // runCmd('git checkout master -- ' + options.destDir);
		 * runCmd('git add -A'); runCmd('git commit -m "' + relMsg + '"');
		 * runCmd('git push -f origin ' + options.destBranch + ' > /dev/null');
		 */
	}

	/**
	 * Executes a shell command
	 *
	 * @param cmd
	 *            the command string to execute
	 * @param wpath
	 *            the optional path/file to write the results to
	 * @param nofail
	 *            true to prevent throwing an error when the command fails to
	 *            execute
	 * @param shortlog
	 *            true to log only the length of the output
	 * @param dupsPath
	 *            path to the command output that will be read, duplicate entry
	 *            lines removed and re-written
	 */
	function runCmd(cmd, wpath, nofail, shortlog, dupsPath) {
		grunt.log.writeln(cmd);
		var rtn = null;
		if (typeof cmd === 'string') {
			rtn = shell.exec(cmd, {
				silent : true
			});
		} else {
			rtn = shell[cmd.shell].apply(shell, cmd.args);
		}
		if (rtn.code !== 0) {
			var e = 'Error "' + rtn.code + '" for commit number '
					+ commit.number + ' ' + rtn.output;
			if (nofail) {
				grunt.log.error(e);
				return;
			}
			throw grunt.util.error(e);
		}
		var output = rtn.output;
		if (dupsPath) {
			// remove duplicate lines
			output = grunt.file.read(dupsPath).replace(regexDupLines, '$1');
			grunt.file.write(dupsPath, output);
		}
		if (output && wpath) {
			grunt.file.write(wpath, output);
		}
		if (output) {
			grunt.log.writeln(output.replace(regexKey, '$1[SECURE]$2'));
		}
		return output;
	}

	/**
	 * Uploads the file asset and associates it with a specified tagged release
	 * see http://developer.github.com/v3/repos/releases/#upload-a-release-asset
	 *
	 * @param filePath
	 *            the path to the file that will be added
	 * @param commit
	 *            the commit the asset is for
	 * @param options
	 *            the task options
	 * @param cb
	 *            the call back function (passed parameters: JSON response,
	 *            error)
	 */
	function uploadDistAsset(filePath, commit, options, cb) {
		var https = require('https');
		var opts = {
			hostname : 'api.github.com',
			port : 443,
			path : '/repos/' + commit.slug + '/releases',
			method : 'GET'
		};
		var req = https.request(opts, function(res) {
			var sc = res.statusCode;
			res.on('data', function(d) {
				var rls = null, rl = null;
				try {
					rls = JSON.parse(d);
					for ( var i = 0; i < rls.length; i++) {
						if (rls[i].tag_name == commit.versionTag) {
							// upload asset
							rl = rls[i];
							opts.method = 'POST';
							opts.path = rl.upload_url.replace(regexHost,
									function(m, h) {
										opts.hostname = h;
										return '/';
									});
							opts.path = opts.path.replace(/{(\?.+)}/, '$1='
									+ commit.versionTag);
							opts.headers = {
								'Content-Type' : 'application/zip'
							};
							var req2 = https.request(opts, function(res2) {
								res.on('data', function(d2) {
									var cf = null;
									try {
										cf = JSON.parse(d2);
										try {
											cb(cf);
										} catch (e) {
											// consume
										}
									} catch (e) {
										cb(cf || rl, e);
									}
								});
							});
							req2.on('error', function(e) {
								cb(rl, e);
							});
							reqWrite(req2, filePath);
							break;
						}
					}
				} catch (e) {
					cb(rl || rls, e);
				}
			});
		});
		req.end();
		req.on('error', function(e) {
			cb(null, e);
		});
	}

	/**
	 * Writes file to the specified stream
	 *
	 * @param stream
	 *            the stream to write to
	 * @param filePath
	 *            the file path to read from
	 */
	function reqWrite(stream, filePath) {
		var chunkSize = 64 * 1024;
		var bufSize = 64 * 1024;
		var bufPos = 0;
		var buf = new Buffer(bufSize);
		fs.createReadStream(filePath, {
			'flags' : 'r',
			'encoding' : 'binary',
			'mode' : 438, /* 0666 */
			'bufferSize' : chunkSize
		}).addListener("data", function(chunk) {
			// Since this is binary data, we cat use String.prototype.length We
			// *WANT* the number of chars, since node uses UTF-16 for bin data
			// meaning one byte bin data = one char = two bytes.
			var bufNextPos = bufPos + chunk.length;
			if (bufNextPos == bufSize) {
				buf.write(chunk, 'binary', bufPos);
				stream.write(buf);
				bufPos = 0;
			} else {
				buf.write(chunk, 'binary', bufPos);
				bufPos = bufNextPos;
			}
		}).addListener("close", function() {
			if (bufPos != 0) {
				stream.write(buf.slice(0, bufPos));
				stream.end();
			} else {
				stream.close();
			}
		});
	}
};<|endoftext|>


<commit_before>
// Used to replace tabulations with spaces
String.prototype.repeat = function (num) {
    'use strict';
    return new Array( num + 1 ).join(this);
};

function clean_tabu(line) {
    'use strict';
    var  res = line.replace(/^\t/g, " ".repeat(10)),
        i = res.search(/\t/);
    while (i >= 0) {
        res = res.substr(0, i) + " ".repeat(8 - ((i + 6) % 8)) + res.substr(i + 1);
        i = res.search(/\t/);
    }
    return res;
}

function capitaliseFirstLetter(string) {
    'use strict';
    return string.charAt(0).toUpperCase() + string.slice(1);
}
function remove_trailing_punctuation(string) {
    'use strict';
    return string.replace(/(,|;|\.)*$/g, "");
}
function clean_string(line) {
    'use strict';
    var res = line;
    res = capitaliseFirstLetter(res);
    res = remove_trailing_punctuation(res);
    return res;
}

// insert the guitar tabs into the current line
function insert_tabs_in_line(cur_line, cur_tabs) {
    'use strict';
    var j = cur_tabs.length,// index amoung the cur_tabs
        l = cur_line.length;
    while (j > 0) {
        j -= 1;
        if (cur_tabs[j] !== undefined) {
            l = Math.min(j, l);//if the tabs are after the end of the text line, we insert them at the end
            cur_line = cur_line.substr(0, l) + "\\[" + cur_tabs[j] + "]" + cur_line.substr(l);
        }
    }
    return cur_line;
}

// extract the tabs of the line into an array where the index is the position of the tab in the line
function extract_tabs(line) {
    'use strict';
    //var reg = /^(.* )?[A-Ga-g](#|b|&)?m?(sus|add)?[0-9]?( *(-|\/) *[A-G](#|b|&)?)? *$/;
    var reg = /^ *[A-Ga-g](#|b|&)?m?(sus|add)?[0-9]?( *(-|\/) *[A-G](#|b)?)?( +[A-Ga-g](#|b|&)?m?(sus|add)?[0-9]?( *(-|\/) *[A-G](#|b|&)?)? *)* *$/,
        reguniq = /[A-Ga-g](#|b|&)?m?(sus|add)?[0-9]?( *(-|\/) *[A-G](#|b|&)?)? *$/,
        i,
        tab;

    if (line.match(reg)) {
        i = line.search(reguniq);
        tab = extract_tabs(line.substr(0, i - 1));
        tab[i] = line.substr(i).trim().replace('b', '&');
        return tab;
    }
    return [];
}

// inserts the tabs into the raw_lines according to the "patacrep formatting"
// input and output are arrays
function parse(raw_lines) {
    'use strict';

    var i = raw_lines.length - 1,    // index amoung the lines of the raw text (we start with the last line)

        cur_line = raw_lines[i],    // line where we currently insert the tabs

        parsed_lines = [],          // lines that are already parsed
        cur_tabs;

    while (i > 0) {
        i -= 1;
        // for every "next line", we try to extract some guitar tabs
        cur_tabs = extract_tabs(clean_tabu(raw_lines[i]));

        if (cur_tabs.length > 0) {
            // if we were able to parse, we insert the guitar tabs into the current line
            cur_line = insert_tabs_in_line(cur_line, cur_tabs);
        } else {
            // else we just move on
            parsed_lines.unshift(cur_line);
            cur_line = clean_string(raw_lines[i]);
        }
        if (i === 0) {
            // for the last iteration
            parsed_lines.unshift(cur_line);
        }
    }
    return parsed_lines;
}

<commit_msg>Update guitar-tabs_songtex.js to consider 'maj' <commit_after>
// Used to replace tabulations with spaces
String.prototype.repeat = function (num) {
    'use strict';
    return new Array( num + 1 ).join(this);
};

function clean_tabu(line) {
    'use strict';
    var  res = line.replace(/^\t/g, " ".repeat(10)),
        i = res.search(/\t/);
    while (i >= 0) {
        res = res.substr(0, i) + " ".repeat(8 - ((i + 6) % 8)) + res.substr(i + 1);
        i = res.search(/\t/);
    }
    return res;
}

function capitaliseFirstLetter(string) {
    'use strict';
    return string.charAt(0).toUpperCase() + string.slice(1);
}
function remove_trailing_punctuation(string) {
    'use strict';
    return string.replace(/(,|;|\.)*$/g, "");
}
function clean_string(line) {
    'use strict';
    var res = line;
    res = capitaliseFirstLetter(res);
    res = remove_trailing_punctuation(res);
    return res;
}

// insert the guitar tabs into the current line
function insert_tabs_in_line(cur_line, cur_tabs) {
    'use strict';
    var j = cur_tabs.length,// index amoung the cur_tabs
        l = cur_line.length;
    while (j > 0) {
        j -= 1;
        if (cur_tabs[j] !== undefined) {
            l = Math.min(j, l);//if the tabs are after the end of the text line, we insert them at the end
            cur_line = cur_line.substr(0, l) + "\\[" + cur_tabs[j] + "]" + cur_line.substr(l);
        }
    }
    return cur_line;
}

// extract the tabs of the line into an array where the index is the position of the tab in the line
function extract_tabs(line) {
    'use strict';
    //var reg = /^(.* )?[A-Ga-g](#|b|&)?m?(sus|add)?[0-9]?( *(-|\/) *[A-G](#|b|&)?)? *$/;
    var reg = /^ *[A-Ga-g](#|b|&)?m?(sus|add|maj)?[0-9]?( *(-|\/) *[A-G](#|b)?)?( +[A-Ga-g](#|b|&)?m?(sus|add|maj)?[0-9]?( *(-|\/) *[A-G](#|b|&)?)? *)* *$/,
        reguniq = /[A-Ga-g](#|b|&)?m?(sus|add|maj)?[0-9]?( *(-|\/) *[A-G](#|b|&)?)? *$/,
        i,
        tab;

    if (line.match(reg)) {
        i = line.search(reguniq);
        tab = extract_tabs(line.substr(0, i - 1));
        tab[i] = line.substr(i).trim().replace('b', '&');
        return tab;
    }
    return [];
}

// inserts the tabs into the raw_lines according to the "patacrep formatting"
// input and output are arrays
function parse(raw_lines) {
    'use strict';

    var i = raw_lines.length - 1,    // index amoung the lines of the raw text (we start with the last line)

        cur_line = raw_lines[i],    // line where we currently insert the tabs

        parsed_lines = [],          // lines that are already parsed
        cur_tabs;

    while (i > 0) {
        i -= 1;
        // for every "next line", we try to extract some guitar tabs
        cur_tabs = extract_tabs(clean_tabu(raw_lines[i]));

        if (cur_tabs.length > 0) {
            // if we were able to parse, we insert the guitar tabs into the current line
            cur_line = insert_tabs_in_line(cur_line, cur_tabs);
        } else {
            // else we just move on
            parsed_lines.unshift(cur_line);
            cur_line = clean_string(raw_lines[i]);
        }
        if (i === 0) {
            // for the last iteration
            parsed_lines.unshift(cur_line);
        }
    }
    return parsed_lines;
}

<|endoftext|>


<commit_before>var path = require('path');
var pkg = require('../../package.json');

/**
 * Configuration class containing all properties to be used throughout the build
 */
var Config = function() {
  this.debugMode = false;
  this.lessExtension = "less";
  this.sassExtension = "scss";
  this.buildSass = false;
  this.copyRightMessage = "Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.";
	var distPath = 'dist';
	var srcPath = 'src';
	this.paths = {
		distComponents: distPath + '/components',
		distLess: distPath + '/less',
    distSass: distPath + '/sass',
		distCSS: distPath + '/css',
		distSamples: distPath + '/samples',
		distSampleComponents: distPath + '/samples/' +  '/Components',
		distJS: distPath + '/js',
		distPackages: distPath + '/packages',
		srcPath: srcPath,
		srcSamples: srcPath + '/samples',
    srcSass: srcPath + '/sass',
		componentsPath : 'src/components',
		srcLess: srcPath + '/less',
		templatePath : srcPath + '/templates'
	};
	this.port =  process.env.PORT || 2020;
	this.projectURL =  "http://localhost";
	this.projectDirectory =  path.resolve(__dirname, '../../' + this.paths.distSamples);
	this.servePaths = [
        {
            'urlPath': '/css',
            'folderPath': '../css'
        }
    ];
	this.nugetConfig = {
		id: "OfficeUIFabric",
		title: "Office UI Fabric",
		version: pkg.version,
		authors: "Microsoft Corporation",
		owners: "Microsoft Corporation",
		description: "Fabric is a responsive, mobile-first, front-end framework, designed to make it quick and simple for you to create web experiences using the Office Design Language. It’s easy to get up and running with Fabric—whether you’re creating a new Office experience from scratch or adding new features to an existing one.",
		summary: "The front-end framework for building experiences for Office and Office 365.",
		language: "en-us",
		projectUrl: "https://github.com/OfficeDev/Office-UI-Fabric",
		licenseUrl: "https://github.com/OfficeDev/Office-UI-Fabric/blob/master/LICENSE",
		copyright: "Copyright (c) Microsoft Corporation",
		requireLicenseAcceptance: true,
		tags: "Microsoft UI Fabric CSS",
		outputDir: this.paths.distPackages
	};
	this.nugetPaths = [
		{src: this.paths.componentsPath, dest: "/content/components/"},
		{src: this.paths.distCSS, dest: "/content/css/"},
		{src: this.paths.distJS, dest: "/content/scripts/"},
		{src: this.paths.distLess, dest: "/content/less/"},
        {src: this.paths.distSass, dest: "/content/sass/"}
	];
  this.componentSamplesUpdate = "Components Samples updated successfully! Yay!";
  this.componentSamplesFinished = ' Component Samples build was successful! Yay!';
  //JS Files to be ignored in the JS Linter for Components
  //NOTE: Only use this for third party files, do not add any Fabric JS files to this.
  this.ignoreComponentJSLinting = [{
        src: this.paths.componentsPath + '/DatePicker/PickaDate.js',
        dist: this.paths.distSampleComponents + '/DatePicker/'
  }];
  //Errors
  this.genericBuildError = "Hmm, something went wrong in the build... Here is the error dump";
};

module.exports = new Config();<commit_msg>Add bundles path to Config<commit_after>var path = require('path');
var pkg = require('../../package.json');

/**
 * Configuration class containing all properties to be used throughout the build
 */
var Config = function() {
  this.debugMode = false;
  this.lessExtension = "less";
  this.sassExtension = "scss";
  this.buildSass = false;
  this.copyRightMessage = "Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE in the project root for license information.";
	var distPath = 'dist';
	var srcPath = 'src';
	this.paths = {
		distComponents: distPath + '/components',
		distLess: distPath + '/less',
    distSass: distPath + '/sass',
		distCSS: distPath + '/css',
		distSamples: distPath + '/samples',
		distSampleComponents: distPath + '/samples/' +  '/Components',
		distJS: distPath + '/js',
		distPackages: distPath + '/packages',
		bundlePath: distPath + '/bundles',
		srcPath: srcPath,
		srcSamples: srcPath + '/samples',
    srcSass: srcPath + '/sass',
		componentsPath : 'src/components',
		srcLess: srcPath + '/less',
		templatePath : srcPath + '/templates'
	};
	this.port =  process.env.PORT || 2020;
	this.projectURL =  "http://localhost";
	this.projectDirectory =  path.resolve(__dirname, '../../' + this.paths.distSamples);
	this.servePaths = [
        {
            'urlPath': '/css',
            'folderPath': '../css'
        }
    ];
	this.nugetConfig = {
		id: "OfficeUIFabric",
		title: "Office UI Fabric",
		version: pkg.version,
		authors: "Microsoft Corporation",
		owners: "Microsoft Corporation",
		description: "Fabric is a responsive, mobile-first, front-end framework, designed to make it quick and simple for you to create web experiences using the Office Design Language. It’s easy to get up and running with Fabric—whether you’re creating a new Office experience from scratch or adding new features to an existing one.",
		summary: "The front-end framework for building experiences for Office and Office 365.",
		language: "en-us",
		projectUrl: "https://github.com/OfficeDev/Office-UI-Fabric",
		licenseUrl: "https://github.com/OfficeDev/Office-UI-Fabric/blob/master/LICENSE",
		copyright: "Copyright (c) Microsoft Corporation",
		requireLicenseAcceptance: true,
		tags: "Microsoft UI Fabric CSS",
		outputDir: this.paths.distPackages
	};
	this.nugetPaths = [
		{src: this.paths.componentsPath, dest: "/content/components/"},
		{src: this.paths.distCSS, dest: "/content/css/"},
		{src: this.paths.distJS, dest: "/content/scripts/"},
		{src: this.paths.distLess, dest: "/content/less/"},
        {src: this.paths.distSass, dest: "/content/sass/"}
	];
  this.componentSamplesUpdate = "Components Samples updated successfully! Yay!";
  this.componentSamplesFinished = ' Component Samples build was successful! Yay!';
  //JS Files to be ignored in the JS Linter for Components
  //NOTE: Only use this for third party files, do not add any Fabric JS files to this.
  this.ignoreComponentJSLinting = [{
        src: this.paths.componentsPath + '/DatePicker/PickaDate.js',
        dist: this.paths.distSampleComponents + '/DatePicker/'
  }];
  //Errors
  this.genericBuildError = "Hmm, something went wrong in the build... Here is the error dump";
};

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


<commit_before>'use strict';

const assemble = require('assemble');
const app      = assemble();
const gulp     = require('gulp');
const config   = require('../config');
const get      = require('get-value');
const extname  = require('gulp-extname');
const plumber  = require('gulp-plumber');
const flatten  = require('gulp-flatten');
const helpers  = require('handlebars-helpers')();

gulp.task('load', (cb) => {

  //Set main assemble options
  app.option('layout', 'default');
  app.layouts('app/layouts/*.hbs');
  app.pages('app/pages/**/*.hbs');
  app.partials('app/components/**/*.hbs');
  app.engine('hbs', require('engine-handlebars'));
  app.data(['app/{pages,components,data}/**/*.json']);

  //Custom helpers
  app.helper('get', (prop) => {
    return get(this.context, prop);
  });

  cb();
});

gulp.task('assemble', ['load'], () => {
    return app.toStream('pages')
      .pipe(app.renderFile())
      .pipe(extname())
      .pipe(flatten())
      .pipe(plumber())
      .pipe(app.dest(config.tmp));
});

gulp.task('assemble:dist', ['load', 'clean:dist'], () => {
    return app.toStream('pages')
      .pipe(app.renderFile())
      .pipe(extname())
      .pipe(flatten())
      .pipe(plumber())
      .pipe(app.dest(config.dist));
});<commit_msg>Removing Assemble default layout option<commit_after>'use strict';

const assemble = require('assemble');
const app      = assemble();
const gulp     = require('gulp');
const config   = require('../config');
const get      = require('get-value');
const extname  = require('gulp-extname');
const plumber  = require('gulp-plumber');
const flatten  = require('gulp-flatten');
const helpers  = require('handlebars-helpers')();

gulp.task('load', (cb) => {

  //Set main assemble options
  app.layouts('app/layouts/*.hbs');
  app.pages('app/pages/**/*.hbs');
  app.partials('app/components/**/*.hbs');
  app.engine('hbs', require('engine-handlebars'));
  app.data(['app/{pages,components,data}/**/*.json']);

  //Custom helpers
  app.helper('get', (prop) => {
    return get(this.context, prop);
  });

  cb();
});

gulp.task('assemble', ['load'], () => {
    return app.toStream('pages')
      .pipe(app.renderFile())
      .pipe(extname())
      .pipe(flatten())
      .pipe(plumber())
      .pipe(app.dest(config.tmp));
});

gulp.task('assemble:dist', ['load', 'clean:dist'], () => {
    return app.toStream('pages')
      .pipe(app.renderFile())
      .pipe(extname())
      .pipe(flatten())
      .pipe(plumber())
      .pipe(app.dest(config.dist));
});<|endoftext|>


<commit_before>// dependencies ------------------------------------------------------------

import config   from '../config';
import agave    from '../libs/agave';
import sanitize from '../libs/sanitize';
import mongo    from '../libs/mongo';
import scitran  from '../libs/scitran';
import validate from 'bids-validator'

let c = mongo.collections;

// handlers ----------------------------------------------------------------

/**
 * Validation
 *
 * Handlers for dataset validation.
 */
export default {

	/**
	 * Flag For Validation
	 */
	flag(req, res, next) {

		// get project id
		let datasetId = req.params.datasetId;

		// check if project id is queued already
		c.validationQueue.updateOne({_id: datasetId}, {_id: datasetId}, {upsert: true}).then((err, result) => {
			if (err) {res.send(err);}
			else {res.send('Dataset ' + datasetId + ' flagged for validation.');}
		});
	},

	/**
	 * Validate
	 *
	 * Executed by the cron runner. Searches for flagged datasets
	 * downloads them, validates them and updates their validation
	 * results.
	 */
	validate() {
		c.validationQueue.find().toArray((err, datasets) => {
			if (err) {
				/* HANDLE ERROR */
			}
			if (datasets && datasets.length > 0) {
				for (let dataset of datasets) {
					scitran.downloadSymlinkDataset(dataset._id, (err, hash) => {
						if (err && err.status == 404) {
							// remove validation flag if dataset can no longer be found
							c.validationQueue.findAndRemove({_id: dataset._id}, [], (err, doc) => {});
						} else {
							validate.BIDS(config.location + '/persistent/datasets/' + hash, {}, (errors, warnings) => {
								scitran.updateProject(dataset._id, {
									metadata: {
										validation: {errors, warnings}
									}
								}, (err, res) => {
									if (errors && errors.length > 0) {
										scitran.addTag('projects', dataset._id, 'invalid', (err, res) => {});
									} else {
										scitran.removeTag('projects', dataset._id, 'invalid', (err, res) => {});
									}
									c.validationQueue.findAndRemove({_id: dataset._id}, [], (err, doc) => {
										scitran.removeTag('projects', dataset._id, 'pendingValidation', (err, res) => {});
									});
								});
							});
						}
					});
				}
			}
		});
	},

	validateOne(req, res, next) {

		// get project id
		let datasetId = req.params.datasetId;
		console.log('datasetId:' + datasetId);

		scitran.downloadSymlinkDataset(datasetId, (err, hash) => {
			console.log(err, hash);
			if (err && err.status == 404) {
				// remove validation flag if dataset can no longer be found
				// c.validationQueue.findAndRemove({_id: dataset._id}, [], (err, doc) => {});
			} else {
				validate.BIDS('./persistent/datasets/' + hash, {}, (errors, warnings) => {
					let validation = {errors, warnings};
					scitran.updateProject(datasetId, {
						metadata: {validation}
					}, (err, res1) => {
						scitran.removeTag('projects', datasetId, 'pendingValidation', (err, res2) => {
							if (errors && errors.length > 0) {
								scitran.addTag('projects', datasetId, 'invalid', (err, res3) => {res.send(validation)});
							} else {
								scitran.removeTag('projects', datasetId, 'invalid', (err, res4) => {res.send(validation)});
							}
						});

					});
				});
			}
		});
	}

}
<commit_msg>removed console logs and unneccessary locgic and updated validating status name<commit_after>// dependencies ------------------------------------------------------------

import config   from '../config';
import agave    from '../libs/agave';
import sanitize from '../libs/sanitize';
import mongo    from '../libs/mongo';
import scitran  from '../libs/scitran';
import validate from 'bids-validator'

let c = mongo.collections;

// handlers ----------------------------------------------------------------

/**
 * Validation
 *
 * Handlers for dataset validation.
 */
export default {

	/**
	 * Flag For Validation
	 */
	flag(req, res, next) {

		// get project id
		let datasetId = req.params.datasetId;

		// check if project id is queued already
		c.validationQueue.updateOne({_id: datasetId}, {_id: datasetId}, {upsert: true}).then((err, result) => {
			if (err) {res.send(err);}
			else {res.send('Dataset ' + datasetId + ' flagged for validation.');}
		});
	},

	/**
	 * Validate
	 *
	 * Executed by the cron runner. Searches for flagged datasets
	 * downloads them, validates them and updates their validation
	 * results.
	 */
	validate() {
		c.validationQueue.find().toArray((err, datasets) => {
			if (err) {
				/* HANDLE ERROR */
			}
			if (datasets && datasets.length > 0) {
				for (let dataset of datasets) {
					scitran.downloadSymlinkDataset(dataset._id, (err, hash) => {
						if (err && err.status == 404) {
							// remove validation flag if dataset can no longer be found
							c.validationQueue.findAndRemove({_id: dataset._id}, [], (err, doc) => {});
						} else {
							validate.BIDS(config.location + '/persistent/datasets/' + hash, {}, (errors, warnings) => {
								scitran.updateProject(dataset._id, {
									metadata: {
										validation: {errors, warnings}
									}
								}, (err, res) => {
									if (errors && errors.length > 0) {
										scitran.addTag('projects', dataset._id, 'invalid', (err, res) => {});
									} else {
										scitran.removeTag('projects', dataset._id, 'invalid', (err, res) => {});
									}
									c.validationQueue.findAndRemove({_id: dataset._id}, [], (err, doc) => {
										scitran.removeTag('projects', dataset._id, 'pendingValidation', (err, res) => {});
									});
								});
							});
						}
					});
				}
			}
		});
	},

	validateOne(req, res, next) {
		// get project id
		let datasetId = req.params.datasetId;

		scitran.downloadSymlinkDataset(datasetId, (err, hash) => {
			validate.BIDS('./persistent/datasets/' + hash, {}, (errors, warnings) => {
				let validation = {errors, warnings};
				scitran.updateProject(datasetId, {
					metadata: {validation}
				}, (err, res1) => {
					scitran.removeTag('projects', datasetId, 'validating', (err, res2) => {
						if (errors && errors.length > 0) {
							scitran.addTag('projects', datasetId, 'invalid', (err, res3) => {res.send(validation)});
						} else {
							scitran.removeTag('projects', datasetId, 'invalid', (err, res4) => {res.send(validation)});
						}
					});

				});
			});
		});
	}

}
<|endoftext|>


<commit_before>import xmldoc from 'xmldoc';

const instrumentsFromMusicXml = partList => {
  return partList.children.map(part => {
    // TODO handle instruments better, defaulting to acoustic guitar
    return 'acoustic_guitar_steel';
    //return part.childNamed('score-instrument').children[0].val.replace('Steel String Guitar', 'acoustic_guitar_steel');
  });
};

const getTuning = (part, maker) => {
  const staff = part.childNamed('measure').childNamed('attributes').childNamed('staff-details');

  return staff.children.slice(1).map(string => {
    const note = string.children[0].val;
    const octave = parseInt(string.children[1].val);
    return (`${note}${maker === 'TuxGuitar' ? octave - 1 : octave}`).toLowerCase();
  });
};

const getBpmForMeasure = (measures, measure, index) => {
  const direction = measure.childNamed('direction');
  if(direction) {
    return parseInt(direction.childNamed('sound').attr.tempo);
  } else {
    return measures[index - 1].bpm ? measures[index - 1].bpm : 120;
  }
};

const getTimeSignatureForMeasure = (measures, measure, index) => {
  const attributes = measure.childNamed('attributes');
  if(attributes) {
    const time = attributes.childNamed('time');
    if(time) {
      const beats = time.childNamed('beats').val;
      const beatType = time.childNamed('beat-type').val;
      return `${beats}/${beatType}`;
    }
  }

  return measures[index - 1].timeSignature ? measures[index - 1].timeSignature : '6/8';
};

const getNotesForMeasure = (notes, stringCount) => {
  return notes.reduce((finalNotes, note) => {
    const duration = note.childNamed('type').val.substring(0, 1);
    const dotted = note.childNamed('dot') ? true : false;
    const isChord = note.childNamed('chord') ? true : false;

    if(note.childNamed('rest')) {
      return finalNotes.concat({
        duration,
        dotted,
        string: ['rest'],
        fret: ['rest']
      });
    }
    const fret = parseInt(note.childNamed('notations').childNamed('technical').childNamed('fret').val);
    const string = stringCount - parseInt(note.childNamed('notations').childNamed('technical').childNamed('string').val);

    let frets, strings;
    if(isChord) {
      frets = finalNotes[finalNotes.length - 1].fret.concat(fret);
      strings = finalNotes[finalNotes.length - 1].string.concat(string);

      return finalNotes.slice(0, finalNotes.length - 1).concat({
        duration,
        fret: frets,
        string: strings,
        dotted
      });
    }

    frets = [fret];
    strings = [string];

    return finalNotes.concat({
      duration,
      fret: frets,
      string: strings,
      dotted
    });
  }, []);
};

const measuresFromMusicXml = (measures, stringCount) => {
  return measures.reduce((finalMeasures, measure, i) => {
    const bpm = getBpmForMeasure(finalMeasures, measure, i);
    const timeSignature = getTimeSignatureForMeasure(finalMeasures, measure, i);
    const notes = getNotesForMeasure(measure.childrenNamed('note'), stringCount);

   return finalMeasures.concat({
     bpm,
     timeSignature,
     notes
   });
 }, []);
};

export function importMusicXml(xmlString) {
  const xml = new xmldoc.XmlDocument(xmlString);
  const parts = xml.childrenNamed('part');

  const instruments = instrumentsFromMusicXml(xml.childNamed('part-list'));
  const maker = xml.childNamed('identification').childNamed('encoding').childNamed('software').val;

  return parts.reduce((finalParts, part, i) => {
    const instrument = instruments[i];
    const tuning = getTuning(part, maker);
    const measures = measuresFromMusicXml(part.childrenNamed('measure'), tuning.length);

    return finalParts.concat({
      instrument,
      tuning,
      measures
    });
  }, []);
}
<commit_msg>fix importing songs with 16th/32nd notes<commit_after>import xmldoc from 'xmldoc';

const instrumentsFromMusicXml = partList => {
  return partList.children.map(part => {
    // TODO handle instruments better, defaulting to acoustic guitar
    return 'acoustic_guitar_steel';
    //return part.childNamed('score-instrument').children[0].val.replace('Steel String Guitar', 'acoustic_guitar_steel');
  });
};

const getTuning = (part, maker) => {
  const staff = part.childNamed('measure').childNamed('attributes').childNamed('staff-details');

  return staff.children.slice(1).map(string => {
    const note = string.children[0].val;
    const octave = parseInt(string.children[1].val);
    return (`${note}${maker === 'TuxGuitar' ? octave - 1 : octave}`).toLowerCase();
  });
};

const getBpmForMeasure = (measures, measure, index) => {
  const direction = measure.childNamed('direction');
  if(direction) {
    return parseInt(direction.childNamed('sound').attr.tempo);
  } else {
    return measures[index - 1].bpm ? measures[index - 1].bpm : 120;
  }
};

const getTimeSignatureForMeasure = (measures, measure, index) => {
  const attributes = measure.childNamed('attributes');
  if(attributes) {
    const time = attributes.childNamed('time');
    if(time) {
      const beats = time.childNamed('beats').val;
      const beatType = time.childNamed('beat-type').val;
      return `${beats}/${beatType}`;
    }
  }

  return measures[index - 1].timeSignature ? measures[index - 1].timeSignature : '6/8';
};

const durationFromType = type => {
  const typeChar = type.substring(0, 1);
  if(typeChar === '1') {
    return 's';
  } else if(typeChar === '3') {
    return 't';
  }
  return typeChar;
};

const getNotesForMeasure = (notes, stringCount) => {
  return notes.reduce((finalNotes, note) => {
    const duration = durationFromType(note.childNamed('type').val);
    const dotted = note.childNamed('dot') ? true : false;
    const isChord = note.childNamed('chord') ? true : false;

    if(note.childNamed('rest')) {
      return finalNotes.concat({
        duration,
        dotted,
        string: ['rest'],
        fret: ['rest']
      });
    }
    const fret = parseInt(note.childNamed('notations').childNamed('technical').childNamed('fret').val);
    const string = stringCount - parseInt(note.childNamed('notations').childNamed('technical').childNamed('string').val);

    let frets, strings;
    if(isChord) {
      frets = finalNotes[finalNotes.length - 1].fret.concat(fret);
      strings = finalNotes[finalNotes.length - 1].string.concat(string);

      return finalNotes.slice(0, finalNotes.length - 1).concat({
        duration,
        fret: frets,
        string: strings,
        dotted
      });
    }

    frets = [fret];
    strings = [string];

    return finalNotes.concat({
      duration,
      fret: frets,
      string: strings,
      dotted
    });
  }, []);
};

const measuresFromMusicXml = (measures, stringCount) => {
  return measures.reduce((finalMeasures, measure, i) => {
    const bpm = getBpmForMeasure(finalMeasures, measure, i);
    const timeSignature = getTimeSignatureForMeasure(finalMeasures, measure, i);
    const notes = getNotesForMeasure(measure.childrenNamed('note'), stringCount);

   return finalMeasures.concat({
     bpm,
     timeSignature,
     notes
   });
 }, []);
};

export function importMusicXml(xmlString) {
  const xml = new xmldoc.XmlDocument(xmlString);
  const parts = xml.childrenNamed('part');

  const instruments = instrumentsFromMusicXml(xml.childNamed('part-list'));
  const maker = xml.childNamed('identification').childNamed('encoding').childNamed('software').val;

  return parts.reduce((finalParts, part, i) => {
    const instrument = instruments[i];
    const tuning = getTuning(part, maker);
    const measures = measuresFromMusicXml(part.childrenNamed('measure'), tuning.length);

    return finalParts.concat({
      instrument,
      tuning,
      measures
    });
  }, []);
}
<|endoftext|>


<commit_before>import _ from 'underscore';
import {PAGER_ITEMS_PER_PAGE as itemsPerPage} from '../constants/appSettings';

export default class Filters {
  static filterRestaurants (items, filter) {
    return items.filter((item) => {
       return item.businessName.toLowerCase().includes(filter.toLowerCase());
    });
  }
  static filterPagerItems (displayRows, pagerNum) {
    return _.first((_.rest(displayRows, [(pagerNum - 1) * itemsPerPage])), itemsPerPage);
  }
  // TODO: Convert to ES6
  static shuffle (sourceArray) {
    for (let i = 0; i < sourceArray.length - 1; i++) {
        let j = i + Math.floor(Math.random() * (sourceArray.length - i));

        let temp = sourceArray[j];
        sourceArray[j] = sourceArray[i];
        sourceArray[i] = temp;
    }
    return sourceArray;
  }
  static alphaSort (items) {
    items.sort((a,b) => {
      if(a.businessName.toLowerCase() < b.businessName.toLowerCase()) return -1;
      if(a.businessName.toLowerCase() > b.businessName.toLowerCase()) return 1;
      return 0;
    });
    return items;
  }
}

<commit_msg>Refactoring filterPagerItems Removing Underscore<commit_after>// import _ from 'underscore';
import {PAGER_ITEMS_PER_PAGE as itemsPerPage} from '../constants/appSettings';

export default class Filters {
  static filterRestaurants (items, filter) {
    return items.filter((item) => {
       return item.businessName.toLowerCase().includes(filter.toLowerCase());
    });
  }
  static filterPagerItems (items, pagerNum) {
    // return _.first((_.rest(items, [(pagerNum - 1) * itemsPerPage])), itemsPerPage);
    // TODO: fix bug: pagination will break if you load the page with a filter already set. the numer of items will be set to the full list.
    const startArray = (pagerNum - 1) * itemsPerPage;
    return (items.slice(startArray, startArray + itemsPerPage));
  }
  // TODO: Convert to ES6
  static shuffle (sourceArray) {
    for (let i = 0; i < sourceArray.length - 1; i++) {
        let j = i + Math.floor(Math.random() * (sourceArray.length - i));

        let temp = sourceArray[j];
        sourceArray[j] = sourceArray[i];
        sourceArray[i] = temp;
    }
    return sourceArray;
  }
  static alphaSort (items) {
    items.sort((a,b) => {
      if(a.businessName.toLowerCase() < b.businessName.toLowerCase()) return -1;
      if(a.businessName.toLowerCase() > b.businessName.toLowerCase()) return 1;
      return 0;
    });
    return items;
  }
}

<|endoftext|>


<commit_before>/**
 This Source Code is licensed under the MIT license. If a copy of the
 MIT-license was not distributed with this file, You can obtain one at:
 http://opensource.org/licenses/mit-license.html.

 @author: Tom Clement (tjclement)
 @license MIT
 @copyright Bizboard, 2015

 */

export function limit(min, value, max) {
    return Math.min(Math.max(min, value), max);
}<commit_msg>Deleted unused file<commit_after><|endoftext|>