<commit_before>///////////Global vars/////////////
// global website base, set to localhost for testing, use deploy script to change
var baseUrl = "http://eyebrowse.herokuapp.com";
var siteName = "Eyebrowse";

///////////////////models//////////////////////

//This object can represent either a whitelist or blacklist for a given user. On an update send results to server to update stored data. On intialization set is synced with server. Should allow offline syncing in the future.
var FilterListItem = Backbone.Model.extend({
    parse: function(data) {
        if (data !== null) {
            return {
                url : data.url,
                id : data.id,
            }
        }
    },
});

/*
    collection to hold filterlist items
*/
var FilterList = Backbone.Collection.extend({

    model: FilterListItem,

    initialize: function(type) {
        _.bindAll(this);
        this.type = type;
        this._fetch();
    },

    getType : function() {
        return this.get("type")
    },

    url : function() {
        return getApiURL(this.type)
    },

    parse: function(data, res){
        if (res.status === 200) {
            return data.objects;
        }
    },

    //wrapper for fetch which logs user out if server errs
    _fetch: function() {
        this.fetch({
            error: _.bind(function(model, xhr, options) {
                console.log(arguments)
                if (typeof user !== "undefined" && navigator.onLine){
                    user.logout();
                }
            }, this)
        });
    },
});

/*
    User object holds the status of the user, the cookie from the server, preferences for eyebrowse, whitelist, blacklist, etc.
*/
var User = Backbone.Model.extend({
    defaults: {
        "loggedIn" : false,
        "whitelist" : new FilterList("whitelist"),
        "blacklist" : new FilterList("blacklist"),
        "username" : "",
        "resourceURI" : "/api/v1/user/",
        "ignoreLoginPrompt" : true,
    },

    initialize : function() {
        _.bindAll(this); //allow access to 'this' in callbacks with "this" meaning the object not the context of the callback

    },

    getWhitelist : function() {
        return this.get("whitelist")
    },

    getBlacklist : function() {
        return this.get("blacklist")
    },

    getUsername : function() {
        return this.get("username")
    },

    getResourceURI : function() {
        return this.get("resourceURI")
    },

    isLoggedIn : function() {
        if (this.getUsername() === this.defaults.username || this.getResourceURI() === this.defaults.resourceURI) {
            this.logout();
        }
        return this.get("loggedIn")
    },

    ignoreLoginPrompt : function(){
        return this.get("ignoreLoginPrompt");
    },

    //when the user is logged in set the boolean to give logged in views.
    setLogin : function(status) {
        this.set({
            "loggedIn": status,
        });

        var map = {
            "true" : "login",
            "false" : "logout"
        };

        loginBadge(map[status]);
    },

    login : function() {
        this.setLogin(true);
        this.setLoginPrompt(false);
    },

    logout : function() {
        this.setLogin(false);
    },

    setUsername : function(username) {
        this.set({
            "username": username,
        });
        this.setResourceURI(username);
    },

    setResourceURI : function(username) {
        this.set({
            "resourceURI" : sprintf("/api/v1/user/%s/", username)
        })
    },

    setWhitelist : function(whitelist) {
        this.setFilterSet("whitelist", whitelist);
    },

    setBlacklist : function(blacklist) {
        this.setFilterSet("blacklist", blacklist);
    },

    setFilterSet : function(type, list) {
        this.set({
            type : list
        })
    },

    setLoginPrompt : function(bool){
        this.set({
            "ignoreLoginPrompt" : bool
        });
    },

    //check if a url is in the blacklist
    inBlackList : function(url) {
        return this.inSet("blacklist", url)
    },

    //check if a url is in the whitelise
    inWhitelist : function(url) {
        return this.inSet("whitelist", url)
    },

    //check if url is in a set (either whitelist or blacklist)
    // documentation for URL.js : http://medialize.github.com/URI.js/docs.html
    inSet : function(setType, url) {
        var set = this.get(setType);
        var uri = new URI(url)
        var hostname = uri.hostname();
        var protocol = uri.protocol();
        return (set.where({"url" : hostname}).length || set.where({"url" : protocol}).length || set.where(url).length)
    },

    //save the current state to local storage
    saveState : function(){
        localStorage.user = JSON.stringify(this);
    },
});

//////////////////data collection handlers/////////////
/*
    inputs:
    tabId - indentifer of tab (unique to session only)
    url - url of the tab making the request
    favIconUrl - used for displaying content
    title - title of the webpage the tab is displaying
    event_type - whether a tab is opening or closing/navigating to a new page etc
*/
function openItem(tabId, url, favIconUrl, title, event_type) {
    if (!user.isLoggedIn()){
        if (!user.ignoreLoginPrompt()){
            chrome.tabs.sendMessage(tabId, {
                "action" : "prompt",
                "type" : "loginPrompt",
                "baseUrl" : baseUrl,
            })
        }
      return
    }
    var timeCheck = checkTimeDelta();
    var uri = new URI(url);
    //if its not in the whitelist lets check that the user has it

    if (!user.inWhitelist(url) && !user.inBlackList(url)) {

        timeCheck.allow = false; // we need to wait for prompt callback
        chrome.tabs.sendMessage(tabId, {
            "action": "prompt",
            "type" : "trackPrompt",
            "baseUrl": baseUrl,
        });
        tmpItem = {
            "tabId" : tabId,
            "url" : url,
            "favIconUrl" : favIconUrl,
            "title" : title,
            "event_type" : event_type,
        }

    } else if (user.inBlackList(url)) {
        return
    }

    if (timeCheck.allow){
        finishOpen(tabId, url, favIconUrl, title, event_type, timeCheck.time);
    }
}

/*
    change the active item state of an item.
    called after a prompt is allowed or timecheck passes
*/
function finishOpen(tabId, url, favIconUrl, title, event_type, time) {
    if (activeItem !== undefined) {
        closeItem(activeItem.tabId, activeItem.url, "blur", time);
    };

    //reassign the active item to be the current tab
    activeItem = {
        "tabId" : tabId,
        "url" : url,
        "favIconUrl" : favIconUrl,
        "title" : title,
        "start_event" : event_type,
        "start_time" : new Date(),
    };
}

/*
    There is only ever one activeItem at a time so only close out the active one.
    This event will be fired when a tab is closed or unfocused but we would have already "closed" the item so we don"t want to do it again.
*/
function closeItem(tabId, url, event_type, time) {
    if (activeItem === undefined) return;
    var time = time || new Date(); // time is undefined for destroy event
    if (activeItem.tabId === tabId && !user.inBlackList(url)) {
        //write to local storage
        var item = $.extend({}, activeItem); //copy activeItem

        item.end_event = event_type;
        item.end_time = time;
        item.total_time = item.end_time - item.start_time;
        item.humanize_time = moment.humanizeDuration(item.total_time);
        local_history.push(item);

        // send data for server and sync whitelist/blacklist

        if (local_history.length) {
            dumpData();
            user.getWhitelist()._fetch();
            user.getBlacklist()._fetch();
        }
    }
}

/*
    checks if the time between the current event and the active item is greater than the delta. Default delta is 900ms
*/
function checkTimeDelta(delta) {
    var delta = delta || 900
    var now = new Date();
    var allow = true; // default to true allows active item to be set initially
    if (activeItem !== undefined) {
        allow = (now.getTime() - activeItem.start_time) > delta
    }

    return {
        "allow" : allow,
        "time" : now,
    }
}

///////////////message handlers///////////////
/*
    create a whitelist or blacklist item when the message comes in from the prompt
*/
function handleFilterListMsg(msg) {
    var type = msg.type;
    var url = msg.url;
    var list;
    if (type == "whitelist") {
        list = user.getWhitelist();
        if (tmpItem !== null) {
            finishOpen(tmpItem.tabId, tmpItem.url, tmpItem.favIconUrl, tmpItem.title, tmpItem.event_type)
            tmpItem = null
        }
    } else if (type == "blacklist") {
        list = user.getBlacklist();
    } else {
        return
    }
    m = list.create({
        "url" : url,
        "user" : user.getResourceURI(),
    });

    localStorage.user = JSON.stringify(user);
}

/*
    close an item if the tab is idle
*/
function handleIdleMsg(msg, tabId) {
    var type = msg.type;
    if (type == "openItem")  {
        openTab(tabId, "focus");
    } else if (type == "closeItem" && activeItem !== undefined) {
        closeTab(tabId, "idle", function() {
                activeItem = undefined;
            });
    }
}

/*
    Open the popup so the user can logback in again
*/
function handleLoginMsg(){
   openLink(chrome.extension.getURL('html/popup.html'));
}

/*
    Store the ignore state so the popup message does not display
*/
function handleIgnoreMsg(){
    user.setLoginPrompt(true);
}

///////////////////server comm utils///////////////////

/*
    Posts data to server
*/
function dumpData() {
    var backlog = []
    var url = getApiURL("history-data");
    var stop = false;
    $.each(local_history, function(index, item){
        if (stop) return; //stop sending on error
        payload = serializePayload(item);
        var that = this;
        $.ajax({
            type: "POST",
            url: url,
            data: payload,
            dataType: "text",
            processData:  false,
            contentType: "application/json",
            error: function(jqXHR, textStatus, errorThrown){
                stop = true;
                if (navigator.onLine){
                    user.logout(); //notify user of server error
                }
            },
            success: function(data, textStatus, jqXHR) {
               local_history.splice(index, 1); //remove item from history on success
            },
        });
    });
}

/*
    converts the data to JSON serialized
*/
function serializePayload(payload) {
    payload.user = user.getResourceURI();
    payload.src = "chrome";
    return JSON.stringify(payload);
}

/*
    build an API url for the given inputs
*/
function getApiURL(resource, id, params) {
    params = params || {};
    var apiBase = sprintf("%s/api/v1/%s", baseUrl, resource);
    var getParams = ""
    for (var key in params) {
      getParams += sprintf("&%s=%s", key, params[key]);
    }

    if (getParams !== "") {
        apiBase += "?" + getParams.slice(1);
    }
    if (id != null) {
        apiBase += "/" + id;
    }
    return apiBase
}

/*
Helper to open urls from the extension to the main website
*/
function openLink(url) {
    chrome.tabs.create({"url": url});
}

///////////////////local storage methods//////////////
/*
    create or parase and return localhistory object
*/
function loadLocalHistory() {
    localString = localStorage.local_history;
    localString = (localString) ? localString : "[]"; // catch undefined case
    return JSON.parse(localString);
}

