<commit_before>define(['../Utils.js'], function(Utils) {

	var XMLHttpFactories = [
		function () {return new XMLHttpRequest()},
		function () {return new ActiveXObject('Msxml2.XMLHTTP')},
		function () {return new ActiveXObject('Msxml3.XMLHTTP')},
		function () {return new ActiveXObject('Microsoft.XMLHTTP')}
	];

	function createXMLHTTPObject() {
		var xmlhttp = false;
		for (var c = 0; c < XMLHttpFactories.length; c++) {
			try {
				xmlhttp = XMLHttpFactories[c]();
			} catch (e) { continue; }
			break;
		}
		return xmlhttp;
	}

	function doRequest(requestURI, success, fail, requestProps) {
		var request = createXMLHTTPObject();
		if (!request) return fail();

		if (!Utils.isObject(requestProps)) {
			requestProps = {};
		}

		var requestMethod = (
			requestProps.hasOwnProperty('method') &&
			Utils.isString(requestProps.method) &&
			requestProps.method || 'GET'
		);

		var requestHeaders = (
			requestProps.hasOwnProperty('headers') &&
			Utils.isObject(requestProps.headers) &&
			requestProps.headers || {}
		);

		var postData = null;

		if (requestProps.hasOwnProperty('data') &&
			!Utils.isUndefined(requestProps.data)) {
			postData = requestProps.data;
			if (!Utils.isObject(postData)) {
				postData = String(postData);
			}
		}

		try {
			request.open(requestMethod, requestURI, true);

			for (var headerName in requestHeaders) {
				if (requestHeaders.hasOwnProperty(headerName)) {
					request.setRequestHeader(headerName,
						requestHeaders[headerName]
					);
				}
			}

			request.onreadystatechange = function() {
				if (request.readyState !== 4) return;
				var status = request.status;
				if (status > 399 && status < 600) return fail();
				success(request.responseText);
			};

			if (Utils.isObject(postData)) {
				var postFields = [];
				for (var fieldName in postData) {
					if (postData.hasOwnProperty(fieldName)) {
						postFields.push(fieldName + '=' +
							encodeURIComponent(postData[fieldName])
						);
					}
				}
				postData = postFields.join('&');
				request.setRequestHeader('Content-type',
					'application/x-www-form-urlencoded'
				);
			}

			request.send(postData);

		} catch (e) { fail(); }
	}

	function removeCallback(callbackId) {
		delete window[callbackId];
		var scriptElement = document.getElementById(callbackId);
		scriptElement.parentNode.removeChild(scriptElement);
	}

	function doJSONPRequest(requestURI, success, fail, requestProps) {

		var requestQuery = [];
		var requestURI = Utils.uri.parse(requestURI);
		var requestParams = Utils.uri.parseQuery(requestURI.query);
		var callbackId = Utils.uniqueId('callback');
		requestParams.callback = callbackId;

		for (var paramName in requestParams) {
			if (requestParams.hasOwnProperty(paramName)) {
				requestQuery.push(paramName +
					'=' + requestParams[paramName]
				);
			}
		}

		requestURI = (
			(requestURI.scheme ? requestURI.scheme + '://' : '') +
			(requestURI.authority ? requestURI.authority : '') +
			(requestURI.path ? requestURI.path : '') +
			(requestQuery.length ? '?' + requestQuery.join('&') : '') +
			(requestURI.fragment ? '#' + requestURI.fragment : '')
		);

		window[callbackId] = success;

		var scriptElement = document.createElement('script');
		scriptElement.setAttribute('id', callbackId);
		scriptElement.setAttribute('src', requestURI);
		scriptElement.setAttribute('type', 'text/javascript');

		var removeCallback = removeCallback.bind(this, callbackId);
		scriptElement.onload = removeCallback;
		scriptElement.onerror = function() {
			removeCallback(); fail();
		};
		// scriptElement.onerror =
		// scriptElement.onreadystatechange =
		// removeCallback.bind(this, callbackId);

		document.getElementsByTagName('head')[0].appendChild(scriptElement);
	}

	return function(requestURI, success, fail, requestProps, isJSONP) {
		if (!isJSONP) doRequest(requestURI, success, fail, requestProps);
		else doJSONPRequest(requestURI, success, fail, requestProps);
	};

});<commit_msg>fix AJAXDriver JSONP request<commit_after>define(['../Utils.js'], function(Utils) {

	var XMLHttpFactories = [
		function () {return new XMLHttpRequest()},
		function () {return new ActiveXObject('Msxml2.XMLHTTP')},
		function () {return new ActiveXObject('Msxml3.XMLHTTP')},
		function () {return new ActiveXObject('Microsoft.XMLHTTP')}
	];

	function createXMLHTTPObject() {
		var xmlhttp = false;
		for (var c = 0; c < XMLHttpFactories.length; c++) {
			try {
				xmlhttp = XMLHttpFactories[c]();
			} catch (e) { continue; }
			break;
		}
		return xmlhttp;
	}

	function doRequest(requestURI, success, fail, requestProps) {
		var request = createXMLHTTPObject();
		if (!request) return fail();

		if (!Utils.isObject(requestProps)) {
			requestProps = {};
		}

		var requestMethod = (
			requestProps.hasOwnProperty('method') &&
			Utils.isString(requestProps.method) &&
			requestProps.method || 'GET'
		);

		var requestHeaders = (
			requestProps.hasOwnProperty('headers') &&
			Utils.isObject(requestProps.headers) &&
			requestProps.headers || {}
		);

		var postData = null;

		if (requestProps.hasOwnProperty('data') &&
			!Utils.isUndefined(requestProps.data)) {
			postData = requestProps.data;
			if (!Utils.isObject(postData)) {
				postData = String(postData);
			}
		}

		try {
			request.open(requestMethod, requestURI, true);

			for (var headerName in requestHeaders) {
				if (requestHeaders.hasOwnProperty(headerName)) {
					request.setRequestHeader(headerName,
						requestHeaders[headerName]
					);
				}
			}

			request.onreadystatechange = function() {
				if (request.readyState !== 4) return;
				var status = request.status;
				if (status > 399 && status < 600) return fail();
				success(request.responseText);
			};

			if (Utils.isObject(postData)) {
				var postFields = [];
				for (var fieldName in postData) {
					if (postData.hasOwnProperty(fieldName)) {
						postFields.push(fieldName + '=' +
							encodeURIComponent(postData[fieldName])
						);
					}
				}
				postData = postFields.join('&');
				request.setRequestHeader('Content-type',
					'application/x-www-form-urlencoded'
				);
			}

			request.send(postData);

		} catch (e) { fail(); }
	}

	function removeCallback(callbackId) {
		delete window[callbackId];
		var scriptElement = document.getElementById(callbackId);
		scriptElement.parentNode.removeChild(scriptElement);
	}

	function doJSONPRequest(requestURI, success, fail, requestProps) {

		var requestQuery = [];
		var requestURI = Utils.uri.parse(requestURI);
		var requestParams = Utils.uri.parseQuery(requestURI.query);
		var callbackId = Utils.uniqueId('callback');
		requestParams.callback = callbackId;

		for (var paramName in requestParams) {
			if (requestParams.hasOwnProperty(paramName)) {
				requestQuery.push(paramName +
					'=' + requestParams[paramName]
				);
			}
		}

		requestURI = (
			(requestURI.scheme ? requestURI.scheme + '://' : '') +
			(requestURI.authority ? requestURI.authority : '') +
			(requestURI.path ? requestURI.path : '') +
			(requestQuery.length ? '?' + requestQuery.join('&') : '') +
			(requestURI.fragment ? '#' + requestURI.fragment : '')
		);

		var cleanup = removeCallback.bind(this, callbackId);

		window[callbackId] = function(response) {
			cleanup();
			success(response);
		};

		var scriptElement = document.createElement('script');
		scriptElement.setAttribute('id', callbackId);
		scriptElement.setAttribute('src', requestURI);
		scriptElement.setAttribute('type', 'text/javascript');

		scriptElement.onerror = function() {
			cleanup();
			fail();
		};

		// scriptElement.onerror =
		// scriptElement.onreadystatechange =
		// removeCallback.bind(this, callbackId);

		document.getElementsByTagName('head')[0].appendChild(scriptElement);
	}

	return function(requestURI, success, fail, requestProps, isJSONP) {
		if (!isJSONP) doRequest(requestURI, success, fail, requestProps);
		else doJSONPRequest(requestURI, success, fail, requestProps);
	};

});<|endoftext|>


<commit_before>(function ($) {
  "use strict";

  addAnswersToSessionStorage();

  $('.carousel').carousel({
    indicators: true,
    shift: 100
  });

  [
    "sleep__range"
  ].forEach(range => {
    if (document.getElementsByClassName(range)[0]){
      var node = document.getElementsByClassName(range)[0];
      addOnInputToElement( node, sleepingLion );
    }
  });

  function addAnswersToSessionStorage(){
    var personality = [];
    var hobbies = [];

    [
      "strange",
      "happy",
      "angry",
      "fun",
      "boring",
      "kind",
      "sad"
    ].forEach(emotion => {
      var node = document.getElementById(emotion);
      addClassToNode(node, 'pop');
      addClickEventArray('personality', node, emotion, personality);
    });

    [
      "sad-emoji",
      "happy-emoji",
      "indifferent-emoji"
    ].forEach(emoji => {
      var node = document.getElementsByClassName(emoji)[0];
      addClickEventSingle('feelings', node, emoji.match(/^[a-z]+/));
    });

    [
      "name",
      "age"
    ].forEach(inputField => {
      var node = document.getElementsByClassName(inputField)[0];
      addKeyupEvent(inputField, node);
    });

    [
      "football",
      "tennis",
      "gymnastics",
      "dance",
      "drawing",
      "photography",
      "cooking",
      "gardening",
      "puzzles",
      "camping",
      "fishing",
      "walking",
      "gymnastics-mobile",
      "photography-mobile",
      "walking-mobile",
      "puzzles-mobile"
    ].forEach(hobby => {
      var node = document.getElementsByClassName(hobby)[0];
      addClassToNode(node, 'js-chosen');
      addClickEventArray('hobbies', node, hobby, hobbies);
    });

    function addKeyupEvent(key, element){
      if(!element){ return; }
      element.addEventListener("keyup", function(){
        addSingleValueToStorage(key, element.value);
      });
    }

    function addClickEventSingle(key, element, value){
      if(!element){ return; }
      element.addEventListener("click", function(){
        addSingleValueToStorage(key, value);
      });
    }

    function addClickEventArray(key, element, value, array){
      if(!element){ return; }
      element.addEventListener("click", function(){
        addValueToArray(key, value, array);
      });
    }

    function addValueToArray(key, value, array){
      array.push(value);
      addArrayToStorage(key, array);
    }

    function addSingleValueToStorage(key, value){
      sessionStorage.setItem(key, value);
    }

    // JSON.stringify() is used here as session storage only supports strings
    function addArrayToStorage(key, array){
      sessionStorage.setItem(key, JSON.stringify(array));
    }
  }

  // Adds a class to baloons which makes them disappear when clicked.
  function addPopClassToBallons(node){
    if (!node){ return; }
    node.addEventListener("click", function(){
      node.classList.add('pop');
    });
  }

  function addOnInputToElement(element, func){
    element.oninput = function(){ func() }
  }

  function sleepingLion(){
    var value = document.getElementsByClassName("sleep__range")[0].value;
    var element = document.getElementsByClassName("sleep__sleeping-lion")[0];
    changeBackgroundPosition(element, value, -332)
  }

  function changeBackgroundPosition(element, value, illustrationSize){
    element.style.backgroundPosition = parseInt(value) * illustrationSize + "px";
  }
})(jQuery);
<commit_msg>Fix addClassToNode function<commit_after>(function ($) {
  "use strict";

  addAnswersToSessionStorage();

  $('.carousel').carousel({
    indicators: true,
    shift: 100
  });

  [
    "sleep__range"
  ].forEach(range => {
    if (document.getElementsByClassName(range)[0]){
      var node = document.getElementsByClassName(range)[0];
      addOnInputToElement( node, sleepingLion );
    }
  });

  function addAnswersToSessionStorage(){
    var personality = [];
    var hobbies = [];

    [
      "strange",
      "happy",
      "angry",
      "fun",
      "boring",
      "kind",
      "sad"
    ].forEach(emotion => {
      var node = document.getElementById(emotion);
      addClassToNode(node, 'pop');
      addClickEventArray('personality', node, emotion, personality);
    });

    [
      "sad-emoji",
      "happy-emoji",
      "indifferent-emoji"
    ].forEach(emoji => {
      var node = document.getElementsByClassName(emoji)[0];
      addClickEventSingle('feelings', node, emoji.match(/^[a-z]+/));
    });

    [
      "name",
      "age"
    ].forEach(inputField => {
      var node = document.getElementsByClassName(inputField)[0];
      addKeyupEvent(inputField, node);
    });

    [
      "football",
      "tennis",
      "gymnastics",
      "dance",
      "drawing",
      "photography",
      "cooking",
      "gardening",
      "puzzles",
      "camping",
      "fishing",
      "walking",
      "gymnastics-mobile",
      "photography-mobile",
      "walking-mobile",
      "puzzles-mobile"
    ].forEach(hobby => {
      var node = document.getElementsByClassName(hobby)[0];
      addClassToNode(node, 'js-chosen');
      addClickEventArray('hobbies', node, hobby, hobbies);
    });

    function addKeyupEvent(key, element){
      if(!element){ return; }
      element.addEventListener("keyup", function(){
        addSingleValueToStorage(key, element.value);
      });
    }

    function addClickEventSingle(key, element, value){
      if(!element){ return; }
      element.addEventListener("click", function(){
        addSingleValueToStorage(key, value);
      });
    }

    function addClickEventArray(key, element, value, array){
      if(!element){ return; }
      element.addEventListener("click", function(){
        addValueToArray(key, value, array);
      });
    }

    function addValueToArray(key, value, array){
      array.push(value);
      addArrayToStorage(key, array);
    }

    function addSingleValueToStorage(key, value){
      sessionStorage.setItem(key, value);
    }

    // JSON.stringify() is used here as session storage only supports strings
    function addArrayToStorage(key, array){
      sessionStorage.setItem(key, JSON.stringify(array));
    }
  }

  // Adds a class to baloons which makes them disappear when clicked.
  function addClassToNode(node, className){
    if (!node){ return; }
    node.addEventListener("click", function(){
      node.classList.add(className);
    });
  }

  function addOnInputToElement(element, func){
    element.oninput = function(){ func() }
  }

  function sleepingLion(){
    var value = document.getElementsByClassName("sleep__range")[0].value;
    var element = document.getElementsByClassName("sleep__sleeping-lion")[0];
    changeBackgroundPosition(element, value, -332)
  }

  function changeBackgroundPosition(element, value, illustrationSize){
    element.style.backgroundPosition = parseInt(value) * illustrationSize + "px";
  }
})(jQuery);
<|endoftext|>


