<commit_before>var fs = require('fs');
var http = require('http');
var request = require('request');
var apputil = require("./util.js");
var db = require('./db.js');
var Promise = require('bluebird');

var sortObject = function (o) {
    var sorted = {},
    key, a = [];
    for (key in o) {
        if (o.hasOwnProperty(key)) {
            a.push(key);
        }
    }
    a.sort();
    for (key = 0; key < a.length; key++) {
        sorted[a[key]] = o[a[key]];
    }
    return sorted;
};

// Look for segments of a message that have an exclamation followed by one or
// more alphaneumeric characters
var parseMessage = function(message, callback) {
	var pattern = /\!([a-zA-Z0-9]+)/g;
	var matches = message.match(pattern);

	if (matches) {
		for (var i = 0; i < matches.length; i++) {
			matches[i] = matches[i].replace(/\!/g, '');
		}
	}
	else {
		// if no matches are found, return an empty array
		// this makes it easier for the function's clients to handle because they
		// do not have to worry about nulls.
		callback(null, []);
	}
	callback(null, matches);
};

var pickRandom = function(cmdObject) {
	var rnged = apputil.shuffle(cmdObject.value);
	return rnged[0];
}

var processCommands = function(inputCommands, commands, callback) {
	var replies = [];
	if (inputCommands){
		for (var i = 0; i < inputCommands.length; i++) {
			var result = commands.find(o => o.name === inputCommands[i].toLowerCase());
			if (result) {
				var reply;
				if (result.selectRandom) {
					reply = pickRandom(result);
				} else {
					reply = result.value[0];
				}
				if (reply) {
					replies.push(reply);
				}
			} else {
				apputil.log(`Command not found: ${inputCommands[i].toLowerCase()}`);
			}
		}
	}
	callback(null, replies);
};

module.exports = {

	investigate: function(text, callback) {
		parseMessage(text, function(err, inputCommands) {
			db.get().collection("commands").find().toArray(function(error, commands) {
				if (error) {
					apputil.log(`Error retrieving commands: ${error}`);
				} else {
					processCommands(inputCommands, commands, function(err, replies){
						callback(err, replies);
					});
				}
			});
		});
	}
};
<commit_msg>Added xbox and psn destiny commands grimoirescore, playtime and pvpsummary [skip ci]<commit_after>var fs = require('fs');
var http = require('http');
var request = require('request');
var destinyCmds = require('./bungieApiCommands.js');
var apputil = require("./util.js");
var db = require('./db.js');
var Promise = require('bluebird');

var sortObject = function (o) {
    var sorted = {},
    key, a = [];
    for (key in o) {
        if (o.hasOwnProperty(key)) {
            a.push(key);
        }
    }
    a.sort();
    for (key = 0; key < a.length; key++) {
        sorted[a[key]] = o[a[key]];
    }
    return sorted;
};

// Look for segments of a message that have an exclamation followed by one or
// more alphaneumeric characters
var parseMessage = function(message, callback) {
	var pattern = /\!([a-zA-Z0-9]+)/g;
	var matches = message.match(pattern);

	if (matches) {
		for (var i = 0; i < matches.length; i++) {
			matches[i] = matches[i].replace(/\!/g, '');
		}
	}
	else {
		// if no matches are found, return an empty array
		// this makes it easier for the function's clients to handle because they
		// do not have to worry about nulls.
		callback(null, []);
	}
	callback(null, matches);
};

var parseUtilityCommands = function(command, message) {
	return message.replace(`!${command} `, '');
};

var pickRandom = function(cmdObject) {
	var rnged = apputil.shuffle(cmdObject.value);
	return rnged[0];
}

var processCommands = function(inputCommands, commands, text, callback) {
	if (inputCommands) {
		// If command needs arguments, it must be the first thing in the comment
		if (inputCommands.length == 1 &&
			text.indexOf('!') == 0 &&
			commands.find(o => o.name === inputCommands[0].toLowerCase()).requiresArgs) {

			var result = commands.find(o => o.name === inputCommands[0].toLowerCase());
			var arg = parseUtilityCommands(inputCommands[0], text);
			switch(result.name) {
				case "grimoirescore" :
					destinyCmds.grimoireScore('1', arg, function(err, reply){
						if (err) { apputil.log(`Error getting grimoirescore: ${err}`); callback(null, [result.value[0]]); }
						else { callback(null, [reply]); }
					});
					break;
				case "grimoirescorepsn" :
					destinyCmds.grimoireScore('2', arg, function(err, reply){
						if (err) { apputil.log(`Error getting grimoirescorepsn: ${err}`); callback(null, [result.value]); }
						else { callback(null, [reply]); }
					});
					break;
				case "playtime" :
					destinyCmds.playTime('1', arg, function(err, reply){
						if (err) { apputil.log(`Error getting playtime: ${err}`); callback(null, [result.value]); }
						else { callback(null, [reply]); }
					});
					break;
				case "playtimepsn" :
					destinyCmds.playTime('2', arg, function(err, reply){
						if (err) { apputil.log(`Error getting playtimepsn: ${err}`); callback(null, [result.value]); }
						else { callback(null, [reply]); }
					});
					break;
				case "pvpsummary" :
					destinyCmds.pvpSummary('1', arg, function(err, reply){
						if (err) { apputil.log(`Error getting pvpsummary: ${err}`); callback(null, [result.value]); }
						else { callback(null, [reply]); }
					});
					break;
				case "pvpsummarypsn" :
					destinyCmds.pvpSummary('2', arg, function(err, reply){
						if (err) { apputil.log(`Error getting pvpsummarypsn: ${err}`); callback(null, [result.value]); }
						else { callback(null, [reply]); }
					});
					break;
				default :
					apputil.log(`Command ${result.name} not handled here. Is the requiresArgs setting correct?`);
					break;
			}
		} else {
			var replies = [];
			for (var i = 0; i < inputCommands.length; i++) {
				var result = commands.find(o => o.name === inputCommands[i].toLowerCase());
				if (result) {
					var reply;
					if (result.selectRandom) {
						reply = pickRandom(result);
					} else {
						reply = result.value[0];
					}
					if (reply) {
						replies.push(reply);
					}
				} else {
					apputil.log(`Command not found: ${inputCommands[i].toLowerCase()}`);
				}
			}
			callback(null, replies);
		}
	}
};

module.exports = {

	investigate: function(text, callback) {
		parseMessage(text, function(err, inputCommands) {
			db.get().collection("commands").find().toArray(function(error, commands) {
				if (error) {
					apputil.log(`Error retrieving commands: ${error}`);
				} else {
					processCommands(inputCommands, commands, text, function(err, replies){
						callback(err, replies);
					});
				}
			});
		});
	}
};
<|endoftext|>


<commit_before>module.exports = [
    {
        name: 'Thermostat Current Temperature',
        deviceId: 9,
        getStg: [function(thermostatData) {
                        return thermostatData.temp;
        }],
                canSet: false,
    },
    {
        name: 'Thermostat Target Temperature',
        deviceId: 31,
        getStg: [function(thermostatData) {
                        var tTemp = thermostatData.t_cool;
                        if (!tTemp) tTemp = thermostatData.t_heat;
                        return tTemp;
        }],
                canSet: true,
                setStg: [function(ipAddr, data, lastData) { // example:   curl -d '{"t_cool":67,"t_heat":67}' http://1.1.1.1/tstat
                        if (isNaN(data)) {
                                return undefined;
                        }
                        else {
                                if (lastData.t_heat) { return "curl -d '{\"t_heat\":" + data + "}' http://" + ipAddr + "/tstat"; }
                                else if (lastData.t_cool) { return "curl -d '{\"t_cool\":" + data + "}' http://" + ipAddr + "/tstat"; }
                                else { return undefined; }
                        }
                        // if (isNaN(data)) return ""; else return "curl -d '{\"t_cool\":" + data + ",\"t_heat\":" + data + "}' http://" + ipAddr + "/tstat";        // setStg just returns the string we want to execute
        }],
    },
    {
        name: 'Thermostat Hold Mode',                // current thermostat hold mode ("hold") - will be one of: 0: disabled, 1: enabled
        deviceId: 244,
        getStg: [function(thermostatData) {
                        var hmModes = ["Thermostat Hold Disabled","Thermostat Hold Enabled"];
                        return hmModes[thermostatData.hold] || "Thermostat Hold Unknown";
        }],
                canSet: true,
                setStg: [function(ipAddr, data, lastData) { // example:   curl -d '{"hold":1}' http://1.1.1.1/tstat  (turns hold on)
                        var hldNum = {"Thermostat Hold Disabled":0,"Thermostat Hold Enabled":1};
                        if (hldNum[data]) { return "curl -d '{\"hold\":" + hldNum[mode] + "}' http://" + ipAddr + "/tstat"; } else { return undefined; };
        }],
    },
    {
        name: 'Thermostat Operating Mode',                // current thermostat operating mode ("tmode") - will be one of: 0: OFF, 1: HEAT, 2: COOL, 3: AUTO
        deviceId: 244,
        getStg: [function(thermostatData) {
                        var opModes = ["Thermostat Mode Off","Thermostat Heat Mode","Thermostat Cool Mode","Thermostat Auto Mode"];
                        return opModes[thermostatData.tmode] || "Thermostat Mode Unknown";
        }],
                canSet: true,
                setStg: [function(ipAddr, data, lastData) { // example:   curl -d '{"tmode":1}' http://1.1.1.1/tstat  (turns to heat mode)
                        var modNum = {"Thermostat Mode Off":0,"Thermostat Heat Mode":1,"Thermostat Cool Mode":2,"Thermostat Auto Mode":3};
                        if (modNum[data]) { return "curl -d '{\"tmode\":" + modNum[data] + "}' http://" + ipAddr + "/tstat"; } else { return undefined; };
        }],
    },
    {
        name: 'Thermostat Fan Operating Mode',                // show current thermostat fan operating mode ("fmode") - will be one of: 0: AUTO, 1: AUTO/CIRCULATE, 2: ON
        deviceId: 244,
        getStg: [function(thermostatData) {
                        var fanOpModes = ["Thermostat Fan Auto Mode","Thermostat Fan Auto/Circ","Thermostat Fan Mode On"];
                        return fanOpModes[thermostatData.fmode] || "Thermostat Fan Unknown";
        }],
                canSet: true,
                setStg: [function(ipAddr, data, lastData) { // example:   curl -d '{"tmode":1}' http://1.1.1.1/tstat  (turns to heat mode)
                        var modNum = {"Thermostat Fan Auto Mode":0,"Thermostat Fan Auto/Circ":1,"Thermostat Fan Mode On":2};
                        if (modNum[data]) { return "curl -d '{\"tmode\":" + modNum[data] + "}' http://" + ipAddr + "/tstat"; } else { return undefined; };
        }],
    },
    {
        name: 'Thermostat Time',                // output a string of the thermostat time ("time":{"day":0,"hour":0,"minute":0}}) - day 0 = Monday
        deviceId: 3680,
        getStg: [function(thermostatData) {
                        var daysWeek = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday', 'Sunday'];
                        var weekDay = daysWeek[thermostatData.time.day];
                        var paddedMin = (thermostatData.time.minute < 10) ? ("0" + thermostatData.time.minute) : thermostatData.time.minute;
                        return weekDay + ", " + thermostatData.time.hour + ":" + paddedMin; // for example, "Wednesday, 13:34"
        }],
                canSet: false,
    },
];

