<commit_before>;document.addEventListener("DOMContentLoaded", function() {
var
	// First find all elements with the data-pjax attribute.
	pjaxContainerList = document.querySelectorAll("[data-pjax]:not(a)"),
	pjaxAnchorList =
		document.querySelectorAll("a[data-pjax]:not([data-pjax='false'])"),
	// Then store all links to pre-load in their own array.
	pjaxAnchorArray = [],
	len_anchor,
	i_anchor,

	pjax = {},
$;

// Add anchors within containers to the array:
Array.prototype.forEach.call(pjaxContainerList, function(el) {
	var
		data = el.getAttribute("data-pjax"),
		list,
	$;

	if(data == "true") {
		data = "a";
	}

	list = el.querySelectorAll(data);

	Array.prototype.forEach.call(list, function(anchor) {
		pjaxAnchorArray.push(anchor);
	});
});

// Add anchors with their own data-pjax attribute to the array:
Array.prototype.forEach.call(pjaxAnchorList, function(anchor) {
	pjaxAnchorArray.push(anchor);
});

// Load cached page for each anchor's href:
len_anchor = pjaxAnchorArray.length;
for(i_anchor = 0; i_anchor < len_anchor; i_anchor++) {
	cache(pjaxAnchorArray[i_anchor]);
}

function cache(anchor) {
	var
		xhr = new XMLHttpRequest(),
	$;

	if(localStorage[anchor.href]) {
		if(pjax[anchor.href]) {
			return;
		}

		cacheLoad(anchor, localStorage[anchor.href]);
		return;
	}

	xhr.open("get", anchor.href, true);
	xhr.addEventListener("load", function() {
		cacheLoad(anchor, this.responseText);
	});
	xhr.send();
};

function cacheLoad(anchor, html) {
	var
		doc = document.implementation.createHTMLDocument(''),
	$;

	doc.documentElement.innerHTML = html;
	localStorage[anchor.href] = html;

	pjax[anchor.href] = {
		"title": doc.title,
		"body": doc.body.innerHTML,
	};
	anchor.addEventListener("click", e_click);
};

function e_click(e) {
	if(!pjax[this.href]) {
		return true;
	}

	e.preventDefault();

	document.title = pjax[this.href].title;
	document.body.innerHTML = pjax[this.href].body;
};

});<commit_msg>Use pathnames<commit_after>;document.addEventListener("DOMContentLoaded", function() {
var
	// First find all elements with the data-pjax attribute.
	pjaxContainerList = document.querySelectorAll("[data-pjax]:not(a)"),
	pjaxAnchorList =
		document.querySelectorAll("a[data-pjax]:not([data-pjax='false'])"),
	// Then store all links to pre-load in their own array.
	pjaxAnchorArray = [],
	len_anchor,
	i_anchor,

	pjax = {},
$;

// Add anchors within containers to the array:
Array.prototype.forEach.call(pjaxContainerList, function(el) {
	var
		data = el.getAttribute("data-pjax"),
		list,
	$;

	if(data == "true") {
		data = "a";
	}

	list = el.querySelectorAll(data);

	Array.prototype.forEach.call(list, function(anchor) {
		pjaxAnchorArray.push(anchor);
	});
});

// Add anchors with their own data-pjax attribute to the array:
Array.prototype.forEach.call(pjaxAnchorList, function(anchor) {
	pjaxAnchorArray.push(anchor);
});

// Load cached page for each anchor's href:
len_anchor = pjaxAnchorArray.length;
for(i_anchor = 0; i_anchor < len_anchor; i_anchor++) {
	cache(pjaxAnchorArray[i_anchor]);
}

function cache(anchor) {
	var
		xhr = new XMLHttpRequest(),
	$;

	if(localStorage[anchor.pathname]) {
		if(pjax[anchor.pathname]) {
			return;
		}

		cacheLoad(anchor, localStorage[anchor.pathname]);
		return;
	}

	xhr.open("get", anchor.pathname, true);
	xhr.addEventListener("load", function() {
		cacheLoad(anchor, this.responseText);
	});
	xhr.send();
};

function cacheLoad(anchor, html) {
	var
		doc = document.implementation.createHTMLDocument(''),
	$;

	doc.documentElement.innerHTML = html;
	localStorage[anchor.pathname] = html;

	pjax[anchor.pathname] = {
		"title": doc.title,
		"body": doc.body.innerHTML,
	};
	anchor.addEventListener("click", e_click);
};

function e_click(e) {
	if(!pjax[this.pathname]) {
		return true;
	}

	e.preventDefault();

	document.title = pjax[this.pathname].title;
	document.body.innerHTML = pjax[this.pathname].body;
};

});<|endoftext|>


<commit_before>/*
Name: mag-komposer v0.2.3
Description: side loading props based on react-komposer (https://github.com/kadirahq/react-komposer)
Let's compose MagJS containers and feed data into components.
Author: Michael Glazer
License: MIT
Homepage: https://github.com/magnumjs/mag.js
@requires mag.js(v0.25.7) & mag addons 0.22.5
(c) 2017
Simple Example: http://embed.plnkr.co/RkCuy0xoyUZyMjSPRKeH/
Full Example: http://embed.plnkr.co/LoI7vOx1KAZkaA8dZSJX/
*/

mag.komposer = function(handlerFunc, loadingComp, errorComp) {
  return function(composed) {
    var lnode = document.createElement('div');
    lnode.appendChild(lnode.cloneNode());

    loadingComp = loadingComp || mag.create(lnode, {
      view: function(state) {
        state.div = 'Loading...';
      }
    });

    //Default error component can be over ridden:
    var enode = document.createElement('div');
    enode.appendChild(enode.cloneNode());

    errorComp = errorComp || mag.create(enode, {
      view: function(state, props) {
        state.div = {
          _text: props.message,
          _style: 'color:red',
        };
      }
    });

    var cleaners = [],
      errors = [],
      loading = [];
    var _subscribe = function(props, instanceID) {
      //why is this here, onunload?
      if (cleaners[props.key]) cleaners[props.key]();

      cleaners[props.key] = handlerFunc(props, function(key, ids, nprops) {

        loading[key] = false;
        var cp = composed().getProps(ids);

        if (nprops instanceof Error) {
          errors[key] = true;
          error = {};
          Object.getOwnPropertyNames(nprops).forEach(function(skey) {
            error[skey] = nprops[skey];
          });
          mag.mod.setProps(ids, mag.merge(cp, error))

        } else {
          mag.mod.setProps(ids, mag.merge(cp, nprops))
        }

        var rnode = mag.getNode(mag.getId(ids));
        if (rnode) {
          mag.redraw(rnode, ids);
        }

      }.bind({}, props.key, instanceID));
    };

    var hoc = {
      controller: function(props) {
        if (!props.key) props.key = performance.now();
        loading[props.key] = true;

        this.didload = function(node, cprops, instanceId) {
          _subscribe(cprops, instanceId);
        };

        this.willgetprops = function(node, cprops, instanceId) {
          _subscribe(cprops, instanceId)
        };
      },
      view: function(state, props) {
        //is loading?
        if (loading[props.key]) {
          state.div = loadingComp(props);
          return;
        }
        //is error?
        if (errors[props.key]) {
          state.div = errorComp(props);
          return;
        }
        state.div = composed(props);
      }
    };

    // virtual node
    var node = document.createElement('div');
    node.appendChild(node.cloneNode())

    return mag.create(node, hoc);
  }
};
<commit_msg>Update mag-komposer.js<commit_after>/*
Name: mag-komposer v0.2.3
Description: side loading props based on react-komposer (https://github.com/kadirahq/react-komposer)
Let's compose MagJS containers and feed data into components.
Author: Michael Glazer
License: MIT
Homepage: https://github.com/magnumjs/mag.js
@requires mag.js(v0.25.7) & mag addons 0.22.5
(c) 2017
Simple Example: http://embed.plnkr.co/RkCuy0xoyUZyMjSPRKeH/
Full Example: http://embed.plnkr.co/LoI7vOx1KAZkaA8dZSJX/
*/

mag.komposer = function(handlerFunc, loadingComp, errorComp) {
  return function(composed) {
    var lnode = document.createElement('div');
    lnode.appendChild(lnode.cloneNode());

    loadingComp = loadingComp || mag.create(lnode, {
      view: function(state) {
        state.div = 'Loading...';
      }
    });

    //Default error component can be over ridden:
    var enode = document.createElement('div');
    enode.appendChild(enode.cloneNode());

    errorComp = errorComp || mag.create(enode, {
      view: function(state, props) {
        state.div = {
          _text: props.message,
          _style: 'color:red',
        };
      }
    });

    var cleaners = [],
      errors = [],
      loading = [];
    var _subscribe = function(props, instanceID) {
      //why is this here, onunload?
      if (cleaners[props.key]) cleaners[props.key]();

      cleaners[props.key] = handlerFunc(props, function(key, ids, nprops) {

        loading[key] = false;
        var cp = mag.mod.getProps(ids);

        if (nprops instanceof Error) {
          errors[key] = true;
          error = {};
          Object.getOwnPropertyNames(nprops).forEach(function(skey) {
            error[skey] = nprops[skey];
          });
          mag.mod.setProps(ids, mag.merge(cp, error))

        } else {
          mag.mod.setProps(ids, mag.merge(cp, nprops))
        }

        var rnode = mag.getNode(mag.getId(ids));
        if (rnode) {
          mag.redraw(rnode, ids);
        }

      }.bind({}, props.key, instanceID));
    };

    var hoc = {
      controller: function(props) {
        if (!props.key) props.key = performance.now();
        loading[props.key] = true;

        this.didload = function(node, cprops, instanceId) {
          _subscribe(cprops, instanceId);
        };

        this.willgetprops = function(node, cprops, instanceId) {
          _subscribe(cprops, instanceId)
        };
      },
      view: function(state, props) {
        //is loading?
        if (loading[props.key]) {
          state.div = loadingComp(props);
          return;
        }
        //is error?
        if (errors[props.key]) {
          state.div = errorComp(props);
          return;
        }
        state.div = composed(props);
      }
    };

    // virtual node
    var node = document.createElement('div');
    node.appendChild(node.cloneNode())

    return mag.create(node, hoc);
  }
};
<|endoftext|>