<commit_before>/**
 * analyze sea3d objects with custom stuffix name
 * w: width
 * h: height
 * v: value
 */

// get all new loaded materials / meshes
var mats = [], meshes = [], dumys = [];
var lines = [];
var i = 0;

module.exports = function(game, lastOnly) {
    var keys = Object.keys(game.sea.objects);
    if (lastOnly) {                                     // 只针对最后一次导入的内容
        for (i = 0; i < keys.length; i++) {
            var key = keys[i];
            if (key.indexOf('m3d/') == 0) {
                meshes.push(game.sea.objects[key]);
            } else if (key.indexOf('dmy/') == 0) {
                dumys.push(game.sea.objects[key]);
            } else if (key.indexOf('mat/') == 0) {
                mats.push(game.sea.objects[key]);
            } else if (key.indexOf('line/') == 0) {
                lines.push(game.sea.objects[key]);
            }
        };
    } else {                                            // 针对所有的物体
        mats   = game.sea.materials || [];
        meshes = game.sea.meshes    || [];
        dumys  = game.sea.dummys    || [];
        lines  = game.sea.lines     || [];
    }

    // 模型
    analyzeObject(meshes)
    // 材质
    analyzeObject(mats);
    // 线
    analyzeObject(lines);

    // 虚拟体
    for (i = 0; i < dumys.length; i++) {                // 默认将所有的虚拟体,设置为不可见,但可点击.
        var dumy = dumys[i];
        dumy.material.transparent = true;
        dumy.material.opacity = 0;
        dumy.type = 'Dummy';                            // 默认为Mesh, 可能是Bug
        dumy.renderOrder = 100;
    };
    analyzeObject(dumys);

    console.log('-> analyzeScene complete.');
};

// 处理的所有注册方法
var process = {
    'hide': function(o, p) {                            // mesh | dummy
        o.visible = false;
    },
    'transparenthide': function(o, p) {
        if (!o.material) {
            return;
        }
        o.material.transparent = true;
        o.material.opacity = 0;
        o.renderOrder = 100;
    },
    'notpickable': function(o, p) {
        o.mouseEnabled = false;
    },
    'metal': function(o, p) {                           // mamteral
        o.metal = true;
        o.needsUpdate = true;
    },
    'opacity': function(o, p) {
        o.transparent = true;
        o.opacity = p['opacity'].v || 0.5;
    },
    'refraction': function(o, p) {
        utils.switchFanSheZheShe(o);
    },
    'nearest': function(o, p) {
        o.map.minFilter = THREE.NearestFilter;
        o.map.needsUpdate = true;
    },
    'line': function(o, p) {                            // line
        var lineMat = o.material;
        lineMat.lineWidth = parseFloat( p['line'].v );
    }
};

// 分析标签化的名称及参数
// {name: 'xxx', parameters: {kao: {v: 1}}}
var analyzeName = function( name ) {
    var arr = name.split('-');                          // 'kao-width_w:5.3_h:4.56-hide_v:true'
    res = {};
    res['parameters'] = {};
    res.name = arr[0];                                  // 'kao'

    var subArr;
    if (arr.length > 1) {
        for (i = 1; i < arr.length; i++) {              // 'width_w:5.3_h:4.56'
            var ar = arr[i].split('_');
            var type = ar[0];
            res['parameters'][type] = {};

            for (var j = 1; j < ar.length; j++) {       // 'w:5.3' 'h:4.56'
                var p = ar[j].split(':');
                res['parameters'][type][p[0]] = p[1];
            };
        };
    }

    return res;
}

var analyzeObject = function( arr ) {
    for (var i = 0; i < arr.length; i++) {
        var obj = arr[i];
        var res = analyzeName(obj.name);

        var types = Object.keys(res.parameters);

        if (types.length == 0) {
            continue;
        }

        obj.name = res.name;

        for (var j = 0; j < types.length; j++) {
            var type = types[j];

            if (process[type]) {
                process[type](obj, res.parameters);
            }
        };
    };
};<commit_msg>add analyzeScene.js support line color parameter.<commit_after>/**
 * analyze sea3d objects with custom stuffix name
 * w: width
 * h: height
 * v: value
 */

// get all new loaded materials / meshes
var mats = [], meshes = [], dumys = [];
var lines = [];
var i = 0;

module.exports = function(game, lastOnly) {
    var keys = Object.keys(game.sea.objects);
    if (lastOnly) {                                     // 只针对最后一次导入的内容
        for (i = 0; i < keys.length; i++) {
            var key = keys[i];
            if (key.indexOf('m3d/') == 0) {
                meshes.push(game.sea.objects[key]);
            } else if (key.indexOf('dmy/') == 0) {
                dumys.push(game.sea.objects[key]);
            } else if (key.indexOf('mat/') == 0) {
                mats.push(game.sea.objects[key]);
            } else if (key.indexOf('line/') == 0) {
                lines.push(game.sea.objects[key]);
            }
        };
    } else {                                            // 针对所有的物体
        mats   = game.sea.materials || [];
        meshes = game.sea.meshes    || [];
        dumys  = game.sea.dummys    || [];
        lines  = game.sea.lines     || [];
    }

    // 模型
    analyzeObject(meshes)
    // 材质
    analyzeObject(mats);
    // 线
    analyzeObject(lines);

    // 虚拟体
    for (i = 0; i < dumys.length; i++) {                // 默认将所有的虚拟体,设置为不可见,但可点击.
        var dumy = dumys[i];
        dumy.material.transparent = true;
        dumy.material.opacity = 0;
        dumy.type = 'Dummy';                            // 默认为Mesh, 可能是Bug
        dumy.renderOrder = 100;
    };
    analyzeObject(dumys);

    console.log('-> analyzeScene complete.');
};

// 处理的所有注册方法
var process = {
    'hide': function(o, p) {                            // mesh | dummy
        o.visible = false;
    },
    'transparenthide': function(o, p) {
        if (!o.material) {
            return;
        }
        o.material.transparent = true;
        o.material.opacity = 0;
        o.renderOrder = 100;
    },
    'notpickable': function(o, p) {
        o.mouseEnabled = false;
    },
    'metal': function(o, p) {                           // mamteral
        o.metal = true;
        o.needsUpdate = true;
    },
    'opacity': function(o, p) {
        o.transparent = true;
        o.opacity = p['opacity'].v || 0.5;
    },
    'refraction': function(o, p) {
        utils.switchFanSheZheShe(o);
    },
    'nearest': function(o, p) {
        o.map.minFilter = THREE.NearestFilter;
        o.map.needsUpdate = true;
    },
    'line': function(o, p) {                            // line
        var lineMat = o.material;
        if (p.line.v) {                                 // width
            lineMat.lineWidth = parseFloat( p.line.v );
        }
        if (p.line.c) {                                 // color
            lineMat.color = new THREE.Color(p.line.c);
        }
    }
};

// 分析标签化的名称及参数
// {name: 'xxx', parameters: {kao: {v: 1}}}
var analyzeName = function( name ) {
    var arr = name.split('-');                          // 'kao-width_w:5.3_h:4.56-hide_v:true'
    res = {};
    res['parameters'] = {};
    res.name = arr[0];                                  // 'kao'

    var subArr;
    if (arr.length > 1) {
        for (i = 1; i < arr.length; i++) {              // 'width_w:5.3_h:4.56'
            var ar = arr[i].split('_');
            var type = ar[0];
            res['parameters'][type] = {};

            for (var j = 1; j < ar.length; j++) {       // 'w:5.3' 'h:4.56'
                var p = ar[j].split(':');
                res['parameters'][type][p[0]] = p[1];
            };
        };
    }

    return res;
}

var analyzeObject = function( arr ) {
    for (var i = 0; i < arr.length; i++) {
        var obj = arr[i];
        var res = analyzeName(obj.name);

        var types = Object.keys(res.parameters);

        if (types.length == 0) {
            continue;
        }

        obj.name = res.name;

        for (var j = 0; j < types.length; j++) {
            var type = types[j];

            if (process[type]) {
                process[type](obj, res.parameters);
            }
        };
    };
};<|endoftext|>


<commit_before>function fetchResultsJS(theForm,event) {
  event.preventDefault();

  var formIntegerArray = ["craftAbility", "craftArtifact", "craftAttribute", "stuntDice", "stuntSuccesses", "numAttempts", "terminus", "targetThreshold", "essence"];
  var formBooleanArray = ["craftSpeciality", "fullExcellency", "willpowerSpend", "flawlessHandiworkMethod", "flawlessHandiworkRepurchase"];

  var returnFloatArray = ["meanSuc", "stdDevSuc", "percentSuc"];
  var returnIntegerArray = ["medianSuc","initialPoolSize"];

  var hash = {};

  $.each(formIntegerArray, function(index, item) { hash[item] = theForm.elements.namedItem(item).value; });
  $.each(formBooleanArray, function(index, item) { hash[item] = (~~theForm.elements.namedItem(item).checked); });

  $.ajax({
    type: 'GET',
    url: '/exaltedcraftingdieroller',
    data: hash,
    dataType: 'json',
    success: function(data) {
      $.each(returnFloatArray, function(index, item) { document.getElementById(item).innerHTML = data[item].toFixed(2); });
      $.each(returnIntegerArray, function(index, item) { document.getElementById(item).innerHTML = data[item]; });
      renderHistogram(data, hash, theForm);
    }
  });
}
<commit_msg>added call to rollPool<commit_after>function fetchResultsJS(theForm,event) {
  event.preventDefault();

  var formIntegerArray = ["craftAbility", "craftArtifact", "craftAttribute", "stuntDice", "stuntSuccesses", "numAttempts", "terminus", "targetThreshold", "essence"];
  var formBooleanArray = ["craftSpeciality", "fullExcellency", "willpowerSpend", "flawlessHandiworkMethod", "flawlessHandiworkRepurchase"];

  var returnFloatArray = ["meanSuc", "stdDevSuc", "percentSuc"];
  var returnIntegerArray = ["medianSuc","initialPoolSize"];

  var hash = {};

  $.each(formIntegerArray, function(index, item) { hash[item] = theForm.elements.namedItem(item).value; });
  $.each(formBooleanArray, function(index, item) { hash[item] = (~~theForm.elements.namedItem(item).checked); });

  rollPool(10);

  $.ajax({
    type: 'GET',
    url: '/exaltedcraftingdieroller',
    data: hash,
    dataType: 'json',
    success: function(data) {
      $.each(returnFloatArray, function(index, item) { document.getElementById(item).innerHTML = data[item].toFixed(2); });
      $.each(returnIntegerArray, function(index, item) { document.getElementById(item).innerHTML = data[item]; });
      renderHistogram(data, hash, theForm);
    }
  });
}
<|endoftext|>


