<commit_before>define(['jquery', 'plugins/typeahead'], function($) {

    !function($) {

        "use strict";

        var Typeselect = function(element, datasets, options) {
            if (typeof options === "undefined")
                options = {};

            this.options = $.extend({}, $.fn.typeselect.defaults, options);

            this.selectedDatums = {};
            this.selectedItems = {};
            this.datasetsByName = {};
            // Begin hack to fix caching issue
            this.urlToDatasetMap = {};
            // End hack to fix caching issue

            var createFilter = function(name, valueKey, filter, selectedDatums) {
                return function(parsedResponse){
                    var datums = filter ? filter(parsedResponse) : parsedResponse;
                    var filtered = $.map(datums, function(datum, index){
                         if (selectedDatums[datum[valueKey]]) return null;
                         else return datum;
                    });
                    return filtered;
                };
            };

            // Support multiple targets based on dataset
            if (!$.isArray(datasets)) datasets = [datasets];

            // Setup stores for selected item targets
            this.$targetsMap = {};
            if (this.options.target)
                this.$defaultTarget = $(this.options.target);

            // Save datasets off for our use later
            this.dataset = datasets;

            // Find all targets for each dataset and modify
            // modify filter attributes so we can remove
            // selected items from future suggestions
            $.each(datasets, $.proxy(function(index, dataset) {
                var valueKey = dataset.valueKey || 'value', dataset_name = dataset.name;
                if (dataset.target) this.$targetsMap[dataset.name] = $(dataset.target);
                if (typeof dataset.remote === 'string' || dataset.remote instanceof String)
                    dataset.remote = {url: dataset.remote};
                this.selectedDatums[dataset_name] = {};

                if (dataset.remote){
                    // Begin hack to fix caching issue
                    this.urlToDatasetMap[dataset.remote.url.replace(/\W/g,'_')] = dataset_name;
                    dataset.name = dataset.remote.url.replace(/\W/g,'_');
                    // End hack to fix caching issue
                    dataset.remote.filter = createFilter(dataset_name, valueKey,
                        dataset.remote.filter, this.selectedDatums[dataset_name]);
                }
                // TODO this cache will containt
                // be the swapped out dataset.name if we did that above
                this.selectedItems[dataset_name] = {};
                this.datasetsByName[dataset_name] = dataset;

                if (dataset.selected)
                    this.prePopulate(dataset.selected, dataset_name);
            }, this));

            // Initialize with twitter (not bootstrap) typeahead
            this.$element = $(element).typeahead(datasets);

            this.$element.on('typeahead:selected', $.proxy(function(event, datum, dataset_name){
                 this.add(datum, dataset_name);
                 // Clear out the textbox
                 this.$element.blur();
                 this.$element.val('');
            }, this));

            this.listen();
        };

        Typeselect.prototype = {

            constructor: Typeselect,

            destroy: function(){
                this.$element.typeahead('destroy');
            },

            listen: function() {
                var targets = [];
                $.each(this.$targetsMap, $.proxy(function(name, $target){
                    if (~$.inArray($target, targets)) return true;
                    $target.on('click', '.close', $.proxy(this.click, this));
                    targets.push($target);
                }, this));

                if (this.$defaultTarget && !$.inArray(targets, this.$defaultTarget))
                    $defaultTarget.on('click', '.close', $.proxy(this.click, this));
            },

            add: function(value, dataset_name) {
                // dataset_name parameter is optional
                // Use first supplied dataset by default
                if (typeof dataset_name === "undefined")
                    dataset_name = this.options.dataset || this.datasets[0].name;
                // Begin hack to fix caching issue
                if (this.urlToDatasetMap.hasOwnProperty(dataset_name))
                    dataset_name = this.urlToDatasetMap[dataset_name]
                // End hack to fix caching issue
                var template, item, $target;
                var dataset = this.datasetsByName[dataset_name];
                var valueKey = dataset.valueKey || "value";
                // Do not add redundant values
                if (this.selectedDatums[dataset_name][value[valueKey]]) return;
                this.selectedDatums[dataset_name][value[valueKey]] = value;

                // Render
                if (dataset.selectedTemplate){
                    if (!$.isFunction(dataset.selectedTemplate))
                        template = dataset.engine.compile(dataset.selectedTemplate);
                    else
                        template = dataset.selectedTemplate;
                    item = $(template.render(value))
                        .attr('data-value', value[valueKey])
                        .attr('data-dataset', dataset_name);
                } else {
                    // default list item with remove icon
                    item = $(this.options.selectedItem)
                        .text(value[valueKey])
                        .attr('data-value', value[valueKey])
                        .attr('data-dataset', dataset_name)
                        .append('×');
                }

                this.selectedItems[dataset_name][value[valueKey]] = item;

                // Add to the target container
                if ($target = this.$targetsMap[dataset_name]){
                    $target.append(item);
                } else {
                    // Use default target
                    this.$defaultTarget.append(item);
                }
            },

            remove: function(value, dataset_name) {
                // dataset_name parameter is optional
                // Use first supplied dataset by default
                if (typeof dataset_name === "undefined")
                    dataset_name = this.options.dataset || this.datasets[0].name;

                // Begin hack to fix caching issue
                if (this.urlToDatasetMap.hasOwnProperty(dataset_name))
                    dataset_name = this.urlToDatasetMap[dataset_name]
                // End hack to fix caching issue

                var valueKey = this.datasetsByName[dataset_name].valueKey || 'value',
                    item;

                // Remove from the selected cache
                if (this.selectedDatums[dataset_name][value])
                    delete this.selectedDatums[dataset_name][value];

                // Remove element from DOM element cache
                if (item = this.selectedItems[dataset_name][value]){
                   delete this.selectedItems[dataset_name][value];
                   item.remove();
                }
            },

            click: function(event) {
                event.preventDefault();
                var $parent = $(event.target).parent();
                this.remove($parent.attr('data-value'), $parent.attr('data-dataset'));
            },

            selected: function(groupByDataset){
                if (groupByDataset)
                    return this.selectedDatums;
                // Flatten
                return $.map(this.selectedDatums, function(key, dataset){
                    return $.map(dataset, function(key, datum){
                        return datum;
                    });
                });
            },

            prePopulate: function(selectedDatums, dataset_name){
                var index;
                if (!$.isArray(selectedDatums))
                    selectedDatums = [selectedDatums];
                for (index = 0; index < selectedDatums.length; index++)
                    this.add(selectedDatums[index], dataset_name);
            }

        };

        $.fn.typeselect = function(option, defaults) {
            return this.each(function() {
                var $this = $(this),
                   data = $this.data('typeselect'),
                   datasets = option;
                if (!data) $this.data('typeselect', (data = new Typeselect(this, datasets, defaults)));
                if (typeof option === 'string') data[option]();
            });
        };

        $.fn.typeselect.defaults = {
            selected: [],
            selectedItem: '

'
        };

        $.fn.typeselect.Constructor = Typeselect;

        /* TYPESELECT DATA-API
         * =================== */
        $(document).on('focus.typeselect.data-api', '[data-provide="typeselect"]', function(e) {
            var $this = $(this);
            if ($this.data('typeselect')) return;
            e.preventDefault();
            $this.typeselect($this.data());
        });
    }($);
});
<commit_msg>Fix URL escape for dataset.name<commit_after>define(['jquery', 'plugins/typeahead'], function($) {

    !function($) {

        "use strict";

        var Typeselect = function(element, datasets, options) {
            if (typeof options === "undefined")
                options = {};

            this.options = $.extend({}, $.fn.typeselect.defaults, options);

            this.selectedDatums = {};
            this.selectedItems = {};
            this.datasetsByName = {};
            // Begin hack to fix caching issue
            this.urlToDatasetMap = {};
            // End hack to fix caching issue

            var createFilter = function(name, valueKey, filter, selectedDatums) {
                return function(parsedResponse){
                    var datums = filter ? filter(parsedResponse) : parsedResponse;
                    var filtered = $.map(datums, function(datum, index){
                         if (selectedDatums[datum[valueKey]]) return null;
                         else return datum;
                    });
                    return filtered;
                };
            };

            // Support multiple targets based on dataset
            if (!$.isArray(datasets)) datasets = [datasets];

            // Setup stores for selected item targets
            this.$targetsMap = {};
            if (this.options.target)
                this.$defaultTarget = $(this.options.target);

            // Save datasets off for our use later
            this.dataset = datasets;

            // Find all targets for each dataset and modify
            // modify filter attributes so we can remove
            // selected items from future suggestions
            $.each(datasets, $.proxy(function(index, dataset) {
                var valueKey = dataset.valueKey || 'value', dataset_name = dataset.name;
                if (dataset.target) this.$targetsMap[dataset.name] = $(dataset.target);
                if (typeof dataset.remote === 'string' || dataset.remote instanceof String)
                    dataset.remote = {url: dataset.remote};
                this.selectedDatums[dataset_name] = {};

                if (dataset.remote){
                    // Begin hack to fix caching issue
                    dataset.name = dataset.remote.url.replace(/[?%&=./:]/g, function(c){
                        var r = {
                            '?':'q',
                            '%':'p',
                            '&':'a',
                            '=':'e',
                            '.':'d',
                            '/':'s',
                            ':':'c'
                        };
                        return r[c];
                    });
                    this.urlToDatasetMap[dataset.name] = dataset_name;
                    // End hack to fix caching issue
                    dataset.remote.filter = createFilter(dataset_name, valueKey,
                        dataset.remote.filter, this.selectedDatums[dataset_name]);
                }
                // TODO this cache will will need to be
                // be the swapped out dataset.name if we did that above
                this.selectedItems[dataset_name] = {};
                this.datasetsByName[dataset_name] = dataset;

                if (dataset.selected)
                    this.prePopulate(dataset.selected, dataset_name);
            }, this));

            // Initialize with twitter (not bootstrap) typeahead
            this.$element = $(element).typeahead(datasets);

            this.$element.on('typeahead:selected', $.proxy(function(event, datum, dataset_name){
                 this.add(datum, dataset_name);
                 // Clear out the textbox
                 this.$element.blur();
                 this.$element.val('');
            }, this));

            this.listen();
        };

        Typeselect.prototype = {

            constructor: Typeselect,

            destroy: function(){
                this.$element.typeahead('destroy');
            },

            listen: function() {
                var targets = [];
                $.each(this.$targetsMap, $.proxy(function(name, $target){
                    if (~$.inArray($target, targets)) return true;
                    $target.on('click', '.close', $.proxy(this.click, this));
                    targets.push($target);
                }, this));

                if (this.$defaultTarget && !$.inArray(targets, this.$defaultTarget))
                    $defaultTarget.on('click', '.close', $.proxy(this.click, this));
            },

            add: function(value, dataset_name) {
                // dataset_name parameter is optional
                // Use first supplied dataset by default
                if (typeof dataset_name === "undefined")
                    dataset_name = this.options.dataset || this.datasets[0].name;
                // Begin hack to fix caching issue
                if (this.urlToDatasetMap.hasOwnProperty(dataset_name))
                    dataset_name = this.urlToDatasetMap[dataset_name]
                // End hack to fix caching issue
                var template, item, $target;
                var dataset = this.datasetsByName[dataset_name];
                var valueKey = dataset.valueKey || "value";
                // Do not add redundant values
                if (this.selectedDatums[dataset_name][value[valueKey]]) return;
                this.selectedDatums[dataset_name][value[valueKey]] = value;

                // Render
                if (dataset.selectedTemplate){
                    if (!$.isFunction(dataset.selectedTemplate))
                        template = dataset.engine.compile(dataset.selectedTemplate);
                    else
                        template = dataset.selectedTemplate;
                    item = $(template.render(value))
                        .attr('data-value', value[valueKey])
                        .attr('data-dataset', dataset_name);
                } else {
                    // default list item with remove icon
                    item = $(this.options.selectedItem)
                        .text(value[valueKey])
                        .attr('data-value', value[valueKey])
                        .attr('data-dataset', dataset_name)
                        .append('×');
                }

                this.selectedItems[dataset_name][value[valueKey]] = item;

                // Add to the target container
                if ($target = this.$targetsMap[dataset_name]){
                    $target.append(item);
                } else {
                    // Use default target
                    this.$defaultTarget.append(item);
                }
            },

            remove: function(value, dataset_name) {
                // dataset_name parameter is optional
                // Use first supplied dataset by default
                if (typeof dataset_name === "undefined")
                    dataset_name = this.options.dataset || this.datasets[0].name;

                // Begin hack to fix caching issue
                if (this.urlToDatasetMap.hasOwnProperty(dataset_name))
                    dataset_name = this.urlToDatasetMap[dataset_name]
                // End hack to fix caching issue

                var valueKey = this.datasetsByName[dataset_name].valueKey || 'value',
                    item;

                // Remove from the selected cache
                if (this.selectedDatums[dataset_name][value])
                    delete this.selectedDatums[dataset_name][value];

                // Remove element from DOM element cache
                if (item = this.selectedItems[dataset_name][value]){
                   delete this.selectedItems[dataset_name][value];
                   item.remove();
                }
            },

            click: function(event) {
                event.preventDefault();
                var $parent = $(event.target).parent();
                this.remove($parent.attr('data-value'), $parent.attr('data-dataset'));
            },

            selected: function(groupByDataset){
                if (groupByDataset)
                    return this.selectedDatums;
                // Flatten
                return $.map(this.selectedDatums, function(key, dataset){
                    return $.map(dataset, function(key, datum){
                        return datum;
                    });
                });
            },

            prePopulate: function(selectedDatums, dataset_name){
                var index;
                if (!$.isArray(selectedDatums))
                    selectedDatums = [selectedDatums];
                for (index = 0; index < selectedDatums.length; index++)
                    this.add(selectedDatums[index], dataset_name);
            }

        };

        $.fn.typeselect = function(option, defaults) {
            return this.each(function() {
                var $this = $(this),
                   data = $this.data('typeselect'),
                   datasets = option;
                if (!data) $this.data('typeselect', (data = new Typeselect(this, datasets, defaults)));
                if (typeof option === 'string') data[option]();
            });
        };

        $.fn.typeselect.defaults = {
            selected: [],
            selectedItem: '

'
        };

        $.fn.typeselect.Constructor = Typeselect;

        /* TYPESELECT DATA-API
         * =================== */
        $(document).on('focus.typeselect.data-api', '[data-provide="typeselect"]', function(e) {
            var $this = $(this);
            if ($this.data('typeselect')) return;
            e.preventDefault();
            $this.typeselect($this.data());
        });
    }($);
});
<|endoftext|>


