<commit_before>(function() {
    var bfjs = {};
    // core is mainly to check if jquery is loaded
    bfjs.core = {
        loaded:false,
        hasBfCredentials:false,
        gatewayChosen:false,
        deferredTransactions:[]
    };
    bfjs.stripe = {
        key: 'stripe',
        loaded:false,
        loadMe:false,
        deferredRequest:null
    };
    bfjs.braintree = {
        key: 'braintree',
        loaded:false,
        loadMe:false,
        deferredRequest:null
    };
    bfjs.state = {
        api: {
            url: null,
            token: null,
            organizationID: null
        }
    };

    bfjs.grabScripts = function() {
        var queue = [];
        if (typeof jQuery !== 'undefined') {
            bfjs.core.loadedCallback();
        } else {
            // everyone has this in their cache anyway, so..
            queue.push({
                src: "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js",
                callback: bfjs.core.loadedCallback
            });
        }
        if (bfjs.stripe.loadMe) {
            if (typeof window.Stripe !== 'undefined') {
                queue.push({
                    src: "https://js.stripe.com/v2/",
                    callback: bfjs.stripe.loadedCallback
                });
            } else {
                bfjs.stripe.loadedCallback();
            }
        }
        if (bfjs.braintree.loadMe) {
            if (typeof window.braintree !== 'undefined') {
                queue.push({
                    src: "https://assets.braintreegateway.com/v2/braintree.js",
                    callback: bfjs.braintree.loadedCallback
                });
            } else {
                bfjs.braintree.loadedCallback();
            }
        }

        for (var i = 0; i<queue.length; i++) {
            bfjs.loadScript(queue[i].src, queue[i].callback);
        }
    };

    var bfjs.Transaction = (function() {
        var TheClass = function(bfjs, formElementCandidate, accountID, callback, targetGateway) {
            this.formElementCandidate = formElementCandidate;
            this.callback = callback;
            this.accountID = accountID;
            this.targetGateway = targetGateway;
            this.bfjs = bfjs;
            this.state = {
                formElement:  null;
                $formElement: null;
            };
        };

        TheClass.construct = function(bfjs, formElementCandidate, accountID, callback, targetGateway) {
            return new TheClass(bfjs, formElementCandidate, accountID, callback, targetGateway);
        };

        var p = TheClass.prototype;

        p.do = function() {
            $( document ).ready(function() {
                var $formElement = $(this.formElementCandidate);
                var formElement = $formElement.get(0);

                if (!(formElement instanceof HTMLElement)) {
                    throw "Expected jQuery object or HTML element. Perhaps the Form hasn't finished loading?";
                }

                this.state.formElement = formElement;
                this.state.$formElement = $formElement;

                $formElement.submit(function(e) {
                    // Disable the submit button to prevent repeated clicks
                    $(this).find('button').prop('disabled', true);

                    e.preventDefault();
                    e.stopPropagation();
                    this.bfjs[this.chosenGateway].deferRequest();
                });

                // ready to go
                $formElement.find('button').prop('disabled', false);
            });
        };

        return TheClass;
    }());

    bfjs.loadScript = function(url, callback){

        var script = document.createElement("script")
        script.type = "text/javascript";

        var doCallback = function() {
            callback();
        };

        if (script.readyState){  //IE
            script.onreadystatechange = function(){
                if (script.readyState == "loaded" ||
                        script.readyState == "complete"){
                    script.onreadystatechange = null;
                    doCallback();
                }
            };
        } else {  //Others
            script.onload = function(){
                doCallback();
            };
        }

        script.src = url;
        document.getElementsByTagName("head")[0].appendChild(script);
    };

    bfjs.core.loadedCallback = function() {
        // now that core's loaded, check if we had pending requests..
        bfjs.core.loaded = true;

        for (var i in bfjs.core.deferredTransactions) {
            var transaction = bfjs.core.deferredTransactions[i];
            transaction.do();
        }
    };

    bfjs.stripe.loadedCallback = function() {
        // now that Stripe's loaded, check if we had pending requests..
        bfjs.stripe.loaded = true;

        if (bfjs.stripe.deferredRequest)
        bfjs.stripe.deferredRequest();
    };

    bfjs.braintree.loadedCallback = function() {
        // now that braintree's loaded, check if we had pending requests..
        bfjs.braintree.loaded = true;

        if (bfjs.braintree.deferredRequest)
        bfjs.braintree.deferredRequest();
    };

    bfjs.stripe.deferRequest = function() {
        if (bfjs.stripe.loaded) {
            bfjs.stripe.do();
        } else {
            bfjs.stripe.deferredRequest = bfjs.stripe.do;
        }
    };

    bfjs.braintree.deferRequest = function() {
        if (bfjs.braintree.loaded) {
            bfjs.braintree.do();
        } else {
            bfjs.braintree.deferredRequest = bfjs.braintree.do;
        }
    };

    bfjs.stripe.do = function(state) {
    	var payload = {
    		"gateway": "Stripe"
    	}

    	if(bfjs.state.api.organizationID != null) {
        	payload.organizationID = bfjs.state.api.organizationID;
        }

        bfjs.doPreAuth(payload, bfjs.stripe.key);
    };

    bfjs.braintree.do = function(state) {
        var payload = {
            "gateway": "Braintree"
        }

        if(bfjs.state.api.organizationID != null) {
            payload.organizationID = bfjs.state.api.organizationID;
        }

        bfjs.doPreAuth(payload, bfjs.braintree.key);
    };

    bfjs.stripe.responseHandler = function(status, response) {
        if (response.error) {
            // Show the errors on the form
            bfjs.ultimateFailure(response.error.message);
        } else {
            // token contains id, last4, and card type
            var token = response.id;
            var card = response.card;

            var payload = {
                stripeToken: token,
                cardID: card.id,
                accountID: bfjs.state.accountID
            };

            if(bfjs.state.api.organizationID != null) {
            	payload.organizationID = bfjs.state.api.organizationID;
            }

            // and re-submit
            bfjs.doAuthCapture(payload, bfjs.stripe.key);
        }
    };

    bfjs.doPreAuth = function(payload, gateway) {
        var controller = "tokenization/"
        var endpoint = "pre-auth";
        var fullURL = bfjs.state.api.url + controller + endpoint;
        var auth = bfjs.state.api.token;

        $.support.cors = true;

        $.ajax({
                type: "POST",
                url: fullURL,
                data: JSON.stringify(payload),
                contentType: 'application/json',
                //dataType: 'jsonp',
                //jsonp: function(data){console.log(data);},
                crossDomain: true,
                xhrFields: {
                    //withCredentials: true
                },
                headers: {
                    'Authorization': 'Bearer '+auth,
                    //'Access-Control-Allow-Origin': "*",
                    //'Access-Control-Request-Headers': 'Authorization Access-Control-Allow-Origin'
                },
                /*beforeSend: function (xhr) {
                    xhr.setRequestHeader ("Authorization", 'Bearer '+auth);
                    xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
                    xhr.withCredentials = true;
                },*/
            })
        .success(function(data) {
            bfjs.preAuthSuccessHandler(data, bfjs.stripe.key);
        })
        .fail(bfjs.preAuthFailHandler);
    };

    bfjs.doAuthCapture = function(payload, gateway) {
        var controller = "tokenization/"
        var endpoint = "auth-capture";
        var fullURL = bfjs.state.api.url + controller + endpoint;
        var auth = bfjs.state.api.token;

        $.ajax({
                type: "POST",
                url: fullURL,
                data: JSON.stringify(payload),
                contentType: 'application/json',
                //dataType: 'jsonp',
                //jsonp: function(data){console.log(data);},
                crossDomain: true,
                xhrFields: {
                    //withCredentials: true
                },
                headers: {
                    'Authorization': 'Bearer '+auth,
                    //'Access-Control-Allow-Origin': "*",
                    //'Access-Control-Request-Headers': 'Authorization Access-Control-Allow-Origin'
                },
                /*beforeSend: function (xhr) {
                    xhr.setRequestHeader ("Authorization", 'Bearer '+auth);
                    xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
                    xhr.withCredentials = true;
                },*/
            })
        .success(function(data) {
            bfjs.authCaptureSuccessHandler(data, bfjs.stripe.key);
        })
        .fail(bfjs.authCaptureFailHandler);
    };

    bfjs.ultimateSuccess = function(paymentMethod) {
        //console.log(paymentMethod);
        bfjs.state.callback(paymentMethod, false);
    };

    bfjs.ultimateFailure = function(reason) {
        console.error(reason);
        bfjs.state.callback(null, reason);
    };

    bfjs.core.getFormValue = function(key) {
        var $formElement = bfjs.state.$formElement;

        return $formElement.find("input[bf-data='"+key+"'], select[bf-data='"+key+"']").val();
    };

    bfjs.stripe.oncePreauthed = function(data) {
        if (!data.results) {
            bfjs.ultimateFailure("Preauthorization failed. Response received, but with no prauth information in it.");
        }
        // This identifies your website in the createToken call below
        var stripePublishableKey = data.results[0].publicKey;
        Stripe.setPublishableKey(stripePublishableKey);

        var mappings = {
            'cardholder-name': 'name',
            'cvc': 'cvc',
            'number': 'number',
            'exp-month': 'exp_month',
            'exp-year': 'exp_year',
            'address-line1': 'address_line1',
            'address-line2': 'address_line2',
            'address-city': 'address_city',
            'address-state': 'address_state',
            'address-zip': 'address_zip',
            'address-country': 'address_country',
        };

        var tokenInfo = {};

        for (var i in mappings) {
            var mapping = mappings[i];
            var valueFromForm = bfjs.core.getFormValue(i);
            if (valueFromForm) {
                tokenInfo[mappings[i]] = valueFromForm;
            }
        }

        Stripe.card.createToken(tokenInfo, bfjs.stripe.responseHandler);
    };

    bfjs.preAuthSuccessHandler = function(data, gateway) {
        //console.log(data);
        try {
            bfjs[gateway].oncePreauthed(data);
        } catch(e) {
            bfjs.ultimateFailure("Preauthorization failed. "+e.message);
        }
    };

    bfjs.preAuthFailHandler = function(reason) {
        // maybe should only go to ultimate failure if ALL gateways fail to tokenize
        bfjs.ultimateFailure(reason);
    };

    bfjs.authCaptureSuccessHandler = function(data, gateway) {
        //console.log(data);
        try {
            var paymentMethod = data.results[0];
            bfjs.ultimateSuccess(paymentMethod);
        } catch(e) {
            bfjs.ultimateFailure("Authorized capture failed. "+e.message);
        }
    };

    bfjs.authCaptureFailHandler = function(reason) {
        // maybe should only go to ultimate failure if ALL gateways fail to tokenize
        bfjs.ultimateFailure(reason);
    };

    bfjs.captureCardOnSubmit = function(formElementSelector, accountID, callback, targetGateway) {
        if (bfjs.core.hasBfCredentials) {
            if (bfjs.core.gatewayChosen){
                var newTransaction = bfjs.Transaction.construct(bfjs, formElementSelector, accountID, callback, targetGateway);
                if (bfjs.core.loaded) {
                    newTransaction.do();
                } else {
                    bfjs.core.deferredTransactions.push(newTransaction);
                }
            } else {
                throw "You need to first call bfjs.loadGateways() with a list of gateways you are likely to use (ie ['stripe', 'braintree'])";
            }
        } else {
            throw "You need to first call bfjs.useAPI() will BillForward credentials";
        }
    };

    bfjs.useAPI = function(url, token, organizationID) {
        bfjs.state.api.url = url;
        bfjs.state.api.token = token;
        bfjs.state.api.organizationID = organizationID;
        bfjs.core.hasBfCredentials = true;
    };

    bfjs.loadGateways = function(gateways) {
        for(var g in gateways) {
            var gateway = gateways[g];
            switch(gateway.toLowerCase()) {
                case 'stripe':
                case 'braintree':
                    bfjs[gateway.toLowerCase()].loadMe = true;
                    bfjs.core.gatewayChosen = true;
                    break;
                default:
                    throw "'"+gateway+"' is not the name of any supported gateway."
            }
        }

        if (bfjs.core.gatewayChosen){
            bfjs.grabScripts();
        }
    };

    window.BillForward = window.BillForward || bfjs;
}());<commit_msg>Added (untested) defer helper classes<commit_after>(function() {
    var bfjs = {};

    bfjs.LateActor = (function() {
        var TheClass = function() {
            this.loaded = false;
            this.deferredTransactions = [];
        };

        TheClass.construct = function() {
            return new TheClass();
        };

        var p = TheClass.prototype;

        p.loadedCallback = function() {
            this.loaded = true;

            for (var i in this.deferredTransactions) {
                var transaction = this.deferredTransactions[i];
                transaction.do();
            }
            this.deferredTransactions = [];
        };

        p.doWhenReady = function(transaction) {
            this.deferredTransactions.push(transaction);
            if (this.loaded) {
                this.loadedCallback();
            }
        };

        return TheClass;
    }());

    bfjs.CoreActor = (function() {
        var TheClass = function() {
            this.hasBfCredentials = false;
            this.gatewayChosen = false;
        };

        TheClass.construct = function() {
            return new TheClass();
        };

        var p = bfjs.LateActor.prototype;
        p.constructor = TheClass;

        return TheClass;
    }());

    bfjs.GatewayActor = (function() {
        var TheClass = function() {
            this.loaded = false;
            this.loadMe = false;
        };

        TheClass.construct = function() {
            return new TheClass();
        };

        var p = bfjs.LateActor.prototype;
        p.constructor = TheClass;

        return TheClass;
    }());

    bfjs.StripeGateway = (function() {
        var TheClass = function() {
            this.key = 'stripe';
        };

        TheClass.construct = function() {
            return new TheClass();
        };

        var p = bfjs.GatewayActor.prototype;
        p.constructor = TheClass;

        return TheClass;
    }());

    bfjs.BraintreeGateway = (function() {
        var TheClass = function() {
            this.key = 'stripe';
        };

        TheClass.construct = function() {
            return new TheClass();
        };

        var p = bfjs.GatewayActor.prototype;
        p.constructor = TheClass;

        return TheClass;
    }());

    // core is mainly to check if jquery is loaded
    bfjs.core = bfjs.CoreActor.construct();

    bfjs.stripe = bfjs.StripeGateway.construct();

    bfjs.braintree = bfjs.BraintreeGateway.construct();

    bfjs.state = {
        api: {
            url: null,
            token: null,
            organizationID: null
        }
    };

    bfjs.grabScripts = function() {
        var queue = [];
        if (typeof jQuery !== 'undefined') {
            bfjs.core.loadedCallback();
        } else {
            // everyone has this in their cache anyway, so..
            queue.push({
                src: "//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js",
                callback: bfjs.core.loadedCallback
            });
        }
        if (bfjs.stripe.loadMe) {
            if (typeof window.Stripe !== 'undefined') {
                queue.push({
                    src: "https://js.stripe.com/v2/",
                    callback: bfjs.stripe.loadedCallback
                });
            } else {
                bfjs.stripe.loadedCallback();
            }
        }
        if (bfjs.braintree.loadMe) {
            if (typeof window.braintree !== 'undefined') {
                queue.push({
                    src: "https://assets.braintreegateway.com/v2/braintree.js",
                    callback: bfjs.braintree.loadedCallback
                });
            } else {
                bfjs.braintree.loadedCallback();
            }
        }

        for (var i = 0; i<queue.length; i++) {
            bfjs.loadScript(queue[i].src, queue[i].callback);
        }
    };

    bfjs.Transaction = (function() {
        var TheClass = function(bfjs, formElementCandidate, accountID, callback, targetGateway) {
            this.formElementCandidate = formElementCandidate;
            this.callback = callback;
            this.accountID = accountID;
            this.targetGateway = targetGateway;
            this.bfjs = bfjs;
            this.state = {
                formElement:  null;
                $formElement: null;
            };
        };

        TheClass.construct = function(bfjs, formElementCandidate, accountID, callback, targetGateway) {
            return new TheClass(bfjs, formElementCandidate, accountID, callback, targetGateway);
        };

        var p = TheClass.prototype;

        p.do = function() {
            $( document ).ready(function() {
                var $formElement = $(this.formElementCandidate);
                var formElement = $formElement.get(0);

                if (!(formElement instanceof HTMLElement)) {
                    throw "Expected jQuery object or HTML element. Perhaps the Form hasn't finished loading?";
                }

                this.state.formElement = formElement;
                this.state.$formElement = $formElement;

                $formElement.submit(function(e) {
                    // Disable the submit button to prevent repeated clicks
                    $(this).find('button').prop('disabled', true);

                    e.preventDefault();
                    e.stopPropagation();
                    this.bfjs[this.chosenGateway].deferRequest();
                });

                // ready to go
                $formElement.find('button').prop('disabled', false);
            });
        };

        return TheClass;
    }());

    bfjs.loadScript = function(url, callback){

        var script = document.createElement("script")
        script.type = "text/javascript";

        var doCallback = function() {
            callback();
        };

        if (script.readyState){  //IE
            script.onreadystatechange = function(){
                if (script.readyState == "loaded" ||
                        script.readyState == "complete"){
                    script.onreadystatechange = null;
                    doCallback();
                }
            };
        } else {  //Others
            script.onload = function(){
                doCallback();
            };
        }

        script.src = url;
        document.getElementsByTagName("head")[0].appendChild(script);
    };

    bfjs.stripe.do = function(state) {
    	var payload = {
    		"gateway": "Stripe"
    	}

    	if(bfjs.state.api.organizationID != null) {
        	payload.organizationID = bfjs.state.api.organizationID;
        }

        bfjs.doPreAuth(payload, bfjs.stripe.key);
    };

    bfjs.braintree.do = function(state) {
        var payload = {
            "gateway": "Braintree"
        }

        if(bfjs.state.api.organizationID != null) {
            payload.organizationID = bfjs.state.api.organizationID;
        }

        bfjs.doPreAuth(payload, bfjs.braintree.key);
    };

    bfjs.stripe.responseHandler = function(status, response) {
        if (response.error) {
            // Show the errors on the form
            bfjs.ultimateFailure(response.error.message);
        } else {
            // token contains id, last4, and card type
            var token = response.id;
            var card = response.card;

            var payload = {
                stripeToken: token,
                cardID: card.id,
                accountID: bfjs.state.accountID
            };

            if(bfjs.state.api.organizationID != null) {
            	payload.organizationID = bfjs.state.api.organizationID;
            }

            // and re-submit
            bfjs.doAuthCapture(payload, bfjs.stripe.key);
        }
    };

    bfjs.doPreAuth = function(payload, gateway) {
        var controller = "tokenization/"
        var endpoint = "pre-auth";
        var fullURL = bfjs.state.api.url + controller + endpoint;
        var auth = bfjs.state.api.token;

        $.support.cors = true;

        $.ajax({
                type: "POST",
                url: fullURL,
                data: JSON.stringify(payload),
                contentType: 'application/json',
                //dataType: 'jsonp',
                //jsonp: function(data){console.log(data);},
                crossDomain: true,
                xhrFields: {
                    //withCredentials: true
                },
                headers: {
                    'Authorization': 'Bearer '+auth,
                    //'Access-Control-Allow-Origin': "*",
                    //'Access-Control-Request-Headers': 'Authorization Access-Control-Allow-Origin'
                },
                /*beforeSend: function (xhr) {
                    xhr.setRequestHeader ("Authorization", 'Bearer '+auth);
                    xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
                    xhr.withCredentials = true;
                },*/
            })
        .success(function(data) {
            bfjs.preAuthSuccessHandler(data, bfjs.stripe.key);
        })
        .fail(bfjs.preAuthFailHandler);
    };

    bfjs.doAuthCapture = function(payload, gateway) {
        var controller = "tokenization/"
        var endpoint = "auth-capture";
        var fullURL = bfjs.state.api.url + controller + endpoint;
        var auth = bfjs.state.api.token;

        $.ajax({
                type: "POST",
                url: fullURL,
                data: JSON.stringify(payload),
                contentType: 'application/json',
                //dataType: 'jsonp',
                //jsonp: function(data){console.log(data);},
                crossDomain: true,
                xhrFields: {
                    //withCredentials: true
                },
                headers: {
                    'Authorization': 'Bearer '+auth,
                    //'Access-Control-Allow-Origin': "*",
                    //'Access-Control-Request-Headers': 'Authorization Access-Control-Allow-Origin'
                },
                /*beforeSend: function (xhr) {
                    xhr.setRequestHeader ("Authorization", 'Bearer '+auth);
                    xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
                    xhr.withCredentials = true;
                },*/
            })
        .success(function(data) {
            bfjs.authCaptureSuccessHandler(data, bfjs.stripe.key);
        })
        .fail(bfjs.authCaptureFailHandler);
    };

    bfjs.ultimateSuccess = function(paymentMethod) {
        //console.log(paymentMethod);
        bfjs.state.callback(paymentMethod, false);
    };

    bfjs.ultimateFailure = function(reason) {
        console.error(reason);
        bfjs.state.callback(null, reason);
    };

    bfjs.core.getFormValue = function(key) {
        var $formElement = bfjs.state.$formElement;

        return $formElement.find("input[bf-data='"+key+"'], select[bf-data='"+key+"']").val();
    };

    bfjs.stripe.oncePreauthed = function(data) {
        if (!data.results) {
            bfjs.ultimateFailure("Preauthorization failed. Response received, but with no prauth information in it.");
        }
        // This identifies your website in the createToken call below
        var stripePublishableKey = data.results[0].publicKey;
        Stripe.setPublishableKey(stripePublishableKey);

        var mappings = {
            'cardholder-name': 'name',
            'cvc': 'cvc',
            'number': 'number',
            'exp-month': 'exp_month',
            'exp-year': 'exp_year',
            'address-line1': 'address_line1',
            'address-line2': 'address_line2',
            'address-city': 'address_city',
            'address-state': 'address_state',
            'address-zip': 'address_zip',
            'address-country': 'address_country',
        };

        var tokenInfo = {};

        for (var i in mappings) {
            var mapping = mappings[i];
            var valueFromForm = bfjs.core.getFormValue(i);
            if (valueFromForm) {
                tokenInfo[mappings[i]] = valueFromForm;
            }
        }

        Stripe.card.createToken(tokenInfo, bfjs.stripe.responseHandler);
    };

    bfjs.preAuthSuccessHandler = function(data, gateway) {
        //console.log(data);
        try {
            bfjs[gateway].oncePreauthed(data);
        } catch(e) {
            bfjs.ultimateFailure("Preauthorization failed. "+e.message);
        }
    };

    bfjs.preAuthFailHandler = function(reason) {
        // maybe should only go to ultimate failure if ALL gateways fail to tokenize
        bfjs.ultimateFailure(reason);
    };

    bfjs.authCaptureSuccessHandler = function(data, gateway) {
        //console.log(data);
        try {
            var paymentMethod = data.results[0];
            bfjs.ultimateSuccess(paymentMethod);
        } catch(e) {
            bfjs.ultimateFailure("Authorized capture failed. "+e.message);
        }
    };

    bfjs.authCaptureFailHandler = function(reason) {
        // maybe should only go to ultimate failure if ALL gateways fail to tokenize
        bfjs.ultimateFailure(reason);
    };

    bfjs.captureCardOnSubmit = function(formElementSelector, accountID, callback, targetGateway) {
        if (bfjs.core.hasBfCredentials) {
            if (bfjs.core.gatewayChosen){
                var newTransaction = bfjs.Transaction.construct(bfjs, formElementSelector, accountID, callback, targetGateway);
                bfjs.core.doWhenReady(newTransaction);
            } else {
                throw "You need to first call bfjs.loadGateways() with a list of gateways you are likely to use (ie ['stripe', 'braintree'])";
            }
        } else {
            throw "You need to first call bfjs.useAPI() will BillForward credentials";
        }
    };

    bfjs.useAPI = function(url, token, organizationID) {
        bfjs.state.api.url = url;
        bfjs.state.api.token = token;
        bfjs.state.api.organizationID = organizationID;
        bfjs.core.hasBfCredentials = true;
    };

    bfjs.loadGateways = function(gateways) {
        for(var g in gateways) {
            var gateway = gateways[g];
            switch(gateway.toLowerCase()) {
                case 'stripe':
                case 'braintree':
                    bfjs[gateway.toLowerCase()].loadMe = true;
                    bfjs.core.gatewayChosen = true;
                    break;
                default:
                    throw "'"+gateway+"' is not the name of any supported gateway."
            }
        }

        if (bfjs.core.gatewayChosen){
            bfjs.grabScripts();
        }
    };

    window.BillForward = window.BillForward || bfjs;
}());<|endoftext|>