<commit_before>/**
 *	Copyright (C) 2014 3D Repo Ltd
 *
 *	This program is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU Affero General Public License as
 *	published by the Free Software Foundation, either version 3 of the
 *	License, or (at your option) any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU Affero General Public License for more details.
 *
 *	You should have received a copy of the GNU Affero General Public License
 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var dbConn_js = require('./db.js');
var async = require('async');
var dbConn = new dbConn_js();
var repoGraphScene = require('./repoGraphScene.js');
var uuid = require('node-uuid');
var log_iface = require('./logger.js');
var logger = log_iface.logger;

function stringToUUID(id) {
	var bytes = uuid.parse(id);
	var buf = new Buffer(bytes);
	return dbConn.Binary(buf, 3);
}

function uuidToString(uuidIn) {
	return uuid.unparse(uuidIn.buffer);
}

var rootUUID = stringToUUID("00000000-0000-0000-0000-000000000000");

/*******************************************************************************
 /* Authenticate user against the database
 * @param {Error} err - Error object
 * @param {RepoNodeMesh} mesh - The RepoNodeMesh object containing the mesh
 * @param {string} tex_uuid - A string representing the tex_uuid attached to the mesh
 * @param {boolean} embedded_texture - Determines whether or not the texture data is embedded in the SRC.
 * @param {Object} res - The http response object
 *******************************************************************************/
exports.authenticate = function(username, password, callback) {
	dbConn.authenticateUser(username, password, function(err)
	{
		if(err)
			return callback(new Error("Authentication Error"));

		callback(null, {username: username});
	});
}

exports.getUserDBList = function(username, callback) {
	if (!username) return callback(new Error("Username is not defined"), null);

	var filter = {
		user: username
	};

	this.getUserInfo(username, function(err, user) {
		callback(null, user["projects"].map(
				function(proj){
					return proj;
				}
			)
		);
	});
}

exports.getUserInfo = function(username, callback) {
	if(!username) return callback(new Error("Unspecified username"));

	var filter = {
		user: username
	};

	var projection = {
		customData : 1
	};

	dbConn.filterColl("admin", "system.users", filter, projection, function(err, coll) {
		if(err) return callback(err);

		callback(null, coll[0]["customData"]);
	});
}

exports.hasAccessToProject = function(username, account, project, callback) {
	if (project == null)
		return callback(null);

	this.getUserDBList(username, function(err, dbList) {
		if(dbList.map( function (db)
		{
			return db["account"] + "." + db["project"]
		}).indexOf(account + "." + project) > -1)
			callback(null);
		else
			callback(new Error("Not Authorized to access database"));
	});

}

exports.getDBList = function(callback) {
	dbConn.dbCallback('admin', function(err, db) {
		if (err) return callback(err);

		db.admin().listDatabases(function(err, dbs) {
			if (err) return callback(err);

			var dbList = [];

			for (var i in dbs.databases)
				dbList.push({ name: dbs.databases[i].name});

			dbList.sort();

			callback(null, dbList);
		});
	});
}

exports.getChildren = function(dbName, uuid, callback) {
	var filter = {
		parents : stringToUUID(uuid),
		type: {$in : ['mesh', 'transformation', 'ref']}
	};

	dbConn.filterColl(dbName, 'scene', filter, null, function(err, doc) {
		if (err) return callback(err);

		callback(null, doc);
	});
};

exports.getRevisions = function(dbName, branch, callback) {

	var filter = {
		type: "revision"
	};

	if(branch)
		if (branch == "root")
			filter["shared_id"] = rootUUID;
		else
			filter["shared_id"] = stringToUUID(branch);

	var projection = {
		_id : 1
	};

	dbConn.filterColl(dbName, 'history', filter, projection, function(err, doc) {
			if (err) return callback(err);

			var revisionList = [];

			for (var i in doc)
			{
				var revisionName = uuidToString(doc[i]._id);
				revisionList.push({name : revisionName});
			}

			callback(null, revisionList);
	});

};

exports.getBranches = function(dbName, callback) {
	var filter = {
		type: "revision"
	};

	var projection = {
		shared_id : 1
	};

	dbConn.filterColl(dbName, 'history', filter, projection, function(err, doc) {
			if (err) return callback(err);

			var branchList = [];

			for (var i in doc)
			{
				var branchName = uuidToString(doc[i].shared_id);

				if (branchList.indexOf(branchName) == -1)
					branchList.push({ name: uuidToString(doc[i].shared_id)});
			}

			callback(null, branchList);
	});

};

exports.getMetadata = function(dbName, uuid, callback) {
	var filter = {
		parents: stringToUUID(uuid),
		type: 'meta'
	};

	var projection = {
		_id: 0,
		shared_id: 0,
		paths: 0,
		type: 0,
		api: 0,
		parents: 0
	};

	dbConn.filterColl(dbName, 'scene', filter, projection, function(err, doc) {
		callback(null, doc);
	});
};

exports.getObject = function(project, uid, rid, sid, callback) {
	logger.log('debug', 'Requesting object (U, R, S) (' + uid + ',' + rid + ',' + sid + ')');

	if (uid)
	{
		var query = {
			_id: stringToUUID(uid)
		};

		dbConn.filterColl(project, 'scene', query, null, function(err,doc) {
			if(err) return callback(err);

			callback(null, doc[0]["type"], uid, repoGraphScene.decode(doc))
		});

	} else if (rid && sid) {
		var historyQuery = {
			_id : stringToUUID(rid)
		};

		dbConn.getLatest(project, 'history', historyQuery, null, function(err, doc)
		{
			var query = {
				shared_id : stringToUUID(sid),
				_id		  : { $in : docs[0]['current']}
			};

			dbConn.filterColl(project, 'scene', query, null, function(err, obj) {
				if (err) return callback(err);

				callback(null, obj[0]["type"], this.stringToUUID(obj[0]["_id"]), repoGraphScene.decode(obj));
			});

		});
	} else {
		return callback(new Error("Not enough information specified"), null, null);
	}
}

exports.getScene = function(project, revision, callback) {
	var historyQuery = null;

	if (revision != null)
	{
		historyQuery = {
			_id: stringToUUID(revision)
		};
	}

	dbConn.getLatest(project, 'history', historyQuery, null, function(err, docs)
	{
		if(err) return callback(err);

		var projection = {
			vertices: 0,
			normals: 0,
			faces: 0,
			data: 0,
			uv_channels: 0
		};

		var query = {
			_id: { $in: docs[0]['current'] }
		};

		dbConn.filterColl(project, 'scene', query, projection, function(err, coll) {
			if (err) return callback(err);

			callback(null, repoGraphScene.decode(coll));
		});
	});

};

exports.getCache = function(project, uid, getData, level, callback) {
	var projection = null;

	if (!getData)
	{
		projection = {
			idx_buf : 0,
			vert_buf : 0
		};
	}

	var filter = {mesh_id : stringToUUID(uid)};

	if (level)
		filter['level'] = parseInt(level);

	dbConn.filterColl(project, "repo.cache", filter, projection, function(err, coll) {
		if (err) return callback(err);

		callback(null, coll);
	});

};

exports.uuidToString = uuidToString;
exports.dbConn		 = dbConn;
<commit_msg>ISSUE #30 - Remove duplicates from branch list<commit_after>/**
 *	Copyright (C) 2014 3D Repo Ltd
 *
 *	This program is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU Affero General Public License as
 *	published by the Free Software Foundation, either version 3 of the
 *	License, or (at your option) any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU Affero General Public License for more details.
 *
 *	You should have received a copy of the GNU Affero General Public License
 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var dbConn_js = require('./db.js');
var async = require('async');
var dbConn = new dbConn_js();
var repoGraphScene = require('./repoGraphScene.js');
var uuid = require('node-uuid');
var log_iface = require('./logger.js');
var logger = log_iface.logger;

function stringToUUID(id) {
	var bytes = uuid.parse(id);
	var buf = new Buffer(bytes);
	return dbConn.Binary(buf, 3);
}

function uuidToString(uuidIn) {
	return uuid.unparse(uuidIn.buffer);
}

var rootUUID = stringToUUID("00000000-0000-0000-0000-000000000000");

/*******************************************************************************
 /* Authenticate user against the database
 * @param {Error} err - Error object
 * @param {RepoNodeMesh} mesh - The RepoNodeMesh object containing the mesh
 * @param {string} tex_uuid - A string representing the tex_uuid attached to the mesh
 * @param {boolean} embedded_texture - Determines whether or not the texture data is embedded in the SRC.
 * @param {Object} res - The http response object
 *******************************************************************************/
exports.authenticate = function(username, password, callback) {
	dbConn.authenticateUser(username, password, function(err)
	{
		if(err)
			return callback(new Error("Authentication Error"));

		callback(null, {username: username});
	});
}

exports.getUserDBList = function(username, callback) {
	if (!username) return callback(new Error("Username is not defined"), null);

	var filter = {
		user: username
	};

	this.getUserInfo(username, function(err, user) {
		callback(null, user["projects"].map(
				function(proj){
					return proj;
				}
			)
		);
	});
}

exports.getUserInfo = function(username, callback) {
	if(!username) return callback(new Error("Unspecified username"));

	var filter = {
		user: username
	};

	var projection = {
		customData : 1
	};

	dbConn.filterColl("admin", "system.users", filter, projection, function(err, coll) {
		if(err) return callback(err);

		callback(null, coll[0]["customData"]);
	});
}

exports.hasAccessToProject = function(username, account, project, callback) {
	if (project == null)
		return callback(null);

	this.getUserDBList(username, function(err, dbList) {
		if(dbList.map( function (db)
		{
			return db["account"] + "." + db["project"]
		}).indexOf(account + "." + project) > -1)
			callback(null);
		else
			callback(new Error("Not Authorized to access database"));
	});

}

exports.getDBList = function(callback) {
	dbConn.dbCallback('admin', function(err, db) {
		if (err) return callback(err);

		db.admin().listDatabases(function(err, dbs) {
			if (err) return callback(err);

			var dbList = [];

			for (var i in dbs.databases)
				dbList.push({ name: dbs.databases[i].name});

			dbList.sort();

			callback(null, dbList);
		});
	});
}

exports.getChildren = function(dbName, uuid, callback) {
	var filter = {
		parents : stringToUUID(uuid),
		type: {$in : ['mesh', 'transformation', 'ref']}
	};

	dbConn.filterColl(dbName, 'scene', filter, null, function(err, doc) {
		if (err) return callback(err);

		callback(null, doc);
	});
};

exports.getRevisions = function(dbName, branch, callback) {

	var filter = {
		type: "revision"
	};

	if(branch)
		if (branch == "root")
			filter["shared_id"] = rootUUID;
		else
			filter["shared_id"] = stringToUUID(branch);

	var projection = {
		_id : 1
	};

	dbConn.filterColl(dbName, 'history', filter, projection, function(err, doc) {
			if (err) return callback(err);

			var revisionList = [];

			for (var i in doc)
			{
				var revisionName = uuidToString(doc[i]._id);
				revisionList.push({name : revisionName});
			}

			callback(null, revisionList);
	});

};

exports.getBranches = function(dbName, callback) {
	var filter = {
		type: "revision"
	};

	var projection = {
		shared_id : 1
	};

	dbConn.filterColl(dbName, 'history', filter, projection, function(err, doc) {
			if (err) return callback(err);

			var branchList = [];

			for (var i in doc)
			{
				var branchName = uuidToString(doc[i].shared_id);

				if (branchList.map(function (e) { return e.name; }).indexOf(branchName) == -1)
					branchList.push({ name: uuidToString(doc[i].shared_id)});
			}

			callback(null, branchList);
	});

};

exports.getMetadata = function(dbName, uuid, callback) {
	var filter = {
		parents: stringToUUID(uuid),
		type: 'meta'
	};

	var projection = {
		_id: 0,
		shared_id: 0,
		paths: 0,
		type: 0,
		api: 0,
		parents: 0
	};

	dbConn.filterColl(dbName, 'scene', filter, projection, function(err, doc) {
		callback(null, doc);
	});
};