<commit_before>/**
 * Script objects are used to control other objects present in the scene.
 *
 * It can access and change every object in the program and supports some events
 *  - initialize
 *    - Called on app initialization, its called after all children elements are initialized, its safe to apply operations on other objects inside this method.
 *  - update(delta)
 *    - Called on every frame after rendering
 *  - dispose
 *    - Called when disposing the program
 *  - onMouseOver(intersections)
 *    - Called on every frame if mouse is on top of one of the script children
 *    - Receives an intersections array as argument.
 *  - onResize(x, y)
 *    - Called every time the window is resized
 *    - Receives width and height as parameters
 *  - onAppData(data)
 *    - Called when receiving data sent by the host website
 *
 * Code written inside scripts have access to the following attributes:
 *  - scene
 *  - program
 *  - self
 *    - Same as this reference but global in the script scope
 *  - Keyboard
 *  - Mouse
 *
 * There is also access to the following functions
 *  - include
 *    - Include a javascript file from resources, when including files the user needs to be carefull and clear manually global declarations
 *
 * @class Script
 * @extends {Object}
 * @param {string} code Javascript code to be used by this script
 * @module Script
 */
function Script(code, mode)
{
	THREE.Group.call(this);

	this.type = "Script";
	this.name = "script";

	/**
	 * Javascript code attached to the script.
	 *
	 * @property code
	 * @type {string}
	 */
	this.code = (code !== undefined) ? code : Script.DEFAULT;

	/**
	 * Mode indicates how to include external javascripts files into the script.
	 *
	 * Can be Script.APPEND, Script.EVALUATE or Script.INCLUDE.
	 *
	 * @property mode
	 * @type {number}
	 */
	this.mode = (mode !== undefined) ? mode : Script.APPEND;

	/**
	 * Compiled function used during runtime.
	 *
	 * @attribute script
	 * @type {Function}
	 */
	this.script = {};

	/**
	 * Pointer to the parent program.
	 *
	 * Used access program resources easier.
	 *
	 * @property program
	 * @type {Program}
	 */
	this.program = null;

	/**
	 * Pointer to the parent scene.
	 *
	 * @property scene
	 * @type {Scene}
	 */
	this.scene = null;
}

Script.prototype = Object.create(THREE.Group.prototype);

/**
 * Regular expression to obtain all the include calls placed inside of scripts.
 *
 * @attribute includeRegex
 * @type {RegExp}
 */