<commit_before>const samples = 100;

$(function () {
    $('#big-chart').highcharts({
        chart: {
            type: 'line',
            zoomType: 'x',
            events: {
                selection: function (event) {
                    if (event.xAxis) {
                        var min = event.xAxis[0].min;
                        var max = event.xAxis[0].max;
                        console.log("Big", min, max);

                        /** Update big-chart with new values */
                        this.series[0].setData(helpers.generateRandomDataEnd(min, max, samples));
                    }
                    /** Disables visual zooming */
                    event.preventDefault()
                }
            }
        },
        title: {
            text: 'Datasets relative to time'
        },
        xAxis: {
            type: 'datetime',
            minRange: samples * 1000,
            title: {
                text: 'Time'
            }
        },
        yAxis: {
            title: {
                text: 'Datasets'
            },
            min: 0
        },
        series: [
            {
                name: 'Datasets',
                /** Stupid random start values */
                data: helpers.generateRandomData(-100, samples)
            }
        ],
        plotOptions: {
            series: {
//                marker: { enabled: false },
                /** Hides the line */
//                lineWidth: 0,
                allowPointSelect: true,
            }
        },
        /** Don't show credits link */
        credits: { enabled: false },
        /** Don't show legend at bottom */
        legend: { enabled: false }
    });

    $('#small-chart').highcharts({
        chart: {
            type: 'line',
            zoomType: 'x',
            spacingLeft: 60,
            events: {
                selection: function (event) {
                    if (event.xAxis) {
                        var min = event.xAxis[0].min;
                        var max = event.xAxis[0].max;
                        console.log("Small", min, max);

                        /** Update big-chart with new values */
                        $('#big-chart').highcharts().series[0].setData(helpers.generateRandomDataEnd(min, max, samples));

                        /** Apply mask on y-axis */
                        this.xAxis[0].removePlotBand('mask');
                        this.xAxis[0].addPlotBand({
                            id: 'mask',
                            from: min,
                            to: max,
                            color: 'rgba(0, 0, 0, 0.2)'
                        });
                    }
                    event.preventDefault()
                }
            }
        },
        title: { text: null },
        xAxis: {
            type: 'datetime',
            title: { enabled: false }
        },
        yAxis: {
            title: { enabled: false },
            labels: { enabled: false },
            min: 0
        },
        series: [
            {
                name: 'Datasets',
                /** Stupid random start values */
                data: helpers.generateRandomData(-300, 1000)
            }
        ],
        plotOptions: {
            series: {
                marker: { enabled: false },
                enableMouseTracking: false
            }
        },
        tooltip: { enabled: false },
        /** Don't show credits link */
//        credits: { enabled: false },
        /** Don't show legend at bottom */
        legend: { enabled: false }
    });

    /** Get JSON data from CKAN API */
    $.getJSON("http://eudat6a.dkrz.de/api/timegraph?start=x&end=y", function (data) {
        options.series[0].data = data;
        var chart = new Highcharts.Chart(options);
    });
});