/*
    name: string - the name of the device
    deviceId: number - the device id of the device - see http://ninjablocks.com/pages/device-ids
    data: function to call which will return parsed date when given ((json object)thermostatData) as arguments
    canSet: boolean - set to true if device is writable
    setStg: a function to call if device is writable upon write which will return a string of the command to execute, given ((string)ipAddr, (string)data), (json object)lastData as arguments

        example retuned data: {"temp":65.50,"tmode":1,"fmode":0,"override":0,"hold":0,"t_heat":68.00,"tstate":1,"fstate":1,"time":{"day":1,"hour":10,"minute":9},"t_type_post":0}
*/
<commit_msg>Delete commands.js<commit_after><|endoftext|>


<commit_before>// (function(module) {

  var teacherView = {};
  var ref = new Firebase('https://queue-you.firebaseio.com/');
  var ref2 = new Firebase('https://queue-you.firebaseio.com/users/');
  // var ref3 = new Firebase('https://queue-you.firebaseio.com/users/-K93F-mA76dCgyazMeEG');
  var profileList = [];
  var keys = [];

  teacherView.showList = function() {
    $('#teacher-button').on('click', function() {
      $('#teacher').show().siblings().hide();
      teacherView.post();
    });
  };

  // /////////////////////////////////////
  //
  //
  // teacherView.test = function() {
  //   $('#teacher-test').on('click', function() {
  //     // e.preventDefault();
  //     $('#form').show().siblings().hide();
  //   });
  // };
  //
  //
  // /////////////////////////////////////

  teacherView.storagePull = function(){
    ref2.on('child_added', function(snapshot, prevChildKey){
      var newPost = snapshot.val();
      // console.log(newPost);
      // console.log(snapshot.key());
      profileList.push(snapshot.val());
      keys.push(snapshot.key());

    });
  };

  teacherView.post = function(){
    for (var i = 0; i < profileList.length; i++) {
      $('ol').append('
Name: ' + profileList[i].name + '
' +
      profileList[i].issue + '
' +
      profileList[i].desc +'
' + '
' + '
');
      teacherView.remove();
    }
  };
  //   profileList.forEach(function(name, issue, desc) {
  //     $('ol').append('
' + this.name + this.issue + this.desc + '
').toHtml();
  //   });
  // };
  teacherView.remove = function() {
    $('li').click(function() {
      var $key = $(this).index();
      console.log($key);
      console.log(keys[$key]);
      var deleteRef = new Firebase('https://queue-you.firebaseio.com/users/' + keys[$key]);
      console.log(deleteRef);
      console.log($(this).index());
      deleteRef.remove();
      $(this).remove();

      // ref2.child.key.remove();
    });
  };

  teacherView.showList();
  teacherView.storagePull();
  // teacherView.test();
//   module.teacherView = teacherView;
// })(window);
<commit_msg>restored IFFE to teacherView.js, cleaned up some useless or obsolete code<commit_after>(function(module) {

  var teacherView = {};
  var ref = new Firebase('https://queue-you.firebaseio.com/');
  var ref2 = new Firebase('https://queue-you.firebaseio.com/users/');
  var profileList = [];
  var keys = [];

  teacherView.showList = function() {
    $('#teacher-button').on('click', function() {
      $('#teacher').show().siblings().hide();
      teacherView.post();
    });
  };

  // /////////////////////////////////////
  //
  //
  // teacherView.test = function() {
  //   $('#teacher-test').on('click', function() {
  //     // e.preventDefault();
  //     $('#form').show().siblings().hide();
  //   });
  // };
  //
  //
  // /////////////////////////////////////

  teacherView.storagePull = function(){
    ref2.on('child_added', function(snapshot, prevChildKey){
      var newPost = snapshot.val();
      profileList.push(snapshot.val());
      keys.push(snapshot.key());

    });
  };

  teacherView.post = function(){
    for (var i = 0; i < profileList.length; i++) {
      $('ol').append('
Name: ' + profileList[i].name + '
' +
      profileList[i].issue + '
' +
      profileList[i].desc +'
' + '
' + '
');
      teacherView.remove();
    }
  };

  teacherView.remove = function() {
    $('li').click(function() {
      var $key = $(this).index();
      console.log($key);
      console.log(keys[$key]);
      var deleteRef = new Firebase('https://queue-you.firebaseio.com/users/' + keys[$key]);
      console.log(deleteRef);
      console.log($(this).index());
      deleteRef.remove();
      $(this).remove();

    });
  };

  teacherView.showList();
  teacherView.storagePull();
  // teacherView.test();
  module.teacherView = teacherView;
})(window);
<|endoftext|>


<commit_before>function testFunction() {
    // Put model data in an array (eventual database/JSON connection)
    "models" : [
        {"modelName" : "BAMPFA Panel", "modelURN" : "urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c2hlZXQuYnVja2V0L0JBTV9QTkxfUjA3LTAxLkNBVFBhcnQ="},
        {"modelName": "D-SET Panel", "modelURN": "urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c2hlZXQuYnVja2V0L0JBTV9QTkxfUjA3LTAxLkNBVFBhcnQ="}
    ]

    // Parse array and write to console
    var modelStatus = JSON.parse(models);
    modelStatus.models[0].modelName + " , " + modelStatus.models[0].modelURN;
    console.log("Model Status: " + modelStatus);
}

function initialize() {
    var options = {
        //"document" : "urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c2hlZXQuYnVja2V0L0JBTV9QTkxfUjA3LTAxLkNBVFBhcnQ=", // BAMPFA Panel
        "document" : "urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bm1fYnVja2V0L01HTV9EU1RfUGFuZWxMLkNBVFBhcnQ=", // D-SET Panel
        "env" : "AutodeskProduction",
        "getAccessToken" : getToken,
        "refreshToken": getToken
    };

    var viewerElement = document.getElementById("viewer");

    var viewer = new Autodesk.Viewing.Viewer3D(viewerElement, {});

    Autodesk.Viewing.Initializer(options,function() {
        viewer.initialize();
        loadDocument(viewer, options.document);
    });
}

function getToken() {
    var theUrl = "http://app.sheetd.com:5000/auth";
    var xmlHttp = null;
    xmlHttp = new XMLHttpRequest();
    xmlHttp.open("GET", theUrl, false);
    xmlHttp.send(null);
    var resp =  JSON.parse(xmlHttp.responseText);
    var token = resp["access_token"];
    return token;
}

function loadDocument(viewer, documentId) {
    // Find the first 3d geometry and load that.
    Autodesk.Viewing.Document.load(documentId, function(doc) {// onLoadCallback
        var geometryItems = [];
        geometryItems = Autodesk.Viewing.Document.getSubItemsWithProperties(doc.getRootItem(), {
            "type" : "geometry",
            "role" : "3d"
        }, true);
        if (geometryItems.length > 0) {
            viewer.load(doc.getViewablePath(geometryItems[0]));
        }
    }, function(errorMsg) {// onErrorCallback
        alert("Load Error: " + errorMsg);
    });
}<commit_msg>js testing<commit_after>function initialize() {
    var options = {
        //"document" : "urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c2hlZXQuYnVja2V0L0JBTV9QTkxfUjA3LTAxLkNBVFBhcnQ=", // BAMPFA Panel
        "document" : "urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bm1fYnVja2V0L01HTV9EU1RfUGFuZWxMLkNBVFBhcnQ=", // D-SET Panel
        "env" : "AutodeskProduction",
        "getAccessToken" : getToken,
        "refreshToken": getToken
    };

    var viewerElement = document.getElementById("viewer");

    var viewer = new Autodesk.Viewing.Viewer3D(viewerElement, {});

    Autodesk.Viewing.Initializer(options,function() {
        viewer.initialize();
        loadDocument(viewer, options.document);
    });
}

function getToken() {
    var theUrl = "http://app.sheetd.com:5000/auth";
    var xmlHttp = null;
    xmlHttp = new XMLHttpRequest();
    xmlHttp.open("GET", theUrl, false);
    xmlHttp.send(null);
    var resp =  JSON.parse(xmlHttp.responseText);
    var token = resp["access_token"];
    return token;
}

function loadDocument(viewer, documentId) {
    // Find the first 3d geometry and load that.
    Autodesk.Viewing.Document.load(documentId, function(doc) {// onLoadCallback
        var geometryItems = [];
        geometryItems = Autodesk.Viewing.Document.getSubItemsWithProperties(doc.getRootItem(), {
            "type" : "geometry",
            "role" : "3d"
        }, true);
        if (geometryItems.length > 0) {
            viewer.load(doc.getViewablePath(geometryItems[0]));
        }
    }, function(errorMsg) {// onErrorCallback
        alert("Load Error: " + errorMsg);
    });
}

function testFunction() {
    // Put model data in an array (eventual database/JSON connection)
    var models = [
        {"modelName" : "BAMPFA Panel", "modelURN" : "urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c2hlZXQuYnVja2V0L0JBTV9QTkxfUjA3LTAxLkNBVFBhcnQ="},
        {"modelName": "D-SET Panel", "modelURN": "urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6c2hlZXQuYnVja2V0L0JBTV9QTkxfUjA3LTAxLkNBVFBhcnQ="}
    ]

    // Parse array and write to console
    var modelStatus = JSON.parse(models);
    modelStatus.models[0].modelName + " , " + modelStatus.models[0].modelURN;
    console.log("Model Status: " + modelStatus);
}<|endoftext|>


<commit_before>// (function(module) {

  var teacherView = {};
  var ref = new Firebase('https://queue-you.firebaseio.com/users');
  var profileList = [];

  teacherView.showList = function() {
    $('#teacher-button').on('click', function() {
      $('#teacher').show().siblings().hide();
      teacherView.post();
    });
  };

  /////////////////////////////////////

  teacherView.test = function() {
    $('#teacher-test').on('click', function() {
      // e.preventDefault();
      $('#form').show().siblings().hide();
    });
  };

  /////////////////////////////////////

  teacherView.storagePull = function(){
    ref.on('child_added', function(snapshot, prevChildKey){
      var newPost = snapshot.val();
      console.log(newPost);
      profileList.push(snapshot.val());
    });
  };

  teacherView.post = function(){
    for (var i = 0; i < profileList.length; i++) {
      $('ol').append('
Name: ' + profileList[i].name + '
' +
      profileList[i].issue + '
' +
      profileList[i].desc +'
' + '
' + '</li');
    }
  };
  //   profileList.forEach(function(name, issue, desc) {
  //     $('ol').append('
' + this.name + this.issue + this.desc + '
').toHtml();
  //   });
  // };

  teacherView.showList();
  teacherView.storagePull();
  teacherView.test();
//   module.teacherView = teacherView;
// })(window);
<commit_msg>figured out firebase problem, added new firebase path in teacherView.js, form submitting and data posting to DOM properly<commit_after>// (function(module) {

  var teacherView = {};
  var ref = new Firebase('https://queue-you.firebaseio.com/');
  var ref2 = new Firebase('https://queue-you.firebaseio.com/users');
  var profileList = [];

  teacherView.showList = function() {
    $('#teacher-button').on('click', function() {
      $('#teacher').show().siblings().hide();
      teacherView.post();
    });
  };

  /////////////////////////////////////

  teacherView.test = function() {
    $('#teacher-test').on('click', function() {
      // e.preventDefault();
      $('#form').show().siblings().hide();
    });
  };

  /////////////////////////////////////

  teacherView.storagePull = function(){
    ref2.on('child_added', function(snapshot, prevChildKey){
      var newPost = snapshot.val();
      console.log(newPost);
      profileList.push(snapshot.val());
    });
  };

  teacherView.post = function(){
    for (var i = 0; i < profileList.length; i++) {
      $('ol').append('
Name: ' + profileList[i].name + '
' +
      profileList[i].issue + '
' +
      profileList[i].desc +'
' + '
' + '</li');
    }
  };
  //   profileList.forEach(function(name, issue, desc) {
  //     $('ol').append('
' + this.name + this.issue + this.desc + '
').toHtml();
  //   });
  // };

  teacherView.showList();
  teacherView.storagePull();
  teacherView.test();
//   module.teacherView = teacherView;
// })(window);
<|endoftext|>


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

  $(".submission-box").on("keyup", function() {
    setGoldenText(this);
  })

  $('tr.route').mouseover(function(){
    addClassHover(this);
  });

  $('tr.route').mouseout(function(){
    removeClassHover(this);
  });

  $(".route").on("click", function() {
    toggleNext(this);
    toggleTRClass(this);
    squadLove();
  });

//############ ZeroClipboard Nightmare #########################

  var client = new ZeroClipboard( $(".route-pre") );

  client.on("ready", function( readyEvent ) {
    client.on("copy", function(event) {
      var preData = event.target.innerText;
      client.setText(preData);
    })
    client.on("aftercopy", function( event ) {
      $(event.target).siblings(".copy-prompt").text("Copied!");
      $(event.target).addClass(".on-click")
      setTimeout(function(){
        $(event.target).siblings(".copy-prompt").text("^click to copy^");
        $(event.target).addClass(".on-click");
      }, 1000);
    });
  });

//################ Thank god that's over ##########################

}); //end of (document).ready()

//######################## Functions #############################

function removeClassHover(that) {
  $(that).removeClass('hover');
}

function setGoldenText(that) {
  $(".golden-text").text($(that).val().toLowerCase());
  $(".g-text-singular").text(pluralize(capitalize($(that).val()), 1));
  $(".g-text-s-dc").text((pluralize($(that).val(), 1)));
}

function addClassHover(that) {
  $(that).addClass('hover');
}

function toggleNext(that) {
  $(that).next().toggle();
}

function toggleTRClass(that) {
  $(that).toggleClass('in-use');
  $(that).toggleClass('hover');
}

function squadLove() {
  var rand100 = Math.floor(Math.random() * 100)
  if (rand100 === 69) {
    $('.sub-box-under').text("Chi Bobolinks 2015!")
  }
}

function capitalize(string) {
  var lowerCaseString = string.toLowerCase();
  return lowerCaseString.charAt(0).toUpperCase() + lowerCaseString.slice(1);
}
<commit_msg>Add toggle('slow')<commit_after>$(document).ready(function() {

  $(".submission-box").on("keyup", function() {
    setGoldenText(this);
  })

  $('tr.route').mouseover(function(){
    addClassHover(this);
  });

  $('tr.route').mouseout(function(){
    removeClassHover(this);
  });

  $(".route").on("click", function() {
    toggleNext(this);
    toggleTRClass(this);
    squadLove();
  });

//############ ZeroClipboard Nightmare #########################

  var client = new ZeroClipboard( $(".route-pre") );

  client.on("ready", function( readyEvent ) {
    client.on("copy", function(event) {
      var preData = event.target.innerText;
      client.setText(preData);
    })
    client.on("aftercopy", function( event ) {
      $(event.target).siblings(".copy-prompt").text("Copied!");
      $(event.target).addClass(".on-click")
      setTimeout(function(){
        $(event.target).siblings(".copy-prompt").text("^click to copy^");
        $(event.target).addClass(".on-click");
      }, 1000);
    });
  });

//################ Thank god that's over ##########################

}); //end of (document).ready()

//######################## Functions #############################

function removeClassHover(that) {
  $(that).removeClass('hover');
}

function setGoldenText(that) {
  $(".golden-text").text($(that).val().toLowerCase());
  $(".g-text-singular").text(pluralize(capitalize($(that).val()), 1));
  $(".g-text-s-dc").text((pluralize($(that).val(), 1)));
}

function addClassHover(that) {
  $(that).addClass('hover');
}

function toggleNext(that) {
  $(that).next().toggle("slow");
}

function toggleTRClass(that) {
  $(that).toggleClass('in-use');
  $(that).toggleClass('hover');
}

function squadLove() {
  var rand100 = Math.floor(Math.random() * 100)
  if (rand100 === 69) {
    $('.sub-box-under').text("Chi Bobolinks 2015!")
  }
}

function capitalize(string) {
  var lowerCaseString = string.toLowerCase();
  return lowerCaseString.charAt(0).toUpperCase() + lowerCaseString.slice(1);
}
<|endoftext|>


<commit_before>$(document).ready(function() {
  var client = new ZeroClipboard( $(".route-pre") );

  client.on( "ready", function( readyEvent ) {
    client.on("copy", function(event) {
      console.log(client);
      var preData = event.target.innerText;
      client.setText(preData);
    })
    client.on( "aftercopy", function( event ) {
      console.log(event.target)
      console.log($(event.target))
      console.log($(event.target).siblings(".copy-prompt").text("Copied!"))

    });
  });
});

$(document).ready(function() {

  $(".submission-box").on("keyup", function() {
    $(".golden-text").text($(this).val().toLowerCase());
    $(".g-text-singular").text(pluralize(capitalize($(this).val()), 1));
    $(".g-text-s-dc").text((pluralize($(this).val(), 1)));
  });

   $('tr.route').mouseover(function(){
      $(this).addClass('hover');
   });

   $('tr.route').mouseout(function(){
      $(this).removeClass('hover');
   });

  $(".route").on("click", function() {
    $(this).next().toggle();
    $(this).toggleClass('in-use');
    $(this).toggleClass('hover');
  });

  var rand100 = Math.floor(Math.random() * 100)
  if (rand100 === 69) {
    $('.sub-box-under').text("Rest-a-licious!")
  } else if (rand100 >= 80) {
    $('.sub-box-under').text("Type something in!")
  } else if (rand100 >= 60) {
      $('.sub-box-under').text("Try your own!")
  } else if (rand100 >= 40) {
      $('.sub-box-under').text("Chi Bobolinks 2015!")
  } else if (rand100 >= 20) {
      $('.sub-box-under').text("Rapid Restful Results! (TM)")
  } else {
      $('.sub-box-under').text("Kitchen it? Kitchen it.")
  }

});

function capitalize(string) {
  var lowerCaseString = string.toLowerCase();
    return lowerCaseString.charAt(0).toUpperCase() + lowerCaseString.slice(1);
}

<commit_msg>add timeout<commit_after>$(document).ready(function() {
  var client = new ZeroClipboard( $(".route-pre") );

  client.on( "ready", function( readyEvent ) {
    client.on("copy", function(event) {
      console.log(client);
      var preData = event.target.innerText;
      client.setText(preData);
    })
    client.on( "aftercopy", function( event ) {
      $(event.target).siblings(".copy-prompt").text("Copied!");
      setTimeout(function(){
        $(event.target).siblings(".copy-prompt").text("^click to copy^");
        }, 10000);
    });
  });
});

$(document).ready(function() {

  $(".submission-box").on("keyup", function() {
    $(".golden-text").text($(this).val().toLowerCase());
    $(".g-text-singular").text(pluralize(capitalize($(this).val()), 1));
    $(".g-text-s-dc").text((pluralize($(this).val(), 1)));
  });

   $('tr.route').mouseover(function(){
      $(this).addClass('hover');
   });

   $('tr.route').mouseout(function(){
      $(this).removeClass('hover');
   });

  $(".route").on("click", function() {
    $(this).next().toggle();
    $(this).toggleClass('in-use');
    $(this).toggleClass('hover');
  });

  var rand100 = Math.floor(Math.random() * 100)
  if (rand100 === 69) {
    $('.sub-box-under').text("Rest-a-licious!")
  } else if (rand100 >= 80) {
    $('.sub-box-under').text("Type something in!")
  } else if (rand100 >= 60) {
      $('.sub-box-under').text("Try your own!")
  } else if (rand100 >= 40) {
      $('.sub-box-under').text("Chi Bobolinks 2015!")
  } else if (rand100 >= 20) {
      $('.sub-box-under').text("Rapid Restful Results! (TM)")
  } else {
      $('.sub-box-under').text("Kitchen it? Kitchen it.")
  }

});

function capitalize(string) {
  var lowerCaseString = string.toLowerCase();
    return lowerCaseString.charAt(0).toUpperCase() + lowerCaseString.slice(1);
}

<|endoftext|>


<commit_before>// Arbitrary numbers chosen to ensure Long Portrait mode fits into Chrome on Android.
// Firefox uses less vertical space for the URL bar so Long Portrait will be available in both.
// 270 is six times 45, as board is twelve squares and logo is two.
// 73 is the remaining 3.24444 squares that can fit into the Chrome window.
// Scaled up until all values are integers for ease of reading.
const THRESHOLD_LongPortraitFitToWidth = 270/(45+270+73);
const THRESHOLD_LongPortraitFitToHeight = (45+270)/(45+270+73);
const THRESHOLD_ShortPortraitFitToWidth = (45+270)/(270+73);
const THRESHOLD_ShortPortraitFitToHeight = 1;
const THRESHOLD_ShortLandscapeFitToWidth = (270+73)/(45+270);
const THRESHOLD_ShortLandscapeFitToHeight = (45+270+73)/(45+270);
const THRESHOLD_LongLandscapeFitToWidth = (45+270+73)/270;

function reorganise() {
  ratio = window.innerWidth / window.innerHeight;
  if (ratio < THRESHOLD_LongPortraitFitToWidth) {arrange_LongPortraitFitToWidth();
  } else if (ratio < THRESHOLD_LongPortraitFitToHeight) {arrange_LongPortraitFitToHeight();
  } else if (ratio < THRESHOLD_ShortPortraitFitToWidth) {arrange_ShortPortraitFitToWidth();
  } else if (ratio < THRESHOLD_ShortPortraitFitToHeight) {arrange_ShortPortraitFitToHeight();
  } else if (ratio < THRESHOLD_ShortLandscapeFitToWidth) {arrange_ShortLandscapeFitToWidth();
  } else if (ratio < THRESHOLD_ShortLandscapeFitToHeight) {arrange_ShortLandscapeFitToHeight();
  } else if (ratio < THRESHOLD_LongLandscapeFitToWidth) {arrange_LongLandscapeFitToWidth();
  } else {arrange_LongLandscapeFitToHeight();
  }
}

function arrange_LongPortraitFitToWidth() {
  document.getElementById('title-west').style.display = 'none';
  document.getElementById('title-north').style.display = 'inline';
  document.getElementById('info-east').style.display = 'none';
  document.getElementById('info-south').style.display = 'inline';

  var w = window.innerWidth;
  document.getElementById('title-north').style.width = w.toString().concat('px');
  document.getElementById('title-north').style.height = (w/6).toString().concat('px');
  document.getElementById('board-area').style.width = w.toString().concat('px');
  document.getElementById('board-area').style.height = w.toString().concat('px');
  document.getElementById('info-south').style.width = w.toString().concat('px');
  document.getElementById('info-south').style.height = (window.innerHeight-w*7/6).toString().concat('px');

  document.getElementById('board-canvas').style.width = w.toString().concat('px');
  document.getElementById('board-canvas').style.height = w.toString().concat('px');
}

function arrange_LongPortraitFitToHeight() {
  document.getElementById('title-west').style.display = 'none';
  document.getElementById('title-north').style.display = 'inline';
  document.getElementById('info-east').style.display = 'none';
  document.getElementById('info-south').style.display = 'inline';

  var w = window.innerHeight * THRESHOLD_LongPortraitFitToWidth;
  document.getElementById('title-north').style.width = w.toString().concat('px');
  document.getElementById('title-north').style.height = (w/6).toString().concat('px');
  document.getElementById('board-area').style.width = w.toString().concat('px');
  document.getElementById('board-area').style.height = w.toString().concat('px');
  document.getElementById('info-south').style.width = w.toString().concat('px');
  document.getElementById('info-south').style.height = (window.innerHeight-w*7/6).toString().concat('px');

  document.getElementById('board-canvas').style.width = w.toString().concat('px');
  document.getElementById('board-canvas').style.height = w.toString().concat('px');
}

function arrange_ShortPortraitFitToWidth() {
  document.getElementById('title-north').style.display = 'none';
  document.getElementById('title-west').style.display = 'inline';
  document.getElementById('info-east').style.display = 'none';
  document.getElementById('info-south').style.display = 'inline';

  var w = window.innerWidth;
  document.getElementById('title-west').style.width = (w/7).toString().concat('px');
  document.getElementById('title-west').style.height = (w*6/7).toString().concat('px');
  document.getElementById('board-area').style.width = (w*6/7).toString().concat('px');
  document.getElementById('board-area').style.height = (w*6/7).toString().concat('px');
  document.getElementById('info-south').style.width = w.toString().concat('px');
  document.getElementById('info-south').style.height = (window.innerHeight-w*6/7).toString().concat('px');

  document.getElementById('board-canvas').style.width = (w*6/7).toString().concat('px');
  document.getElementById('board-canvas').style.height = (w*6/7).toString().concat('px');
}

function arrange_ShortPortraitFitToHeight() {
  document.getElementById('title-north').style.display = 'none';
  document.getElementById('title-west').style.display = 'inline';
  document.getElementById('info-east').style.display = 'none';
  document.getElementById('info-south').style.display = 'inline';

  var w = window.innerHeight * THRESHOLD_ShortPortraitFitToWidth;
  document.getElementById('title-west').style.width = (w/7).toString().concat('px');
  document.getElementById('title-west').style.height = (w*6/7).toString().concat('px');
  document.getElementById('board-area').style.width = (w*6/7).toString().concat('px');
  document.getElementById('board-area').style.height = (w*6/7).toString().concat('px');
  document.getElementById('info-south').style.width = w.toString().concat('px');
  document.getElementById('info-south').style.height = (window.innerHeight-w*6/7).toString().concat('px');

  document.getElementById('board-canvas').style.width = (w*6/7).toString().concat('px');
  document.getElementById('board-canvas').style.height = (w*6/7).toString().concat('px');
}

function arrange_ShortLandscapeFitToWidth() {
  document.getElementById('title-west').style.display = 'none';
  document.getElementById('title-north').style.display = 'inline';
  document.getElementById('info-south').style.display = 'none';
  document.getElementById('info-east').style.display = 'inline';

  var h = window.innerWidth * THRESHOLD_ShortPortraitFitToWidth;
  document.getElementById('title-north').style.width = (h*6/7).toString().concat('px');
  document.getElementById('title-north').style.height = (h/7).toString().concat('px');
  document.getElementById('board-area').style.width = (h*6/7).toString().concat('px');
  document.getElementById('board-area').style.height = (h*6/7).toString().concat('px');
  document.getElementById('info-east').style.width = (window.innerWidth-h*6/7).toString().concat('px');
  document.getElementById('info-east').style.height = h.toString().concat('px');

  document.getElementById('board-canvas').style.width = (h*6/7).toString().concat('px');
  document.getElementById('board-canvas').style.height = (h*6/7).toString().concat('px');
}

function arrange_ShortLandscapeFitToHeight() {
  document.getElementById('title-west').style.display = 'none';
  document.getElementById('title-north').style.display = 'inline';
  document.getElementById('info-south').style.display = 'none';
  document.getElementById('info-east').style.display = 'inline';

  var h = window.innerHeight;
  document.getElementById('title-north').style.width = (h*6/7).toString().concat('px');
  document.getElementById('title-north').style.height = (h/7).toString().concat('px');
  document.getElementById('board-area').style.width = (h*6/7).toString().concat('px');
  document.getElementById('board-area').style.height = (h*6/7).toString().concat('px');
  document.getElementById('info-east').style.width = (window.innerWidth-h*6/7).toString().concat('px');
  document.getElementById('info-east').style.height = h.toString().concat('px');

  document.getElementById('board-canvas').style.width = (h*6/7).toString().concat('px');
  document.getElementById('board-canvas').style.height = (h*6/7).toString().concat('px');
}

function arrange_LongLandscapeFitToWidth() {
  document.getElementById('title-north').style.display = 'none';
  document.getElementById('title-west').style.display = 'inline';
  document.getElementById('info-south').style.display = 'none';
  document.getElementById('info-east').style.display = 'inline';

  var h  = window.innerWidth * THRESHOLD_LongPortraitFitToWidth;
  document.getElementById('title-west').style.width = (h/6).toString().concat('px');
  document.getElementById('title-west').style.height = h.toString().concat('px');
  document.getElementById('board-area').style.width = h.toString().concat('px');
  document.getElementById('board-area').style.height = h.toString().concat('px');
  document.getElementById('info-east').style.width = (window.innerWidth-h*7/6).toString().concat('px');
  document.getElementById('info-east').style.height = h.toString().concat('px');

  document.getElementById('board-canvas').style.width = h.toString().concat('px');
  document.getElementById('board-canvas').style.height = h.toString().concat('px');
}

function arrange_LongLandscapeFitToHeight() {
  document.getElementById('title-north').style.display = 'none';
  document.getElementById('title-west').style.display = 'inline';
  document.getElementById('info-south').style.display = 'none';
  document.getElementById('info-east').style.display = 'inline';

  var h  = window.innerHeight;
  document.getElementById('title-west').style.width = (h/6).toString().concat('px');
  document.getElementById('title-west').style.height = h.toString().concat('px');
  document.getElementById('board-area').style.width = h.toString().concat('px');
  document.getElementById('board-area').style.height = h.toString().concat('px');
  document.getElementById('info-east').style.width = (window.innerWidth-h*7/6).toString().concat('px');
  document.getElementById('info-east').style.height = h.toString().concat('px');

  document.getElementById('board-canvas').style.width = h.toString().concat('px');
  document.getElementById('board-canvas').style.height = h.toString().concat('px');
}

window.onresize = reorganise;
<commit_msg>Apply new div names<commit_after>// Arbitrary numbers chosen to ensure Long Portrait mode fits into Chrome on Android.
// Firefox uses less vertical space for the URL bar so Long Portrait will be available in both.
// 270 is six times 45, as board is twelve squares and logo is two.
// 73 is the remaining 3.24444 squares that can fit into the Chrome window.
// Scaled up until all values are integers for ease of reading.
const THRESHOLD_LongPortraitFitToWidth = 270/(45+270+73);
const THRESHOLD_LongPortraitFitToHeight = (45+270)/(45+270+73);
const THRESHOLD_ShortPortraitFitToWidth = (45+270)/(270+73);
const THRESHOLD_ShortPortraitFitToHeight = 1;
const THRESHOLD_ShortLandscapeFitToWidth = (270+73)/(45+270);
const THRESHOLD_ShortLandscapeFitToHeight = (45+270+73)/(45+270);
const THRESHOLD_LongLandscapeFitToWidth = (45+270+73)/270;

function reorganise() {
  ratio = window.innerWidth / window.innerHeight;
  if (ratio < THRESHOLD_LongPortraitFitToWidth) {arrange_LongPortraitFitToWidth();
  } else if (ratio < THRESHOLD_LongPortraitFitToHeight) {arrange_LongPortraitFitToHeight();
  } else if (ratio < THRESHOLD_ShortPortraitFitToWidth) {arrange_ShortPortraitFitToWidth();
  } else if (ratio < THRESHOLD_ShortPortraitFitToHeight) {arrange_ShortPortraitFitToHeight();
  } else if (ratio < THRESHOLD_ShortLandscapeFitToWidth) {arrange_ShortLandscapeFitToWidth();
  } else if (ratio < THRESHOLD_ShortLandscapeFitToHeight) {arrange_ShortLandscapeFitToHeight();
  } else if (ratio < THRESHOLD_LongLandscapeFitToWidth) {arrange_LongLandscapeFitToWidth();
  } else {arrange_LongLandscapeFitToHeight();
  }
}

function arrange_LongPortraitFitToWidth() {
  document.getElementById('div-title-west').style.display = 'none';
  document.getElementById('div-title-north').style.display = 'inline';
  document.getElementById('div-info-east').style.display = 'none';
  document.getElementById('div-info-south').style.display = 'inline';

  var w = window.innerWidth;
  document.getElementById('div-title-north').style.width = w.toString().concat('px');
  document.getElementById('div-title-north').style.height = (w/6).toString().concat('px');
  document.getElementById('div-board-area').style.width = w.toString().concat('px');
  document.getElementById('div-board-area').style.height = w.toString().concat('px');
  document.getElementById('div-info-south').style.width = w.toString().concat('px');
  document.getElementById('div-info-south').style.height = (window.innerHeight-w*7/6).toString().concat('px');

  document.getElementById('board-canvas').style.width = w.toString().concat('px');
  document.getElementById('board-canvas').style.height = w.toString().concat('px');
}

function arrange_LongPortraitFitToHeight() {
  document.getElementById('div-title-west').style.display = 'none';
  document.getElementById('div-title-north').style.display = 'inline';
  document.getElementById('div-info-east').style.display = 'none';
  document.getElementById('div-info-south').style.display = 'inline';

  var w = window.innerHeight * THRESHOLD_LongPortraitFitToWidth;
  document.getElementById('div-title-north').style.width = w.toString().concat('px');
  document.getElementById('div-title-north').style.height = (w/6).toString().concat('px');
  document.getElementById('div-board-area').style.width = w.toString().concat('px');
  document.getElementById('div-board-area').style.height = w.toString().concat('px');
  document.getElementById('div-info-south').style.width = w.toString().concat('px');
  document.getElementById('div-info-south').style.height = (window.innerHeight-w*7/6).toString().concat('px');

  document.getElementById('board-canvas').style.width = w.toString().concat('px');
  document.getElementById('board-canvas').style.height = w.toString().concat('px');
}

function arrange_ShortPortraitFitToWidth() {
  document.getElementById('div-title-north').style.display = 'none';
  document.getElementById('div-title-west').style.display = 'inline';
  document.getElementById('div-info-east').style.display = 'none';
  document.getElementById('div-info-south').style.display = 'inline';

  var w = window.innerWidth;
  document.getElementById('div-title-west').style.width = (w/7).toString().concat('px');
  document.getElementById('div-title-west').style.height = (w*6/7).toString().concat('px');
  document.getElementById('div-board-area').style.width = (w*6/7).toString().concat('px');
  document.getElementById('div-board-area').style.height = (w*6/7).toString().concat('px');
  document.getElementById('div-info-south').style.width = w.toString().concat('px');
  document.getElementById('div-info-south').style.height = (window.innerHeight-w*6/7).toString().concat('px');

  document.getElementById('board-canvas').style.width = (w*6/7).toString().concat('px');
  document.getElementById('board-canvas').style.height = (w*6/7).toString().concat('px');
}

function arrange_ShortPortraitFitToHeight() {
  document.getElementById('div-title-north').style.display = 'none';
  document.getElementById('div-title-west').style.display = 'inline';
  document.getElementById('div-info-east').style.display = 'none';
  document.getElementById('div-info-south').style.display = 'inline';

  var w = window.innerHeight * THRESHOLD_ShortPortraitFitToWidth;
  document.getElementById('div-title-west').style.width = (w/7).toString().concat('px');
  document.getElementById('div-title-west').style.height = (w*6/7).toString().concat('px');
  document.getElementById('div-board-area').style.width = (w*6/7).toString().concat('px');
  document.getElementById('div-board-area').style.height = (w*6/7).toString().concat('px');
  document.getElementById('div-info-south').style.width = w.toString().concat('px');
  document.getElementById('div-info-south').style.height = (window.innerHeight-w*6/7).toString().concat('px');

  document.getElementById('board-canvas').style.width = (w*6/7).toString().concat('px');
  document.getElementById('board-canvas').style.height = (w*6/7).toString().concat('px');
}

function arrange_ShortLandscapeFitToWidth() {
  document.getElementById('div-title-west').style.display = 'none';
  document.getElementById('div-title-north').style.display = 'inline';
  document.getElementById('div-info-south').style.display = 'none';
  document.getElementById('div-info-east').style.display = 'inline';

  var h = window.innerWidth * THRESHOLD_ShortPortraitFitToWidth;
  document.getElementById('div-title-north').style.width = (h*6/7).toString().concat('px');
  document.getElementById('div-title-north').style.height = (h/7).toString().concat('px');
  document.getElementById('div-board-area').style.width = (h*6/7).toString().concat('px');
  document.getElementById('div-board-area').style.height = (h*6/7).toString().concat('px');
  document.getElementById('div-info-east').style.width = (window.innerWidth-h*6/7).toString().concat('px');
  document.getElementById('div-info-east').style.height = h.toString().concat('px');

  document.getElementById('board-canvas').style.width = (h*6/7).toString().concat('px');
  document.getElementById('board-canvas').style.height = (h*6/7).toString().concat('px');
}

function arrange_ShortLandscapeFitToHeight() {
  document.getElementById('div-title-west').style.display = 'none';
  document.getElementById('div-title-north').style.display = 'inline';
  document.getElementById('div-info-south').style.display = 'none';
  document.getElementById('div-info-east').style.display = 'inline';

  var h = window.innerHeight;
  document.getElementById('div-title-north').style.width = (h*6/7).toString().concat('px');
  document.getElementById('div-title-north').style.height = (h/7).toString().concat('px');
  document.getElementById('div-board-area').style.width = (h*6/7).toString().concat('px');
  document.getElementById('div-board-area').style.height = (h*6/7).toString().concat('px');
  document.getElementById('div-info-east').style.width = (window.innerWidth-h*6/7).toString().concat('px');
  document.getElementById('div-info-east').style.height = h.toString().concat('px');

  document.getElementById('board-canvas').style.width = (h*6/7).toString().concat('px');
  document.getElementById('board-canvas').style.height = (h*6/7).toString().concat('px');
}

function arrange_LongLandscapeFitToWidth() {
  document.getElementById('div-title-north').style.display = 'none';
  document.getElementById('div-title-west').style.display = 'inline';
  document.getElementById('div-info-south').style.display = 'none';
  document.getElementById('div-info-east').style.display = 'inline';

  var h  = window.innerWidth * THRESHOLD_LongPortraitFitToWidth;
  document.getElementById('div-title-west').style.width = (h/6).toString().concat('px');
  document.getElementById('div-title-west').style.height = h.toString().concat('px');
  document.getElementById('div-board-area').style.width = h.toString().concat('px');
  document.getElementById('div-board-area').style.height = h.toString().concat('px');
  document.getElementById('div-info-east').style.width = (window.innerWidth-h*7/6).toString().concat('px');
  document.getElementById('div-info-east').style.height = h.toString().concat('px');

  document.getElementById('board-canvas').style.width = h.toString().concat('px');
  document.getElementById('board-canvas').style.height = h.toString().concat('px');
}

function arrange_LongLandscapeFitToHeight() {
  document.getElementById('div-title-north').style.display = 'none';
  document.getElementById('div-title-west').style.display = 'inline';
  document.getElementById('div-info-south').style.display = 'none';
  document.getElementById('div-info-east').style.display = 'inline';

  var h  = window.innerHeight;
  document.getElementById('div-title-west').style.width = (h/6).toString().concat('px');
  document.getElementById('div-title-west').style.height = h.toString().concat('px');
  document.getElementById('div-board-area').style.width = h.toString().concat('px');
  document.getElementById('div-board-area').style.height = h.toString().concat('px');
  document.getElementById('div-info-east').style.width = (window.innerWidth-h*7/6).toString().concat('px');
  document.getElementById('div-info-east').style.height = h.toString().concat('px');

  document.getElementById('board-canvas').style.width = h.toString().concat('px');
  document.getElementById('board-canvas').style.height = h.toString().concat('px');
}

window.onresize = reorganise;
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var bufrw = require('bufrw');
var inherits = require('util').inherits;
var errors = require('../errors');

// TODO: different struct pattern that doesn't realize a temporary list of
// [key, val] tuples may be better. At the very least, such structure would
// allow for more precise error reporting.

function HeaderRW(countrw, keyrw, valrw, options) {
    if (!(this instanceof HeaderRW)) {
        return new HeaderRW(countrw, keyrw, valrw, options);
    }
    var self = this;
    self.countrw = countrw;
    self.keyrw = keyrw;
    self.valrw = valrw;
    self.enforceHeaderCount = options.enforceHeaderCount;
    self.enforceKeyLength = options.enforceKeyLength;
    bufrw.Base.call(self);
}
inherits(HeaderRW, bufrw.Base);

HeaderRW.prototype.byteLength = function byteLength(headers) {
    var self = this;
    var length = 0;
    var keys = Object.keys(headers);
    var res;

    length += self.countrw.width;

    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        res = self.keyrw.byteLength(key);
        if (res.err) return res;
        length += res.length;

        res = self.valrw.byteLength(headers[key]);
        if (res.err) return res;
        length += res.length;
    }

    return bufrw.LengthResult.just(length);
};

HeaderRW.prototype.writeInto = function writeInto(headers, buffer, offset) {
    var self = this;
    var keys = Object.keys(headers);
    var res;

    res = self.countrw.writeInto(keys.length, buffer, offset);

    if (self.enforceHeaderCount && keys.length > 128) {
        return bufrw.WriteResult.error(errors.TooManyHeaders({
            offset: offset,
            endOffset: res.offset,
            count: keys.length
        }), offset);
    }

    for (var i = 0; i < keys.length; i++) {
        if (res.err) return res;
        offset = res.offset;

        var key = keys[i];
        // TODO: Check that its' 16 bytes
        if (self.enforceKeyLength && key.length > 16) {
            return bufrw.WriteResult.error(errors.TransportHeaderTooLong({
                offset: offset,
                endOffset: res.offset,
                headerName: key
            }), offset);
        }

        res = self.keyrw.writeInto(key, buffer, offset);
        if (res.err) return res;
        offset = res.offset;

        res = self.valrw.writeInto(headers[key], buffer, offset);
    }

    return res;
};

HeaderRW.prototype.readFrom = function readFrom(buffer, offset) {
    var self = this;
    var headers = {};
    var start = 0;
    var n = 0;
    var key = '';
    var val = '';
    var res;

    res = self.countrw.readFrom(buffer, offset);
    if (res.err) return res;
    offset = res.offset;
    n = res.value;

    if (self.enforceHeaderCount && n > 128) {
        return bufrw.ReadResult.error(errors.TooManyHeaders({
            offset: offset,
            endOffset: res.offset,
            count: n
        }), offset, headers);
    }

    for (var i = 0; i < n; i++) {
        start = offset;

        res = self.keyrw.readFrom(buffer, offset);
        if (res.err) return res;
        key = res.value;

        if (!key.length) {
            return bufrw.ReadResult.error(errors.NullKeyError({
                offset: offset,
                endOffset: res.offset
            }), offset, headers);
        // TODO: check key is 16 bytes; not 16 characters
        } else if (self.enforceKeyLength && key.length > 16) {
            return bufrw.ReadResult.error(errors.TransportHeaderTooLong({
                offset: offset,
                endOffset: res.offset,
                headerName: key
            }), offset, headers);
        }
        offset = res.offset;

        res = self.valrw.readFrom(buffer, offset);
        if (res.err) return res;
        val = res.value;

        if (headers[key] !== undefined) {
            return bufrw.ReadResult.error(errors.DuplicateHeaderKeyError({
                offset: start,
                endOffset: res.offset,
                key: key,
                value: val,
                priorValue: headers[key]
            }), offset, headers);
        }
        offset = res.offset;

        headers[key] = val;
    }

    return bufrw.ReadResult.just(offset, headers);
};

module.exports = HeaderRW;

// nh:1 (hk~1 hv~1){nh}
module.exports.header1 = HeaderRW(bufrw.UInt8, bufrw.str1, bufrw.str1, {
    enforceHeaderCount: true,
    enforceKeyLength: true
});

// nh:2 (hk~2 hv~2){nh}
module.exports.header2 = HeaderRW(bufrw.UInt16BE, bufrw.str2, bufrw.str2, {
    enforceHeaderCount: false,
    enforceKeyLength: false
});
<commit_msg>v2/header: use maxHeaderCount and maxKeyLength<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var bufrw = require('bufrw');
var inherits = require('util').inherits;
var errors = require('../errors');

// TODO: different struct pattern that doesn't realize a temporary list of
// [key, val] tuples may be better. At the very least, such structure would
// allow for more precise error reporting.

function HeaderRW(countrw, keyrw, valrw, options) {
    if (!(this instanceof HeaderRW)) {
        return new HeaderRW(countrw, keyrw, valrw, options);
    }
    var self = this;
    self.countrw = countrw;
    self.keyrw = keyrw;
    self.valrw = valrw;
    self.maxHeaderCount = options.maxHeaderCount;
    self.maxKeyLength = options.maxKeyLength;
    bufrw.Base.call(self);
}
inherits(HeaderRW, bufrw.Base);

HeaderRW.prototype.byteLength = function byteLength(headers) {
    var self = this;
    var length = 0;
    var keys = Object.keys(headers);
    var res;

    length += self.countrw.width;

    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        res = self.keyrw.byteLength(key);
        if (res.err) return res;
        length += res.length;

        res = self.valrw.byteLength(headers[key]);
        if (res.err) return res;
        length += res.length;
    }

    return bufrw.LengthResult.just(length);
};