Script.includeRegex = /include[ ]*\([ \n]*["'].+?["'][ \n]*\);*/gi;
Script.includeRegexStart = /include[ ]*\([ \n]*["']/gi;
Script.includeRegexEnd = /["'][ \n]*\);*/gi;

/**
 * Default script code used when creating a new Script.
 *
 * @attribute DEFAULT
 * @type {string}
 */
Script.DEFAULT = "function initialize()\n{\n	//TODO <INITIALIZATION CODE>\n}\n\nfunction update(delta)\n{\n	//TODO <UPDATE CODE>\n}\n";

/**
 * List of default methods that can be implemented by scripts.
 *
 * @attribute METHODS
 * @type {Array}
 */
Script.METHODS = ["initialize", "update", "dispose", "onMouseOver", "onResize", "onAppData"];

/**
 * Append libraries on initialization.
 *
 * Libraries are appended to the script code on initialization.
 *
 * @attribute APPEND
 * @type {number}
 */
Script.APPEND = 100;

/**
 * Evaluate libs during runtime.
 *
 * This allows to load new libs during runtime, but its not possible to access private statements.
 *
 * @attribute EVALUATE
 * @type {number}
 */
Script.EVALUATE = 101;

/**
 * Include file into the document.body.
 *
 * This imports the JS file as any other file included into a <script> tag.
 *
 * @attribute INCLUDE
 * @type {number}
 */
Script.INCLUDE = 102;

/**
 * Auxiliar function to include javascript source file from resource into the script.
 *
 * The imported source is evaluated and loaded in the context of the script.
 *
 * Global declarations need to be cleaned using the dipose method.
 *
 * @method include
 * @param {string} name Javascript resource name.
 */

/**
 * Get includes from the code.
 *
 * Used to extract includes from code when loading libraries in APPEND mode.
 *
 * @static
 * @method getIncludes
 * @param {string} code Script code.
 */
Script.getIncludes = function(code)
{
	var results = [];

	// Regex object is statefull and iterates on each exec() call
	var includeRegex = new RegExp(Script.includeRegex, 'gi');

	while(true)
	{
		var match = includeRegex.exec(code);
		if(match === null)
		{
			break;
		}

		var include = match[0];
		include = include.replace(Script.includeRegexStart, '');
		include = include.replace(Script.includeRegexEnd, '');

		console.log("nunuStudio: Include script.", match, include);

		results.push(include);
	}

	return results;
}

/**
 * Remove includes from code.
 *
 * Used to remove include statements when initializing code in APPEND mode.
 *
 * @static
 * @method removeIncludes
 * @param {string} code Script code.
 */
Script.removeIncludes = function(code)
{
	return code.replace(Script.includeRegex, "");
}

/**
 * Initialize script. Automatically called by the runtime.
 *
 * Compiles the script code and calls the script initialize method if it exists after the code is compiled.
 *
 * @method initialize
 */
Script.prototype.initialize = function()
{
	var node = this;
	while(node.parent !== null)
	{
		node = node.parent;
		if(node instanceof Scene)
		{
			this.scene = node;
		}
		else if(node instanceof Program)
		{
			this.program = node;
		}
	}

	THREE.Object3D.prototype.initialize.call(this);

	var self = this;

	this.compileCode(this.code, function()
	{
		if(self.script.initialize !== undefined)
		{
			self.script.initialize.call(self);
		}
	});
};

/**
 * Update script state.
 *
 * Calls the script update method if it exists.
 *
 * @method update
 */
Script.prototype.update = function(delta)
{
	if(this.script.onMouseOver !== undefined)
	{
		var intersections = this.scene.raycaster.intersectObjects(this.children, true);
		if(intersections.length > 0)
		{
			this.script.onMouseOver.call(this, intersections);
		}
	}

	if(this.script.update !== undefined)
	{
		this.script.update.call(this, delta);
	}

	THREE.Object3D.prototype.update.call(this, delta);
};

/**
 * Disposes the script, can be used to clear resources when the program exits.
 *
 * Calls the script dispose method if it exists.
 *
 * @method dispose
 */
Script.prototype.dispose = function()
{
	if(this.script.dispose !== undefined)
	{
		this.script.dispose.call(this);
	}

	THREE.Object3D.prototype.dispose.call(this);
}

/**
 * Call resize method if available.
 *
 * The resize method receives width and height as arguments.
 *
 * @method resize
 */
Script.prototype.resize = function(x, y)
{
	if(this.script.onResize !== undefined)
	{
		this.script.onResize.call(this, x, y);
	}
};

/**
 * Call onAppData if available.
 *
 * Called automatically every time external data is passed to the runtime.
 *
 * @method appData
 * @param {Object} data
 */
Script.prototype.appData = function(data)
{
	if(this.script.onAppData !== undefined)
	{
		this.script.onAppData.call(this, data);
	}
};

/**
 * Set script code.
 *
 * Can be used to dinamically change the script code. However it is not recommended can lead to undefined behavior.
 *
 * @method compileCode
 * @param {string} code
 * @param {Function} onReady Funtion called when the code is ready.
 */
Script.prototype.compileCode = function(code, onReady)
{
	if(code !== undefined)
	{
		this.code = code;
	}

	try
	{
		//Public method declaration
		var code = this.code;
		for(var i = 0; i < Script.METHODS.length; i++)
		{
			var method = Script.METHODS[i];
			code += "\nif(this." + method + " == undefined && typeof " + method + " !== 'undefined'){this." + method + " = " + method + ";}";
		}

		//Append libraries to code
		if(this.mode === Script.APPEND)
		{
			var libs = Script.getIncludes(code);
			code = Script.removeIncludes(code);

			for(var i = 0; i < libs.length; i++)
			{
				code = this.program.getResourceByName(libs[i]).data + "\n" + code;
			}

			code += "\nfunction include(name)\
			{\
				console.warn(\"nunuStudio: Script running in append mode \" + name);\
			}";
		}
		//Declare include method
		else if(this.mode === Script.EVALUATE)
		{
			code += "\nfunction include(name)\
			{\
				var text = program.getResourceByName(name);\
				if(text !== null)\
				{\
					new Function(text.data).call(this);\
				}\
				else\
				{\
					console.warn(\"nunuStudio: Javascript file \" + name + \" not found in resources\");\
				}\
			}";
		}
		//Include
		else if(this.mode === Script.INCLUDE)
		{
			var libs = Script.getIncludes(code);
			code = Script.removeIncludes(code);

			var fileCounter = 0;

			for(var i = 0; i < libs.length; i++)
			{
				var blob = new Blob([this.program.getResourceByName(libs[i]).data], {type:"text/plain"});
				var url = URL.createObjectURL(blob);

				var js = document.createElement("script");
				js.type = "text/javascript";
				js.async = false;
				js.src = url;
				js.onload = function()
				{
					fileCounter++;

					if(fileCounter === libs.length)
					{
						onReady();
					}
				};
				js.onerror = js.onload;
				document.body.appendChild(js);
			}
		}

		//Evaluate code and create constructor
		var Constructor = new Function("Keyboard, Mouse, self, program, scene", code);

		//Create script object
		try
		{
			this.script = new Constructor(this.program.keyboard, this.program.mouse, this, this.program, this.scene);
		}
		catch(e)
		{
			console.warn("nunuStudio: Error initializing script code", e);
			throw "Error initializing script code";
			this.script = {};
		}

		if(this.mode !== Script.INCLUDE)
		{
			onReady();
		}
	}
	catch(e)
	{
		console.warn("nunuStudio: Error compiling script code", e);
		throw "Error compiling script code";
		this.script = {};
	}
};

Script.prototype.toJSON = function(meta)
{
	var data = THREE.Object3D.prototype.toJSON.call(this, meta);

	data.object.code = this.code;
	data.object.mode = this.mode;

	return data;
};
<commit_msg>Derp<commit_after>/**
 * Script objects are used to control other objects present in the scene.
 *
 * It can access and change every object in the program and supports some events
 *  - initialize
 *    - Called on app initialization, its called after all children elements are initialized, its safe to apply operations on other objects inside this method.
 *  - update(delta)
 *    - Called on every frame after rendering
 *  - dispose
 *    - Called when disposing the program
 *  - onMouseOver(intersections)
 *    - Called on every frame if mouse is on top of one of the script children
 *    - Receives an intersections array as argument.
 *  - onResize(x, y)
 *    - Called every time the window is resized
 *    - Receives width and height as parameters
 *  - onAppData(data)
 *    - Called when receiving data sent by the host website
 *
 * Code written inside scripts have access to the following attributes:
 *  - scene
 *  - program
 *  - self
 *    - Same as this reference but global in the script scope
 *  - Keyboard
 *  - Mouse
 *
 * There is also access to the following functions
 *  - include
 *    - Include a javascript file from resources, when including files the user needs to be carefull and clear manually global declarations
 *
 * @class Script
 * @extends {Object}
 * @param {string} code Javascript code to be used by this script
 * @module Script
 */
function Script(code, mode)
{
	THREE.Group.call(this);

	this.type = "Script";
	this.name = "script";

	/**
	 * Javascript code attached to the script.
	 *
	 * @property code
	 * @type {string}
	 */
	this.code = (code !== undefined) ? code : Script.DEFAULT;

	/**
	 * Mode indicates how to include external javascripts files into the script.
	 *
	 * Can be Script.APPEND, Script.EVALUATE or Script.INCLUDE.
	 *
	 * @property mode
	 * @type {number}
	 */
	this.mode = (mode !== undefined) ? mode : Script.APPEND;

	/**
	 * Compiled function used during runtime.
	 *
	 * @attribute script
	 * @type {Function}
	 */
	this.script = {};

	/**
	 * Pointer to the parent program.
	 *
	 * Used access program resources easier.
	 *
	 * @property program
	 * @type {Program}
	 */
	this.program = null;

	/**
	 * Pointer to the parent scene.
	 *
	 * @property scene
	 * @type {Scene}
	 */
	this.scene = null;
}

Script.prototype = Object.create(THREE.Group.prototype);

/**
 * Regular expression to obtain all the include calls placed inside of scripts.
 *
 * @attribute includeRegex
 * @type {RegExp}
 */
Script.includeRegex = /include[ ]*\([ \n]*["'].+?["'][ \n]*\);*/gi;
Script.includeRegexStart = /include[ ]*\([ \n]*["']/gi;
Script.includeRegexEnd = /["'][ \n]*\);*/gi;

/**
 * Default script code used when creating a new Script.
 *
 * @attribute DEFAULT
 * @type {string}
 */
Script.DEFAULT = "function initialize()\n{\n	//TODO <INITIALIZATION CODE>\n}\n\nfunction update(delta)\n{\n	//TODO <UPDATE CODE>\n}\n";

/**
 * List of default methods that can be implemented by scripts.
 *
 * @attribute METHODS
 * @type {Array}
 */
Script.METHODS = ["initialize", "update", "dispose", "onMouseOver", "onResize", "onAppData"];

/**
 * Append libraries on initialization.
 *
 * Libraries are appended to the script code on initialization.
 *
 * @attribute APPEND
 * @type {number}
 */
Script.APPEND = 100;

/**
 * Evaluate libs during runtime.
 *
 * This allows to load new libs during runtime, but its not possible to access private statements.
 *
 * @attribute EVALUATE
 * @type {number}
 */
Script.EVALUATE = 101;

/**
 * Include file into the document.body.
 *
 * This imports the JS file as any other file included into a <script> tag.
 *
 * @attribute INCLUDE
 * @type {number}
 */
Script.INCLUDE = 102;

/**
 * Auxiliar function to include javascript source file from resource into the script.
 *
 * The imported source is evaluated and loaded in the context of the script.
 *
 * Global declarations need to be cleaned using the dipose method.
 *
 * @method include
 * @param {string} name Javascript resource name.
 */

/**
 * Get includes from the code.
 *
 * Used to extract includes from code when loading libraries in APPEND mode.
 *
 * @static
 * @method getIncludes
 * @param {string} code Script code.
 */
Script.getIncludes = function(code)
{
	var results = [];

	// Regex object is statefull and iterates on each exec() call
	var includeRegex = new RegExp(Script.includeRegex, 'gi');

	while(true)
	{
		var match = includeRegex.exec(code);
		if(match === null)
		{
			break;
		}

		// Filter only the resource/library name
		var include = match[0];
		include = include.replace(Script.includeRegexStart, '');
		include = include.replace(Script.includeRegexEnd, '');
		results.push(include);
	}

	return results;
}

/**
 * Remove includes from code.
 *
 * Used to remove include statements when initializing code in APPEND mode.
 *
 * @static
 * @method removeIncludes
 * @param {string} code Script code.
 */
Script.removeIncludes = function(code)
{
	return code.replace(Script.includeRegex, "");
}

/**
 * Initialize script. Automatically called by the runtime.
 *
 * Compiles the script code and calls the script initialize method if it exists after the code is compiled.
 *
 * @method initialize
 */
Script.prototype.initialize = function()
{
	var node = this;
	while(node.parent !== null)
	{
		node = node.parent;
		if(node instanceof Scene)
		{
			this.scene = node;
		}
		else if(node instanceof Program)
		{
			this.program = node;
		}
	}

	THREE.Object3D.prototype.initialize.call(this);

	var self = this;

	this.compileCode(this.code, function()
	{
		if(self.script.initialize !== undefined)
		{
			self.script.initialize.call(self);
		}
	});
};

/**
 * Update script state.
 *
 * Calls the script update method if it exists.
 *
 * @method update
 */
Script.prototype.update = function(delta)
{
	if(this.script.onMouseOver !== undefined)
	{
		var intersections = this.scene.raycaster.intersectObjects(this.children, true);
		if(intersections.length > 0)
		{
			this.script.onMouseOver.call(this, intersections);
		}
	}

	if(this.script.update !== undefined)
	{
		this.script.update.call(this, delta);
	}

	THREE.Object3D.prototype.update.call(this, delta);
};

/**
 * Disposes the script, can be used to clear resources when the program exits.
 *
 * Calls the script dispose method if it exists.
 *
 * @method dispose
 */
Script.prototype.dispose = function()
{
	if(this.script.dispose !== undefined)
	{
		this.script.dispose.call(this);
	}

	THREE.Object3D.prototype.dispose.call(this);
}

/**
 * Call resize method if available.
 *
 * The resize method receives width and height as arguments.
 *
 * @method resize
 */
Script.prototype.resize = function(x, y)
{
	if(this.script.onResize !== undefined)
	{
		this.script.onResize.call(this, x, y);
	}
};

/**
 * Call onAppData if available.
 *
 * Called automatically every time external data is passed to the runtime.
 *
 * @method appData
 * @param {Object} data
 */
Script.prototype.appData = function(data)
{
	if(this.script.onAppData !== undefined)
	{
		this.script.onAppData.call(this, data);
	}
};

/**
 * Set script code.
 *
 * Can be used to dinamically change the script code. However it is not recommended can lead to undefined behavior.
 *
 * @method compileCode
 * @param {string} code
 * @param {Function} onReady Funtion called when the code is ready.
 */
Script.prototype.compileCode = function(code, onReady)
{
	if(code !== undefined)
	{
		this.code = code;
	}

	try
	{
		//Public method declaration
		var code = this.code;
		for(var i = 0; i < Script.METHODS.length; i++)
		{
			var method = Script.METHODS[i];
			code += "\nif(this." + method + " == undefined && typeof " + method + " !== 'undefined'){this." + method + " = " + method + ";}";
		}

		//Append libraries to code
		if(this.mode === Script.APPEND)
		{
			var libs = Script.getIncludes(code);
			code = Script.removeIncludes(code);

			for(var i = 0; i < libs.length; i++)
			{
				code = this.program.getResourceByName(libs[i]).data + "\n" + code;
			}

			code += "\nfunction include(name)\
			{\
				console.warn(\"nunuStudio: Script running in append mode \" + name);\
			}";
		}
		//Declare include method
		else if(this.mode === Script.EVALUATE)
		{
			code += "\nfunction include(name)\
			{\
				var text = program.getResourceByName(name);\
				if(text !== null)\
				{\
					new Function(text.data).call(this);\
				}\
				else\
				{\
					console.warn(\"nunuStudio: Javascript file \" + name + \" not found in resources\");\
				}\
			}";
		}
		//Include
		else if(this.mode === Script.INCLUDE)
		{
			var libs = Script.getIncludes(code);
			code = Script.removeIncludes(code);

			var fileCounter = 0;

			for(var i = 0; i < libs.length; i++)
			{
				var blob = new Blob([this.program.getResourceByName(libs[i]).data], {type:"text/plain"});
				var url = URL.createObjectURL(blob);

				var js = document.createElement("script");
				js.type = "text/javascript";
				js.async = false;
				js.src = url;
				js.onload = function()
				{
					fileCounter++;

					if(fileCounter === libs.length)
					{
						onReady();
					}
				};
				js.onerror = js.onload;
				document.body.appendChild(js);
			}
		}

		//Evaluate code and create constructor
		var Constructor = new Function("Keyboard, Mouse, self, program, scene", code);

		//Create script object
		try
		{
			this.script = new Constructor(this.program.keyboard, this.program.mouse, this, this.program, this.scene);
		}
		catch(e)
		{
			console.warn("nunuStudio: Error initializing script code", e);
			throw "Error initializing script code";
			this.script = {};
		}

		if(this.mode !== Script.INCLUDE)
		{
			onReady();
		}
	}
	catch(e)
	{
		console.warn("nunuStudio: Error compiling script code", e);
		throw "Error compiling script code";
		this.script = {};
	}
};

Script.prototype.toJSON = function(meta)
{
	var data = THREE.Object3D.prototype.toJSON.call(this, meta);

	data.object.code = this.code;
	data.object.mode = this.mode;

	return data;
};
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Mon Jan 29 2018 11:58:53 GMT+0700 (SE Asia Standard Time)

// Super-useful!  http://www.bradoncode.com/blog/2015/02/27/karma-tutorial/#handling-html-fixtures

module.exports = {
  // base path that will be used to resolve all patterns (eg. files, exclude)
  basePath: '..',

  // frameworks to use
  // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
  frameworks: ['mocha', 'chai', 'fixture'],

  // list of files / patterns to load in the browser
  files: [
    'unit_tests/test_utils.js', // A basic utility script useful for constructing tests
    'unit_tests/modernizr.js', // A dependency-managed utility script that helps with browser feature detection.
    'unit_tests/cases/**/*.js', // Where the tests actually reside.
    'unit_tests/json/**/*.json', // Where pre-loaded JSON resides.
    {pattern: 'unit_tests/resources/**/*.*', watched: true, served: true, included: false}, // General testing resources.
    {pattern: 'release/unminified/web/**/*.css', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/**/*.gif', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/**/*.png', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/**/*.eot', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/**/*.ttf', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/**/*.woff', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/*.js', watched: true, served: true, included: false},  // The actual KMW code.
    {pattern: 'release/unminified/web/*.map', watched: true, served: true, included: false}, // + sourcemaps.
    {pattern: 'unit_tests/fixtures/**/*.html', watched: true} // HTML structures useful for testing.
  ],

  proxies: {
    "/source/": "/base/release/unminified/web/",
    "/resources/": "/base/unit_tests/resources/"
  },

  // list of files / patterns to exclude
  exclude: [
  ],

  jsonFixturesPreprocessor: {
    stripPrefix: 'unit_tests/json',
    variableName: '__json__'
  },

  // preprocess matching files before serving them to the browser
  // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
  preprocessors: {
    'unit_tests/fixtures/**/*.html'	: ['html2js'],
    'unit_tests/json/**/*.json' : ['json_fixtures']
  },

  // web server port
  port: 9876,

  // enable / disable colors in the output (reporters and logs)
  colors: true,

  // enable / disable watching file and executing tests whenever any file changes
  autoWatch: true,

  // Continuous Integration mode
  // if true, Karma captures browsers, runs the tests and exits
  // if false, it generates the pages and acts as a persistent server.
  singleRun: true,
}
<commit_msg>Deporting a couple of other accidental migrants.<commit_after>// Karma configuration
// Generated on Mon Jan 29 2018 11:58:53 GMT+0700 (SE Asia Standard Time)

// Super-useful!  http://www.bradoncode.com/blog/2015/02/27/karma-tutorial/#handling-html-fixtures

module.exports = {
  // base path that will be used to resolve all patterns (eg. files, exclude)
  basePath: '..',

  // frameworks to use
  // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
  frameworks: ['mocha', 'chai', 'fixture'],

  // list of files / patterns to load in the browser
  files: [
    'unit_tests/test_utils.js', // A basic utility script useful for constructing tests
    'unit_tests/modernizr.js', // A dependency-managed utility script that helps with browser feature detection.
    'unit_tests/cases/**/*.js', // Where the tests actually reside.
    {pattern: 'unit_tests/resources/**/*.*', watched: true, served: true, included: false}, // General testing resources.
    {pattern: 'release/unminified/web/**/*.css', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/**/*.gif', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/**/*.png', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/**/*.eot', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/**/*.ttf', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/**/*.woff', watched: false, served: true, included: false}, // OSK resources
    {pattern: 'release/unminified/web/*.js', watched: true, served: true, included: false},  // The actual KMW code.
    {pattern: 'release/unminified/web/*.map', watched: true, served: true, included: false}, // + sourcemaps.
    {pattern: 'unit_tests/fixtures/**/*.html', watched: true} // HTML structures useful for testing.
  ],

  proxies: {
    "/source/": "/base/release/unminified/web/",
    "/resources/": "/base/unit_tests/resources/"
  },

  // list of files / patterns to exclude
  exclude: [
  ],

  // preprocess matching files before serving them to the browser
  // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
  preprocessors: {
    'unit_tests/fixtures/**/*.html'	: ['html2js'],
  },

  // web server port
  port: 9876,

  // enable / disable colors in the output (reporters and logs)
  colors: true,

  // enable / disable watching file and executing tests whenever any file changes
  autoWatch: true,

  // Continuous Integration mode
  // if true, Karma captures browsers, runs the tests and exits
  // if false, it generates the pages and acts as a persistent server.
  singleRun: true,
}
<|endoftext|>


<commit_before>var app = app || {};

(function() {
    'use strict';

    app.BlogRouter = Backbone.Router.extend({
        routes: {
            "": "index",
            "page/:page": "page",
            "tag/:tag(/page/:page)": "tag",
            ":id": "id",
            "search/:query(/page/:page)": "search",
            "*path": "id"
        },

        index: function() {
            // Fetch new posts when the user decides to navigate to the homepage.
            // This action is rate limited by app.page.collection.fetch itself.
            if (_.has(app.page, "collection")) {
                if (app.page.config.get("refresh_posts_when_navigating_home")) {
                    app.page.collection.fetch({ reset: true });
                }
            }
            this.page(0);
        },

        page: function(page) {
            app.page.filter = app.PostCollection.prototype.makeFilterDefault();
            app.page.currentPage = +page;
            app.page.kind = ["page"];
            app.page.render();
        },

        id: function(id) {
            if (_.has(app.page, "collection")) {
                app.page.filter = app.PostCollection.prototype.makeFilterId(id);
                app.page.currentPage = 0;
                app.page.kind = ["id", id];
                app.page.render();
            }
        },

        tag: function(tag, page) {
            if (tag === "_excluded" || tag === "_hidden") {
                // Do not search for the special tags.
                app.page.filter = function() {
                    return [];
                }
            } else {
                app.page.filter = app.PostCollection.prototype.makeFilterTag(tag);
                app.page.currentPage = +page;
            }
            app.page.kind = ["tag", tag];
            app.page.render();
        },

        search: function(query, page) {
            app.page.filter = app.PostCollection.prototype.makeFilterText(query.toLowerCase());
            app.page.kind = ["search", query];
            app.page.currentPage = +page;
            app.page.render();
        }
    });
})();
<commit_msg>blogrouter.js: Removed unnecessary conditional<commit_after>var app = app || {};

(function() {
    'use strict';

    app.BlogRouter = Backbone.Router.extend({
        routes: {
            "": "index",
            "page/:page": "page",
            "tag/:tag(/page/:page)": "tag",
            ":id": "id",
            "search/:query(/page/:page)": "search",
            "*path": "id"
        },

        index: function() {
            // Fetch new posts when the user decides to navigate to the homepage.
            // This action is rate limited by app.page.collection.fetch itself.
            if (_.has(app.page, "collection")) {
                if (app.page.config.get("refresh_posts_when_navigating_home")) {
                    app.page.collection.fetch({ reset: true });
                }
            }
            this.page(0);
        },

        page: function(page) {
            app.page.filter = app.PostCollection.prototype.makeFilterDefault();
            app.page.currentPage = +page;
            app.page.kind = ["page"];
            app.page.render();
        },

        id: function(id) {
            app.page.filter = app.PostCollection.prototype.makeFilterId(id);
            app.page.currentPage = 0;
            app.page.kind = ["id", id];
            app.page.render();
        },

        tag: function(tag, page) {
            if (tag === "_excluded" || tag === "_hidden") {
                // Do not search for the special tags.
                app.page.filter = function() {
                    return [];
                }
            } else {
                app.page.filter = app.PostCollection.prototype.makeFilterTag(tag);
                app.page.currentPage = +page;
            }
            app.page.kind = ["tag", tag];
            app.page.render();
        },

        search: function(query, page) {
            app.page.filter = app.PostCollection.prototype.makeFilterText(query.toLowerCase());
            app.page.kind = ["search", query];
            app.page.currentPage = +page;
            app.page.render();
        }
    });
})();
<|endoftext|>


<commit_before>var Query = Backbone.Model.extend({
    initialize: function(args) {
        this.cube = args.cube;

        // Generate a unique query id
        this.name = 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'
        .replace(/[xy]/g, function (c) {
            var r = Math.random() * 16 | 0,
            v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        }).toUpperCase();

        // Parse cube information
        this.parse_cube();

        // Create the query on the server workspace
        this.save();
    },

    parse_cube: function() {
        var parsed_cube = this.cube.split('/');
        this.attributes.connection = parsed_cube[0];
        this.attributes.catalog = parsed_cube[1];
        this.attributes.schema = parsed_cube[2];
        this.attributes.cube = parsed_cube[3];
    },

    url: function() {
        return Saiku.session.username + "/query/" + this.name;
    }
});<commit_msg>Ensure queries are deleted when they are no longer needed<commit_after>var Query = Backbone.Model.extend({
    initialize: function(args) {
        this.cube = args.cube;

        // Generate a unique query id
        this.name = 'xxxxxxxx-xxxx-xxxx-yxxx-xxxxxxxxxxxx'
        .replace(/[xy]/g, function (c) {
            var r = Math.random() * 16 | 0,
            v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        }).toUpperCase();

        // Parse cube information
        this.parse_cube();

        // Create the query on the server workspace
        this.save();
    },

    parse: function() {
        this.id = this.name;
    },

    parse_cube: function() {
        var parsed_cube = this.cube.split('/');
        this.attributes.connection = parsed_cube[0];
        this.attributes.catalog = parsed_cube[1];
        this.attributes.schema = parsed_cube[2];
        this.attributes.cube = parsed_cube[3];
    },

    url: function() {
        return Saiku.session.username + "/query/" + this.name;
    }
});<|endoftext|>


<commit_before>import localforage from 'localforage';

/*
 * @description
 * Will fire a reset action with the persisted state
 */
export const reset = store => next => action => {
  if (action.type !== 'ACTIVATE') return next(action);
  console.log('Reseting data');
  localforage.getItem('state')
    .then(state => store.dispatch({type: 'RESET', state}))
    .catch(err => {console.log(err); return next(action);});
};

/*
 * @desscription
 * Will stash the state of the store into IndexedDB on every update
 */
export const stash = store => next => action => {
  let result = next(action);
  console.log('Stashing Data');
  localforage.setItem('state', store.getState())
    .catch(err => console.log(err));

  return result;
};

<commit_msg>skip stashing data if the event is reset<commit_after>import localforage from 'localforage';

/*
 * @description
 * Will fire a reset action with the persisted state
 */
export const reset = store => next => action => {
  if (action.type !== 'ACTIVATE') return next(action);
  console.log('Reseting data');
  localforage.getItem('state')
    .then(state => store.dispatch({type: 'RESET', state}))
    .catch(err => {console.log(err); return next(action);});
};

/*
 * @desscription
 * Will stash the state of the store into IndexedDB on every update
 */
export const stash = store => next => action => {
  let result = next(action);

  if (action.type !== 'RESET') {
    console.log('Stashing Data');
    localforage.setItem('state', store.getState())
      .catch(err => console.log(err));
  }

  return result;
};

<|endoftext|>


<commit_before>import localforage from 'localforage';

/*
 * @description
 * Will fire a reset action with the persisted state
 */
export const reset = store => next => action => {
  if (action.type !== 'ACTIVATE') return next(action);
  console.log('Reseting data');
  localforage.getItem('state')
    .then(state => store.dispatch({type: 'RESET', state}))
    .catch(err => {console.log(err); return next(action);});
};

/*
 * @desscription
 * Will stash the state of the store into IndexedDB on every update
 */
export const stash = store => next => action => {
  let result = next(action);
  console.log('Stashing Data');
  localforage.setItem('state', store.getState())
    .catch(err => console.log(err));

  return result;
};

<commit_msg>formatting<commit_after>import localforage from 'localforage';

/*
 * @description
 * Will fire a reset action with the persisted state
 */
export const reset = store => next => action => {
  if (action.type !== 'ACTIVATE') return next(action);
  console.log('Reseting data');
  localforage.getItem('state')
    .then(state => store.dispatch({type: 'RESET', state}))
    .catch(err => {console.log(err); return next(action);});
};

/*
 * @desscription
 * Will stash the state of the store into IndexedDB on every update
 */
export const stash = store => next => action => {
  let result = next(action);
  console.log('Stashing Data');
  localforage.setItem('state', store.getState())
    .catch(err => console.log(err));

  return result;
};

<|endoftext|>


<commit_before>
init_dragable = function(){
    $("#q").draggable({
        axis: "y",
        start: function(){
            var $c = $("#canvas-frame");
            $c.css('bottom', 'inherit');
            $(this).css('height',50);
        },
        drag: function( event, ui ) {
            var height = ui.position.top-30;
            $("#canvas-frame").css('height', height);
            gadgets.window.adjustHeight();
        },
        stop: function(){
            $(this).css('height',3);
            gadgets.window.adjustHeight();
            $(this).css('top','');
        }
    });
}
gadgets.util.registerOnLoadHandler(init_dragable);
<commit_msg>Update sevianno-draggable.js<commit_after>
var init_dragable = function(){
    $("#q").draggable({
        axis: "y",
        start: function(){
            var $c = $("#canvas-frame");
            $c.css('bottom', 'inherit');
            $(this).css('height',50);
        },
        drag: function( event, ui ) {
            var height = ui.position.top-30;
            $("#canvas-frame").css('height', height);
            gadgets.window.adjustHeight();
        },
        stop: function(){
            $(this).css('height',3);
            gadgets.window.adjustHeight();
            $(this).css('top','');
        }
    });
}
gadgets.util.registerOnLoadHandler(init_dragable);
<|endoftext|>


<commit_before>/**
 * Interface to the terminal (command line).
 *
 * It's a thin wrapper around the readline module.  Adds support for bluebird
 * Promises.
 *
 * It has the same interface as fancyview.js, but is less fancy.
 */

var colors = require('colors');
var P = require('bluebird');
var readline = require('readline');
var events = require('events');

exports.TermView = function() {
  var self = new events.EventEmitter();

  self.rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
      completer: function(line, callback) {
        if (!self.completer) {
          return;
        }
        return self.completer(line, callback);
      }
  });

  var rl = self.rl;

  self.setPrompt = rl.setPrompt.bind(rl);

  self.prompt = function() {
    rl.prompt();
    var end = colors.stripColors(rl._prompt + rl.line).length;
    readline.cursorTo(rl.output, end);
    rl.cursor = colors.stripColors(rl.line).length;
  }
  self.completer = null;

  /**
   * Asks the user a question. Returns a Promise with the user's response.
   */
  self.question = function(prompt) {
    return new P(function(resolve, reject) {
      rl.question(prompt, function(reply) {
        resolve(reply);
      });
    });
  }

  /**
   * Write a message to the terminal, ensuring that the prompt line stays where
   * it's supposed to.
   */
  self.log = function() {
    if (process.stdout.clearLine) {
      process.stdout.clearLine();
      process.stdout.cursorTo(0);
    }
    console.log.apply(null, arguments);
  }

  self.err = function() {
    self.log.apply(null, arguments);
  }

  self.showHelp = function(text) {
    self.log(text)
  }
  self.hideHelp = function() {}

  self.setModeLine = function() {}
  self.setHelpLine = function() {}
  self.render = function() {}

  self.setInputLine = function(text) {
    rl.line = text;
    self.prompt();
  }

  var focused = 'main';

  self.focusInput = function() {
    focused = 'input';
  }

  self.focusMainBox = function() {
    focused = 'main';
  }

  process.stdin.on('keypress', function(key) {
    if (focused != 'input') {
      rl.line = '';
    }
    self.emit(focused + '.key', key);
  })

  rl.on('line', function(text) {
    self.emit('input.submit', text);
  });

  rl.on('close', function() {
    process.exit(0);
  });

  return self;
}

<commit_msg>Remove term.js<commit_after><|endoftext|>


<commit_before>// Copyright 2002-2012, University of Colorado

/**
 * An interval between two Trails.
 *
 * @author Jonathan Olson <olsonsjc@gmail.com>
 */

define( function( require ) {
  "use strict";

  var assert = require( 'ASSERT/assert' )( 'scenery' );

  var Transform3 = require( 'DOT/Transform3' );

  var scenery = require( 'SCENERY/scenery' );

  require( 'SCENERY/util/Trail' );

  scenery.TrailInterval = function( a, b ) {
    assert && assert( a.compare( b ) <= 0, 'TrailInterval parameters must not be out of order' );

    this.a = a;
    this.b = b;
  };
  var TrailInterval = scenery.TrailInterval;

  TrailInterval.prototype = {
    constructor: TrailInterval,

    reindex: function() {
      this.a && this.a.reindex();
      this.b && this.b.reindex();
    },

    /*
     * Whether the union of this and the specified interval doesn't include any additional trails, when
     * both are treated as exclusive endpoints (exclusive between a and b). We also make the assumption
     * that a !== b || a === null for either interval, since otherwise it is not well defined.
     */
    exclusiveUnionable: function( interval ) {
      return ( !this.a || !interval.b || this.a.compare( interval.b ) === -1 ) &&
             ( !this.b || !interval.a || this.b.compare( interval.a ) === 1 );
    },

    union: function( interval ) {
      return new TrailInterval(
        this.a.compare( interval.a ) === -1 ? this.a : interval.a,
        this.b.compare( interval.b ) ===  1 ? this.b : interval.b
      );
    }
  };

  return TrailInterval;
} );

<commit_msg>Removing redundant import<commit_after>// Copyright 2002-2012, University of Colorado

/**
 * An interval between two Trails.
 *
 * @author Jonathan Olson <olsonsjc@gmail.com>
 */

define( function( require ) {
  "use strict";

  var assert = require( 'ASSERT/assert' )( 'scenery' );

  var scenery = require( 'SCENERY/scenery' );
  require( 'SCENERY/util/Trail' );

  scenery.TrailInterval = function( a, b ) {
    assert && assert( a.compare( b ) <= 0, 'TrailInterval parameters must not be out of order' );

    this.a = a;
    this.b = b;
  };
  var TrailInterval = scenery.TrailInterval;

  TrailInterval.prototype = {
    constructor: TrailInterval,

    reindex: function() {
      this.a && this.a.reindex();
      this.b && this.b.reindex();
    },

    /*
     * Whether the union of this and the specified interval doesn't include any additional trails, when
     * both are treated as exclusive endpoints (exclusive between a and b). We also make the assumption
     * that a !== b || a === null for either interval, since otherwise it is not well defined.
     */
    exclusiveUnionable: function( interval ) {
      return ( !this.a || !interval.b || this.a.compare( interval.b ) === -1 ) &&
             ( !this.b || !interval.a || this.b.compare( interval.a ) === 1 );
    },

    union: function( interval ) {
      return new TrailInterval(
        this.a.compare( interval.a ) === -1 ? this.a : interval.a,
        this.b.compare( interval.b ) ===  1 ? this.b : interval.b
      );
    }
  };

  return TrailInterval;
} );

<|endoftext|>


<commit_before>import { browserHistory } from 'react-router'
import { startCase } from 'lodash'
import { addMessage } from '../messages/actions'
import { setPage, ARTICLE, LOADING } from '../page/actions'
import { extractSlug } from '../../../utility/Slugs'

export function loadArticle(requestedSlug, flashLoading = true) {
  return (dispatch) => {
    if (flashLoading) dispatch({ type: LOADING, slug: requestedSlug })

    let slug = requestedSlug
    fetch(`/api/page/${requestedSlug}`, { credentials: 'include' })
      .then((response) => {
        slug = extractSlug(response.url)
        if (slug !== requestedSlug) browserHistory.replace(`/page/${slug}`)
        return response.json()
      })
      .then((article) => {
        const title = article.title || startCase(slug)
        const keywords = [
          ...(article.aliases || []),
          ...(article.tags || []),
          title,
        ]
        dispatch(setPage(ARTICLE, { ...article, slug, title, keywords }))
      })
  }
}

export function deleteArticle(slug) {
  return dispatch => fetch(`/api/page/${slug}`, {
    credentials: 'include',
    method:      'DELETE',
  }).then((response) => {
    if (response.status === 410 /* Deleted */) {
      dispatch(loadArticle('home'))
      dispatch(addMessage(`Article ${slug} was successfully deleted!`))
    } else if (response.status === 401 /* Unauthorized */) {
      dispatch(addMessage(`Your account does not have permission to delete the '${slug}' article.`))
    } else if (response.status === 500 /* Internal Server Error */) {
      dispatch(addMessage(`An error occurred while attempting to delete the '${slug}' article. Please try again.`))
    }
  })
}

export function saveArticle(slug, article) {
  return dispatch => fetch(`/api/page/${slug}`, {
    body: JSON.stringify(article),

    credentials: 'include',
    method:      'POST',
    mode:        'cors',

    headers: new Headers({
      'Content-Type': 'application/json',
      Accept:         'application/json',
    }),
  }).then((response) => {
    /* eslint-disable no-throw-literal */
    if (response.status === 200 /* OK */) {
      return response.json()
    } else if (response.status === 401 /* Unauthorized */) {
      throw ({ status: 401, message: `Your account does not have permission to update the '${slug}' article.` })
    } else if (response.status === 500 /* Internal Server Error */) {
      throw ({ status: 500, message: `An error occurred while attempting to save the '${slug}' article. Please try again.` })
    }

    return {}
  }).then(updated => dispatch(setPage(ARTICLE, updated)))
    .catch((error) => {
      if (error && error.message) dispatch(addMessage(error.message))
    })
}
<commit_msg>:bugfix: loadArticle now always updates the browserHistory<commit_after>import { browserHistory } from 'react-router'
import { startCase } from 'lodash'
import { addMessage } from '../messages/actions'
import { setPage, ARTICLE, LOADING } from '../page/actions'
import { extractSlug } from '../../../utility/Slugs'

export function loadArticle(requestedSlug, flashLoading = true) {
  return (dispatch) => {
    if (flashLoading) dispatch({ type: LOADING, slug: requestedSlug })

    let slug = requestedSlug
    fetch(`/api/page/${requestedSlug}`, { credentials: 'include' })
      .then((response) => {
        slug = extractSlug(response.url)
        if (slug !== requestedSlug) {
          browserHistory.replace(`/page/${slug}`)
        } else {
          browserHistory.replace(`/page/${requestedSlug}`)
        }
        return response.json()
      })
      .then((article) => {
        const title = article.title || startCase(slug)
        const keywords = [
          ...(article.aliases || []),
          ...(article.tags || []),
          title,
        ]
        dispatch(setPage(ARTICLE, { ...article, slug, title, keywords }))
      })
  }
}

export function deleteArticle(slug) {
  return dispatch => fetch(`/api/page/${slug}`, {
    credentials: 'include',
    method:      'DELETE',
  }).then((response) => {
    if (response.status === 410 /* Deleted */) {
      dispatch(loadArticle('home'))
      dispatch(addMessage(`Article ${slug} was successfully deleted!`))
    } else if (response.status === 401 /* Unauthorized */) {
      dispatch(addMessage(`Your account does not have permission to delete the '${slug}' article.`))
    } else if (response.status === 500 /* Internal Server Error */) {
      dispatch(addMessage(`An error occurred while attempting to delete the '${slug}' article. Please try again.`))
    }
  })
}

export function saveArticle(slug, article) {
  return dispatch => fetch(`/api/page/${slug}`, {
    body: JSON.stringify(article),

    credentials: 'include',
    method:      'POST',
    mode:        'cors',

    headers: new Headers({
      'Content-Type': 'application/json',
      Accept:         'application/json',
    }),
  }).then((response) => {
    /* eslint-disable no-throw-literal */
    if (response.status === 200 /* OK */) {
      return response.json()
    } else if (response.status === 401 /* Unauthorized */) {
      throw ({ status: 401, message: `Your account does not have permission to update the '${slug}' article.` })
    } else if (response.status === 500 /* Internal Server Error */) {
      throw ({ status: 500, message: `An error occurred while attempting to save the '${slug}' article. Please try again.` })
    }

    return {}
  }).then(updated => dispatch(setPage(ARTICLE, updated)))
    .catch((error) => {
      if (error && error.message) dispatch(addMessage(error.message))
    })
}
<|endoftext|>


<commit_before>(function() {
	'use strict';

	angular
		.module('greyjays.evaluations')
		.filter('formaterDate', formaterDate);

	/** @ngInject */
	function formaterDate() {
		return function(input, format) {
			var maDate = new Date(input);
			var lesMois = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"];
			var lesJours = ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"];
			var str = '';
			if (format == 'mois ANNEE') {
				str += lesMois[maDate.getMonth()] + ' ' + maDate.getFullYear();
			} else if (format == 'jour mois annee') {
				str += maDate.getDate() + ' ' + lesMois[maDate.getMonth()].toLowerCase() + ' ' + maDate.getFullYear();
			} else if (format == 'hh mm') {
				str += maDate.getHours() + 'h';
				if (maDate.getMinutes() < 10) { str += '0'; }
				str += maDate.getMinutes();
			} else if (format == 'libelle jour') {
				str += lesJours[maDate.getDay()] + ' ' + maDate.getDate();
			} else if (format == 'libelle jour mois') {
				str += lesJours[maDate.getDay()] + ' ' + maDate.getDate() + ' ' + lesMois[maDate.getMonth()].toLowerCase();
			} else if (format == 'mois') {
				str += lesMois[maDate.getMonth()];
			} else if (format == 'JJ/MM/AAAA') {
				if (maDate.getDate() < 10) { str += '0'; }
				str += maDate.getDate();
				str += '/';
				if (maDate.getMonth() < 9) { str += '0'; }
				str += maDate.getMonth()+1;
				str += '/';
				str += maDate.getFullYear();
			} else if (format == 'JJ/MM/AAAA à HHhMM') {
				if (maDate.getDate() < 10) { str += '0'; }
				str += maDate.getDate();
				str += '/';
				if (maDate.getMonth() < 9) { str += '0'; }
				str += maDate.getMonth()+1;
				str += '/';
				str += maDate.getFullYear();
				str += ' à ' + maDate.getHours() + 'h';
				if (maDate.getMinutes() < 10) { str += '0'; }
				str += maDate.getMinutes();
			}
			return str;
		};
	}
})();
<commit_msg>correction anomalie gmt+1 gmt+2<commit_after>(function() {
	'use strict';

	angular
		.module('greyjays.evaluations')
		.filter('formaterDate', formaterDate);

	/** @ngInject */
	function formaterDate() {
		return function(input, format) {
			var maDate = new Date(input);
			/*console.log(input);
			console.log(maDate);
			console.log(maDate.getTimezoneOffset());*/
			var lesMois = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"];
			var lesJours = ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"];
			var str = '';
			if (format == 'mois ANNEE') {
				str += lesMois[maDate.getMonth()] + ' ' + maDate.getFullYear();
			} else if (format == 'jour mois annee') {
				str += maDate.getDate() + ' ' + lesMois[maDate.getMonth()].toLowerCase() + ' ' + maDate.getFullYear();
			} else if (format == 'hh mm') {
				str += maDate.getHours() + 'h';
				if (maDate.getMinutes() < 10) { str += '0'; }
				str += maDate.getMinutes();
			} else if (format == 'libelle jour') {
				str += lesJours[maDate.getDay()] + ' ' + maDate.getDate();
			} else if (format == 'libelle jour mois') {
				str += lesJours[maDate.getDay()] + ' ' + maDate.getDate() + ' ' + lesMois[maDate.getMonth()].toLowerCase();
			} else if (format == 'mois') {
				str += lesMois[maDate.getMonth()];
			} else if (format == 'JJ/MM/AAAA') {
				if (maDate.getDate() < 10) { str += '0'; }
				str += maDate.getDate();
				str += '/';
				if (maDate.getMonth() < 9) { str += '0'; }
				str += maDate.getMonth()+1;
				str += '/';
				str += maDate.getFullYear();
			} else if (format == 'JJ/MM/AAAA à HHhMM') {
				if (maDate.getDate() < 10) { str += '0'; }
				str += maDate.getDate();
				str += '/';
				if (maDate.getMonth() < 9) { str += '0'; }
				str += maDate.getMonth()+1;
				str += '/';
				str += maDate.getFullYear();
				str += ' à ' + maDate.getHours() + 'h';
				if (maDate.getMinutes() < 10) { str += '0'; }
				str += maDate.getMinutes();
			} else if (format == 'sql') {
				var offset = maDate.getTimezoneOffset();
				str += new Date(maDate.getTime() - offset * 60 * 1000);
			}
			return str;
		};
	}
})();
<|endoftext|>


<commit_before>// index.db.js
;(function(window){

    // 'use strict';
    // ** IE won't let you use strict mode and re-assign to window.indexdDB

    window.indexedDB =  window.indexedDB ||
                        window.mozIndexedDB ||
                        window.webkitIndexedDB ||
                        window.msIndexedDB;

    window.IDBTransaction =  window.IDBTransaction ||
                             window.webkitIDBTransaction ||
                             window.msIDBTransaction;

    window.IDBKeyRange = window.IDBKeyRange ||
                         window.webkitIDBKeyRange ||
                         window.msIDBKeyRange;

    var db = {

        version: 3, // important: only use whole numbers!

        objectStoreName: 'tasks',

        instance: {},

        upgrade: function(e) {

            var _db = e.target.result;

            if(!_db.objectStoreNames.contains(db.objectStoreName)){
                _db.createObjectStore(
                    db.objectStoreName,
                    { keyPath: 'id', autoIncrement: true});
            }
        },

        errorHandler: function(error){
            alert('error: ' + error.target.code);
            debugger;
        },

        getObjectStore: function(mode){
            var mode = mode || 'readonly';
            var txn = db.instance.transaction([db.objectStoreName], mode);
            var store = txn.objectStore(db.objectStoreName);

            return store;
        },

        open: function(callback){

            var request = window.indexedDB.open(
                            db.objectStoreName,
                            db.version);

            request.onerror = db.errorHandler;

            request.onupgradeneeded = db.upgrade;

            request.onsuccess = function(e){
                db.instance = request.result;
                db.instance.onerror = db.errorHandler;
                callback();
            };
        },

        save: function(note, callback){

            db.open(function(){

                var store = db.getObjectStore('readwrite'),
                    request;

                request = note.id ? store.put(note) : store.add(note);

                request.onsuccess = callback;
            });
        },

        'delete': function(id, callback){

            id = parseInt(id);

            db.open(function(){

                var
                    store = db.getObjectStore('readwrite'),
                    request = store.delete(id);

                request.onsuccess = callback;
            });
        },

        getAll: function(callback){

            db.open(function(){

                var
                    store = db.getObjectStore(),
                    cursor = store.openCursor(),
                    data = [];

                cursor.onsuccess = function (e) {

                    var result = e.target.result;

                    if (result && result !== null) {
                        data.push(result.value);
                        result.continue();
                    } else {
                        callback(data);
                    }
                };

            });
        },

        get: function(id, callback){

            id = parseInt(id);

            db.open(function(){

                var
                    store = db.getObjectStore(),
                    request = store.get(id);

                request.onsuccess = function(e){
                    callback(e.target.result);
                };
            });
        },

        deleteAll: function(callback){
            db.open(function(){

                var
                    store = db.getObjectStore('readwrite'),
                    request = store.clear();

                request.onsuccess = callback;
            });
        }
    };

    window.app = window.app || {};
    window.app.db = db;

}(window));<commit_msg>moved indexedb assignment to it's own IIFE<commit_after>// index.db.js
;(function(window){

    window.indexedDB =  window.indexedDB ||
                        window.mozIndexedDB ||
                        window.webkitIndexedDB ||
                        window.msIndexedDB;

    window.IDBTransaction =  window.IDBTransaction ||
                             window.webkitIDBTransaction ||
                             window.msIDBTransaction;

    window.IDBKeyRange = window.IDBKeyRange ||
                         window.webkitIDBKeyRange ||
                         window.msIDBKeyRange;
}(window));

(function(window){

    'use strict';

    var db = {

        version: 3, // important: only use whole numbers!

        objectStoreName: 'tasks',

        instance: {},

        upgrade: function(e) {

            var _db = e.target.result;

            if(!_db.objectStoreNames.contains(db.objectStoreName)){
                _db.createObjectStore(
                    db.objectStoreName,
                    { keyPath: 'id', autoIncrement: true});
            }
        },

        errorHandler: function(error){
            alert('error: ' + error.target.code);
            debugger;
        },

        getObjectStore: function(mode){
            var mode = mode || 'readonly';
            var txn = db.instance.transaction([db.objectStoreName], mode);
            var store = txn.objectStore(db.objectStoreName);

            return store;
        },

        open: function(callback){

            var request = window.indexedDB.open(
                            db.objectStoreName,
                            db.version);

            request.onerror = db.errorHandler;

            request.onupgradeneeded = db.upgrade;

            request.onsuccess = function(e){
                db.instance = request.result;
                db.instance.onerror = db.errorHandler;
                callback();
            };
        },

        save: function(note, callback){

            db.open(function(){

                var store = db.getObjectStore('readwrite'),
                    request;

                request = note.id ? store.put(note) : store.add(note);

                request.onsuccess = callback;
            });
        },

        'delete': function(id, callback){

            id = parseInt(id);

            db.open(function(){

                var
                    store = db.getObjectStore('readwrite'),
                    request = store.delete(id);

                request.onsuccess = callback;
            });
        },

        getAll: function(callback){

            db.open(function(){

                var
                    store = db.getObjectStore(),
                    cursor = store.openCursor(),
                    data = [];

                cursor.onsuccess = function (e) {

                    var result = e.target.result;

                    if (result && result !== null) {
                        data.push(result.value);
                        result.continue();
                    } else {
                        callback(data);
                    }
                };

            });
        },

        get: function(id, callback){

            id = parseInt(id);

            db.open(function(){

                var
                    store = db.getObjectStore(),
                    request = store.get(id);

                request.onsuccess = function(e){
                    callback(e.target.result);
                };
            });
        },

        deleteAll: function(callback){
            db.open(function(){

                var
                    store = db.getObjectStore('readwrite'),
                    request = store.clear();

                request.onsuccess = callback;
            });
        }
    };

    window.app = window.app || {};
    window.app.db = db;

}(window));<|endoftext|>