exports.getObject = function(project, uid, rid, sid, callback) {
	logger.log('debug', 'Requesting object (U, R, S) (' + uid + ',' + rid + ',' + sid + ')');

	if (uid)
	{
		var query = {
			_id: stringToUUID(uid)
		};

		dbConn.filterColl(project, 'scene', query, null, function(err,doc) {
			if(err) return callback(err);

			callback(null, doc[0]["type"], uid, repoGraphScene.decode(doc))
		});

	} else if (rid && sid) {
		var historyQuery = {
			_id : stringToUUID(rid)
		};

		dbConn.getLatest(project, 'history', historyQuery, null, function(err, doc)
		{
			var query = {
				shared_id : stringToUUID(sid),
				_id		  : { $in : docs[0]['current']}
			};

			dbConn.filterColl(project, 'scene', query, null, function(err, obj) {
				if (err) return callback(err);

				callback(null, obj[0]["type"], this.stringToUUID(obj[0]["_id"]), repoGraphScene.decode(obj));
			});

		});
	} else {
		return callback(new Error("Not enough information specified"), null, null);
	}
}

exports.getScene = function(project, revision, callback) {
	var historyQuery = null;

	if (revision != null)
	{
		historyQuery = {
			_id: stringToUUID(revision)
		};
	}

	dbConn.getLatest(project, 'history', historyQuery, null, function(err, docs)
	{
		if(err) return callback(err);

		var projection = {
			vertices: 0,
			normals: 0,
			faces: 0,
			data: 0,
			uv_channels: 0
		};

		var query = {
			_id: { $in: docs[0]['current'] }
		};

		dbConn.filterColl(project, 'scene', query, projection, function(err, coll) {
			if (err) return callback(err);

			callback(null, repoGraphScene.decode(coll));
		});
	});

};

exports.getCache = function(project, uid, getData, level, callback) {
	var projection = null;

	if (!getData)
	{
		projection = {
			idx_buf : 0,
			vert_buf : 0
		};
	}

	var filter = {mesh_id : stringToUUID(uid)};

	if (level)
		filter['level'] = parseInt(level);

	dbConn.filterColl(project, "repo.cache", filter, projection, function(err, coll) {
		if (err) return callback(err);

		callback(null, coll);
	});

};

exports.uuidToString = uuidToString;
exports.dbConn		 = dbConn;
<|endoftext|>


<commit_before>import * as DS from './delaney';
import * as props from './properties';
import * as derived from './derived';
import { covers } from './covers';

import { rationals as Q } from '../arithmetic/types';

const _assert = (condition, message) => {
  if (!condition)
    throw new Error(message || 'assertion error');
};

const _map1dOrbits = (fn, ds) => {
  const result = [];

  for (const i of ds.indices()) {
    for (const j of ds.indices()) {
      if (j > i) {
        for (const D of DS.orbitReps2(ds, i, j))
          result.push(fn(i, j, D));
      }
    }
  }

  return result;
};

const _loopless = (ds, i, j, D) =>
  DS.orbit2(ds, i, j, D).every(E => ds.s(i, E) != E && ds.s(j, E) != E);

const _unbranched = ds => _map1dOrbits(ds.v.bind(ds), ds).every(v => v == 1);

const _fullyBranched = ds => _map1dOrbits(ds.v.bind(ds), ds).every(v => !!v);

const _sum = numbers => numbers.reduce((a, x) => Q.plus(a, x), 0);

export const curvature = (ds, vDefault = 1) => {
  _assert(DS.dim(ds) == 2, 'must be two-dimensional');
  _assert(props.isConnected(ds), 'must be connected');

  const orbitContribution = (i, j, D) =>
    Q.div((_loopless(ds, i, j, D) ? 2 : 1), (ds.v(i, j, D) || vDefault));

  return Q.minus(_sum(_map1dOrbits(orbitContribution, ds)), DS.size(ds));
};

export const isProtoEuclidean = ds => Q.ge(curvature(ds), 0);
export const isProtoSpherical = ds => Q.gt(curvature(ds), 0);
export const isEuclidean = ds => _fullyBranched(ds) && Q.eq(curvature(ds), 0);
export const isHyperbolic = ds => _fullyBranched(ds) && Q.lt(curvature(ds), 0);

export const isSpherical = ds => {
  if (_fullyBranched(ds) && isProtoSpherical(ds)) {
    const dso = derived.orientedCover(ds);
    const cones = _map1dOrbits(dso.v.bind(dso), dso).filter(v => v > 1);

    return (
      cones.length != 1
        && (cones.length != 2 || (cones[0] == cones[1]))
    );
  }
  else
    return false;
};

export const orbifoldSymbol = ds => {
  //TODO correctly handle multiple boundary components

  const orbitType = (i, j, D) => [ds.v(i, j, D), _loopless(ds, i, j, D)];

  const types = _map1dOrbits(orbitType, ds);
  const cones = types.filter(([v, c]) => v > 1 && c).map(([v]) => v);
  const corners = types.filter(([v, c]) => v > 1 && !c).map(([v]) => v);

  const cost = Q.minus(2, _sum([
    Q.div(curvature(ds), 2),
    _sum(cones.map(v => Q.div(v - 1, v))),
    _sum(corners.map(v => Q.div(v - 1, 2*v))),
    (props.isLoopless(ds) ? 0 : 1)
  ]));

  _assert(Q.typeOf(cost) == 'Integer',
          'residual cost should be an integer, got ${cost}');

  const repeat = (c, n) => new Array(n).fill(c);

  const sym = [].concat(
    cones.sort().reverse(),
    (props.isLoopless(ds) ? [] : ['*']),
    corners.sort().reverse(),
    (props.isWeaklyOriented(ds) ? repeat('o', cost/2) : repeat('x', cost))
  ).join('');

  if (sym == 'x' || sym == '*' || sym == '')
    return '1'+sym;
  else
    return sym;
};

export const toroidalCover = ds => {
  _assert(isEuclidean(ds), 'must be euclidean');

  const dso = derived.orientedCover(ds);
  const degree = Math.max(..._map1dOrbits(dso.v.bind(dso), dso));

  for (const cov of covers(dso, degree)) {
    if (_unbranched(cov))
      return cov;
  };
};

const _eulerCharacteristic = ds => {
  const nrLoops = i => ds.elements().filter(D => ds.s(i, D) == D).length;
  const nrOrbits = (i, j) => DS.orbitReps2(ds, i, j).length;

  const nf = ds.size;
  const ne = (3 * nf + nrLoops(0) + nrLoops(1) + nrLoops(2)) / 2;
  const nv = nrOrbits(0, 1) + nrOrbits(0, 2) + nrOrbits(1, 2);

  return nf - ne + nv;
};

const _cutsOffDisk = (ds, cut, allow2Cone) => {
  const checkCones = cones => (
    cones.length == 0 || (allow2Cone && cones.length == 1 && cones[0] == 2)
  );

  const pairs = [];
  for (const D of cut) {
    const E = ds.s(1, D);
    pairs.push([D, D]);
    pairs.push([E, E]);
  }
  const tmp = DS.withPairings(ds, 1, pairs);
  const patch = derived.subsymbol(tmp, [0, 1, 2], cut[0]);

  if (patch.size == cut.length)
    return false;

  if (_eulerCharacteristic(ds) > 0) {
    if (patch.size == ds.size) {
      const vs = [ds.v(0, 1, cut[0]), ds.v(1, 2, cut[0])];
      if (cut.length > 2)
        vs.push(ds.v(1, 2, cut[1]));

      if (checkCones(vs.filter(v => v > 1)))
        return false;
    }

    if (patch.size == ds.size - cut.length) {
      if (
        cut.every(D => ds.v(1, 2, D) == 1)
          && cut.every(D => ds.v(0, 1, D) == 1)
      ) {
        const rest = derived.subsymbol(tmp, [0, 1, 2], ds.s(1, cut[0]));

        const orbitType = (i, j, D) =>
              [rest.v(i, j, D), _loopless(rest, i, j, D)];
        const types = _map1dOrbits(orbitType, rest);

        if (checkCones(types.filter(([v, c]) => v > 1 && c).map(([v]) => v)))
          return false;
      }
    }
  }

  if (!props.isWeaklyOriented(patch))
    return false;

  if (_eulerCharacteristic(patch) != 1)
    return false;

  const orbitType = (i, j, D) => [patch.v(i, j, D), _loopless(patch, i, j, D)];
  const types = _map1dOrbits(orbitType, patch);

  return checkCones(types.filter(([v, c]) => v > 1 && c).map(([v]) => v));
};

export const isPseudoConvex = ds => {
  _assert(DS.dim(ds) == 2, 'must be two-dimensional');
  _assert(props.isConnected(ds), 'must be connected');

  const log = () => {};
  //const log = console.log;

  ds = derived.canonical(derived.orientedCover(ds));
  log(`isPseudoConvex(${ds})`);
  const ori = props.partialOrientation(ds);

  for (const A1 of ds.elements().filter(D => ori[D] > 0)) {
    log(`  A1 = ${A1}`);
    const onTrail1 = Array(ds.size + 1).fill(0);
    onTrail1[A1] = 1;
    let A2 = ds.s(0, A1);

    while (!onTrail1[A2]) {
      log(`    A2 = ${A2}`);
      const onTrail2 = onTrail1.slice();
      onTrail2[A2] = 1;
      let B2 = ds.s(2, A2);

      while (B2 == A1 || !onTrail2[B2]) {
        log(`      B2 = ${B2}`);
        if (B2 == A1) {
          if (_cutsOffDisk(ds, [A1, A2], true))
            return false;
          else
            break;
        }

        const onTrail3 = onTrail2.slice();
        onTrail3[B2] = 1;
        let B1 = ds.s(0, B2);

        while (!onTrail3[B1]) {
          log(`        B1 = ${B1}`);

          const onTrail4 = onTrail3.slice();
          onTrail4[B1] = 1;
          let T = ds.s(2, B1);

          while (T != A1 && ds.s(1, T) != B1 && !onTrail4[T]) {
            onTrail4[T] = onTrail4[ds.s(1, T)] = 1;
            T = ds.s(2, ds.s(1, T));
          }
          log(`          T = ${T}`);

          if (T == A1 && _cutsOffDisk(ds, [A1, A2, B2, B1], false))
            return false;

          onTrail3[B1] = onTrail3[ds.s(1, B1)] = 1;
          B1 = ds.s(0, ds.s(1, B1));
        }

        onTrail2[B2] = onTrail2[ds.s(1, B2)] = 1;
        B2 = ds.s(2, ds.s(1, B2));
      }

      onTrail1[A2] = onTrail1[ds.s(1, A2)] = 1;
      A2 = ds.s(0, ds.s(1, A2));
    }
  }

  return true;
};

if (require.main == module) {
  const test = ds => {
    const is = fn => fn(ds) ? 'is' : 'is not';

    console.log(`ds = ${ds}`);
    console.log(`  curvature is ${curvature(ds)}`);
    console.log(`  symbol ${is(isProtoEuclidean)} proto-euclidean`);
    console.log(`  symbol ${is(isProtoSpherical)} proto-spherical`);
    console.log(`  symbol ${is(isEuclidean)} euclidean`);
    console.log(`  symbol ${is(isHyperbolic)} hyperbolic`);
    console.log(`  symbol ${is(isSpherical)} spherical`);
    console.log(`  symbol ${is(isPseudoConvex)} pseudo-convex`);
    console.log(`  orbifold symbol = ${orbifoldSymbol(ds)}`);

    if (isEuclidean(ds)) {
      const dst = toroidalCover(ds);
      console.log(`  toroidal cover = ${dst}`);

      const curv = curvature(dst);
      const orbs = orbifoldSymbol(dst);

      if (Q.eq(curv, 0) && orbs == 'o')
        console.log('    (curvature and orbifold symbol okay)');
      else
        console.error(`    !!!! curvature ${curv}, orbifold symbol ${orbs}`);
    }
    console.log();
  };

  test(DS.parse('<1.1:3:1 2 3,1 3,2 3:4 0,0>'));
  test(DS.parse('<1.1:3:1 2 3,1 3,2 3:4 8,0>'));
  test(DS.parse('<1.1:3:1 2 3,1 3,2 3:4 8,3>'));
  test(DS.parse('<1.1:1:1,1,1:5,3>'));
  test(DS.parse('<1.1:1:1,1,1:6,3>'));
  test(DS.parse('<1.1:1:1,1,1:7,3>'));
  test(DS.parse('<1.1:2:2,1 2,1 2:2,4 4>'));
  test(DS.parse('<1.1:2:2,1 2,1 2:2,4 5>'));
  test(DS.parse('<1.1:8:2 4 6 8,8 3 5 7,6 5 8 7:4,4>'));
  test(DS.parse('<1.1:8:2 4 6 8,8 3 5 7,5 6 8 7:4,4>'));
  test(DS.parse('<1.1:5:2 4 5,1 2 3 5,3 4 5:8 3,8 3>')); // not pseudo-convex
  test(DS.parse('<1.1:4:2 4,1 3 4,3 4:4,4>'));

  test(DS.parse('<1.1:12:1 3 5 8 10 11 12,2 3 6 7 10 12 11,1 4 5 9 7 11 10 12:3 3 3,6 3 3>'));
}
<commit_msg>delaney2d: get rid of underscores in function names<commit_after>import * as DS from './delaney';
import * as props from './properties';
import * as derived from './derived';
import { covers } from './covers';

