<commit_before>/**
 *   JavaScript Modelling Framework (JSMF)
 *   Copyright 2014 © Henri Tudor
 * 	 Copyright 2015 © LIST
 *   Authors : J.S. Sottet, A Vagner
 *
 *    Todo
 *      | Inheritance, Attributes and references overloading: Tested - Still missing For Reference inheritance
 *      - Get all the attribute of a given "Model"
 *      - implement different level of checking (type) : different conformances-flexibility
 *      - Checking for type in references according to supertypes inheritance chain
 *      - Setting and Checking for types that are not JS primitive types (attributes)
 *      - Persistence and Loading using JSON
 *      - Enhance Persistence/check persistence with Neo4J -> using batch / update
 *      - load model from db neo4J?
 *		- Add keyword "Any" for loose typing?
 *      - Dynamic of objects/instances/classes e.g., adding an attribute to the clas after instanciation will allow the object to set/get the new attribute.
 *           - also see conformance flexibility
 *      - Permit the addition of new attribute/relation without behing an instance of a specific class
 *            - also see conformance flexibility
 *      - Add the inference/generalisation of instance attribute to class
 *      - Add a checking between Models and Metamodel (conformance).
 *      - Do the Opposite relation automatic building.
 *      | Build a fonction that get all Attribute and/or all reference from the inheritance chain. To be tested
 *      | Demotion/Promotion (see JSMF_Utils) --> to be enhanced thanks to model<->reference model associations
 *
 *  Done
 *      - Build a filter function that get all the element of a given type
 *
 *  Bug
 *      - Inheritance issue (see Ava Bug)
 */

var modelDB = require('./JSMFNeo4j.js'); // not direclty requiering Neo4J-JSMF
var _ = require('underscore');

//DEF: Check Type Strict, Partial, None | Check Cardinality Strict, Partial, None, ...
//Natural => Formal
function Model(name) {
    this.__name = name;
    this.referenceModel = {}; //set the metamodel of this
    this.modellingElements = {};
}

//WARNING CHECK if classs is defined
Model.prototype.setModellingElement = function (Class) {
    var tab = [];
    if (Class.__name == undefined) {
        tab = this.modellingElements[Class.conformsTo().__name];
        if (tab == undefined) {
            tab = [];
        }

        tab.push(Class);
       // console.log('ConformsTo : ', Class.conformsTo().__name);
        this.modellingElements[Class.conformsTo().__name] = tab;
    } else {
        if (tab == undefined) {
            tab = [];
        }
        tab.push(Class);
        this.modellingElements[Class.__name] = tab;

    }
};

//
Model.prototype.setModellingElements = function (ClassTab) {
    if (ClassTab instanceof Array) {
        for (i in ClassTab) {
            if (ClassTab[i].__name == undefined) { //i.e. not  a meta-element
                var tab = [];

                tab = this.modellingElements[ClassTab[i].conformsTo().__name];
                if (tab == undefined) {
                    tab = [];
                }
                tab.push(ClassTab[i]);
                this.modellingElements[ClassTab[i].conformsTo().__name] = tab;
               // console.log('Conformsto: ', ClassTab[i].conformsTo().__name);
            } else {
                this.modellingElements[ClassTab[i].__name] = ClassTab[i];
            }
        }
    } else {
        console.error("Unable to set one element use Model.setModellingElements calling setModellingElement with only one element.");
        this.setModellingElement(ClassTab);
    }
};

//Send to JSMF Util?
Model.prototype.getPersistedID = function (ModelElement) {
    var result = modelDB.resolve(ModelElement);
    return result;
}

//Send to JSMF Util?
Model.prototype.contains = function (ModelElement) {
    var indexM = ModelElement.conformsTo().__name;
    var result = _.contains(this.modellingElements[indexM], ModelElement);
    return result;
}

Model.prototype.Filter = function(Classifier) {
 return this.modellingElements[Classifier.__name] ;

}

Model.prototype.setReferenceModel = function (metamodel) {
    this.referenceModel = metamodel;
}

//WARNING model could be correct in JSMF sense but not in Neo4J.
Model.prototype.save = function () {
    // CHECK that ALL Referenced elements are valid in the DB : i.e., they have at least one attribute which is set...
    modelDB.saveModel(this);
}

//M2
function Class(name) {
    this.__name = name;
    this.__attributes = {};
    this.__references = {};
    this.__superType = {};
}

Class.newInstance = function (classname){
	var Obj = new Class(classname);  //here check promote/demote functions
	return Obj;
};

//Class conformsTo itself (metacircularity)
Class.conformsTo = function() {
	return Class;

};

Class.prototype.setAttribute = function (name, type) {
    if (_.contains(this.__attributes, name)) {} else {
        this.__attributes[name] = type;
    }
};

Class.prototype.setSuperType = function (Class) {
    this.__superType[Class.__name] = Class;
}

Class.prototype.getInheritanceChain = function(result) {

    if (Object.getOwnPropertyNames(this.__superType).length == 0 || this.__superType == undefined) {
        return result;
    } else {
        for(i in this.__superType) {
			result.push(this.__superType[i]);
		}
        return this.__superType[i].getInheritanceChain(result);
    }
}

//
Class.prototype.getAllReferences = function() {
    var result={};
    _.each(this.__references, function(elem, index) {
        result[index]=elem;
    });
    var allsuperTypes = this.getInheritanceChain([]);
    for(var i in allsuperTypes) {
		refSuperType = allsuperTypes[i];
        _.each(refSuperType.__references, function(elem, index) {
            result[index]=elem;
        });
	}
    return result;
}

Class.prototype.getAllAttributes = function() {
    var result=[];

    result.push(this.__attributes)
    var allsuperTypes = this.getInheritanceChain([]);
    for(var i in allsuperTypes) {
		refSuperType = allsuperTypes[i];
        result.push(refSuperType.__attributes);
	}
    return result;
}

//Instance of MetaClass is conforms to Class.
Class.prototype.conformsTo = function () {
    //var result = new Class("M3Class");
    //result = this; //incorrect hypothesis <=> not self defined
    return Class; //.prototype;
};

//Relation nature: Composition: added +unprecised number of arguments key/value toset some addition info on the reference.
Class.prototype.setReference = function (name, type, cardinality, opposite, composite) {
    //check name?
    this.__references[name] = {
        "type": type, //should check the type?
        "card": cardinality
    }
    //To be TESTED
    if (opposite !== undefined) {
        var tmp = this.__references[name];
        tmp.opposite = opposite;
    }
    if (composite !== undefined) {
         var tmp = this.__references[name];
        tmp.composite = composite;
    }
};

/******************************
//Enum definition : should extend class? or a super class classifier?
*****************************/
function Enum(name) {
    this.__name = name;
    this.__literals = {};
    return this;
}

Enum.prototype.conformsTo = function() {return Enum;}

Enum.prototype.setLiteral = function(name, value) {
     if (_.contains(this.__literals, name)) {} else {
        this.__literals[name]=value;
     }
};

Enum.prototype.getValue= function(name) {
    return this.__literals[name];
}

/****************************************************************************************
*       Building Instance: attributes and references conforms to metamodel elements
****************************************************************************************/
function makeAssignation(ob, index, attype) {
    //if attype = primitive JS type else ...
    var type = new attype;
    return function (param) {
        if (param.__proto__ == type.__proto__) { //Strict equal?
            ob[index] = param;
        } else {
            console.log("Assigning wrong type: " + param.__proto__ + " expected " + type.__proto__);
        }
    };
}

// Adding the creaiton of opposite except for ARRAY of Type
function makeReference(ob, index, type, card, opposite) {
    return function (param) {
        //CheckCardinalities
        var elementsinrelation = ob[index].length;
        if (card == 1 && elementsinrelation >= 1) {
            console.log("error trying to assign multiple elements to a single reference");
        } else {
            if (type === Class) { // <=> bypasscheckType, equivalent to any
                ob[index].push(param);
            } else {
                if (type instanceof Array) { //Checking all the element type in array
                    if (_.contains(type, param.conformsTo())) {
                        ob[index].push(param);
                    } else {
                        console.log("assigning wrong type: " + param.conformsTo().__name + " Expecting types in " + type);
                    }
                } else {
                    if (type == param.conformsTo() || _.contains(type,param.conformsTo().getInheritanceChain([]))) { //|| _.contains(type, param.getInheritanceChain([])) //WARNING : Debugging Inheritance issue by Ava
                        //Check if the object is not already in reference collection<?
                        if(_.contains(ob[index],param)) {
                            console.log("Error trying to assign already assigned object: "+ param);
                            //maybe assigning it because of circular opposite relation
                        } else {
                            ob[index].push(param);
                            if(opposite!=undefined) {
                                var functionStr = 'set'+opposite;
                                param[functionStr](ob); //WARNING IF PARAM IS NOT CURRENTLY DEFINED? -> push 2 times....
                            }
                        }
                    } else {
                        console.log(_.contains(param.conformsTo().getInheritanceChain([])),type);
                        console.log(param.conformsTo().getInheritanceChain([]))
                        //ob[index].push(param); //WARNING DO the push if type
                        console.log("assigning wrong type: " + param.conformsTo().__name + " to current reference." + " Type " + type.__name + " was expected");
                    }
                }
            }
        }
    };
}

Class.prototype.newInstance = function (name) {
    var result = {};
    var self = this;

    //Get all the super types of the current instance
    var allsuperType = this.getInheritanceChain([]);

    //create setter for attributes from superclass
	for(var i in allsuperType) {
		refSuperType = allsuperType[i];
        for (var sup in refSuperType.__attributes) {
         	result[sup] = new refSuperType.__attributes[sup]();
            var attype = refSuperType.__attributes[sup];
            result["set" + sup] = makeAssignation(result, sup, attype);
       	}
        //do the same for references
        for (var sup in refSuperType.__references) {
            result[sup] = [];
            var type = refSuperType.__references[sup].type;
            var card = refSuperType.__references[sup].card;
            var opposite = refSuperType.__references[sup].opposite;
            result["set" + sup] = makeReference(result, sup, type, card, opposite);
        }
	}

    //create setter for attributes (super attributes will be overwritten if they have the same name)
    for (var i in this.__attributes) {
        if(this.__attributes[i].conformsTo== undefined) {
            result[i] = new this.__attributes[i](); //Warning work for JS primitive types... and any function ... but not for enum type overload primitves?
            var attype = this.__attributes[i];
        } else {
            console.log(this.__attributes[i]);
        }
        result["set" + i] = makeAssignation(result, i, attype);
    }

    //create setter for references (super references will be overwritten if they have the same name)
    for (var j in this.__references) {
        result[j] = [];
        var type = this.__references[j].type;
        var card = this.__references[j].card;
        var opposite = this.__references[j].opposite;
        result["set" + j] = makeReference(result, j, type, card, opposite);
    }

    // Assign the "type" to which M1 class is conform to.
    result.conformsTo = function () {
        return self;
    };

    return result;
};

//Export three main framework functions
module.exports = {

    Class: Class,

    Model: Model,

    Enum : Enum

};<commit_msg>JSMF opposite + checking for double assignation of the same referenced object<commit_after>/**
 *   JavaScript Modelling Framework (JSMF)
 *   Copyright 2014 © Henri Tudor
 * 	 Copyright 2015 © LIST
 *   Authors : J.S. Sottet, A Vagner
 *
 *    Todo
 *      | Inheritance, Attributes and references overloading: Tested - Still missing For Reference inheritance
 *      - Get all the attribute of a given "Model"
 *      - implement different level of checking (type) : different conformances-flexibility
 *      - Checking for type in references according to supertypes inheritance chain
 *      - Setting and Checking for types that are not JS primitive types (attributes)
 *      - Persistence and Loading using JSON
 *      - Enhance Persistence/check persistence with Neo4J -> using batch / update
 *      - load model from db neo4J?
 *		- Add keyword "Any" for loose typing?
 *      - Dynamic of objects/instances/classes e.g., adding an attribute to the clas after instanciation will allow the object to set/get the new attribute.
 *           - also see conformance flexibility
 *      - Permit the addition of new attribute/relation without behing an instance of a specific class
 *            - also see conformance flexibility
 *      - Add the inference/generalisation of instance attribute to class
 *      - Add a checking between Models and Metamodel (conformance).
 *      - Do the Opposite relation automatic building.
 *      | Build a fonction that get all Attribute and/or all reference from the inheritance chain. To be tested
 *      | Demotion/Promotion (see JSMF_Utils) --> to be enhanced thanks to model<->reference model associations
 *
 *  Done
 *      - Build a filter function that get all the element of a given type
 *
 *  Bug
 *      - Inheritance issue (see Ava Bug)
 */

