<commit_before>/**
 * Chris Troutner 4/22/16
 * ConnextCMS.com
 * This plugin allows linking to locally hosted files.
 *
 * The code here was originally copied from the 'link' TinyMCE plugin. The code was very sophisicated and I left whatever code that didn't
 * seem to be in my way. It's a bit of a hack. Consider yourself warned.
 */

/**
 * Example plugin that adds a toolbar button and menu item.
 */
tinymce.PluginManager.add('file_link', function(editor, url) {

  //Easier to just store the selected filename into a global variable.
  var selectedFileName = '';

  // Add a button that opens a window
	editor.addButton('file_link', {
		icon: 'link',
    tooltip: 'Insert/edit file',
		onclick: createLinkList(showDialog),
    stateSelector: 'a[href]'
	});

  function createLinkList(callback) {
    //debugger;
		return function() {
			var linkList = editor.settings.link_list;

			if (typeof linkList == "string") {
				tinymce.util.XHR.send({
					url: linkList,
					success: function(text) {
						callback(tinymce.util.JSON.parse(text));
					}
				});
			} else if (typeof linkList == "function") {
				linkList(callback);
			} else {
				callback(linkList);
			}
		};
	}

  function buildListItems(inputList, itemCallback, startItems) {
    //debugger;
		function appendItems(values, output) {
			output = output || [];

			tinymce.each(values, function(item) {
				var menuItem = {text: item.text || item.title};

				if (item.menu) {
					menuItem.menu = appendItems(item.menu);
				} else {
					menuItem.value = item.value;

					if (itemCallback) {
						itemCallback(menuItem);
					}
				}

				output.push(menuItem);
			});

			return output;
		}

		return appendItems(inputList, startItems || []);
	}

  function showDialog(linkList) {
    //debugger;
		var data = {}, selection = editor.selection, dom = editor.dom, selectedElm, anchorElm, initialText;
		var win, onlyText, textListCtrl, linkListCtrl, relListCtrl, targetListCtrl, fileListCtrl, classListCtrl, linkTitleCtrl, value;

		function linkListChangeHandler(e) {
			var textCtrl = win.find('#text');

			if (!textCtrl.value() || (e.lastControl && textCtrl.value() == e.lastControl.text())) {
				textCtrl.value(e.control.text());
			}

			win.find('#href').value(e.control.value());
		}

		function buildAnchorListControl(url) {
      //debugger;
			var anchorList = [];

			tinymce.each(editor.dom.select('a:not([href])'), function(anchor) {
        //debugger;
				var id = anchor.name || anchor.id;

				if (id) {
					anchorList.push({
						text: id,
						value: '#' + id,
						selected: url.indexOf('#' + id) != -1
					});
				}
			});

			if (anchorList.length) {
				anchorList.unshift({text: 'None', value: ''});

				return {
					name: 'anchor',
					type: 'listbox',
					label: 'Anchors',
					values: anchorList,
					onselect: linkListChangeHandler
				};
			}
		}

		function updateText() {
      //debugger;
			if (!initialText && data.text.length === 0 && onlyText) {
				this.parent().parent().find('#text')[0].value(this.value());
			}
		}

		function urlChange(e) {
			var meta = e.meta || {};

			if (linkListCtrl) {
				linkListCtrl.value(editor.convertURL(this.value(), 'href'));
			}

			tinymce.each(e.meta, function(value, key) {
				win.find('#' + key).value(value);
			});

			if (!meta.text) {
				updateText.call(this);
			}
		}

		function isOnlyTextSelected(anchorElm) {
      //debugger;
			var html = selection.getContent();

			// Partial html and not a fully selected anchor element
			if (/</.test(html) && (!/^<a [^>]+>[^<]+<\/a>$/.test(html) || html.indexOf('href=') == -1)) {
				return false;
			}

			if (anchorElm) {
				var nodes = anchorElm.childNodes, i;

				if (nodes.length === 0) {
					return false;
				}

				for (i = nodes.length - 1; i >= 0; i--) {
					if (nodes[i].nodeType != 3) {
						return false;
					}
				}
			}

			return true;
		}

		selectedElm = selection.getNode();
		anchorElm = dom.getParent(selectedElm, 'a[href]');
		onlyText = isOnlyTextSelected();

		data.text = initialText = anchorElm ? (anchorElm.innerText || anchorElm.textContent) : selection.getContent({format: 'text'});
		data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : '';

		if (anchorElm) {
			data.target = dom.getAttrib(anchorElm, 'target');
		} else if (editor.settings.default_link_target) {
			data.target = editor.settings.default_link_target;
		}

		if ((value = dom.getAttrib(anchorElm, 'rel'))) {
			data.rel = value;
		}

		if ((value = dom.getAttrib(anchorElm, 'class'))) {
			data['class'] = value;
		}

		if ((value = dom.getAttrib(anchorElm, 'title'))) {
			data.title = value;
		}

		if (onlyText) {
			textListCtrl = {
				name: 'text',
				type: 'textbox',
				size: 40,
				label: 'Text to display',
				onchange: function() {
					data.text = this.value();
				}
			};
		}

		if (linkList) {
			linkListCtrl = {
				type: 'listbox',
				label: 'Link list',
				values: buildListItems(
					linkList,
					function(item) {
						item.value = editor.convertURL(item.value || item.url, 'href');
					},
					[{text: 'None', value: ''}]
				),
				onselect: linkListChangeHandler,
				value: editor.convertURL(data.href, 'href'),
				onPostRender: function() {
					/*eslint consistent-this:0*/
					linkListCtrl = this;
				}
			};
		}

		if (editor.settings.target_list !== false) {
			if (!editor.settings.target_list) {
				editor.settings.target_list = [
					{text: 'None', value: ''},
					{text: 'New window', value: '_blank'}
				];
			}

			targetListCtrl = {
				name: 'target',
				type: 'listbox',
				label: 'Target',
				values: buildListItems(editor.settings.target_list)
			};
		}

    //CT
    //Create the drop-down list of files in CMS
    debugger;
    if (editor.settings.file_list !== false) {

      //CT 9/8/16 - Took out this if statement as it was keeping the file list from refreshing when new files were uploaded.
      //if (!editor.settings.file_list) {
        debugger;

        editor.settings.file_list = [];
        for( var i=0; i < global.fileUploadCollection.length; i++ ) {
          editor.settings.file_list.push(
            //{text: global.fileUploadCollection.models[i].get('fileName'), value: global.fileUploadCollection.models[i].get('url')}
            {text: global.fileUploadCollection.models[i].get('name'), value: i}
          );
        }

				//editor.settings.file_list = [
				//	{text: 'None', value: ''},
				//	{text: 'New window', value: '_blank'}
				//];
			//}

			fileListCtrl = {
				name: 'file',
				type: 'listbox',
				label: 'File',
				values: buildListItems(editor.settings.file_list)
			};
		}

		if (editor.settings.rel_list) {
			relListCtrl = {
				name: 'rel',
				type: 'listbox',
				label: 'Rel',
				values: buildListItems(editor.settings.rel_list)
			};
		}

		if (editor.settings.link_class_list) {
			classListCtrl = {
				name: 'class',
				type: 'listbox',
				label: 'Class',
				values: buildListItems(
					editor.settings.link_class_list,
					function(item) {
						if (item.value) {
							item.textStyle = function() {
								return editor.formatter.getCssText({inline: 'a', classes: [item.value]});
							};
						}
					}
				)
			};
		}

		if (editor.settings.link_title !== false) {
			linkTitleCtrl = {
				name: 'title',
				type: 'textbox',
				label: 'Title',
				value: data.title
			};
		}

		win = editor.windowManager.open({
			title: 'Insert link',
			data: data,
			body: [
				fileListCtrl,
        /*
        {
					name: 'href',
					type: 'filepicker',
					filetype: 'file',
					size: 40,
					autofocus: true,
					label: 'Url',
					onchange: urlChange,
					//onkeyup: updateText
				},
        */
				textListCtrl,
				linkTitleCtrl,
				buildAnchorListControl(data.href),
				linkListCtrl,
				relListCtrl
				//targetListCtrl,
				//classListCtrl
			],
			onSubmit: function(e) {
        //debugger;
				/*eslint dot-notation: 0*/
				var href;

				data = tinymce.extend(data, e.data);
				//href = data.href;
        href = global.fileUploadCollection.models[data.file].get('url');

				// Delay confirm since onSubmit will move focus
				function delayedConfirm(message, callback) {
					var rng = editor.selection.getRng();

					tinymce.util.Delay.setEditorTimeout(editor, function() {
						editor.windowManager.confirm(message, function(state) {
							editor.selection.setRng(rng);
							callback(state);
						});
					});
				}

				function insertLink() {
          //debugger;
					var linkAttrs = {
						href: href,
						target: data.target ? data.target : null,
						rel: data.rel ? data.rel : null,
						"class": data["class"] ? data["class"] : null,
						title: data.title ? data.title : null,
            download: global.fileUploadCollection.models[data.file].get('fileName')
					};

					if (anchorElm) {
						editor.focus();

						if (onlyText && data.text != initialText) {
							if ("innerText" in anchorElm) {
								anchorElm.innerText = data.text;
							} else {
								anchorElm.textContent = data.text;
							}
						}

						dom.setAttribs(anchorElm, linkAttrs);

						selection.select(anchorElm);
						editor.undoManager.add();
					} else {
						if (onlyText) {
							editor.insertContent(dom.createHTML('a', linkAttrs, dom.encode(data.text)));
						} else {
							editor.execCommand('mceInsertLink', false, linkAttrs);
						}
					}
				}

				if (!href) {
					editor.execCommand('unlink');
					return;
				}

				// Is email and not //user@domain.com
				if (href.indexOf('@') > 0 && href.indexOf('//') == -1 && href.indexOf('mailto:') == -1) {
					delayedConfirm(
						'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?',
						function(state) {
							if (state) {
								href = 'mailto:' + href;
							}

							insertLink();
						}
					);

					return;
				}

				// Is not protocol prefixed
				if ((editor.settings.link_assume_external_targets && !/^\w+:/i.test(href)) ||
					(!editor.settings.link_assume_external_targets && /^\s*www[\.|\d\.]/i.test(href))) {
					delayedConfirm(
						'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?',
						function(state) {
							if (state) {
								href = 'http://' + href;
							}

							insertLink();
						}
					);

					return;
				}

				insertLink();
			}
		});
	}

});<commit_msg>trying to get file_link plugin to refresh after file upload.<commit_after>/**
 * Chris Troutner 4/22/16
 * ConnextCMS.com
 * This plugin allows linking to locally hosted files.
 *
 * The code here was originally copied from the 'link' TinyMCE plugin. The code was very sophisicated and I left whatever code that didn't
 * seem to be in my way. It's a bit of a hack. Consider yourself warned.
 */

/**
 * Example plugin that adds a toolbar button and menu item.
 */