/** Define some helper properties and methods */
function helpers() {
}

helpers.yearZero = moment.utc([0]);
helpers.epoch = moment.utc([1970]);
helpers.second = 1;
helpers.minute = 60 * helpers.second;
helpers.hour = 60 * helpers.minute;
helpers.day = 24 * helpers.hour;
helpers.week = 7 * helpers.day;
helpers.month = 30 * helpers.day;
helpers.year = 12 * helpers.month;

/** zb should be seconds from Year 0 in UTC, as Number or String */
helpers.zeroBasedAsUnix = function (zb) {
    return helpers.yearZero.unix() + Number(zb)
};

/** Converts milliseconds to seconds */
helpers.msToS = function (ms) {
    return ms / 1000
};

/** Converts seconds to milliseconds */
helpers.sToMs = function (s) {
    return s * 1000
};

/** Generates a random integer between min and max */
helpers.getRandomInt = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
};

/** Generates some random data for diagram */
helpers.generateRandomData = function (stime, n) {
    var data = [];
    var start;

    if (stime < -1000 || stime > 2500) {
        start = stime;
    } else {
        start = moment.utc([stime]).valueOf();
    }

    const min = helpers.sToMs(helpers.week);
    const max = helpers.sToMs(helpers.year);

    for (var i = 0; i < n; i++) {
        data.push([
            start += helpers.getRandomInt(min, max),
            helpers.getRandomInt(0, 20)
        ]);
    }

    return data
};

/** Generates some random data for diagram */
helpers.generateRandomDataEnd = function (stime, etime, n) {
    var data = [];

    console.log(stime, etime, n);
    const step = (etime - stime) / n;
    console.log("step = ", step);

    for (var i = 0, start = stime; i < n; i++) {
        data.push([
            start += step,
            helpers.getRandomInt(0, 20)
        ]);
    }

    return data
};

/** Converts integer seconds into human readable format */
function convertSecondsToHuman(seconds) {
    var era;

    if (seconds < 0) {
        // Negative values = Before Christ
        era = "BC";
        seconds = Math.abs(seconds);
    } else if (seconds >= 0) {
        // Positive values = After Christ
        era = "AD";
    } else {
        return null;
    }

    function calcToHuman(rest, div, sign) {
        var t = Math.round(rest / div);
        if (t)
            return "" + t + sign;
        else
            return "";
    }

    var rest = seconds;
    var human = "";

    human += calcToHuman(rest, helpers.year, "y");
    rest = (rest % helpers.year);

    human += calcToHuman(rest, helpers.month, "m");
    rest = (rest % helpers.month);

    human += calcToHuman(rest, helpers.day, "d");
    rest = (rest % helpers.day);

    human += calcToHuman(rest, helpers.hour, "h");
    rest = (rest % helpers.hour);

    human += calcToHuman(rest, helpers.minute, "m");
    rest = (rest % helpers.minute);

    human += calcToHuman(rest, helpers.second, "s");
//    rest = (rest % helpers.second);

    return human + " " + era;
}

/** Creates a shallow copy of an array */
function shallow_copy(array) {
  return array.slice(0)
}
<commit_msg>Add unix to zero-based conversion function<commit_after>const samples = 100;