var modelDB = require('./JSMFNeo4j.js'); // not direclty requiering Neo4J-JSMF
var _ = require('underscore');

//DEF: Check Type Strict, Partial, None | Check Cardinality Strict, Partial, None, ...
//Natural => Formal
function Model(name) {
    this.__name = name;
    this.referenceModel = {}; //set the metamodel of this
    this.modellingElements = {};
}

//WARNING CHECK if classs is defined
Model.prototype.setModellingElement = function (Class) {
    var tab = [];
    if (Class.__name == undefined) {
        tab = this.modellingElements[Class.conformsTo().__name];
        if (tab == undefined) {
            tab = [];
        }

        tab.push(Class);
       // console.log('ConformsTo : ', Class.conformsTo().__name);
        this.modellingElements[Class.conformsTo().__name] = tab;
    } else {
        if (tab == undefined) {
            tab = [];
        }
        tab.push(Class);
        this.modellingElements[Class.__name] = tab;

    }
};

//
Model.prototype.setModellingElements = function (ClassTab) {
    if (ClassTab instanceof Array) {
        for (i in ClassTab) {
            if (ClassTab[i].__name == undefined) { //i.e. not  a meta-element
                var tab = [];

                tab = this.modellingElements[ClassTab[i].conformsTo().__name];
                if (tab == undefined) {
                    tab = [];
                }
                tab.push(ClassTab[i]);
                this.modellingElements[ClassTab[i].conformsTo().__name] = tab;
               // console.log('Conformsto: ', ClassTab[i].conformsTo().__name);
            } else {
                this.modellingElements[ClassTab[i].__name] = ClassTab[i];
            }
        }
    } else {
        console.error("Unable to set one element use Model.setModellingElements calling setModellingElement with only one element.");
        this.setModellingElement(ClassTab);
    }
};

//Send to JSMF Util?
Model.prototype.getPersistedID = function (ModelElement) {
    var result = modelDB.resolve(ModelElement);
    return result;
}

//Send to JSMF Util?
Model.prototype.contains = function (ModelElement) {
    var indexM = ModelElement.conformsTo().__name;
    var result = _.contains(this.modellingElements[indexM], ModelElement);
    return result;
}

Model.prototype.Filter = function(Classifier) {
 return this.modellingElements[Classifier.__name] ;

}

Model.prototype.setReferenceModel = function (metamodel) {
    this.referenceModel = metamodel;
}

//WARNING model could be correct in JSMF sense but not in Neo4J.
Model.prototype.save = function () {
    // CHECK that ALL Referenced elements are valid in the DB : i.e., they have at least one attribute which is set...
    modelDB.saveModel(this);
}

//M2
function Class(name) {
    this.__name = name;
    this.__attributes = {};
    this.__references = {};
    this.__superType = {};
}

Class.newInstance = function (classname){
	var Obj = new Class(classname);  //here check promote/demote functions
	return Obj;
};

//Class conformsTo itself (metacircularity)
Class.conformsTo = function() {
	return Class;

};

Class.prototype.setAttribute = function (name, type) {
    if (_.contains(this.__attributes, name)) {} else {
        this.__attributes[name] = type;
    }
};

Class.prototype.setSuperType = function (Class) {
    this.__superType[Class.__name] = Class;
}

Class.prototype.getInheritanceChain = function(result) {

    if (Object.getOwnPropertyNames(this.__superType).length == 0 || this.__superType == undefined) {
        return result;
    } else {
        for(i in this.__superType) {
			result.push(this.__superType[i]);
		}
        return this.__superType[i].getInheritanceChain(result);
    }
}

//
Class.prototype.getAllReferences = function() {
    var result={};
    _.each(this.__references, function(elem, index) {
        result[index]=elem;
    });
    var allsuperTypes = this.getInheritanceChain([]);
    for(var i in allsuperTypes) {
		refSuperType = allsuperTypes[i];
        _.each(refSuperType.__references, function(elem, index) {
            result[index]=elem;
        });
	}
    return result;
}

Class.prototype.getAllAttributes = function() {
    var result=[];

    result.push(this.__attributes)
    var allsuperTypes = this.getInheritanceChain([]);
    for(var i in allsuperTypes) {
		refSuperType = allsuperTypes[i];
        result.push(refSuperType.__attributes);
	}
    return result;
}

//Instance of MetaClass is conforms to Class.
Class.prototype.conformsTo = function () {
    //var result = new Class("M3Class");
    //result = this; //incorrect hypothesis <=> not self defined
    return Class; //.prototype;
};

//Relation nature: Composition: added +unprecised number of arguments key/value toset some addition info on the reference.
Class.prototype.setReference = function (name, type, cardinality, opposite, composite) {
    //check name?
    this.__references[name] = {
        "type": type, //should check the type?
        "card": cardinality
    }
    //To be TESTED
    if (opposite !== undefined) {
        var tmp = this.__references[name];
        tmp.opposite = opposite;
    }
    if (composite !== undefined) {
         var tmp = this.__references[name];
        tmp.composite = composite;
    }
};

/******************************
//Enum definition : should extend class? or a super class classifier?
*****************************/
function Enum(name) {
    this.__name = name;
    this.__literals = {};
    return this;
}

Enum.prototype.conformsTo = function() {return Enum;}

Enum.prototype.setLiteral = function(name, value) {
     if (_.contains(this.__literals, name)) {} else {
        this.__literals[name]=value;
     }
};

Enum.prototype.getValue= function(name) {
    return this.__literals[name];
}

/****************************************************************************************
*       Building Instance: attributes and references conforms to metamodel elements
****************************************************************************************/
function makeAssignation(ob, index, attype) {
    //if attype = primitive JS type else ...
    var type = new attype;
    return function (param) {
        if (param.__proto__ == type.__proto__) { //Strict equal?
            ob[index] = param;
        } else {
            console.log("Assigning wrong type: " + param.__proto__ + " expected " + type.__proto__);
        }
    };
}

// Adding the creaiton of opposite except for ARRAY of Type
function makeReference(ob, index, type, card, opposite) {
    return function (param) {
        //CheckCardinalities
        var elementsinrelation = ob[index].length;
        if (card == 1 && elementsinrelation >= 1) {
            console.log("error trying to assign multiple elements to a single reference");
        } else {
            if (type === Class) { // <=> bypasscheckType, equivalent to any
                ob[index].push(param);
            } else {
                if (type instanceof Array) { //Checking all the element type in array
                    if (_.contains(type, param.conformsTo())) {
                        ob[index].push(param);
                    } else {
                        console.log("assigning wrong type: " + param.conformsTo().__name + " Expecting types in " + type);
                    }
                } else {
                    if (type == param.conformsTo() || _.contains(type,param.conformsTo().getInheritanceChain([]))) { //|| _.contains(type, param.getInheritanceChain([])) //WARNING : Debugging Inheritance issue by Ava
                        //Check if the object is not already in reference collection<?
                        if(_.contains(ob[index],param)) {
                            console.log("Error trying to assign already assigned object of relation "+ index);
                            //maybe assigning it because of circular opposite relation
                        } else {
                            ob[index].push(param); //ob[index]=param...
                            if(opposite!=undefined) {
                                var functionStr = 'set'+opposite;
                                param[opposite].push(ob);
                                //param[functionStr](ob); // using object function but consequently it is trying to push 2 times.... but have all the checks...
                                //even for inheritance
                            }
                        }
                    } else {
                        console.log(_.contains(param.conformsTo().getInheritanceChain([])),type);
                        console.log(param.conformsTo().getInheritanceChain([]))
                        //ob[index].push(param); //WARNING DO the push if type
                        console.log("assigning wrong type: " + param.conformsTo().__name + " to current reference." + " Type " + type.__name + " was expected");
                    }
                }
            }
        }
    };
}

Class.prototype.newInstance = function (name) {
    var result = {};
    var self = this;

    //Get all the super types of the current instance
    var allsuperType = this.getInheritanceChain([]);

    //create setter for attributes from superclass
	for(var i in allsuperType) {
		refSuperType = allsuperType[i];
        for (var sup in refSuperType.__attributes) {
         	result[sup] = new refSuperType.__attributes[sup]();
            var attype = refSuperType.__attributes[sup];
            result["set" + sup] = makeAssignation(result, sup, attype);
       	}
        //do the same for references
        for (var sup in refSuperType.__references) {
            result[sup] = [];
            var type = refSuperType.__references[sup].type;
            var card = refSuperType.__references[sup].card;
            var opposite = refSuperType.__references[sup].opposite;
            result["set" + sup] = makeReference(result, sup, type, card, opposite);
        }
	}

    //create setter for attributes (super attributes will be overwritten if they have the same name)
    for (var i in this.__attributes) {
        if(this.__attributes[i].conformsTo== undefined) {
            result[i] = new this.__attributes[i](); //Warning work for JS primitive types... and any function ... but not for enum type overload primitves?
            var attype = this.__attributes[i];
        } else {
            console.log(this.__attributes[i]);
        }
        result["set" + i] = makeAssignation(result, i, attype);
    }

    //create setter for references (super references will be overwritten if they have the same name)
    for (var j in this.__references) {
        result[j] = [];
        var type = this.__references[j].type;
        var card = this.__references[j].card;
        var opposite = this.__references[j].opposite;
        result["set" + j] = makeReference(result, j, type, card, opposite);
    }

    // Assign the "type" to which M1 class is conform to.
    result.conformsTo = function () {
        return self;
    };

    return result;
};

//Export three main framework functions
module.exports = {

    Class: Class,

    Model: Model,

    Enum : Enum

};<|endoftext|>


<commit_before>/*
 *  File:		defaults.js
 *  Purpose:	Default values, settings and initial values for the app
 *  Author:		Adam Reed (adam@secretcode.ninja)
 *  Licence:	BSD 3-Clause Licence
 */

var app = angular.module('BlueCube.defaults', [])

// Default settings for key parts of the app
app.constant('appDefaults', {
	// Whether to attempt to auto connect to the cube ("true" | "false")
	autoConnect: "true",

	// Whether to send colour changes automatically in the All view ("true" | "false")
	liveAllColourChanges: "true",

	// Minimum and Maximum allowable history items (I recommend keeping this between 20 and 200)
	minAllowedHistoryItems: 20,
	maxAllowedHistoryItems: 200,

	// Maximum number of items to keep in the history (it should be between minAllowedHistoryItems
	// and maxAllowedHistoryItems set above)
	maxHistoryItems: 100,

	// Items for RSSI Signal Strength Indicator, that set the bounds for what we consider full
	// signal strength and at where we consider we have no signal.
	signalConsideredFullStrengthAt: -30,
	signalConsideredNoStrengthAt: -100,
});

// Bluetooth LE Characteristic and search time
app.constant('bleDefaults', {
	// Characteristics for the Nordic's UART Service as used by the Adafruit Bluefruit LE devices
	serviceUUID: '6e400001-b5a3-f393-e0a9-e50e24dcca9e',
	txCharacteristic: '6e400002-b5a3-f393-e0a9-e50e24dcca9e',	// transmit is from the phone's perspective
	rxCharacteristic: '6e400003-b5a3-f393-e0a9-e50e24dcca9e',	// receive is from the phone's perspective
	searchTime: 3	// seconds
});