tinymce.PluginManager.add('file_link', function(editor, url) {

  //Easier to just store the selected filename into a global variable.
  var selectedFileName = '';

  // Add a button that opens a window
	editor.addButton('file_link', {
		icon: 'link',
    tooltip: 'Insert/edit file',
		onclick: createLinkList(showDialog),
    stateSelector: 'a[href]'
	});

  function createLinkList(callback) {
    //debugger;
		return function() {
			var linkList = editor.settings.link_list;

			if (typeof linkList == "string") {
				tinymce.util.XHR.send({
					url: linkList,
					success: function(text) {
						callback(tinymce.util.JSON.parse(text));
					}
				});
			} else if (typeof linkList == "function") {
				linkList(callback);
			} else {
				callback(linkList);
			}
		};
	}

  function buildListItems(inputList, itemCallback, startItems) {
    //debugger;
		function appendItems(values, output) {
			output = output || [];

			tinymce.each(values, function(item) {
				var menuItem = {text: item.text || item.title};

				if (item.menu) {
					menuItem.menu = appendItems(item.menu);
				} else {
					menuItem.value = item.value;

					if (itemCallback) {
						itemCallback(menuItem);
					}
				}

				output.push(menuItem);
			});

			return output;
		}

		return appendItems(inputList, startItems || []);
	}

  function showDialog(linkList) {
    //debugger;
		var data = {}, selection = editor.selection, dom = editor.dom, selectedElm, anchorElm, initialText;
		var win, onlyText, textListCtrl, linkListCtrl, relListCtrl, targetListCtrl, fileListCtrl, classListCtrl, linkTitleCtrl, value;

		function linkListChangeHandler(e) {
			var textCtrl = win.find('#text');

			if (!textCtrl.value() || (e.lastControl && textCtrl.value() == e.lastControl.text())) {
				textCtrl.value(e.control.text());
			}

			win.find('#href').value(e.control.value());
		}

		function buildAnchorListControl(url) {
      //debugger;
			var anchorList = [];

			tinymce.each(editor.dom.select('a:not([href])'), function(anchor) {
        //debugger;
				var id = anchor.name || anchor.id;

				if (id) {
					anchorList.push({
						text: id,
						value: '#' + id,
						selected: url.indexOf('#' + id) != -1
					});
				}
			});

			if (anchorList.length) {
				anchorList.unshift({text: 'None', value: ''});

				return {
					name: 'anchor',
					type: 'listbox',
					label: 'Anchors',
					values: anchorList,
					onselect: linkListChangeHandler
				};
			}
		}

		function updateText() {
      //debugger;
			if (!initialText && data.text.length === 0 && onlyText) {
				this.parent().parent().find('#text')[0].value(this.value());
			}
		}

		function urlChange(e) {
			var meta = e.meta || {};

			if (linkListCtrl) {
				linkListCtrl.value(editor.convertURL(this.value(), 'href'));
			}

			tinymce.each(e.meta, function(value, key) {
				win.find('#' + key).value(value);
			});

			if (!meta.text) {
				updateText.call(this);
			}
		}

		function isOnlyTextSelected(anchorElm) {
      //debugger;
			var html = selection.getContent();

			// Partial html and not a fully selected anchor element
			if (/</.test(html) && (!/^<a [^>]+>[^<]+<\/a>$/.test(html) || html.indexOf('href=') == -1)) {
				return false;
			}

			if (anchorElm) {
				var nodes = anchorElm.childNodes, i;

				if (nodes.length === 0) {
					return false;
				}

				for (i = nodes.length - 1; i >= 0; i--) {
					if (nodes[i].nodeType != 3) {
						return false;
					}
				}
			}

			return true;
		}

		selectedElm = selection.getNode();
		anchorElm = dom.getParent(selectedElm, 'a[href]');
		onlyText = isOnlyTextSelected();

		data.text = initialText = anchorElm ? (anchorElm.innerText || anchorElm.textContent) : selection.getContent({format: 'text'});
		data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : '';

		if (anchorElm) {
			data.target = dom.getAttrib(anchorElm, 'target');
		} else if (editor.settings.default_link_target) {
			data.target = editor.settings.default_link_target;
		}

		if ((value = dom.getAttrib(anchorElm, 'rel'))) {
			data.rel = value;
		}

		if ((value = dom.getAttrib(anchorElm, 'class'))) {
			data['class'] = value;
		}

		if ((value = dom.getAttrib(anchorElm, 'title'))) {
			data.title = value;
		}

		if (onlyText) {
			textListCtrl = {
				name: 'text',
				type: 'textbox',
				size: 40,
				label: 'Text to display',
				onchange: function() {
					data.text = this.value();
				}
			};
		}

		if (linkList) {
			linkListCtrl = {
				type: 'listbox',
				label: 'Link list',
				values: buildListItems(
					linkList,
					function(item) {
						item.value = editor.convertURL(item.value || item.url, 'href');
					},
					[{text: 'None', value: ''}]
				),
				onselect: linkListChangeHandler,
				value: editor.convertURL(data.href, 'href'),
				onPostRender: function() {
					/*eslint consistent-this:0*/
					linkListCtrl = this;
				}
			};
		}

		if (editor.settings.target_list !== false) {
			if (!editor.settings.target_list) {
				editor.settings.target_list = [
					{text: 'None', value: ''},
					{text: 'New window', value: '_blank'}
				];
			}

			targetListCtrl = {
				name: 'target',
				type: 'listbox',
				label: 'Target',
				values: buildListItems(editor.settings.target_list)
			};
		}

    //CT
    //Create the drop-down list of files in CMS
    debugger;
    if (editor.settings.file_list !== false) {

      //CT 9/8/16 - Took out this if statement as it was keeping the file list from refreshing when new files were uploaded.
      //if (!editor.settings.file_list) {
        debugger;

        editor.settings.file_list = [];
        //for( var i=0; i < global.fileUploadCollection.length; i++ ) {
        for( var i=global.fileUploadCollection.length-1; i > -1; i-- ) {
          editor.settings.file_list.push(
            //{text: global.fileUploadCollection.models[i].get('fileName'), value: global.fileUploadCollection.models[i].get('url')}
            {text: global.fileUploadCollection.models[i].get('name'), value: i}
          );
        }

				//editor.settings.file_list = [
				//	{text: 'None', value: ''},
				//	{text: 'New window', value: '_blank'}
				//];
			//}

			fileListCtrl = {
				name: 'file',
				type: 'listbox',
				label: 'File',
				values: buildListItems(editor.settings.file_list)
			};
		}

		if (editor.settings.rel_list) {
			relListCtrl = {
				name: 'rel',
				type: 'listbox',
				label: 'Rel',
				values: buildListItems(editor.settings.rel_list)
			};
		}

		if (editor.settings.link_class_list) {
			classListCtrl = {
				name: 'class',
				type: 'listbox',
				label: 'Class',
				values: buildListItems(
					editor.settings.link_class_list,
					function(item) {
						if (item.value) {
							item.textStyle = function() {
								return editor.formatter.getCssText({inline: 'a', classes: [item.value]});
							};
						}
					}
				)
			};
		}

		if (editor.settings.link_title !== false) {
			linkTitleCtrl = {
				name: 'title',
				type: 'textbox',
				label: 'Title',
				value: data.title
			};
		}

		win = editor.windowManager.open({
			title: 'Insert link',
			data: data,
			body: [
				fileListCtrl,
        /*
        {
					name: 'href',
					type: 'filepicker',
					filetype: 'file',
					size: 40,
					autofocus: true,
					label: 'Url',
					onchange: urlChange,
					//onkeyup: updateText
				},
        */
				textListCtrl,
				linkTitleCtrl,
				buildAnchorListControl(data.href),
				linkListCtrl,
				relListCtrl
				//targetListCtrl,
				//classListCtrl
			],
			onSubmit: function(e) {
        //debugger;
				/*eslint dot-notation: 0*/
				var href;

				data = tinymce.extend(data, e.data);
				//href = data.href;
        href = global.fileUploadCollection.models[data.file].get('url');

				// Delay confirm since onSubmit will move focus
				function delayedConfirm(message, callback) {
					var rng = editor.selection.getRng();

					tinymce.util.Delay.setEditorTimeout(editor, function() {
						editor.windowManager.confirm(message, function(state) {
							editor.selection.setRng(rng);
							callback(state);
						});
					});
				}

				function insertLink() {
          //debugger;
					var linkAttrs = {
						href: href,
						target: data.target ? data.target : null,
						rel: data.rel ? data.rel : null,
						"class": data["class"] ? data["class"] : null,
						title: data.title ? data.title : null,
            download: global.fileUploadCollection.models[data.file].get('fileName')
					};

					if (anchorElm) {
						editor.focus();

						if (onlyText && data.text != initialText) {
							if ("innerText" in anchorElm) {
								anchorElm.innerText = data.text;
							} else {
								anchorElm.textContent = data.text;
							}
						}

						dom.setAttribs(anchorElm, linkAttrs);

						selection.select(anchorElm);
						editor.undoManager.add();
					} else {
						if (onlyText) {
							editor.insertContent(dom.createHTML('a', linkAttrs, dom.encode(data.text)));
						} else {
							editor.execCommand('mceInsertLink', false, linkAttrs);
						}
					}
				}

				if (!href) {
					editor.execCommand('unlink');
					return;
				}

				// Is email and not //user@domain.com
				if (href.indexOf('@') > 0 && href.indexOf('//') == -1 && href.indexOf('mailto:') == -1) {
					delayedConfirm(
						'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?',
						function(state) {
							if (state) {
								href = 'mailto:' + href;
							}

							insertLink();
						}
					);

					return;
				}

				// Is not protocol prefixed
				if ((editor.settings.link_assume_external_targets && !/^\w+:/i.test(href)) ||
					(!editor.settings.link_assume_external_targets && /^\s*www[\.|\d\.]/i.test(href))) {
					delayedConfirm(
						'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?',
						function(state) {
							if (state) {
								href = 'http://' + href;
							}

							insertLink();
						}
					);

					return;
				}

				insertLink();
			}
		});
	}

});<|endoftext|>


<commit_before>var gulp = require('gulp');

var clean = require('gulp-clean');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

var bases = {
    app: 'app/',
    dist: 'dist/',
};

var paths = {
    scripts: ['scripts/app.js', 'scripts/model/task.js', 'scripts/collection/tasks.js', 'scripts/view/sandbox.js', 'scripts/view/task.js', 'scripts/view/modal.js', 'scripts/view/editable_input.js', 'scripts/router.js', 'scripts/app_bootstrap.js'],
    styles: ['styles/**/*.css', 'styles/**/*.eot', 'styles/**/*.svg', 'styles/**/*.ttf', 'styles/**/*.woff'],
    html: ['index.html', '404.html'],
    bower: ['bower_components/jquery/dist/jquery.js', 'bower_components/underscore/underscore.js', 'bower_components/backbone/backbone.js', 'bower_components/backbone.localStorage/backbone.localStorage-min.js'],
    extras: ['crossdomain.xml', 'humans.txt', 'manifest.appcache', 'robots.txt', 'favicon.ico', '.htaccess'],
};

gulp.task('clean', function() {
    return gulp.src(bases.dist)
        .pipe(clean());
});

gulp.task('scripts', function() {
    return gulp.src(paths.scripts, {cwd: bases.app})
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(uglify())
        .pipe(concat('multitasq.min.js'))
        .pipe(gulp.dest(bases.app + 'scripts/'));
});

/* Not needed for favicon
gulp.task('imagemin', function() {
    return gulp.src(paths.images)
        .pipe(imagemin())
        .pipe(gulp.dest(bases.dist));
});
*/

gulp.task('copy', function() {
    // copy html
    gulp.src(paths.html, {cwd: bases.app})
        .pipe(gulp.dest(bases.dist));

    // copy styles
    gulp.src(paths.styles, {cwd: 'app/**'})
        .pipe(gulp.dest(bases.dist));

    // copy processed script
    gulp.src('app/scripts/multitasq.min.js')
        .pipe(gulp.dest(bases.dist + 'scripts/'));

    // copy bower scripts
    gulp.src(paths.bower, {cwd: 'app/**'})
        .pipe(gulp.dest(bases.dist));

    // copy extra html5bp files
    gulp.src(paths.extras, {cwd: bases.app})
        .pipe(gulp.dest(bases.dist));
});

gulp.task('watch', function() {
    gulp.watch('app/**/*', ['scripts', 'copy']);
});

gulp.task('default', ['clean', 'scripts', 'copy']);

<commit_msg>fixed problem with asynchronous gulp tasks<commit_after>var gulp = require('gulp');

var clean = require('gulp-clean');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

var bases = {
    app: 'app/',
    dist: 'dist/',
};