/*
    Get and return the user from local storage.
    If no user is found create a new one.
    If an old user exists unJSON the object and return it.
*/
function getLocalStorageUser() {
    var storedUser = localStorage.user;
    if (storedUser === undefined || storedUser === "null") {
        user = new User();
        localStorage.user = JSON.stringify(user)//store user
        return user
    }

    o = JSON.parse(storedUser);
    var u = new User();

    u.setUsername(o.username);
    u.setLogin(o.loggedIn);
    if (o.loggedIn){
        //if the user is logged in don't ignore the prompt
        u.setLoginPrompt(false);
    }
    u.setBlacklist(o.blacklist);
    u.setWhitelist(o.whitelist);

    return u
}

/*
    Clear the local storage for the given key
*/
function clearLocalStorage(key) {
    localStorage[key] = null;
}

/*
    remove all local history from storage
*/
function clearStorage(){
    localStorage.removeItem("local_history")
    local_history = []
}

//////////////////badge utils////////////////////

/*
    wraps the chrome badge update function
*/
function updateBadge(text) {
    chrome.browserAction.setBadgeText(
        {
            "text" : text
        });
}

/*
    clear login flag
*/
function loginBadge(e) {
    if (e == "logout") {
        updateBadge("!");
    } else if(e == "login") {
        updateBadge("");
    }
}

/*
    initialize the badge with login flag
*/
function initBadge() {
    chrome.browserAction.setBadgeBackgroundColor({"color":"#cd5c5c"});
    if (!user.isLoggedIn()) {
        loginBadge("logout");
    }
}

// dictionary mapping all open items. Keyed on tabIds and containing all information to be written to the log.
var activeItem;
var tmpItem;

local_history = loadLocalHistory();

user = getLocalStorageUser();
initBadge()

localStorage.setItem("baseUrl", baseUrl);<commit_msg>change<commit_after>///////////Global vars/////////////
// global website base, set to localhost for testing, use deploy script to change
var baseUrl = "http://eyebrowse.herokuapp.com";
var siteName = "Eyebrowse";

///////////////////models//////////////////////

//This object can represent either a whitelist or blacklist for a given user. On an update send results to server to update stored data. On intialization set is synced with server. Should allow offline syncing in the future.
var FilterListItem = Backbone.Model.extend({
    parse: function(data) {
        if (data !== null) {
            return {
                url : data.url,
                id : data.id,
            }
        }
    },
});

/*
    collection to hold filterlist items
*/
var FilterList = Backbone.Collection.extend({

    model: FilterListItem,

    initialize: function(type) {
        _.bindAll(this);
        this.type = type;
        this._fetch();
    },

    getType : function() {
        return this.get("type")
    },

    url : function() {
        return getApiURL(this.type)
    },

    parse: function(data, res){
        if (res.status === 200) {
            return data.objects;
        }
    },

    //wrapper for fetch which logs user out if server errs
    _fetch: function() {
        this.fetch({
            error: _.bind(function(model, xhr, options) {
                if (typeof user !== "undefined" && navigator.onLine){
                    user.logout();
                }
            }, this)
        });
    },
});

/*
    User object holds the status of the user, the cookie from the server, preferences for eyebrowse, whitelist, blacklist, etc.
*/
var User = Backbone.Model.extend({
    defaults: {
        "loggedIn" : false,
        "whitelist" : new FilterList("whitelist"),
        "blacklist" : new FilterList("blacklist"),
        "username" : "",
        "resourceURI" : "/api/v1/user/",
        "ignoreLoginPrompt" : true,
    },

    initialize : function() {
        _.bindAll(this); //allow access to 'this' in callbacks with "this" meaning the object not the context of the callback

    },

    getWhitelist : function() {
        return this.get("whitelist")
    },

    getBlacklist : function() {
        return this.get("blacklist")
    },

    getUsername : function() {
        return this.get("username")
    },

    getResourceURI : function() {
        return this.get("resourceURI")
    },

    isLoggedIn : function() {
        if (this.getUsername() === this.defaults.username || this.getResourceURI() === this.defaults.resourceURI) {
            this.logout();
        }
        return this.get("loggedIn")
    },

    ignoreLoginPrompt : function(){
        return this.get("ignoreLoginPrompt");
    },

    //when the user is logged in set the boolean to give logged in views.
    setLogin : function(status) {
        this.set({
            "loggedIn": status,
        });

        var map = {
            "true" : "login",
            "false" : "logout"
        };

        loginBadge(map[status]);
    },

    login : function() {
        this.setLogin(true);
        this.setLoginPrompt(false);
    },

    logout : function() {
        this.setLogin(false);
    },

    setUsername : function(username) {
        this.set({
            "username": username,
        });
        this.setResourceURI(username);
    },

    setResourceURI : function(username) {
        this.set({
            "resourceURI" : sprintf("/api/v1/user/%s/", username)
        })
    },

    setWhitelist : function(whitelist) {
        this.setFilterSet("whitelist", whitelist);
    },

    setBlacklist : function(blacklist) {
        this.setFilterSet("blacklist", blacklist);
    },

    setFilterSet : function(type, list) {
        this.set({
            type : list
        })
    },

    setLoginPrompt : function(bool){
        this.set({
            "ignoreLoginPrompt" : bool
        });
    },

    //check if a url is in the blacklist
    inBlackList : function(url) {
        return this.inSet("blacklist", url)
    },

    //check if a url is in the whitelise
    inWhitelist : function(url) {
        return this.inSet("whitelist", url)
    },

    //check if url is in a set (either whitelist or blacklist)
    // documentation for URL.js : http://medialize.github.com/URI.js/docs.html
    inSet : function(setType, url) {
        var set = this.get(setType);
        var uri = new URI(url)
        var hostname = uri.hostname();
        var protocol = uri.protocol();
        return (set.where({"url" : hostname}).length || set.where({"url" : protocol}).length || set.where(url).length)
    },

    //save the current state to local storage
    saveState : function(){
        localStorage.user = JSON.stringify(this);
    },
});

//////////////////data collection handlers/////////////
/*
    inputs:
    tabId - indentifer of tab (unique to session only)
    url - url of the tab making the request
    favIconUrl - used for displaying content
    title - title of the webpage the tab is displaying
    event_type - whether a tab is opening or closing/navigating to a new page etc
*/
function openItem(tabId, url, favIconUrl, title, event_type) {
    if (!user.isLoggedIn()){
        if (!user.ignoreLoginPrompt()){
            chrome.tabs.sendMessage(tabId, {
                "action" : "prompt",
                "type" : "loginPrompt",
                "baseUrl" : baseUrl,
            })
        }
      return
    }
    var timeCheck = checkTimeDelta();
    var uri = new URI(url);
    //if its not in the whitelist lets check that the user has it

    if (!user.inWhitelist(url) && !user.inBlackList(url)) {

        timeCheck.allow = false; // we need to wait for prompt callback
        chrome.tabs.sendMessage(tabId, {
            "action": "prompt",
            "type" : "trackPrompt",
            "baseUrl": baseUrl,
        });
        tmpItem = {
            "tabId" : tabId,
            "url" : url,
            "favIconUrl" : favIconUrl,
            "title" : title,
            "event_type" : event_type,
        }

    } else if (user.inBlackList(url)) {
        return
    }

    if (timeCheck.allow){
        finishOpen(tabId, url, favIconUrl, title, event_type, timeCheck.time);
    }
}

/*
    change the active item state of an item.
    called after a prompt is allowed or timecheck passes
*/
function finishOpen(tabId, url, favIconUrl, title, event_type, time) {
    if (activeItem !== undefined) {
        closeItem(activeItem.tabId, activeItem.url, "blur", time);
    };

    //reassign the active item to be the current tab
    activeItem = {
        "tabId" : tabId,
        "url" : url,
        "favIconUrl" : favIconUrl,
        "title" : title,
        "start_event" : event_type,
        "start_time" : new Date(),
    };
}

/*
    There is only ever one activeItem at a time so only close out the active one.
    This event will be fired when a tab is closed or unfocused but we would have already "closed" the item so we don"t want to do it again.
*/
function closeItem(tabId, url, event_type, time) {
    if (activeItem === undefined) return;
    var time = time || new Date(); // time is undefined for destroy event
    if (activeItem.tabId === tabId && !user.inBlackList(url)) {
        //write to local storage
        var item = $.extend({}, activeItem); //copy activeItem

        item.end_event = event_type;
        item.end_time = time;
        item.total_time = item.end_time - item.start_time;
        item.humanize_time = moment.humanizeDuration(item.total_time);
        local_history.push(item);

        // send data for server and sync whitelist/blacklist

        if (local_history.length) {
            dumpData();
            user.getWhitelist()._fetch();
            user.getBlacklist()._fetch();
        }
    }
}

/*
    checks if the time between the current event and the active item is greater than the delta. Default delta is 900ms
*/
function checkTimeDelta(delta) {
    var delta = delta || 900
    var now = new Date();
    var allow = true; // default to true allows active item to be set initially
    if (activeItem !== undefined) {
        allow = (now.getTime() - activeItem.start_time) > delta
    }

    return {
        "allow" : allow,
        "time" : now,
    }
}

///////////////message handlers///////////////
/*
    create a whitelist or blacklist item when the message comes in from the prompt
*/
function handleFilterListMsg(msg) {
    var type = msg.type;
    var url = msg.url;
    var list;
    if (type == "whitelist") {
        list = user.getWhitelist();
        if (tmpItem !== null) {
            finishOpen(tmpItem.tabId, tmpItem.url, tmpItem.favIconUrl, tmpItem.title, tmpItem.event_type)
            tmpItem = null
        }
    } else if (type == "blacklist") {
        list = user.getBlacklist();
    } else {
        return
    }
    m = list.create({
        "url" : url,
        "user" : user.getResourceURI(),
    });

    localStorage.user = JSON.stringify(user);
}

/*
    close an item if the tab is idle
*/
function handleIdleMsg(msg, tabId) {
    var type = msg.type;
    if (type == "openItem")  {
        openTab(tabId, "focus");
    } else if (type == "closeItem" && activeItem !== undefined) {
        closeTab(tabId, "idle", function() {
                activeItem = undefined;
            });
    }
}

/*
    Open the popup so the user can logback in again
*/
function handleLoginMsg(){
   openLink(chrome.extension.getURL('html/popup.html'));
}

/*
    Store the ignore state so the popup message does not display
*/
function handleIgnoreMsg(){
    user.setLoginPrompt(true);
}

///////////////////server comm utils///////////////////