// Default settings for Colours within the app
app.constant('colourDefaults', {
	// The default colour used for the colour picker if the user hasn't previously selected a
	// colour
	defaultColour: '00d1ff',

	// The default colour used for the second colour picker (if required) if the user hasn't
	// previously selected a colour
	otherColour: 'f80ed1',

	// The default favourite colours. These match the defined colours in the Cube Library, but there
	// is no reason that they can't be changed
	favouriteColours:	[
							{
								id: 1,
								hex: '000000',	// Black
							},
							{
								id: 2,
								hex: '0000FF',	// Blue
							},
							{
								id: 3,
								hex: '00ff00',	// Green
							},
							{
								id: 4,
								hex: 'ff4500',	// Orange
							},
							{
								id: 5,
								hex: 'ff1444',	// Pink
							},
							{
								id: 6,
								hex: 'ff00ff',	// Purple
							},
							{
								id: 7,
								hex: 'ff0000',	// Red
							},
							{
								id: 8,
								hex: 'ffffff',	// White
							},
							{
								id: 9,
								hex: 'ffff00',	// Yellow
							}
						],

	// To ensure that each favourite colour has a unique ID, we store the next ID that should
	// be used. It's 10 because we have 9 favourites above already defined.
	favouriteColoursNextIndex: 10,
});

// Default settings for the Set, Copy and Move Plane Views
app.constant('axisDefaults', {
	// Default axis to select ('X' | 'Y' | 'Z')
	axis: 'X',

	// The first or only offset to use ('0' | '1' | '2' | '3')
	fromOffset: '0',

	// The second offset to use ('0' | '1' | '2' | '3')
	toOffset: '1',
});

// Define the defaults for the Box and Sphere views
app.constant('graphicsDefaults', {
	/* boxStyle:	0 = Solid
					1 = Walls Only
					2 = Edges Only
					3 = Walls Filled
					4 = Edges Filled */
	boxStyle: '0',

	/* sphereStyle:	0: Walls Only
					1: Solid */
	sphereStyle: '0',

	// sphereSize:	3 or 4
	sphereSize: '3',
});

// Initially provided static favourites
app.constant('staticFavouritesDefaults', {
	// A sample set of static favourites to get the user started
	staticFavourites: 	[
							{
								id: 0,
								name: "Rainbow",
								cmds:	[
											{"id":1,"cmd":"set 000 180064;"},
											{"id":2,"cmd":"set 001 0C0032;"},
											{"id":3,"cmd":"set 002 060019;"},
											{"id":4,"cmd":"set 003 03000C;"},
											{"id":5,"cmd":"set 010 380044;"},
											{"id":6,"cmd":"set 011 1C0022;"},
											{"id":7,"cmd":"set 012 0E0011;"},
											{"id":8,"cmd":"set 013 070008;"},
											{"id":9,"cmd":"set 020 580024;"},
											{"id":10,"cmd":"set 021 2C0012;"},
											{"id":11,"cmd":"set 022 160009;"},
											{"id":12,"cmd":"set 023 0B0004;"},
											{"id":13,"cmd":"set 030 780004;"},
											{"id":14,"cmd":"set 031 3C0002;"},
											{"id":15,"cmd":"set 032 1E0001;"},
											{"id":16,"cmd":"set 033 0F0000;"},
											{"id":17,"cmd":"set 130 641800;"},
											{"id":18,"cmd":"set 131 320C00;"},
											{"id":19,"cmd":"set 132 190600;"},
											{"id":20,"cmd":"set 133 0C0300;"},
											{"id":21,"cmd":"set 230 443800;"},
											{"id":22,"cmd":"set 231 221C00;"},
											{"id":23,"cmd":"set 232 110E00;"},
											{"id":24,"cmd":"set 233 080700;"},
											{"id":25,"cmd":"set 330 245800;"},
											{"id":26,"cmd":"set 331 122C00;"},
											{"id":27,"cmd":"set 332 091600;"},
											{"id":28,"cmd":"set 333 040B00;"},
											{"id":29,"cmd":"set 320 047800;"},
											{"id":30,"cmd":"set 321 023C00;"},
											{"id":31,"cmd":"set 322 011E00;"},
											{"id":32,"cmd":"set 323 000F00;"},
											{"id":33,"cmd":"set 310 006418;"},
											{"id":34,"cmd":"set 311 00320C;"},
											{"id":35,"cmd":"set 312 001906;"},
											{"id":36,"cmd":"set 313 000C03;"},
											{"id":37,"cmd":"set 300 004438;"},
											{"id":38,"cmd":"set 301 00221C;"},
											{"id":39,"cmd":"set 302 00110E;"},
											{"id":40,"cmd":"set 303 000807;"},
											{"id":41,"cmd":"set 200 002458;"},
											{"id":42,"cmd":"set 201 00122C;"},
											{"id":43,"cmd":"set 202 000916;"},
											{"id":44,"cmd":"set 203 00040B;"},
											{"id":45,"cmd":"set 100 000478;"},
											{"id":46,"cmd":"set 101 00023C;"},
											{"id":47,"cmd":"set 102 00011E;"},
											{"id":48,"cmd":"set 103 00000F;"},
											{"id":49,"cmd":"set 110 180064;"},
											{"id":50,"cmd":"set 111 0C0032;"},
											{"id":51,"cmd":"set 112 060019;"},
											{"id":52,"cmd":"set 113 03000C;"},
											{"id":53,"cmd":"set 120 780004;"},
											{"id":54,"cmd":"set 121 3C0002;"},
											{"id":55,"cmd":"set 122 1E0001;"},
											{"id":56,"cmd":"set 123 0F0000;"},
											{"id":57,"cmd":"set 220 245800;"},
											{"id":58,"cmd":"set 221 122C00;"},
											{"id":59,"cmd":"set 222 091600;"},
											{"id":60,"cmd":"set 223 040B00;"},
											{"id":61,"cmd":"set 210 004438;"},
											{"id":62,"cmd":"set 211 00221C;"},
											{"id":63,"cmd":"set 212 00110E;"},
											{"id":64,"cmd":"set 213 000807;"}
										]
							},
						{
							id: 1,
							name: "All Black",
							cmds:	[
										{"id":1,"cmd":"all 000000;"}
									]
						},
						{
							id: 2,
							name: "Crossed Planes",
							cmds:	[
										{"id":1,"cmd":"setplane X 2 0000ff;"},
										{"id":2,"cmd":"setplane Y 1 3DF400;"}
									]
						},
						{
							id: 3,
							name: "Filled Sphere",
							cmds:	[
										{"id":1,"cmd":"sphere 111 ff0000 00ff00;"},
										{"id":2,"cmd":"box 000 333 0000ff 2;"}
									]
						}
					],

	// To ensure that each static favourite has a unique ID, we store the next ID that should
	// be used. It's 4 because we have 3 static favourites above already defined.
	staticFavouritesNextIndex: 4,
});

// Initially provided user defined functions
app.constant('userDefinedFunctionsDefaults', {
	// Provide a sample set of user defined functions to match those that ship with the included
	// Arduino sketch
	userDefinedFunctions:	[
								{
									id: 0,
									name: "Pulse Blue",
									number: 1,
									colourRequired: true,
									colour: "0000ff",
								},
								{
									id: 1,
									name: "Pulse Green",
									number: 1,
									colourRequired: true,
									colour: "00ff00",
								},
								{
									id: 2,
									name: "Wave",
									number: 2,
									colourRequired: true,
									colour: "fc00ff",
								},
								{
									id: 3,
									name: "ZigZag",
									number: 3,
									colourRequired: true,
									colour: "b7ff00",
								}
							],

	// To ensure that each user defined function has a unique ID, we store the next ID that should
	// be used. It's 4 because we have 3 user defined functions above already defined.
	userDefinedFunctionsNextIndex: 4,
});
<commit_msg>Change the rainbow static favourite so that it wraps around the cube.<commit_after>/*
 *  File:		defaults.js
 *  Purpose:	Default values, settings and initial values for the app
 *  Author:		Adam Reed (adam@secretcode.ninja)
 *  Licence:	BSD 3-Clause Licence
 */

var app = angular.module('BlueCube.defaults', [])

// Default settings for key parts of the app
app.constant('appDefaults', {
	// Whether to attempt to auto connect to the cube ("true" | "false")
	autoConnect: "true",

	// Whether to send colour changes automatically in the All view ("true" | "false")
	liveAllColourChanges: "true",

	// Minimum and Maximum allowable history items (I recommend keeping this between 20 and 200)
	minAllowedHistoryItems: 20,
	maxAllowedHistoryItems: 200,

	// Maximum number of items to keep in the history (it should be between minAllowedHistoryItems
	// and maxAllowedHistoryItems set above)
	maxHistoryItems: 100,

	// Items for RSSI Signal Strength Indicator, that set the bounds for what we consider full
	// signal strength and at where we consider we have no signal.
	signalConsideredFullStrengthAt: -30,
	signalConsideredNoStrengthAt: -100,
});

// Bluetooth LE Characteristic and search time
app.constant('bleDefaults', {
	// Characteristics for the Nordic's UART Service as used by the Adafruit Bluefruit LE devices
	serviceUUID: '6e400001-b5a3-f393-e0a9-e50e24dcca9e',
	txCharacteristic: '6e400002-b5a3-f393-e0a9-e50e24dcca9e',	// transmit is from the phone's perspective
	rxCharacteristic: '6e400003-b5a3-f393-e0a9-e50e24dcca9e',	// receive is from the phone's perspective
	searchTime: 3	// seconds
});

// Default settings for Colours within the app
app.constant('colourDefaults', {
	// The default colour used for the colour picker if the user hasn't previously selected a
	// colour
	defaultColour: '00d1ff',

	// The default colour used for the second colour picker (if required) if the user hasn't
	// previously selected a colour
	otherColour: 'f80ed1',

	// The default favourite colours. These match the defined colours in the Cube Library, but there
	// is no reason that they can't be changed
	favouriteColours:	[
							{
								id: 1,
								hex: '000000',	// Black
							},
							{
								id: 2,
								hex: '0000FF',	// Blue
							},
							{
								id: 3,
								hex: '00ff00',	// Green
							},
							{
								id: 4,
								hex: 'ff4500',	// Orange
							},
							{
								id: 5,
								hex: 'ff1444',	// Pink
							},
							{
								id: 6,
								hex: 'ff00ff',	// Purple
							},
							{
								id: 7,
								hex: 'ff0000',	// Red
							},
							{
								id: 8,
								hex: 'ffffff',	// White
							},
							{
								id: 9,
								hex: 'ffff00',	// Yellow
							}
						],

	// To ensure that each favourite colour has a unique ID, we store the next ID that should
	// be used. It's 10 because we have 9 favourites above already defined.
	favouriteColoursNextIndex: 10,
});

// Default settings for the Set, Copy and Move Plane Views
app.constant('axisDefaults', {
	// Default axis to select ('X' | 'Y' | 'Z')
	axis: 'X',

	// The first or only offset to use ('0' | '1' | '2' | '3')
	fromOffset: '0',

	// The second offset to use ('0' | '1' | '2' | '3')
	toOffset: '1',
});

// Define the defaults for the Box and Sphere views
app.constant('graphicsDefaults', {
	/* boxStyle:	0 = Solid
					1 = Walls Only
					2 = Edges Only
					3 = Walls Filled
					4 = Edges Filled */
	boxStyle: '0',

	/* sphereStyle:	0: Walls Only
					1: Solid */
	sphereStyle: '0',

	// sphereSize:	3 or 4
	sphereSize: '3',
});