var paths = {
    scripts: ['scripts/app.js', 'scripts/model/task.js', 'scripts/collection/tasks.js', 'scripts/view/sandbox.js', 'scripts/view/task.js', 'scripts/view/modal.js', 'scripts/view/editable_input.js', 'scripts/router.js', 'scripts/app_bootstrap.js'],
    styles: ['styles/**/*.css', 'styles/**/*.eot', 'styles/**/*.svg', 'styles/**/*.ttf', 'styles/**/*.woff'],
    html: ['index.html', '404.html'],
    bower: ['bower_components/jquery/dist/jquery.js', 'bower_components/underscore/underscore.js', 'bower_components/backbone/backbone.js', 'bower_components/backbone.localStorage/backbone.localStorage-min.js'],
    extras: ['crossdomain.xml', 'humans.txt', 'manifest.appcache', 'robots.txt', 'favicon.ico', '.htaccess'],
};

gulp.task('clean', function() {
    return gulp.src(bases.dist)
        .pipe(clean());
});

gulp.task('scripts', function() {
    return gulp.src(paths.scripts, {cwd: bases.app})
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(uglify())
        .pipe(concat('multitasq.min.js'))
        .pipe(gulp.dest(bases.app + 'scripts/'));
});

/* Not needed for favicon
gulp.task('imagemin', function() {
    return gulp.src(paths.images)
        .pipe(imagemin())
        .pipe(gulp.dest(bases.dist));
});
*/

gulp.task('copy', ['clean', 'scripts'], function() {
    // copy html
    gulp.src(paths.html, {cwd: bases.app})
        .pipe(gulp.dest(bases.dist));

    // copy styles
    gulp.src(paths.styles, {cwd: 'app/**'})
        .pipe(gulp.dest(bases.dist));

    // copy processed script
    gulp.src('app/scripts/multitasq.min.js')
        .pipe(gulp.dest(bases.dist + 'scripts/'));

    // copy bower scripts
    gulp.src(paths.bower, {cwd: 'app/**'})
        .pipe(gulp.dest(bases.dist));

    // copy extra html5bp files
    gulp.src(paths.extras, {cwd: bases.app})
        .pipe(gulp.dest(bases.dist));
});

gulp.task('testclean', function(callback) {

    return gulp.src('dist/bower_components/**')
        .pipe(clean());
});

gulp.task('testcopy', ['testclean'], function() {

    // copy bower scripts
    gulp.src(paths.bower, {cwd: 'app/**'})
        .pipe(gulp.dest(bases.dist));
});

gulp.task('watch', function() {
    gulp.watch('app/**/*', ['scripts', 'copy']);
});

gulp.task('default', ['clean', 'scripts', 'copy']);

gulp.task('practice', ['testclean', 'testcopy']);

<|endoftext|>


<commit_before>/*
 This is the javacsript for the part of the file that will be incharge of adding
questions to the database.
 */

function assessmentOnLoad() {
    generateTopicCheckboxes();
    generateSectionCheckboxes();
}

function success() {
    alert("Your assessment was assigned.");
}

function error() {
    alert("Your assessment was not created.");
}

//Called by an onload event in the body
function generateTopicCheckboxes() {
    var token = getCookie("token");
    var dataDef = {"requestType":"getTopics", "session": token};
    var urlDef = "/cgi-bin/request.py";
    var dataTypeDef = "json";
  //$.post(urlToSubmitTo, dataToSubmit, successFunctionToRunOnReturn, expectedReturnType)
    $.post(urlDef, dataDef, setTopics, dataTypeDef);
}
//Will store the topics. Declared here so other functions can see it.
var numTopics = [];
function setTopics(topics) {
    var keys = Object.keys(topics);
    // using this style of for loop, i is the index of each key in keys
    for(var i in keys)
    {
        //check to make sure that the key is an actual, useful member of the JSON (not something added by jQuery)
        if(topics.hasOwnProperty(keys[i]))
        {
            //Create and append a new option to the option element.
            var span = document.createElement("span");
            span.className = "addTopic";
            var input = document.createElement("input");
            //<input type="checkbox" id="searching" value="searching"> Searching
            //gets the topic
            input.id = topics[keys[i]];
            input.setAttribute("type","checkbox");
            input.innerHTML = topics[keys[i]];
            span.appendChild(input);
            document.getElementById("topicSelect").appendChild(span);
            numTopics.push(topics[keys[i]]);
        }
    }
    function getTopics() {
        topics = "";
        for(var i = 0; i < numTopics.length; i++) {
            if($('#'+numTopics[i]).prop('checked')) topics += numTopics[i] + " ";
        }
        return topics;
    }
 }

 function doThis() {
     alert("got here");
 }

//Called by an onload event in the body
function generateSectionCheckboxes() {
    var dataDef = {requestType:"getSections","session":getCookie("token"),"username":getCookie("username")};
    var urlDef = "/cgi-bin/request.py";
    var dataTypeDef = "json";
  //$.post(urlToSubmitTo, dataToSubmit, successFunctionToRunOnReturn, expectedReturnType)
    $.post(urlDef, dataDef, setSections, dataTypeDef);
}
//Will store the topics. Declared here so other functions can see it.
var sections = [];
function setSections(sections) {
   //Create and append a new option to the option element.
    var sectionContainer = document.getElementByID("sectionSelect");
    for(var i=0; i<Object.keys(sections).length; i++)
    {
        var name = sections[i].name;
        var span = document.createElement("span");
        span.className("addSection");
        var input = document.createElement("input");
        input.setAttribute("type","checkbox");
        input.id = name;
        input.innerHTML = name;
        span.appendChild(input);
        document.getElementById("sectionSelect").appendChild(span);
        sections.push(sections[i]);
    }
 }

function reload() {
    location.reload();
}