/*
    Posts data to server
*/
function dumpData() {
    var backlog = []
    var url = getApiURL("history-data");
    var stop = false;
    $.each(local_history, function(index, item){
        if (stop) return; //stop sending on error
        payload = serializePayload(item);
        var that = this;
        $.ajax({
            type: "POST",
            url: url,
            data: payload,
            dataType: "text",
            processData:  false,
            contentType: "application/json",
            error: function(jqXHR, textStatus, errorThrown){
                stop = true;
                if (navigator.onLine){
                    user.logout(); //notify user of server error
                }
            },
            success: function(data, textStatus, jqXHR) {
               local_history.splice(index, 1); //remove item from history on success
            },
        });
    });
}

/*
    converts the data to JSON serialized
*/
function serializePayload(payload) {
    payload.user = user.getResourceURI();
    payload.src = "chrome";
    return JSON.stringify(payload);
}

/*
    build an API url for the given inputs
*/
function getApiURL(resource, id, params) {
    params = params || {};
    var apiBase = sprintf("%s/api/v1/%s", baseUrl, resource);
    var getParams = ""
    for (var key in params) {
      getParams += sprintf("&%s=%s", key, params[key]);
    }

    if (getParams !== "") {
        apiBase += "?" + getParams.slice(1);
    }
    if (id != null) {
        apiBase += "/" + id;
    }
    return apiBase
}

/*
Helper to open urls from the extension to the main website
*/
function openLink(url) {
    chrome.tabs.create({"url": url});
}

///////////////////local storage methods//////////////
/*
    create or parase and return localhistory object
*/
function loadLocalHistory() {
    localString = localStorage.local_history;
    localString = (localString) ? localString : "[]"; // catch undefined case
    return JSON.parse(localString);
}

/*
    Get and return the user from local storage.
    If no user is found create a new one.
    If an old user exists unJSON the object and return it.
*/
function getLocalStorageUser() {
    var storedUser = localStorage.user;
    if (storedUser === undefined || storedUser === "null") {
        user = new User();
        localStorage.user = JSON.stringify(user)//store user
        return user
    }

    o = JSON.parse(storedUser);
    var u = new User();

    u.setUsername(o.username);
    u.setLogin(o.loggedIn);
    if (o.loggedIn){
        //if the user is logged in don't ignore the prompt
        u.setLoginPrompt(false);
    }
    u.setBlacklist(o.blacklist);
    u.setWhitelist(o.whitelist);

    return u
}

/*
    Clear the local storage for the given key
*/
function clearLocalStorage(key) {
    localStorage[key] = null;
}

/*
    remove all local history from storage
*/
function clearStorage(){
    localStorage.removeItem("local_history")
    local_history = []
}

//////////////////badge utils////////////////////

/*
    wraps the chrome badge update function
*/
function updateBadge(text) {
    chrome.browserAction.setBadgeText(
        {
            "text" : text
        });
}

/*
    clear login flag
*/
function loginBadge(e) {
    if (e == "logout") {
        updateBadge("!");
    } else if(e == "login") {
        updateBadge("");
    }
}

/*
    initialize the badge with login flag
*/
function initBadge() {
    chrome.browserAction.setBadgeBackgroundColor({"color":"#cd5c5c"});
    if (!user.isLoggedIn()) {
        loginBadge("logout");
    }
}

// dictionary mapping all open items. Keyed on tabIds and containing all information to be written to the log.
var activeItem;
var tmpItem;

local_history = loadLocalHistory();

user = getLocalStorageUser();
initBadge()

localStorage.setItem("baseUrl", baseUrl);<|endoftext|>


<commit_before>define("run", function(require){
	var $ = require("jquery");
	var _ = require("underscore");
	var Backbone = require("backbone");
	var Router = require("router");
	var App = require("app");

	var router = new Router();

	Backbone.history.start();
});

require(["config"], function(){
	require(["run"]);
});
<commit_msg>Require bootstrap JS.<commit_after>define("run", function(require){
	var $ = require("jquery");
	var _ = require("underscore");
	var bootstrap = require("libs/bootstrap/dist/js/bootstrap.min");
	var Backbone = require("backbone");
	var Router = require("router");
	var App = require("app");

	var router = new Router();

	Backbone.history.start();
});

require(["config"], function(){
	require(["run"]);
});
<|endoftext|>