<commit_before>(function(ext) {

    //The variable that will hold the json to be read from
    var jsonObject = null;
    //The scale applied to the kinect data to make it map to the canvas better.
    var xScale = 280;
    var yScale = 210;
    var zScale = 200;

    //The status of the kinect
    var status = 0;

    //alert letting the user know what needs to be done before loading the extension.
    alert("BEFORE CLICKING OK: Make sure the kinect is connected and KinectinScratchServer has started");

    console.log("connecting to server ..");

    // create a new websocket and connect
    window.ws = new WebSocket('ws://localhost:8181/');

    // when data is comming from the server, this method is called
    ws.onmessage = function (evt) {
        jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
    };

    // when the connection is established, this method is called
    ws.onopen = function () {
        console.log('.. connection open');
    };

    // when the connection is closed, this method is called
    ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
    };

    // Cleanup function when the extension is unloaded
    ext._shutdown = function()
    {
    window.ws.close();
    };

    // Reports status of kinect
    ext._getStatus = function() {
        if(status == 0)
        {
        return {status: 0, msg: 'Kinect is not connected to Scratch'};
        }
        if(status == 1)
        {
            return {status: 1, msg: 'Kinect is connected, but is not detecting any bodies'};
        }
        if(status == 2)
        {
            return {status: 2, msg: 'Kinect is sending body data'};
        }

    };

        // Block and block menu descriptions
    var descriptor = {
        blocks: [
            ['r', '%m.l %m.k1 %m.x', 'joints', 'Body 1', 'Head', 'x'],
            ['', 'restart local connection', 'restart'],
            ['', 'Create connection to %s', 'ipconnect', '0.0.0.0'],
            ['', 'Close connection', 'closeconn'],
            ['', 'Basic body check', 'basic_body_check'],
            ['b', 'connected', 'connected'],
            ['b', '%m.l tracked', 'tracked', 'Body 1'],
            ['', 'console.log %n', 'write'],
            ['', 'bad only %n', 'writeB'],
            ['r', '%m.l id', 'l', 'Body 1'],
            ['r', '%m.l %m.d Handstate', 'handd', 'Body 1', 'Left'],
            ['b', '%m.l %m.d Handstate is %m.n', 'hand', 'Body 1', 'Left', 'Closed']
        ],

        menus: {
        k: ['Left Ankle X', 'Left Ankle Y', 'Right Ankle X', 'Right Ankle Y', 'Left Elbow X', 'Left Elbow Y', 'Right Elbow X', 'Right Elbow Y', 'Left Foot X', 'Left Foot Y', 'Right Foot X', 'Right Foot Y', 'Left Hand X', 'Left Hand Y', 'Right Hand X', 'Right Hand Y', 'Left Hand Tip X', 'Left Hand Tip Y', 'Right Hand Tip X', 'Right Hand Tip Y', 'Head X', 'Head Y', 'Left Hip X', 'Left Hip Y', 'Right Hip X', 'Right Hip Y', 'Left Knee X', 'Left Knee Y', 'Right Knee X', 'Right Knee Y', 'Neck X', 'Neck Y', 'Left Shoulder X', 'Left Shoulder Y', 'Right Shoulder X', 'Right Shoulder Y', 'Spine Base X', 'Spine Base Y', 'Spine Middle X', 'Spine Middle Y', 'Spine Shoulder X', 'Spine Shoulder Y', 'Left Thumb X', 'Left Thumb Y', 'Right Thumb X', 'Right Thumb Y', 'Left Wrist X', 'Left Wrist Y', 'Right Wrist X', 'Right Wrist Y'],
	    k1: ['Left Ankle', 'Right Ankle', 'Left Elbow', 'Right Elbow', 'Left Foot', 'Right Foot', 'Left Hand', 'Right Hand', 'Left Hand Tip', 'Right Hand Tip', 'Head', 'Left Hip', 'Right Hip', 'Left Knee', 'Right Knee', 'Neck', 'Left Shoulder', 'Right Shoulder', 'Spine Base', 'Spine Middle', 'Spine Shoulder', 'Left Thumb', 'Right Thumb', 'Left Wrist', 'Right Wrist'],
        l: ['Body 1', 'Body 2', 'Body 3', 'Body 4', 'Body 5', 'Body 6'],
        n: ['Unknown', 'Not Tracked', 'Open', 'Closed', 'Lasso'],
        x: ['x', 'y', 'z'],
        d: ['Left', 'Right']
    }
    };

    //restarts the local connection
    ext.restart = function() {
        window.ws.close();
        console.log("connecting to local server ..");
        window.ws = new WebSocket('ws://localhost:8181/');

        // when data is comming from the server, this method is called
        ws.onmessage = function (evt) {
            jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
    };

    // when the connection is established, this method is called
    ws.onopen = function () {
        console.log('.. connection open');
    };

    // when the connection is closed, this method is called
    ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
    };
    };

    //s: a string containing the ip the user wishes to connect to.
    //Creates a remote connection to s.
    ext.ipconnect = function(s) {
        window.ws.close();
        console.log("connecting to "+s+' ..');
        window.ws = new WebSocket('ws://'+s+':8181/');

        // when data is comming from the server, this method is called
        ws.onmessage = function (evt) {
            jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
    };

    // when the connection is established, this method is called
    ws.onopen = function () {
        console.log('.. connection open');
    };

    // when the connection is closed, this method is called
    ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
    };
    }

    //Closes the current connection
    ext.closeconn = function()
    {
        window.ws.close();
    }

    //m: the number to be written to the console
    //Outputs numeric content to console
    ext.write = function(m){
        console.log(m);
    };

    //m: input to be compared to 0
    //Writes "bad" in console if the input is 0
    ext.writeB = function(m){
        if(m == 0)
        {
            console.log("bad");
        }
    };

    //Checks the body 1 head x coordinate
    //Good for check if any data is getting in from the kinect
    ext.basic_body_check = function() {
        console.log(jsonObject.bodies[0].joints[3].x*xScale);
    };

    //m: the body chosen (Body 1-6)
    //Gives the id of the selected body
    ext.l = function(m)
    {
        switch(m){
            case 'Body 1': return jsonObject.bodies[0].id;
            case 'Body 2': return jsonObject.bodies[1].id;
            case 'Body 3': return jsonObject.bodies[2].id;
            case 'Body 4': return jsonObject.bodies[3].id;
            case 'Body 5': return jsonObject.bodies[4].id;
            case 'Body 6': return jsonObject.bodies[5].id;
        }
    }

        //True if scratch is receiving the kinect (but not necessarily data)
    ext.connected = function()
    {
        if(status == 0){
            return false;
        }

        if(status == 1 || 2){
            return true;
        }
    };

    //m: the body chosen (Body 1-6)
    //True if scratch is receiving the chosen body data
    ext.tracked = function(m)
    {
        var i = -1;
        switch(m){
            case 'Body 1': i = 0;
                break;
            case 'Body 2': i = 1;
                break;
            case 'Body 3': i = 2;
                break;
            case 'Body 4': i = 3;
                break;
            case 'Body 5': i = 4;
                break;
            case 'Body 6': i = 5;
                break;
        }

        return jsonObject.bodies[i].id != 0;
    };

    //l: the body chosen (Body 1-6)
    //d: which handstate (left or right)
    //Outputs the left handstate of the selected body
    ext.handd = function(l,d)
    {
        var i;
        switch(l){
            case 'Body 1': i=0;
                break;
            case 'Body 2': i=1;
                break;
            case 'Body 3': i=2;
                break;
            case 'Body 4': i=3;
                break;
            case 'Body 5': i=4;
                break;
            case 'Body 6': i=5;
                break;
        }

        switch(d)
        {
            case 'Left': return jsonObject.bodies[i].lhandstate;
            case 'Right': return jsonObject.bodies[i].rhandstate;
        }
    }

    //l: The selected body (Body 1-6)
    //d: Which handstate (left or right)
    //n: The selected handstate (Unknown, Not Tracked, Open, Closed, Lasso)
    //Returns true if the selected bodies left handstate is the same as block selected one.
    ext.hand = function(l,d,n)
    {
        var i;
        var j;
        switch(l){
            case 'Body 1': i=0;
                break;
            case 'Body 2': i=1;
                break;
            case 'Body 3': i=2;
                break;
            case 'Body 4': i=3;
                break;
            case 'Body 5': i=4;
                break;
            case 'Body 6': i=5;
                break;
        }

        switch(n)
        {
            case 'Unknown': j = 0;
                break;
            case 'Not Tracked': j = 1;
                break;
            case 'Open': j = 2;
                break;
            case 'Closed': j = 3;
                break;
            case 'Lasso': j = 4;
                break;
        }

        switch(d)
        {
            case 'Left': return jsonObject.bodies[i].lhandstate == j;
            case 'Right': return jsonObject.bodies[i].rhandstate == j;
        }
    }

    //l: The body chosen (Body 1-6).
    //k1: The joint chosen (All joint the kinect v2 tracks).
    //x: The chosen coordinate (x, y, or z).
    //Gets the coordinate chosen from the joint chosen from the body chosen
    ext.joints = function(l,k1,x)
    {
        var a;
        var b;
        switch(k1){
            case 'Left Ankle': a=14;
                break;
            case 'Right Ankle': a=18;
                break;
            case 'Left Elbow': a=5;
                break;
            case 'Right Elbow': a=9;
                break;
            case 'Left Foot': a=15;
                break;
            case 'Right Foot': a=19;
                break;
            case 'Left Hand': a=7;
                break;
            case 'Right Hand': a=11;
                break;
            case 'Left Hand Tip': a=21;
                break;
            case 'Right Hand Tip': a=23;
                break;
            case 'Head': a=3;
                break;
            case 'Left Hip': a=12;
                break;
            case 'Right Hip': a=16;
                break;
            case 'Left Knee': a=13;
                break;
            case 'Right Knee': a=17;
                break;
            case 'Neck': a=2;
                break;
            case 'Left Shoulder': a=4;
                break;
            case 'Right Shoulder': a=8;
                break;
            case 'Spine Base': a=0;
                break;
            case 'Spine Middle': a=1;
                break;
            case 'Spine Shoulder': a=20;
                break;
            case 'Left Thumb': a=22;
                break;
            case 'Right Thumb': a=24;
                break;
            case 'Left Wrist': a=6;
                break;
            case 'Right Wrist': a=10;
                break;
        }

        switch(l){
            case 'Body 1': b=0;
                break;
            case 'Body 2': b=1;
                break;
            case 'Body 3': b=2;
                break;
            case 'Body 4': b=3;
                break;
            case 'Body 5': b=4;
                break;
            case 'Body 6': b=5;
                break;
        }

        switch(x){
            case 'x': return jsonObject.bodies[b].joints[a].x*xScale;
            case 'y': return jsonObject.bodies[b].joints[a].y*yScale;
            case 'z': return jsonObject.bodies[b].joints[a].z*zScale;
        }
    }

    // Register the extension
    ScratchExtensions.register('SkelScratch', descriptor, ext);
})({});<commit_msg>Reorganize block order (and remove reference to KinectinScratchServer)<commit_after>(function(ext) {

    //The variable that will hold the json to be read from
    var jsonObject = null;

    //The scale applied to the kinect data to make it map to the canvas better.
    var xScale = 280;
    var yScale = 210;
    var zScale = 200;

    //The status of the kinect
    var status = 0;

    //alert letting the user know what needs to be done before loading the extension.
    alert("BEFORE CLICKING OK: Make sure the kinect is connected and your JSON websocket server has started");

    console.log("connecting to server ..");

    // create a new websocket and connect
    window.ws = new WebSocket('ws://localhost:8181/');

    // when data is comming from the server, this method is called
    ws.onmessage = function (evt) {
        jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
    };

    // when the connection is established, this method is called
    ws.onopen = function () {
        console.log('.. connection open');
    };

    // when the connection is closed, this method is called
    ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
    };

    // Cleanup function when the extension is unloaded
    ext._shutdown = function()
    {
    window.ws.close();
    };

    // Reports status of kinect
    ext._getStatus = function() {
        if(status == 0)
        {
        return {status: 0, msg: 'Kinect is not connected to Scratch'};
        }
        if(status == 1)
        {
            return {status: 1, msg: 'Kinect is connected, but is not detecting any bodies'};
        }
        if(status == 2)
        {
            return {status: 2, msg: 'Kinect is sending body data'};
        }

    };

        // Block and block menu descriptions
    var descriptor = {
        blocks: [
            ['r', '%m.l %m.k1 %m.x', 'joints', 'Body 1', 'Head', 'x'],
            ['r', '%m.l %m.d Handstate', 'handd', 'Body 1', 'Left'],
            ['r', '%m.l id', 'l', 'Body 1'],
            ['b', '%m.l %m.d Handstate is %m.n', 'hand', 'Body 1', 'Left', 'Closed'],
            ['b', '%m.l tracked', 'tracked', 'Body 1'],
            ['b', 'connected', 'connected'],
            ['', 'Basic body check', 'basic_body_check'],
            ['', 'restart local connection', 'restart'],
            ['', 'Create connection to %s', 'ipconnect', '0.0.0.0'],
            ['', 'Close connection', 'closeconn'],
            ['', 'console.log %n', 'write'],
            ['', 'bad only %n', 'writeB']
        ],

        menus: {
        k: ['Left Ankle X', 'Left Ankle Y', 'Right Ankle X', 'Right Ankle Y', 'Left Elbow X', 'Left Elbow Y', 'Right Elbow X', 'Right Elbow Y', 'Left Foot X', 'Left Foot Y', 'Right Foot X', 'Right Foot Y', 'Left Hand X', 'Left Hand Y', 'Right Hand X', 'Right Hand Y', 'Left Hand Tip X', 'Left Hand Tip Y', 'Right Hand Tip X', 'Right Hand Tip Y', 'Head X', 'Head Y', 'Left Hip X', 'Left Hip Y', 'Right Hip X', 'Right Hip Y', 'Left Knee X', 'Left Knee Y', 'Right Knee X', 'Right Knee Y', 'Neck X', 'Neck Y', 'Left Shoulder X', 'Left Shoulder Y', 'Right Shoulder X', 'Right Shoulder Y', 'Spine Base X', 'Spine Base Y', 'Spine Middle X', 'Spine Middle Y', 'Spine Shoulder X', 'Spine Shoulder Y', 'Left Thumb X', 'Left Thumb Y', 'Right Thumb X', 'Right Thumb Y', 'Left Wrist X', 'Left Wrist Y', 'Right Wrist X', 'Right Wrist Y'],
	    k1: ['Left Ankle', 'Right Ankle', 'Left Elbow', 'Right Elbow', 'Left Foot', 'Right Foot', 'Left Hand', 'Right Hand', 'Left Hand Tip', 'Right Hand Tip', 'Head', 'Left Hip', 'Right Hip', 'Left Knee', 'Right Knee', 'Neck', 'Left Shoulder', 'Right Shoulder', 'Spine Base', 'Spine Middle', 'Spine Shoulder', 'Left Thumb', 'Right Thumb', 'Left Wrist', 'Right Wrist'],
        l: ['Body 1', 'Body 2', 'Body 3', 'Body 4', 'Body 5', 'Body 6'],
        n: ['Unknown', 'Not Tracked', 'Open', 'Closed', 'Lasso'],
        x: ['x', 'y', 'z'],
        d: ['Left', 'Right']
    }
    };

    //restarts the local connection
    ext.restart = function() {
        window.ws.close();
        console.log("connecting to local server ..");
        window.ws = new WebSocket('ws://localhost:8181/');

        // when data is comming from the server, this method is called
        ws.onmessage = function (evt) {
            jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
    };

    // when the connection is established, this method is called
    ws.onopen = function () {
        console.log('.. connection open');
    };

    // when the connection is closed, this method is called
    ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
    };
    };

    //s: a string containing the ip the user wishes to connect to.
    //Creates a remote connection to s.
    ext.ipconnect = function(s) {
        window.ws.close();
        console.log("connecting to "+s+' ..');
        window.ws = new WebSocket('ws://'+s+':8181/');

        // when data is comming from the server, this method is called
        ws.onmessage = function (evt) {
            jsonObject = JSON.parse(evt.data);
            if(jsonObject.bodies == '')
            {
                status = 1;
            } else
            {
                status = 2;
            }
    };

    // when the connection is established, this method is called
    ws.onopen = function () {
        console.log('.. connection open');
    };

    // when the connection is closed, this method is called
    ws.onclose = function () {
        console.log('.. connection closed');
        status = 0;
    };
    }

    //Closes the current connection
    ext.closeconn = function()
    {
        window.ws.close();
    }

    //m: the number to be written to the console
    //Outputs numeric content to console
    ext.write = function(m){
        console.log(m);
    };

    //m: input to be compared to 0
    //Writes "bad" in console if the input is 0
    ext.writeB = function(m){
        if(m == 0)
        {
            console.log("bad");
        }
    };

    //Checks the body 1 head x coordinate
    //Good for check if any data is getting in from the kinect
    ext.basic_body_check = function() {
        console.log(jsonObject.bodies[0].joints[3].x*xScale);
    };

    //m: the body chosen (Body 1-6)
    //Gives the id of the selected body
    ext.l = function(m)
    {
        switch(m){
            case 'Body 1': return jsonObject.bodies[0].id;
            case 'Body 2': return jsonObject.bodies[1].id;
            case 'Body 3': return jsonObject.bodies[2].id;
            case 'Body 4': return jsonObject.bodies[3].id;
            case 'Body 5': return jsonObject.bodies[4].id;
            case 'Body 6': return jsonObject.bodies[5].id;
        }
    }

        //True if scratch is receiving the kinect (but not necessarily data)
    ext.connected = function()
    {
        if(status == 0){
            return false;
        }

        if(status == 1 || 2){
            return true;
        }
    };

    //m: the body chosen (Body 1-6)
    //True if scratch is receiving the chosen body data
    ext.tracked = function(m)
    {
        var i = -1;
        switch(m){
            case 'Body 1': i = 0;
                break;
            case 'Body 2': i = 1;
                break;
            case 'Body 3': i = 2;
                break;
            case 'Body 4': i = 3;
                break;
            case 'Body 5': i = 4;
                break;
            case 'Body 6': i = 5;
                break;
        }

        return jsonObject.bodies[i].id != 0;
    };

    //l: the body chosen (Body 1-6)
    //d: which handstate (left or right)
    //Outputs the left handstate of the selected body
    ext.handd = function(l,d)
    {
        var i;
        switch(l){
            case 'Body 1': i=0;
                break;
            case 'Body 2': i=1;
                break;
            case 'Body 3': i=2;
                break;
            case 'Body 4': i=3;
                break;
            case 'Body 5': i=4;
                break;
            case 'Body 6': i=5;
                break;
        }

        switch(d)
        {
            case 'Left': return jsonObject.bodies[i].lhandstate;
            case 'Right': return jsonObject.bodies[i].rhandstate;
        }
    }

    //l: The selected body (Body 1-6)
    //d: Which handstate (left or right)
    //n: The selected handstate (Unknown, Not Tracked, Open, Closed, Lasso)
    //Returns true if the selected bodies left handstate is the same as block selected one.
    ext.hand = function(l,d,n)
    {
        var i;
        var j;
        switch(l){
            case 'Body 1': i=0;
                break;
            case 'Body 2': i=1;
                break;
            case 'Body 3': i=2;
                break;
            case 'Body 4': i=3;
                break;
            case 'Body 5': i=4;
                break;
            case 'Body 6': i=5;
                break;
        }

        switch(n)
        {
            case 'Unknown': j = 0;
                break;
            case 'Not Tracked': j = 1;
                break;
            case 'Open': j = 2;
                break;
            case 'Closed': j = 3;
                break;
            case 'Lasso': j = 4;
                break;
        }

        switch(d)
        {
            case 'Left': return jsonObject.bodies[i].lhandstate == j;
            case 'Right': return jsonObject.bodies[i].rhandstate == j;
        }
    }

    //l: The body chosen (Body 1-6).
    //k1: The joint chosen (All joint the kinect v2 tracks).
    //x: The chosen coordinate (x, y, or z).
    //Gets the coordinate chosen from the joint chosen from the body chosen
    ext.joints = function(l,k1,x)
    {
        var a;
        var b;
        switch(k1){
            case 'Left Ankle': a=14;
                break;
            case 'Right Ankle': a=18;
                break;
            case 'Left Elbow': a=5;
                break;
            case 'Right Elbow': a=9;
                break;
            case 'Left Foot': a=15;
                break;
            case 'Right Foot': a=19;
                break;
            case 'Left Hand': a=7;
                break;
            case 'Right Hand': a=11;
                break;
            case 'Left Hand Tip': a=21;
                break;
            case 'Right Hand Tip': a=23;
                break;
            case 'Head': a=3;
                break;
            case 'Left Hip': a=12;
                break;
            case 'Right Hip': a=16;
                break;
            case 'Left Knee': a=13;
                break;
            case 'Right Knee': a=17;
                break;
            case 'Neck': a=2;
                break;
            case 'Left Shoulder': a=4;
                break;
            case 'Right Shoulder': a=8;
                break;
            case 'Spine Base': a=0;
                break;
            case 'Spine Middle': a=1;
                break;
            case 'Spine Shoulder': a=20;
                break;
            case 'Left Thumb': a=22;
                break;
            case 'Right Thumb': a=24;
                break;
            case 'Left Wrist': a=6;
                break;
            case 'Right Wrist': a=10;
                break;
        }

        switch(l){
            case 'Body 1': b=0;
                break;
            case 'Body 2': b=1;
                break;
            case 'Body 3': b=2;
                break;
            case 'Body 4': b=3;
                break;
            case 'Body 5': b=4;
                break;
            case 'Body 6': b=5;
                break;
        }

        switch(x){
            case 'x': return jsonObject.bodies[b].joints[a].x*xScale;
            case 'y': return jsonObject.bodies[b].joints[a].y*yScale;
            case 'z': return jsonObject.bodies[b].joints[a].z*zScale;
        }
    }

    // Register the extension
    ScratchExtensions.register('SkelScratch', descriptor, ext);
})({});<|endoftext|>