$(function () {
    $('#big-chart').highcharts({
        chart: {
            type: 'line',
            zoomType: 'x',
            events: {
                selection: function (event) {
                    if (event.xAxis) {
                        var min = event.xAxis[0].min;
                        var max = event.xAxis[0].max;
                        console.log("Big", min, max);

                        /** Update big-chart with new values */
                        this.series[0].setData(helpers.generateRandomDataEnd(min, max, samples));
                    }
                    /** Disables visual zooming */
                    event.preventDefault()
                }
            }
        },
        title: {
            text: 'Datasets relative to time'
        },
        xAxis: {
            type: 'datetime',
            minRange: samples * 1000,
            title: {
                text: 'Time'
            }
        },
        yAxis: {
            title: {
                text: 'Datasets'
            },
            min: 0
        },
        series: [
            {
                name: 'Datasets',
                /** Stupid random start values */
                data: helpers.generateRandomData(-100, samples)
            }
        ],
        plotOptions: {
            series: {
//                marker: { enabled: false },
                /** Hides the line */
//                lineWidth: 0,
                allowPointSelect: true,
            }
        },
        /** Don't show credits link */
        credits: { enabled: false },
        /** Don't show legend at bottom */
        legend: { enabled: false }
    });

    $('#small-chart').highcharts({
        chart: {
            type: 'line',
            zoomType: 'x',
            spacingLeft: 60,
            events: {
                selection: function (event) {
                    if (event.xAxis) {
                        var min = event.xAxis[0].min;
                        var max = event.xAxis[0].max;
                        console.log("Small", min, max);

                        /** Update big-chart with new values */
                        $('#big-chart').highcharts().series[0].setData(helpers.generateRandomDataEnd(min, max, samples));

                        /** Apply mask on y-axis */
                        this.xAxis[0].removePlotBand('mask');
                        this.xAxis[0].addPlotBand({
                            id: 'mask',
                            from: min,
                            to: max,
                            color: 'rgba(0, 0, 0, 0.2)'
                        });
                    }
                    event.preventDefault()
                }
            }
        },
        title: { text: null },
        xAxis: {
            type: 'datetime',
            title: { enabled: false }
        },
        yAxis: {
            title: { enabled: false },
            labels: { enabled: false },
            min: 0
        },
        series: [
            {
                name: 'Datasets',
                /** Stupid random start values */
                data: helpers.generateRandomData(-300, 1000)
            }
        ],
        plotOptions: {
            series: {
                marker: { enabled: false },
                enableMouseTracking: false
            }
        },
        tooltip: { enabled: false },
        /** Don't show credits link */
//        credits: { enabled: false },
        /** Don't show legend at bottom */
        legend: { enabled: false }
    });

    /** Get JSON data from CKAN API */
    $.getJSON("http://eudat6a.dkrz.de/api/timegraph?start=x&end=y", function (data) {
        options.series[0].data = data;
        var chart = new Highcharts.Chart(options);
    });
});

/** Define some helper properties and methods */
function helpers() {
}

helpers.yearZero = moment.utc([0]);
helpers.epoch = moment.utc([1970]);
helpers.second = 1;
helpers.minute = 60 * helpers.second;
helpers.hour = 60 * helpers.minute;
helpers.day = 24 * helpers.hour;
helpers.week = 7 * helpers.day;
helpers.month = 30 * helpers.day;
helpers.year = 12 * helpers.month;

/** zb should be seconds from Year 0 in UTC, as Number or String */
helpers.zeroBasedAsUnix = function (zb) {
    return helpers.yearZero.unix() + Number(zb)
};

/** ux should be seconds from Year 1970 (Epoch) in UTC, as Number or String */
helpers.unixAsZeroBased = function (ux) {
    return Number(ux) - helpers.yearZero.unix()
};

/** Converts milliseconds to seconds */
helpers.msToS = function (ms) {
    return ms / 1000
};

/** Converts seconds to milliseconds */
helpers.sToMs = function (s) {
    return s * 1000
};

/** Generates a random integer between min and max */
helpers.getRandomInt = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
};

/** Generates some random data for diagram */
helpers.generateRandomData = function (stime, n) {
    var data = [];
    var start;

    if (stime < -1000 || stime > 2500) {
        start = stime;
    } else {
        start = moment.utc([stime]).valueOf();
    }

    const min = helpers.sToMs(helpers.week);
    const max = helpers.sToMs(helpers.year);

    for (var i = 0; i < n; i++) {
        data.push([
            start += helpers.getRandomInt(min, max),
            helpers.getRandomInt(0, 20)
        ]);
    }

    return data
};

/** Generates some random data for diagram */
helpers.generateRandomDataEnd = function (stime, etime, n) {
    var data = [];

    console.log(stime, etime, n);
    const step = (etime - stime) / n;
    console.log("step = ", step);

    for (var i = 0, start = stime; i < n; i++) {
        data.push([
            start += step,
            helpers.getRandomInt(0, 20)
        ]);
    }

    return data
};

/** Converts integer seconds into human readable format */
function convertSecondsToHuman(seconds) {
    var era;

    if (seconds < 0) {
        // Negative values = Before Christ
        era = "BC";
        seconds = Math.abs(seconds);
    } else if (seconds >= 0) {
        // Positive values = After Christ
        era = "AD";
    } else {
        return null;
    }

    function calcToHuman(rest, div, sign) {
        var t = Math.round(rest / div);
        if (t)
            return "" + t + sign;
        else
            return "";
    }

    var rest = seconds;
    var human = "";

    human += calcToHuman(rest, helpers.year, "y");
    rest = (rest % helpers.year);

    human += calcToHuman(rest, helpers.month, "m");
    rest = (rest % helpers.month);

    human += calcToHuman(rest, helpers.day, "d");
    rest = (rest % helpers.day);

    human += calcToHuman(rest, helpers.hour, "h");
    rest = (rest % helpers.hour);

    human += calcToHuman(rest, helpers.minute, "m");
    rest = (rest % helpers.minute);

    human += calcToHuman(rest, helpers.second, "s");
//    rest = (rest % helpers.second);

    return human + " " + era;
}

/** Creates a shallow copy of an array */
function shallow_copy(array) {
  return array.slice(0)
}
<|endoftext|>


<commit_before>import lux from "lux.js";
import { map, reduce, get as _get, set as _set, find, cloneDeep, groupBy } from "lodash";

function getHostDetails( host ) {
	const { project, branch, owner, releaseOnly } = host.package;
	const { name: hostName, ip } = host.serviceHost.host;

	return {
		name: host.name,
		project,
		branch,
		owner,
		hostName,
		ip,
		releaseOnly
	};
}

export default new lux.Store( {
	namespace: "project",
	state: {
		packages: {},
		projects: {},
		hosts: [],
		hostByProject: {},
		deployChoice: null,
		releaseChoice: null
	},
	handlers: {
		loadProjectsSuccess( { packages: pkgs } ) {
			const packages = cloneDeep( pkgs );
			this.setState( this.reduceProjects( packages ) );
		},
		loadHostsSuccess( { hosts } ) {
			const mappedHosts = hosts.map( getHostDetails );

			this.setState( {
				hostByProject: groupBy( mappedHosts, "project" ),
				hosts: mappedHosts
			} );
		},
		triggerDeploy( { pkg, host } ) {
			const hostRef = find( this.getState().hosts, { name: host } );
			hostRef.status = null;
			this.setState( {
				deployChoice: {
					pkg, host
				}
			} );
		},
		finalizeDeploy() {
			const { deployChoice } = this.getState();
			deployChoice.saving = true;
			this.setState( { deployChoice } );
		},
		cancelDeploy() {
			this.setState( { deployChoice: null } );
		},
		applySettingsSuccess() {
			this.setState( { deployChoice: null } );
		},
		applySettingsError( e ) {
			const { deployChoice } = this.getState();
			if ( deployChoice ) {
				deployChoice.saving = false;
				deployChoice.error = "There was a problem deploying this package.";
				this.setState( { deployChoice } );
			}
		},
		loadHostStatusSuccess( { name, status } ) {
			const host = find( this.getState().hosts, { name } );
			if ( host ) {
				host.owner = _get( status.activity, "running.owner", host.owner );
				host.project = _get( status.activity, "running.project", host.project );
				host.branch = _get( status.activity, "running.branch", host.branch );
				host.slug = _get( status.activity, "running.slug", host.slug );
				host.version = _get( status.activity, "running.version", host.version ),
				host.status = {
					serviceUptime: _get( status, "uptime.service", "" ),
					hostUptime: _get( status, "uptime.host", "" ),
					fetchTime: new Date()
				};
			}
		},
		confirmReleasePackage( pkg ) {
			this.setState( { releaseChoice: pkg } );
		},
		releasePackage() {
			this.setState( { releaseChoice: null } );
		},
		cancelReleasePackage() {
			this.setState( { releaseChoice: null } );
		},
		releasePackageSuccess() {
			this.setState( { releaseChoice: null } );
		},
		releasePackageError() {
			this.setState( { releaseChoice: null } );
		}
	},
	reduceProjects( packages ) {
		const releases = packages.reduce( ( memo, item ) => {
			if ( item.build ) {
				return memo;
			}
			memo[ `${item.relative}-${item.architecture}-${item.platform}-${item.version}` ] = item.slug;
			return memo;
		}, {} );
		return packages.reduce( ( memo, item ) => {
			if ( !item.build ) {
				return memo;
			}
			const versionPath = [ "projects", item.project, "owners", item.owner, "branches", item.branch ];
			let versions = _get( memo, versionPath, [] );

			versions.push( item.file );
			_set( memo, versionPath, versions );
			item.simpleVersion = item.simpleVersion || item.version.split( "-" )[ 0 ];
			const releaseCheck = releases[ `${item.relative}-${item.architecture}-${item.platform}-${item.simpleVersion}` ];
			item.released = releaseCheck === item.slug;
			item.releasable = !releaseCheck;
			memo.packages[ item.file ] = item;

			return memo;
		}, {
			projects: {},
			packages: {}
		} );
	},
	getProjects() {
		let projects = this.getState().projects;

		return reduce( projects, ( memo, project, name ) => {
			const owner = Object.keys( project.owners )[ 0 ];
			const branch = Object.keys( project.owners[ owner ].branches )[ 0 ];
			memo.push( {
				name,
				owner,
				branch
			} );
			return memo;
		}, [] );
	},
	getProject( name, owner, branch ) {
		const { packages, projects, hostByProject } = this.getState();
		const currentProject = projects[name];

		if ( !currentProject ) {
			return { owners: [], branches: [], versions: {}, hosts: [] };
		}

		const currentOwner = currentProject.owners[owner];
		let branchPackages = _get( currentOwner, [ "branches", branch ], [] );

		const versions = branchPackages.reduce( ( memo, name ) => {
			let item = packages[name];
			let version = item.version.split( "-" )[0];

			const packagesPath = [ version, "builds", `b${item.build}`, "packages" ];
			let buildPackages = _get( memo, packagesPath, [] );

			buildPackages.push( item );
			_set( memo, packagesPath, buildPackages );

			return memo;
		}, {} );

		return {
			owners: map( currentProject.owners, ( owner, name ) => {
				return {
					name,
					branches: Object.keys( owner.branches )
				};
			} ),
			branches: Object.keys( currentOwner.branches ),
			versions,
			hosts: hostByProject[ name ] || []
		};
	},
	getHosts() {
		return this.getState().hosts;
	},
	getDeployChoice() {
		const { deployChoice, hosts } = this.getState();
		if ( !deployChoice ) {
			return null;
		}
		return Object.assign( {}, deployChoice, {
			host: hosts.find( host => deployChoice.host === host.name )
		} );
	},
	getDeployChoiceSettings() {
		const { pkg, host } = this.getDeployChoice();
		const data = [];
		[ "project", "owner", "branch", "version" ].forEach( function( field ) {
			data.push( { op: "change", field, value: pkg[ field ] } );
		} );
		return {
			name: host.name,
			data
		};
	},
	getReleaseChoice() {
		const { releaseChoice } = this.getState();
		return releaseChoice || null;
	}
} );
<commit_msg>Moved reduceProjects out of store methods into private method<commit_after>import lux from "lux.js";
import { map, reduce, get as _get, set as _set, find, cloneDeep, groupBy } from "lodash";