HeaderRW.prototype.writeInto = function writeInto(headers, buffer, offset) {
    var self = this;
    var keys = Object.keys(headers);
    var res;

    res = self.countrw.writeInto(keys.length, buffer, offset);

    if (keys.length > self.maxHeaderCount) {
        return bufrw.WriteResult.error(errors.TooManyHeaders({
            offset: offset,
            endOffset: res.offset,
            count: keys.length
        }), offset);
    }

    for (var i = 0; i < keys.length; i++) {
        if (res.err) return res;
        offset = res.offset;

        var key = keys[i];
        // TODO: Check that its' 16 bytes
        if (key.length > self.maxKeyLength) {
            return bufrw.WriteResult.error(errors.TransportHeaderTooLong({
                offset: offset,
                endOffset: res.offset,
                headerName: key
            }), offset);
        }

        res = self.keyrw.writeInto(key, buffer, offset);
        if (res.err) return res;
        offset = res.offset;

        res = self.valrw.writeInto(headers[key], buffer, offset);
    }

    return res;
};

HeaderRW.prototype.readFrom = function readFrom(buffer, offset) {
    var self = this;
    var headers = {};
    var start = 0;
    var n = 0;
    var key = '';
    var val = '';
    var res;

    res = self.countrw.readFrom(buffer, offset);
    if (res.err) return res;
    offset = res.offset;
    n = res.value;

    if (n > self.maxHeaderCount) {
        return bufrw.ReadResult.error(errors.TooManyHeaders({
            offset: offset,
            endOffset: res.offset,
            count: n
        }), offset, headers);
    }

    for (var i = 0; i < n; i++) {
        start = offset;

        res = self.keyrw.readFrom(buffer, offset);
        if (res.err) return res;
        key = res.value;

        if (!key.length) {
            return bufrw.ReadResult.error(errors.NullKeyError({
                offset: offset,
                endOffset: res.offset
            }), offset, headers);
        // TODO: check key is 16 bytes; not 16 characters
        } else if (key.length > self.maxKeyLength) {
            return bufrw.ReadResult.error(errors.TransportHeaderTooLong({
                offset: offset,
                endOffset: res.offset,
                headerName: key
            }), offset, headers);
        }
        offset = res.offset;

        res = self.valrw.readFrom(buffer, offset);
        if (res.err) return res;
        val = res.value;

        if (headers[key] !== undefined) {
            return bufrw.ReadResult.error(errors.DuplicateHeaderKeyError({
                offset: start,
                endOffset: res.offset,
                key: key,
                value: val,
                priorValue: headers[key]
            }), offset, headers);
        }
        offset = res.offset;

        headers[key] = val;
    }

    return bufrw.ReadResult.just(offset, headers);
};