// Initially provided static favourites
app.constant('staticFavouritesDefaults', {
	// A sample set of static favourites to get the user started
	staticFavourites: 	[
							{
								id: 0,
								name: "Rainbow",
								cmds:	[
											{"id":1,"cmd":"set 000 180064;"},
											{"id":2,"cmd":"set 011 0C0032;"},
											{"id":3,"cmd":"set 022 060019;"},
											{"id":4,"cmd":"set 033 03000C;"},
											{"id":5,"cmd":"set 010 380044;"},
											{"id":6,"cmd":"set 021 1C0022;"},
											{"id":7,"cmd":"set 032 0E0011;"},
											{"id":8,"cmd":"set 133 070008;"},
											{"id":9,"cmd":"set 020 580024;"},
											{"id":10,"cmd":"set 031 2C0012;"},
											{"id":11,"cmd":"set 132 160009;"},
											{"id":12,"cmd":"set 233 0B0004;"},
											{"id":13,"cmd":"set 030 780004;"},
											{"id":14,"cmd":"set 131 3C0002;"},
											{"id":15,"cmd":"set 232 1E0001;"},
											{"id":16,"cmd":"set 333 0F0000;"},
											{"id":17,"cmd":"set 130 641800;"},
											{"id":18,"cmd":"set 231 320C00;"},
											{"id":19,"cmd":"set 332 190600;"},
											{"id":20,"cmd":"set 323 0C0300;"},
											{"id":21,"cmd":"set 230 443800;"},
											{"id":22,"cmd":"set 331 221C00;"},
											{"id":23,"cmd":"set 322 110E00;"},
											{"id":24,"cmd":"set 313 080700;"},
											{"id":25,"cmd":"set 330 245800;"},
											{"id":26,"cmd":"set 321 122C00;"},
											{"id":27,"cmd":"set 312 091600;"},
											{"id":28,"cmd":"set 303 040B00;"},
											{"id":29,"cmd":"set 320 047800;"},
											{"id":30,"cmd":"set 311 023C00;"},
											{"id":31,"cmd":"set 302 011E00;"},
											{"id":32,"cmd":"set 203 000F00;"},
											{"id":33,"cmd":"set 310 006418;"},
											{"id":34,"cmd":"set 301 00320C;"},
											{"id":35,"cmd":"set 202 001906;"},
											{"id":36,"cmd":"set 103 000C03;"},
											{"id":37,"cmd":"set 300 004438;"},
											{"id":38,"cmd":"set 201 00221C;"},
											{"id":39,"cmd":"set 102 00110E;"},
											{"id":40,"cmd":"set 003 000807;"},
											{"id":41,"cmd":"set 200 002458;"},
											{"id":42,"cmd":"set 101 00122C;"},
											{"id":43,"cmd":"set 002 000916;"},
											{"id":44,"cmd":"set 013 00040B;"},
											{"id":45,"cmd":"set 100 000478;"},
											{"id":46,"cmd":"set 001 00023C;"},
											{"id":47,"cmd":"set 012 00011E;"},
											{"id":48,"cmd":"set 023 00000F;"},
											{"id":49,"cmd":"set 110 180064;"},
											{"id":50,"cmd":"set 121 0C0032;"},
											{"id":51,"cmd":"set 222 060019;"},
											{"id":52,"cmd":"set 213 03000C;"},
											{"id":53,"cmd":"set 120 780004;"},
											{"id":54,"cmd":"set 221 3C0002;"},
											{"id":55,"cmd":"set 212 1E0001;"},
											{"id":56,"cmd":"set 113 0F0000;"},
											{"id":57,"cmd":"set 220 245800;"},
											{"id":58,"cmd":"set 211 122C00;"},
											{"id":59,"cmd":"set 112 091600;"},
											{"id":60,"cmd":"set 123 040B00;"},
											{"id":61,"cmd":"set 210 004438;"},
											{"id":62,"cmd":"set 111 00221C;"},
											{"id":63,"cmd":"set 122 00110E;"},
											{"id":64,"cmd":"set 223 000807;"}
										]
							},
							{
							id: 1,
							name: "All Black",
							cmds:	[
										{"id":1,"cmd":"all 000000;"}
									]
						},
						{
							id: 2,
							name: "Crossed Planes",
							cmds:	[
										{"id":1,"cmd":"setplane X 2 0000ff;"},
										{"id":2,"cmd":"setplane Y 1 3DF400;"}
									]
						},
						{
							id: 3,
							name: "Filled Sphere",
							cmds:	[
										{"id":1,"cmd":"sphere 111 ff0000 00ff00;"},
										{"id":2,"cmd":"box 000 333 0000ff 2;"}
									]
						}
					],

	// To ensure that each static favourite has a unique ID, we store the next ID that should
	// be used. It's 4 because we have 3 static favourites above already defined.
	staticFavouritesNextIndex: 4,
});

// Initially provided user defined functions
app.constant('userDefinedFunctionsDefaults', {
	// Provide a sample set of user defined functions to match those that ship with the included
	// Arduino sketch
	userDefinedFunctions:	[
								{
									id: 0,
									name: "Pulse Blue",
									number: 1,
									colourRequired: true,
									colour: "0000ff",
								},
								{
									id: 1,
									name: "Pulse Green",
									number: 1,
									colourRequired: true,
									colour: "00ff00",
								},
								{
									id: 2,
									name: "Wave",
									number: 2,
									colourRequired: true,
									colour: "fc00ff",
								},
								{
									id: 3,
									name: "ZigZag",
									number: 3,
									colourRequired: true,
									colour: "b7ff00",
								}
							],

	// To ensure that each user defined function has a unique ID, we store the next ID that should
	// be used. It's 4 because we have 3 user defined functions above already defined.
	userDefinedFunctionsNextIndex: 4,
});
<|endoftext|>


<commit_before>

demo.icestate = function(){};
demo.icestate.prototype = {
    preload: function(){
        loadImages();
        loadCatBoss();

        // make sure to set this to the size of the tile map
        game.world.setBounds(0, 0, 1000, 6000);

        // load in tile map assets
        game.load.tilemap('iceStage', 'assets/tilemaps/IceMap2.json', null, Phaser.Tilemap.TILED_JSON);
        game.load.image('ice_sprite', 'assets/tilemaps/ice_sprite.png');
        game.load.image('LargeLadderTop', 'assets/tilemaps/ice_ladder_sprite.png');
        game.load.image('tempBlueBlock', 'assets/tilemaps/blue_snow.png');
        game.load.image('tempGreenBlock', 'assets/tilemaps/green_snow.png');
        game.load.image('tempPurpleBlock', 'assets/tilemaps/purple_snow.png');
        game.load.image('LargeLadder', 'assets/tilemaps/ice_ladder_sprite.png');
    },

    create: function(){
//        game.physics.startSystem(Phaser.Physics.ARCADE);
//        cursors = game.input.keyboard.createCursorKeys();

        // stop all other sounds
        game.sound.stopAll();
        game.camera.y = game.world.height;

        // play background music
        guitar2 = game.add.audio('guitar2');

        guitar2.play('','',0.3,true,true);

        game.stage.backgroundColor = '#DDDDDD';

//        cursors = game.input.keyboard.createCursorKeys();

        // add in the tile map * make into function - creates dictionary and cycles through dictionary
        iceMap = game.add.tilemap('iceStage');
        iceMap.addTilesetImage('ice_sprite');
        iceMap.addTilesetImage('LargeLadder');
        iceMap.addTilesetImage('LargeLadderTop');
        iceMap.addTilesetImage('tempBlueBlock');
        iceMap.addTilesetImage('tempPurpleBlock');
        iceMap.addTilesetImage('tempGreenBlock');

        icelayer1 = iceMap.createLayer('Platforms');
        icelayer2 = iceMap.createLayer('Ladders');
        icelayer1.resizeWorld();
        icelayer2.resizeWorld();

        game.physics.arcade.enable(icelayer1);
        game.physics.arcade.enable(icelayer2);

        createChameleon(500,game.world.height - 300);

        place_cat_boss(0,0);

        iceMap.setCollision(12, true, icelayer1);
        iceMap.setCollisionBetween(1, 9, true, icelayer1)

        //prep for placing fruit and enemies and health packs
        createInventory(0,0);
        make_fruit_groups();
        make_enemy_groups();
        make_healthpack_groups();

        // place fruit
        placeHealthpack (700, 5400);
        placeFruit(700, game.world.height - 300, "bluefruit");
        placeFruit(650, game.world.height -450,"greenfruit");
        placeFruit(750, game.world.height - 1600, "bluefruit");
        placeFruit(150, 1000, "greenfruit");
        placeFruit(200, 300, "purplefruit");
        placeFruit(500, game.world.height - 1600, "purplefruit");
        placeFruit(825, 5025, "bluefruit");
        placeHealthpack(725,3275);
//        placeFruit(725, 3275, "greenfruit"); // put in moving platform to get to here
        placeFruit(400, 3125, "greenfruit");
        placeFruit(450, 2475, "bluefruit");
        placeFruit(675,1925, "purplefruit");
        placeFruit(275,8575,"greenfruit");
        placeFruit(775,875,"purplefruit");
        placeHealthpack(25, 250);
        placeFruit(925, 250, "greenfruit");
        placeFruit(450,2775, "purplefruit");

        placeHealthpack(500, 550);

//        // place enemies ( note don't put anything with y pos above 5050 )
        var bird1 = placeBird(275,5050,["green"]);

        // tween bird 2
        var bird2 = placeBird(575,3875,["blue"]);
        bird2.mytween = game.add.tween(bird2).to({x:[650, 575], y:[3875,3875]}, 1000, Phaser.Easing.Linear.None, true, 0, -1, false);

        placeSnake(325,3475, ["purple"]);

        // tween snake
        var snake1 = placeSnake(325, 4875, ["purple"]); // TWEEN THIS ENEMY!
        snake1.mytween = game.add.tween(snake1).to({x:[125, 325], y:[4875,4875]}, 1000, Phaser.Easing.Linear.None, true, 0, -1, false);

//        placeSnake(475, 775, "blue");
        placeBird(350,2475,["purple"]);
        placeBird(500, 2475, ["green"]);
//        placeBird(500,1650,["red"]);
//
//        // place moving platforms
        addMovingPlatforms();
        placeMP(325, 4025, 2, 1, 6, 0, 100, 0);
        placeMP(525, 3325, 3, 1, 4, 0, 150, 0);
//
//        make_balloon_group();
//        placeBalloon(200, 2300);

        // place health bar
        place_hearts(450, 0);

    },
    update: function(){
        // move the camera (if it wasnt obvious)
        move_camera(1,1);

        var tile_arr2 = get_surrounding_tiles(icelayer1, iceMap);
        collideIce(tile_arr2);

        // colide with icelayer and allow player to jump
        game.physics.arcade.collide(player, icelayer1);

        if (game.camera.y != 0) {
            // catboss stays asleep until 3 seconds after camera reaches the top
            cat_boss.throw_ball_timer = game.time.time + 3000;
        }
        var boss_collision_list = [icelayer1, icelayer2]
        cat_boss_move(boss_collision_list);

        player.tint = 0xffffff;
        // check for ballooning
        if (player.ballooning){
            chameleon_float();
        } else {
            chameleonmove();
        }

        // Game over if you fall off the screen
        if (game.camera.y+650 < player.body.y) {
            console.log("ICE");
            deadplayer(true);
        }

        // move enemies
        birds_group.forEach(moveBird, this);
        snakes_group.forEach(moveSnake, this);
        moving_platform_group.forEach(movingPlatformsUpdate, this);

        //checkforladders(iceMap, icelayer2);
        var tile_arr1 = get_surrounding_tiles(icelayer2, iceMap);
        ladder_movement(tile_arr1, 10, 11);

        update_health(player.health);

    }
};
<commit_msg>hopefully no merge error<commit_after>