<commit_before>import React, {
  Component,
  View,
  StyleSheet,
  ScrollView,
  DeviceEventEmitter,
  Dimensions,
  LayoutAnimation,
  PropTypes,
  Platform
} from 'react-native';

const { height: screenHeight } = Dimensions.get('window');
const animations               = {
  layout: {
    easeInEaseOut: {
      duration: 250,
      create: {
        type: LayoutAnimation.Types.easeInEaseOut,
        property: LayoutAnimation.Properties.scaleXY
      },
      update: {
        delay: 0,
        type: LayoutAnimation.Types.easeInEaseOut
      }
    }
  }
};

class SmartScrollView extends Component {

  constructor(){
    super();
    this.state = {
      scrollPosition : 0,
    }
    this._refCreator           = this._refCreator.bind(this);
    this._focusNode            = this._focusNode.bind(this);
    this._keyboardWillHide     = this._keyboardWillHide.bind(this);
    this._keyboardWillShow     = this._keyboardWillShow.bind(this);
    this._updateScrollPosition = this._updateScrollPosition.bind(this);
  }

  componentDidMount() {
    if (this.props.forceFocusField !== this.state.focusedField){
      this._focusField('input_' + this.props.forceFocusField)
    }

    this._listeners = [
      DeviceEventEmitter.addListener(Platform.OS == 'IOS' ? 'keyboardDidShow' : 'keyboardDidShow', this._keyboardWillShow),
      DeviceEventEmitter.addListener(Platform.OS == 'IOS' ? 'keyboardWillHide' : 'keyboardDidHide', this._keyboardWillHide),
    ];
  }

  componentWillUpdate(props, state) {
    if (state.keyboardUp !== this.state.keyboardUp) {
      LayoutAnimation.configureNext(animations.layout.easeInEaseOut)
    }
  }

  componentWillReceiveProps(props) {
    if (props.forceFocusField !== undefined && props.forceFocusField !== this.state.focusedField){
      this._focusField('input_' + props.forceFocusField)
    }
  }

  componentWillUnmount() {
    this._listeners.forEach((listener) => listener.remove());
  }

  _findScrollWindowHeight(keyboardHeight){
    const {x, y, width, height} = this._layout
    const spaceBelow    = screenHeight - y - height;
    return height - Math.max(keyboardHeight - spaceBelow, 0);
  }

  _keyboardWillShow(e) {
    const scrollWindowHeight = this._findScrollWindowHeight(e.endCoordinates.height)

    this.setState({
      scrollWindowHeight,
      keyBoardUp: true
    })
  }