module.exports = HeaderRW;

// nh:1 (hk~1 hv~1){nh}
module.exports.header1 = HeaderRW(bufrw.UInt8, bufrw.str1, bufrw.str1, {
    maxHeaderCount: 128,
    maxKeyLength: 16
});

// nh:2 (hk~2 hv~2){nh}
module.exports.header2 = HeaderRW(bufrw.UInt16BE, bufrw.str2, bufrw.str2, {
    maxHeaderCount: Infinity,
    maxKeyLength: Infinity
});
<|endoftext|>


<commit_before>    function startIntro(){
        var intro = introJs();
          intro.setOptions({
            steps: [
              {
                intro: "This tutorial will help you use metasearch. A search " +
                "tool intended to help you find MRI data shared publicly on " +
                "the Web. It is provided by the Open Neuroimaging Laboratory " +
                "project as a companion to the BrainBox project. " +
                "If you have MRI data to publish, please visit: " +
                "" +
                "MetaSearch on Github and post " +
                "an issue."
              },
              {
                element: "#filter",
                intro: "You can interactively filter your data using this " +
                "interactive parallel coordinates plot. You can drag along a " +
                "column to brush or select elements. Clicking anywhere " +
                "outside the selected area on the column will reset the " +
                "selection. Clicking on a column header will color the data " +
                "by z-score if the data are numeric. You can also reorder " +
                "columns by dragging a column header left or right.",
                position: 'bottom'
              },
              {
                element: '#keep-data',
                intro: "After you have created a selection, this button helps" +
                " reduce the data you are manipulating to just the selection.",
                position: 'bottom'
              },
              {
                element: '#exclude-data',
                intro: "This button is the reverse of keep and removes the " +
                "selection from dataset and draws the remaining data. You can" +
                "repeat this process to remove different sets of data at a time.",
                position: 'bottom'
              },
              {
                element: '#reset-data',
                intro: 'This button resets the data to the original dataset.',
                position: 'bottom'
              },
              {
                element: '#post-data',
                intro: 'This button uses the selected data to create a CSV ' +
                'table for use in BrainBox ' +
                'to generate a new project. It limits the selection to ' +
                'participants with MRI data.',
                position: 'bottom'
              },
              {
                element: '#grid',
                intro: 'This grid shows the selected data in tabular form. ' +
                'Each column can be sorted by clicking on the header. The ' +
                'BrainBox link under the MRI column will open the MRI using BrainBox when ' +
                'available. Hovering on any row shows the corresponding data ' +
                'on the parallel coordinate display as a line.',
                position: 'top'
              },
              {
                element: '#pager',
                intro: 'This displays the total number of data rows and ' +
                'allows paginating the display using the button on the right.',
                position: 'top'
              },
              {
                element: '#github',
                intro: 'Contribute data and code by joining the ' +
                '' +
                'MetaSearch Project!',
                position: 'bottom'
              },
              {
                element: '#tutorial',
                intro: 'That\'s it for now. Please provide feedback using ' +
                'Neurostars!',
                position: 'bottom'
              }
            ]
          });
          intro.start();
      }