<commit_before>
<commit_msg>Initial calls to datasource and displaying result<commit_after>$(document).ready(function(){
	var dataSource = "http://data.seattle.gov/api/views/kzjm-xkqj/rows.json?jsonp=?&max_rows=100";

	$.ajax({
		type : "GET",
		dataType : "JSONP",
		url : dataSource,
		success: function(result) {
			console.log(result.data);

			var incidents = [];
			$.each( result.data, function( i, incident ) {
				console.log(incident);

				// Incident ID 	[14]
				// Address		[8]
				// Type 		[9]
				// Datetime 	[10]
				// Lat 			[11]
				// Long 		[12]

				var indicentID = incident[14];
				var address = incident[8];
				var type = incident[9];
				var date = new Date(incident[10] * 1000);
				var lat = incident[11];
				var long = incident[12];

				incidents.push('
' + indicentID + '	' + type + '	' + address + '	' + date.toLocaleTimeString() + ' ' + date.toLocaleDateString() + '	' + lat + '	' + long + '
');

				// var row = [];

				// for(var column = 0; column < incident.length; column++){
				// 	//row.push('' + column + ', ' + incident[column] + "	")
				// }

				// incidents.push('
' + row + '
');
			});

			//$("#log").append('
' + incidents.length + ' records returned.
')
			$("#log").append(incidents.join(''));
		},
		error: function(xhr, status, error) {
		  	console.log(JSON.parse(xhr.responseText));
		}
	});
});<|endoftext|>


<commit_before>$(function() {
    var sequencer = new Sequencer();

    // Enqueue a simple synchronous action
    sequencer.do(function () { console.log("1st"); });

    // Waits for one second then performs an action after the delay has elapsed.
    // This also demonstrates "do" task chaining.
    sequencer.doWait(1000).do(function () { console.log("2nd after 1 second"); });

    // Performs an action and waits until the given handle is released
    sequencer.doWithHandle(function (handle) { setTimeout(handle.release, 3000); });

    // Another simple synchronous action
    sequencer.do(function () { console.log("3rd after waiting for handle for 3 seconds"); });

    // A jquery.transit transition (optional jquery.transit-extension)
    sequencer.doTransition($(".animated"), { scale: 2, duration: 2000 });

    // Continues only after the transition is complete
    sequencer.do(function () { console.log("4th after jquery.transit transition is complete"); });
});
<commit_msg>Added a doWaitForHandle test.<commit_after>$(function() {
    var sequencer = new Sequencer();

    // Enqueue a simple synchronous action
    sequencer.do(function () { console.log("1st"); });

    // Waits for one second then performs an action after the delay has elapsed.
    // This also demonstrates "do" task chaining.
    sequencer.doWait(1000).do(function () { console.log("2nd after 1 second"); });

    // Performs an action and waits until the given handle is released
    sequencer.doWithHandle(function (handle) { setTimeout(handle.release, 3000); });

    // Another simple synchronous action
    sequencer.do(function () { console.log("3rd after waiting for handle for 3 seconds"); });

    // A jquery.transit transition (optional jquery.transit-extension)
    sequencer.doTransition($(".animated"), { scale: 2, duration: 2000 });

    // Continues only after the transition is complete
    sequencer.do(function () { console.log("4th after jquery.transit transition is complete"); });

    // Create a handle and wait until some asynchronous code releases it
    var blockUntilLaterHandle = new Handle();
    sequencer.doWaitForHandle(blockUntilLaterHandle);

    // This will run after the external handle is released
    sequencer.do(function () { console.log("5th after waiting for an external handle to be released"); });

    // Release the handle sometime later so that the sequence can continue.
    // Note that a long delay is used here because enqueueing tasks in the sequencer
    // is an instantaneous operation; this line runs almost instantly at page load!
    setTimeout(blockUntilLaterHandle.release, 15000);
});
<|endoftext|>


<commit_before>$(document).ready(function() {

    $("#logical-machines-price-accesory-guide").validate({
        rules : {
            dimensionInches : {
                required : true,
                number : true,
            }
        },
        messages : {
            dimensionInches : {
                required : "This is a required field.",
                number : "Please enter a number.",
            }
        }
    });

    // Declare global variables
    var $machineModelDesc = $('.machine-model-description'), $machineImage = $('#machine-image'), $nextMachineImage = $('#machine-image').next('#machine-title'), $btnAdd = $('#btnAdd'), $btnDel = $('#btnDel'), $grandTotalContainer = $('#cost-container .amount'), grandTotal = parseInt($grandTotalContainer.text(), 10),
    // S-4 Machine attributes
    $s4Machine = $('label[for="s4"]'), s4MachineName = $s4Machine.find('.machineName').text(), s4MachineType = $s4Machine.find('.machineType').text(), s4MachinePrice = $s4Machine.find('.amount').text()
    // S-5Machine attributes
    $s5Machine = $('label[for="s5"]'), s5MachineName = $s5Machine.find('.machineName').text(), s5MachineType = $s5Machine.find('.machineType').text(), s5MachinePrice = $s5Machine.find('.amount').text()
    // S-6 Machine attributes
    $s6Machine = $('label[for="s6"]'), s6MachineName = $s6Machine.find('.machineName').text(), s6MachineType = $s6Machine.find('.machineType').text(), s6MachinePrice = $s6Machine.find('.amount').text()
    // S-7 Machine attributes
    $s7Machine = $('label[for="s7"]'), s7MachineName = $s7Machine.find('.machineName').text(), s7MachineType = $s7Machine.find('.machineType').text(), s7MachinePrice = $s7Machine.find('.amount').text();

    //  $('.field-name-machine-model input').each(function(index) {
    //      var machineID = $(this).attr('id');
    //  });

    // Create instances of the machine object and assign
    // properties
    //  machineS4 = {
    //      machineName : $('input '),
    //      machineType : "Weigh/Fill System",
    //      machinePrice : 6150
    //  };

    // Hide fallback content, add and delete button
    $('.large-discharge-funnel,.field-name-dimensions li,#step-2,#step-3,#step-4,#step-5,#hidden-accessories-page,.spout-shape-images > *,#btnAdd,#btnDel,.btnCalculate').hide();
    // Remove fallback form elements
    $('.default-spout,.default-discharge-funnel,#btnQuote').remove();
    // .bottom class puts a negative z-index on the hidden
    // accessories page so that it loads underneath the rest of
    // the content. This removes that class on load.
    $('.bottom').removeClass('bottom');
    // Hide all but the first machine model description
    $machineModelDesc.not('.machine-model-description:first').hide();
    // Remove .hidden class from JS ready content
    $('.small-discharge-funnel,.large-discharge-funnel,#btnAdd,#btnDel,#btnFront,#btnSide,.cloneSpout,.step-submit,#sidebar,#btnPrint,#btnEmail,#btnClose,#btnContinue,.order-summary,#hidden-accessories-page,#machine-title,#order-summary').removeClass('hidden');
    // Check the default discharge funnel field
    $('#small-standard-discharge-funnel').prop('checked', true).addClass('active');

    // Add a waypoint to the sidebar
    var $mi_container = $('#sidebar');
    // Remove the no-sidebar class for fallback
    $('#main-content').removeClass('no-sidebar');
    // Set the .sticky class when waypoint is reached
    $mi_container.waypoint(function(direction) {
        $('#machine-image-container').toggleClass('sticky', direction === 'down');
    });

    function radioSelect() {
        var $radioInputFields = $('input[name=machine-model],input[name=weight-hopper],input[name=discharge-funnel]');

        $radioInputFields.click(function(e) {
            var $fieldID = $(this), inputVal = $fieldID.closest('ul.field-type-radio').find('.active').attr('id'), objectVal = $fieldID.attr('id');

            if (inputVal == objectVal) {
                e.preventDefault();
                //add this to prevent default click behaviour
            } else {

                var fieldVal = $fieldID.val(), radioName = $fieldID.attr("name");

                switch (fieldVal) {
                    case 'S-4':
                        $machineModelDesc.hide();
                        $s4Machine.find('.machine-model-description').show();
                        $machineImage.removeClass('s4 s5 s6 s7').addClass('s4');
                        $nextMachineImage.html(s4MachineName + " " + s4MachineType);
                        break;
                    case 'S-5':
                        $machineModelDesc.hide();
                        $s5Machine.find('.machine-model-description').show();
                        $machineImage.removeClass('s4 s5 s6 s7').addClass('s5');
                        $nextMachineImage.html(s5MachineName + " " + s5MachineType);
                        break;
                    case 'S-6':
                        $machineModelDesc.hide();
                        $s6Machine.find('.machine-model-description').show();
                        $machineImage.removeClass('s4 s5 s6 s7').addClass('s6');
                        $nextMachineImage.html(s6MachineName + " " + s6MachineType);
                        break;
                    case 'S-7':
                        $machineModelDesc.hide();
                        $s7Machine.find('.machine-model-description').show();
                        $machineImage.removeClass('s4 s5 s6 s7').addClass('s7');
                        $nextMachineImage.html(s7MachineName + " " + s7MachineType);
                        break;
                    case 'small-weight-hopper':
                        $('.small-discharge-funnel').show().find('#small-standard-discharge-funnel').prop('checked', true);
                        $('.large-discharge-funnel').hide().find('input').prop('checked', false);
                        $machineImage.removeClass('smwh lrgwh std-fnl steep-fnl').addClass('smwh std-fnl');
                        break;
                    case 'large-weight-hopper':
                        $('.large-discharge-funnel').show().find('#large-standard-discharge-funnel').prop('checked', false);
                        $('.small-discharge-funnel').hide().find('input').prop('checked', false);
                        $machineImage.removeClass('smwh lrgwh std-fnl steep-fnl').addClass('lrgwh std-fnl');
                        break;
                    case 'small-steep-funnel':
                    case 'large-steep-funnel':
                    case 'small-standard-discharge-funnel':
                    case 'large-standard-discharge-funnel':
                        $machineImage.toggleClass('std-fnl steep-fnl');
                        break;

                }
                calculateTotal($fieldID);
            }
        });
    }

    radioSelect();

    function spoutSelect() {
        $('input.spout-type').click(function() {
            var $fieldID = $(this), fieldVal = $fieldID.val(), $spoutContainer = $fieldID.closest('fieldset');

            $spoutContainer.find('.btnCalculate').show();
            // Toggle active class
            $spoutContainer.find('input.active').removeClass('active');
            $fieldID.addClass('active');
            // Show the spout image
            $machineImage.find('.spout').removeClass('hidden');
            // Hide all the dimensions fields and images
            $spoutContainer.find('.field-name-dimensions li').hide();
            $spoutContainer.find('.spout-shape-images > *').hide();

            switch (fieldVal) {
                case 'flag-bag':
                    $spoutContainer.find('.spout-width-inches').show();
                    $spoutContainer.find('.spout-shape-images > .flat-bag-spout-shape').show();
                    $spoutContainer.find('.description p').html("Enter the width of the bag opening (W).");
                    break;
                case '4-sided-bag':
                    $spoutContainer.find('.spout-width-inches,.spout-height-inches').show();
                    $spoutContainer.find('.spout-shape-images > .four-sided-bag-spout-shape').show();
                    $spoutContainer.find('.description p').html("Looking down at the top of your bag, enter the dimensions (D1) and (D2) of the bag opening.");
                    break;
                case 'can-jar':
                    $spoutContainer.find('.spout-diameter-inches').show();
                    $spoutContainer.find('.spout-shape-images > .can-or-jar-spout-shape').show();
                    $spoutContainer.find('.description p').html("Enter the inside diameter of the bottle or can opening (D).");
                    break;
            }

        });
    }

    spoutSelect();

    function calculateTotal($fieldID) {
        var price = parseInt($fieldID.next('label').find(".amount").text(), 10), siblingAmounts = 0, radioName = $fieldID.attr("name");

        $("input[name='" + radioName + "'].active").not($fieldID).each(function() {
            siblingAmounts += parseInt($(this).next("label").find(".amount").text(), 10);
        });
        $fieldID.toggleClass("active");
        $("input[name='" + radioName + "']").not($fieldID).removeClass("active");
        if ($fieldID.hasClass("active")) {
            grandTotal -= siblingAmounts;
            grandTotal += price;
        } else {
            grandTotal -= price;
        }
        $grandTotalContainer.html(grandTotal);
    }

    $('#btnFront,#btnSide').click(function() {
        btnDirection = $(this).val();
        if (btnDirection === 'Front') {
            $machineImage.addClass('front').removeClass('side');
        } else {
            $machineImage.addClass('side').removeClass('front');
        }
    });

    $('.step-submit').click(function() {
        var $stepContainer = $(this).closest('.step-container'), nextStepContainerID = $stepContainer.next().attr('id'), prevStepContainerID = $stepContainer.prev().attr('id');
        $('#pag-navigation a').removeClass('active');

        if ($(this).is('.next')) {
            $stepContainer.hide().next().show();
            $('#pag-navigation a[href*=' + nextStepContainerID + ']').addClass('active');
        } else {
            $stepContainer.hide().prev().show();
            $('#pag-navigation a[href*=' + prevStepContainerID + ']').addClass('active');
        }
    });

    $('#pag-navigation a').click(function() {
        var stepValue = $(this).attr('href');
        $('#pag-navigation a').removeClass('active');
        $(this).addClass('active');
        $('.step-container').hide();
        $(stepValue).show();
    });

    $('#hidden-accessories-page-btn').click(function() {
        $('#hidden-accessories-page').show();
    });
    $('#btnClose,#btnContinue').click(function() {
        $(this).closest('.step-container').hide();
    });

    function calculateSpoutSize() {
        $('.btnCalculate').click(function() {

            var num = $('.cloneSpout').length, $spoutContainer = $(this).closest('fieldset');
            var dimensionFields = $spoutContainer.find('.field-type-textfield input').filter(":visible");

            if (dimensionFields.valid()) {
                if (num < 3) {
                    $btnAdd.show();
                }
                $spoutContainer.find('.field-type-radio').hide();
                $spoutContainer.find('.description').hide();
            }
        });
    }

    calculateSpoutSize();

    $btnAdd.click(function() {
        var num = $('.cloneSpout').length, newNum = new Number(num + 1),
        // the numeric ID of the new input field
        // being
        // added
        newSpoutID = 'spout' + newNum, newSpoutTypeID = 'spout' + newNum + "type", newSpoutDimensionsID = 'spout' + newNum + "dimensions",
        // create the new element via clone(),
        // and
        // manipulate it's ID using newNum value
        newElem = $('#spout' + num).clone().attr('id', newSpoutID),
        // manipulate the name/id values of the
        // elements
        // inside the new element
        radioFieldID = 1;
        newElem.children('legend').html('Spout ' + newNum).next().attr('id', newSpoutTypeID).find('input').attr({
            "id" : function(arr) {
                return newSpoutTypeID + arr
            },
            'name' : newSpoutTypeID
        }).prop('checked', false).removeClass('active').next().attr('for', function(arr) {
            return newSpoutTypeID + arr
        });
        newElem.find('.description p').html("Please enter the spout type spout that you require by clicking on the image above.");
        newElem.find('.spout-shape-images > *').hide()
        newElem.children('.field-name-dimensions').attr('id', newSpoutDimensionsID).find('li').hide().find('.spout-width-inches input').attr('id', newSpoutID + "-width-inches").closest('.field-name-dimensions').find('.spout-height-inches input').attr('id', newSpoutID + "-height-inches").closest('.field-name-dimensions').find('.spout-diameter-inches input').attr('id', newSpoutID + "-diameter-inches");
        // insert the new element after the last
        // "duplicatable" input field
        $('#spout' + num).after(newElem);

        // enable the "remove" button
        $btnDel.show().prop('disabled', false);

        // business rule: you can only add 5
        // names
        $btnAdd.hide();

        spoutSelect();
        calculateSpoutSize();

    });

    $btnDel.click(function() {
        // Check the number of spouts
        var num = $('.cloneSpout').length;

        if ($('#spout' + num + ' input').hasClass('active')) {
            price = parseInt($('#spout' + num + ' input.active + label .amount').text(), 10);
            grandTotal -= price;
            $grandTotalContainer.html(grandTotal);
        }

        // Remove the last spout
        $('#spout' + num).remove();

        // Show the "add" button
        if (num == 3) {
            $btnAdd.show();
        }
        // Disable the "remove" button
        if (num - 1 == 1) {
            $btnDel.hide().attr('disabled', 'disabled');
        }
    });

});
<commit_msg>Switch dynamic instruction to use show hide on a p instead of variables. Added calculation of the the Flat bag spout. Setto disable dimension fields, remove radio fields and enter dynamic test showing results of the calculation on pressing calculate button. Add functionality to delete the values of the first spout whilst retaining the field.<commit_after>$(document).ready(function() {

    $("#logical-machines-price-accesory-guide").validate({
        rules : {
            dimensionInches : {
                required : true,
                number : true,
            }
        },
        messages : {
            dimensionInches : {
                required : "This is a required field.",
                number : "Please enter a number.",
            }
        }
    });

    // Declare global variables
    var $machineModelDesc = $('.machine-model-description'), $machineImage = $('#machine-image'), $nextMachineImage = $('#machine-image').next('#machine-title'), $btnAdd = $('#btnAdd'), $btnDel = $('#btnDel'), $grandTotalContainer = $('#cost-container .amount'), grandTotal = parseInt($grandTotalContainer.text(), 10),
    // S-4 Machine attributes
    $s4Machine = $('label[for="s4"]'), s4MachineName = $s4Machine.find('.machineName').text(), s4MachineType = $s4Machine.find('.machineType').text(), s4MachinePrice = $s4Machine.find('.amount').text()
    // S-5Machine attributes
    $s5Machine = $('label[for="s5"]'), s5MachineName = $s5Machine.find('.machineName').text(), s5MachineType = $s5Machine.find('.machineType').text(), s5MachinePrice = $s5Machine.find('.amount').text()
    // S-6 Machine attributes
    $s6Machine = $('label[for="s6"]'), s6MachineName = $s6Machine.find('.machineName').text(), s6MachineType = $s6Machine.find('.machineType').text(), s6MachinePrice = $s6Machine.find('.amount').text()
    // S-7 Machine attributes
    $s7Machine = $('label[for="s7"]'), s7MachineName = $s7Machine.find('.machineName').text(), s7MachineType = $s7Machine.find('.machineType').text(), s7MachinePrice = $s7Machine.find('.amount').text();

    //  $('.field-name-machine-model input').each(function(index) {
    //      var machineID = $(this).attr('id');
    //  });

    // Create instances of the machine object and assign
    // properties
    //  machineS4 = {
    //      machineName : $('input '),
    //      machineType : "Weigh/Fill System",
    //      machinePrice : 6150
    //  };

    // Hide fallback content, add and delete button
    $('.large-discharge-funnel,.field-name-dimensions li,#step-2,#step-3,#step-4,#step-5,#hidden-accessories-page,.spout-shape-images > *,#btnAdd,#btnDel,.btnCalculate,.spoutCalculation,.flatBagDesc,.fourSidedBagDesc,.canJarDesc').hide();
    // Remove fallback form elements
    $('.default-spout,.default-discharge-funnel,#btnQuote').remove();
    // .bottom class puts a negative z-index on the hidden
    // accessories page so that it loads underneath the rest of
    // the content. This removes that class on load.
    $('.bottom').removeClass('bottom');
    // Hide all but the first machine model description
    $machineModelDesc.not('.machine-model-description:first').hide();
    // Remove .hidden class from JS ready content
    $('.small-discharge-funnel,.large-discharge-funnel,#btnAdd,#btnDel,#btnFront,#btnSide,.cloneSpout,.step-submit,#sidebar,#btnPrint,#btnEmail,#btnClose,#btnContinue,.order-summary,#hidden-accessories-page,#machine-title,#order-summary').removeClass('hidden');
    // Check the default discharge funnel field
    $('#small-standard-discharge-funnel').prop('checked', true).addClass('active');

    // Add a waypoint to the sidebar
    var $mi_container = $('#sidebar');
    // Remove the no-sidebar class for fallback
    $('#main-content').removeClass('no-sidebar');
    // Set the .sticky class when waypoint is reached
    $mi_container.waypoint(function(direction) {
        $('#machine-image-container').toggleClass('sticky', direction === 'down');
    });

    function radioSelect() {
        var $radioInputFields = $('input[name=machine-model],input[name=weight-hopper],input[name=discharge-funnel]');

        $radioInputFields.click(function(e) {
            var $fieldID = $(this), inputVal = $fieldID.closest('ul.field-type-radio').find('.active').attr('id'), objectVal = $fieldID.attr('id');

            if (inputVal == objectVal) {
                e.preventDefault();
                //add this to prevent default click behaviour
            } else {

                var fieldVal = $fieldID.val(), radioName = $fieldID.attr("name");

                switch (fieldVal) {
                    case 'S-4':
                        $machineModelDesc.hide();
                        $s4Machine.find('.machine-model-description').show();
                        $machineImage.removeClass('s4 s5 s6 s7').addClass('s4');
                        $nextMachineImage.html(s4MachineName + " " + s4MachineType);
                        break;
                    case 'S-5':
                        $machineModelDesc.hide();
                        $s5Machine.find('.machine-model-description').show();
                        $machineImage.removeClass('s4 s5 s6 s7').addClass('s5');
                        $nextMachineImage.html(s5MachineName + " " + s5MachineType);
                        break;
                    case 'S-6':
                        $machineModelDesc.hide();
                        $s6Machine.find('.machine-model-description').show();
                        $machineImage.removeClass('s4 s5 s6 s7').addClass('s6');
                        $nextMachineImage.html(s6MachineName + " " + s6MachineType);
                        break;
                    case 'S-7':
                        $machineModelDesc.hide();
                        $s7Machine.find('.machine-model-description').show();
                        $machineImage.removeClass('s4 s5 s6 s7').addClass('s7');
                        $nextMachineImage.html(s7MachineName + " " + s7MachineType);
                        break;
                    case 'small-weight-hopper':
                        $('.small-discharge-funnel').show().find('#small-standard-discharge-funnel').prop('checked', true);
                        $('.large-discharge-funnel').hide().find('input').prop('checked', false);
                        $machineImage.removeClass('smwh lrgwh std-fnl steep-fnl').addClass('smwh std-fnl');
                        break;
                    case 'large-weight-hopper':
                        $('.large-discharge-funnel').show().find('#large-standard-discharge-funnel').prop('checked', false);
                        $('.small-discharge-funnel').hide().find('input').prop('checked', false);
                        $machineImage.removeClass('smwh lrgwh std-fnl steep-fnl').addClass('lrgwh std-fnl');
                        break;
                    case 'small-steep-funnel':
                    case 'large-steep-funnel':
                    case 'small-standard-discharge-funnel':
                    case 'large-standard-discharge-funnel':
                        $machineImage.toggleClass('std-fnl steep-fnl');
                        break;

                }
                calculateTotal($fieldID);
            }
        });
    }

    radioSelect();

    function spoutSelect() {
        $('input.spout-type').click(function() {
            var $fieldID = $(this), fieldVal = $fieldID.val(), $spoutContainer = $fieldID.closest('fieldset');

            $spoutContainer.find('.btnCalculate').show();
            // Toggle active class
            $spoutContainer.find('input.active').removeClass('active');
            $fieldID.addClass('active');
            // Show the spout image
            $machineImage.find('.spout').removeClass('hidden');
            // Hide all the dimensions fields and images
            $spoutContainer.find('.field-name-dimensions li').hide();
            $spoutContainer.find('.spout-shape-images > *').hide();
            $spoutContainer.find('p').hide();

            switch (fieldVal) {
                case 'flag-bag':
                    $spoutContainer.find('.spout-width-inches').show();
                    $spoutContainer.find('.spout-shape-images > .flat-bag-spout-shape').show();
                    $spoutContainer.find('.description .flatBagDesc').show();
                    break;
                case '4-sided-bag':
                    $spoutContainer.find('.spout-width-inches,.spout-height-inches').show();
                    $spoutContainer.find('.spout-shape-images > .four-sided-bag-spout-shape').show();
                    $spoutContainer.find('.description .fourSidedBagDesc').show();
                    break;
                case 'can-jar':
                    $spoutContainer.find('.spout-diameter-inches').show();
                    $spoutContainer.find('.spout-shape-images > .can-or-jar-spout-shape').show();
                    $spoutContainer.find('.description .canJarDesc').show();
                    break;
            }

        });
    }

    spoutSelect();

    function calculateTotal($fieldID) {
        var price = parseInt($fieldID.next('label').find(".amount").text(), 10), siblingAmounts = 0, radioName = $fieldID.attr("name");

        $("input[name='" + radioName + "'].active").not($fieldID).each(function() {
            siblingAmounts += parseInt($(this).next("label").find(".amount").text(), 10);
        });
        $fieldID.toggleClass("active");
        $("input[name='" + radioName + "']").not($fieldID).removeClass("active");
        if ($fieldID.hasClass("active")) {
            grandTotal -= siblingAmounts;
            grandTotal += price;
        } else {
            grandTotal -= price;
        }
        $grandTotalContainer.html(grandTotal);
    }

    $('#btnFront,#btnSide').click(function() {
        btnDirection = $(this).val();
        if (btnDirection === 'Front') {
            $machineImage.addClass('front').removeClass('side');
        } else {
            $machineImage.addClass('side').removeClass('front');
        }
    });

    $('.step-submit').click(function() {
        var $stepContainer = $(this).closest('.step-container'), nextStepContainerID = $stepContainer.next().attr('id'), prevStepContainerID = $stepContainer.prev().attr('id');
        $('#pag-navigation a').removeClass('active');

        if ($(this).is('.next')) {
            $stepContainer.hide().next().show();
            $('#pag-navigation a[href*=' + nextStepContainerID + ']').addClass('active');
        } else {
            $stepContainer.hide().prev().show();
            $('#pag-navigation a[href*=' + prevStepContainerID + ']').addClass('active');
        }
    });

    $('#pag-navigation a').click(function() {
        var stepValue = $(this).attr('href');
        $('#pag-navigation a').removeClass('active');
        $(this).addClass('active');
        $('.step-container').hide();
        $(stepValue).show();
    });

    $('#hidden-accessories-page-btn').click(function() {
        $('#hidden-accessories-page').show();
    });
    $('#btnClose,#btnContinue').click(function() {
        $(this).closest('.step-container').hide();
    });

    function calculateSpoutSize() {
        $('.btnCalculate').click(function() {

            var num = $('.cloneSpout').length, $spoutContainer = $(this).closest('fieldset'),
            // The selected spout type
            $spoutSelected = $spoutContainer.find('.field-name-spout-type input:checked'), spoutSelectedVal = $spoutSelected.val(), spoutSelectedTitle = $spoutSelected.next('label').find('h4').text();
            // Spout dimension values
            dimensionFieldWidth = $spoutContainer.find('#spout1WidthInches').val(), dimensionFieldHeight = $spoutContainer.find('#spout1HeightInches').val(), dimensionFieldDiameter = $spoutContainer.find('#spout1DiameterInches').val(),
            // Visisble dimension fields
            $dimensionFieldsVisible = $spoutContainer.find('.field-type-textfield input').filter(":visible");

            if ($dimensionFieldsVisible.valid()) {

                var spoutSize = 0;
                switch (spoutSelectedVal) {
                    case 'flag-bag':
                        if (dimensionFieldWidth < 2) {
                            spoutSize = 0.75;
                        } else if (dimensionFieldWidth >= 2 && 2.4 >= dimensionFieldWidth) {
                            spoutSize = 1;
                        } else if (dimensionFieldWidth >= 2.5 && 2.9 >= dimensionFieldWidth) {
                            spoutSize = 1.25;
                        } else if (dimensionFieldWidth >= 3 && 3.5 >= dimensionFieldWidth) {
                            spoutSize = 1.5;
                        } else if (dimensionFieldWidth >= 3.6 && 3.9 >= dimensionFieldWidth) {
                            spoutSize = 1.75;
                        } else if (dimensionFieldWidth >= 4 && 4.9 >= dimensionFieldWidth) {
                            spoutSize = 2;
                        } else if (dimensionFieldWidth >= 5 && 5.9 >= dimensionFieldWidth) {
                            spoutSize = 2.5;
                        } else if (dimensionFieldWidth >= 6 && 6.5 >= dimensionFieldWidth) {
                            spoutSize = 3;
                        } else {
                            spoutSize = 3.5;
                        }
                        break;
                    case '4-sided-bag':
                        alert(dimensionFieldWidth + " " + dimensionFieldHeight);
                        break;
                    case 'can-jar':
                        alert(dimensionFieldDiameter);
                        break;
                }
                $spoutContainer.find('.spoutCalculation').show().find('.spout-name').text(spoutSelectedTitle).next('.spout-size').text(spoutSize);
                if (num < 3) {
                    $btnAdd.show();
                }
                $(this).hide();
                $spoutContainer.find('.field-name-spout-type,.description').hide();
                $dimensionFieldsVisible.prop("disabled", true);
                $btnDel.show().prop('disabled', false);
            }
        });
    }

    calculateSpoutSize();

    $btnAdd.click(function() {
        var num = $('.cloneSpout').length, newNum = new Number(num + 1),
        // the numeric ID of the new input field
        // being
        // added
        newSpoutID = 'spout' + newNum, newSpoutTypeID = 'spout' + newNum + "type", newSpoutDimensionsID = 'spout' + newNum + "dimensions",
        // create the new element via clone(),
        // and
        // manipulate it's ID using newNum value
        newElem = $('#spout' + num).clone().attr('id', newSpoutID),
        // manipulate the name/id values of the
        // elements
        // inside the new element
        radioFieldID = 1;
        newElem.children('legend').html('Spout ' + newNum).next().attr('id', newSpoutTypeID).find('input').attr({
            "id" : function(arr) {
                return newSpoutTypeID + arr
            },
            'name' : newSpoutTypeID
        }).prop('checked', false).removeClass('active').next().attr('for', function(arr) {
            return newSpoutTypeID + arr
        });
        newElem.find('.description p.spout-selection').show();
        newElem.find('.spout-shape-images > *').hide()
        newElem.children('.field-name-dimensions').attr('id', newSpoutDimensionsID).find('li').hide().find('.spout-width-inches input').attr('id', newSpoutID + "-width-inches").closest('.field-name-dimensions').find('.spout-height-inches input').attr('id', newSpoutID + "-height-inches").closest('.field-name-dimensions').find('.spout-diameter-inches input').attr('id', newSpoutID + "-diameter-inches");
        // insert the new element after the last
        // "duplicatable" input field
        $('#spout' + num).after(newElem);

        // enable the "remove" button
        $btnDel.show().prop('disabled', false);

        // business rule: you can only add 5
        // names
        $btnAdd.hide();

        spoutSelect();
        calculateSpoutSize();

    });

    $btnDel.click(function() {
        // Check the number of spouts
        var num = $('.cloneSpout').length, $spoutField = $("#spout" + num);

        //if ($('#spout' + num + ' input').hasClass('active')) {
        //    price = parseInt($('#spout' + num + ' input.active + label .amount').text(), 10);
        //    grandTotal -= price;
        //    $grandTotalContainer.html(grandTotal);
        //}

        // Disable the "remove" button
        if (num == 1) {
            //$btnDel.hide().attr('disabled', 'disabled');
            $spoutField.find('.field-name-spout-type').show().find('input').prop('checked', false);
            $spoutField.find('.description').show().find('p').hide().filter('.spout-selection').show();
            $spoutField.find('.field-name-dimensions li').hide().find('input').prop('disabled', false).val("");
            $spoutField.find('.spout-shape-images > *').hide();
            $spoutField.find('.spoutCalculation').hide()
            $btnAdd.hide();
            $btnDel.hide();
        } else {
            // Remove the last spout
            $('#spout' + num).remove();
        }
        // Show the "add" button
        if (num == 3) {
            $btnAdd.show();
        }
    });

});
<|endoftext|>


<commit_before>/* global document, setInterval */

define(['react', 'filterGraph'], function (React, filterGraph) {
    "use strict";

    var r = React.DOM;

    React.renderComponent(
        filterGraph(),
        document.getElementById('example'));
});
<commit_msg>jshint compliance<commit_after>/* global define, document */

define(["react", "filterGraph"], function (React, filterGraph) {
    "use strict";

    // var r = React.DOM;

    React.renderComponent(
        filterGraph(),
        document.getElementById("example"));
});
<|endoftext|>


<commit_before>var game = new Phaser.Game(400,450, Phaser.AUTO, 'gameDiv')
var timer = 60
var cursors
var right = true
var counter=0
var swipeLeft=false,swipeRight=false, isGameRunning=true
var timerText=null
var swipeCoordX, swipeCoordY, swipeCoordX2, swipeCoordY2, swipeMinDistance = 100
var isJumped = false

var mainState = {
    preload: function() {
         this.game.load.image('tree', 'assets/tree.png')
         this.game.stage.backgroundColor = "#ffffff"
         this.game.load.spritesheet('monkey','assets/jumpy.png',82,108)
         this.game.load.image('sky','assets/sky.png')
         this.game.load.image('platform','assets/platform.png')
         this.game.load.image('sky','assets/sky.png')
         this.game.load.spritesheet('chain', 'assets/chain.png', 16, 26)
         this.game.load.spritesheet('chain', 'assets/btn.png', 193, 71)
    },

    create: function() {

         //make the GAME full screen
         this.game.scale.fullScreenScaleMode = Phaser.ScaleManager.SHOW_ALL
         this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL
         this.game.scale.refresh()

         //initialization of global variables
         isGameRunning = true
         right = true
         timer = 60
         isJumped = false

        //start the system
        this.game.physics.startSystem(Phaser.Physics.P2JS)
        //this.game.physics.startSystem(Phaser.Physics.ARCADE)

        //add preloaded sprites to the game
        this.sky = this.game.add.sprite(0,0,"sky")
        this.tree = this.game.add.sprite(0,0,"tree")
        this.monkey = this.game.add.sprite(400,1000,'monkey')
        this.ground = this.game.add.sprite(0,1200,'platform')

        //apply physics on the objects
        //game.physics.p2.enable(this.tree)
        game.physics.p2.setImpactEvents(true);
        game.physics.p2.restitution = 0.8;

        game.physics.p2.enable(this.monkey)
        game.physics.p2.enable(this.ground)

        //timer ticks interval 1s per tick
        interval=setInterval(function(){timer -= 1},1000)

        //create animations
        this.monkey.animations.add('game',[3, 0, 1, 2], 5, true)

        //start animation
        this.monkey.animations.play('game')

         //scales and anchors
        this.monkey.anchor.setTo(.5, .5)
        this.monkey.scale.setTo(.8, .8)
        this.sky.scale.setTo(2, 2)
        this.ground.scale.setTo(1.8, 0.8)

        this.monkey.body.gravity.y = 300
        this.ground.body.gravity.y = 300
        this.ground.body.immovable = true

        // stop falling from the world's bound
        this.monkey.body.collideWorldBounds = true
        this.ground.body.collideWorldBounds = true

        //camera bounds and activate follow
        this.game.world.setBounds(0, 0, 900, 1200)
        game.camera.follow(this.monkey)

        //keyboard inputs
        cursors = this.game.input.keyboard.createCursorKeys()

        //swipe co-ordinates
        this.game.input.onDown.add(function(pointer) {
            swipeCoordX = pointer.clientX
            swipeCoordY = pointer.clientY
        }, this)

        this.game.input.onUp.add(function(pointer) {
            swipeCoordX2 = pointer.clientX
            swipeCoordY2 = pointer.clientY
            if(swipeCoordX2 < swipeCoordX - swipeMinDistance){
                //console.log("left")
                swipeLeft=true
            }
            else if(swipeCoordX2 > swipeCoordX + swipeMinDistance){
                //console.log("right")
                swipeRight=true
            }
        }, this);

     },
     update: function() {

        if(isGameRunning){
            //detect monkey and ground collision
             game.physics.arcade.collide(this.monkey, this.ground)

            //console.log(this.monkey.body.touching.down)
            if(timer<=0 || (isJumped && this.monkey.body.touching.down) ){
                //Game Over
                console.log("game over")
                isGameRunning = false

                this.game.add.tween(this.monkey).to({angle: right? -90:90}, 100).start()
                gameOverText = game.add.text(
                    game.world.width / 2,
                    game.world.height / 2,
                    "Game Over",
                    {
                        font: '32px Comic Sans MS',
                        fill: '#fff',
                        stroke: '#430',
                        strokeThickness: 4,
                        align: 'center'
                    }
                )
                gameOverText.fixedToCamera = true
                gameOverText.cameraOffset.setTo(100, 200)

                this.button = this.game.add.button(this.game.world.centerX, this.game.world.centerY, 'button', this.actionOnClick, this, 1, 1, 1)
                this.button.anchor.setTo(.5,-1)
                this.button.scale.setTo(.6,.6)
                this.button.onInputUp.add(this.up, this)
                this.button.fixedToCamera = true
                this.button.cameraOffset.setTo(180,240)
                clearInterval(interval)

            }

            if(timerText!=null)timerText.destroy()
                  timerText = game.add.text(
                        10,
                        10,
                        "Time: "+timer+"s",
                        {
                            font: '24px Comic Sans MS',
                            fill: '#fff',
                            stroke: '#000',
                            strokeThickness: 2,
                            align: 'center'
                        })
            timerText.fixedToCamera = true
            timerText.cameraOffset.setTo(10, 10)

            counter++

            //commented for testing purpose, it will allow the monkey to jump infinitely
            //if (cursors.up.isDown && this.monkey.body.touching.down){
            this.monkey.body.velocity.x=0
            if (swipeLeft || swipeRight || cursors.up.isDown ){
                //console.log("up")
                isJumped = true
                this.monkey.body.velocity.y = -350
                this.monkey.frame = 1
            }
            if (swipeLeft || cursors.left.isDown){
                //console.log("left")
                this.monkey.body.velocity.x = -350
                this.monkey.animations.play('game')
                if(right) {right =  false
                this.monkey.scale.x*=-1
                }
            }
            else if (swipeRight || cursors.right.isDown){
                //console.log("right")
                this.monkey.body.velocity.x = 350
                if(!right) {
                    right =  true
                    this.monkey.scale.x *= -1
                }

                this.monkey.animations.play('game')
            }
            else{
                this.monkey.animations.stop()
                this.monkey.frame = 5
            }

            if(counter>20){
                counter=0
                swipeLeft=swipeRight=false
            }
            if((300<=this.monkey.body.x && this.monkey.body.x<450) && (50<=this.monkey.body.y && this.monkey.body.y <=130)){
                //console.log("Home Win!")
                isGameRunning=false
                this.monkey.frame = 0
                gameOverText = game.add.text(
                    game.world.width / 2,
                    game.world.height / 2,
                    "Level Complete",
                    {
                        font: '32px Comic Sans MS',
                        fill: '#fff',
                        stroke: '#430',
                        strokeThickness: 4,
                        align: 'center'
                    }
                )
                gameOverText.fixedToCamera = true
                gameOverText.cameraOffset.setTo(60, 200)

                this.button = this.game.add.button(this.game.world.centerX, this.game.world.centerY, 'button', this.actionOnClick, this, 1, 1, 1)
                this.button.anchor.setTo(.5,-1)
                this.button.scale.setTo(.6,.6)
                this.button.onInputUp.add(this.up, this)
                this.button.fixedToCamera = true
                this.button.cameraOffset.setTo(180,240)
                clearInterval(interval)

            }
        }
        else{

        }

    },
    render: function() {

    //game.debug.cameraInfo(game.camera, 32, 32)
    //game.debug.spriteCoords(this.monkey, 0, 32)
   },
    up: function() {
        //start main state
        this.game.state.add('main', mainState)
        this.game.state.start('main')

    },
     actionOnClick: function(){

    },
    tick: function(){
        timer-=1
    }
}

var button
var background

var welcomeScreenState = {
    preload: function() {
    this.game.load.spritesheet('button', 'assets/button_sprite_sheet.png', 193, 71)
    this.game.load.image('background','assets/screen.png')
    },

    create: function() {
        //make the GAME full screen
        this.game.scale.fullScreenScaleMode = Phaser.ScaleManager.SHOW_ALL
        this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL
        this.game.scale.refresh()

        this.game.stage.backgroundColor = '#182d3b'
        this.background = this.game.add.tileSprite(0, 0, 900, 1200, 'background')

        this.button = this.game.add.button(this.game.world.centerX, this.game.world.centerY, 'button', this.actionOnClick, this, 2, 1, 0)
        this.button.anchor.setTo(.5,-1)
        this.button.scale.setTo(.5,.5)
        //this.button.onInputOver.add(this.over, this)
        //this.button.onInputOut.add(this.out, this)
        this.button.onInputUp.add(this.up, this)
    },

    up: function() {
        //start main state
        this.game.state.add('main', mainState)
        this.game.state.start('main')

    },
     actionOnClick: function(){
    },
}

game.state.add('welcomeScreen',welcomeScreenState)
game.state.start('welcomeScreen')
<commit_msg>Added the first creeper :v:<commit_after>var game = new Phaser.Game(400,450, Phaser.AUTO, 'gameDiv')
var timer = 60
var cursors
var right = true
var counter=0
var swipeLeft=false,swipeRight=false, isGameRunning=true
var timerText=null
var swipeCoordX, swipeCoordY, swipeCoordX2, swipeCoordY2, swipeMinDistance = 100
var isJumped = false
var flipper=true
var lastRect

var mainState = {
    preload: function() {
         this.game.load.image('tree', 'assets/tree.png')
         this.game.stage.backgroundColor = "#ffffff"
         this.game.load.spritesheet('monkey','assets/jumpy.png',82,108)
         this.game.load.image('sky','assets/sky.png')
         this.game.load.image('platform','assets/platform.png')
         this.game.load.image('sky','assets/sky.png')
         this.game.load.spritesheet('chain', 'assets/chain.png', 16, 26)
         this.game.load.spritesheet('chain', 'assets/btn.png', 193, 71)
         this.game.load.spritesheet('chain', 'assets/chain.png', 16, 26);
    },

    create: function() {

         //make the GAME full screen
         this.game.scale.fullScreenScaleMode = Phaser.ScaleManager.SHOW_ALL
         this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL
         this.game.scale.refresh()

         //initialization of global variables
         isGameRunning = true
         right = true
         timer = 60
         isJumped = false

        //start the system
        this.game.physics.startSystem(Phaser.Physics.P2JS)
        //this.game.physics.startSystem(Phaser.Physics.ARCADE)

        //add preloaded sprites to the game
        this.sky = this.game.add.sprite(0,0,"sky")
        this.tree = this.game.add.sprite(0,0,"tree")
        this.monkey = this.game.add.sprite(400,1100,'monkey')
        this.ground = this.game.add.sprite(0,1200,'platform')

        //apply physics on the objects
        //game.physics.p2.enable(this.tree)
        game.physics.p2.setImpactEvents(true)
        game.physics.p2.restitution = 0.8
        game.physics.p2.enable(this.monkey)
        game.physics.p2.enable(this.ground)
        game.physics.p2.gravity.y=12000
        this.monkey.body.fixedRotation = true

        //timer ticks interval 1s per tick
        interval=setInterval(function(){timer -= 1},1000)

        //create animations
        this.monkey.animations.add('game',[3, 0, 1, 2], 5, true)

        //start animation
        this.monkey.animations.play('game')

         //scales and anchors
        this.monkey.anchor.setTo(.5, .5)
        this.monkey.scale.setTo(.8, .8)
        this.sky.scale.setTo(2, 2)
        this.ground.scale.setTo(4, 1.8)

        this.monkey.body.gravity.y = 1300
        this.ground.body.immovable = true
        this.ground.body.static = true

        // stop falling from the world's bound
        this.monkey.body.collideWorldBounds = true
        this.ground.body.collideWorldBounds = true

        //camera bounds and activate follow
        this.game.world.setBounds(0, 0, 900, 1200)
        game.camera.follow(this.monkey)

        //keyboard inputs
        cursors = this.game.input.keyboard.createCursorKeys()

        //swipe co-ordinates
        this.game.input.onDown.add(function(pointer) {
            swipeCoordX = pointer.clientX
            swipeCoordY = pointer.clientY
        }, this)

        this.game.input.onUp.add(function(pointer) {
            swipeCoordX2 = pointer.clientX
            swipeCoordY2 = pointer.clientY
            if(swipeCoordX2 < swipeCoordX - swipeMinDistance){
                //console.log("left")
                swipeLeft=true
            }
            else if(swipeCoordX2 > swipeCoordX + swipeMinDistance){
                //console.log("right")
                swipeRight=true
            }
        }, this)

    //  Length, xAnchor, yAnchor
    createRope(5, 280, 885)

     },
     update: function() {

        if(isGameRunning){
            //detect monkey and ground collision
             game.physics.arcade.collide(this.monkey, this.ground)

            //console.log(this.monkey.body.touching.down)
            //if(timer<=0 || (isJumped && this.monkey.body.touching.down) ){
            if(timer<=0 || (isJumped && false) ){
                //Game Over
                console.log("game over")
                isGameRunning = false

                this.game.add.tween(this.monkey).to({angle: right? -90:90}, 100).start()
                gameOverText = game.add.text(
                    game.world.width / 2,
                    game.world.height / 2,
                    "Game Over",
                    {
                        font: '32px Comic Sans MS',
                        fill: '#fff',
                        stroke: '#430',
                        strokeThickness: 4,
                        align: 'center'
                    }
                )
                gameOverText.fixedToCamera = true
                gameOverText.cameraOffset.setTo(100, 200)

                this.button = this.game.add.button(this.game.world.centerX, this.game.world.centerY, 'button', this.actionOnClick, this, 1, 1, 1)
                this.button.anchor.setTo(.5,-1)
                this.button.scale.setTo(.6,.6)
                this.button.onInputUp.add(this.up, this)
                this.button.fixedToCamera = true
                this.button.cameraOffset.setTo(180,240)
                clearInterval(interval)

            }

            if(timerText!=null)timerText.destroy()
                  timerText = game.add.text(
                        10,
                        10,
                        "Time: "+timer+"s",
                        {
                            font: '24px Comic Sans MS',
                            fill: '#fff',
                            stroke: '#000',
                            strokeThickness: 2,
                            align: 'center'
                        })
            timerText.fixedToCamera = true
            timerText.cameraOffset.setTo(10, 10)

            counter++

            //commented for testing purpose, it will allow the monkey to jump infinitely
            //if (cursors.up.isDown && this.monkey.body.touching.down){
            this.monkey.body.setZeroVelocity()
            if (swipeLeft || swipeRight || cursors.up.isDown ){
                //console.log("up")
                isJumped = true
                this.monkey.body.velocity.y = -350
                this.monkey.frame = 1
            }
            if (swipeLeft || cursors.left.isDown){
                //console.log("left")
                this.monkey.body.moveLeft(350)
                this.monkey.animations.play('game')
                if(right) {right =  false
                this.monkey.scale.x*=-1
                }
            }
            else if (swipeRight || cursors.right.isDown){
                //console.log("right")
                this.monkey.body.velocity.x = 350
                if(!right) {
                    right =  true
                    this.monkey.scale.x *= -1
                }

                this.monkey.animations.play('game')
            }
            else{
                this.monkey.animations.stop()
                this.monkey.frame = 5
            }

            if(counter>20){
                counter=0
                swipeLeft=swipeRight=false
            }
            if((300<=this.monkey.body.x && this.monkey.body.x<450) && (50<=this.monkey.body.y && this.monkey.body.y <=130)){
                //console.log("Home Win!")
                isGameRunning=false
                this.monkey.frame = 0
                gameOverText = game.add.text(
                    game.world.width / 2,
                    game.world.height / 2,
                    "Level Complete",
                    {
                        font: '32px Comic Sans MS',
                        fill: '#fff',
                        stroke: '#430',
                        strokeThickness: 4,
                        align: 'center'
                    }
                )
                gameOverText.fixedToCamera = true
                gameOverText.cameraOffset.setTo(60, 200)

                this.button = this.game.add.button(this.game.world.centerX, this.game.world.centerY, 'button', this.actionOnClick, this, 1, 1, 1)
                this.button.anchor.setTo(.5,-1)
                this.button.scale.setTo(.6,.6)
                this.button.onInputUp.add(this.up, this)
                this.button.fixedToCamera = true
                this.button.cameraOffset.setTo(180,240)
                clearInterval(interval)

            }
        }
        else{

        }

    },
    render: function() {

    //game.debug.cameraInfo(game.camera, 32, 32)
    game.debug.spriteCoords(this.monkey, 0, 32)
   },
    up: function() {
        //start main state
        this.game.state.add('main', mainState)
        this.game.state.start('main')

    },
     actionOnClick: function(){

    },
    tick: function(){
        timer-=1
    }
}

var button
var background

var welcomeScreenState = {
    preload: function() {
    this.game.load.spritesheet('button', 'assets/button_sprite_sheet.png', 193, 71)
    this.game.load.image('background','assets/screen.png')
    },

    create: function() {
        //make the GAME full screen
        this.game.scale.fullScreenScaleMode = Phaser.ScaleManager.SHOW_ALL
        this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL
        this.game.scale.refresh()

        this.game.stage.backgroundColor = '#182d3b'
        this.background = this.game.add.tileSprite(0, 0, 900, 1200, 'background')

        this.button = this.game.add.button(this.game.world.centerX, this.game.world.centerY, 'button', this.actionOnClick, this, 2, 1, 0)
        this.button.anchor.setTo(.5,-1)
        this.button.scale.setTo(.5,.5)
        //this.button.onInputOver.add(this.over, this)
        //this.button.onInputOut.add(this.out, this)
        this.button.onInputUp.add(this.up, this)
    },

    up: function() {
        //start main state
        this.game.state.add('main', mainState)
        this.game.state.start('main')

    },
     actionOnClick: function(){
    },
}

game.state.add('welcomeScreen',welcomeScreenState)
game.state.start('welcomeScreen')

function createRope(length, xAnchor, yAnchor) {

    var height = 20;        //  Height for the physics body - your image height is 8px
    var width = 16;         //  This is the width for the physics body. If too small the rectangles will get scrambled together.
    var maxForce = 20000;   //  The force that holds the rectangles together.

    for (var i = 0; i <= length; i++)
    {
        var x = xAnchor;                    //  All rects are on the same x position
        var y = yAnchor + (i * height);     //  Every new rect is positioned below the last

        if (i % 2 === 0)
        {
            //  Add sprite (and switch frame every 2nd time)
            newRect = game.add.sprite(x, y, 'chain', 1);

        }
        else
        {
            newRect = game.add.sprite(x, y, 'chain', 1);
            lastRect.bringToTop();
        }

        //  Enable physicsbody
        game.physics.p2.enable(newRect, false);

        //  Set custom rectangle
        newRect.body.setRectangle(width, height);

        if (i === 0)
        {
            newRect.body.static = true;
        }
        else
        {
            //  Anchor the first one created
            newRect.body.velocity.x = 400;      //  Give it a push :) just for fun
            newRect.body.mass = length / i;     //  Reduce mass for evey rope element
        }

        //  After the first rectangle is created we can add the constraint
        if (lastRect)
        {
            game.physics.p2.createRevoluteConstraint(newRect, [0, -10], lastRect, [0, 10], maxForce);
        }

        lastRect = newRect;

    }

}

<|endoftext|>


<commit_before>const TETRIS_ROWS = 18;
const TETRIS_COLS = 10;
const TETRIS_CELL_SIZE = 20;

const tetrisTable = Array.from({ length: TETRIS_ROWS })
	.map(() => Array.from({ length: TETRIS_COLS }).map(() => false));

tetrisTable.push(Array.from({ length: TETRIS_COLS }).map(() => true));

const figures = [
	{
		color: 'red',
		cells: [
			[1, 1],
			[1, 1],
		]
	},
	{
		color: 'yellow',
		cells: [
			[1],
			[1],
			[1],
			[1],
		]
	},
	{
		color: 'lightgreen',
		cells: [
			[1, 1, 0],
			[0, 1, 1],
		]
	},
	{
		color: 'lightblue',
		cells: [
			[0, 1, 1],
			[1, 1, 0],
		]
	},
	{
		color: 'blue',
		cells: [
			[1, 1, 1],
			[1, 0, 0],
		]
	},
	{
		color: 'purple',
		cells: [
			[1, 1, 1],
			[0, 0, 1],
		]
	},
	{
		color: 'green',
		cells: [
			[1, 1, 1],
			[0, 1, 0],
		]
	},
];

function getCellX(row) {
	return TETRIS_CELL_SIZE * row;
}

function getCellY(col) {
	return TETRIS_CELL_SIZE * col;
}

let currentFigure = {
	obj: {},
	row: 0,
	col: 0
};

let gameSpeed = 100;

function getFigure() {
	const index = Math.random() * figures.length | 0;
	currentFigure.obj = figures[index];
	currentFigure.row = 0;
	currentFigure.col = 0;
}

function checkForCollision(offsetRow, offsetCol) {
	for(let i = 0; i < currentFigure.obj.cells.length; i += 1) {
		const row = offsetRow + i;
		for(let j = 0; j < currentFigure.obj.cells[i].length; j += 1) {
			const col = offsetCol + j;

			if(currentFigure.obj.cells[i][j] && tetrisTable[row][col]) {
				return true;
			}
		}
	}

	return false;
}

function update() {
	let canFall = !checkForCollision(currentFigure.row + 1, currentFigure.col);

	if(canFall) {
		currentFigure.row += 1;
	} else {
		for(let i = 0; i < currentFigure.obj.cells.length; i += 1) {
			const row = currentFigure.row + i;
			for(let j = 0; j < currentFigure.obj.cells[i].length; j += 1) {
				const col = currentFigure.col + j;

				if(currentFigure.obj.cells[i][j]) {
					tetrisTable[row][col] = currentFigure.obj.color;
				}
			}
		}

		getFigure();
	}

	setTimeout(update, gameSpeed);
}

getFigure();
update();

window.addEventListener('keydown', function(ev) {
	console.log(ev.key);

	if(ev.key === 'ArrowLeft') {
		console.log('Left');
		let canMove = currentFigure.col > 0 && !checkForCollision(currentFigure.row, currentFigure.col - 1);
		if(canMove) {
			currentFigure.col -= 1;
		}
	} else if(ev.key === 'ArrowRight') {
		console.log('Right');
		let canMove = currentFigure.col + currentFigure.obj.cells[0].length < TETRIS_COLS && !checkForCollision(currentFigure.row, currentFigure.col + 1);
		if(canMove) {
			currentFigure.col += 1;
		}
	}
});
<commit_msg>Spawn figures ontop of the table<commit_after>const TETRIS_ROWS = 18;
const TETRIS_COLS = 10;
const TETRIS_CELL_SIZE = 20;

const tetrisTable = Array.from({ length: TETRIS_ROWS })
	.map(() => Array.from({ length: TETRIS_COLS }).map(() => false));

tetrisTable.push(Array.from({ length: TETRIS_COLS }).map(() => true));

const figures = [
	{
		color: 'red',
		cells: [
			[1, 1],
			[1, 1],
		]
	},
	{
		color: 'yellow',
		cells: [
			[1],
			[1],
			[1],
			[1],
		]
	},
	{
		color: 'lightgreen',
		cells: [
			[1, 1, 0],
			[0, 1, 1],
		]
	},
	{
		color: 'lightblue',
		cells: [
			[0, 1, 1],
			[1, 1, 0],
		]
	},
	{
		color: 'blue',
		cells: [
			[1, 1, 1],
			[1, 0, 0],
		]
	},
	{
		color: 'purple',
		cells: [
			[1, 1, 1],
			[0, 0, 1],
		]
	},
	{
		color: 'green',
		cells: [
			[1, 1, 1],
			[0, 1, 0],
		]
	},
];

function getCellX(row) {
	return TETRIS_CELL_SIZE * row;
}

function getCellY(col) {
	return TETRIS_CELL_SIZE * col;
}

let currentFigure = {
	obj: {},
	row: 0,
	col: 0
};

let gameSpeed = 100;

function getFigure() {
	const index = Math.random() * figures.length | 0;
	currentFigure.obj = figures[index];
	currentFigure.row = -figures[index].cells.length;
	currentFigure.col = 0;
}

function checkForCollision(offsetRow, offsetCol) {
	for(let i = 0; i < currentFigure.obj.cells.length; i += 1) {
		const row = offsetRow + i;
		if(row < 0) {
			continue;
		}

		for(let j = 0; j < currentFigure.obj.cells[i].length; j += 1) {
			const col = offsetCol + j;

			if(currentFigure.obj.cells[i][j] && tetrisTable[row][col]) {
				return true;
			}
		}
	}

	return false;
}

function update() {
	let canFall = !checkForCollision(currentFigure.row + 1, currentFigure.col);

	if(canFall) {
		currentFigure.row += 1;
	} else {
		for(let i = 0; i < currentFigure.obj.cells.length; i += 1) {
			const row = currentFigure.row + i;
			for(let j = 0; j < currentFigure.obj.cells[i].length; j += 1) {
				const col = currentFigure.col + j;

				if(currentFigure.obj.cells[i][j]) {
					tetrisTable[row][col] = currentFigure.obj.color;
				}
			}
		}

		getFigure();
	}

	setTimeout(update, gameSpeed);
}

getFigure();
update();

window.addEventListener('keydown', function(ev) {
	console.log(ev.key);

	if(ev.key === 'ArrowLeft') {
		const canMove = currentFigure.col > 0 && !checkForCollision(currentFigure.row, currentFigure.col - 1);
		if(canMove) {
			currentFigure.col -= 1;
		}
	} else if(ev.key === 'ArrowRight') {
		const canMove = currentFigure.col + currentFigure.obj.cells[0].length < TETRIS_COLS && !checkForCollision(currentFigure.row, currentFigure.col + 1);
		if(canMove) {
			currentFigure.col += 1;
		}
	}
});
<|endoftext|>