demo.icestate = function(){};
demo.icestate.prototype = {
    preload: function(){
        loadImages();
        loadCatBoss();

        // make sure to set this to the size of the tile map
        game.world.setBounds(0, 0, 1000, 6000);

        // load in tile map assets
        game.load.tilemap('iceStage', 'assets/tilemaps/IceMap2.json', null, Phaser.Tilemap.TILED_JSON);
        game.load.image('ice_sprite', 'assets/tilemaps/ice_sprite.png');
        game.load.image('LargeLadderTop', 'assets/tilemaps/ice_ladder_sprite.png');
        game.load.image('tempBlueBlock', 'assets/tilemaps/blue_snow.png');
        game.load.image('tempGreenBlock', 'assets/tilemaps/green_snow.png');
        game.load.image('tempPurpleBlock', 'assets/tilemaps/purple_snow.png');
        game.load.image('LargeLadder', 'assets/tilemaps/ice_ladder_sprite.png');
    },

    create: function(){
//        game.physics.startSystem(Phaser.Physics.ARCADE);
//        cursors = game.input.keyboard.createCursorKeys();

        // stop all other sounds
        game.sound.stopAll();
        game.camera.y = game.world.height;

        // play background music
        guitar2 = game.add.audio('guitar2');

        guitar2.play('','',0.3,true,true);

        game.stage.backgroundColor = '#DDDDDD';

//        cursors = game.input.keyboard.createCursorKeys();

        // add in the tile map * make into function - creates dictionary and cycles through dictionary
        iceMap = game.add.tilemap('iceStage');
        iceMap.addTilesetImage('ice_sprite');
        iceMap.addTilesetImage('LargeLadder');
        iceMap.addTilesetImage('LargeLadderTop');
        iceMap.addTilesetImage('tempBlueBlock');
        iceMap.addTilesetImage('tempPurpleBlock');
        iceMap.addTilesetImage('tempGreenBlock');

        icelayer1 = iceMap.createLayer('Platforms');
        icelayer2 = iceMap.createLayer('Ladders');
        icelayer1.resizeWorld();
        icelayer2.resizeWorld();

        game.physics.arcade.enable(icelayer1);
        game.physics.arcade.enable(icelayer2);

        createChameleon(500,game.world.height - 300);

        place_cat_boss(0,0);

        iceMap.setCollision(12, true, icelayer1);
        iceMap.setCollisionBetween(1, 9, true, icelayer1);
        iceMap.setCollisionBetween(10, 11, true, icelayer2);

        //prep for placing fruit and enemies and health packs
        createInventory(0,0);
        make_fruit_groups();
        make_enemy_groups();
        make_healthpack_groups();

        // place fruit
        placeHealthpack (700, 5400);
        placeFruit(700, game.world.height - 300, "bluefruit");
        placeFruit(650, game.world.height -450,"greenfruit");
        placeFruit(750, game.world.height - 1600, "bluefruit");
        placeFruit(150, 1000, "greenfruit");
        placeFruit(200, 300, "purplefruit");
        placeFruit(500, game.world.height - 1600, "purplefruit");
        placeFruit(825, 5025, "bluefruit");
        placeHealthpack(725,3275);
//        placeFruit(725, 3275, "greenfruit"); // put in moving platform to get to here
        placeFruit(400, 3125, "greenfruit");
        placeFruit(450, 2475, "bluefruit");
        placeFruit(675,1925, "purplefruit");
        placeFruit(275,8575,"greenfruit");
        placeFruit(775,875,"purplefruit");
        placeHealthpack(25, 250);
        placeFruit(925, 250, "greenfruit");
        placeFruit(450,2775, "purplefruit");

        placeHealthpack(500, 550);

//        // place enemies ( note don't put anything with y pos above 5050 )
        var bird1 = placeBird(275,5050,["green"]);

        // tween bird 2
        var bird2 = placeBird(575,3875,["blue"]);
        bird2.mytween = game.add.tween(bird2).to({x:[650, 575], y:[3875,3875]}, 1000, Phaser.Easing.Linear.None, true, 0, -1, false);

        placeSnake(325,3475, ["purple"]);

        // tween snake
        var snake1 = placeSnake(325, 4875, ["purple"]); // TWEEN THIS ENEMY!
        snake1.mytween = game.add.tween(snake1).to({x:[125, 325], y:[4875,4875]}, 1000, Phaser.Easing.Linear.None, true, 0, -1, false);

//        placeSnake(475, 775, "blue");
        placeBird(350,2475,["purple"]);
        placeBird(500, 2475, ["green"]);
//        placeBird(500,1650,["red"]);
//
//        // place moving platforms
        addMovingPlatforms();
        placeMP(325, 4025, 2, 1, 6, 0, 100, 0);
        placeMP(525, 3325, 3, 1, 4, 0, 150, 0);
//
//        make_balloon_group();
//        placeBalloon(200, 2300);

        // place health bar
        place_hearts(450, 0);

    },
    update: function(){
        // move the camera (if it wasnt obvious)
        move_camera(1,1);

        var tile_arr2 = get_surrounding_tiles(icelayer1, iceMap);
        collideIce(tile_arr2);

        // colide with icelayer and allow player to jump
        game.physics.arcade.collide(player, icelayer1);

        if (game.camera.y != 0) {
            // catboss stays asleep until 3 seconds after camera reaches the top
            cat_boss.throw_ball_timer = game.time.time + 3000;
        }
        var boss_collision_list = [icelayer1, icelayer2]
        cat_boss_move(boss_collision_list);

        player.tint = 0xffffff;
        // check for ballooning
        if (player.ballooning){
            chameleon_float();
        } else {
            chameleonmove();
        }

        // Game over if you fall off the screen
        if (game.camera.y+650 < player.body.y) {
            console.log("ICE");
            deadplayer(true);
        }

        // move enemies
        birds_group.forEach(moveBird, this);
        snakes_group.forEach(moveSnake, this);
        moving_platform_group.forEach(movingPlatformsUpdate, this);

        //checkforladders(iceMap, icelayer2);
        var tile_arr1 = get_surrounding_tiles(icelayer2, iceMap);
        ladder_movement(tile_arr1, 10, 11);

        update_health(player.health);

    }
};
<|endoftext|>


<commit_before>/**
 * Created by tdemille on 8/24/15.
 */

// AWS Lambda passes a context object to the handler.  This is a mock of that object
// and allows us to test lambda functions locally witout stubbing out context code
// if one was testing the getRemainingTimeInMillis function we could ad an actual
//counter that decrements here
exports.MockContext = function() {

    this.awsRequestId = 123;
    this.logStreamName = "logstreamname";
    this.clientContext = "local test";
    this.identity = "42532341245322";
    this.logGroupName = "logGroupName";
    this.logStreamName = "logSTreamName";
    this.functionName = "functionName()";

    this.done = function (err, data) {
        console.log("you called done from your code with data: ", data, " err ", err);
    }
    this.succeed = function (data) {
        console.log("you called succeed from your code with data: ", data);
    }
    this.fail = function (err) {
        console.log("you called fail from your code with err:", err);
    }

    this.getRemainingTimeInMillis = function () {
        return 1000;
    }
}
<commit_msg>added lic<commit_after>/*
 * (C) Copyright Tom DeMille
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     Tom DeMille
 */

// AWS Lambda passes a context object to the handler.  This is a mock of that object
// and allows us to test lambda functions locally witout stubbing out context code
// if one was testing the getRemainingTimeInMillis function we could ad an actual
//counter that decrements here
exports.MockContext = function () {

	this.awsRequestId = 123;
	this.logStreamName = "logstreamname";
	this.clientContext = "local test";
	this.identity = "42532341245322";
	this.logGroupName = "logGroupName";
	this.logStreamName = "logSTreamName";
	this.functionName = "functionName()";

	this.done = function ( err, data ) {
		console.log( "you called done from your code with data: ", data, " err ", err );
	}
	this.succeed = function ( data ) {
		console.log( "you called succeed from your code with data: ", data );
	}
	this.fail = function ( err ) {
		console.log( "you called fail from your code with err:", err );
	}

	this.getRemainingTimeInMillis = function () {
		return 1000;
	}
}
<|endoftext|>


<commit_before>'use strict';

var Stream = require('stream');

function Resource() {
  if (!(this instanceof Resource)) return new Resource();
  this.cache = {};
}

/**
 * Invalidate the cache.
 *
 * @api public
 */
Resource.prototype.invalidate = function invalidate() {
  this.cache = {};
  return this;
};

//
// Make the Resource extendable.
//
Resource.extend = require('extendable');

//
// Initialize.
//
module.exports = Resource;
<commit_msg>[ocd] Rewrite the resource interface to a Object.create pattern<commit_after>'use strict';

function Resource() {
  if (!(this instanceof Resource)) return new Resource();
}

Resource.prototype = Object.create(require('stream').prototype, {
  constructor: {
    value: Resource,
    writable: true,
    enumerable: false,
    configurable: true
  },

  /**
   * Simple lookup table that caches responses so we're not doing duplicate
   * lookups of data. If people don't want to have their shit cached. They
   * should set it to `undefined` explicitly.
   *
   * @type {Object}
   * @public
   */
  cache: {
    value: [],
    writable: true,
    enumerable: false,
    configurable: true
  },

  /**
   * Simple state that people can manipulate which perists untill the resource
   * has been destroyed.
   *
   * @ptype {Mixed}
   * @public
   */
  state: {
    value: null,
    writable: true,
    enumerable: false,
    configurable: true
  },

  //
  // !IMPORTANT
  //
  // Function's should never overriden as we might depend on them internally,
  // that's why they are configured with writable: false and configurable: false
  // by default.
  //
  // !IMPORTANT
  //

  /**
   * Invalidate the cache all other get requests will now bypass the cache. It
   * needs to set the cache to a `false` value. We're not allowed to set it to
   * `undefined` as that's the indication that the user doesn't want to use any
   * resource caching.
   *
   * @api private
   */
  invalidate: {
    enumerable: false,
    value: function invalidate() {
      this.cache = null;
    }
  },

  /**
   * Get a new value from the resource.
   *
   * @param {Mixed} data The query or data we need to retrieve.
   * @param {Function} fn The callback.
   * @api public
   */
  get: {
    enumerable: false,
    value: function get(data, fn) {
      if (this.sync) this.sync('read', data, fn);
      this.emit('read');
    }
  },

  /**
   * Update a value in the resource.
   *
   * @param {Mixed} data The data that needs to be updated.
   * @param {Function} fn The callback.
   * @api public
   */
  set: {
    enumerable: false,
    value: function set(data, fn) {
      if (this.sync) this.sync('update', data, fn);
      this.emit('update');
    }
  },

  /**
   * Remove a value in the resource.
   *
   * @param {Mixed} data The data that needs to be removed.
   * @param {Function} fn The callback.
   * @api public
   */
  del: {
    enumerable: false,
    value: function deletes(data, fn) {
      if (this.sync) this.sync('delete', data, fn);
      this.emit('delete');
    }
  },

  /**
   * Configure the resource.
   *
   * @api private
   */
  configure: {
    enumerable: false,
    value: function configure(req, res) {
      this.cache.length = 0;

      if (this.initialise) {
        this.initialise(req, res);
      } else {
        this.sync('create', req, function noop() {});
      }
    }
  }
});

//
// Make the Resource extendable.
//
Resource.extend = require('extendable');

//
// Expose the Resource on the exports through the same interface as we're doing
// with Pagelet and Page constructors
//
// ```js
// Resource.extend({
//   ..
// }).on(module);
// ```
//
Resource.on = function on(module) {
  module.exports = this;
  return this;
};

//
// Initialize.
//
module.exports = Resource;
<|endoftext|>


<commit_before>'use strict';

var kiwi_web = require('../lib/kiwi-web.js');

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['awesome'] = {
  setUp: function(done) {
    // setup here
    done();
  },
  'no args': function(test) {
    test.expect(1);
    // tests here
    test.equal(kiwi_web.awesome(), 'awesome', 'should be awesome.');
    test.done();
  }
};
<commit_msg>Removes unnecessary file.<commit_after><|endoftext|>


<commit_before>var JSProblemState = {
	'answer': ''
};