<commit_msg>some help changes<commit_after>    function startIntro(){
        var intro = introJs();
          intro.setOptions({
            steps: [
              {
                intro: "This tutorial will help you use metasearch, a search " +
                "tool intended to help you find MRI data shared publicly on " +
                "the Web. It is provided by the Open Neuroimaging Laboratory " +
                "project as a companion to the BrainBox, a brain " +
                "curation and annotation tool. " +
                "If you want to see your data on MetaSearch, please " +
                "" +
                "let us know"
              },
              {
                element: "#filter",
                intro: "You can interactively filter your data using this " +
                "interactive parallel coordinates plot. You can drag along a " +
                "column to brush or select elements. Clicking anywhere " +
                "outside the selected area on the column will reset the " +
                "selection. Clicking on a column header will color the data " +
                "by z-score if the data are numeric. You can also reorder " +
                "columns by dragging a column header left or right.",
                position: 'bottom'
              },
              {
                element: '#keep-data',
                intro: "After you have created a selection, this button helps" +
                " reduce the data you are manipulating to just the selection.",
                position: 'bottom'
              },
              {
                element: '#exclude-data',
                intro: "This button is the reverse of keep and removes the " +
                "selection from dataset and draws the remaining data. You can" +
                "repeat this process to remove different sets of data at a time.",
                position: 'bottom'
              },
              {
                element: '#reset-data',
                intro: 'This button resets the data to the original dataset.',
                position: 'bottom'
              },
              {
                element: '#post-data',
                intro: 'This button uses the selected data to create a CSV ' +
                'table for use in BrainBox ' +
                'to generate a new project. It limits the selection to ' +
                'participants with MRI data.',
                position: 'bottom'
              },
              {
                element: '#grid',
                intro: 'This grid shows the selected data in tabular form. ' +
                'Each column can be sorted by clicking on the header. The ' +
                'BrainBox link under the MRI column will open the MRI using BrainBox when ' +
                'available. Hovering on any row shows the corresponding data ' +
                'on the parallel coordinate display as a line.',
                position: 'top'
              },
              {
                element: '#pager',
                intro: 'This displays the total number of data rows and ' +
                'allows paginating the display using the button on the right.',
                position: 'top'
              },
              {
                element: '#github',
                intro: 'Contribute data and code by joining the ' +
                '' +
                'MetaSearch Project!',
                position: 'bottom'
              },
              {
                element: '#tutorial',
                intro: 'That\'s it for now. Please provide feedback using ' +
                'Neurostars!',
                position: 'bottom'
              }
            ]
          });
          intro.start();
      }