function getHostDetails( host ) {
	const { project, branch, owner, releaseOnly } = host.package;
	const { name: hostName, ip } = host.serviceHost.host;

	return {
		name: host.name,
		project,
		branch,
		owner,
		hostName,
		ip,
		releaseOnly
	};
}

function reduceProjects( packages ) {
	const releases = packages.reduce( ( memo, item ) => {
		if ( item.build ) {
			return memo;
		}
		memo[ `${item.relative}-${item.architecture}-${item.platform}-${item.version}` ] = item.slug;
		return memo;
	}, {} );
	return packages.reduce( ( memo, item ) => {
		if ( !item.build ) {
			return memo;
		}
		const versionPath = [ "projects", item.project, "owners", item.owner, "branches", item.branch ];
		let versions = _get( memo, versionPath, [] );

		versions.push( item.file );
		_set( memo, versionPath, versions );
		item.simpleVersion = item.simpleVersion || item.version.split( "-" )[ 0 ];
		const releaseCheck = releases[ `${item.relative}-${item.architecture}-${item.platform}-${item.simpleVersion}` ];
		item.released = releaseCheck === item.slug;
		item.releasable = !releaseCheck;
		memo.packages[ item.file ] = item;

		return memo;
	}, {
		projects: {},
		packages: {}
	} );
}

export default new lux.Store( {
	namespace: "project",
	state: {
		packages: {},
		projects: {},
		hosts: [],
		hostByProject: {},
		deployChoice: null,
		releaseChoice: null
	},
	handlers: {
		loadProjectsSuccess( { packages: pkgs } ) {
			const packages = cloneDeep( pkgs );
			this.setState( reduceProjects( packages ) );
		},
		loadHostsSuccess( { hosts } ) {
			const mappedHosts = hosts.map( getHostDetails );

			this.setState( {
				hostByProject: groupBy( mappedHosts, "project" ),
				hosts: mappedHosts
			} );
		},
		triggerDeploy( { pkg, host } ) {
			const hostRef = find( this.getState().hosts, { name: host } );
			hostRef.status = null;
			this.setState( {
				deployChoice: {
					pkg, host
				}
			} );
		},
		finalizeDeploy() {
			const { deployChoice } = this.getState();
			deployChoice.saving = true;
			this.setState( { deployChoice } );
		},
		cancelDeploy() {
			this.setState( { deployChoice: null } );
		},
		applySettingsSuccess() {
			this.setState( { deployChoice: null } );
		},
		applySettingsError( e ) {
			const { deployChoice } = this.getState();
			if ( deployChoice ) {
				deployChoice.saving = false;
				deployChoice.error = "There was a problem deploying this package.";
				this.setState( { deployChoice } );
			}
		},
		loadHostStatusSuccess( { name, status } ) {
			const host = find( this.getState().hosts, { name } );
			if ( host ) {
				host.owner = _get( status.activity, "running.owner", host.owner );
				host.project = _get( status.activity, "running.project", host.project );
				host.branch = _get( status.activity, "running.branch", host.branch );
				host.slug = _get( status.activity, "running.slug", host.slug );
				host.version = _get( status.activity, "running.version", host.version ),
				host.status = {
					serviceUptime: _get( status, "uptime.service", "" ),
					hostUptime: _get( status, "uptime.host", "" ),
					fetchTime: new Date()
				};
			}
		},
		confirmReleasePackage( pkg ) {
			this.setState( { releaseChoice: pkg } );
		},
		releasePackage() {
			this.setState( { releaseChoice: null } );
		},
		cancelReleasePackage() {
			this.setState( { releaseChoice: null } );
		},
		releasePackageSuccess() {
			this.setState( { releaseChoice: null } );
		},
		releasePackageError() {
			this.setState( { releaseChoice: null } );
		}
	},
	getProjects() {
		let projects = this.getState().projects;

		return reduce( projects, ( memo, project, name ) => {
			const owner = Object.keys( project.owners )[ 0 ];
			const branch = Object.keys( project.owners[ owner ].branches )[ 0 ];
			memo.push( {
				name,
				owner,
				branch
			} );
			return memo;
		}, [] );
	},
	getProject( name, owner, branch ) {
		const { packages, projects, hostByProject } = this.getState();
		const currentProject = projects[name];

		if ( !currentProject ) {
			return { owners: [], branches: [], versions: {}, hosts: [] };
		}

		const currentOwner = currentProject.owners[owner];
		let branchPackages = _get( currentOwner, [ "branches", branch ], [] );

		const versions = branchPackages.reduce( ( memo, name ) => {
			let item = packages[name];
			let version = item.version.split( "-" )[0];

			const packagesPath = [ version, "builds", `b${item.build}`, "packages" ];
			let buildPackages = _get( memo, packagesPath, [] );

			buildPackages.push( item );
			_set( memo, packagesPath, buildPackages );

			return memo;
		}, {} );

		return {
			owners: map( currentProject.owners, ( owner, name ) => {
				return {
					name,
					branches: Object.keys( owner.branches )
				};
			} ),
			branches: Object.keys( currentOwner.branches ),
			versions,
			hosts: hostByProject[ name ] || []
		};
	},
	getHosts() {
		return this.getState().hosts;
	},
	getDeployChoice() {
		const { deployChoice, hosts } = this.getState();
		if ( !deployChoice ) {
			return null;
		}
		return Object.assign( {}, deployChoice, {
			host: hosts.find( host => deployChoice.host === host.name )
		} );
	},
	getDeployChoiceSettings() {
		const { pkg, host } = this.getDeployChoice();
		const data = [];
		[ "project", "owner", "branch", "version" ].forEach( function( field ) {
			data.push( { op: "change", field, value: pkg[ field ] } );
		} );
		return {
			name: host.name,
			data
		};
	},
	getReleaseChoice() {
		const { releaseChoice } = this.getState();
		return releaseChoice || null;
	}
} );
<|endoftext|>