  _keyboardWillHide() {
    this.setState({
      keyBoardUp: false
    });
    this._smartScroll && this._smartScroll.scrollTo({y: 0});
  }

  _refCreator () {
    const refs = arguments;
    return component => Object.keys(refs).forEach(i => this[refs[i]] = component);
  }

  _focusField (ref) {
    const node = this[ref];
    const {type} = node.props.smartScrollOptions;

    switch(type) {
      case 'text':
        this[ref].focus();
        break;
      case 'custom':
        this._focusNode(ref);
    }
  }

  _focusNode (ref) {
    const {
      scrollPosition,
      scrollWindowHeight,
    }                       = this.state;
    const {
      scrollPadding,
      onRefFocus
    }                       = this.props;
    const num               = React.findNodeHandle(this._smartScroll);
    const strippedBackRef   = ref.slice('input_'.length);

    setTimeout(() => {
      onRefFocus(strippedBackRef);
      this.setState({focusedField: strippedBackRef})
      this[ref].measureLayout(num, (X,Y,W,H) => {
        const py = Y - scrollPosition;

        if ( py + H > scrollWindowHeight ){
          const nextScrollPosition = (Y + H) - scrollWindowHeight + scrollPadding;

          this._smartScroll.scrollTo({y: nextScrollPosition});
          this.setState({scrollPosition:nextScrollPosition })
        } else if ( py < 0 ) {
          const nextScrollPosition = Y - scrollPadding;

          this._smartScroll.scrollTo({y: nextScrollPosition})
          this.setState({ scrollPosition: nextScrollPosition})
        }
      });
    }, 0);
  }

  _updateScrollPosition (event) {
    this.setState({ scrollPosition: event.nativeEvent.contentOffset.y });
  }

  render () {

    const {
      children: scrollChildren,
      contentContainerStyle,
      scrollContainerStyle,
      zoomScale,
      showsVerticalScrollIndicator,
      contentInset,
      onScroll
    }                = this.props;
    let inputIndex   = 0;
    const smartClone = (element, i) => {
      const { smartScrollOptions } = element.props;
      let smartProps               = { key: i };

      if (smartScrollOptions.type !== undefined) {
        const ref          = 'input_' + inputIndex;

        smartProps.ref = this._refCreator(ref, smartScrollOptions.scrollRef && 'input_' + smartScrollOptions.scrollRef);

        if (smartScrollOptions.type === 'text') {
          smartProps.onFocus = () => {
            smartProps.onFocus = element.props.onFocus && element.props.onFocus();
            this._focusNode(ref)
          };

          if (smartScrollOptions.moveToNext === true) {
            const nextRef              = 'input_' + (inputIndex+1);
            const focusNextField       = () => this._focusField(nextRef)
            smartProps.blurOnSubmit    = false;
            smartProps.onSubmitEditing = smartScrollOptions.onSubmitEditing ?
              () => smartScrollOptions.onSubmitEditing(focusNextField) :
              focusNextField
          }
        }

        inputIndex += 1
      }

      return React.cloneElement(element, smartProps)
    }

    function recursivelyCheckAndAdd(children, i) {
      return React.Children.map(children, (child, j) => {
        if (child.props !== undefined) {
          if (child.props.smartScrollOptions !== undefined) {
            return smartClone(child, ''+i+j);
          } else if (child.props.children !== undefined) {
            return React.cloneElement(child, {key: i}, recursivelyCheckAndAdd(child.props.children, ''+i+j));
          } else {
            return React.cloneElement(child, {key: i});
          }
        } else {
          return child
        }
      })
    }

    const content = recursivelyCheckAndAdd(scrollChildren, '0');

    return (
      <View
        ref   = { component => this._container=component }
        style = {scrollContainerStyle}
        onLayout={(e) => this._layout = e.nativeEvent.layout}
      >
        <View
          style     = {this.state.keyBoardUp ? { height: this.state.scrollWindowHeight } : styles.flex1}
        >
          <ScrollView
            ref                              = { component => this._smartScroll=component }
            automaticallyAdjustContentInsets = { false }
            scrollsToTop                     = { false }
            style                            = { styles.flex1 }
            onScroll                         = { (event) => {
              this._updateScrollPosition(event)
              onScroll(event)
            }}
            scrollEventThrottle              = { 16 }
            contentContainerStyle            = { contentContainerStyle }
            contentInset                     = { contentInset }
            zoomScale                        = { zoomScale }
            showsVerticalScrollIndicator     = { showsVerticalScrollIndicator }
            keyboardShouldPersistTaps        = { true }
            bounces                          = { false }
          >
            {content}
          </ScrollView>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  flex1: {
    flex: 1
  }
});

SmartScrollView.propTypes = {
  forceFocusField:              PropTypes.oneOf(PropTypes.number, PropTypes.string),
  scrollContainerStyle:         PropTypes.number,
  contentContainerStyle:        PropTypes.number,
  zoomScale:                    PropTypes.number,
  showsVerticalScrollIndicator: PropTypes.bool,
  contentInset:                 PropTypes.object,
  onScroll:                     PropTypes.func,
  onRefFocus:                   PropTypes.func,
};

SmartScrollView.defaultProps = {
  scrollContainerStyle:         styles.flex1,
  scrollPadding:                5,
  zoomScale:                    1,
  showsVerticalScrollIndicator: true,
  contentInset:                 {top: 0, left: 0, bottom: 0, right: 0},
  onScroll:                     () => {},
  onRefFocus:                   () => {}
};

export default SmartScrollView;

// import dismissKeyboard from 'dismissKeyboard';
// this._scrollTap            = this._scrollTap.bind(this);
// lastTap:         0
// _scrollTap () {
//   const {lastTap}  = this.state;
//   const currentTap = new Date().getTime();
//   console.log("tap")
//
//   if (currentTap - lastTap < 500) {
//     dismissKeyboard()
//   }
//
//   this.setState({
//     lastTap: currentTap
//   })
// }
<commit_msg>Update returnKeyType automatically<commit_after>import React, {
  Component,
  View,
  StyleSheet,
  ScrollView,
  DeviceEventEmitter,
  Dimensions,
  LayoutAnimation,
  PropTypes,
  Platform
} from 'react-native';

const { height: screenHeight } = Dimensions.get('window');
const animations               = {
  layout: {
    easeInEaseOut: {
      duration: 250,
      create: {
        type: LayoutAnimation.Types.easeInEaseOut,
        property: LayoutAnimation.Properties.scaleXY
      },
      update: {
        delay: 0,
        type: LayoutAnimation.Types.easeInEaseOut
      }
    }
  }
};

class SmartScrollView extends Component {

  constructor(){
    super();
    this.state = {
      scrollPosition : 0,
    }
    this._refCreator           = this._refCreator.bind(this);
    this._focusNode            = this._focusNode.bind(this);
    this._keyboardWillHide     = this._keyboardWillHide.bind(this);
    this._keyboardWillShow     = this._keyboardWillShow.bind(this);
    this._updateScrollPosition = this._updateScrollPosition.bind(this);
  }

  componentDidMount() {
    if (this.props.forceFocusField !== this.state.focusedField){
      this._focusField('input_' + this.props.forceFocusField)
    }

    this._listeners = [
      DeviceEventEmitter.addListener(Platform.OS == 'IOS' ? 'keyboardDidShow' : 'keyboardDidShow', this._keyboardWillShow),
      DeviceEventEmitter.addListener(Platform.OS == 'IOS' ? 'keyboardWillHide' : 'keyboardDidHide', this._keyboardWillHide),
    ];
  }

  componentWillUpdate(props, state) {
    if (state.keyboardUp !== this.state.keyboardUp) {
      LayoutAnimation.configureNext(animations.layout.easeInEaseOut)
    }
  }

  componentWillReceiveProps(props) {
    if (props.forceFocusField !== undefined && props.forceFocusField !== this.state.focusedField){
      this._focusField('input_' + props.forceFocusField)
    }
  }

  componentWillUnmount() {
    this._listeners.forEach((listener) => listener.remove());
  }

  _findScrollWindowHeight(keyboardHeight){
    const {x, y, width, height} = this._layout
    const spaceBelow    = screenHeight - y - height;
    return height - Math.max(keyboardHeight - spaceBelow, 0);
  }

  _keyboardWillShow(e) {
    const scrollWindowHeight = this._findScrollWindowHeight(e.endCoordinates.height)

    this.setState({
      scrollWindowHeight,
      keyBoardUp: true
    })
  }

  _keyboardWillHide() {
    this.setState({
      keyBoardUp: false
    });
    this._smartScroll && this._smartScroll.scrollTo({y: 0});
  }

  _refCreator () {
    const refs = arguments;
    return component => Object.keys(refs).forEach(i => this[refs[i]] = component);
  }

  _focusField (ref) {
    const node = this[ref];
    const {type} = node.props.smartScrollOptions;

    switch(type) {
      case 'text':
        this[ref].focus();
        break;
      case 'custom':
        this._focusNode(ref);
    }
  }

  _focusNode (ref) {
    const {
      scrollPosition,
      scrollWindowHeight,
    }                       = this.state;
    const {
      scrollPadding,
      onRefFocus
    }                       = this.props;
    const num               = React.findNodeHandle(this._smartScroll);
    const strippedBackRef   = ref.slice('input_'.length);

    setTimeout(() => {
      onRefFocus(strippedBackRef);
      this.setState({focusedField: strippedBackRef})
      this[ref].measureLayout(num, (X,Y,W,H) => {
        const py = Y - scrollPosition;

        if ( py + H > scrollWindowHeight ){
          const nextScrollPosition = (Y + H) - scrollWindowHeight + scrollPadding;

          this._smartScroll.scrollTo({y: nextScrollPosition});
          this.setState({scrollPosition: nextScrollPosition })
        } else if ( py < 0 ) {
          const nextScrollPosition = Y - scrollPadding;

          this._smartScroll.scrollTo({y: nextScrollPosition})
          this.setState({ scrollPosition: nextScrollPosition})
        }
      });
    }, 0);
  }

  _updateScrollPosition (event) {
    this.setState({ scrollPosition: event.nativeEvent.contentOffset.y });
  }