<|endoftext|>


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

/*
 * This validator is defined by a grammar, which is
 *    grammar : [ "block", string ]
 *            | [ "zeroOrMore" | "oneOrMore" | "optional", list of 1 grammar element ]
 *            | [ "choice" | "interleave", list of grammar elements  ]
 *
 * Example: [ 'oneOrMore', [
 *             [ 'interleave', [
 *                ['block', 'A'],
 *                ['zeroOrMore', [
 *                   ['block', 'D']
 *                ] ],
 *                ['block', 'B'],
 *                ['optional', [
 *                   ['block', 'C']
 *                ] ],
 *                ['choice', [
 *                   ['block', 'C'],
 *                   ['block', 'E']
 *                ] ]
 *             ] ]
 *          ] ];
 *
 * The grammar is to be validated against a list of block names like:
 *    [ 'A', 'C', 'B', 'A', 'B', 'C', 'A', 'D', 'E', 'B' ],
 *
 * The validator is a function that reads the list and tries to match it
 * against the grammar. A list is validated only if it entirely matches the
 * entire grammar. For instance, ['A', 'B'] does not match ['block', A']
 *
 * Validator is the object that will do the recursion.  Validator
 * implements a validator per magic_name and a dispatcher that calls the
 * right _validate method for the current magic_name.  It uses
 * IndexSet as an intermediate way of storing the matches.
 * IndexSet contains the first index of the list that is not yet
 * matched.  For instance, if we've validated the first two elements of a
 * list, _indexes will be [2]. The validator may then try to extend the
 * validation for position 2 onwards. _indexes is empty if nothing has
 * matched. The list is considered fully validated if _indexes contains the
 * end-of-list position.
 * The recursion is depth first, with an option to end it as soon as we've
 * found a full match.
 *
 */