<commit_before>(function (exports, node) {

	var GameState = node.GameState;
	var Utils = node.Utils;

	/*
	 * Holds information about the list of players.
	 *
	 */

	/**
	 * Expose constructor
	 */
	exports.PlayerList = PlayerList;

	function PlayerList(list) {

		this.pl = list || {};

		this.size = function() {
			return Utils.getListSize(this.pl);
		};

	//	console.log('This is the size ' + this.size());

	}

	exports.PlayerList.prototype.importIDS = function(arrayIDS) {

		var PREFIX = 'P_';
		var i = this.size();
		var j = 0;
		for (;j<arrayIDS.length;j++){
			this.add(arrayIDS[j],'P_' + ++i);
		}
	};

	PlayerList.prototype.addPlayer = function (player) {
		if (!player) return false;
		return this.add(player.id, player.name);
	};

	PlayerList.prototype.add = function (player) {
		if (!player) return false;
		// Check if the id is unique
		if (!this.exist(player.id)) {
			this.pl[player.id] = new Player(player);
			//console.log('Added Player ' + this.pl[pid]);
			return true;
		}

		console.log('E: Attempt to add a new player already in the player list' + this.pl[player.id]);
		return false;
	};

	// OLD ADD
//	PlayerList.prototype.add = function (pid,name) {
//		// Check if the id is unique
//		if (!this.exist(pid)) {
//			this.pl[pid] = new Player({id: pid, name: name});
//			//console.log('Added Player ' + this.pl[pid]);
//			return true;
//		}
//
//		console.log('E: Attempt to add a new player already in the player list' + this.pl.id);
//		return false;
//	};

	PlayerList.prototype.remove = function (pid) {
		// Check if the id exists
		if (this.exist(pid)) {
			delete this.pl[pid];

			return true;
		}

		console.log('E: Attempt to remove a non-existing player from the the player list');
		return false;
	};

	PlayerList.prototype.get = function (pid) {
		// Check if the id exists
		if (this.exist(pid)) {
			return this.pl[pid];
		}

		console.log('W: Attempt to access a non-existing player from the the player list ' + pid);
		return false;
	};

	PlayerList.prototype.pop = function (pid) {
		var p = this.get(pid);
		if (p) {
			this.remove(pid);
		}
		return p;
	};

	PlayerList.prototype.getRandom = function () {
		return this.toArray()[Math.floor(Math.random()*(this.size()))];
	};

	PlayerList.prototype.getAllIDs = function () {

	     return this.map(function(o){
	    	 return o.getId();
	     	});
	};

	PlayerList.prototype.updatePlayer = function (player) {

		if (this.exist(pid)) {
			this.pl[pid] = player;

			return true;
		}

		console.log('W: Attempt to access a non-existing player from the the player list ' + player.id);
		return false;
	};

	PlayerList.prototype.updatePlayerState = function (pid, state) {

		if (!this.exist(pid)) {
			console.log('W: Attempt to access a non-existing player from the the player list ' + player.id);
			return false;
		}

		if ('undefined' === typeof state) {
			console.log('W: Attempt to assign to a player an undefined state');
			return false;
		}

		//console.log(this.pl);

		this.pl[pid].state = state;

		return true;
	};

	PlayerList.prototype.exist = function (pid) {
		return (typeof(this.pl[pid]) !== 'undefined') ? true : false;
	};

	// Returns an array of array of n groups of players {pid: name}
	//The last group could have less elements.
	PlayerList.prototype.getNGroups = function (n) {

		var copy = this.toArray();
		var nPlayers = copy.length;

		var gSize = Math.floor( nPlayers / n);
		var inGroupCount = 0;

		var result = new Array();

		// Init values for the loop algorithm
		var i;
		var idx;
		var gid = -1;
		var count = gSize +1; // immediately creates a new group in the loop
		for (i=0;i<nPlayers;i++){

			// Prepare the array container for the elements of the new group
			if (count >= gSize) {
				gid++;
				result[gid] = new PlayerList();
				count = 0;
			}

			// Get a random idx between 0 and array length
			idx = Math.floor(Math.random()*copy.length);

			result[gid].add(copy[idx].id,copy[idx].name);
			copy.splice(idx,1);
			count++;
		}

		return result;
	};

	// Returns an array of array of groups of n players {pid: name};
	// The last group could have less elements.
	PlayerList.prototype.getGroupsSizeN = function (n) {
		// TODO: getGroupsSizeN
	};

	PlayerList.prototype.checkState = function(gameState,strict) {
		if (this.isStateDone(gameState,strict)) {
			node.emit('STATEDONE');
		}
	};

	// TODO: improve
	// Returns true if all the players are on the same gameState = gameState
	// and they are all GameState = DONE.
	// If strict is TRUE, also not initialized players are taken into account
	PlayerList.prototype.isStateDone = function(gameState, strict) {

		//console.log('1--------> ' + gameState);

		// Check whether a gameState variable is passed
		// if not try to use the node.game.gameState as the default state
		// if node.game has not been initialized yet return false
		if ('undefined' === typeof gameState){
			if ('undefined' === typeof node.game) {
				return false;
			}
			else {
				var gameState = node.game.gameState;
			}
		}

		//console.log('2--------> ' + gameState);

		var strict = strict || false;

		var result = this.map(function(p){
			var gs = new GameState(p.state);

			//console.log('Going to compare ' + gs + ' and ' + gameState);

			// Player is done for his state
			if (p.state.is !== GameState.iss.DONE) {
				return 0;
			}
			// The state of the player is actually the one we are interested in
			if (GameState.compare(gameState, p.state, false) !== 0) {
				return 0;
			}

			return 1;
		});

		var i;
		var sum = 0;
		for (i=0; i<result.length;i++) {
			sum = sum + Number(result[i]);
		}

		var total = (strict) ? this.size() : this.actives();

		return (sum === total) ? true : false;

	};

	// Returns the number of player whose state is different from 0:0:0
	PlayerList.prototype.actives = function(gameState) {
		var result = 0;

		this.forEach(function(p){
			var gs = new GameState(p.state);

			// Player is done for his state
			if (GameState.compare(gs, new GameState()) !== 0) {
				result++;
			}

		});

		//console.log('ACTIVES: ' + result);

		return result;
	};

	PlayerList.prototype.toArray = function () {

		var result = Array();

		for (var key in this.pl) {
		    if (this.pl.hasOwnProperty(key)) {
		    	result.push(this.pl[key]);
		    }
		}
		return result;
		return result.sort();

	};

	PlayerList.prototype.forEach = function(callback, thisArg) {

		for (var key in this.pl) {
		    if (this.pl.hasOwnProperty(key)) {
		    	callback.call(thisArg, this.pl[key]);
		    }
		  }
	};

	PlayerList.prototype.map = function(callback, thisArg) {

		 var result = new Array();

		 for (var key in this.pl) {
			 if (this.pl.hasOwnProperty(key)) {
				 result.push(callback.call(thisArg, this.pl[key]));
			 }
		  }

		  return result;
	};

	PlayerList.prototype.toString = function (eol) {

		var out = '';
		var EOL = eol || '\n';

		for (var key in this.pl) {
		    if (this.pl.hasOwnProperty(key)) {
		    	out += key + ': ' + this.pl[key].name;
		    	var state = new GameState(this.pl[key].state);
		    	//console.log('STATE: ' + this.pl[key].state.state);

		    	out += ': ' + state + EOL;
		    }
		}

		return out;

	};

	//Player

	/**
	 * Expose constructor
	 */

	exports.Player = Player;

	function Player (pl) {

		// PRIVATE variables
		this.id = pl.id;
		this.name = pl.name;
		this.state = pl.state || new GameState();
	}

	Player.prototype.getId = function() {
		return this.id;
	};

	Player.prototype.getName = function() {
		return this.name;
	};

	Player.prototype.updateState = function (state) {
		this.state = state;
	};

	Player.prototype.toString = function() {
		var out = this.getName() + ' (' + this.getId() + ') ' + new GameState(this.state);
		return out;
	};

})(
	'undefined' != typeof node ? node : module.exports
  , 'undefined' != typeof node ? node : module.parent.exports
);<commit_msg>Removed PlayerListOld<commit_after><|endoftext|>


<commit_before>Template.navigation.events({
  'click .js-add-milestone': function(e) {
    var data = { }
    Blaze.renderWithData(Template._formModal, { title: 'Add Milestone', template: '_milestonesForm', data }, document.body);
  },
})

Template.navigation.helpers({
  canAddMilestones: function() {
    return Meteor.userId() && Session.get('canAddMilestones');
  },
})<commit_msg>beautified  _navigaton.js<commit_after>Template.navigation.events({
  'click .js-add-milestone': function() {
    let data = { };
    Blaze.renderWithData(Template._formModal, {
      'title': 'Add Milestone',
      'template': '_milestonesForm', data }, document.body);
  },
});

Template.navigation.helpers({
  'canAddMilestones': function() {
    return Meteor.userId() && Session.get('canAddMilestones');
  },
});
<|endoftext|>


<commit_before>(function() {

    Nv.MapItem = function(map, config) {
        config.tooltipText = config.name;

        Nv.MapObject.call(this, map, 34, 34, config.position, config);

        this.name = config.name;
        this.key = config.key;

        var image = new Kinetic.Image({
            x: 0,
            y: 0,
            image: config.session.images[config.key],
            width: 34,
            height: 34
        });

        this.image = image;
        this.config = config;

        this.add(this.image);

        map.enableCollisionsFor(this);
    };

    Nv.MapItem.prototype = {
        onClick: function() {
            var hero = Nv.sessionInstance().hero,
                item = this;

            // move hero to item abd pickup item
            hero.moveToPosition(this.getX()-1, this.getY()-1, function(){
                item.hideFromUI();
            });

            // pickup item
            this.emitEvent('/items', 'itemPickedUp', {
                'heroId': hero.id,
                'itemKey': this.key,
            });
        }
    };

    Kinetic.Util.extend(Nv.MapItem, Nv.MapObject);
})();<commit_msg>[web] items are now hidden when picked up<commit_after>(function() {

    Nv.MapItem = function(map, config) {
        config.tooltipText = config.name;

        Nv.MapObject.call(this, map, 34, 34, config.position, config);

        this.name = config.name;
        this.key = config.key;

        var image = new Kinetic.Image({
            x: 0,
            y: 0,
            image: config.session.images[config.key],
            width: 34,
            height: 34
        });

        this.image = image;
        this.config = config;

        this.add(this.image);

        map.enableCollisionsFor(this);
    };

    Nv.MapItem.prototype = {
        onClick: function() {
            var hero = Nv.sessionInstance().hero,
                item = this;

            // move hero to item abd pickup item
            hero.moveToPosition(this.getX()-1, this.getY()-1, function(){
                // pickup item
                item.emitEvent('/items', 'itemPickedUp', {
                    'heroId': hero.id,
                    'itemKey': item.key,
                });
            });

        },

    };

    Kinetic.Util.extend(Nv.MapItem, Nv.MapObject);

    function setupEvents() {
        var itemsSocket = this.session.connectToChannel('/items'),
            item = this;

        itemsSocket.on('itemPickedUp', function(data){
            if (data.itemKey === item.key) {
                item.hideFromUI();
            }
        });
    }
})();<|endoftext|>


<commit_before>class BulletTime {
    constructor() {
        this.index = [];
        this.freeId = 0;
    }

    addEvent(time, callback) {
        // Adds an event to the timeline and returns its ID. Accepts an optional callback function as a parameter.
        this.index.push({
            id: this.freeId,
            callback: callback
        });
        this.freeId++;
        return this.freeId - 1;
    }

    removeEvent(id) {
        // Removes the event with the given ID from the timeline.
        let result = this.index.filter((obj) => obj.id === id);
        if (result) this.index.splice(this.index.indexOf(result), 1);
    }

    play() {
        // Begins playback from the current position.
    }

    pause() {
        // Pauses playback at the current position.
    }

    seek() {
        // Seeks the timeline to the specified position.
    }
}<commit_msg>Additional scaffold edits<commit_after>class BulletTime {
    constructor() {
        this._index = [];
        this._freeId = 0;
    }

    addEvent(time, callback) {
        // Adds an event to the timeline and returns its ID. Accepts an optional callback function as a parameter.
        this._index.push({
            id: this._freeId,
            time: time,
            callback: callback
        });
        return this._freeId++;
    }

    removeEvent(id) {
        // Removes the event with the given ID from the timeline.
        let result = this._index.filter((obj) => obj.id === id);
        if (result) this._index.splice(this._index.indexOf(result), 1);
    }

    play() {
        // Begins playback from the current position.
    }

    pause() {
        // Pauses playback at the current position.
    }

    seek() {
        // Seeks the timeline to the specified position.
    }
}<|endoftext|>


<commit_before>import {Selection, NodeSelection, TextSelection} from "prosemirror-state"
import browser from "./browser"
import {domIndex} from "./dom"

function moveSelectionBlock(state, dir) {
  let {$anchor, $head} = state.selection
  let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head)
  let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null
  return $start && Selection.findFrom($start, dir)
}

function apply(view, sel) {
  view.dispatch(view.state.tr.setSelection(sel).scrollIntoView())
  return true
}

function selectHorizontally(view, dir) {
  let sel = view.state.selection
  if (sel instanceof TextSelection) {
    if (!sel.empty) {
      return false
    } else if (view.endOfTextblock(dir > 0 ? "right" : "left")) {
      let next = moveSelectionBlock(view.state, dir)
      if (next && (next instanceof NodeSelection)) return apply(view, next)
      return false
    } else {
      let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter
      if (node && NodeSelection.isSelectable(node))
        return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head))
      return false
    }
  } else if (sel instanceof NodeSelection && sel.node.isInline) {
    return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from))
  } else {
    let next = moveSelectionBlock(view.state, dir)
    if (next) return apply(view, next)
    return false
  }
}

function nodeLen(node) {
  return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length
}

function isIgnorable(dom) {
  let desc = dom.pmViewDesc
  return desc && desc.size == 0
}