// This wrapper function is necessary.
var textlog = (function() {

	// REQUIRED --- DO NOT REMOVE/CHANGE!!
	var channel;

	// REQUIRED --- DO NOT REMOVE/CHANGE!!
	if (window.parent !== window) {
		channel = Channel.build({
			window: window.parent,
			origin: '*',
			scope: 'JSInput'
		});
		channel.bind('getGrade', getGrade);
		channel.bind('getState', getState);
		channel.bind('setState', setState);
	}

	function getState(){
	    console.log('getting state');
        JSProblemState['answer'] = document.getElementById('answer').value;
        // This string gets URI-decoded later, so percents need to be escaped.
        JSProblemState['answer'] = JSProblemState['answer'].replace('%', '%25');
		return JSON.stringify(JSProblemState);
	}

	function setState() {
	    console.log('setting state');
		stateStr = arguments.length === 1 ? arguments[0] : arguments[1];
		JSProblemState = JSON.parse(stateStr);
	    document.getElementById('answer').value = JSProblemState['answer'];
	}

	function getGrade() {
	    console.log('getting grade');
        JSProblemState['answer'] = document.getElementById('answer').value;
		parent.logThatThing(JSProblemState);
        // This string gets URI-decoded later, so percents need to be escaped.
        JSProblemState['answer'] = JSProblemState['answer'].replace('%', '%25');
		return JSON.stringify(JSProblemState);
	}

	// REQUIRED --- DO NOT REMOVE/CHANGE!!
	return {
		getState: getState,
		setState: setState,
		getGrade: getGrade
	};

}());

console.log('inner ready');
<commit_msg>Find ALL the percents.<commit_after>var JSProblemState = {
	'answer': ''
};

// This wrapper function is necessary.
var textlog = (function() {

	// REQUIRED --- DO NOT REMOVE/CHANGE!!
	var channel;

	// REQUIRED --- DO NOT REMOVE/CHANGE!!
	if (window.parent !== window) {
		channel = Channel.build({
			window: window.parent,
			origin: '*',
			scope: 'JSInput'
		});
		channel.bind('getGrade', getGrade);
		channel.bind('getState', getState);
		channel.bind('setState', setState);
	}

	function getState(){
	    console.log('getting state');
        JSProblemState['answer'] = document.getElementById('answer').value;
        // This string gets URI-decoded later, so percents need to be escaped.
        JSProblemState['answer'] = JSProblemState['answer'].replace(/%/g, '%25');
		return JSON.stringify(JSProblemState);
	}

	function setState() {
	    console.log('setting state');
		stateStr = arguments.length === 1 ? arguments[0] : arguments[1];
		JSProblemState = JSON.parse(stateStr);
	    document.getElementById('answer').value = JSProblemState['answer'];
	}

	function getGrade() {
	    console.log('getting grade');
        JSProblemState['answer'] = document.getElementById('answer').value;
		parent.logThatThing(JSProblemState);
        // This string gets URI-decoded later, so percents need to be escaped.
        JSProblemState['answer'] = JSProblemState['answer'].replace(/%/g, '%25');
		return JSON.stringify(JSProblemState);
	}

	// REQUIRED --- DO NOT REMOVE/CHANGE!!
	return {
		getState: getState,
		setState: setState,
		getGrade: getGrade
	};

}());

console.log('inner ready');
<|endoftext|>


<commit_before>/**
 * @copyright Copyright 2017-2019 Kevin Locke <kevin@kevinlocke.name>
 * @license MIT
 */

'use strict';

const { assert } = require('chai');
const path = require('path');
const rimraf = require('rimraf');
const { pathToFileURL } = require('url');
const { promisify } = require('util');

const gitUtils = require('../../lib/git-utils');
const execFileOut = require('../../lib/exec-file-out');

const defaultBranch = 'main';
const isWindows = /^win/i.test(process.platform);
const rimrafP = promisify(rimraf);

const BRANCH_REMOTES = {
  // Note:  must be origin so ls-remote default is origin for all git versions
  [defaultBranch]: `origin/${defaultBranch}`,
  branch1: 'remote1/rbranch5',
  branch2: 'remote2/rbranch6',
  branchnoremote: false,
  branchnourl: 'nourl/rbranch2',
  branchnotslug: 'notslug/rbranch3',
};
const REMOTES = {
  notslug: 'foo',
  origin: 'https://github.com/owner/repo',
  remote1: 'git@github.com:owner1/repo1.git',
  remote2: 'https://github.com/owner2/repo2.git',
};
const TAGS = ['tag1'];
/** Path to repository in which tests are run. */
const TEST_REPO_PATH = path.join(__dirname, '..', '..', 'test-repo');

const options = Object.freeze({ cwd: TEST_REPO_PATH });

function neverCalled() {
  throw new Error('should not be called');
}

before('setup test repository', function() {
  // Some git versions can run quite slowly on Windows
  this.timeout(isWindows ? 8000 : 4000);

  return rimrafP(TEST_REPO_PATH)
    .then(async () => {
      try {
        await execFileOut(
          'git',
          // git-init(1) in 2.30.0 warns that default branch subject to change.
          // It may also have non-default global- or user-configuration.
          // Specify --initial-branch to avoid depending on default
          ['init', '-q', `--initial-branch=${defaultBranch}`, TEST_REPO_PATH],
        );
      } catch {
        // git < 2.28.0 doesn't understand --initial-branch, default is master
        await execFileOut('git', ['init', '-q', TEST_REPO_PATH]);
        if (defaultBranch !== 'master') {
          await execFileOut(
            'git',
            ['symbolic-ref', 'HEAD', `refs/heads/${defaultBranch}`],
            options,
          );
        }
      }
    })
    // The user name and email must be configured for the later git commands
    // to work.  On Travis CI (and probably others) there is no global config
    .then(() => execFileOut(
      'git',
      ['-C', TEST_REPO_PATH, 'config', 'user.name', 'Test User'],
    ))
    .then(() => execFileOut(
      'git',
      ['-C', TEST_REPO_PATH, 'config', 'user.email', 'test@example.com'],
    ))
    .then(() => execFileOut(
      'git',
      ['-C', TEST_REPO_PATH, 'commit', '-q', '-m', 'Initial Commit',
        '--allow-empty'],
    ))
    .then(() => execFileOut('git', ['-C', TEST_REPO_PATH, 'tag', TAGS[0]]))
    .then(() => execFileOut(
      'git',
      ['-C', TEST_REPO_PATH, 'commit', '-q', '-m', 'Second Commit',
        '--allow-empty'],
    ))
    .then(() => Object.keys(REMOTES).reduce((p, remoteName) => p.then(() => {
      const remoteUrl = REMOTES[remoteName];
      return execFileOut(
        'git',
        ['-C', TEST_REPO_PATH, 'remote', 'add', remoteName, remoteUrl],
      );
    }), Promise.resolve()))
    .then(() => Object.keys(BRANCH_REMOTES)
      .filter((branchName) => branchName !== defaultBranch)
      .reduce((p, branchName) => p.then(() => execFileOut(
        'git',
        ['-C', TEST_REPO_PATH, 'branch', branchName],
      )), Promise.resolve()))
    .then(() => Object.keys(BRANCH_REMOTES)
      .reduce((p, branchName) => p.then(() => {
        const upstream = BRANCH_REMOTES[branchName];
        if (!upstream) {
          return p;
        }
        // Note:  Can't use 'git branch -u' without fetching remote
        const upstreamParts = upstream.split('/');
        assert.strictEqual(upstreamParts.length, 2);
        const remoteName = upstreamParts[0];
        const remoteBranch = upstreamParts[1];
        const remoteRef = `refs/heads/${remoteBranch}`;
        const configBranch = `branch.${branchName}`;
        const configMerge = `${configBranch}.merge`;
        const configRemote = `${configBranch}.remote`;
        return execFileOut(
          'git',
          ['-C', TEST_REPO_PATH, 'config', '--add', configRemote, remoteName],
        )
          .then(() => execFileOut(
            'git',
            ['-C', TEST_REPO_PATH,
              'config', '--add', configMerge, remoteRef],
          ));
      }), Promise.resolve()));
});

after('remove test repository', () => rimrafP(TEST_REPO_PATH));

function checkoutDefault() {
  return execFileOut('git', ['checkout', '-q', defaultBranch], options);
}

describe('gitUtils', () => {
  describe('.getBranch', () => {
    after(checkoutDefault);

    it(`resolves ${defaultBranch} on ${defaultBranch}`,
      () => gitUtils.getBranch(options)
        .then((branch) => {
          assert.strictEqual(branch, defaultBranch);
        }));

    it('resolves branch1 on branch1',
      () => execFileOut('git', ['checkout', '-q', 'branch1'], options)
        .then(() => gitUtils.getBranch(options))
        .then((branch) => {
          assert.strictEqual(branch, 'branch1');
        }));

    it('rejects with Error not on branch',
      () => execFileOut('git', ['checkout', '-q', 'HEAD^'], options)
        .then(() => gitUtils.getBranch(options))
        .then(
          neverCalled,
          (err) => {
            assert.instanceOf(err, Error);
            assert.match(err.message, /branch/i);
          },
        ));
  });

  describe('.getRemote', () => {
    after(checkoutDefault);

    Object.keys(BRANCH_REMOTES).forEach((branch) => {
      const remoteRef = BRANCH_REMOTES[branch];
      if (!remoteRef) {
        return;
      }
      const remote = remoteRef.split('/')[0];
      it(`resolves ${branch} to ${remote}`,
        () => gitUtils.getRemote(branch, options).then((result) => {
          assert.strictEqual(result, remote);
        }));
    });

    it('rejects branch without remote with Error',
      () => gitUtils.getRemote('branchnoremote', options).then(
        neverCalled,
        (err) => {
          assert.instanceOf(err, Error);
        },
      ));
  });

  describe('.getRemoteUrl', () => {
    Object.keys(REMOTES).forEach((remoteName) => {
      const remoteUrl = REMOTES[remoteName];
      it(`resolves ${remoteName} to ${remoteUrl}`,
        () => gitUtils.getRemoteUrl(remoteName, options)
          .then((resultUrl) => {
            assert.strictEqual(resultUrl, remoteUrl);
          }));
    });

    it('rejects invalid remote with Error',
      () => gitUtils.getRemoteUrl('invalidremote', options).then(
        neverCalled,
        (err) => {
          assert.instanceOf(err, Error);
        },
      ));

    it('uses ls-remote default for unspecified remote',
      () => gitUtils.getRemoteUrl(null, options)
        .then((resultUrl) => {
          assert.strictEqual(resultUrl, REMOTES.origin);
        }));
  });

  describe('.gitUrlIsLocalNotSsh', () => {
    [
      { url: '.', result: true },
      { url: '/foo/bar', result: true },
      { url: 'http://example.com', result: false },
      { url: 'git://example.com', result: false },
      { url: 'git@example.com:foo', result: false },
      { url: 'file:///foo/bar', result: false },
      { url: '/foo:bar', result: true },
      { url: 'foo:bar', result: false },
    ].forEach((testCase) => {
      it(`${testCase.url} is ${testCase.result}`, () => {
        assert.strictEqual(
          gitUtils.gitUrlIsLocalNotSsh(testCase.url),
          testCase.result,
        );
      });
    });

    const drivePath = 'C:/foo';
    if (isWindows) {
      it(`${drivePath} is true on Windows`, () => {
        assert.strictEqual(
          gitUtils.gitUrlIsLocalNotSsh(drivePath),
          true,
        );
      });
    } else {
      it(`${drivePath} is false on non-Windows`, () => {
        assert.strictEqual(
          gitUtils.gitUrlIsLocalNotSsh(drivePath),
          false,
        );
      });
    }
  });

  describe('.parseGitUrl', () => {
    it('parses http: like url module', () => {
      const testUrl = 'http://user@example.com/foo/bar';
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testUrl),
        Object.assign(new URL(testUrl), { helper: undefined }),
      );
    });

    it('parses git: like url module', () => {
      const testUrl = 'git://user@example.com/foo/bar';
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testUrl),
        Object.assign(new URL(testUrl), { helper: undefined }),
      );
    });

    it('parses SCP-like URL like ssh: URL', () => {
      const testUrl = 'user@example.com:foo/bar.git';
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testUrl),
        Object.assign(
          new URL('ssh://user@example.com/foo/bar.git'),
          { helper: undefined },
        ),
      );
    });

    it('parses absolute path like file:// URL', () => {
      const testPath = path.resolve(path.join('foo', 'bar'));
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testPath),
        Object.assign(pathToFileURL(testPath), { helper: undefined }),
      );
    });

    it('parses relative path like file:// URL', () => {
      const testPath = path.join('foo', 'bar');
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testPath),
        Object.assign(pathToFileURL(testPath), { helper: undefined }),
      );
    });

    if (isWindows) {
      it('parses Windows path like file:// URL on Windows', () => {
        assert.deepStrictEqual(
          gitUtils.parseGitUrl('C:\\foo\\bar'),
          Object.assign(new URL('file:///C:/foo/bar'), { helper: undefined }),
        );
      });
    } else {
      it('parses Windows path like URL on non-Windows', () => {
        const testPath = 'C:\\foo\\bar';
        assert.deepStrictEqual(
          gitUtils.parseGitUrl(testPath),
          Object.assign(new URL(testPath), { helper: undefined }),
        );
      });
    }

    it('adds helper property for transport helper', () => {
      const testUrl = 'myhelper::user@example.com:foo/bar.git';
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testUrl),
        Object.assign(
          new URL('ssh://user@example.com/foo/bar.git'),
          { helper: 'myhelper' },
        ),
      );
    });
  });

  describe('.resolveCommit', () => {
    let headHash;
    it('can resolve the hash of HEAD',
      () => gitUtils.resolveCommit('HEAD', options).then((hash) => {
        assert.match(hash, /^[a-fA-F0-9]{40}$/);
        headHash = hash;
      }));

    it('can resolve a hash to itself',
      () => gitUtils.resolveCommit(headHash, options).then((hash) => {
        assert.strictEqual(hash, headHash);
      }));

    it('can resolve branch name to commit hash', () => {
      const branchName = Object.keys(BRANCH_REMOTES)[0];
      return gitUtils.resolveCommit(branchName, options).then((hash) => {
        assert.match(hash, /^[a-fA-F0-9]{40}$/);
      });
    });

    it('can resolve tag name to commit hash',
      () => gitUtils.resolveCommit(TAGS[0], options).then((hash) => {
        assert.match(hash, /^[a-fA-F0-9]{40}$/);
      }));

    it('rejects with Error for unresolvable name',
      () => gitUtils.resolveCommit('notabranch', options).then(
        neverCalled,
        (err) => {
          assert(err instanceof Error);
        },
      ));
  });
});
<commit_msg>Add TODO to replace rimraf with fs.rmdir on 12.10<commit_after>/**
 * @copyright Copyright 2017-2019 Kevin Locke <kevin@kevinlocke.name>
 * @license MIT
 */