import { rationals as Q } from '../arithmetic/types';

const assert = (condition, message) => {
  if (!condition)
    throw new Error(message || 'assertion error');
};

const map1dOrbits = (fn, ds) => {
  const result = [];

  for (const i of ds.indices()) {
    for (const j of ds.indices()) {
      if (j > i) {
        for (const D of DS.orbitReps2(ds, i, j))
          result.push(fn(i, j, D));
      }
    }
  }

  return result;
};

const loopless = (ds, i, j, D) =>
  DS.orbit2(ds, i, j, D).every(E => ds.s(i, E) != E && ds.s(j, E) != E);

const unbranched = ds => map1dOrbits(ds.v.bind(ds), ds).every(v => v == 1);

const fullyBranched = ds => map1dOrbits(ds.v.bind(ds), ds).every(v => !!v);

const sum = numbers => numbers.reduce((a, x) => Q.plus(a, x), 0);

export const curvature = (ds, vDefault = 1) => {
  assert(DS.dim(ds) == 2, 'must be two-dimensional');
  assert(props.isConnected(ds), 'must be connected');

  const orbitContribution = (i, j, D) =>
    Q.div((loopless(ds, i, j, D) ? 2 : 1), (ds.v(i, j, D) || vDefault));

  return Q.minus(sum(map1dOrbits(orbitContribution, ds)), DS.size(ds));
};

export const isProtoEuclidean = ds => Q.ge(curvature(ds), 0);
export const isProtoSpherical = ds => Q.gt(curvature(ds), 0);
export const isEuclidean = ds => fullyBranched(ds) && Q.eq(curvature(ds), 0);
export const isHyperbolic = ds => fullyBranched(ds) && Q.lt(curvature(ds), 0);

export const isSpherical = ds => {
  if (fullyBranched(ds) && isProtoSpherical(ds)) {
    const dso = derived.orientedCover(ds);
    const cones = map1dOrbits(dso.v.bind(dso), dso).filter(v => v > 1);

    return (
      cones.length != 1
        && (cones.length != 2 || (cones[0] == cones[1]))
    );
  }
  else
    return false;
};

export const orbifoldSymbol = ds => {
  //TODO correctly handle multiple boundary components

  const orbitType = (i, j, D) => [ds.v(i, j, D), loopless(ds, i, j, D)];

  const types = map1dOrbits(orbitType, ds);
  const cones = types.filter(([v, c]) => v > 1 && c).map(([v]) => v);
  const corners = types.filter(([v, c]) => v > 1 && !c).map(([v]) => v);

  const cost = Q.minus(2, sum([
    Q.div(curvature(ds), 2),
    sum(cones.map(v => Q.div(v - 1, v))),
    sum(corners.map(v => Q.div(v - 1, 2*v))),
    (props.isLoopless(ds) ? 0 : 1)
  ]));

  assert(Q.typeOf(cost) == 'Integer',
          'residual cost should be an integer, got ${cost}');

  const repeat = (c, n) => new Array(n).fill(c);

  const sym = [].concat(
    cones.sort().reverse(),
    (props.isLoopless(ds) ? [] : ['*']),
    corners.sort().reverse(),
    (props.isWeaklyOriented(ds) ? repeat('o', cost/2) : repeat('x', cost))
  ).join('');

  if (sym == 'x' || sym == '*' || sym == '')
    return '1'+sym;
  else
    return sym;
};

export const toroidalCover = ds => {
  assert(isEuclidean(ds), 'must be euclidean');

  const dso = derived.orientedCover(ds);
  const degree = Math.max(...map1dOrbits(dso.v.bind(dso), dso));

  for (const cov of covers(dso, degree)) {
    if (unbranched(cov))
      return cov;
  };
};

const eulerCharacteristic = ds => {
  const nrLoops = i => ds.elements().filter(D => ds.s(i, D) == D).length;
  const nrOrbits = (i, j) => DS.orbitReps2(ds, i, j).length;

  const nf = ds.size;
  const ne = (3 * nf + nrLoops(0) + nrLoops(1) + nrLoops(2)) / 2;
  const nv = nrOrbits(0, 1) + nrOrbits(0, 2) + nrOrbits(1, 2);

  return nf - ne + nv;
};

const cutsOffDisk = (ds, cut, allow2Cone) => {
  const checkCones = cones => (
    cones.length == 0 || (allow2Cone && cones.length == 1 && cones[0] == 2)
  );

  const pairs = [];
  for (const D of cut) {
    const E = ds.s(1, D);
    pairs.push([D, D]);
    pairs.push([E, E]);
  }
  const tmp = DS.withPairings(ds, 1, pairs);
  const patch = derived.subsymbol(tmp, [0, 1, 2], cut[0]);

  if (patch.size == cut.length)
    return false;

  if (eulerCharacteristic(ds) > 0) {
    if (patch.size == ds.size) {
      const vs = [ds.v(0, 1, cut[0]), ds.v(1, 2, cut[0])];
      if (cut.length > 2)
        vs.push(ds.v(1, 2, cut[1]));

      if (checkCones(vs.filter(v => v > 1)))
        return false;
    }

    if (patch.size == ds.size - cut.length) {
      if (
        cut.every(D => ds.v(1, 2, D) == 1)
          && cut.every(D => ds.v(0, 1, D) == 1)
      ) {
        const rest = derived.subsymbol(tmp, [0, 1, 2], ds.s(1, cut[0]));

        const orbitType = (i, j, D) =>
              [rest.v(i, j, D), loopless(rest, i, j, D)];
        const types = map1dOrbits(orbitType, rest);

        if (checkCones(types.filter(([v, c]) => v > 1 && c).map(([v]) => v)))
          return false;
      }
    }
  }

  if (!props.isWeaklyOriented(patch))
    return false;

  if (eulerCharacteristic(patch) != 1)
    return false;

  const orbitType = (i, j, D) => [patch.v(i, j, D), loopless(patch, i, j, D)];
  const types = map1dOrbits(orbitType, patch);

  return checkCones(types.filter(([v, c]) => v > 1 && c).map(([v]) => v));
};

export const isPseudoConvex = ds => {
  assert(DS.dim(ds) == 2, 'must be two-dimensional');
  assert(props.isConnected(ds), 'must be connected');

  const log = () => {};
  //const log = console.log;

  ds = derived.canonical(derived.orientedCover(ds));
  log(`isPseudoConvex(${ds})`);
  const ori = props.partialOrientation(ds);

  for (const A1 of ds.elements().filter(D => ori[D] > 0)) {
    log(`  A1 = ${A1}`);
    const onTrail1 = Array(ds.size + 1).fill(0);
    onTrail1[A1] = 1;
    let A2 = ds.s(0, A1);

    while (!onTrail1[A2]) {
      log(`    A2 = ${A2}`);
      const onTrail2 = onTrail1.slice();
      onTrail2[A2] = 1;
      let B2 = ds.s(2, A2);

      while (B2 == A1 || !onTrail2[B2]) {
        log(`      B2 = ${B2}`);
        if (B2 == A1) {
          if (cutsOffDisk(ds, [A1, A2], true))
            return false;
          else
            break;
        }

        const onTrail3 = onTrail2.slice();
        onTrail3[B2] = 1;
        let B1 = ds.s(0, B2);

        while (!onTrail3[B1]) {
          log(`        B1 = ${B1}`);

          const onTrail4 = onTrail3.slice();
          onTrail4[B1] = 1;
          let T = ds.s(2, B1);

          while (T != A1 && ds.s(1, T) != B1 && !onTrail4[T]) {
            onTrail4[T] = onTrail4[ds.s(1, T)] = 1;
            T = ds.s(2, ds.s(1, T));
          }
          log(`          T = ${T}`);

          if (T == A1 && cutsOffDisk(ds, [A1, A2, B2, B1], false))
            return false;

          onTrail3[B1] = onTrail3[ds.s(1, B1)] = 1;
          B1 = ds.s(0, ds.s(1, B1));
        }

        onTrail2[B2] = onTrail2[ds.s(1, B2)] = 1;
        B2 = ds.s(2, ds.s(1, B2));
      }

      onTrail1[A2] = onTrail1[ds.s(1, A2)] = 1;
      A2 = ds.s(0, ds.s(1, A2));
    }
  }

  return true;
};

if (require.main == module) {
  const test = ds => {
    const is = fn => fn(ds) ? 'is' : 'is not';

    console.log(`ds = ${ds}`);
    console.log(`  curvature is ${curvature(ds)}`);
    console.log(`  symbol ${is(isProtoEuclidean)} proto-euclidean`);
    console.log(`  symbol ${is(isProtoSpherical)} proto-spherical`);
    console.log(`  symbol ${is(isEuclidean)} euclidean`);
    console.log(`  symbol ${is(isHyperbolic)} hyperbolic`);
    console.log(`  symbol ${is(isSpherical)} spherical`);
    console.log(`  symbol ${is(isPseudoConvex)} pseudo-convex`);
    console.log(`  orbifold symbol = ${orbifoldSymbol(ds)}`);

    if (isEuclidean(ds)) {
      const dst = toroidalCover(ds);
      console.log(`  toroidal cover = ${dst}`);

      const curv = curvature(dst);
      const orbs = orbifoldSymbol(dst);

      if (Q.eq(curv, 0) && orbs == 'o')
        console.log('    (curvature and orbifold symbol okay)');
      else
        console.error(`    !!!! curvature ${curv}, orbifold symbol ${orbs}`);
    }
    console.log();
  };

  test(DS.parse('<1.1:3:1 2 3,1 3,2 3:4 0,0>'));
  test(DS.parse('<1.1:3:1 2 3,1 3,2 3:4 8,0>'));
  test(DS.parse('<1.1:3:1 2 3,1 3,2 3:4 8,3>'));
  test(DS.parse('<1.1:1:1,1,1:5,3>'));
  test(DS.parse('<1.1:1:1,1,1:6,3>'));
  test(DS.parse('<1.1:1:1,1,1:7,3>'));
  test(DS.parse('<1.1:2:2,1 2,1 2:2,4 4>'));
  test(DS.parse('<1.1:2:2,1 2,1 2:2,4 5>'));
  test(DS.parse('<1.1:8:2 4 6 8,8 3 5 7,6 5 8 7:4,4>'));
  test(DS.parse('<1.1:8:2 4 6 8,8 3 5 7,5 6 8 7:4,4>'));
  test(DS.parse('<1.1:5:2 4 5,1 2 3 5,3 4 5:8 3,8 3>')); // not pseudo-convex
  test(DS.parse('<1.1:4:2 4,1 3 4,3 4:4,4>'));

  test(DS.parse('<1.1:12:1 3 5 8 10 11 12,2 3 6 7 10 12 11,1 4 5 9 7 11 10 12:3 3 3,6 3 3>'));
}
<|endoftext|>


<commit_before>$(function(){

  $('.show-coach').on('click', function(){
    startTimer();
    transitionToCoach();
  });

  appendTask(task1);
  appendTask(task2);

  appendMessage(message1);
  appendMessage(message2);

  theCoachSays();
  window.setInterval(function(){
    theCoachSays();
  }, 4500);

  $('.add-task').on('click', function(){
  	var hour=$("#hours").val();
  	var mins=$("#minutes").val();
  	var secs=$("#seconds").val();
  	if (!onlyNumbers(hour, mins, secs)) {
  		alert("Please insert only numbers");
  		return;
  	}
  	var tasks = $("#task").val();
  	var task = {
  	hours: hour,
  	minutes: mins,
  	seconds: secs,
  	name: tasks,
  	time: convertMS(hour,mins,secs),
  	};
  	appendTask(task);
  	$("#hours").val('');
  	$("#task").val('');
  	$("#minutes").val('');
  	$("#seconds").val('');
  })
});