/* *************
 * Structure that holds the result of the validator.
 * *************/

function IndexSet() {
    this._indexes_lookup = {};  // To keep distinct indexes
    this._indexes = [];         // All the keys in the object are transformed to string, so we keep the integers in this list
    Array.prototype.slice.call(arguments).map(this.addIndex, this);     // Extra constructor parameters are assumed to be indexes to add
}

// The validation is a success if _indexes is not empty
IndexSet.prototype.isEmpty = function() {
    return this._indexes.length == 0;
};

// getter to protect the internal variable
IndexSet.prototype.getIndexes = function() {
    // Returns a copy to make sure the caller doesn't modify our internal structure
    return this._indexes.slice();
};

// add a new index to the list, avoiding repetitions
IndexSet.prototype.addIndex = function(i) {
    if (!(i in this._indexes_lookup)) {
        this._indexes_lookup[i] = 1;
        this._indexes.push(i);
    }
    return this;
};

// wrapper around addIndex to add all the indexes of a IndexSet into another
IndexSet.prototype.extendWithOtherSet = function(r) {
    r.getIndexes().map(this.addIndex, this);
    return this;
};

// tells whether the set contains the index of the end of a Validator's list
IndexSet.prototype.hasEndOfList = function(v) {
    return (v._list.length in this._indexes_lookup);
};

// string representation
IndexSet.prototype.toString = function() {
    return "Matching indexes: " + (this.isEmpty() ? "empty" : JSON.stringify(this.getIndexes()));
};

/* *************
 * Structure that holds a validator.
 * It is initialized with a grammar and has a validate() method that checks
 * whether the given list matches the grammar
 * *************/

function Validator(grammar) {
    this._grammar = grammar;
}

Validator.prototype.validate = function(list) {
    this._list = list;
    this._indent = "";
    this._cache = {};
    var x = this._pair_dispatcher(this._grammar, 0, true);
    return x.hasEndOfList(this);
};

// Returns the simplest instance of a IndexSet that reports that the
// list is fully validated. This is used to discard partial matches and
// prune parts of the search tree (some kind of branch-and-bound approach)
Validator.prototype.bestResult = function(r) {
    return new IndexSet(this._list.length);
};

// Helper method to print indented debug statements to the console
Validator.prototype.debug = function() {
    var args = Array.prototype.slice.call(arguments);
    args.unshift(this._indent);
    Function.apply.call(console.log, console, args);
};

Validator.prototype._validate_block = function(expectedBlockName, i, mustUseAll) {
    if (i == this._list.length) {
        this.debug("!", "exhausted");
        return new IndexSet();
    } else if (this._list[i] == expectedBlockName) {
        return new IndexSet(i+1);
    } else {
        return new IndexSet();
    }
};

Validator.prototype._validate_oneOrMore = function(patterns, i, mustUseAll) {
    // We can assume that patterns is a list with a single element
    var result = new IndexSet();
    var indexes_to_test = [i];
    var indexes_tested = {};
    while (indexes_to_test.length > 0) {
        var j = indexes_to_test.shift();
        if (j in indexes_tested) {
            continue;
        }
        indexes_tested[j] = 1;
        var x = this._pair_dispatcher(patterns[0], j, mustUseAll);
        if (mustUseAll && x.hasEndOfList(this)) {
            // quick bail-out
            return x;
        }
        result.extendWithOtherSet(x);
        Array.prototype.push.apply(indexes_to_test, x.getIndexes());
    }
    return result;
};

Validator.prototype._validate_zeroOrMore = function(patterns, i, mustUseAll) {
    if (i == this._list.length) {
        // quick bail-out
        return new IndexSet(i);
    }
    // zeroOrMore always matches, but we need to call validate_oneOrMore
    // too to check for potential repetitions
    var result = new IndexSet(i);
    var x = this._named_dispatcher("oneOrMore", patterns, i, mustUseAll);
    result.extendWithOtherSet(x);
    return result;
};

Validator.prototype._validate_optional = function(patterns, i, mustUseAll) {
    if (i == this._list.length) {
        // quick bail-out
        return new IndexSet(i);
    }
    // optional always matches, but we need to check the actual pattern too
    // We can assume that patterns is a list with a single element
    var result = new IndexSet(i);
    var x = this._pair_dispatcher(patterns[0], i, mustUseAll);
    result.extendWithOtherSet(x);
    return result;
};

Validator.prototype._validate_choice = function(patterns, i, mustUseAll) {
    if (patterns.length == 0) {
        return new IndexSet(i);
    }
    // Simply test each element of patterns
    var result = new IndexSet();
    for(var ind=0; ind<patterns.length; ind++) {
        var x = this._pair_dispatcher(patterns[ind], i, mustUseAll);
        if (mustUseAll && x.hasEndOfList(this)) {
            // quick bail-out
            return x;
        }
        result.extendWithOtherSet(x);
    }
    return result;
};

Validator.prototype._validate_interleave = function(patterns, i, mustUseAll) {
    if (patterns.length == 0) {
        return new IndexSet(i);
    } else if (patterns.length == 1) {
        // Trivial interleave, defer
        return this._pair_dispatcher(patterns[0], i, mustUseAll);
    }
    // We try to validate each element
    var result = new IndexSet();
    for(var ind=0; ind<patterns.length; ind++) {
        var x = this._pair_dispatcher(patterns[ind], i, false);
        if (!x.isEmpty()) {
            // Whenever there is a match we try to validate an interleave made of the remaining patterns
            var remaining_patterns = JSON.parse(JSON.stringify(patterns));
            remaining_patterns.splice(ind, 1);
            var all_indexes = x.getIndexes();
            for(var ind2=0; ind2<all_indexes.length; ind2++) {
                var y = this._named_dispatcher("interleave", remaining_patterns, all_indexes[ind2], mustUseAll);
                if (mustUseAll && y.hasEndOfList(this)) {
                    // quick bail-out
                    return y;
                }
                result.extendWithOtherSet(y);
            }
        }
    }
    return result;
};

// Choose the appropriate _validate_* method based on magic_name
// Results are memoized into this._cache to avoid repeating the same validation.
// The _validate_* methods could be calling each other, but they rather come back
// to the dispatcher which ensures that we're not repeating the same calls.
Validator.prototype._named_dispatcher = function(magic_name, content, i, mustUseAll) {
    this.debug(">", magic_name, JSON.stringify(content), i);

    var key = JSON.stringify(Array.prototype.slice.call(arguments));
    if (key in this._cache) {
        this.debug("!", "cached", this._cache[key].toString());
        return this._cache[key];
    }

    var back_indent = this._indent;
    this._indent = this._indent + "  ";

    var f = {
        "block": this._validate_block,
        "oneOrMore": this._validate_oneOrMore,
        "zeroOrMore": this._validate_zeroOrMore,
        "optional": this._validate_optional,
        "choice": this._validate_choice,
        "interleave": this._validate_interleave
    }[magic_name];
    var x = f.call(this, content, i, mustUseAll);

    if (mustUseAll && x.hasEndOfList(this)) {
        // All we are interested in is the fact there is a full match
        // We can discard the other indexes
        x = this.bestResult();
    }

    this._indent = back_indent;
    this.debug("<", x.toString());
    this._cache[key] = x;
    return x;
};

// Wrapper around _named_dispatcher that understands pairs (array) like (magic_name, content)
Validator.prototype._pair_dispatcher = function(pair, i, mustUseAll) {
    return this._named_dispatcher(pair[0], pair[1], i, mustUseAll);
};

function assert_Validator(grammar, list, expected) {
    var v = new Validator(grammar);
    var x = v.validate(list);
    console.log(expected == x ? "OK" : "FAIL", JSON.stringify(list), "vs", JSON.stringify(grammar));
}

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

/*
 * This validator is defined by a grammar, which is
 *    grammar : [ "block", string ]
 *            | [ "zeroOrMore" | "oneOrMore" | "optional", list of 1 grammar element ]
 *            | [ "choice" | "interleave", list of grammar elements  ]
 *
 * Example: [ 'oneOrMore', [
 *             [ 'interleave', [
 *                ['block', 'A'],
 *                ['zeroOrMore', [
 *                   ['block', 'D']
 *                ] ],
 *                ['block', 'B'],
 *                ['optional', [
 *                   ['block', 'C']
 *                ] ],
 *                ['choice', [
 *                   ['block', 'C'],
 *                   ['block', 'E']
 *                ] ]
 *             ] ]
 *          ] ];
 *
 * The grammar is to be validated against a list of block names like:
 *    [ 'A', 'C', 'B', 'A', 'B', 'C', 'A', 'D', 'E', 'B' ],
 *
 * The validator is a function that reads the list and tries to match it
 * against the grammar. A list is validated only if it entirely matches the
 * entire grammar. For instance, ['A', 'B'] does not match ['block', A']
 *
 * Validator is the object that will do the recursion.  Validator
 * implements a validator per magic_name and a dispatcher that calls the
 * right _validate method for the current magic_name.  It uses
 * IndexSet as an intermediate way of storing the matches.
 * IndexSet contains the first index of the list that is not yet
 * matched.  For instance, if we've validated the first two elements of a
 * list, _indexes will be [2]. The validator may then try to extend the
 * validation for position 2 onwards. _indexes is empty if nothing has
 * matched. The list is considered fully validated if _indexes contains the
 * end-of-list position.
 * The recursion is depth first, with an option to end it as soon as we've
 * found a full match.
 *
 */

/* *************
 * Structure that holds the result of the validator.
 * *************/

function IndexSet() {
    this._indexes_lookup = {};  // To keep distinct indexes
    this._indexes = [];         // All the keys in the object are transformed to string, so we keep the integers in this list
    Array.prototype.slice.call(arguments).map(this.addIndex, this);     // Extra constructor parameters are assumed to be indexes to add
}

// The validation is a success if _indexes is not empty
IndexSet.prototype.isEmpty = function() {
    return this._indexes.length == 0;
};

// getter to protect the internal variable
IndexSet.prototype.getIndexes = function() {
    // Returns a copy to make sure the caller doesn't modify our internal structure
    return this._indexes.slice();
};

// add a new index to the list, avoiding repetitions
IndexSet.prototype.addIndex = function(i) {
    if (!(i in this._indexes_lookup)) {
        this._indexes_lookup[i] = 1;
        this._indexes.push(i);
    }
    return this;
};

// wrapper around addIndex to add all the indexes of a IndexSet into another
IndexSet.prototype.extendWithOtherSet = function(r) {
    r.getIndexes().map(this.addIndex, this);
    return this;
};