'use strict';

const { assert } = require('chai');
const path = require('path');
// TODO [engine:node@>=12.10]: Use fs.rmdir({recursive: true})
const rimraf = require('rimraf');
const { pathToFileURL } = require('url');
const { promisify } = require('util');

const gitUtils = require('../../lib/git-utils');
const execFileOut = require('../../lib/exec-file-out');

const defaultBranch = 'main';
const isWindows = /^win/i.test(process.platform);
const rimrafP = promisify(rimraf);

const BRANCH_REMOTES = {
  // Note:  must be origin so ls-remote default is origin for all git versions
  [defaultBranch]: `origin/${defaultBranch}`,
  branch1: 'remote1/rbranch5',
  branch2: 'remote2/rbranch6',
  branchnoremote: false,
  branchnourl: 'nourl/rbranch2',
  branchnotslug: 'notslug/rbranch3',
};
const REMOTES = {
  notslug: 'foo',
  origin: 'https://github.com/owner/repo',
  remote1: 'git@github.com:owner1/repo1.git',
  remote2: 'https://github.com/owner2/repo2.git',
};
const TAGS = ['tag1'];
/** Path to repository in which tests are run. */
const TEST_REPO_PATH = path.join(__dirname, '..', '..', 'test-repo');

const options = Object.freeze({ cwd: TEST_REPO_PATH });

function neverCalled() {
  throw new Error('should not be called');
}

before('setup test repository', function() {
  // Some git versions can run quite slowly on Windows
  this.timeout(isWindows ? 8000 : 4000);

  return rimrafP(TEST_REPO_PATH)
    .then(async () => {
      try {
        await execFileOut(
          'git',
          // git-init(1) in 2.30.0 warns that default branch subject to change.
          // It may also have non-default global- or user-configuration.
          // Specify --initial-branch to avoid depending on default
          ['init', '-q', `--initial-branch=${defaultBranch}`, TEST_REPO_PATH],
        );
      } catch {
        // git < 2.28.0 doesn't understand --initial-branch, default is master
        await execFileOut('git', ['init', '-q', TEST_REPO_PATH]);
        if (defaultBranch !== 'master') {
          await execFileOut(
            'git',
            ['symbolic-ref', 'HEAD', `refs/heads/${defaultBranch}`],
            options,
          );
        }
      }
    })
    // The user name and email must be configured for the later git commands
    // to work.  On Travis CI (and probably others) there is no global config
    .then(() => execFileOut(
      'git',
      ['-C', TEST_REPO_PATH, 'config', 'user.name', 'Test User'],
    ))
    .then(() => execFileOut(
      'git',
      ['-C', TEST_REPO_PATH, 'config', 'user.email', 'test@example.com'],
    ))
    .then(() => execFileOut(
      'git',
      ['-C', TEST_REPO_PATH, 'commit', '-q', '-m', 'Initial Commit',
        '--allow-empty'],
    ))
    .then(() => execFileOut('git', ['-C', TEST_REPO_PATH, 'tag', TAGS[0]]))
    .then(() => execFileOut(
      'git',
      ['-C', TEST_REPO_PATH, 'commit', '-q', '-m', 'Second Commit',
        '--allow-empty'],
    ))
    .then(() => Object.keys(REMOTES).reduce((p, remoteName) => p.then(() => {
      const remoteUrl = REMOTES[remoteName];
      return execFileOut(
        'git',
        ['-C', TEST_REPO_PATH, 'remote', 'add', remoteName, remoteUrl],
      );
    }), Promise.resolve()))
    .then(() => Object.keys(BRANCH_REMOTES)
      .filter((branchName) => branchName !== defaultBranch)
      .reduce((p, branchName) => p.then(() => execFileOut(
        'git',
        ['-C', TEST_REPO_PATH, 'branch', branchName],
      )), Promise.resolve()))
    .then(() => Object.keys(BRANCH_REMOTES)
      .reduce((p, branchName) => p.then(() => {
        const upstream = BRANCH_REMOTES[branchName];
        if (!upstream) {
          return p;
        }
        // Note:  Can't use 'git branch -u' without fetching remote
        const upstreamParts = upstream.split('/');
        assert.strictEqual(upstreamParts.length, 2);
        const remoteName = upstreamParts[0];
        const remoteBranch = upstreamParts[1];
        const remoteRef = `refs/heads/${remoteBranch}`;
        const configBranch = `branch.${branchName}`;
        const configMerge = `${configBranch}.merge`;
        const configRemote = `${configBranch}.remote`;
        return execFileOut(
          'git',
          ['-C', TEST_REPO_PATH, 'config', '--add', configRemote, remoteName],
        )
          .then(() => execFileOut(
            'git',
            ['-C', TEST_REPO_PATH,
              'config', '--add', configMerge, remoteRef],
          ));
      }), Promise.resolve()));
});

after('remove test repository', () => rimrafP(TEST_REPO_PATH));

function checkoutDefault() {
  return execFileOut('git', ['checkout', '-q', defaultBranch], options);
}

describe('gitUtils', () => {
  describe('.getBranch', () => {
    after(checkoutDefault);

    it(`resolves ${defaultBranch} on ${defaultBranch}`,
      () => gitUtils.getBranch(options)
        .then((branch) => {
          assert.strictEqual(branch, defaultBranch);
        }));

    it('resolves branch1 on branch1',
      () => execFileOut('git', ['checkout', '-q', 'branch1'], options)
        .then(() => gitUtils.getBranch(options))
        .then((branch) => {
          assert.strictEqual(branch, 'branch1');
        }));

    it('rejects with Error not on branch',
      () => execFileOut('git', ['checkout', '-q', 'HEAD^'], options)
        .then(() => gitUtils.getBranch(options))
        .then(
          neverCalled,
          (err) => {
            assert.instanceOf(err, Error);
            assert.match(err.message, /branch/i);
          },
        ));
  });

  describe('.getRemote', () => {
    after(checkoutDefault);

    Object.keys(BRANCH_REMOTES).forEach((branch) => {
      const remoteRef = BRANCH_REMOTES[branch];
      if (!remoteRef) {
        return;
      }
      const remote = remoteRef.split('/')[0];
      it(`resolves ${branch} to ${remote}`,
        () => gitUtils.getRemote(branch, options).then((result) => {
          assert.strictEqual(result, remote);
        }));
    });

    it('rejects branch without remote with Error',
      () => gitUtils.getRemote('branchnoremote', options).then(
        neverCalled,
        (err) => {
          assert.instanceOf(err, Error);
        },
      ));
  });

  describe('.getRemoteUrl', () => {
    Object.keys(REMOTES).forEach((remoteName) => {
      const remoteUrl = REMOTES[remoteName];
      it(`resolves ${remoteName} to ${remoteUrl}`,
        () => gitUtils.getRemoteUrl(remoteName, options)
          .then((resultUrl) => {
            assert.strictEqual(resultUrl, remoteUrl);
          }));
    });

    it('rejects invalid remote with Error',
      () => gitUtils.getRemoteUrl('invalidremote', options).then(
        neverCalled,
        (err) => {
          assert.instanceOf(err, Error);
        },
      ));

    it('uses ls-remote default for unspecified remote',
      () => gitUtils.getRemoteUrl(null, options)
        .then((resultUrl) => {
          assert.strictEqual(resultUrl, REMOTES.origin);
        }));
  });

  describe('.gitUrlIsLocalNotSsh', () => {
    [
      { url: '.', result: true },
      { url: '/foo/bar', result: true },
      { url: 'http://example.com', result: false },
      { url: 'git://example.com', result: false },
      { url: 'git@example.com:foo', result: false },
      { url: 'file:///foo/bar', result: false },
      { url: '/foo:bar', result: true },
      { url: 'foo:bar', result: false },
    ].forEach((testCase) => {
      it(`${testCase.url} is ${testCase.result}`, () => {
        assert.strictEqual(
          gitUtils.gitUrlIsLocalNotSsh(testCase.url),
          testCase.result,
        );
      });
    });

    const drivePath = 'C:/foo';
    if (isWindows) {
      it(`${drivePath} is true on Windows`, () => {
        assert.strictEqual(
          gitUtils.gitUrlIsLocalNotSsh(drivePath),
          true,
        );
      });
    } else {
      it(`${drivePath} is false on non-Windows`, () => {
        assert.strictEqual(
          gitUtils.gitUrlIsLocalNotSsh(drivePath),
          false,
        );
      });
    }
  });

  describe('.parseGitUrl', () => {
    it('parses http: like url module', () => {
      const testUrl = 'http://user@example.com/foo/bar';
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testUrl),
        Object.assign(new URL(testUrl), { helper: undefined }),
      );
    });

    it('parses git: like url module', () => {
      const testUrl = 'git://user@example.com/foo/bar';
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testUrl),
        Object.assign(new URL(testUrl), { helper: undefined }),
      );
    });

    it('parses SCP-like URL like ssh: URL', () => {
      const testUrl = 'user@example.com:foo/bar.git';
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testUrl),
        Object.assign(
          new URL('ssh://user@example.com/foo/bar.git'),
          { helper: undefined },
        ),
      );
    });

    it('parses absolute path like file:// URL', () => {
      const testPath = path.resolve(path.join('foo', 'bar'));
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testPath),
        Object.assign(pathToFileURL(testPath), { helper: undefined }),
      );
    });

    it('parses relative path like file:// URL', () => {
      const testPath = path.join('foo', 'bar');
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testPath),
        Object.assign(pathToFileURL(testPath), { helper: undefined }),
      );
    });

    if (isWindows) {
      it('parses Windows path like file:// URL on Windows', () => {
        assert.deepStrictEqual(
          gitUtils.parseGitUrl('C:\\foo\\bar'),
          Object.assign(new URL('file:///C:/foo/bar'), { helper: undefined }),
        );
      });
    } else {
      it('parses Windows path like URL on non-Windows', () => {
        const testPath = 'C:\\foo\\bar';
        assert.deepStrictEqual(
          gitUtils.parseGitUrl(testPath),
          Object.assign(new URL(testPath), { helper: undefined }),
        );
      });
    }

    it('adds helper property for transport helper', () => {
      const testUrl = 'myhelper::user@example.com:foo/bar.git';
      assert.deepStrictEqual(
        gitUtils.parseGitUrl(testUrl),
        Object.assign(
          new URL('ssh://user@example.com/foo/bar.git'),
          { helper: 'myhelper' },
        ),
      );
    });
  });

  describe('.resolveCommit', () => {
    let headHash;
    it('can resolve the hash of HEAD',
      () => gitUtils.resolveCommit('HEAD', options).then((hash) => {
        assert.match(hash, /^[a-fA-F0-9]{40}$/);
        headHash = hash;
      }));

    it('can resolve a hash to itself',
      () => gitUtils.resolveCommit(headHash, options).then((hash) => {
        assert.strictEqual(hash, headHash);
      }));

    it('can resolve branch name to commit hash', () => {
      const branchName = Object.keys(BRANCH_REMOTES)[0];
      return gitUtils.resolveCommit(branchName, options).then((hash) => {
        assert.match(hash, /^[a-fA-F0-9]{40}$/);
      });
    });

    it('can resolve tag name to commit hash',
      () => gitUtils.resolveCommit(TAGS[0], options).then((hash) => {
        assert.match(hash, /^[a-fA-F0-9]{40}$/);
      }));

    it('rejects with Error for unresolvable name',
      () => gitUtils.resolveCommit('notabranch', options).then(
        neverCalled,
        (err) => {
          assert(err instanceof Error);
        },
      ));
  });
});
<|endoftext|>