// Make sure the cursor isn't directly after one or more ignored
// nodes, which will confuse the browser's cursor motion logic.
function skipIgnoredNodesLeft(view) {
  let sel = view.root.getSelection()
  let node = sel.anchorNode, offset = sel.anchorOffset
  let moveNode, moveOffset
  for (;;) {
    if (offset > 0) {
      if (node.nodeType != 1) {
        if (node.nodeType == 3 && node.nodeValue.charAt(offset - 1) == "\ufeff") {
          moveNode = node
          moveOffset = --offset
        } else break
      } else {
        let before = node.childNodes[offset - 1]
        if (isIgnorable(before)) {
          moveNode = node
          moveOffset = --offset
        } else if (before.nodeType == 3) {
          node = before
          offset = node.nodeValue.length
        } else break
      }
    } else if (isBlockNode(node)) {
      break
    } else {
      let prev = node.previousSibling
      while (prev && isIgnorable(prev)) {
        moveNode = node.parentNode
        moveOffset = domIndex(prev)
        prev = prev.previousSibling
      }
      if (!prev) {
        node = node.parentNode
        if (node == view.dom) break
        offset = 0
      } else {
        node = prev
        offset = nodeLen(node)
      }
    }
  }
  if (moveNode) setSel(sel, moveNode, moveOffset)
}

// Make sure the cursor isn't directly before one or more ignored
// nodes.
function skipIgnoredNodesRight(view) {
  let sel = view.root.getSelection()
  let node = sel.anchorNode, offset = sel.anchorOffset, len = nodeLen(node)
  let moveNode, moveOffset
  for (;;) {
    if (offset < len) {
      if (node.nodeType != 1) break
      let after = node.childNodes[offset]
      if (isIgnorable(after)) {
        moveNode = node
        moveOffset = ++offset
      }
      else break
    } else if (isBlockNode(node)) {
      break
    } else {
      let next = node.nextSibling
      while (next && isIgnorable(next)) {
        moveNode = next.parentNode
        moveOffset = domIndex(next) + 1
        next = next.nextSibling
      }
      if (!next) {
        node = node.parentNode
        if (node == view.dom) break
        offset = len = 0
      } else {
        node = next
        offset = 0
        len = nodeLen(node)
      }
    }
  }
  if (moveNode) setSel(sel, moveNode, moveOffset)
}

function isBlockNode(dom) {
  let desc = dom.pmViewDesc
  return desc && desc.node && desc.node.isBlock
}

function setSel(sel, node, offset) {
  let range = document.createRange()
  range.setEnd(node, offset)
  range.setStart(node, offset)
  sel.removeAllRanges()
  sel.addRange(range)
}

// : (EditorState, number)
// Check whether vertical selection motion would involve node
// selections. If so, apply it (if not, the result is left to the
// browser)
function selectVertically(view, dir) {
  let sel = view.state.selection
  if (sel instanceof TextSelection && !sel.empty) return false
  let {$from, $to} = sel

  if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) {
    let next = moveSelectionBlock(view.state, dir)
    if (next && (next instanceof NodeSelection))
      return apply(view, next)
  }
  if (!$from.parent.inlineContent) {
    let beyond = Selection.findFrom(dir < 0 ? $from : $to, dir)
    return beyond ? apply(view, beyond) : true
  }
  return false
}

function stopNativeHorizontalDelete(view, dir) {
  if (!(view.state.selection instanceof TextSelection)) return true
  let {$head, $anchor, empty} = view.state.selection
  if (!$head.sameParent($anchor)) return true
  if (!empty) return false
  if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) return true
  let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter)
  if (nextNode && !nextNode.isText) {
    let tr = view.state.tr
    if (dir < 0) tr.delete($head.pos - nextNode.nodeSize, $head.pos)
    else tr.delete($head.pos, $head.pos + nextNode.nodeSize)
    view.dispatch(tr)
    return true
  }
  return false
}

// A backdrop key mapping used to make sure we always suppress keys
// that have a dangerous default effect, even if the commands they are
// bound to return false, and to make sure that cursor-motion keys
// find a cursor (as opposed to a node selection) when pressed. For
// cursor-motion keys, the code in the handlers also takes care of
// block selections.

function getMods(event) {
  let result = ""
  if (event.ctrlKey) result += "c"
  if (event.metaKey) result += "m"
  if (event.altKey) result += "a"
  if (event.shiftKey) result += "s"
  return result
}

export function captureKeyDown(view, event) {
  let code = event.keyCode, mods = getMods(event)
  if (code == 8 || (browser.mac && code == 72 && mods == "c")) { // Backspace, Ctrl-h on Mac
    return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view)
  } else if (code == 46 || (browser.mac && code == 68 && mods == "c")) { // Delete, Ctrl-d on Mac
    return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view)
  } else if (code == 13 || code == 27) { // Enter, Esc
    return true
  } else if (code == 37) { // Left arrow
    return selectHorizontally(view, -1) || skipIgnoredNodesLeft(view)
  } else if (code == 39) { // Right arrow
    return selectHorizontally(view, 1) || skipIgnoredNodesRight(view)
  } else if (code == 38) { // Up arrow
    return selectVertically(view, -1) || skipIgnoredNodesLeft(view)
  } else if (code == 40) { // Down arrow
    return selectVertically(view, 1) || skipIgnoredNodesRight(view)
  } else if (mods == (browser.mac ? "m" : "c") &&
             (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz]
    return true
  }
  return false
}
<commit_msg>Don't automatically select non-atom inline nodes<commit_after>import {Selection, NodeSelection, TextSelection} from "prosemirror-state"
import browser from "./browser"
import {domIndex} from "./dom"

function moveSelectionBlock(state, dir) {
  let {$anchor, $head} = state.selection
  let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head)
  let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null
  return $start && Selection.findFrom($start, dir)
}

function apply(view, sel) {
  view.dispatch(view.state.tr.setSelection(sel).scrollIntoView())
  return true
}

function selectHorizontally(view, dir) {
  let sel = view.state.selection
  if (sel instanceof TextSelection) {
    if (!sel.empty) {
      return false
    } else if (view.endOfTextblock(dir > 0 ? "right" : "left")) {
      let next = moveSelectionBlock(view.state, dir)
      if (next && (next instanceof NodeSelection)) return apply(view, next)
      return false
    } else {
      let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc
      if (node && NodeSelection.isSelectable(node) &&
          (node.isAtom || (desc = view.docView.descAt($head.pos)) && !desc.contentDOM))
        return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head))
      return false
    }
  } else if (sel instanceof NodeSelection && sel.node.isInline) {
    return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from))
  } else {
    let next = moveSelectionBlock(view.state, dir)
    if (next) return apply(view, next)
    return false
  }
}

function nodeLen(node) {
  return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length
}

function isIgnorable(dom) {
  let desc = dom.pmViewDesc
  return desc && desc.size == 0
}

// Make sure the cursor isn't directly after one or more ignored
// nodes, which will confuse the browser's cursor motion logic.
function skipIgnoredNodesLeft(view) {
  let sel = view.root.getSelection()
  let node = sel.anchorNode, offset = sel.anchorOffset
  let moveNode, moveOffset
  for (;;) {
    if (offset > 0) {
      if (node.nodeType != 1) {
        if (node.nodeType == 3 && node.nodeValue.charAt(offset - 1) == "\ufeff") {
          moveNode = node
          moveOffset = --offset
        } else break
      } else {
        let before = node.childNodes[offset - 1]
        if (isIgnorable(before)) {
          moveNode = node
          moveOffset = --offset
        } else if (before.nodeType == 3) {
          node = before
          offset = node.nodeValue.length
        } else break
      }
    } else if (isBlockNode(node)) {
      break
    } else {
      let prev = node.previousSibling
      while (prev && isIgnorable(prev)) {
        moveNode = node.parentNode
        moveOffset = domIndex(prev)
        prev = prev.previousSibling
      }
      if (!prev) {
        node = node.parentNode
        if (node == view.dom) break
        offset = 0
      } else {
        node = prev
        offset = nodeLen(node)
      }
    }
  }
  if (moveNode) setSel(sel, moveNode, moveOffset)
}

// Make sure the cursor isn't directly before one or more ignored
// nodes.
function skipIgnoredNodesRight(view) {
  let sel = view.root.getSelection()
  let node = sel.anchorNode, offset = sel.anchorOffset, len = nodeLen(node)
  let moveNode, moveOffset
  for (;;) {
    if (offset < len) {
      if (node.nodeType != 1) break
      let after = node.childNodes[offset]
      if (isIgnorable(after)) {
        moveNode = node
        moveOffset = ++offset
      }
      else break
    } else if (isBlockNode(node)) {
      break
    } else {
      let next = node.nextSibling
      while (next && isIgnorable(next)) {
        moveNode = next.parentNode
        moveOffset = domIndex(next) + 1
        next = next.nextSibling
      }
      if (!next) {
        node = node.parentNode
        if (node == view.dom) break
        offset = len = 0
      } else {
        node = next
        offset = 0
        len = nodeLen(node)
      }
    }
  }
  if (moveNode) setSel(sel, moveNode, moveOffset)
}

function isBlockNode(dom) {
  let desc = dom.pmViewDesc
  return desc && desc.node && desc.node.isBlock
}

function setSel(sel, node, offset) {
  let range = document.createRange()
  range.setEnd(node, offset)
  range.setStart(node, offset)
  sel.removeAllRanges()
  sel.addRange(range)
}

// : (EditorState, number)
// Check whether vertical selection motion would involve node
// selections. If so, apply it (if not, the result is left to the
// browser)
function selectVertically(view, dir) {
  let sel = view.state.selection
  if (sel instanceof TextSelection && !sel.empty) return false
  let {$from, $to} = sel

  if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) {
    let next = moveSelectionBlock(view.state, dir)
    if (next && (next instanceof NodeSelection))
      return apply(view, next)
  }
  if (!$from.parent.inlineContent) {
    let beyond = Selection.findFrom(dir < 0 ? $from : $to, dir)
    return beyond ? apply(view, beyond) : true
  }
  return false
}

function stopNativeHorizontalDelete(view, dir) {
  if (!(view.state.selection instanceof TextSelection)) return true
  let {$head, $anchor, empty} = view.state.selection
  if (!$head.sameParent($anchor)) return true
  if (!empty) return false
  if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) return true
  let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter)
  if (nextNode && !nextNode.isText) {
    let tr = view.state.tr
    if (dir < 0) tr.delete($head.pos - nextNode.nodeSize, $head.pos)
    else tr.delete($head.pos, $head.pos + nextNode.nodeSize)
    view.dispatch(tr)
    return true
  }
  return false
}

// A backdrop key mapping used to make sure we always suppress keys
// that have a dangerous default effect, even if the commands they are
// bound to return false, and to make sure that cursor-motion keys
// find a cursor (as opposed to a node selection) when pressed. For
// cursor-motion keys, the code in the handlers also takes care of
// block selections.