  render () {

    const {
      children: scrollChildren,
      contentContainerStyle,
      scrollContainerStyle,
      zoomScale,
      showsVerticalScrollIndicator,
      contentInset,
      onScroll
    }                = this.props;
    let inputIndex   = 0;
    const smartClone = (element, i) => {
      const { smartScrollOptions } = element.props;
      let smartProps               = { key: i };

      if (smartScrollOptions.type !== undefined) {
        const ref          = 'input_' + inputIndex;

        smartProps.ref = this._refCreator(ref, smartScrollOptions.scrollRef && 'input_' + smartScrollOptions.scrollRef);

        if (smartScrollOptions.type === 'text') {
          smartProps.onFocus = () => {
            smartProps.onFocus = element.props.onFocus && element.props.onFocus();
            this._focusNode(ref)
          };

          if (smartScrollOptions.moveToNext === true) {
            const nextRef              = 'input_' + (inputIndex+1);
            const focusNextField       = () => this._focusField(nextRef)

            if(typeof(element.props.returnKeyType) === 'undefined'){
              smartProps.returnKeyType  = 'next'
            }

            smartProps.blurOnSubmit    = false;
            smartProps.onSubmitEditing = smartScrollOptions.onSubmitEditing ?
              () => smartScrollOptions.onSubmitEditing(focusNextField) :
              focusNextField
          }
        }

        inputIndex += 1
      }

      return React.cloneElement(element, smartProps)
    }

    function recursivelyCheckAndAdd(children, i) {
      return React.Children.map(children, (child, j) => {
        if (child.props !== undefined) {
          if (child.props.smartScrollOptions !== undefined) {
            return smartClone(child, ''+i+j);
          } else if (child.props.children !== undefined) {
            return React.cloneElement(child, {key: i}, recursivelyCheckAndAdd(child.props.children, ''+i+j));
          } else {
            return React.cloneElement(child, {key: i});
          }
        } else {
          return child
        }
      })
    }

    const content = recursivelyCheckAndAdd(scrollChildren, '0');

    return (
      <View
        ref   = { component => this._container=component }
        style = {scrollContainerStyle}
        onLayout={(e) => this._layout = e.nativeEvent.layout}
      >
        <View
          style     = {this.state.keyBoardUp ? { height: this.state.scrollWindowHeight } : styles.flex1}
        >
          <ScrollView
            ref                              = { component => this._smartScroll=component }
            automaticallyAdjustContentInsets = { false }
            scrollsToTop                     = { false }
            style                            = { styles.flex1 }
            onScroll                         = { (event) => {
              this._updateScrollPosition(event)
              onScroll(event)
            }}
            scrollEventThrottle              = { 16 }
            contentContainerStyle            = { contentContainerStyle }
            contentInset                     = { contentInset }
            zoomScale                        = { zoomScale }
            showsVerticalScrollIndicator     = { showsVerticalScrollIndicator }
            keyboardShouldPersistTaps        = { true }
            bounces                          = { false }
          >
            {content}
          </ScrollView>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  flex1: {
    flex: 1
  }
});

SmartScrollView.propTypes = {
  forceFocusField:              PropTypes.oneOf(PropTypes.number, PropTypes.string),
  scrollContainerStyle:         PropTypes.number,
  contentContainerStyle:        PropTypes.number,
  zoomScale:                    PropTypes.number,
  showsVerticalScrollIndicator: PropTypes.bool,
  contentInset:                 PropTypes.object,
  onScroll:                     PropTypes.func,
  onRefFocus:                   PropTypes.func,
};

SmartScrollView.defaultProps = {
  scrollContainerStyle:         styles.flex1,
  scrollPadding:                5,
  zoomScale:                    1,
  showsVerticalScrollIndicator: true,
  contentInset:                 {top: 0, left: 0, bottom: 0, right: 0},
  onScroll:                     () => {},
  onRefFocus:                   () => {}
};

export default SmartScrollView;

// import dismissKeyboard from 'dismissKeyboard';
// this._scrollTap            = this._scrollTap.bind(this);
// lastTap:         0
// _scrollTap () {
//   const {lastTap}  = this.state;
//   const currentTap = new Date().getTime();
//   console.log("tap")
//
//   if (currentTap - lastTap < 500) {
//     dismissKeyboard()
//   }
//
//   this.setState({
//     lastTap: currentTap
//   })
// }
<|endoftext|>


<commit_before>// @flow

const theme = {
  /*
   *  Colors
   */

  primary: 'rgb(0, 80, 131)',
  primaryLight1: 'rgb(187,14,61)',

  success: '#255425',

  secondary: 'rgb(23, 132, 172)',
  secondaryHighContrast: '#005b7c',

  textShadow: '0 0 7px rgba(144, 144, 144, 0.62)',
  white: '#fff',

  // greyscale

  greyScale7: 'rgb(107,98,98)',
  greyScale6: 'rgb(245,245,245)',
  greyScale5: 'rgb(222,222,222)',
  greyScale4: 'rgb(200, 200, 200)',
  greyScale3: 'rgb(144,144,144)',
  greyScale2: 'rgb(61,61,61)',
  greyScale1: 'rgb(36,36,36)',

  // impacts
  impacts: {
    HIGH: 'rgb(185, 36, 36)',
    MODERATE: '#634d0c',
    LOW: '#015c0a',
    MODIFIER: '#c94d18',
  },
  //
  // alerts

  alertInfo: 'rgb(237, 248, 251)',

  // table

  tableStripe: 'rgb(236, 243, 246)',

  /*
   *  Dimensions
   */

  facetsPanelWidth: '35rem',

  headerPosition: 'fixed',

  spacing: '2rem',
};

export const globalRules = `
  a:link {
    color: ${theme.primary};
    text-decoration: underline;
  }
`;

export default theme;
<commit_msg>💄 don't harcode underline in a:link<commit_after>// @flow

const theme = {
  /*
   *  Colors
   */

  primary: 'rgb(0, 80, 131)',
  primaryLight1: 'rgb(187,14,61)',

  success: '#255425',

  secondary: 'rgb(23, 132, 172)',
  secondaryHighContrast: '#005b7c',

  textShadow: '0 0 7px rgba(144, 144, 144, 0.62)',
  white: '#fff',

  // greyscale

  greyScale7: 'rgb(107,98,98)',
  greyScale6: 'rgb(245,245,245)',
  greyScale5: 'rgb(222,222,222)',
  greyScale4: 'rgb(200, 200, 200)',
  greyScale3: 'rgb(144,144,144)',
  greyScale2: 'rgb(61,61,61)',
  greyScale1: 'rgb(36,36,36)',

  // impacts
  impacts: {
    HIGH: 'rgb(185, 36, 36)',
    MODERATE: '#634d0c',
    LOW: '#015c0a',
    MODIFIER: '#c94d18',
  },
  //
  // alerts

  alertInfo: 'rgb(237, 248, 251)',

  // table

  tableStripe: 'rgb(236, 243, 246)',

  /*
   *  Dimensions
   */

  facetsPanelWidth: '35rem',

  headerPosition: 'fixed',

  spacing: '2rem',
};

export const globalRules = `
  a:link {
    color: ${theme.primary};
  }
`;

export default theme;
<|endoftext|>


<commit_before>/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

var contactSelectorAction = 'acls-contacts';
var defaultUserID = '';
var AclEditor = {
    userRightsHeight: null,
    userRightsWidth: null
};

var usersToSubscribe = [];

function addUser(userName, userID, type) {
    var result = false;
    if (!$(userID)) {
        var ul = $("userList");
        var lis = ul.childNodesWithTag("li");
        var newNode = nodeForUser(userName, userID, canSubscribeUsers);
        newNode.addClassName("normal-" + type);

        var count = lis.length - 1;
        var inserted = false;
        while (count > -1 && !inserted) {
            if ($(lis[count]).hasClassName("normal-user")) {
                if ((count+1) < lis.length)
                    ul.insertBefore(newNode, lis[count+1]);
                else
                    ul.appendChild(newNode);
                inserted = true;
            }
            else {
                count--;
            }
        }
        if (!inserted) {
            if (lis.length > 0)
                ul.insertBefore(newNode, lis[0]);
            else
                ul.appendChild(newNode);
        }

        var url = window.location.href;
        var elements = url.split("/");
        elements[elements.length-1] = ("addUserInAcls?uid="
                                       + userID);
        triggerAjaxRequest(elements.join("/"), addUserCallback, newNode);
        result = true;
    }
    return result;
}

function addUserCallback(http) {
    if (http.readyState == 4) {
        if (!isHttpStatus204(http.status)) {
            var node = http.callbackData;
            node.parentNode.removeChild(node);
        }
    }
}

function setEventsOnUserNode(node) {
    var n = $(node);
    n.observe("mousedown", listRowMouseDownHandler);
    n.observe("selectstart", listRowMouseDownHandler);
    n.observe("dblclick", onOpenUserRights);
    n.observe("click", onRowClick);

    var cbParents = n.childNodesWithTag("label");
    if (cbParents && cbParents.length) {
        var cbParent = $(cbParents[0]);
        var checkbox = cbParent.childNodesWithTag("input")[0];
        $(checkbox).observe("change", onSubscriptionChange);
    }
}

function onSubscriptionChange(event) {
    var li = this.parentNode.parentNode;
    var username = li.getAttribute("id");
    var idx = usersToSubscribe.indexOf(username);
    if (this.checked) {
        if (idx < 0)
            usersToSubscribe.push(username);
    } else {
        if (idx > -1)
            usersToSubscribe.splice(idx, 1);
    }
}

function nodeForUser(userName, userId, canSubscribe) {
    var node = createElement("li");
    node.id = userId;

    var span = createElement("span");
    span.addClassName("userFullName");
    span.appendChild(document.createTextNode(" " + userName));
    node.appendChild(span);

    if (canSubscribe) {
        var label = createElement("label");
        label.addClassName("subscriptionArea");
        var cb = createElement("input");
        cb.type = "checkbox";
        label.appendChild(cb);
        label.appendChild(document.createTextNode(_("Subscribe User")));
        node.appendChild(label);
    }

    setEventsOnUserNode(node);

    return node;
}

function onUserAdd(event) {
    openUserFolderSelector(null, "user");

    preventDefault(event);
}

function removeUserCallback(http) {
    var node = http.callbackData;

    if (http.readyState == 4
        && isHttpStatus204(http.status))
        node.parentNode.removeChild(node);
    else
        log("error deleting user: " + node.getAttribute("id"));
}

function onUserRemove(event) {
    var userList = $("userList");
    var nodes = userList.getSelectedRows();

    var url = window.location.href;
    var elements = url.split("/");
    elements[elements.length-1] = "removeUserFromAcls?uid=";
    var baseURL = elements.join("/");

    for (var i = 0; i < nodes.length; i++) {
        var userId = nodes[i].id;
        if (userId != defaultUserID && userId != "anonymous") {
            triggerAjaxRequest(baseURL + userId, removeUserCallback,
                               nodes[i]);
        }
    }
    preventDefault(event);
}

function subscribeToFolder(refreshCallback, refreshCallbackData) {
    var result = true;
    if (UserLogin != refreshCallbackData["folder"]) {
        result = addUser(refreshCallbackData["folderName"],
                         refreshCallbackData["folder"],
                         refreshCallbackData["type"]);
    }
    else
        refreshCallbackData["window"].alert(_("You cannot subscribe to a folder that you own!"));
    return result;
}

function openRightsForUserID(userID) {
    var url = window.location.href;
    var elements = url.split("/");
    elements[elements.length-1] = "userRights?uid=" + userID;

    var height = AclEditor.userRightsHeight;
    if (userID == "anonymous") {
        height -= 42;
        if (CurrentModule() == "Contacts") {
            height -= 21;
        }
    }
    window.open(elements.join("/"), "",
                "width=" + AclEditor.userRightsWidth
                + ",height=" + height
                + ",resizable=0,scrollbars=0,toolbar=0,"
                + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
}

function openRightsForUser(button) {
    var nodes = $("userList").getSelectedRows();
    if (nodes.length > 0)
        openRightsForUserID(nodes[0].getAttribute("id"));

    return false;
}

function onOpenUserRights(event) {
    openRightsForUser();
    preventDefault(event);
}

function onAclLoadHandler() {
    var ul = $("userList");
    var lis = ul.childNodesWithTag("li");
    for (var i = 0; i < lis.length; i++)
        setEventsOnUserNode(lis[i]);

    var input = $("defaultUserID");
    if (input) {
        defaultUserID = $("defaultUserID").value;
        var userNode = nodeForUser(_("Any Authenticated User"),
                                   defaultUserID);
        userNode.addClassName("any-user");
        userNode.setAttribute("title",
                              _("Any user not listed above"));
        ul.appendChild(userNode);
    }
    if (isPublicAccessEnabled && CurrentModule() != "Mail") {
        userNode = nodeForUser(_("Public Access"), "anonymous");
        userNode.addClassName("anonymous-user");
        userNode.setAttribute("title",
                              _("Anybody accessing this resource from the public area"));
        ul.appendChild(userNode);
    }

    var buttonArea = $("userSelectorButtons");
    if (buttonArea) {
        var buttons = buttonArea.childNodesWithTag("a");
        $("aclAddUser").stopObserving ("click");
        $("aclDeleteUser").stopObserving ("click");
        $("aclAddUser").observe("mousedown", onUserAdd);
        $("aclDeleteUser").observe("mousedown", onUserRemove);
    }

    AclEditor['userRightsHeight'] = window.opener.getUsersRightsWindowHeight();
    AclEditor['userRightsWidth'] = window.opener.getUsersRightsWindowWidth();

    Event.observe(window, "unload", onAclCloseHandler);
}

function onAclCloseHandler(event) {
    if (usersToSubscribe.length) {
        var url = (URLForFolderID($("folderID").value)
                   + "/subscribeUsers?uids=" + usersToSubscribe.join(","));
        new Ajax.Request(url, {
            asynchronous: false,
            method: 'get',
            onFailure: function(transport) {
                    log("Can't subscribe users: " + transport.status);
                }
        });
    }

    return true;
}

document.observe("dom:loaded", onAclLoadHandler);
<commit_msg>Fix URL encoding of user id in UIxAclEditor.js<commit_after>/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

var contactSelectorAction = 'acls-contacts';
var defaultUserID = '';
var AclEditor = {
    userRightsHeight: null,
    userRightsWidth: null
};

var usersToSubscribe = [];

function addUser(userName, userID, type) {
    var result = false;
    if (!$(userID)) {
        var ul = $("userList");
        var lis = ul.childNodesWithTag("li");
        var newNode = nodeForUser(userName, userID, canSubscribeUsers);
        newNode.addClassName("normal-" + type);

        var count = lis.length - 1;
        var inserted = false;
        while (count > -1 && !inserted) {
            if ($(lis[count]).hasClassName("normal-user")) {
                if ((count+1) < lis.length)
                    ul.insertBefore(newNode, lis[count+1]);
                else
                    ul.appendChild(newNode);
                inserted = true;
            }
            else {
                count--;
            }
        }
        if (!inserted) {
            if (lis.length > 0)
                ul.insertBefore(newNode, lis[0]);
            else
                ul.appendChild(newNode);
        }

        var url = window.location.href;
        var elements = url.split("/");
        elements[elements.length-1] = ("addUserInAcls?uid="
                                       + encodeURIComponent(userID));
        triggerAjaxRequest(elements.join("/"), addUserCallback, newNode);
        result = true;
    }
    return result;
}

function addUserCallback(http) {
    if (http.readyState == 4) {
        if (!isHttpStatus204(http.status)) {
            var node = http.callbackData;
            node.parentNode.removeChild(node);
        }
    }
}

function setEventsOnUserNode(node) {
    var n = $(node);
    n.observe("mousedown", listRowMouseDownHandler);
    n.observe("selectstart", listRowMouseDownHandler);
    n.observe("dblclick", onOpenUserRights);
    n.observe("click", onRowClick);

    var cbParents = n.childNodesWithTag("label");
    if (cbParents && cbParents.length) {
        var cbParent = $(cbParents[0]);
        var checkbox = cbParent.childNodesWithTag("input")[0];
        $(checkbox).observe("change", onSubscriptionChange);
    }
}

function onSubscriptionChange(event) {
    var li = this.parentNode.parentNode;
    var username = li.getAttribute("id");
    var idx = usersToSubscribe.indexOf(username);
    if (this.checked) {
        if (idx < 0)
            usersToSubscribe.push(username);
    } else {
        if (idx > -1)
            usersToSubscribe.splice(idx, 1);
    }
}

function nodeForUser(userName, userId, canSubscribe) {
    var node = createElement("li");
    node.id = userId;

    var span = createElement("span");
    span.addClassName("userFullName");
    span.appendChild(document.createTextNode(" " + userName));
    node.appendChild(span);

    if (canSubscribe) {
        var label = createElement("label");
        label.addClassName("subscriptionArea");
        var cb = createElement("input");
        cb.type = "checkbox";
        label.appendChild(cb);
        label.appendChild(document.createTextNode(_("Subscribe User")));
        node.appendChild(label);
    }

    setEventsOnUserNode(node);

    return node;
}

function onUserAdd(event) {
    openUserFolderSelector(null, "user");

    preventDefault(event);
}

function removeUserCallback(http) {
    var node = http.callbackData;

    if (http.readyState == 4
        && isHttpStatus204(http.status))
        node.parentNode.removeChild(node);
    else
        log("error deleting user: " + node.getAttribute("id"));
}

function onUserRemove(event) {
    var userList = $("userList");
    var nodes = userList.getSelectedRows();

    var url = window.location.href;
    var elements = url.split("/");
    elements[elements.length-1] = "removeUserFromAcls?uid=";
    var baseURL = elements.join("/");

    for (var i = 0; i < nodes.length; i++) {
        var userId = nodes[i].id;
        if (userId != defaultUserID && userId != "anonymous") {
            triggerAjaxRequest(baseURL + userId, removeUserCallback,
                               nodes[i]);
        }
    }
    preventDefault(event);
}

function subscribeToFolder(refreshCallback, refreshCallbackData) {
    var result = true;
    if (UserLogin != refreshCallbackData["folder"]) {
        result = addUser(refreshCallbackData["folderName"],
                         refreshCallbackData["folder"],
                         refreshCallbackData["type"]);
    }
    else
        refreshCallbackData["window"].alert(_("You cannot subscribe to a folder that you own!"));
    return result;
}

function openRightsForUserID(userID) {
    var url = window.location.href;
    var elements = url.split("/");
    elements[elements.length-1] = "userRights?uid=" + userID;

    var height = AclEditor.userRightsHeight;
    if (userID == "anonymous") {
        height -= 42;
        if (CurrentModule() == "Contacts") {
            height -= 21;
        }
    }
    window.open(elements.join("/"), "",
                "width=" + AclEditor.userRightsWidth
                + ",height=" + height
                + ",resizable=0,scrollbars=0,toolbar=0,"
                + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
}

function openRightsForUser(button) {
    var nodes = $("userList").getSelectedRows();
    if (nodes.length > 0)
        openRightsForUserID(nodes[0].getAttribute("id"));

    return false;
}

function onOpenUserRights(event) {
    openRightsForUser();
    preventDefault(event);
}

function onAclLoadHandler() {
    var ul = $("userList");
    var lis = ul.childNodesWithTag("li");
    for (var i = 0; i < lis.length; i++)
        setEventsOnUserNode(lis[i]);

    var input = $("defaultUserID");
    if (input) {
        defaultUserID = $("defaultUserID").value;
        var userNode = nodeForUser(_("Any Authenticated User"),
                                   defaultUserID);
        userNode.addClassName("any-user");
        userNode.setAttribute("title",
                              _("Any user not listed above"));
        ul.appendChild(userNode);
    }
    if (isPublicAccessEnabled && CurrentModule() != "Mail") {
        userNode = nodeForUser(_("Public Access"), "anonymous");
        userNode.addClassName("anonymous-user");
        userNode.setAttribute("title",
                              _("Anybody accessing this resource from the public area"));
        ul.appendChild(userNode);
    }

    var buttonArea = $("userSelectorButtons");
    if (buttonArea) {
        var buttons = buttonArea.childNodesWithTag("a");
        $("aclAddUser").stopObserving ("click");
        $("aclDeleteUser").stopObserving ("click");
        $("aclAddUser").observe("mousedown", onUserAdd);
        $("aclDeleteUser").observe("mousedown", onUserRemove);
    }

    AclEditor['userRightsHeight'] = window.opener.getUsersRightsWindowHeight();
    AclEditor['userRightsWidth'] = window.opener.getUsersRightsWindowWidth();

    Event.observe(window, "unload", onAclCloseHandler);
}

function onAclCloseHandler(event) {
    if (usersToSubscribe.length) {
        var url = (URLForFolderID($("folderID").value)
                   + "/subscribeUsers?uids=" + usersToSubscribe.join(","));
        new Ajax.Request(url, {
            asynchronous: false,
            method: 'get',
            onFailure: function(transport) {
                    log("Can't subscribe users: " + transport.status);
                }
        });
    }

    return true;
}

document.observe("dom:loaded", onAclLoadHandler);
<|endoftext|>


<commit_before>// ----------------------------------------------------------------------- //
// The Registration Container                                              //
// This Container Component links the Redux store to the Registration Page //
// ----------------------------------------------------------------------- //

/**
 * React-Redux and React-Router Imports
 * @import connect a function that passes the state down to the specified
 *                 component as props
 * @import browserHistory the urls that will be rendered in the browser
 **/
import { connect } from 'react-redux';
import { browserHistory } from 'react-router';

//Registration Page Presentational Component
import RegistrationPage from '../pages/RegistrationPage';

//Redux actions for fetching data from the redux store and changing ui state
import {
  incrementCurrentTutotial,
  decrementCurrentTutotial,
  setCurrentTutorial,
  setActiveState,
  setInactiveState,
  setWaitingState,
  forkPortfolio,
  editTutorial} from '../../redux/actions/registrationActions';
import {
  currentScholar,
  fetchScholars} from '../../redux/actions/communityActions';

/**
 * a function declaration to be called by React-Redux
 * here we specify what parts of the application state to share with the Registration Page
 * @param state the application state as passed in by Redux
 * @return object.tutorialsList the list of tutorial ids
 * @return object.tutorialsById an object mapping tutorial ids to tutorial data
 * @return object.currentTutorial the id of the tutorial to be rendered
 * @return object.isButtonActive boolean indicating whether the user can moves on to the next tutorial
 * @return object.currentUser the id of the user as saved in the browser sessions
 * @return object.username the gitlan username of the user going through registration
 **/
const mapStateToProps = (state) => {
  return {
    currentUser: state.community.get('currentlyLoggedIn'),
    tutorialsList: state.registration.get('tutorialsList').toArray(),
    tutorialsById: state.registration.get('tutorialsById').toJSON(),
    currentTutorial: state.registration.get('currentTutorial'),
    isButtonActive: state.registration.get('isButtonActive'),
    username: state.registration.get('username'),
    currentState: state.registration.get('currentState')
  }
}

/**
 * a function declaration to be called  by React-Redux
 * here we define functions to be passed to the Registration Page as props
 * these functions dispatch Redux actions to update the application state
 * @param dispatch a function that can dispatch actions to the Redux store
 * @return object.mount fetches data from the redux store before rendering
 * @return object.incrementStep increments the current visible tutorial
 * @return object.decrementStep decrements the current visible tutorial
 * @return object.onButtonClick handles the button click in each tutorial
 **/
const mapDispatchToProps = (dispatch) => {
  return {
    mount: (id) => {
      return () => {
        dispatch(setCurrentTutorial(parseInt(id, 10)));
        dispatch(currentScholar((res) => {return res}));
        dispatch(fetchScholars());
      }
    },
    incrementStep: () => {
      dispatch(incrementCurrentTutotial());
      dispatch(setInactiveState());
    },
    decrementStep: () => {
      dispatch(decrementCurrentTutotial());
    },
    onButtonClick: (user_id) => {
      console.log('in onButtonClick');
      return (id, a) => {
        console.log('Im in onButtonClick');
        console.log('id ', id);
        switch (id) {
          case 2:
          case 3:
          case 4:
          case 6:
          case 8:
            console.log('about to run this');
            window.open(a);
            dispatch(setActiveState());
            //window.location.replace('/build/register/'+(id+1));
            return

          case 1:
          case 7:
          case 9:
            window.location.replace(a);
            dispatch(setActiveState());
            return

          case 5:
            dispatch(setWaitingState());
            dispatch(forkPortfolio(user_id, function(username) {
              console.log('username ', username);
              dispatch(editTutorial('6', ['Success! You now have a repository for your personal LIME portfolio called lime-portfolio. Your personal portfolio will be viewable in roughly 15 minutes at '+username+'.gitlab.io/lime-portfolio. You can customize it and make it your own by editing the repo.'], 'Customize my portfolio!', 'https://gitlab.com/'+username+'/lime-portfolio'));
              dispatch(incrementCurrentTutotial());
              browserHistory.push('/build/register/6');
              dispatch(setActiveState());
            }));
            return

          default:
            return
        }
      }
    }
  }
}

/**
 * a function declaration to be called  by React-Redux
 * this function can be used to use the state data fetched by mapStateToProps
 * with the defined functions in mapDispatchToProps
 * @param stateProps all the props taken directly from the state
 * @param dispatchProps all the functions defined above to dispatch events
 * @param ownProps all the props passed into the container from parent elements (router)
 * @return the mixture of these two props to be passed into the presentation component
 **/
const mergeProps = (stateProps, dispatchProps, ownProps) => {
  return {
    currentUser: stateProps.currentUser,
    username: stateProps.username,
    tutorialsList: stateProps.tutorialsList,
    tutorialsById: stateProps.tutorialsById,
    currentTutorial: stateProps.currentTutorial,
    isButtonActive: stateProps.isButtonActive,
    incrementStep: dispatchProps.incrementStep,
    decrementStep: dispatchProps.decrementStep,
    mount: dispatchProps.mount(ownProps.routeParams.id, stateProps.username),
    onButtonClick: dispatchProps.onButtonClick(stateProps.currentUser),
    currentState: stateProps.currentState
  }
}

/**
 * Here we use the react-redux connect function to define a React Component with the
 * state defined in the function declarations above. This Container Componenet passes
 * the entire state to RegistrationPage as props
 **/
const RegistrationContainer = connect(
  mapStateToProps,
  mapDispatchToProps,
  mergeProps
)(RegistrationPage)

export default RegistrationContainer;<commit_msg>Remove first next step button<commit_after>// ----------------------------------------------------------------------- //
// The Registration Container                                              //
// This Container Component links the Redux store to the Registration Page //
// ----------------------------------------------------------------------- //

/**
 * React-Redux and React-Router Imports
 * @import connect a function that passes the state down to the specified
 *                 component as props
 * @import browserHistory the urls that will be rendered in the browser
 **/
import { connect } from 'react-redux';
import { browserHistory } from 'react-router';

//Registration Page Presentational Component
import RegistrationPage from '../pages/RegistrationPage';

//Redux actions for fetching data from the redux store and changing ui state
import {
  incrementCurrentTutotial,
  decrementCurrentTutotial,
  setCurrentTutorial,
  setActiveState,
  setInactiveState,
  setWaitingState,
  forkPortfolio,
  editTutorial} from '../../redux/actions/registrationActions';
import {
  currentScholar,
  fetchScholars} from '../../redux/actions/communityActions';

/**
 * a function declaration to be called by React-Redux
 * here we specify what parts of the application state to share with the Registration Page
 * @param state the application state as passed in by Redux
 * @return object.tutorialsList the list of tutorial ids
 * @return object.tutorialsById an object mapping tutorial ids to tutorial data
 * @return object.currentTutorial the id of the tutorial to be rendered
 * @return object.isButtonActive boolean indicating whether the user can moves on to the next tutorial
 * @return object.currentUser the id of the user as saved in the browser sessions
 * @return object.username the gitlan username of the user going through registration
 **/
const mapStateToProps = (state) => {
  return {
    currentUser: state.community.get('currentlyLoggedIn'),
    tutorialsList: state.registration.get('tutorialsList').toArray(),
    tutorialsById: state.registration.get('tutorialsById').toJSON(),
    currentTutorial: state.registration.get('currentTutorial'),
    isButtonActive: state.registration.get('isButtonActive'),
    username: state.registration.get('username'),
    currentState: state.registration.get('currentState')
  }
}

/**
 * a function declaration to be called  by React-Redux
 * here we define functions to be passed to the Registration Page as props
 * these functions dispatch Redux actions to update the application state
 * @param dispatch a function that can dispatch actions to the Redux store
 * @return object.mount fetches data from the redux store before rendering
 * @return object.incrementStep increments the current visible tutorial
 * @return object.decrementStep decrements the current visible tutorial
 * @return object.onButtonClick handles the button click in each tutorial
 **/
const mapDispatchToProps = (dispatch) => {
  return {
    mount: (id) => {
      return () => {
        dispatch(setCurrentTutorial(parseInt(id, 10)));
        dispatch(currentScholar((res) => {return res}));
        dispatch(fetchScholars());
      }
    },
    incrementStep: () => {
      dispatch(incrementCurrentTutotial());
      dispatch(setInactiveState());
    },
    decrementStep: () => {
      dispatch(decrementCurrentTutotial());
    },
    onButtonClick: (user_id) => {
      console.log('in onButtonClick');
      return (id, a) => {
        console.log('Im in onButtonClick');
        console.log('id ', id);
        switch (id) {
          case 2:
          case 3:
          case 4:
          case 6:
          case 8:
            console.log('about to run this');
            window.open(a);
            dispatch(setActiveState());
            //window.location.replace('/build/register/'+(id+1));
            return

          case 1:
          case 9:
            window.location.replace(a);
            return

          case 7:
            window.location.replace(a);
            dispatch(setActiveState());
            return

          case 5:
            dispatch(setWaitingState());
            dispatch(forkPortfolio(user_id, function(username) {
              console.log('username ', username);
              dispatch(editTutorial('6', ['Success! You now have a repository for your personal LIME portfolio called lime-portfolio. Your personal portfolio will be viewable in roughly 15 minutes at '+username+'.gitlab.io/lime-portfolio. You can customize it and make it your own by editing the repo.'], 'Customize my portfolio!', 'https://gitlab.com/'+username+'/lime-portfolio'));
              dispatch(incrementCurrentTutotial());
              browserHistory.push('/build/register/6');
              dispatch(setActiveState());
            }));
            return

          default:
            return
        }
      }
    }
  }
}

/**
 * a function declaration to be called  by React-Redux
 * this function can be used to use the state data fetched by mapStateToProps
 * with the defined functions in mapDispatchToProps
 * @param stateProps all the props taken directly from the state
 * @param dispatchProps all the functions defined above to dispatch events
 * @param ownProps all the props passed into the container from parent elements (router)
 * @return the mixture of these two props to be passed into the presentation component
 **/
const mergeProps = (stateProps, dispatchProps, ownProps) => {
  return {
    currentUser: stateProps.currentUser,
    username: stateProps.username,
    tutorialsList: stateProps.tutorialsList,
    tutorialsById: stateProps.tutorialsById,
    currentTutorial: stateProps.currentTutorial,
    isButtonActive: stateProps.isButtonActive,
    incrementStep: dispatchProps.incrementStep,
    decrementStep: dispatchProps.decrementStep,
    mount: dispatchProps.mount(ownProps.routeParams.id, stateProps.username),
    onButtonClick: dispatchProps.onButtonClick(stateProps.currentUser),
    currentState: stateProps.currentState
  }
}

/**
 * Here we use the react-redux connect function to define a React Component with the
 * state defined in the function declarations above. This Container Componenet passes
 * the entire state to RegistrationPage as props
 **/
const RegistrationContainer = connect(
  mapStateToProps,
  mapDispatchToProps,
  mergeProps
)(RegistrationPage)

export default RegistrationContainer;<|endoftext|>


<commit_before>/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactErrorUtils
 * @flow
 */

'use strict';

let caughtError = null;

/**
 * Call a function while guarding against errors that happens within it.
 * Returns an error if it throws, otherwise null.
 *
 * @param {String} name of the guard to use for logging or debugging
 * @param {Function} func The function to invoke
 * @param {*} context The context to use when calling the function
 * @param {...*} args Arguments for function
 */
const ReactErrorUtils = {
  invokeGuardedCallback: function<A, B, C, D, E, F, Context>(
    name: string | null,
    func: (a: A, b: B, c: C, d: D, e: E, f: F) => void,
    context: Context,
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
  ): Error | null {
    const funcArgs = Array.prototype.slice.call(arguments, 3);
    try {
      func.apply(context, funcArgs);
    } catch (error) {
      return error;
    }
    return null;
  },

  /**
   * Same as invokeGuardedCallback, but instead of returning an error, it stores
   * it in a global so it can be rethrown by `rethrowCaughtError` later.
   *
   * @param {String} name of the guard to use for logging or debugging
   * @param {Function} func The function to invoke
   * @param {*} context The context to use when calling the function
   * @param {...*} args Arguments for function
   */
  invokeGuardedCallbackAndCatchFirstError: function<A, B, C, D, E, F, Context>(
    name: string | null,
    func: (a: A, b: B, c: C, d: D, e: E, f: F) => void,
    context: Context,
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
  ): void {
    const error = ReactErrorUtils.invokeGuardedCallback.apply(this, arguments);
    if (error !== null && caughtError === null) {
      caughtError = error;
    }
  },

  /**
   * During execution of guarded functions we will capture the first error which
   * we will rethrow to be handled by the top level error handler.
   */
  rethrowCaughtError: function() {
    if (caughtError) {
      const error = caughtError;
      caughtError = null;
      throw error;
    }
  },
};

if (__DEV__) {
  /**
   * To help development we can get better devtools integration by simulating a
   * real browser event.
   */
  if (
    typeof window !== 'undefined' &&
    typeof window.dispatchEvent === 'function' &&
    typeof document !== 'undefined' &&
    typeof document.createEvent === 'function'
  ) {
    const fakeNode = document.createElement('react');
    let depth = 0;

    ReactErrorUtils.invokeGuardedCallback = function(
      name,
      func,
      context,
      a,
      b,
      c,
      d,
      e,
      f,
    ) {
      depth++;
      const thisDepth = depth;
      const funcArgs = Array.prototype.slice.call(arguments, 3);
      const boundFunc = function() {
        func.apply(context, funcArgs);
      };
      let fakeEventError = null;
      const onFakeEventError = function(event) {
        // Don't capture nested errors
        if (depth === thisDepth) {
          fakeEventError = event.error;
        }
      };
      const evtType = `react-${name ? name : 'invokeguardedcallback'}-${depth}`;
      window.addEventListener('error', onFakeEventError);
      fakeNode.addEventListener(evtType, boundFunc, false);
      const evt = document.createEvent('Event');
      evt.initEvent(evtType, false, false);
      fakeNode.dispatchEvent(evt);
      fakeNode.removeEventListener(evtType, boundFunc, false);
      window.removeEventListener('error', onFakeEventError);
      depth--;
      return fakeEventError;
    };
  }
}

module.exports = ReactErrorUtils;
<commit_msg>Add dynamic injection to ReactErrorUtils (#9246)<commit_after>/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactErrorUtils
 * @flow
 */

'use strict';

const invariant = require('invariant');

let caughtError = null;

/**
 * Call a function while guarding against errors that happens within it.
 * Returns an error if it throws, otherwise null.
 *
 * @param {String} name of the guard to use for logging or debugging
 * @param {Function} func The function to invoke
 * @param {*} context The context to use when calling the function
 * @param {...*} args Arguments for function
 */
const ReactErrorUtils = {
  injection: {
    injectErrorUtils(injectedErrorUtils: Object) {
      invariant(
        typeof injectedErrorUtils.invokeGuardedCallback === 'function',
        'Injected invokeGuardedCallback() must be a function.',
      );
      invariant(
        typeof injectedErrorUtils.rethrowCaughtError === 'function',
        'Injected rethrowCaughtError() must be a function.',
      );
      ReactErrorUtils.invokeGuardedCallback = injectedErrorUtils.invokeGuardedCallback;
      ReactErrorUtils.rethrowCaughtError = injectedErrorUtils.rethrowCaughtError;
    },
  },

  invokeGuardedCallback: function<A, B, C, D, E, F, Context>(
    name: string | null,
    func: (a: A, b: B, c: C, d: D, e: E, f: F) => void,
    context: Context,
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
  ): Error | null {
    const funcArgs = Array.prototype.slice.call(arguments, 3);
    try {
      func.apply(context, funcArgs);
    } catch (error) {
      return error;
    }
    return null;
  },

  /**
   * Same as invokeGuardedCallback, but instead of returning an error, it stores
   * it in a global so it can be rethrown by `rethrowCaughtError` later.
   *
   * @param {String} name of the guard to use for logging or debugging
   * @param {Function} func The function to invoke
   * @param {*} context The context to use when calling the function
   * @param {...*} args Arguments for function
   */
  invokeGuardedCallbackAndCatchFirstError: function<A, B, C, D, E, F, Context>(
    name: string | null,
    func: (a: A, b: B, c: C, d: D, e: E, f: F) => void,
    context: Context,
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
  ): void {
    const error = ReactErrorUtils.invokeGuardedCallback.apply(this, arguments);
    if (error !== null && caughtError === null) {
      caughtError = error;
    }
  },

  /**
   * During execution of guarded functions we will capture the first error which
   * we will rethrow to be handled by the top level error handler.
   */
  rethrowCaughtError: function() {
    if (caughtError) {
      const error = caughtError;
      caughtError = null;
      throw error;
    }
  },
};

if (__DEV__) {
  /**
   * To help development we can get better devtools integration by simulating a
   * real browser event.
   */
  if (
    typeof window !== 'undefined' &&
    typeof window.dispatchEvent === 'function' &&
    typeof document !== 'undefined' &&
    typeof document.createEvent === 'function'
  ) {
    const fakeNode = document.createElement('react');
    let depth = 0;

    ReactErrorUtils.invokeGuardedCallback = function(
      name,
      func,
      context,
      a,
      b,
      c,
      d,
      e,
      f,
    ) {
      depth++;
      const thisDepth = depth;
      const funcArgs = Array.prototype.slice.call(arguments, 3);
      const boundFunc = function() {
        func.apply(context, funcArgs);
      };
      let fakeEventError = null;
      const onFakeEventError = function(event) {
        // Don't capture nested errors
        if (depth === thisDepth) {
          fakeEventError = event.error;
        }
      };
      const evtType = `react-${name ? name : 'invokeguardedcallback'}-${depth}`;
      window.addEventListener('error', onFakeEventError);
      fakeNode.addEventListener(evtType, boundFunc, false);
      const evt = document.createEvent('Event');
      evt.initEvent(evtType, false, false);
      fakeNode.dispatchEvent(evt);
      fakeNode.removeEventListener(evtType, boundFunc, false);
      window.removeEventListener('error', onFakeEventError);
      depth--;
      return fakeEventError;
    };
  }
}

module.exports = ReactErrorUtils;
<|endoftext|>


<commit_before>import React from 'react'
import {connect} from 'react-redux'
import classnames from 'classnames'
import {loadPlayer} from './services/playerOverview/actions'
import {CLASSINDEX_TO_NAME, JUMP_CLASSES} from 'root/constants/TFClasses'

import TimeAgo from 'react-timeago'
import DocumentTitle from 'react-document-title'
import {Row, Col, Tabs, Tab, Table} from 'react-bootstrap'
import SteamAvatar from 'root/components/SteamAvatar'
import Throbber from 'root/components/Throbber'
import PlayerOverviewStats from './components/PlayerOverviewStats'

import './styles.styl'

function getFormattedDate(date) {
  var year = date.getFullYear()
  var month = (1 + date.getMonth()).toString()
  month = month.length > 1 ? month : '0' + month
  var day = date.getDate().toString()
  day = day.length > 1 ? day : '0' + day
  return month + '/' + day + '/' + year
}

export class PlayerOverview extends React.Component {
  componentDidMount() {
    this.props.loadPlayer(this.props.params.id)
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.params.id !== this.props.params.id) {
      this.props.loadPlayer(nextProps.params.id)
    }
  }

  renderClassRankStats(playerClass) {
    const cri = this.props.data.class_rank_info[playerClass]
    return (

           {`${Math.floor(cri.points)} Points`}

           {`Rank ${cri.rank} (5th in United States)`}

    )
  }

  renderChatRank() {
    const {data} = this.props
    const cri = data.class_rank_info
    const soldier = cri[3]
    const demoman = cri[4]
    let title
    let tfClass
    let rank
    if (soldier.rank < demoman.rank) {
      title = soldier.title
      tfClass = 'soldier'
      rank = soldier.rank
    }
    else {
      title = demoman.title
      tfClass = 'demoman'
      rank = demoman.rank
    }
    return (

        <span className={`tf-icon sm ${tfClass}`}/>

          {title}

          (Rank {rank})

    )
  }

  render() {
    if (!this.props.data || this.props.fetching) {
      return
<Throbber />

    }
    const data = this.props.data
    const pi = data.player_info
    const firstSeenDate = new Date(pi.first_seen * 1000)
    return (
      <DocumentTitle title={`Tempus - ${pi.name}`}>

                  <SteamAvatar steamID={pi.steamid} size="mediumlarge" />

                  Online <TimeAgo date={pi.last_seen * 1000} />

                  Joined {getFormattedDate(firstSeenDate)}

                    {pi.name}

                {this.renderChatRank()}

              <Row>
                {JUMP_CLASSES.map(pc => {
                  const playerClassName = CLASSINDEX_TO_NAME[pc]
                  const icon =
                  return (
                    <PlayerOverviewStats leaderboardURL={`/ranks/${playerClassName.toLowerCase()}`}
                                         leaderboardTitle={playerClassName}
                                         icon={icon}
                                         rankInfo={data.class_rank_info[pc]}
                                         countryRankInfo={data.country_class_rank_info[pc]}
                                         playerInfo={data.player_info}
                                         prStats={data.pr_stats}
                                         wrStats={data.wr_stats}
                                         topStats={data.top_stats}
                                         zoneCount={data.zone_count} />
                  )
                })}
                <PlayerOverviewStats leaderboardURL="/ranks/overall"
                                     leaderboardTitle={'Overall'}
                                     icon={}
                                     rankInfo={data.rank_info}
                                     countryRankInfo={data.country_rank_info}
                                     playerInfo={data.player_info}
                                     prStats={data.pr_stats}
                                     wrStats={data.wr_stats}
                                     topStats={data.top_stats}
                                     zoneCount={data.zone_count} />
              </Row>

              <Tabs className="player-overview-tabs">
                <Tab title="Soldier" eventKey="1">

                      World Records (placeholder)

                      Incomplete Maps (placeholder)

                </Tab>
                <Tab title="Demoman" eventKey="2">
                </Tab>
              </Tabs>

      </DocumentTitle>
    )
  }
}

function mapStateToProps(state) {
  const {playerOverview} = state
  const {fetching, error, data} = playerOverview
  return {fetching, error, data: data ? data.toJS() : data}
}

export default connect(
  mapStateToProps,
  {loadPlayer}
)(PlayerOverview)
<commit_msg>Fix loading player overview page.<commit_after>import React from 'react'
import {connect} from 'react-redux'
import classnames from 'classnames'
import {loadPlayer} from './services/playerOverview/actions'
import {CLASSINDEX_TO_NAME, JUMP_CLASSES} from 'root/constants/TFClasses'

import TimeAgo from 'react-timeago'
import DocumentTitle from 'react-document-title'
import {Row, Col, Tabs, Tab, Table} from 'react-bootstrap'
import SteamAvatar from 'root/components/SteamAvatar'
import Throbber from 'root/components/Throbber'
import PlayerOverviewStats from './components/PlayerOverviewStats'

import './styles.styl'

function getFormattedDate(date) {
  var year = date.getFullYear()
  var month = (1 + date.getMonth()).toString()
  month = month.length > 1 ? month : '0' + month
  var day = date.getDate().toString()
  day = day.length > 1 ? day : '0' + day
  return month + '/' + day + '/' + year
}

export class PlayerOverview extends React.Component {
  componentWillMount() {
    console.log(this.props)
    this.props.loadPlayer(this.props.match.params.id)
  }

  componentWillReceiveProps(nextProps) {
    console.log(this.props)
    if (nextProps.match.params.id !== this.props.match.params.id) {
      this.props.loadPlayer(nextProps.match.params.id)
    }
  }

  renderClassRankStats(playerClass) {
    const cri = this.props.data.class_rank_info[playerClass]
    return (

           {`${Math.floor(cri.points)} Points`}

           {`Rank ${cri.rank} (5th in United States)`}

    )
  }

  renderChatRank() {
    const {data} = this.props
    const cri = data.class_rank_info
    const soldier = cri[3]
    const demoman = cri[4]
    let title
    let tfClass
    let rank
    if (soldier.rank < demoman.rank) {
      title = soldier.title
      tfClass = 'soldier'
      rank = soldier.rank
    }
    else {
      title = demoman.title
      tfClass = 'demoman'
      rank = demoman.rank
    }
    return (

        <span className={`tf-icon sm ${tfClass}`}/>

          {title}

          (Rank {rank})

    )
  }

  render() {
    if (!this.props.data || this.props.fetching) {
      return
<Throbber />

    }
    const data = this.props.data
    const pi = data.player_info
    const firstSeenDate = new Date(pi.first_seen * 1000)
    return (
      <DocumentTitle title={`Tempus - ${pi.name}`}>

                  <SteamAvatar steamID={pi.steamid} size="mediumlarge" />

                  Online <TimeAgo date={pi.last_seen * 1000} />

                  Joined {getFormattedDate(firstSeenDate)}

                    {pi.name}

                {this.renderChatRank()}

              <Row>
                {JUMP_CLASSES.map(pc => {
                  const playerClassName = CLASSINDEX_TO_NAME[pc]
                  const icon =
                  return (
                    <PlayerOverviewStats leaderboardURL={`/ranks/${playerClassName.toLowerCase()}`}
                                         leaderboardTitle={playerClassName}
                                         icon={icon}
                                         rankInfo={data.class_rank_info[pc]}
                                         countryRankInfo={data.country_class_rank_info[pc]}
                                         playerInfo={data.player_info}
                                         prStats={data.pr_stats}
                                         wrStats={data.wr_stats}
                                         topStats={data.top_stats}
                                         zoneCount={data.zone_count} />
                  )
                })}
                <PlayerOverviewStats leaderboardURL="/ranks/overall"
                                     leaderboardTitle={'Overall'}
                                     icon={}
                                     rankInfo={data.rank_info}
                                     countryRankInfo={data.country_rank_info}
                                     playerInfo={data.player_info}
                                     prStats={data.pr_stats}
                                     wrStats={data.wr_stats}
                                     topStats={data.top_stats}
                                     zoneCount={data.zone_count} />
              </Row>

              <Tabs className="player-overview-tabs">
                <Tab title="Soldier" eventKey="1">

                      World Records (placeholder)

                      Incomplete Maps (placeholder)

                </Tab>
                <Tab title="Demoman" eventKey="2">
                </Tab>
              </Tabs>

      </DocumentTitle>
    )
  }
}

function mapStateToProps(state) {
  const {playerOverview} = state
  const {fetching, error, data} = playerOverview
  return {fetching, error, data: data ? data.toJS() : data}
}

export default connect(
  mapStateToProps,
  {loadPlayer}
)(PlayerOverview)
<|endoftext|>