<commit_before>const http = require('http');
const events = require('events');
const serverPort = 36001;
const librato = require('../lib/librato.js');

let emitter;

module.exports = {
  setUp: function(callback) {
    emitter = new events.EventEmitter();
    this.server = http.createServer();
    this.server.listen(serverPort, '127.0.0.1', function() {
      callback();
    });

    this.api_mock = function(validRequest, errorResponse, callback) {
      return function(req, res) {
        let data = '';
        req.on('data', function(chunk) {
          data += chunk;
        });
        req.on('end', function() {
          let body = JSON.parse(data);
          if (validRequest) {
            res.writeHead(200, {});
            res.end('');
            callback(req, res, body);
          } else {
            res.writeHead(400, {'content-type': 'application/json'});
            res.end(JSON.stringify(errorResponse));
            callback(req, res, body);
          }
        });
      };
    };
    // Librato Backend
    librato.init(null, {
      debug: false,
      librato: {
        email: '-@-',
        token: '-',
        api: 'http://127.0.0.1:' + serverPort,
        writeToLegacy: false,
        batchSize: 5,
      },
    }, emitter);
  },
  tearDown: function(callback) {
    this.server.close(function() {
      callback();
    });
  },
  testValidMeasurementNoTags: function(test) {
    let metrics = {gauges: {my_gauge: 1}};

    this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
      let measurement = body.measurements[0];
      test.ok(measurement);
      test.equal(measurement.name, 'my_gauge');
      test.equal(measurement.value, 1);
      test.deepEqual(measurement.tags, {});
      test.done();
    }));
    emitter.emit('flush', 123, metrics);
  },

  testValidMeasurementSingleTag: function(test) {
    test.expect(4);
    let metrics = {gauges: {'my_gauge#foo=bar': 1}};
    this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
      let measurement = body.measurements[0];
      test.ok(measurement);
      test.equal(measurement.name, 'my_gauge');
      test.equal(measurement.value, 1);
      test.deepEqual(measurement.tags, {foo: 'bar'});
      test.done();
    }));
    emitter.emit('flush', 123, metrics);
  },
  testValidMeasurementMultipleTags: function(test) {
    test.expect(4);
    let metrics = {gauges: {'my_gauge#foo=bar,biz=baz': 1}};
    this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
      let measurement = body.measurements[0];
      test.ok(measurement);
      test.equal(measurement.name, 'my_gauge');
      test.equal(measurement.value, 1);
      test.deepEqual(measurement.tags, {
        foo: 'bar',
        biz: 'baz',
      });
      test.done();
    }));
    emitter.emit('flush', 123, metrics);
  },
  testIgnoreBrokenMetrics: function(test) {
    test.expect(5);
    let metrics = {
      gauges: {
        cool_gauge: 123,
        bad_counter: 321,
      },
    };
    let errors = {errors: {params: {type: ['\'bad_counter\'' + ' is a counter, but was' + ' submitted as different type']}}};
    // Simulate failure...
    this.server.once('request', this.api_mock(false, errors, function(req, res, body) {
      let gauges = {};
      for (let k in body.measurements) {
        gauges[body.measurements[k].name] = body.measurements[k].value;
      }
      test.ok(gauges.cool_gauge);
      test.ok(gauges.bad_counter);
      test.equal(res.statusCode, 400);
      setTimeout(function() {
        this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
          let gauges = {};
          for (let k in body.measurements) {
            gauges[body.measurements[k].name] = body.measurements[k].value;
          }
          test.ok(gauges.cool_gauge);
          test.strictEqual(gauges.bad_counter, undefined);
          test.done();
        }));
        emitter.emit('flush', 123, metrics);
      }.bind(this), 500);
    }.bind(this)));
    emitter.emit('flush', 123, metrics);
  },
  testTimers: function(test) {
    test.expect(7);
    let metrics = {
      timers: {
        'my_timer#tag=foo': [
          41,
          73.5,
        ],
      },
      timer_data: {'my_timer#tag=foo': null},
    };
    this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
      let measurement = body.measurements[0];
      test.ok(measurement);
      test.equal(measurement.name, 'my_timer');
      test.equal(measurement.value, undefined);
      test.equal(measurement.min, 41);
      test.equal(measurement.max, 73.5);
      test.equal(measurement.sum, 114.5);
      test.deepEqual(measurement.tags, {tag: 'foo'});
      test.done();
    }));
    emitter.emit('flush', 123, metrics);
  },

  testMaxBatchSize: function(test) {
    test.expect(0);
    var gauges = {};
    for (var i = 0; i < 5; i++) {
      var key = 'gauge' + i;
      gauges[key] = 1;
    }
    var metrics = {gauges: gauges};

    this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
    }));

    this.emitter.emit('flush', 123, metrics);
    test.done();
  },
};
<commit_msg>Spacing. Variable cleanup<commit_after>'use strict';

const http = require('http');
const events = require('events');
const serverPort = 36001;
const librato = require('../lib/librato.js');

var emitter;

module.exports = {
  setUp: function(callback) {
    emitter = new events.EventEmitter();
    this.server = http.createServer();
    this.server.listen(serverPort, '127.0.0.1', function() {
      callback();
    });

    this.api_mock = function(validRequest, errorResponse, callback) {
      return function(req, res) {
        let data = '';
        req.on('data', function(chunk) {
          data += chunk;
        });
        req.on('end', function() {
          let body = JSON.parse(data);
          if (validRequest) {
            res.writeHead(200, {});
            res.end('');
            callback(req, res, body);
          } else {
            res.writeHead(400, {'content-type': 'application/json'});
            res.end(JSON.stringify(errorResponse));
            callback(req, res, body);
          }
        });
      };
    };

    this.config = {
      debug: false,
      librato: {
        email: '-@-',
        token: '-',
        api: 'http://127.0.0.1:' + serverPort,
        writeToLegacy: false,
        batchSize: 5,
      },
    };

    librato.init(null, this.config, emitter);
  },

  tearDown: function(callback) {
    this.server.close(function() {
      callback();
    });
  },

  testValidMeasurementNoTags: function(test) {
    let metrics = {gauges: {my_gauge: 1}};

    this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
      let measurement = body.measurements[0];
      test.ok(measurement);
      test.equal(measurement.name, 'my_gauge');
      test.equal(measurement.value, 1);
      test.deepEqual(measurement.tags, {});
      test.done();
    }));
    emitter.emit('flush', 123, metrics);
  },

  testValidMeasurementSingleTag: function(test) {
    test.expect(4);
    let metrics = {gauges: {'my_gauge#foo=bar': 1}};
    this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
      let measurement = body.measurements[0];
      test.ok(measurement);
      test.equal(measurement.name, 'my_gauge');
      test.equal(measurement.value, 1);
      test.deepEqual(measurement.tags, {foo: 'bar'});
      test.done();
    }));
    emitter.emit('flush', 123, metrics);
  },

  testValidMeasurementMultipleTags: function(test) {
    test.expect(4);
    let metrics = {gauges: {'my_gauge#foo=bar,biz=baz': 1}};
    this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
      let measurement = body.measurements[0];
      test.ok(measurement);
      test.equal(measurement.name, 'my_gauge');
      test.equal(measurement.value, 1);
      test.deepEqual(measurement.tags, {
        foo: 'bar',
        biz: 'baz',
      });
      test.done();
    }));
    emitter.emit('flush', 123, metrics);
  },

  testIgnoreBrokenMetrics: function(test) {
    test.expect(5);
    let metrics = {
      gauges: {
        cool_gauge: 123,
        bad_counter: 321,
      },
    };
    let errors = {errors: {params: {type: ['\'bad_counter\'' + ' is a counter, but was' + ' submitted as different type']}}};
    // Simulate failure...
    this.server.once('request', this.api_mock(false, errors, function(req, res, body) {
      let gauges = {};
      for (let k in body.measurements) {
        gauges[body.measurements[k].name] = body.measurements[k].value;
      }
      test.ok(gauges.cool_gauge);
      test.ok(gauges.bad_counter);
      test.equal(res.statusCode, 400);
      setTimeout(function() {
        this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
          let gauges = {};
          for (let k in body.measurements) {
            gauges[body.measurements[k].name] = body.measurements[k].value;
          }
          test.ok(gauges.cool_gauge);
          test.strictEqual(gauges.bad_counter, undefined);
          test.done();
        }));
        emitter.emit('flush', 123, metrics);
      }.bind(this), 500);
    }.bind(this)));
    emitter.emit('flush', 123, metrics);
  },

  testTimers: function(test) {
    test.expect(7);
    let metrics = {
      timers: {
        'my_timer#tag=foo': [
          41,
          73.5,
        ],
      },
      timer_data: {'my_timer#tag=foo': null},
    };
    this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
      let measurement = body.measurements[0];
      test.ok(measurement);
      test.equal(measurement.name, 'my_timer');
      test.equal(measurement.value, undefined);
      test.equal(measurement.min, 41);
      test.equal(measurement.max, 73.5);
      test.equal(measurement.sum, 114.5);
      test.deepEqual(measurement.tags, {tag: 'foo'});
      test.done();
    }));
    emitter.emit('flush', 123, metrics);
  },

  testMaxBatchSize: function(test) {
    test.expect(0);
    var gauges = {};
    for (var i = 0; i < 5; i++) {
      var key = 'gauge' + i;
      gauges[key] = 1;
    }
    var metrics = {gauges: gauges};

    this.server.once('request', this.api_mock(true, {}, function(req, res, body) {
    }));

    this.emitter.emit('flush', 123, metrics);
    test.done();
  },
};
<|endoftext|>