function submitAssignment()
{
    var dataDef = {requestType:"addAssessment",;
    var urlDef = "/cgi-bin/request.py";
    var dataTypeDef = "json";
  //$.post(urlToSubmitTo, dataToSubmit, successFunctionToRunOnReturn, expectedReturnType)
    $.post(urlDef, dataDef, setSections, dataTypeDef);
}

function sendAssignment()
{

}
<commit_msg>update assessment generation<commit_after>/*
 This is the javacsript for the part of the file that will be incharge of adding
questions to the database.
 */

function assessmentOnLoad() {
    generateTopicCheckboxes();
    generateSectionCheckboxes();
}

function success() {
    alert("Your assessment was assigned.");
}

function error() {
    alert("Your assessment was not created.");
}

//Called by an onload event in the body
function generateTopicCheckboxes() {
    var token = getCookie("token");
    var dataDef = {"requestType":"getTopics", "session": token};
    var urlDef = "/cgi-bin/request.py";
    var dataTypeDef = "json";
  //$.post(urlToSubmitTo, dataToSubmit, successFunctionToRunOnReturn, expectedReturnType)
    $.post(urlDef, dataDef, setTopics, dataTypeDef);
}
//Will store the topics. Declared here so other functions can see it.
var numTopics = [];
function setTopics(topics) {
    var keys = Object.keys(topics);
    // using this style of for loop, i is the index of each key in keys
    for(var i in keys)
    {
        //check to make sure that the key is an actual, useful member of the JSON (not something added by jQuery)
        if(topics.hasOwnProperty(keys[i]))
        {
            //Create and append a new option to the option element.
            var span = document.createElement("span");
            span.className = "addTopic";
            var input = document.createElement("input");
            //<input type="checkbox" id="searching" value="searching"> Searching
            //gets the topic
            input.id = topics[keys[i]];
            input.setAttribute("type","checkbox");
            input.innerHTML = topics[keys[i]];
            span.appendChild(input);
            document.getElementById("topicSelect").appendChild(span);
            numTopics.push(topics[keys[i]]);
        }
    }
    function getTopics() {
        topics = "";
        for(var i = 0; i < numTopics.length; i++) {
            if($('#'+numTopics[i]).prop('checked')) topics += numTopics[i] + " ";
        }
        return topics;
    }
 }

 function doThis() {
     alert("got here");
 }

//Called by an onload event in the body
function generateSectionCheckboxes() {
    var dataDef = {"requestType":"getSections","session":getCookie("token"),"username":getCookie("username")};
    var urlDef = "/cgi-bin/request.py";
    var dataTypeDef = "json";
  //$.post(urlToSubmitTo, dataToSubmit, successFunctionToRunOnReturn, expectedReturnType)
    $.post(urlDef, dataDef, setSections, dataTypeDef);
}
//Will store the topics. Declared here so other functions can see it.
var sections = [];
function setSections(sections) {
   //Create and append a new option to the option element.
    var sectionContainer = document.getElementByID("sectionSelect");
    for(var i=0; i<Object.keys(sections).length; i++)
    {
        var name = sections[i].name;
        var span = document.createElement("span");
        span.className("addSection");
        var input = document.createElement("input");
        input.setAttribute("type","checkbox");
        input.id = name;
        input.innerHTML = name;
        span.appendChild(input);
        document.getElementById("sectionSelect").appendChild(span);
        sections.push(sections[i]);
    }
 }

function reload() {
    location.reload();
}

function submitAssignment(foo)
{
    var dataDef = foo
    var urlDef = "/cgi-bin/request.py";
    var dataTypeDef = "json";
  //$.post(urlToSubmitTo, dataToSubmit, successFunctionToRunOnReturn, expectedReturnType)
    $.post(urlDef, dataDef, setSections, dataTypeDef);
}

function sendAssignment()
{
    var assessJson = { "requestType":"addAssessment" }
    assessJson["type"] = Test/quiz;`
    assessJson["isAuto"] = "1";
    assessJson["sectionIds"] = list of section Ids
    assessJson["name"] = name From input;
    assessJson["topicList"] = list of topics;
    assessJson["numQuestions"] = integer
    submitAssignment(assessJson);
}
<|endoftext|>


<commit_before>
import GameMode from './_gamemode';
import config from '../config';
import gamestate from '../gamestate';
import {shakeUpdate} from '../ScreenShake.js'
import * as Cars from '../Cars.js';

import _ from 'lodash';

let lastTime = 0;

export default class Valet {
  static loop(now) {
    const delta = now - lastTime;
    lastTime = now

    // Only update the topmost (last) (currently "active") menu layer
    if (gamestate.menus.length > 0) {
      gamestate.menus[gamestate.menus.length - 1].update(now, delta)
    }

    shakeUpdate()

    //TODO: Have a gameloop function. Maybe have a seperate one for each gametype
    if (gamestate.playing) {
      // TODO: do initialization better somehow?
      if (!gamestate.player) {
        var car = _.sample(Cars);
        let spawn = _.sample(gamestate.level.spawnPoints);

        gamestate.player =  new car(spawn);
      }
      gamestate.player.update();

      if (p2.vec2.length(gamestate.player.chassisBody.velocity) <= 0.05) {
        gamestate.player.chassisBody.backWheel.setBrakeForce(2);
        gamestate.player.boxShape.collisionGroup = config.CAR;
        gamestate.cars.push(gamestate.player);
        var car = _.sample(Cars);
        let spawn = _.sample(gamestate.level.spawnPoints);
        gamestate.player =  new car(spawn);
      }

      for (let i = gamestate.cars.length - 1; i >= 0; i--) {
        gamestate.cars[i].update()
      }
    }

    requestAnimationFrame(Valet.loop);
    if (gamestate.playing) config.world.step(1/60);
    config.renderer.render(config.stage);
  }
}
<commit_msg>nit(js): now conforms to eslint rules<commit_after>import GameMode from './_gamemode';
import config from '../config';
import gamestate from '../gamestate';
import { shakeUpdate } from '../ScreenShake.js'
import * as Cars from '../Cars.js';

import _ from 'lodash';

let lastTime = 0;

export default class Valet extends GameMode {
  static loop(now) {
    const delta = now - lastTime;
    lastTime = now

    // Only update the topmost (last) (currently "active") menu layer
    if (gamestate.menus.length > 0) {
      gamestate.menus[gamestate.menus.length - 1].update(now, delta)
    }

    shakeUpdate()

    // TODO: Have a gameloop function. Maybe have a seperate one for each gametype
    if (gamestate.playing) {
      // TODO: do initialization better somehow?
      if (!gamestate.player) {
        const car = _.sample(Cars);
        const spawn = _.sample(gamestate.level.spawnPoints);

        gamestate.player =  new car(spawn);
      }
      gamestate.player.update();

      if (p2.vec2.length(gamestate.player.chassisBody.velocity) <= 0.05) {
        gamestate.player.chassisBody.backWheel.setBrakeForce(2);
        gamestate.player.boxShape.collisionGroup = config.CAR;
        gamestate.cars.push(gamestate.player);
        const car = _.sample(Cars);
        const spawn = _.sample(gamestate.level.spawnPoints);
        gamestate.player =  new car(spawn);
      }

      for (let i = gamestate.cars.length - 1; i >= 0; i--) {
        gamestate.cars[i].update()
      }
    }

    requestAnimationFrame(Valet.loop);
    if (gamestate.playing) config.world.step(1/60);
    config.renderer.render(config.stage);
  }
}
<|endoftext|>


<commit_before>var vec3 = require('/gl-matrix/vec3.js');
var mat4 = require('/gl-matrix/mat4.js');
var quat = require('/gl-matrix/quat.js');

function Vector3(x, y, z) {
    this[0] = x || 0;
    this[1] = y || 0;
    this[2] = z || 0;
}

Vector3.prototype = new Float32Array(3);

Vector3.prototype.x = function(x) {
    if (x === undefined) {
        return this[0];
    }
    this[0] = x;
};

Vector3.prototype.y = function(y) {
    if (y === undefined) {
        return this[1];
    }
    this[1] = y;
};

Vector3.prototype.z = function(z) {
    if (z === undefined) {
        return this[2];
    }
    this[2] = z;
};

Vector3.prototype.set = function(x, y, z) {
    if (arguments.length === 1) {
        vec3.copy(this, arguments[0]);
    } else if (arguments.length === 3) {
        this[0] = x;
        this[1] = y;
        this[2] = z;
    } else {
        throw new TypeError('Wrong number of arguments.');
    }
    return this;
};

Vector3.prototype.add = function(vector3, result) {
    return vec3.add(result || new Vector3(), this, vector3);
};

Vector3.prototype.subtract = function(vector3, result) {
    return vec3.sub(result || new Vector3(), this, vector3);
};

Vector3.prototype.sub = Vector3.prototype.subtract;

Vector3.prototype.multiply = function(vector3, result) {
    return vec3.mul(result || new Vector3(), this, vector3);
};

Vector3.prototype.mul = Vector3.prototype.multiply;

Vector3.prototype.divide = function(vector3, result) {
    return vec3.divide(result || new Vector3(), this, vector3);
};

Vector3.prototype.div = Vector3.prototype.divide;

Vector3.prototype.dot = function(vector3) {
    return vec3.dot(this, vector3);
};

Vector3.prototype.cross = function(vector3, result) {
    return vec3.cross(result || new Vector3(), this, vector3);
};

Vector3.prototype.scale = function(value, result) {
    return vec3.scale(result || new Vector3(), this, value);
};

Vector3.prototype.transform = function(value, result) {
    if (value instanceof Matrix) {
        return vec3.transformMat4(result || new Vector3(), this, value);
    }
    if (value instanceof Quaternion) {
        return vec3.transformQuat(result || new Vector3(), this, value);
    }
};

Vector3.prototype.negate = function(result) {
    return vec3.negate(result || new Vector3(), this);
};

Vector3.prototype.lerp = function(vector3, t, result) {
    return vec3.lerp(result || new Vector3(), vector3, this, t);
};

Vector3.prototype.normalize = function(result) {
    return vec3.normalize(result || new Vector3(), this);
};

Vector3.prototype.len = function() {
    return vec3.length(this);
};

Vector3.prototype.squaredDistance = function(vector3) {
    return vec3.squaredDistance(this, vector3);
};

Vector3.prototype.toString = function() {
    return vec3.str(this);
};

function Matrix() {
    //mat4.identity(this);
    var mat = mat4.create();
    mat.__proto__ = Matrix.prototype;
    return mat;
}

Matrix.prototype = new Float32Array(16);

Matrix.prototype.set = function(value) {
    return mat4.copy(this, value);
};

Matrix.prototype.translate = (function() {
    var _translate = new Vector3();

    return function(x, y, z) {
        _translate.set(x,y,z);
        mat4.translate(this, this, _translate);
        return this;
    }
})();

Matrix.prototype.rotate = function(x, y, z) {
    mat4.rotateX(this, this, x);
    mat4.rotateY(this, this, y);
    mat4.rotateZ(this, this, z);
};

Matrix.prototype.scale = (function() {
    var _scale = new Vector3();

    return function(x, y, z) {
        _scale.set(x,y,z);
        mat4.scale(this, this, _scale);
        return this;
    }
})();

Matrix.prototype.multiply = function(matrix, result) {
    return mat4.multiply(result || new Matrix(), this, matrix);
};

Matrix.prototype.invert = function(result) {
    return mat4.invert(result || new Matrix(), this);
};

Matrix.prototype.toString = function() {
    return mat4.str(this);
};

Matrix.perspective = function(fieldOfView, aspectRatio, near, far, result) {
    return mat4.perspective(
        result || new Matrix(), fieldOfView, aspectRatio, near, far);
};

Matrix.lookAt = function(eye, center, up, result) {
    return mat4.lookAt(result || new Matrix(), eye, center, up);
};

function Quaternion() {
    quat.identity(this);

    Object.defineProperty(this, 'eulerAngles', {
        get: (function() {
            var _result = new Vector3();

            // Found the implementation at gamedev.stackexchange.com
            // Organizing a Transform class to internally use quaternions.

            return function() {
                var x = this[0];
                var y = this[1];
                var z = this[2];
                var w = this[3];
                var roll = Math.atan2(2*(x*y+z*w),(1-2*(y*y+z*z)));
                var pitch = Math.asin(2*(x*z-w*y));
                var yaw = Math.atan2(2*(x*w+y*z),(1-2*(z*z+w*w)));
                _result.set(pitch,yaw,roll);
                return _result;
            }
        })(),
        set: function(value) {
            var halfPitch = value[0] * 0.5;
            var sinPitch = Math.sin(halfPitch);
            var cosPitch = Math.cos(halfPitch);

            var halfYaw = value[1] * 0.5;
            var sinYaw = Math.sin(halfYaw);
            var cosYaw = Math.cos(halfYaw);

            var halfRoll = value[2] * 0.5;
            var sinRoll = Math.sin(halfRoll);
            var cosRoll = Math.cos(halfRoll);

            this[0] = ((cosYaw * sinPitch) * cosRoll) + ((sinYaw * cosPitch) * sinRoll);
            this[1] = ((sinYaw * cosPitch) * cosRoll) - ((cosYaw * sinPitch) * sinRoll);
            this[2] = ((cosYaw * cosPitch) * sinRoll) - ((sinYaw * sinPitch) * cosRoll);
            this[3] = ((cosYaw * cosPitch) * cosRoll) + ((sinYaw * sinPitch) * sinRoll);
        }
    });
}

Quaternion.prototype = new Float32Array(4);

Quaternion.prototype.rotateX = function(value) {
    return quat.rotateX(this, this, value);
};

Quaternion.prototype.rotateY = function(value) {
    return quat.rotateY(this, this, value);
};

Quaternion.prototype.rotateZ = function(value) {
    return quat.rotateZ(this, this, value);
};

Quaternion.prototype.add = function(value, result) {
    return quat.add(result || new Quaternion(), this, value);
};

Quaternion.prototype.mul = function(value, result) {
    return quat.mul(result || new Quaternion(), this, value);
};

Quaternion.prototype.toString = function() {
    return quat.str(this);
};

module.exports.Vector3 = Vector3;
module.exports.Matrix = Matrix;
module.exports.Quaternion = Quaternion;<commit_msg>Changed the way Vector3 is created and added Quaternion invert.<commit_after>var vec3 = require('/gl-matrix/vec3.js');
var mat4 = require('/gl-matrix/mat4.js');
var quat = require('/gl-matrix/quat.js');

function Vector3(x, y, z) {
    var vec = vec3.fromValues(x||0, y||0, z||0);
    vec.__proto__ = Vector3.prototype;
    return vec;
}

Vector3.prototype = new Float32Array(3);

Vector3.prototype.x = function(x) {
    if (x === undefined) {
        return this[0];
    }
    this[0] = x;
};

Vector3.prototype.y = function(y) {
    if (y === undefined) {
        return this[1];
    }
    this[1] = y;
};

Vector3.prototype.z = function(z) {
    if (z === undefined) {
        return this[2];
    }
    this[2] = z;
};

Vector3.prototype.set = function(x, y, z) {
    if (arguments.length === 1) {
        vec3.copy(this, arguments[0]);
    } else if (arguments.length === 3) {
        this[0] = x;
        this[1] = y;
        this[2] = z;
    } else {
        throw new TypeError('Wrong number of arguments.');
    }
    return this;
};

Vector3.prototype.add = function(vector3, result) {
    return vec3.add(result || new Vector3(), this, vector3);
};

Vector3.prototype.subtract = function(vector3, result) {
    return vec3.sub(result || new Vector3(), this, vector3);
};

Vector3.prototype.sub = Vector3.prototype.subtract;

Vector3.prototype.multiply = function(vector3, result) {
    return vec3.mul(result || new Vector3(), this, vector3);
};

Vector3.prototype.mul = Vector3.prototype.multiply;

Vector3.prototype.divide = function(vector3, result) {
    return vec3.divide(result || new Vector3(), this, vector3);
};

Vector3.prototype.div = Vector3.prototype.divide;

Vector3.prototype.dot = function(vector3) {
    return vec3.dot(this, vector3);
};

Vector3.prototype.cross = function(vector3, result) {
    return vec3.cross(result || new Vector3(), this, vector3);
};

Vector3.prototype.scale = function(value, result) {
    return vec3.scale(result || new Vector3(), this, value);
};

Vector3.prototype.transform = function(value, result) {
    if (value instanceof Matrix) {
        return vec3.transformMat4(result || new Vector3(), this, value);
    }
    if (value instanceof Quaternion) {
        return vec3.transformQuat(result || new Vector3(), this, value);
    }
};

Vector3.prototype.negate = function(result) {
    return vec3.negate(result || new Vector3(), this);
};

Vector3.prototype.lerp = function(vector3, t, result) {
    return vec3.lerp(result || new Vector3(), vector3, this, t);
};

Vector3.prototype.normalize = function(result) {
    return vec3.normalize(result || new Vector3(), this);
};

Vector3.prototype.len = function() {
    return vec3.length(this);
};

Vector3.prototype.squaredDistance = function(vector3) {
    return vec3.squaredDistance(this, vector3);
};

Vector3.prototype.toString = function() {
    return vec3.str(this);
};

function Matrix() {
    //mat4.identity(this);
    var mat = mat4.create();
    mat.__proto__ = Matrix.prototype;
    return mat;
}

Matrix.prototype = new Float32Array(16);

Matrix.prototype.set = function(value) {
    return mat4.copy(this, value);
};

Matrix.prototype.translate = (function() {
    var _translate = new Vector3();

    return function(x, y, z) {
        _translate.set(x,y,z);
        mat4.translate(this, this, _translate);
        return this;
    }
})();

Matrix.prototype.rotate = function(x, y, z) {
    mat4.rotateX(this, this, x);
    mat4.rotateY(this, this, y);
    mat4.rotateZ(this, this, z);
};

Matrix.prototype.scale = (function() {
    var _scale = new Vector3();

    return function(x, y, z) {
        _scale.set(x,y,z);
        mat4.scale(this, this, _scale);
        return this;
    }
})();

Matrix.prototype.multiply = function(matrix, result) {
    return mat4.multiply(result || new Matrix(), this, matrix);
};

Matrix.prototype.invert = function(result) {
    return mat4.invert(result || new Matrix(), this);
};

Matrix.prototype.toString = function() {
    return mat4.str(this);
};

Matrix.perspective = function(fieldOfView, aspectRatio, near, far, result) {
    return mat4.perspective(
        result || new Matrix(), fieldOfView, aspectRatio, near, far);
};

Matrix.lookAt = function(eye, center, up, result) {
    return mat4.lookAt(result || new Matrix(), eye, center, up);
};

function Quaternion() {
    quat.identity(this);

    Object.defineProperty(this, 'eulerAngles', {
        get: (function() {
            var _result = new Vector3();

            // Found the implementation at gamedev.stackexchange.com
            // Organizing a Transform class to internally use quaternions.

            return function() {
                var x = this[0];
                var y = this[1];
                var z = this[2];
                var w = this[3];
                var roll = Math.atan2(2*(x*y+z*w),(1-2*(y*y+z*z)));
                var pitch = Math.asin(2*(x*z-w*y));
                var yaw = Math.atan2(2*(x*w+y*z),(1-2*(z*z+w*w)));
                _result.set(pitch,yaw,roll);
                return _result;
            }
        })(),
        set: function(value) {
            var halfPitch = value[0] * 0.5;
            var sinPitch = Math.sin(halfPitch);
            var cosPitch = Math.cos(halfPitch);

            var halfYaw = value[1] * 0.5;
            var sinYaw = Math.sin(halfYaw);
            var cosYaw = Math.cos(halfYaw);

            var halfRoll = value[2] * 0.5;
            var sinRoll = Math.sin(halfRoll);
            var cosRoll = Math.cos(halfRoll);

            this[0] = ((cosYaw * sinPitch) * cosRoll) + ((sinYaw * cosPitch) * sinRoll);
            this[1] = ((sinYaw * cosPitch) * cosRoll) - ((cosYaw * sinPitch) * sinRoll);
            this[2] = ((cosYaw * cosPitch) * sinRoll) - ((sinYaw * sinPitch) * cosRoll);
            this[3] = ((cosYaw * cosPitch) * cosRoll) + ((sinYaw * sinPitch) * sinRoll);
        }
    });
}

Quaternion.prototype = new Float32Array(4);

Quaternion.prototype.rotateX = function(value) {
    return quat.rotateX(this, this, value);
};

Quaternion.prototype.rotateY = function(value) {
    return quat.rotateY(this, this, value);
};

Quaternion.prototype.rotateZ = function(value) {
    return quat.rotateZ(this, this, value);
};

Quaternion.prototype.add = function(value, result) {
    return quat.add(result || new Quaternion(), this, value);
};

Quaternion.prototype.mul = function(value, result) {
    return quat.mul(result || new Quaternion(), this, value);
};

Quaternion.prototype.invert = function(result) {
    return quat.invert(result || new Quaternion(), this);
};

Quaternion.prototype.toString = function() {
    return quat.str(this);
};

module.exports.Vector3 = Vector3;
module.exports.Matrix = Matrix;
module.exports.Quaternion = Quaternion;<|endoftext|>


<commit_before>
//
// Copyright © 2016-present Kary Foundation, Inc. All Rights Reserved
//   Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

//
// ─── IMPORTS ────────────────────────────────────────────────────────────────────
//

    const argv                  = require('yargs').argv
    const darwinInfoPlistBase   = require('./build/darwin-info-base.json')
    const exec                  = require('child_process').exec
    const fs                    = require('fs-extra')
    const gulp                  = require('gulp')
    const less                  = require('less')
    const mv                    = require('mv')
    const packageJson           = require('./package.json')
    const path                  = require('path')
    const plist                 = require('plist')
    const request               = require('request')
    const ugly                  = require('gulp-uglify')
    const util                  = require('util')

//
// ─── CONSTANTS ──────────────────────────────────────────────────────────────────
//

    const version = "v1.0"
    const resultDirPath = '_compiled'
    const nightlyName = 'Orchestra Nightly'

//
// ─── TOOLS ──────────────────────────────────────────────────────────────────────
//

    /** Run shell commands easy! */
    function shell ( command , callback ) {
        return new Promise(( resolve, reject ) => {
            exec( command, err => {
                if ( err )
                    reject( err )
                else
                    resolve( )
            })
        })
    }

//
// ─── COPY DIR FILES ─────────────────────────────────────────────────────────────
//

    /** Copy to binary from dir */
    function copyToBinaryFromDir ( dir, subfolder ) {
        fs.readdir( dir , ( err , files ) => {
            // if error
            if ( err )
                console.log(`Could not get files from directory ${ dir }`)

            // if right
            files.forEach( name => {
                let dest
                if ( !( subfolder === undefined || subfolder === '' || subfolder === null ) )
                    dest = path.join( resultDirPath , subfolder , name )
                else
                    dest = path.join( resultDirPath , name )

                if ( !( name.endsWith('.map') || name.endsWith('.d.ts') ) )
                    copyFile(
                        getLocalPath( path.join( dir , name ) ),
                        getLocalPath( dest )
                    )})})}

//
// ─── COPY SINGLE FILE ───────────────────────────────────────────────────────────
//

    /** Copies a file from `origin` to `destination` */
    async function copyFile ( origin, destination ) {
        if ( /\.DS_Store/.test( origin ) ) { return }

        await new Promise(( resolve, reject ) => {
            fs.copy( origin, destination, err => {
                if ( err )
                    reject(`Could not copy file ${ origin }`)
                else
                    resolve( )
            })
        })
    }

//
// ─── GET LOCAL PATH ─────────────────────────────────────────────────────────────
//

    /** Get Local Path in the current directory */
    function getLocalPath ( address ) {
        return path.join( __dirname , address )
    }

//
// ─── COPY FILES ─────────────────────────────────────────────────────────────────
//

    /** Copies static resource files into the result directory */
    gulp.task( 'copyResourceFiles', callback => {

        function copyNodeModules ( handle ) {
            let address = path.join( 'node_modules', handle )
            copyToBinaryFromDir( address, address )
        }

        // codes
        copyToBinaryFromDir( 'view' )
        copyToBinaryFromDir( 'editor' )
        copyToBinaryFromDir( 'libs' )
        copyToBinaryFromDir( 'windows' )
        copyToBinaryFromDir( 'winserver' )

        // design files
        copyToBinaryFromDir( 'resources' )
        copyToBinaryFromDir( 'designs/icon/file-icon-darwin/icns' )

        // node modules
        copyNodeModules( 'concerto-compiler' )
        copyNodeModules( 'messenger' )
        copyNodeModules( 'regulex' )
        copyNodeModules( 'amdefine' )
        copyNodeModules( 'monaco-editor/min/vs' )
        copyNodeModules( 'regexpu-core' )
        copyNodeModules( 'regexpu' )
        copyNodeModules( 'regjsgen' )
        copyNodeModules( 'regjsparser' )
        copyNodeModules( 'regenerate' )
        copyNodeModules( 'unicode-match-property-ecmascript' )
        copyNodeModules( 'unicode-canonical-property-names-ecmascript' )
        copyNodeModules( 'unicode-property-aliases-ecmascript' )
        copyNodeModules( 'jsesc' )
        copyNodeModules( 'recast' )
        copyNodeModules( 'unicode-match-property-value-ecmascript' )
        copyNodeModules( 'ast-types' )
        copyNodeModules( 'source-map' )
        copyNodeModules( 'esprima' )
        copyNodeModules( 'private' )

        // package
        copyFile(
            getLocalPath( 'package.json' ),
            getLocalPath( path.join( resultDirPath , 'package.json' ) )
        )

        callback()
    })

//
// ─── GETTING COMMIT COUNT ───────────────────────────────────────────────────────
//

    gulp.task( 'get-commit-counts', callback => {
        const commitCountFilePath = `./${resultDirPath}/about/commit-count.txt`
        const githubOrchestraRepositoryAPI =
            'https://api.github.com/repos/karyfoundation/orchestra/stats/contributors'

        try {
            new Promise (( resolve, reject ) => {
                const rejectHandler = ( ) =>
                    reject('Could not connect to GitHub')

                const options = {
                    url: githubOrchestraRepositoryAPI,
                    method: 'GET',
                    headers: {
                        'User-Agent':   'Super Agent/0.0.1',
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                }

                request( options, ( error, response, body ) => {
                    if ( !error && response.statusCode == 200 ) {
                        try {
                            const data = JSON.parse( body )[ 0 ].total.toString( )
                            resolve( data )
                        } catch ( parseError ) {
                            rejectHandler( )
                        }
                    } else {
                        rejectHandler( )
                    }
                })
            })
            .then( GitHubCommitCount => {
                fs.writeFileSync( commitCountFilePath, GitHubCommitCount )
                callback( )
            })
            .catch( e => {
                throw e
            })

        } catch ( error ) {
            try {
                shell( 'git rev-list --all --count > ' + commitCountFilePath )
                callback( )

            } catch ( error2 ) {
                callback('Could not save latest commits count')
            }
        }
    })

//
// ─── SHEETS ─────────────────────────────────────────────────────────────────────
//

    /** Compiles the Less style sheets */
    gulp.task( 'sheets', callback => {
        try {
            let lessSourceCode = fs.readFileSync(
                path.join( __dirname, 'sheets', 'ui.less' ), 'utf8' )

            less.render( lessSourceCode, ( err, output ) => {
                if ( err ) {
                    console.log(`Less failure: ${ err }`); return
                }
                fs.writeFile(
                    path.join( __dirname, '_compiled/style.css' ),
                    output.css,
                    error => {
                        if ( error ) {
                            console.log('could not store the less file')
                        } else {
                            callback()
                        }
                    }
                )
            })
        } catch ( err ) {
            console.log('Compiling less failed ' + err )
        }
    })

//
// ─── ELECTRON PACKER ────────────────────────────────────────────────────────────
//

    async function packOrchestraForDarwin ( ) {
        const iconFile =
            (( packageJson.productName !== nightlyName )
                ? './designs/icon/icns/icon.icns'
                : './designs/icon-nightly/icns/icon.icns'
                )

        // build script
        const packBashScript =
            ( 'electron-packager'
            + ' _compiled "' + packageJson.productName + '"'
            + ' --platform=darwin --arch=x64'
            + ' --overwrite=true'
            + ' --app-bundle-id="org.karyfoundation.orchestra"'
            + ' --app-copyright="Copyright 2016-present, Kary Foundation, Inc. All rights reserved."'
            + ' --app-version="' + packageJson.version + '"'
            + ' --icon=' + iconFile
            + ' --name="' + packageJson.productName + '"'
            + ' --out=_release'
            + ' --protocol="orchestra"'
            + ' --protocol-name="Orchestra"'
        )

        // building
        await shell( packBashScript )
        updateDarwinInfoPlistFile( )
    }

    function updateDarwinInfoPlistFile ( ) {
        // data
        const plistFilePath = (( packageJson.productName !== nightlyName )
            ? '_release/Orchestra-darwin-x64/Orchestra.app/Contents/Info.plist'
            : '_release/Orchestra Nightly-darwin-x64/Orchestra.app/Contents/Info.plist'
        )

        // loading the info file
        const plistFileString =
            fs.readFileSync( plistFilePath, 'utf8' )
        const infoJSON =
            plist.parse( plistFileString )

        // adding stuff to the plist data
        const newInfoJSON =
            Object.assign( infoJSON, darwinInfoPlistBase )

        // making new plist info
        const newPlistFileString =
            plist.build( newInfoJSON )

        // done, now saving it back
        fs.writeFileSync( plistFilePath, newPlistFileString )
    }

    async function createMacDMGImage ( ) {
        const orchestraMacAppAddress =
            " _release/Orchestra-darwin-x64/Orchestra.app"

        fs.mkdirpSync('./_installers/macOS')

        await shell ( 'electron-installer-dmg'
                    + orchestraMacAppAddress
                    + ' Orchestra'
                    + ' --out="./_installers/macOS"'
                    + ' --overwrite'
                    )}

//
// ─── PACK FOR LINUX ─────────────────────────────────────────────────────────────
//

    async function packOrchestraForLinux ( ) {
        // to be continued...
    }

//
// ─── PACK FOR WINDOWS ───────────────────────────────────────────────────────────
//

    async function packOrchestraForWindows ( ) {
        // to be continued...
    }

//
// ─── PACK ───────────────────────────────────────────────────────────────────────
//

    gulp.task( 'pack-orchestra', [ 'copyResourceFiles', 'sheets' ], callback => {
        async function packFunctionBody ( ) {
            if ( argv.debug )
                return await shell( 'npm run electron' )

            if ( argv.pack )
                await buildAllPlatforms( )

            if ( argv.installers )
                await createInstallersForAllPlatforms( )
        }

        packFunctionBody( )
            .then( callback )
            .catch( callback )
    })

//
// ─── BUILD FOR ALL PLATFORMS ────────────────────────────────────────────────────
//

    async function buildAllPlatforms ( ) {
        await runAsyncFunctions([
            packOrchestraForDarwin,
            packOrchestraForLinux,
            packOrchestraForWindows
        ])
    }

//
// ─── CREATE INSTALLERS FOR ALL PLATFORMS ────────────────────────────────────────
//

    async function createInstallersForAllPlatforms ( ) {
        await runAsyncFunctions([
            createMacDMGImage
        ])
    }

//
// ─── RUN MANY ASYNC FUNCTIONS ───────────────────────────────────────────────────
//

    async function runAsyncFunctions ( functions ) {
        await Promise.all( functions.map( func => func( ) ) )
    }

//
// ─── AFTER PACK ─────────────────────────────────────────────────────────────────
//

    gulp.task( 'build-orchestra', [ 'pack-orchestra' ], ( ) => {

    })

//
// ─── MAIN ───────────────────────────────────────────────────────────────────────
//

    /** Where everything starts */
    gulp.task( 'default', [ 'build-orchestra' ])

// ────────────────────────────────────────────────────────────────────────────────
<commit_msg>now making awesome DMG files with great backgronuds and stuff<commit_after>
//
// Copyright © 2016-present Kary Foundation, Inc. All Rights Reserved
//   Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

//
// ─── IMPORTS ────────────────────────────────────────────────────────────────────
//

    const argv                  = require('yargs').argv
    const darwinInfoPlistBase   = require('./build/darwin-info-base.json')
    const exec                  = require('child_process').exec
    const fs                    = require('fs-extra')
    const gulp                  = require('gulp')
    const less                  = require('less')
    const mv                    = require('mv')
    const packageJson           = require('./package.json')
    const path                  = require('path')
    const plist                 = require('plist')
    const request               = require('request')
    const ugly                  = require('gulp-uglify')
    const util                  = require('util')

//
// ─── CONSTANTS ──────────────────────────────────────────────────────────────────
//

    const version = "v1.0"
    const resultDirPath = '_compiled'
    const nightlyName = 'Orchestra Nightly'

//
// ─── TOOLS ──────────────────────────────────────────────────────────────────────
//

    /** Run shell commands easy! */
    function shell ( command , callback ) {
        return new Promise(( resolve, reject ) => {
            exec( command.join(' '), err => {
                if ( err )
                    reject( err )
                else
                    resolve( )
            })})}

//
// ─── COPY DIR FILES ─────────────────────────────────────────────────────────────
//

    /** Copy to binary from dir */
    function copyToBinaryFromDir ( dir, subfolder ) {
        fs.readdir( dir , ( err , files ) => {
            // if error
            if ( err )
                console.log(`Could not get files from directory ${ dir }`)

            // if right
            files.forEach( name => {
                let dest
                if ( !( subfolder === undefined || subfolder === '' || subfolder === null ) )
                    dest = path.join( resultDirPath , subfolder , name )
                else
                    dest = path.join( resultDirPath , name )

                if ( !( name.endsWith('.map') || name.endsWith('.d.ts') ) )
                    copyFile(
                        getLocalPath( path.join( dir , name ) ),
                        getLocalPath( dest )
                    )})})}

//
// ─── COPY SINGLE FILE ───────────────────────────────────────────────────────────
//

    /** Copies a file from `origin` to `destination` */
    async function copyFile ( origin, destination ) {
        if ( /\.DS_Store/.test( origin ) ) { return }

        await new Promise(( resolve, reject ) => {
            fs.copy( origin, destination, err => {
                if ( err )
                    reject(`Could not copy file ${ origin }`)
                else
                    resolve( )
            })
        })
    }

//
// ─── GET LOCAL PATH ─────────────────────────────────────────────────────────────
//

    /** Get Local Path in the current directory */
    function getLocalPath ( address ) {
        return path.join( __dirname , address )
    }

//
// ─── COPY FILES ─────────────────────────────────────────────────────────────────
//

    /** Copies static resource files into the result directory */
    gulp.task( 'copyResourceFiles', callback => {

        function copyNodeModules ( handle ) {
            let address = path.join( 'node_modules', handle )
            copyToBinaryFromDir( address, address )
        }

        // codes
        copyToBinaryFromDir( 'view' )
        copyToBinaryFromDir( 'editor' )
        copyToBinaryFromDir( 'libs' )
        copyToBinaryFromDir( 'windows' )
        copyToBinaryFromDir( 'winserver' )

        // design files
        copyToBinaryFromDir( 'resources' )
        copyToBinaryFromDir( 'designs/icon/file-icon-darwin/icns' )

        // node modules
        copyNodeModules( 'concerto-compiler' )
        copyNodeModules( 'messenger' )
        copyNodeModules( 'regulex' )
        copyNodeModules( 'amdefine' )
        copyNodeModules( 'monaco-editor/min/vs' )
        copyNodeModules( 'regexpu-core' )
        copyNodeModules( 'regexpu' )
        copyNodeModules( 'regjsgen' )
        copyNodeModules( 'regjsparser' )
        copyNodeModules( 'regenerate' )
        copyNodeModules( 'unicode-match-property-ecmascript' )
        copyNodeModules( 'unicode-canonical-property-names-ecmascript' )
        copyNodeModules( 'unicode-property-aliases-ecmascript' )
        copyNodeModules( 'jsesc' )
        copyNodeModules( 'recast' )
        copyNodeModules( 'unicode-match-property-value-ecmascript' )
        copyNodeModules( 'ast-types' )
        copyNodeModules( 'source-map' )
        copyNodeModules( 'esprima' )
        copyNodeModules( 'private' )

        // package
        copyFile(
            getLocalPath( 'package.json' ),
            getLocalPath( path.join( resultDirPath , 'package.json' ) )
        )

        callback()
    })

//
// ─── GETTING COMMIT COUNT ───────────────────────────────────────────────────────
//

    gulp.task( 'get-commit-counts', callback => {
        const commitCountFilePath = `./${resultDirPath}/about/commit-count.txt`
        const githubOrchestraRepositoryAPI =
            'https://api.github.com/repos/karyfoundation/orchestra/stats/contributors'

        try {
            new Promise (( resolve, reject ) => {
                const rejectHandler = ( ) =>
                    reject('Could not connect to GitHub')

                const options = {
                    url: githubOrchestraRepositoryAPI,
                    method: 'GET',
                    headers: {
                        'User-Agent':   'Super Agent/0.0.1',
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                }

                request( options, ( error, response, body ) => {
                    if ( !error && response.statusCode == 200 ) {
                        try {
                            const data = JSON.parse( body )[ 0 ].total.toString( )
                            resolve( data )
                        } catch ( parseError ) {
                            rejectHandler( )
                        }
                    } else {
                        rejectHandler( )
                    }
                })
            })
            .then( GitHubCommitCount => {
                fs.writeFileSync( commitCountFilePath, GitHubCommitCount )
                callback( )
            })
            .catch( e => {
                throw e
            })

        } catch ( error ) {
            try {
                shell([ 'git', 'rev-list', '--all', '--count',
                        '>', commitCountFilePath ])
                callback( )

            } catch ( error2 ) {
                callback('Could not save latest commits count')
            }
        }
    })

//
// ─── SHEETS ─────────────────────────────────────────────────────────────────────
//

    /** Compiles the Less style sheets */
    gulp.task( 'sheets', callback => {
        try {
            let lessSourceCode = fs.readFileSync(
                path.join( __dirname, 'sheets', 'ui.less' ), 'utf8' )

            less.render( lessSourceCode, ( err, output ) => {
                if ( err ) {
                    console.log(`Less failure: ${ err }`); return
                }
                fs.writeFile(
                    path.join( __dirname, '_compiled/style.css' ),
                    output.css,
                    error => {
                        if ( error ) {
                            console.log('could not store the less file')
                        } else {
                            callback( )
                        }
                    }
                )
            })
        } catch ( err ) {
            console.log('Compiling less failed ' + err )
        }
    })

//
// ─── ELECTRON PACKER ────────────────────────────────────────────────────────────
//

    async function packOrchestraForDarwin ( ) {
        const iconFile =
            (( packageJson.productName !== nightlyName )
                ? './designs/icon/icns/icon.icns'
                : './designs/icon-nightly/icns/icon.icns'
                )

        // build script
        const packBashScript = [
            'electron-packager',
            ' _compiled',
            '"' + packageJson.productName + '"',
            '--platform=darwin',
            '--arch=x64',
            '--overwrite=true',
            '--app-bundle-id="org.karyfoundation.orchestra"',
            '--app-copyright="Copyright 2016-present, Kary Foundation, Inc. All rights reserved."',
            '--app-version="' + packageJson.version + '"',
            '--icon=' + iconFile,
            '--name="' + packageJson.productName + '"',
            '--out=_release',
            '--protocol="orchestra"',
            '--protocol-name="Orchestra"',
        ]

        // building
        await shell( packBashScript )
        updateDarwinInfoPlistFile( )
    }

    function updateDarwinInfoPlistFile ( ) {
        // data
        const plistFilePath = (( packageJson.productName !== nightlyName )
            ? '_release/Orchestra-darwin-x64/Orchestra.app/Contents/Info.plist'
            : '_release/Orchestra Nightly-darwin-x64/Orchestra.app/Contents/Info.plist'
        )

        // loading the info file
        const plistFileString =
            fs.readFileSync( plistFilePath, 'utf8' )
        const infoJSON =
            plist.parse( plistFileString )

        // adding stuff to the plist data
        const newInfoJSON =
            Object.assign( infoJSON, darwinInfoPlistBase )

        // making new plist info
        const newPlistFileString =
            plist.build( newInfoJSON )

        // done, now saving it back
        fs.writeFileSync( plistFilePath, newPlistFileString )
    }

    async function createMacDMGImage ( ) {
        const orchestraMacAppAddress =
            "_release/Orchestra-darwin-x64/Orchestra.app"

        fs.mkdirpSync('./_installers/macOS')

        await shell([
            'electron-installer-dmg',
            orchestraMacAppAddress,
            'Orchestra',
            '--out="./_installers/macOS"',
            '--icon-size=152',
            '--icon="./designs/icon/icns/icon.icns"',
            '--background="./build/dmg-back.png"',
            '--overwrite'
        ])
    }

//
// ─── PACK FOR LINUX ─────────────────────────────────────────────────────────────
//

    async function packOrchestraForLinux ( ) {
        // to be continued...
    }

//
// ─── PACK FOR WINDOWS ───────────────────────────────────────────────────────────
//

    async function packOrchestraForWindows ( ) {
        // to be continued...
    }

//
// ─── PACK ───────────────────────────────────────────────────────────────────────
//

    gulp.task( 'pack-orchestra', [ 'copyResourceFiles', 'sheets' ], callback => {
        async function packFunctionBody ( ) {
            if ( argv.debug )
                return await shell([ 'npm', 'run', 'electron' ])

            if ( argv.pack )
                await buildAllPlatforms( )

            if ( argv.installers )
                await createInstallersForAllPlatforms( )
        }

        packFunctionBody( )
            .then( callback )
            .catch( callback )
    })

//
// ─── BUILD FOR ALL PLATFORMS ────────────────────────────────────────────────────
//

    async function buildAllPlatforms ( ) {
        await runAsyncFunctions([
            packOrchestraForDarwin,
            packOrchestraForLinux,
            packOrchestraForWindows
        ])
    }

//
// ─── CREATE INSTALLERS FOR ALL PLATFORMS ────────────────────────────────────────
//

    async function createInstallersForAllPlatforms ( ) {
        await runAsyncFunctions([
            createMacDMGImage
        ])
    }

//
// ─── RUN MANY ASYNC FUNCTIONS ───────────────────────────────────────────────────
//

    async function runAsyncFunctions ( functions ) {
        await Promise.all( functions.map( func => func( ) ) )
    }

//
// ─── AFTER PACK ─────────────────────────────────────────────────────────────────
//

    gulp.task( 'build-orchestra', [ 'pack-orchestra' ], ( ) => {

    })

//
// ─── MAIN ───────────────────────────────────────────────────────────────────────
//

    /** Where everything starts */
    gulp.task( 'default', [ 'build-orchestra' ])

// ────────────────────────────────────────────────────────────────────────────────
<|endoftext|>


<commit_before>'use strict';

var config = require('./util/config'),
    log = require('./util/logger'),
    path = require('path'),
    url = require('url');

function createPaths() {
    var routes = config.routes,
        connect = require('connect'),
        keys = config.routes ? Object.keys(routes).sort(function (a, b) {
            return b.length - a.length;
        }) : [],
        paths = [],
        proxyMiddleware = require('./proxy/proxy-middleware');

    for (var i = 0; i < keys.length; i++) {
        var endpoints = routes[keys[i]],
            functions = [];

        if (typeof endpoints === 'string') {
            var options = url.parse(endpoints);
            if (options.host) {
                functions.push((function(options) {
                    options.route = keys[i];
                    var proxyHandler = proxyMiddleware(options);
                    return function(req, res, next) {
                        var end = res.end;

                        res.end = function() {
                            log.verbose.http(res.statusCode, path.normalize(options.protocol + '//' + options.host + req.url) + ' (' + req.url + ')');
                            return end.apply(this,arguments);
                        };

                        proxyHandler(req, res, function() {
                            next();
                        });
                    };
                })(options));
            } else {
                functions.push((function() {
                    var dir = path.resolve(path.normalize(endpoints)),
                        route = keys[i],
                        staticHandler = connect.static(dir);

                    return function(req, res, next) {
                        var end = res.end,
                            originalUrl = req.url,
                            modifiedUrl;

                        res.end = function() {
                            log.verbose.http(res.statusCode, path.normalize(dir + '/' + modifiedUrl) + ' (' + req.url + ')');
                            return end.apply(this,arguments);
                        };

                        modifiedUrl = req.url = req.url.replace(route, '') || req.url;

                        res.on('error', function(err) {
                            next(err);
                        });

                        staticHandler(req, res, function() {
                            req.url = originalUrl;
                            next();
                        });
                    };
                })());
            }
        }

        paths.push({path: keys[i], functions: functions});
    }

    return paths;
}

module.exports = function (newConfig) {
    config(newConfig);

    var paths = createPaths();

    return function (req, res, next) {
        req.url = path.normalize(req.url);

        var pathname = url.parse(req.url).pathname;

        for (var i = 0; i < paths.length; i++) {
            if (pathname.indexOf(paths[i].path) === 0) {
                paths[i].functions[0](req, res, next);
                return;
            }
        }

        next();
    };
};
<commit_msg>Update proxy lib name.<commit_after>'use strict';

var config = require('./util/config'),
    log = require('./util/logger'),
    path = require('path'),
    url = require('url');

function createPaths() {
    var routes = config.routes,
        connect = require('connect'),
        keys = config.routes ? Object.keys(routes).sort(function (a, b) {
            return b.length - a.length;
        }) : [],
        paths = [],
        proxyMiddleware = require('./proxy/proxy');

    for (var i = 0; i < keys.length; i++) {
        var endpoints = routes[keys[i]],
            functions = [];

        if (typeof endpoints === 'string') {
            var options = url.parse(endpoints);
            if (options.host) {
                functions.push((function(options) {
                    options.route = keys[i];
                    var proxyHandler = proxyMiddleware(options);
                    return function(req, res, next) {
                        var end = res.end;

                        res.end = function() {
                            log.verbose.http(res.statusCode, path.normalize(options.protocol + '//' + options.host + req.url) + ' (' + req.url + ')');
                            return end.apply(this,arguments);
                        };

                        proxyHandler(req, res, function() {
                            next();
                        });
                    };
                })(options));
            } else {
                functions.push((function() {
                    var dir = path.resolve(path.normalize(endpoints)),
                        route = keys[i],
                        staticHandler = connect.static(dir);

                    return function(req, res, next) {
                        var end = res.end,
                            originalUrl = req.url,
                            modifiedUrl;

                        res.end = function() {
                            log.verbose.http(res.statusCode, path.normalize(dir + '/' + modifiedUrl) + ' (' + req.url + ')');
                            return end.apply(this,arguments);
                        };

                        modifiedUrl = req.url = req.url.replace(route, '') || req.url;

                        res.on('error', function(err) {
                            next(err);
                        });

                        staticHandler(req, res, function() {
                            req.url = originalUrl;
                            next();
                        });
                    };
                })());
            }
        }

        paths.push({path: keys[i], functions: functions});
    }

    return paths;
}

module.exports = function (newConfig) {
    config(newConfig);

    var paths = createPaths();

    return function (req, res, next) {
        req.url = path.normalize(req.url);

        var pathname = url.parse(req.url).pathname;

        for (var i = 0; i < paths.length; i++) {
            if (pathname.indexOf(paths[i].path) === 0) {
                paths[i].functions[0](req, res, next);
                return;
            }
        }

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


<commit_before>'use strict';

var browsersync = require('browser-sync').create(),
    gulp        = require('gulp'),
    autoprefixer= require('gulp-autoprefixer'),
    cleancss    = require('gulp-clean-css'),
    concat      = require('gulp-concat'),
    csscomb     = require('gulp-csscomb'),
    imagemin    = require('gulp-imagemin'),
    csslint     = require('gulp-csslint'),
    jshint      = require('gulp-jshint'),
    rename      = require('gulp-rename'),
    sass        = require('gulp-sass'),
    sourcemaps  = require('gulp-sourcemaps'),
    uglify      = require('gulp-uglify');

var noop        = require("through2").obj();

/**
 *  Config
 */

var paths = {
    src: {
        root:       './src',
        html:       { folder: '.',          extensions: ['*.html', '*.htm']},
        style:      { folder: 'scss',       extensions: ['*.scss', '*.sass', '*.css'] },
        scripts:    { folder: 'scripts',    extensions: ['*.js'] },
        images:     { folder: 'images',     extensions: ['*.png', '*.jpg', '*.jpeg', '*.gif', '*.svg'] },
        fonts:      { folder: 'fonts',      extensions: ['*.ttf', '*.eot', '*.otf', '*.woff', '*.woff2'] },
    },
    dest: {
        root:       './dist',
        html:       { folder: '.',          extensions: ['*.html', '*.htm']},
        style:      { folder: 'css',        extensions: ['*.css'] },
        scripts:    { folder: 'js',         extensions: ['*.js'] },
        images:     { folder: 'images',     extensions: ['*.png', '*.jpg', '*.jpeg', '*.gif', '*.svg'] },
        fonts:      { folder: 'fonts',      extensions: ['*.ttf', '*.eot', '*.otf', '*.woff', '*.woff2'] },
    }
};

var plugins = {
    browsersync: false,
    html: {},
    style: {
        run: {
            sass: true,
            cleancss: true,
            autoprefixer: true,
            csscomb: true,
            csslint: true,
            sourcemaps: true
        },
        sass: {
            options: {
                includePaths: []
            },
            onError: sass.logError
        },
        cleancss: {
            options: {
                compatibility: 'ie8',
                inline: ['local', 'remote', '!fonts.googleapis.com'],
                level: 2
            },
            callback: (details) => {
                console.log('\t' + details.name + ' => ' + details.stats.originalSize);
                console.log('\t' + details.name + '    ' + (details.stats.minifiedSize - details.stats.originalSize));
                console.log('\t' + details.name + ' => ' + details.stats.minifiedSize);
            }
        },
        autoprefixer: {
            options: {
                browsers: ['> 1%', 'last 2 versions']
            }
        },
        csscomb: {},
        csslint: {},
        sourcemaps: {
            options: {},
            writeOptions: {},
            writePath: './'
        },
        concat: {
            name: 'app.css'
        },
        rename: {
            basename: 'app'
        }
    },
    scripts: {
        run: {
            jshint: true,
            uglify: true,
            sourcemaps: true
        },
        jshint: {
            reporter: 'default'
        },
        sourcemaps: {
            options: {},
            writeOptions: {},
            writePath: './'
        },
        concat: {
            name: 'app.js'
        },
        rename: {
            basename: 'app'
        }
    },
    images: {
        run: {
            imagemin: true
        },
        imagemin: {
            options: {
                interlaced: true,
                progressive: true,
                optimizationLevel: 5,
                svgoPlugins: [{ removeViewBox: true }]
            }
        }
    },
    fonts: {},
    serve: {
        options: {
            server: paths.dest.root
        }
    }
};

/**
 *  Utils
 */

function getExtensions(path, root) {
    return path.extensions.map((extension) => {
        return root + '/' + path.folder + '/**/' + extension;
    });
};

/**
 *  HTML
 */

gulp.task('html', () => {
    var $ = plugins.html;

    return gulp.src(getExtensions(paths.src.html, paths.src.root))
        .pipe(gulp.dest(paths.dest.root + '/' + paths.dest.html.folder));
});

/**
 *  Style
 */

gulp.task('style', () => {
    var $ = plugins.style;

    return gulp.src(getExtensions(paths.src.style, paths.src.root))
        .pipe($.run.sourcemaps && $.run.sass ? sourcemaps.init($.sourcemaps.options) : noop)
        .pipe($.run.sass ? sass($.sass.options).on('error', $.sass.onError) : noop)
        .pipe($.run.sass ? concat($.concat.name) : noop)
        .pipe($.run.autoprefixer && $.run.sass ? autoprefixer($.autoprefixer.options) : noop)
        .pipe($.run.csscomb && $.run.sass ? csscomb($.csscomb.options) : noop)
        .pipe($.run.csslint && $.run.sass ? csslint($.csslint.options) : noop)
        .pipe($.run.csslint && $.run.sass ? csslint.formatter($.csslint.formatterOptions) : noop)
        .pipe($.run.sass ? gulp.dest(paths.dest.root + '/' + paths.dest.style.folder) : noop)
        .pipe($.run.cleancss && $.run.sass ? rename({ suffix: '.min', basename: $.rename.basename }) : noop)
        .pipe($.run.cleancss && $.run.sass ? cleancss($.cleancss.options, $.cleancss.callback) : noop)
        .pipe($.run.sourcemaps && $.run.sass ? sourcemaps.write($.sourcemaps.writePath, $.sourcemaps.writeOptions) : noop)
        .pipe(gulp.dest(paths.dest.root + '/' + paths.dest.style.folder))
        .pipe(plugins.browsersync ? browsersync.stream() : noop);
});

/**
 *  Scripts
 */

gulp.task('scripts', () => {
    var $ = plugins.scripts;

    return gulp.src(getExtensions(paths.src.scripts, paths.src.root))
        .pipe($.run.jshint ? jshint() : noop)
        .pipe($.run.jshint ? jshint.reporter($.jshint.reporter) : noop)
        .pipe($.run.sourcemaps && $.run.uglify ? sourcemaps.init($.sourcemaps.options) : noop)
        .pipe(concat($.concat.name))
        .pipe(gulp.dest(paths.dest.root + '/' + paths.dest.scripts.folder))
        .pipe($.run.uglify ? uglify() : noop)
        .pipe($.run.uglify ? rename({ suffix: '.min', basename: $.rename.basename }) : noop)
        .pipe($.run.sourcemaps && $.run.uglify ? sourcemaps.write($.sourcemaps.writePath, $.sourcemaps.writeOptions) : noop)
        .pipe(gulp.dest(paths.dest.root + '/' + paths.dest.scripts.folder))
        .pipe(plugins.browsersync ? browsersync.stream() : noop);
});

/**
 *  Images
 */

gulp.task('images', () => {
    var $ = plugins.images;

    return gulp.src(getExtensions(paths.src.images, paths.root))
        .pipe($.run.imagemin ? imagemin($.imagemin.options) : noop)
        .pipe(gulp.dest(paths.dest.root + '/' + paths.dest.images.folder))
        .pipe(plugins.browsersync ? browsersync.stream() : noop);
});

/**
 *  Fonts
 */

gulp.task('fonts', () => {
    var $ = plugins.fonts;

    return gulp.src(getExtensions(paths.src.fonts, paths.src.root))
        .pipe(gulp.dest(gulp.dest.root + '/' + paths.dest.fonts.folder))
        .pipe(plugins.browsersync ? browsersync.stream() : noop);
});

/**
 *  Default (build all)
 */

gulp.task('default', ['html', 'style', 'scripts', 'images', 'fonts']);

/**
 *  Serve
 */

gulp.task('serve', ['default'], () => {
    var $ = plugins.serve;

    browsersync.init($.options);

    plugins.browsersync = true;

    gulp.watch(getExtensions(paths.src.html,    paths.src.root), ['html']);
    gulp.watch(getExtensions(paths.src.style,   paths.src.root), ['style']);
    gulp.watch(getExtensions(paths.src.scripts, paths.src.root), ['scripts']);
    gulp.watch(getExtensions(paths.src.images,  paths.src.root), ['images']);
    gulp.watch(getExtensions(paths.src.fonts,   paths.src.root), ['fonts']);
    gulp.watch(getExtensions(paths.dest.html,   paths.dest.root)).on('change', browsersync.reload);
});
<commit_msg>Change browsersync default config<commit_after>'use strict';

var browsersync = require('browser-sync').create(),
    gulp        = require('gulp'),
    autoprefixer= require('gulp-autoprefixer'),
    cleancss    = require('gulp-clean-css'),
    concat      = require('gulp-concat'),
    csscomb     = require('gulp-csscomb'),
    imagemin    = require('gulp-imagemin'),
    csslint     = require('gulp-csslint'),
    jshint      = require('gulp-jshint'),
    rename      = require('gulp-rename'),
    sass        = require('gulp-sass'),
    sourcemaps  = require('gulp-sourcemaps'),
    uglify      = require('gulp-uglify');

var noop        = require("through2").obj();

/**
 *  Config
 */

var paths = {
    src: {
        root:       './src',
        html:       { folder: '.',          extensions: ['*.html', '*.htm']},
        style:      { folder: 'scss',       extensions: ['*.scss', '*.sass', '*.css'] },
        scripts:    { folder: 'scripts',    extensions: ['*.js'] },
        images:     { folder: 'images',     extensions: ['*.png', '*.jpg', '*.jpeg', '*.gif', '*.svg'] },
        fonts:      { folder: 'fonts',      extensions: ['*.ttf', '*.eot', '*.otf', '*.woff', '*.woff2'] },
    },
    dest: {
        root:       './dist',
        html:       { folder: '.',          extensions: ['*.html', '*.htm']},
        style:      { folder: 'css',        extensions: ['*.css'] },
        scripts:    { folder: 'js',         extensions: ['*.js'] },
        images:     { folder: 'images',     extensions: ['*.png', '*.jpg', '*.jpeg', '*.gif', '*.svg'] },
        fonts:      { folder: 'fonts',      extensions: ['*.ttf', '*.eot', '*.otf', '*.woff', '*.woff2'] },
    }
};

var plugins = {
    browsersync: false,
    html: {},
    style: {
        run: {
            sass: true,
            cleancss: true,
            autoprefixer: true,
            csscomb: true,
            csslint: true,
            sourcemaps: true
        },
        sass: {
            options: {
                includePaths: []
            },
            onError: sass.logError
        },
        cleancss: {
            options: {
                compatibility: 'ie8',
                inline: ['local', 'remote', '!fonts.googleapis.com'],
                level: 2
            },
            callback: (details) => {
                console.log('\t' + details.name + ' => ' + details.stats.originalSize);
                console.log('\t' + details.name + '    ' + (details.stats.minifiedSize - details.stats.originalSize));
                console.log('\t' + details.name + ' => ' + details.stats.minifiedSize);
            }
        },
        autoprefixer: {
            options: {
                browsers: ['> 1%', 'last 2 versions']
            }
        },
        csscomb: {},
        csslint: {},
        sourcemaps: {
            options: {},
            writeOptions: {},
            writePath: './'
        },
        concat: {
            name: 'app.css'
        },
        rename: {
            basename: 'app'
        }
    },
    scripts: {
        run: {
            jshint: true,
            uglify: true,
            sourcemaps: true
        },
        jshint: {
            reporter: 'default'
        },
        sourcemaps: {
            options: {},
            writeOptions: {},
            writePath: './'
        },
        concat: {
            name: 'app.js'
        },
        rename: {
            basename: 'app'
        }
    },
    images: {
        run: {
            imagemin: true
        },
        imagemin: {
            options: {
                interlaced: true,
                progressive: true,
                optimizationLevel: 5,
                svgoPlugins: [{ removeViewBox: true }]
            }
        }
    },
    fonts: {},
    serve: {
        options: {
            server: paths.dest.root,
            ghostMode: false,
            logFileChanges: false,
            reloadOnRestart: true,
            notify: false
        }
    }
};

/**
 *  Utils
 */

function getExtensions(path, root) {
    return path.extensions.map((extension) => {
        return root + '/' + path.folder + '/**/' + extension;
    });
};

/**
 *  HTML
 */

gulp.task('html', () => {
    var $ = plugins.html;

    return gulp.src(getExtensions(paths.src.html, paths.src.root))
        .pipe(gulp.dest(paths.dest.root + '/' + paths.dest.html.folder));
});

/**
 *  Style
 */

gulp.task('style', () => {
    var $ = plugins.style;

    return gulp.src(getExtensions(paths.src.style, paths.src.root))
        .pipe($.run.sourcemaps && $.run.sass ? sourcemaps.init($.sourcemaps.options) : noop)
        .pipe($.run.sass ? sass($.sass.options).on('error', $.sass.onError) : noop)
        .pipe($.run.sass ? concat($.concat.name) : noop)
        .pipe($.run.autoprefixer && $.run.sass ? autoprefixer($.autoprefixer.options) : noop)
        .pipe($.run.csscomb && $.run.sass ? csscomb($.csscomb.options) : noop)
        .pipe($.run.csslint && $.run.sass ? csslint($.csslint.options) : noop)
        .pipe($.run.csslint && $.run.sass ? csslint.formatter($.csslint.formatterOptions) : noop)
        .pipe($.run.sass ? gulp.dest(paths.dest.root + '/' + paths.dest.style.folder) : noop)
        .pipe($.run.cleancss && $.run.sass ? rename({ suffix: '.min', basename: $.rename.basename }) : noop)
        .pipe($.run.cleancss && $.run.sass ? cleancss($.cleancss.options, $.cleancss.callback) : noop)
        .pipe($.run.sourcemaps && $.run.sass ? sourcemaps.write($.sourcemaps.writePath, $.sourcemaps.writeOptions) : noop)
        .pipe(gulp.dest(paths.dest.root + '/' + paths.dest.style.folder))
        .pipe(plugins.browsersync ? browsersync.stream() : noop);
});

/**
 *  Scripts
 */

gulp.task('scripts', () => {
    var $ = plugins.scripts;

    return gulp.src(getExtensions(paths.src.scripts, paths.src.root))
        .pipe($.run.jshint ? jshint() : noop)
        .pipe($.run.jshint ? jshint.reporter($.jshint.reporter) : noop)
        .pipe($.run.sourcemaps && $.run.uglify ? sourcemaps.init($.sourcemaps.options) : noop)
        .pipe(concat($.concat.name))
        .pipe(gulp.dest(paths.dest.root + '/' + paths.dest.scripts.folder))
        .pipe($.run.uglify ? uglify() : noop)
        .pipe($.run.uglify ? rename({ suffix: '.min', basename: $.rename.basename }) : noop)
        .pipe($.run.sourcemaps && $.run.uglify ? sourcemaps.write($.sourcemaps.writePath, $.sourcemaps.writeOptions) : noop)
        .pipe(gulp.dest(paths.dest.root + '/' + paths.dest.scripts.folder))
        .pipe(plugins.browsersync ? browsersync.stream() : noop);
});

/**
 *  Images
 */

gulp.task('images', () => {
    var $ = plugins.images;

    return gulp.src(getExtensions(paths.src.images, paths.root))
        .pipe($.run.imagemin ? imagemin($.imagemin.options) : noop)
        .pipe(gulp.dest(paths.dest.root + '/' + paths.dest.images.folder))
        .pipe(plugins.browsersync ? browsersync.stream() : noop);
});

/**
 *  Fonts
 */

gulp.task('fonts', () => {
    var $ = plugins.fonts;

    return gulp.src(getExtensions(paths.src.fonts, paths.src.root))
        .pipe(gulp.dest(gulp.dest.root + '/' + paths.dest.fonts.folder))
        .pipe(plugins.browsersync ? browsersync.stream() : noop);
});

/**
 *  Default (build all)
 */

gulp.task('default', ['html', 'style', 'scripts', 'images', 'fonts']);

/**
 *  Serve
 */

gulp.task('serve', ['default'], () => {
    var $ = plugins.serve;

    browsersync.init($.options);

    plugins.browsersync = true;

    gulp.watch(getExtensions(paths.src.html,    paths.src.root), ['html']);
    gulp.watch(getExtensions(paths.src.style,   paths.src.root), ['style']);
    gulp.watch(getExtensions(paths.src.scripts, paths.src.root), ['scripts']);
    gulp.watch(getExtensions(paths.src.images,  paths.src.root), ['images']);
    gulp.watch(getExtensions(paths.src.fonts,   paths.src.root), ['fonts']);
    gulp.watch(getExtensions(paths.dest.html,   paths.dest.root)).on('change', browsersync.reload);
});
<|endoftext|>


<commit_before>'use strict';

angular.module('logincontroller', [])

.controller('LoginCtrl', function($scope) {
        $scope.login = function(user) {
            console.log(user);
            console.log($scope)
        };
});<commit_msg>Go to home after login button<commit_after>'use strict';

angular.module('logincontroller', [])

.controller('LoginCtrl', function($scope, $state) {
        $scope.login = function(user) {
            // Should probably log in here?
            $state.go('home')
        };
});<|endoftext|>