function getMessages()
{
  $.ajax({ url: "query/?id=" + maxId, success: function( data ) {
      data = JSON.parse(data);
      // sanitize the data into valid objects
      for(var i = 0; i < data.length; i++) {
          var message = {"id": "", "name": "", "message": "", "image_url": ""};
          message.id = data[i].pk;
          message.name = data[i].fields.name;
          message.text = data[i].fields.motivation_text;
          message.image_url = data[i].fields.image_url;
          appendMessage(message);
      }
  }, dataType: 'json'});
}

// call when user presses on lets go
function transitionToCoach()
{
  $('.coach-page').show();
  $('.task-number').html("Number of Tasks: " + tasklist.length);
  $('.initial-page').hide();
  //getMessages();
  window.setInterval(function() {
      //getMessages();
  }, 60000);
}

var count = 0;
function appendTask(item)
{

  tasklist.push(item);
  $('.task-list').append("

" +
    item.name + "
" +
    "Hour: " + item.hours + " " +
    "Min: " + item.minutes + " " +
    "Sec: " + item.seconds + " " +
    "

");
  count++;
  $('.front-list').prepend("

" +
     "" + item.name + "
" +
  	 "Hours: " + item.hours + " " +
  	 "Min: " + item.minutes + " " +
  	 "Sec: " + item.seconds + " " +
  	 "

");

  if (!readyToGo)
  {
    readyToGo = true;
    $('.lame-coach-message').hide();
    $('.ready-to-go').show();
  }
}

function appendMessage(item)
{
  if (item.id > maxId)
    maxId = item.id;

  $('.message-list').prepend($("
" + item.name +
    ": " + item.text + "</span
").fadeIn('slow'));
}

// accepts a message.  if no message, then random talks.
function theCoachSays(message)
{
  if (message)
  {
    window.clearInterval(coachTimer);
    $('.the-coach').addClass('talking');
    $('.the-coach-says').html(message);
    $('.the-coach-says').show();
    setTimeout(function(){
      $('.the-coach').removeClass('talking');
      $('.the-coach-says').hide();
      randomTalking();
    }, 2000 );
  }
  else {
    window.clearInterval(coachTimer);
    $('.the-coach').addClass('talking');
    $('.the-coach-says').html(coachMessages[Math.floor(Math.random()*coachMessages.length)]);
    $('.the-coach-says').show();
    setTimeout(function(){
      $('.the-coach').removeClass('talking');
      $('.the-coach-says').hide();
    }, 2000 );
    randomTalking();
  }
}
// Coach says random stuff
function randomTalking()
{
  coachTimer = setInterval(function(){
    $('.the-coach').addClass('talking');
    $('.the-coach-says').html(coachMessages[Math.floor(Math.random()*coachMessages.length)]);
    $('.the-coach-says').show();
    setTimeout(function(){
      $('.the-coach').removeClass('talking');
      $('.the-coach-says').hide();
    }, 2000 );
  }, 4500);
}

var messageList = [];
var maxId = -1;
var coachMessages = [
  "Work on it harder soldier!",
  "What are you, a chicken?",
  "I really need a cheeseburger right now....",
  "You're doing well!  Just kidding, you're performing like crap.",
  "C'mon man, I've seen babies performing better.",
  "Hello World!",
  "Prove P = NP next!",
  "Man, this hackathon is kinda long, dontcha think?"
]

var tasklist = [];
var coachTimer;
var readyToGo = false; // has someone added a task yet?
var task1 = {
  name: "Study for ORF 309",
  time: 5000,
  hours: 0,
  minutes: 0,
  seconds: 5
};
var task2 = {
  name: "Finish drafting my Hackathon idea",
  time: 10000,
  hours: 10,
  minutes: 13,
  seconds: 20
};
var message1 = {
  id: 0,
  name: "Harold Wu",
  text: "Hey man, I hope you are doing well!  You got this!"
};
var message2 = {
  id: 0,
  name: "The Dude",
  text: "Dude, like thats just your opinion man."
};

function onlyNumbers(a,b,c)
{
	return !isNaN(a) && isFinite(parseFloat(a))
	&& !isNaN(b) && isFinite(parseFloat(b))
	&& !isNaN(c) && isFinite(parseFloat(c));
}

function convertMS(a,b,c)
{
	return parseInt(a)*3600000 + parseInt(b)*60000 + parseInt(c)*1000;
}

var taskNum = 0;

function startTimer()
{
  if (taskNum < tasklist.length) {
    var task = tasklist[taskNum];
      $($('.task-time')[taskNum]).countdown({until: task.hours + "h " + task.minutes + "m " + task.seconds + "s", format: "HMS", layout:'{d<}{dn} {dl} and {d>}'+
        '{hn} {hl}, {mn} {ml}, {sn} {sl}', onExpiry: expired});
  }
}

function expired() {
  taskNum++;
  startTimer();
}

function taskFinished(numTask) {
  $($('.task-item')[numTask]).fadeOut(1000);
  $($('.task-time')[numTask]).countdown('destroy');
  taskNum++;
  startTimer();
}
<commit_msg>updated the index.js page to do most recent<commit_after>$(function(){

  $('.show-coach').on('click', function(){
    startTimer();
    transitionToCoach();
  });

  appendTask(task1);
  appendTask(task2);

  appendMessage(message1);
  appendMessage(message2);

  theCoachSays();
  window.setInterval(function(){
    theCoachSays();
  }, 4500);

  $('.add-task').on('click', function(){
  	var hour=$("#hours").val();
  	var mins=$("#minutes").val();
  	var secs=$("#seconds").val();
  	if (!onlyNumbers(hour, mins, secs)) {
  		alert("Please insert only numbers");
  		return;
  	}
  	var tasks = $("#task").val();
  	var task = {
  	hours: hour,
  	minutes: mins,
  	seconds: secs,
  	name: tasks,
  	time: convertMS(hour,mins,secs),
  	};
  	appendTask(task);
  	$("#hours").val('');
  	$("#task").val('');
  	$("#minutes").val('');
  	$("#seconds").val('');
  })
});

function getMessages()
{
  $.ajax({ url: "query/?id=" + maxId + "&time=" + full_time + "&date=" + full_date, success: function( data ) {
      data = JSON.parse(data);
      // sanitize the data into valid objects
      for(var i = 0; i < data.length; i++) {
          var message = {"id": "", "name": "", "message": "", "image_url": ""};
          message.id = data[i].pk;
          message.name = data[i].fields.name;
          message.text = data[i].fields.motivation_text;
          message.image_url = data[i].fields.image_url;
          appendMessage(message);
      }
  }, dataType: 'json'});
}

// call when user presses on lets go
function transitionToCoach()
{
  $('.coach-page').show();
  $('.task-number').html("Number of Tasks: " + tasklist.length);
  $('.initial-page').hide();
  getMessages();
  window.setInterval(function() {
      getMessages();
  }, 60000);
}

var count = 0;
function appendTask(item)
{

  tasklist.push(item);
  $('.task-list').append("

" +
    item.name + "
" +
    "Hour: " + item.hours + " " +
    "Min: " + item.minutes + " " +
    "Sec: " + item.seconds + " " +
    "

");
  count++;
  $('.front-list').prepend("

" +
     "" + item.name + "
" +
  	 "Hours: " + item.hours + " " +
  	 "Min: " + item.minutes + " " +
  	 "Sec: " + item.seconds + " " +
  	 "

");

  if (!readyToGo)
  {
    readyToGo = true;
    $('.lame-coach-message').hide();
    $('.ready-to-go').show();
  }
}

function appendMessage(item)
{
  if (item.id > maxId)
    maxId = item.id;

  $('.message-list').prepend($("
" + item.name +
    ": " + item.text + "</span
").fadeIn('slow'));
}

// accepts a message.  if no message, then random talks.
function theCoachSays(message)
{
  if (message)
  {
    window.clearInterval(coachTimer);
    $('.the-coach').addClass('talking');
    $('.the-coach-says').html(message);
    $('.the-coach-says').show();
    setTimeout(function(){
      $('.the-coach').removeClass('talking');
      $('.the-coach-says').hide();
      randomTalking();
    }, 2000 );
  }
  else {
    window.clearInterval(coachTimer);
    $('.the-coach').addClass('talking');
    $('.the-coach-says').html(coachMessages[Math.floor(Math.random()*coachMessages.length)]);
    $('.the-coach-says').show();
    setTimeout(function(){
      $('.the-coach').removeClass('talking');
      $('.the-coach-says').hide();
    }, 2000 );
    randomTalking();
  }
}
// Coach says random stuff
function randomTalking()
{
  coachTimer = setInterval(function(){
    $('.the-coach').addClass('talking');
    $('.the-coach-says').html(coachMessages[Math.floor(Math.random()*coachMessages.length)]);
    $('.the-coach-says').show();
    setTimeout(function(){
      $('.the-coach').removeClass('talking');
      $('.the-coach-says').hide();
    }, 2000 );
  }, 4500);
}

var date = new Date();
var date_year = date.getFullYear();
var date_day = date.getDate();
var date_month = date.getMonth() + 1;
var full_date = "" + date_year + "-" + date_month + "-" + date_day
var time_min = date.getMinutes();
var time_hours = date.getHours() - 1;
var full_time = "" + time_hours + ":" + time_min + ":00";
var messageList = [];
var maxId = -1;
var coachMessages = [
  "Work on it harder soldier!",
  "What are you, a chicken?",
  "I really need a cheeseburger right now....",
  "You're doing well!  Just kidding, you're performing like crap.",
  "C'mon man, I've seen babies performing better.",
  "Hello World!",
  "Prove P = NP next!",
  "Man, this hackathon is kinda long, dontcha think?"
]

var tasklist = [];
var coachTimer;
var readyToGo = false; // has someone added a task yet?
var task1 = {
  name: "Study for ORF 309",
  time: 5000,
  hours: 0,
  minutes: 0,
  seconds: 5
};
var task2 = {
  name: "Finish drafting my Hackathon idea",
  time: 10000,
  hours: 10,
  minutes: 13,
  seconds: 20
};
var message1 = {
  id: 0,
  name: "Harold Wu",
  text: "Hey man, I hope you are doing well!  You got this!"
};
var message2 = {
  id: 0,
  name: "The Dude",
  text: "Dude, like thats just your opinion man."
};

function onlyNumbers(a,b,c)
{
	return !isNaN(a) && isFinite(parseFloat(a))
	&& !isNaN(b) && isFinite(parseFloat(b))
	&& !isNaN(c) && isFinite(parseFloat(c));
}

function convertMS(a,b,c)
{
	return parseInt(a)*3600000 + parseInt(b)*60000 + parseInt(c)*1000;
}

var taskNum = 0;

function startTimer()
{
  if (taskNum < tasklist.length) {
    var task = tasklist[taskNum];
      $($('.task-time')[taskNum]).countdown({until: task.hours + "h " + task.minutes + "m " + task.seconds + "s", format: "HMS", layout:'{d<}{dn} {dl} and {d>}'+
        '{hn} {hl}, {mn} {ml}, {sn} {sl}', onExpiry: expired});
  }
}

function expired() {
  taskNum++;
  startTimer();
}

function taskFinished(numTask) {
  $($('.task-item')[numTask]).fadeOut(1000);
  $($('.task-time')[numTask]).countdown('destroy');
  taskNum++;
  startTimer();
}
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');

/**
 * Creates an instance of Part.
 * Part objects represent a collection of positive integers.
 *
 * @constructor
 * @this {Part}
 * @param {string} str The string to be parsed as a range.
 * @param {object} unit The unit of measurement of time (see units.js).
 */
function Part(str, unit) {
  this.unit = unit;
  var stringParts = str.split('/');
  if (stringParts.length > 2) {
    throw new Error('Interval syntax error');
  }
  var rangeString = stringParts[0];
  var step = stringParts[1];
  if (typeof step !== 'undefined') {
    step = parseInt(step, 10);
    if (isNaN(step) || step < 1) {
      throw new Error('Invalid interval step value');
    }
  }
  step = step || 1;
  if (unit.alt) {
    rangeString = rangeString.toUpperCase();
    for (var i = 0; i < unit.alt.length; i++) {
      rangeString = rangeString.replace(unit.alt[i], i + unit.min);
    }
  }
  var parsedValues;
  if (rangeString === '*') {
    parsedValues = _.range(unit.min, unit.max + 1);
  } else {
    var parsed = _.map(rangeString.split(','), function(part) {
      var subparts = part.split('-');
      if (subparts.length === 1) {
        var value = parseInt(subparts[0], 10);
        if (isNaN(value)) {
          throw new Error('Invalid value');
        }
        return [value];
      } else if (subparts.length === 2) {
        var minValue = parseInt(subparts[0], 10);
        var maxValue = parseInt(subparts[1], 10);
        if (maxValue <= minValue) {
          throw new Error(
            'Part syntax error: max range is less than min range'
          );
        }
        return _.range(minValue, maxValue + 1);
      } else {
        throw new Error('Part syntax error');
      }
    });
    parsedValues = _.sortBy(_.union(_.flatten(parsed)));
    var first = parsedValues[0];
    var last = parsedValues[parsedValues.length - 1];
    if (first < unit.min || last > unit.max) {
      throw new Error('Value out of range');
    }
  }
  // Apply interval step
  if (step > 1) {
    parsedValues = parsedValues.filter(function(value) {
      return value % step === 0;
    });
    if (!parsedValues.length) {
      throw new Error('Empty interval value');
    }
  }
  this.values = parsedValues;
}

/**
 * Returns the smallest value in the range.
 *
 * @this {Part}
 * @return {number} The smallest value.
 */
Part.prototype.min = function() {
  return this.values[0];
};

/**
 * Returns the largest value in the range.
 *
 * @this {Part}
 * @return {number} The largest value.
 */
Part.prototype.max = function() {
  return this.values[this.values.length - 1];
};

/**
 * Returns true if range has all the values of the unit.
 *
 * @this {Part}
 * @return {boolean} true/false.
 */
Part.prototype.isFull = function() {
  return this.values.length === this.unit.max - this.unit.min + 1;
};

/**
 * Returns the difference between first and second elements in the range.
 *
 * @this {Part}
 * @return {boolean} true/false.
 */
Part.prototype.getStep = function() {
  if (this.values.length > 2) {
    var step = this.values[1] - this.values[0];
    if (step > 1) {
      return step;
    }
  }
};

/**
 * Returns true if the range can be represented as an interval.
 *
 * @this {Part}
 * @param {number} step The difference between numbers in the interval.
 * @return {boolean} true/false.
 */
Part.prototype.isInterval = function(step) {
  for (var i = 1; i < this.values.length; i++) {
    var prev = this.values[i - 1];
    var value = this.values[i];
    if (value - prev !== step) {
      return false;
    }
  }
  return true;
};

/**
 * Returns true if the range contains all the interval values.
 *
 * @this {Part}
 * @param {number} step The difference between numbers in the interval.
 * @return {boolean} true/false.
 */
Part.prototype.isFullInterval = function(step) {
  var unit = this.unit;
  var min = this.min();
  var max = this.max();
  var haveAllValues = this.values.length == (max - min) / step + 1;
  if (min - step < unit.min && max + step > unit.max && haveAllValues) {
    return true;
  }
  return false;
};

/**
 * Returns the range as an array of integers.
 *
 * @this {Part}
 * @return {array} The range as an array.
 */
Part.prototype.toArray = function() {
  return this.values;
};

/**
 * Returns the range as a string.
 *
 * @this {Part}
 * @return {string} The range as a string.
 */
Part.prototype.toString = function() {
  if (this.isFull()) {
    return '*';
  }
  var step = this.getStep();
  if (step && this.isInterval(step)) {
    if (this.isFullInterval(step)) {
      return '*/' + step;
    } else {
      return this.min() + '-' + this.max() + '/' + step;
    }
  } else {
    var retval = [];
    var startPart = null;
    _.forEach(this.values, function(value, index, self) {
      if (value !== self[index + 1] - 1) {
        if (startPart !== null) {
          retval.push(startPart + '-' + value);
          startPart = null;
        } else {
          retval.push(value);
        }
      } else if (startPart === null) {
        startPart = value;
      }
    });
    return retval.join(',');
  }
};

module.exports = Part;
<commit_msg>Factored out toRanges from Part<commit_after>'use strict';

var _ = require('lodash');

/**
 * Creates an instance of Part.
 * Part objects represent a collection of positive integers.
 *
 * @constructor
 * @this {Part}
 * @param {string} str The string to be parsed as a range.
 * @param {object} unit The unit of measurement of time (see units.js).
 */
function Part(str, unit) {
  this.unit = unit;
  var stringParts = str.split('/');
  if (stringParts.length > 2) {
    throw new Error('Interval syntax error');
  }
  var rangeString = stringParts[0];
  var step = stringParts[1];
  if (typeof step !== 'undefined') {
    step = parseInt(step, 10);
    if (isNaN(step) || step < 1) {
      throw new Error('Invalid interval step value');
    }
  }
  step = step || 1;
  if (unit.alt) {
    rangeString = rangeString.toUpperCase();
    for (var i = 0; i < unit.alt.length; i++) {
      rangeString = rangeString.replace(unit.alt[i], i + unit.min);
    }
  }
  var parsedValues;
  if (rangeString === '*') {
    parsedValues = _.range(unit.min, unit.max + 1);
  } else {
    var parsed = _.map(rangeString.split(','), function(part) {
      var subparts = part.split('-');
      if (subparts.length === 1) {
        var value = parseInt(subparts[0], 10);
        if (isNaN(value)) {
          throw new Error('Invalid value');
        }
        return [value];
      } else if (subparts.length === 2) {
        var minValue = parseInt(subparts[0], 10);
        var maxValue = parseInt(subparts[1], 10);
        if (maxValue <= minValue) {
          throw new Error(
            'Part syntax error: max range is less than min range'
          );
        }
        return _.range(minValue, maxValue + 1);
      } else {
        throw new Error('Part syntax error');
      }
    });
    parsedValues = _.sortBy(_.union(_.flatten(parsed)));
    var first = parsedValues[0];
    var last = parsedValues[parsedValues.length - 1];
    if (first < unit.min || last > unit.max) {
      throw new Error('Value out of range');
    }
  }
  // Apply interval step
  if (step > 1) {
    parsedValues = parsedValues.filter(function(value) {
      return value % step === 0;
    });
    if (!parsedValues.length) {
      throw new Error('Empty interval value');
    }
  }
  this.values = parsedValues;
}

/**
 * Returns the smallest value in the range.
 *
 * @this {Part}
 * @return {number} The smallest value.
 */
Part.prototype.min = function() {
  return this.values[0];
};

/**
 * Returns the largest value in the range.
 *
 * @this {Part}
 * @return {number} The largest value.
 */
Part.prototype.max = function() {
  return this.values[this.values.length - 1];
};

/**
 * Returns true if range has all the values of the unit.
 *
 * @this {Part}
 * @return {boolean} true/false.
 */
Part.prototype.isFull = function() {
  return this.values.length === this.unit.max - this.unit.min + 1;
};

/**
 * Returns the difference between first and second elements in the range.
 *
 * @this {Part}
 * @return {boolean} true/false.
 */
Part.prototype.getStep = function() {
  if (this.values.length > 2) {
    var step = this.values[1] - this.values[0];
    if (step > 1) {
      return step;
    }
  }
};

/**
 * Returns true if the range can be represented as an interval.
 *
 * @this {Part}
 * @param {number} step The difference between numbers in the interval.
 * @return {boolean} true/false.
 */
Part.prototype.isInterval = function(step) {
  for (var i = 1; i < this.values.length; i++) {
    var prev = this.values[i - 1];
    var value = this.values[i];
    if (value - prev !== step) {
      return false;
    }
  }
  return true;
};

/**
 * Returns true if the range contains all the interval values.
 *
 * @this {Part}
 * @param {number} step The difference between numbers in the interval.
 * @return {boolean} true/false.
 */
Part.prototype.isFullInterval = function(step) {
  var unit = this.unit;
  var min = this.min();
  var max = this.max();
  var haveAllValues = this.values.length == (max - min) / step + 1;
  if (min - step < unit.min && max + step > unit.max && haveAllValues) {
    return true;
  }
  return false;
};

/**
 * Returns the range as an array of positive integers.
 *
 * @this {Part}
 * @return {array} The range as an array.
 */
Part.prototype.toArray = function() {
  return this.values;
};

/**
 * Returns the range as an array of ranges
 * defined as arrays of positive integers.
 *
 * @this {Part}
 * @return {array} The range as a multi-dimentional array.
 */
Part.prototype.toRanges = function() {
  var retval = [];
  var startPart = null;
  _.forEach(this.values, function(value, index, self) {
    if (value !== self[index + 1] - 1) {
      if (startPart !== null) {
        retval.push([startPart, value]);
        startPart = null;
      } else {
        retval.push(value);
      }
    } else if (startPart === null) {
      startPart = value;
    }
  });
  return retval;
};

/**
 * Returns the range as a string.
 *
 * @this {Part}
 * @return {string} The range as a string.
 */
Part.prototype.toString = function() {
  if (this.isFull()) {
    return '*';
  }
  var step = this.getStep();
  if (step && this.isInterval(step)) {
    if (this.isFullInterval(step)) {
      return '*/' + step;
    } else {
      return this.min() + '-' + this.max() + '/' + step;
    }
  } else {
    return this.toRanges().map(function(range) {
      if (range.length) {
        return range[0] + '-' + range[1];
      }
      return range;
    }).join(',');
  }
};

module.exports = Part;
<|endoftext|>


<commit_before>function doStepwiseAnimation(elementName, structs, duration) {
    var container = new FornaContainer(elementName, {'applyForce': false,
            'allowPanningAndZooming': true,
            "labelInterval":0,
            "initialSize": [800,800],
            "transitionDuration": duration });

    var funcs = []

        for (i = 0; i < structs.length; i++) {
            if (funcs.length === 0)
                (function(val) { funcs.push(function() { container.transitionRNA(structs[val]); container.setOutlineColor('white');
                                            })} )(i);
            else
                (function(val, prevFunc) { funcs.push(function() { container.transitionRNA(structs[val], prevFunc); container.setOutlineColor('white');
                                                      })} )(i, funcs[funcs.length-1] );
        }

    funcs[funcs.length-1]();
}

function createCotranscriptionalTreemap(element, filename) {
var options = {'applyForce': false,
        'allowPanningAndZooming': true,
        "labelInterval":0,
        "initialSize": [800,800],
        "transitionDuration": 0 }

var margin = {top: 10, right: 60, bottom: 40, left: 10},
    totalWidth = 800
    totalHeight = 500

    treemapWidth = totalWidth * 0.75 - margin.left - margin.right,
    treemapHeight = totalHeight - margin.top - margin.bottom,

    lineChartWidth = totalWidth - treemapWidth - margin.left - margin.right,
    lineChartHeight = totalHeight - margin.top - margin.bottom;

var lineX = d3.scale.linear().range([0, lineChartWidth]);
var lineY = d3.scale.linear().range([0, lineChartHeight]);

var color = d3.scale.category20();

var treemap = d3.layout.treemap()
    .size([treemapWidth, treemapHeight])
    .sticky(false)
    .value(function(d) { return d.size; });

var wholeDiv = d3.select(element).append("div")
    .style("position", "relative")
    .style("width", (treemapWidth + lineChartWidth + margin.left + margin.right) + "px")
    .style("height", (treemapHeight + margin.top + margin.bottom) + "px")
    .style("left", margin.left + "px")
    .style("top", margin.top + "px");

var treemapDiv = wholeDiv.append("div")
    .style("position", "absolute")
    .style("width", (treemapWidth) + "px")
    .style("height", (treemapHeight + margin.bottom) + "px")
    .style("left", 0 + "px")
    .style("top", margin.top + "px");

var lineChartDiv = wholeDiv.append("div")
    .style("position", "absolute")
    .style("width", (lineChartWidth + margin.right) + "px")
    .style("height", (lineChartHeight + margin.bottom + margin.top) + "px")
    .style("left", treemapWidth + "px")
    .style("top", 0 + "px");

var svg = lineChartDiv.append("svg")
.attr("width", lineChartWidth)
.attr("height", lineChartHeight)
.append("g")
.attr('transform', "translate(0," + margin.top + ")");

var line = d3.svg.line()
    .interpolate("basis")
    .x(function(d) { return lineX(+d.conc); })
    .y(function(d) { return lineY(+d.time); });

function divName(d) {
    return "div" + d.name;
}

var bisectTime = d3.bisector(function(d) { return d.time; }).left;

function drawCotranscriptionalLine() {
    d3.dsv(" ", 'text/plain')(filename, function(error, data) {
            data.forEach(function(d) {
                d.time = +d.time;
                d.conc = +d.conc;
                //d.full_id = d.id + '-' + d.struct.length;
                //console.log('d.full_id', d.full_id);
                    });

        color.domain(d3.set(data.map(function(d) { return d.id })).values());

        lineX.domain(d3.extent(data, function(d) { return +d.conc; }));
        lineY.domain(d3.extent(data, function(d) { return +d.time; }));

    var xAxis = d3.svg.axis()
        .scale(lineX)
        .orient("bottom");

    var yAxis = d3.svg.axis()
        .scale(lineY)
        .orient("right");
        console.log('extent:', d3.extent(data, function(d) { return +d.time}));

    svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + lineChartHeight + ")")
    .call(xAxis);

    svg.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(" + (lineChartWidth) + ",0)")
    .call(yAxis)
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr('x', -10)
    .attr("y", 35)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("Time (Seconds)");

        var nestedData = d3.nest().key(function(d) { return +d.id; }).entries(data)
        var concProfile = svg.selectAll(".concProfile")
        .data(nestedData)
        .enter().append("g")
        .attr("class", "concProfile");

        function createInitialRoot(nestedData) {
          var root = {"name": "graph",
              "children": nestedData.map(function(d) { return {"name": d.key, "struct":
                        d.values[0].struct, "size": 1 / nestedData.length};})};
          return root;

        }
        var root = createInitialRoot(nestedData);

      var containers = {};

      var node = treemapDiv.datum(root).selectAll(".treemapNode")
          .data(treemap.nodes)
        .enter().append("div")
          .attr("class", "treemapNode")
          .attr("id", divName)
          .call(position)
          //.style("background", function(d) { return d.children ? color(d.name) : null; })
          //.text(function(d) { return d.children ? null : d.name; })
          .each(function(d) {
                  if (typeof d.struct != 'undefined') {
                  containers[divName(d)] = new FornaContainer("#" + divName(d), options);
                  containers[divName(d)].transitionRNA(d.struct);
                  containers[divName(d)].setOutlineColor(color(d.name));
                  }
                  } );

        concProfile.append("path")
        .attr("class", "line")
        .attr("d", function(d) { return line(d.values); })
        .style("stroke", function(d) {
            return color(d.key);
            });

            svg.append("rect")
            .attr("class", "overlay")
            .attr("width", lineChartWidth)
            .attr("height", lineChartHeight)
            .on("mouseover", function() { })
            .on("mousemove", mousemove);

            wholeDiv
                .on("mouseout", function() {
                        var xy = d3.mouse(this);

                        /*
                        if (xy[0] < 0 || xy[1] < margin.top ||
                                xy[0] > treemapWidth + lineChartWidth ||
                                xy[1] > treemapHeight + margin.top) {
                        */
                        if (xy[0] > treemapWidth + lineChartWidth) {
                        /*
                           console.log('d3.mouse(this)', d3.mouse(this));
                           console.log('this', this, treemapHeight + margin.top, treemapWidth + lineChartWidth);
                         */

                        var root = createInitialRoot(nestedData);
                        updateTreemap(root);
                        }
                        })

            function updateTreemap(root) {
                var node = treemapDiv.datum(root).selectAll(".treemapNode")
                    .data(treemap.nodes)
                    .call(position)
                    .each(function(d) {
                            if (typeof d.struct != 'undefined') {
                                var cont = containers[divName(d)];
                                cont.setSize();

                                cont.setOutlineColor(color(d.name));
                            }
                    });
            }

            function mousemove() {
                var y0 = lineY.invert(d3.mouse(this)[1]);
                i = bisectTime(data, y0, 1);
                var values = nestedData.map(function(data) {
                        var i = bisectTime(data.values, y0, 0)

                        if (i >= data.values.length || i == 0)
                            return {"name": data.key, "struct": data.values[0].struct, "size": 0};

                        var d0 = data.values[i-1];
                        var d1 = data.values[i];

                        var sc = d3.scale.linear()
                        .domain([data.values[i-1].time, data.values[i].time])
                        .range([data.values[i-1].conc, data.values[i].conc])

                        var value = sc(y0);

                        var retVal= {"name": data.key, "struct": data.values[0].struct, "size": +value};
                        containers[divName(retVal)].transitionRNA(data.values[i].struct)
                        return retVal;
                        });

                var root = {"name": "graph",
                    "children": values };

                updateTreemap(root);
            }
    });
}

drawCotranscriptionalLine();

function position() {
  this.style("left", function(d) {  return d.x + "px"; })
      .style("top", function(d) { return d.y + "px"; })
      .style("width", function(d) { return Math.max(0, d.dx - 1) + "px"; })
      .style("height", function(d) { return Math.max(0, d.dy - 1) + "px"; });
}
    }

<commit_msg>Some old changes<commit_after>function doStepwiseAnimation(elementName, structs, duration) {
    var container = new FornaContainer(elementName, {'applyForce': false,
            'allowPanningAndZooming': true,
            "labelInterval":0,
            "initialSize": [800,800],
            "transitionDuration": duration });

    var funcs = []

        for (i = 0; i < structs.length; i++) {
            if (funcs.length === 0)
                (function(val) { funcs.push(function() { container.transitionRNA(structs[val]); container.setOutlineColor('white');
                                            })} )(i);
            else
                (function(val, prevFunc) { funcs.push(function() { container.transitionRNA(structs[val], prevFunc); container.setOutlineColor('white');
                                                      })} )(i, funcs[funcs.length-1] );
        }

    funcs[funcs.length-1]();
}

function createCotranscriptionalTreemap(element, filename) {
var options = {'applyForce': false,
        'allowPanningAndZooming': true,
        "labelInterval":0,
        "initialSize": [800,800],
        "transitionDuration": 0 }

var margin = {top: 10, right: 60, bottom: 40, left: 10},
    totalWidth = 800
    totalHeight = 500

    treemapWidth = totalWidth * 0.75 - margin.left - margin.right,
    treemapHeight = totalHeight - margin.top - margin.bottom,

    lineChartWidth = totalWidth - treemapWidth - margin.left - margin.right,
    lineChartHeight = totalHeight - margin.top - margin.bottom;

var lineX = d3.scale.linear().range([0, lineChartWidth]);
var lineY = d3.scale.linear().range([0, lineChartHeight]);

var color = d3.scale.category20();

var treemap = d3.layout.treemap()
    .size([treemapWidth, treemapHeight])
    .sticky(false)
    .value(function(d) { return d.size; });

var wholeDiv = d3.select(element).append("div")
    .style("position", "relative")
    .style("width", (treemapWidth + lineChartWidth + margin.left + margin.right) + "px")
    .style("height", (treemapHeight + margin.top + margin.bottom) + "px")
    .style("left", margin.left + "px")
    .style("top", margin.top + "px");

var treemapDiv = wholeDiv.append("div")
    .style("position", "absolute")
    .style("width", (treemapWidth) + "px")
    .style("height", (treemapHeight + margin.bottom) + "px")
    .style("left", 0 + "px")
    .style("top", margin.top + "px");

var lineChartDiv = wholeDiv.append("div")
    .style("position", "absolute")
    .style("width", (lineChartWidth + margin.right) + "px")
    .style("height", (lineChartHeight + margin.bottom + margin.top) + "px")
    .style("left", treemapWidth + "px")
    .style("top", 0 + "px");

var svg = lineChartDiv.append("svg")
.attr("width", lineChartWidth)
.attr("height", lineChartHeight)
.append("g")
.attr('transform', "translate(0," + margin.top + ")");

var line = d3.svg.line()
    .interpolate("basis")
    .x(function(d) { return lineX(+d.conc); })
    .y(function(d) { return lineY(+d.time); });

function divName(d) {
    return "div" + d.name;
}

var bisectTime = d3.bisector(function(d) { return d.time; }).left;

function drawCotranscriptionalLine() {
    d3.dsv(" ", 'text/plain')(filename, function(error, data) {
            data.forEach(function(d) {
                d.time = +d.time;
                d.conc = +d.conc;
                //d.full_id = d.id + '-' + d.struct.length;
                //console.log('d.full_id', d.full_id);
                    });

        color.domain(d3.set(data.map(function(d) { return d.id })).values());

        lineX.domain(d3.extent(data, function(d) { return +d.conc; }));
        lineY.domain(d3.extent(data, function(d) { return +d.time; }));

    var xAxis = d3.svg.axis()
        .scale(lineX)
        .orient("bottom");

    var yAxis = d3.svg.axis()
        .scale(lineY)
        .orient("right");
        console.log('extent:', d3.extent(data, function(d) { return +d.time}));

    svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + lineChartHeight + ")")
    .call(xAxis);

    svg.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(" + (lineChartWidth) + ",0)")
    .call(yAxis)
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr('x', -10)
    .attr("y", 35)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("Time (Seconds)");

        var nestedData = d3.nest().key(function(d) { return +d.id; }).entries(data)
        var concProfile = svg.selectAll(".concProfile")
        .data(nestedData)
        .enter().append("g")
        .attr("class", "concProfile");

        function createInitialRoot(nestedData) {
          var root = {"name": "graph",
              "children": nestedData.map(function(d) { return {"name": d.key, "struct":
                        d.values[0].struct, "size": 1 / nestedData.length};})};
          return root;

        }
        var root = createInitialRoot(nestedData);

      var containers = {};

      var node = treemapDiv.datum(root).selectAll(".treemapNode")
          .data(treemap.nodes)
        .enter().append("div")
          .attr("class", "treemapNode")
          .attr("id", divName)
          .call(position)
          //.style("background", function(d) { return d.children ? color(d.name) : null; })
          //.text(function(d) { return d.children ? null : d.name; })
          .each(function(d) {
                  if (typeof d.struct != 'undefined') {
                  containers[divName(d)] = new FornaContainer("#" + divName(d), options);
                  containers[divName(d)].transitionRNA(d.struct);
                  containers[divName(d)].setOutlineColor(color(d.name));
                  }
                  } );

        concProfile.append("path")
        .attr("class", "line")
        .attr("d", function(d) { return line(d.values); })
        .style("stroke", function(d) {
            return color(d.key);
            });

            svg.append("rect")
            .attr("class", "overlay")
            .attr("width", lineChartWidth)
            .attr("height", lineChartHeight)
            .on("mouseover", function() { })
            .on("mousemove", mousemove);

            wholeDiv
                .on("mouseout", function() {
                        var xy = d3.mouse(this);

                        /*
                        if (xy[0] < 0 || xy[1] < margin.top ||
                                xy[0] > treemapWidth + lineChartWidth ||
                                xy[1] > treemapHeight + margin.top) {
                        */
                        if (xy[0] > treemapWidth + lineChartWidth) {
                        /*
                           console.log('d3.mouse(this)', d3.mouse(this));
                           console.log('this', this, treemapHeight + margin.top, treemapWidth + lineChartWidth);
                         */

                        var root = createInitialRoot(nestedData);
                        updateTreemap(root);
                        }
                        })

            function updateTreemap(root) {
                var node = treemapDiv.datum(root).selectAll(".treemapNode")
                    .data(treemap.nodes)
                    .call(position)
                    .each(function(d) {
                            if (typeof d.struct != 'undefined') {
                                var cont = containers[divName(d)];
                                cont.setSize();

                                cont.setOutlineColor(color(d.name));
                            }
                    });
            }

            function mousemove() {
                var y0 = lineY.invert(d3.mouse(this)[1]);
                i = bisectTime(data, y0, 1);
                var values = nestedData.map(function(data) {
                        var i = bisectTime(data.values, y0, 0)

                        if (i >= data.values.length || i == 0)
                            return {"name": data.key, "struct": data.values[0].struct, "size": 0};

                        var d0 = data.values[i-1];
                        var d1 = data.values[i];

                        var sc = d3.scale.linear()
                        .domain([data.values[i-1].time, data.values[i].time])
                        .range([data.values[i-1].conc, data.values[i].conc])

                        var value = sc(y0);

                        var retVal= {"name": data.key, "struct": data.values[0].struct, "size": +value};
                        containers[divName(retVal)].transitionRNA(data.values[i].struct)
                        return retVal;
                        });

                var root = {"name": "graph",
                    "children": values };

                updateTreemap(root);
            }
    });
}

drawCotranscriptionalLine();

function position() {
  this.style("left", function(d) {  console.log('yo'); return d.x + "px"; })
      .style("top", function(d) { return d.y + "px"; })
      .style("width", function(d) { return Math.max(0, d.dx - 1) + "px"; })
      .style("height", function(d) { return Math.max(0, d.dy - 1) + "px"; });
}
    }

<|endoftext|>