// tells whether the set contains the index of the end of a Validator's list
IndexSet.prototype.hasEndOfList = function(v) {
    return (v._list.length in this._indexes_lookup);
};

// string representation
IndexSet.prototype.toString = function() {
    return "Matching indexes: " + (this.isEmpty() ? "empty" : JSON.stringify(this.getIndexes()));
};

/* *************
 * Structure that holds a validator.
 * It is initialized with a grammar and has a validate() method that checks
 * whether the given list matches the grammar
 * *************/

function Validator(grammar) {
    this._grammar = grammar;
}

Validator.prototype.validate = function(list) {
    this._list = list;
    this._indent = "";
    this._cache = {};
    var x = this._pair_dispatcher(this._grammar, 0, true);
    return x.hasEndOfList(this);
};

// Helper method to print indented debug statements to the console
Validator.prototype.debug = function() {
    var args = Array.prototype.slice.call(arguments);
    args.unshift(this._indent);
    Function.apply.call(console.log, console, args);
};

Validator.prototype._validate_block = function(expectedBlockName, i, mustUseAll) {
    if (i == this._list.length) {
        this.debug("!", "exhausted");
        return new IndexSet();
    } else if (this._list[i] == expectedBlockName) {
        return new IndexSet(i+1);
    } else {
        return new IndexSet();
    }
};

Validator.prototype._validate_oneOrMore = function(patterns, i, mustUseAll) {
    // We can assume that patterns is a list with a single element
    var result = new IndexSet();
    var indexes_to_test = [i];
    var indexes_tested = {};
    while (indexes_to_test.length > 0) {
        var j = indexes_to_test.shift();
        if (j in indexes_tested) {
            continue;
        }
        indexes_tested[j] = 1;
        var x = this._pair_dispatcher(patterns[0], j, mustUseAll);
        if (mustUseAll && x.hasEndOfList(this)) {
            // quick bail-out
            return x;
        }
        result.extendWithOtherSet(x);
        Array.prototype.push.apply(indexes_to_test, x.getIndexes());
    }
    return result;
};

Validator.prototype._validate_zeroOrMore = function(patterns, i, mustUseAll) {
    if (i == this._list.length) {
        // quick bail-out
        return new IndexSet(i);
    }
    // zeroOrMore always matches, but we need to call validate_oneOrMore
    // too to check for potential repetitions
    var result = new IndexSet(i);
    var x = this._named_dispatcher("oneOrMore", patterns, i, mustUseAll);
    result.extendWithOtherSet(x);
    return result;
};

Validator.prototype._validate_optional = function(patterns, i, mustUseAll) {
    if (i == this._list.length) {
        // quick bail-out
        return new IndexSet(i);
    }
    // optional always matches, but we need to check the actual pattern too
    // We can assume that patterns is a list with a single element
    var result = new IndexSet(i);
    var x = this._pair_dispatcher(patterns[0], i, mustUseAll);
    result.extendWithOtherSet(x);
    return result;
};

Validator.prototype._validate_choice = function(patterns, i, mustUseAll) {
    if (patterns.length == 0) {
        return new IndexSet(i);
    }
    // Simply test each element of patterns
    var result = new IndexSet();
    for(var ind=0; ind<patterns.length; ind++) {
        var x = this._pair_dispatcher(patterns[ind], i, mustUseAll);
        if (mustUseAll && x.hasEndOfList(this)) {
            // quick bail-out
            return x;
        }
        result.extendWithOtherSet(x);
    }
    return result;
};

Validator.prototype._validate_interleave = function(patterns, i, mustUseAll) {
    if (patterns.length == 0) {
        return new IndexSet(i);
    } else if (patterns.length == 1) {
        // Trivial interleave, defer
        return this._pair_dispatcher(patterns[0], i, mustUseAll);
    }
    // We try to validate each element
    var result = new IndexSet();
    for(var ind=0; ind<patterns.length; ind++) {
        var x = this._pair_dispatcher(patterns[ind], i, false);
        if (!x.isEmpty()) {
            // Whenever there is a match we try to validate an interleave made of the remaining patterns
            var remaining_patterns = JSON.parse(JSON.stringify(patterns));
            remaining_patterns.splice(ind, 1);
            var all_indexes = x.getIndexes();
            for(var ind2=0; ind2<all_indexes.length; ind2++) {
                var y = this._named_dispatcher("interleave", remaining_patterns, all_indexes[ind2], mustUseAll);
                if (mustUseAll && y.hasEndOfList(this)) {
                    // quick bail-out
                    return y;
                }
                result.extendWithOtherSet(y);
            }
        }
    }
    return result;
};

// Choose the appropriate _validate_* method based on magic_name
// Results are memoized into this._cache to avoid repeating the same validation.
// The _validate_* methods could be calling each other, but they rather come back
// to the dispatcher which ensures that we're not repeating the same calls.
Validator.prototype._named_dispatcher = function(magic_name, content, i, mustUseAll) {
    this.debug(">", magic_name, JSON.stringify(content), i);

    var key = JSON.stringify(Array.prototype.slice.call(arguments));
    if (key in this._cache) {
        this.debug("!", "cached", this._cache[key].toString());
        return this._cache[key];
    }

    var back_indent = this._indent;
    this._indent = this._indent + "  ";

    var f = {
        "block": this._validate_block,
        "oneOrMore": this._validate_oneOrMore,
        "zeroOrMore": this._validate_zeroOrMore,
        "optional": this._validate_optional,
        "choice": this._validate_choice,
        "interleave": this._validate_interleave
    }[magic_name];
    var x = f.call(this, content, i, mustUseAll);

    if (mustUseAll && x.hasEndOfList(this)) {
        // All we are interested in is the fact there is a full match
        // We can discard the other indexes
        x = new IndexSet(this._list.length);
    }

    this._indent = back_indent;
    this.debug("<", x.toString());
    this._cache[key] = x;
    return x;
};

// Wrapper around _named_dispatcher that understands pairs (array) like (magic_name, content)
Validator.prototype._pair_dispatcher = function(pair, i, mustUseAll) {
    return this._named_dispatcher(pair[0], pair[1], i, mustUseAll);
};

function assert_Validator(grammar, list, expected) {
    var v = new Validator(grammar);
    var x = v.validate(list);
    console.log(expected == x ? "OK" : "FAIL", JSON.stringify(list), "vs", JSON.stringify(grammar));
}

<|endoftext|>


<commit_before>const { darken } = require('postcss-js-mixins/lib/colorHelpers');

let variables = {};

variables.unit = {
	default: 'rem',
	fontSize: 'rem',
	lineHeight: 'em'
};

variables.root = {
	fontSize: '62.5%'
};

variables.default = {
	radius: '3px',
	opacity: 0.2,
	duration: '0.2s',
	timing: 'ease-in-out'
};

variables.width = {
	min: 0,
	max: '1280px'
};

variables.bumper = {
	enabled: true,
	padding: '6%'
};

variables.block = {
	margin: {
		bottom: '4rem'
	}
};

variables.grid = {
	margin: '5%',
	columns: 8,
	spaceless: false
};

variables.colors = {
	primary: '#349bb9',
	secondary: '#70c1b3',
	tertiary: '#f18f01',
	info: '#00f',
	success: '#008000',
	warning: '#f00',
	white: '#fff',
	lightestGray: darken('#fff', 4),
	lighterGray: darken('#fff', 10),
	lightGray: darken('#fff', 25),
	gray: darken('#fff', 35),
	darkGray: darken('#fff', 55),
	darkerGray: darken('#fff', 65),
	darkestGray: darken('#fff', 75),
	black: '#000'
};

variables.colors.body = {
	background: variables.colors.white
};

variables.font = {
	color: variables.colors.darkestGray,
	family: 'Arial Helvetica sans-serif',
	size: '1.6rem',
	weight: {
		normal: 'normal',
		bold: 600
	},
	lineHeight: '1em'
};

variables.mark = {
	color: variables.font.color,
	background: 'yellow'
};

variables.abbr = {
	underline: 'dotted'
};

variables.border = {
	color: variables.colors.lightGray,
	style: 'solid',
	width: '1px'
};

variables.paragraph = {
	color: variables.font.color,
	weight: variables.font.weight.normal,
	lineHeight: '1.7em',
	margin: {
		bottom: '2rem'
	}
};

variables.figure = {
	borderColor: false,
	rounded: false,
	padding: variables.block.margin.bottom
};

variables.figCaption = {
	color: variables.colors.darkGray,
	fontStyle: 'italic',
	lineHeight: variables.paragraph.lineHeight
};

module.exports = variables;<commit_msg>Add link and selection variables<commit_after>const { darken } = require('postcss-js-mixins/lib/colorHelpers');

let variables = {};

variables.unit = {
	default: 'rem',
	fontSize: 'rem',
	lineHeight: 'em'
};

variables.root = {
	fontSize: '62.5%'
};

variables.default = {
	radius: '3px',
	opacity: 0.2,
	duration: '0.2s',
	timing: 'ease-in-out'
};

variables.width = {
	min: 0,
	max: '1280px'
};

variables.bumper = {
	enabled: true,
	padding: '6%'
};

variables.block = {
	margin: {
		bottom: '4rem'
	}
};

variables.grid = {
	margin: '5%',
	columns: 8,
	spaceless: false
};

variables.colors = {
	primary: '#349bb9',
	secondary: '#70c1b3',
	tertiary: '#f18f01',
	info: '#00f',
	success: '#008000',
	warning: '#f00',
	white: '#fff',
	lightestGray: darken('#fff', 4),
	lighterGray: darken('#fff', 10),
	lightGray: darken('#fff', 25),
	gray: darken('#fff', 35),
	darkGray: darken('#fff', 55),
	darkerGray: darken('#fff', 65),
	darkestGray: darken('#fff', 75),
	black: '#000'
};

variables.colors.body = {
	background: variables.colors.white
};

variables.font = {
	color: variables.colors.darkestGray,
	family: 'Arial Helvetica sans-serif',
	size: '1.6rem',
	weight: {
		normal: 'normal',
		bold: 600
	},
	lineHeight: '1em'
};

variables.mark = {
	color: variables.font.color,
	background: 'yellow'
};

variables.abbr = {
	underline: 'dotted'
};

variables.border = {
	color: variables.colors.lightGray,
	style: 'solid',
	width: '1px'
};

variables.paragraph = {
	color: variables.font.color,
	weight: variables.font.weight.normal,
	lineHeight: '1.7em',
	margin: {
		bottom: '2rem'
	}
};

variables.figure = {
	borderColor: false,
	rounded: false,
	padding: variables.block.margin.bottom
};

variables.figCaption = {
	color: variables.colors.darkGray,
	fontStyle: 'italic',
	lineHeight: variables.paragraph.lineHeight
};

variables.link = {
	color: variables.colors.primary,
	decoration: 'none'
};

variables.link.hover = {
	color: darken(variables.link.color, 10),
	decoration: 'none'
};

variables.link.active = {
	color: darken(variables.link.color, 20)
};

variables.selection = {
	color: variables.colors.white,
	background: variables.link.color
};

module.exports = variables;<|endoftext|>