function getMods(event) {
  let result = ""
  if (event.ctrlKey) result += "c"
  if (event.metaKey) result += "m"
  if (event.altKey) result += "a"
  if (event.shiftKey) result += "s"
  return result
}

export function captureKeyDown(view, event) {
  let code = event.keyCode, mods = getMods(event)
  if (code == 8 || (browser.mac && code == 72 && mods == "c")) { // Backspace, Ctrl-h on Mac
    return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodesLeft(view)
  } else if (code == 46 || (browser.mac && code == 68 && mods == "c")) { // Delete, Ctrl-d on Mac
    return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodesRight(view)
  } else if (code == 13 || code == 27) { // Enter, Esc
    return true
  } else if (code == 37) { // Left arrow
    return selectHorizontally(view, -1) || skipIgnoredNodesLeft(view)
  } else if (code == 39) { // Right arrow
    return selectHorizontally(view, 1) || skipIgnoredNodesRight(view)
  } else if (code == 38) { // Up arrow
    return selectVertically(view, -1) || skipIgnoredNodesLeft(view)
  } else if (code == 40) { // Down arrow
    return selectVertically(view, 1) || skipIgnoredNodesRight(view)
  } else if (mods == (browser.mac ? "m" : "c") &&
             (code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz]
    return true
  }
  return false
}
<|endoftext|>


<commit_before>exports.names = ['reload'];
exports.hidden = true;
exports.enabled = true;
exports.matchStart = true;
exports.cd_all = 10;
exports.cd_user = 30;
exports.cd_manager = 0;
exports.min_role = PERMISSIONS.COHOST;
exports.handler = function (data) {
    modMessage(data, 'Reloading commands...');

    load_responses();
};
<commit_msg>reload no longer outputs a message<commit_after>exports.names = ['reload'];
exports.hidden = true;
exports.enabled = true;
exports.matchStart = true;
exports.cd_all = 10;
exports.cd_user = 30;
exports.cd_manager = 0;
exports.min_role = PERMISSIONS.COHOST;
exports.handler = function (data) {
    load_responses();
};
<|endoftext|>


<commit_before>// Try await not then

const Discord = require('discord.js');
const config = require("../settings.json");

exports.run = function(client, message){
  let Author = message.author.id;
  let status = ['online', 'idle', 'dnd', 'invisible'];
  const embed = new Discord.RichEmbed()
    .setTitle("Margarine's Status Menu")
    .setColor(0x00AE86)
    .setDescription("Set Margarine's status")
    .setThumbnail(config.mAvatar)
    .setTimestamp()
    .addField("To set status:", "Type 1 for online.\nType 2 for idle.\nType 3 for Do not disturb.\nType 4 for Invisible.")
    .addField("To exit menu:", "Type exit.")

  message.channel.send({embed})
    .then(message => {
      if(message.Author.reply == '1'){
        console.log('Status changed.');
        client.user.setStatus(status[0]);
      } else if (message.Author.reply == '2'){
        console.log('Status changed.');
        client.user.setStatus(status[1]);
      } else if (message.Author.reply == '3'){
        console.log('Status changed.');
        client.user.setStatus(status[2]);
      } else if (message.Author.reply == '4'){
        console.log('Status changed.');
        client.user.setStatus(status[3]);
      } //else {
        //message.channel.send("You didn't follow instructions.");
      //}
    });
}

exports.conf = {
  enabled: true,
  guildOnly: false,
  aliases: ['status'],
  permLevel: 5
};

exports.help = {
  name: 'status',
  description: 'Set the status.',
  usage: 'status <args>'
};<commit_msg>Update status.js<commit_after>const Discord = require("discord.js");
const config = require("../settings.json");

exports.run = async (client, message) => {
  let status = ["online", "idle", "dnd", "invisible"];
  const embed = new Discord.RichEmbed()
    .setTitle("Margarine's Status Menu")
    .setColor(0x00AE86)
    .setDescription("Set Margarine's status")
    .setThumbnail(config.mAvatar)
    .setTimestamp()
    .addField("To set status:", "ðŸ˜„ for online.\nðŸ˜ for idle.\nðŸ˜¡ for Do not disturb.\nðŸ‘» for Invisible.")
    .addField("To exit menu:", "âŒ")

  await message.channel.send({embed})
    .then(message => {
      message.react("ðŸ˜„");
      message.react("ðŸ˜");
      message.react("ðŸ˜¡");
      message.react("ðŸ‘»");
      message.react("âŒ");
    });

  if(client.messageReactionAdd === "ðŸ˜„"){
    console.log("Status changed.");
    return client.user.setStatus(status[0]);
  } else if (client.messageReactionAdd === "ðŸ˜"){
    console.log("Status changed.");
    return client.user.setStatus(status[1]);
  } else if (client.messageReactionAdd === "ðŸ˜¡"){
    console.log("Status changed.");
    return client.user.setStatus(status[2]);
  } else if (client.messageReactionAdd === "ðŸ‘»"){
    console.log("Status changed.");
    return client.user.setStatus(status[3]);
  } else if (client.messageReactionAdd === "âŒ"){
    console.log("User exited status menu.");
    return message.channel.send("You have exited the menu.");
  }
};

exports.conf = {
  enabled: true,
  guildOnly: false,
  aliases: ["status"],
  permLevel: 5
};

exports.help = {
  name: "status",
  description: "Set the status.",
  usage: "status"
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

require("babel-core/register")({
    stage: 0,
    ignore: function(filename) {
        // ignore node modules in the current directory
        if (!/node_modules/.test(__dirname) || filename.indexOf(process.cwd()) === 0) {
            return /node_modules/.test(filename);
        }

        // don't ignore node_modules in gluestick
        return !/\/node_modules\/gluestick\/src\//.test(filename);
    }
});

require("./cli");

<commit_msg>Fix npm start<commit_after>#!/usr/bin/env node
'use strict';

require("babel-core/register")({
    stage: 0,
    ignore: function(filename) {
        // ignore node modules in the current directory
        if (!/node_modules/.test(__dirname) || filename.indexOf(process.cwd()) === 0) {
            // When you run `npm start` it will run `gluestick start` but it
            // doesn't run from /usr/local/bin it actually runs it from the
            // project's node_moduls/.bin/gluestick location. For this reason
            // we cannot ignore the `cli.js` file or we wont be able to use ES6
            // in our command line interface.
            // do not skip the babel hook on the cli file
            if (/node_modules\/gluestick\/src\/cli.js/.test(filename)) return false;

            // do skip the rest of the files in node_modules
            return /node_modules/.test(filename);
        }

        // don't ignore node_modules in gluestick
        return !/\/node_modules\/gluestick\/src\//.test(filename);
    }
});

require("./cli");

<|endoftext|>


<commit_before>"use strict";

let { EventEmitter } = require("events");

let Main   = require("../common/Main");
let Block  = require("../common/Block");
let Player = require("../common/Player");
let { Side } = require("../common/network");
let { extend } = require("../common/utility");

let Input      = require("./Input");
let Controller = require("./Controller");
let Client     = require("./Client");
let Assets     = require("./Assets");
let { Graphics } = require("./graphics");

let Game = module.exports = class Game extends Main {

  constructor(canvas, size, scale) {
    super(Side.CLIENT);

    this.canvas     = canvas;
    this.input      = new Input(this);
    this.controller = new Controller(this);
    this.client     = new Client(this);
    this.assets     = new Assets(this);
    this.graphics   = new Graphics(this, canvas, size, scale);

    // Using a web worker, we can avoid set-interval running at
    // crippled speed when the tab is in the background. Justice!
    this.worker = new Worker("worker.js");
  }

  get player() { return null; } // TODO: this.client.tracking[@client.own-id]; }

  run(ups = 30) {
    this.assets.load("loading-screen", () => {
      this.graphics.init();
      this.assets.load("game", () => {
        this.emit("ready");
        let interval = 1 / ups;
        this.worker.postMessage(interval * 1000);
        this.worker.addEventListener("message", () => this.update(interval));
        this.client.connect();
      });
    });
  }

  update(delta) {
    this.controller.update();
    super.update(delta);
  }

};

window.addEventListener("load", () => {
  let canvas = document.getElementById("game");
  let game = window.game = new Game(canvas);

  game.client.on("connect", () => { console.log("Connected"); });
  game.client.on("disconnect", (reason) => { console.log(`Disconnected (${ reason })`); });
  game.client.on("login", () => {
    console.log(`Logged in with ID '${ game.client.ownId }'`);
    game.add(extend(new Player(), { pos: [ 64, 64 ], networkId: game.client.ownId }));
  });
  game.run();
});
<commit_msg>Re-implement Game.player<commit_after>"use strict";

let { EventEmitter } = require("events");

let Main   = require("../common/Main");
let Block  = require("../common/Block");
let Player = require("../common/Player");
let { Side } = require("../common/network");
let { extend } = require("../common/utility");

let Input      = require("./Input");
let Controller = require("./Controller");
let Client     = require("./Client");
let Assets     = require("./Assets");
let { Graphics } = require("./graphics");

let Game = module.exports = class Game extends Main {

  constructor(canvas, size, scale) {
    super(Side.CLIENT);

    this.canvas     = canvas;
    this.input      = new Input(this);
    this.controller = new Controller(this);
    this.client     = new Client(this);
    this.assets     = new Assets(this);
    this.graphics   = new Graphics(this, canvas, size, scale);

    // Using a web worker, we can avoid set-interval running at
    // crippled speed when the tab is in the background. Justice!
    this.worker = new Worker("worker.js");
  }

  get player() { return this.entities.get(this.client.ownId); }

  run(ups = 30) {
    this.assets.load("loading-screen", () => {
      this.graphics.init();
      this.assets.load("game", () => {
        this.emit("ready");
        let interval = 1 / ups;
        this.worker.postMessage(interval * 1000);
        this.worker.addEventListener("message", () => this.update(interval));
        this.client.connect();
      });
    });
  }

  update(delta) {
    this.controller.update();
    super.update(delta);
  }

};

window.addEventListener("load", () => {
  let canvas = document.getElementById("game");
  let game = window.game = new Game(canvas);

  game.client.on("connect", () => { console.log("Connected"); });
  game.client.on("disconnect", (reason) => { console.log(`Disconnected (${ reason })`); });
  game.client.on("login", () => {
    console.log(`Logged in with ID '${ game.client.ownId }'`);
    game.add(extend(new Player(), { pos: [ 64, 64 ], networkId: game.client.ownId }));
  });
  game.run();
});
<|endoftext|>