<commit_before>
window.onerror = function(msg, url, linenumber) {
    alert('Error message: '+msg+'\nURL: '+url+'\nLine Number: '+linenumber);
    return true;
}

window.App = {};
App.isIE = function () {
    var ua = window.navigator.userAgent;
    var msie = ua.indexOf('MSIE ');
    var trident = ua.indexOf('Trident/');

    // if (msie > 0) {
    //     // IE 10 or older => return version number
    //     return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
    // }

    // if (trident > 0) {
    //     // IE 11 (or newer) => return version number
    //     var rv = ua.indexOf('rv:');
    //     return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
    // }

    // other browser
    return msie > 0 || trident > 0;
}

App.showLoader = function (count)
{
	if(!document.getElementById("tt-global-loader"))
	{
		var loader = document.createElement('div');
		loader.total =  (!count || count < 0) ? 0 : count;
		loader.setAttribute("id", "tt-global-loader");
		loader.setAttribute("style", "position : absolute; top: 0px; left: 0px; background : rgba(0,0,0,0.25); z-index: 100; width : 100%; height : 100%; text-align: center;");
		var text = document.createElement("div");
		text.setAttribute("style", "position: relative; display: inline-block; font-size: 2.5em; text-align: center; top : 50%; transform: translateY(-50%);");
		text.setAttribute("class", "text strong noselect");
		text.innerHTML = "Loading";
		var bar = document.createElement('div');
		bar.setAttribute("style", "width : 0%; height: 6px; bottom: 0px; background: #343433; border-radius: 4px; box-shadow: 1px 1px 0px #fff;");

		text.appendChild(bar);
		loader.appendChild(text);

		loader.updateValue = function (value) {
			loader.value = value;
			$(bar).width(((value / loader.total) * 100) + "%");
			return value >= loader.total;
		};
		$(loader).hide();
		document.body.appendChild(loader);
		$(loader).fadeIn();
	} else {
		var loader = document.getElementById("tt-global-loader");
		loader.total = count;
		loader.updateValue(loader.value);
	}
}

App.updateLoder = function (value)
{
	var loader = document.getElementById("tt-global-loader");
	if(loader)
	{
		if(loader.updateValue(value))
		{
			App.hideLoader()
		}
	}
}

App.hideLoader = function ()
{
	var loader = document.getElementById("tt-global-loader");
	if(loader)
	{
		$(loader).fadeOut(function() {
			document.body.removeChild(loader);
			loader = null;
		});
	}
}

App.imagePopup = function (img)
{
	$.magnificPopup.open({
		type : "image",
		items : {
			src : img
		}
	});
}

App.notify = function (item, duration)
{
	var notify = document.getElementById("tt-global-notify");
	if(notify)
	{
		notify.destroy();
	}

	notify = document.createElement('div');
	notify.setAttribute("id", "tt-global-notify");
	notify.setAttribute("style", "background : rgba(240,240,240,0.80); border-bottom : 1px #f7941e solid; width: 100%; height: 25px; position: absolute; top : -50px; left: 0px; z-index: 99");

	var txt = document.createElement("div");
	txt.setAttribute("style", "position: relative; color: #343433; text-shadow: 1px 1px 0px #fff; text-align: center; height: 25px; vertical-align: middle; line-height: 25px;");
	txt.innerHTML = item;
	notify.appendChild(txt);

	notify.close = function ()
	{
		var tmp = this;
		$(tmp).animate({ top : "-=50px" }, 600, function () { tmp.destroy(); });
	};

	notify.destroy = function ()
	{
		document.body.removeChild(this);
	}

	// $(notify).hide();
	document.body.appendChild(notify);
	$(notify).animate({ top : "+=50px" }, 600, function () {
		var tmp = notify;
		setTimeout(function() {
			tmp.close();
			tmp = null;
		}, duration);
	});
}

function updatePage()
{
	var _height  = $("body").height() - $("#header").height() - $("#headerSeparator").height() - $("#footer").height() - 15;
	$("#contentWrapper").height(_height);
	if($("body").height() > 900 && $("body").width() > 1850)
	{
		$(".backdrop").show();
	} else {
		$(".backdrop").hide();
	}
}

$( window ).bind("load", function () {

	$("input.nav").click(function () {
		window.location.href = '/' + this.id;
	});
	$("img.previewImage").click(function () {
		App.imagePopup($(this).attr("src").replace(".png", ".jpg"))
	});
	updatePage();
	if(App.isIE())
	{

		var items = "Ta strona wymaga nowoczesnej przeglądarki. Skorzystaj z" +
					"" +
					" lub " +
					"";
		App.notify(items, 60000);
	}
});
$( window ).resize(updatePage);

<commit_msg>removed global error function<commit_after>window.App = {};
App.isIE = function () {
    var ua = window.navigator.userAgent;
    var msie = ua.indexOf('MSIE ');
    var trident = ua.indexOf('Trident/');

    // if (msie > 0) {
    //     // IE 10 or older => return version number
    //     return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
    // }

    // if (trident > 0) {
    //     // IE 11 (or newer) => return version number
    //     var rv = ua.indexOf('rv:');
    //     return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
    // }

    // other browser
    return msie > 0 || trident > 0;
}

App.showLoader = function (count)
{
	if(!document.getElementById("tt-global-loader"))
	{
		var loader = document.createElement('div');
		loader.total =  (!count || count < 0) ? 0 : count;
		loader.setAttribute("id", "tt-global-loader");
		loader.setAttribute("style", "position : absolute; top: 0px; left: 0px; background : rgba(0,0,0,0.25); z-index: 100; width : 100%; height : 100%; text-align: center;");
		var text = document.createElement("div");
		text.setAttribute("style", "position: relative; display: inline-block; font-size: 2.5em; text-align: center; top : 50%; transform: translateY(-50%);");
		text.setAttribute("class", "text strong noselect");
		text.innerHTML = "Loading";
		var bar = document.createElement('div');
		bar.setAttribute("style", "width : 0%; height: 6px; bottom: 0px; background: #343433; border-radius: 4px; box-shadow: 1px 1px 0px #fff;");

		text.appendChild(bar);
		loader.appendChild(text);

		loader.updateValue = function (value) {
			loader.value = value;
			$(bar).width(((value / loader.total) * 100) + "%");
			return value >= loader.total;
		};
		$(loader).hide();
		document.body.appendChild(loader);
		$(loader).fadeIn();
	} else {
		var loader = document.getElementById("tt-global-loader");
		loader.total = count;
		loader.updateValue(loader.value);
	}
}

App.updateLoder = function (value)
{
	var loader = document.getElementById("tt-global-loader");
	if(loader)
	{
		if(loader.updateValue(value))
		{
			App.hideLoader()
		}
	}
}

App.hideLoader = function ()
{
	var loader = document.getElementById("tt-global-loader");
	if(loader)
	{
		$(loader).fadeOut(function() {
			document.body.removeChild(loader);
			loader = null;
		});
	}
}

App.imagePopup = function (img)
{
	$.magnificPopup.open({
		type : "image",
		items : {
			src : img
		}
	});
}

App.notify = function (item, duration)
{
	var notify = document.getElementById("tt-global-notify");
	if(notify)
	{
		notify.destroy();
	}

	notify = document.createElement('div');
	notify.setAttribute("id", "tt-global-notify");
	notify.setAttribute("style", "background : rgba(240,240,240,0.80); border-bottom : 1px #f7941e solid; width: 100%; height: 25px; position: absolute; top : -50px; left: 0px; z-index: 99");

	var txt = document.createElement("div");
	txt.setAttribute("style", "position: relative; color: #343433; text-shadow: 1px 1px 0px #fff; text-align: center; height: 25px; vertical-align: middle; line-height: 25px;");
	txt.innerHTML = item;
	notify.appendChild(txt);

	notify.close = function ()
	{
		var tmp = this;
		$(tmp).animate({ top : "-=50px" }, 600, function () { tmp.destroy(); });
	};

	notify.destroy = function ()
	{
		document.body.removeChild(this);
	}

	// $(notify).hide();
	document.body.appendChild(notify);
	$(notify).animate({ top : "+=50px" }, 600, function () {
		var tmp = notify;
		setTimeout(function() {
			tmp.close();
			tmp = null;
		}, duration);
	});
}

function updatePage()
{
	var _height  = $("body").height() - $("#header").height() - $("#headerSeparator").height() - $("#footer").height() - 15;
	$("#contentWrapper").height(_height);
	if($("body").height() > 900 && $("body").width() > 1850)
	{
		$(".backdrop").show();
	} else {
		$(".backdrop").hide();
	}
}

$( window ).bind("load", function () {

	$("input.nav").click(function () {
		window.location.href = '/' + this.id;
	});
	$("img.previewImage").click(function () {
		App.imagePopup($(this).attr("src").replace(".png", ".jpg"))
	});
	updatePage();
	if(App.isIE())
	{

		var items = "Ta strona wymaga nowoczesnej przeglądarki. Skorzystaj z" +
					"" +
					" lub " +
					"";
		App.notify(items, 60000);
	}
});
$( window ).resize(updatePage);

<|endoftext|>


<commit_before>var allRecords = null;
var normalizeYAxis = false;
var curOverlay = null;

function fetchArrayBuffer(url, callback) {
  var oReq = new XMLHttpRequest();
  oReq.open("GET", url, true);
  oReq.responseType = "arraybuffer";

  oReq.onload = function (oEvent) {
    var arrayBuffer = oReq.response; // Note: not oReq.responseText
    if (arrayBuffer) {
      callback(arrayBuffer);
    } else {
      console.log("Couldn't fetch file " + url);
    }
  };

  oReq.send(null);
}

function readBtsfRecord(dataBuf, offset, H) {
  var dv = new DataView(dataBuf);
  var N = dv.getUint32(offset+4*0, true);
  var L = dv.getUint32(offset+4*1, true);

  var C = null;
  if(H > 8) {
    C = dv.getFloat32(offset+4*2, true);
  }

  var decoder = new TextDecoder();
  var strView = new DataView(dataBuf, offset+H, L);
  var str = decoder.decode(strView);

  var data = [];
  var datOffset = offset+H+L;
  for(var i = 0; i < N; i++) {
    var T = dv.getInt32(datOffset+i*8, true);
    var D = dv.getFloat32(datOffset+i*8+4, true);
    data.push({t: T, v: D});
  }

  return {
    size: H+L+N*8,
    record: {
      name: str,
      data: data,
      corr: C
    }
  };
}

function readBtsfFile(dataBuf) {
  var dv = new DataView(dataBuf);
  var V = dv.getUint32(0, true);
  var F = dv.getUint32(4*1, true);
  var H = dv.getUint32(4*2, true);
  var R = dv.getUint32(4*3, true);
  console.log("loaded file",[V,F,H,R]);

  var offset = F;
  var records = [];
  for(var i = 0; i < R; i++) {
    var res = readBtsfRecord(dataBuf, offset, H);
    offset += res.size;
    records.push(res.record);
  }
  return records;
}

function serializeBtsfRecord(record) {
  var encoder = new TextEncoder("utf-8");
  var nameBuf = encoder.encode(record.name);

  var length = 4*4+4*2+nameBuf.length+record.data.length*8;
  var dataBuf = new ArrayBuffer(length);
  var dv = new DataView(dataBuf);

  // header
  dv.setUint32(4*0, 1, true);
  dv.setUint32(4*1, 4*4, true);
  dv.setUint32(4*2, 4*2, true);
  dv.setUint32(4*3, 1, true);

  // record
  dv.setUint32(16+4*0, record.data.length, true);
  dv.setUint32(16+4*1, record.name.length, true);
  for (var i = 0; i < nameBuf.length; i++) {
    dv.setUint8(6*4+i, nameBuf[i]);
  }
  for (var i = 0; i < record.data.length; i++) {
    dv.setInt32(6*4+nameBuf.length+i*8, record.data[i].t, true);
    dv.setFloat32(6*4+nameBuf.length+i*8+4, record.data[i].v, true);
  }

  return dataBuf;
}

function maybeTrim(name, len) {
  if(name.length > len-3) {
    return name.slice(0,len-3)+"...";
  } else {
    return name;
  }
}

function drawGraphLine(ctx,w,h, data) {
  var maxV = _.max(data, function(p) { return p.v; }).v;
  var minV = _.min(data, function(p) { return p.v; }).v;
  var maxT = _.max(data, function(p) { return p.t; }).t;
  var minT = _.min(data, function(p) { return p.t; }).t;

  ctx.beginPath();
  ctx.moveTo(0,h);
  for(var i = 0; i < data.length; i++) {
    var x = (data[i].t-minT)/(maxT-minT)*w;
    var yFrac;
    if(normalizeYAxis) {
      yFrac = (data[i].v-minV)/(maxV-minV);
    } else {
      yFrac = (data[i].v)/(maxV);
    }
    var y = yFrac*(h-5)+2;
    if(i == 0) ctx.moveTo(x,h-y);
    ctx.lineTo(x,h-y);
  }
  ctx.stroke();
}

function drawGraph(graphNum, data) {
  var canvasEl = document.getElementById("canv-"+graphNum);
  var ctx = canvasEl.getContext("2d");

  ctx.fillStyle = "white";
  ctx.fillRect(0,0,canvasEl.width,canvasEl.height);

  if(curOverlay !== null) {
    ctx.strokeStyle = "grey";
    drawGraphLine(ctx,canvasEl.width,canvasEl.height, curOverlay);
  }
  ctx.strokeStyle = "#2196F3";
  drawGraphLine(ctx,canvasEl.width,canvasEl.height, data);
}

function displayRecords(records, maxRecords) {
  var numToDisplay = Math.min(maxRecords, records.length);
  setNumberOfGraphs(numToDisplay);

  for(var i = 0; i < numToDisplay; i++) {
    var label = document.getElementById("label-"+i);
    label.innerText = maybeTrim(records[i].name,60);
    label.title = records[i].name;

    var link = document.getElementById("btn-"+i);
    // needed because JS closures interact weirdly with loops
    (function(){
      var record = records[i];
      link.onclick = function() {
        findCorrelations(record);
      }
    })();

    drawGraph(i, records[i].data);
  }
}

// sets up the DOM with the right number of graph boxes
function setNumberOfGraphs(n) {
  var graphsDiv = document.getElementById("graphs");
  var numPresent = graphsDiv.children.length;
  var delta = n - numPresent;

  if(delta > 0) {
    for(var i = 0; i < delta; i++) {
      var graphDiv = document.createElement("div");
      graphDiv.className = "graph";

      var label = document.createElement("h4");
      label.id = "label-"+(numPresent+i);
      graphDiv.appendChild(label);

      var canvas = document.createElement("canvas");
      canvas.id = "canv-"+(numPresent+i);
      canvas.height = 160;
      canvas.width = 300;
      graphDiv.appendChild(canvas);

      var correlate = document.createElement("img");
      correlate.id = "btn-"+(numPresent+i);
      correlate.src = "graph-icon.svg";
      graphDiv.appendChild(correlate);

      var correlation = document.createElement("span");
      correlation.innerText = "r = 0.8";
      correlation.className = "correlation"
      graphDiv.appendChild(correlation);

      graphsDiv.appendChild(graphDiv);
    }
  } else if(delta < 0) {
    for(var i = 0; i < -delta; i++) {
      graphsDiv.children[numPresent-1-i].remove();
    }
  }
}

function filterGraphs() {
  var query = document.getElementById("filter-box").value;
  normalizeYAxis = !document.getElementById("zeroYAxis").checked;
  var records = _.filter(allRecords, function(r) {
    return r.name.includes(query);
  });
  displayRecords(records, 200);
}

function findCorrelations(record) {
  var dataBuf = serializeBtsfRecord(record);
  var xhr = new XMLHttpRequest;
  xhr.open("POST", "/find", true);
  xhr.responseType = "arraybuffer";
  xhr.onload = function (oEvent) {
    var arrayBuffer = xhr.response; // Note: not oReq.responseText
    if (arrayBuffer) {
      allRecords = readBtsfFile(arrayBuffer);

      curOverlay = record.data;
      document.getElementById('filter-box').value = "";
      document.getElementById('zeroYAxis').checked = false;

      filterGraphs();
    } else {
      console.log("Couldn't fetch file " + url);
    }
  };
  xhr.send(new DataView(dataBuf));
}

function loadBtsf(dataBuf) {
  allRecords = readBtsfFile(dataBuf);
  filterGraphs();
}

function init() {
  fetchArrayBuffer("btsf/mortality.btsf", loadBtsf);
  document.getElementById("filter-box").focus();
}
<commit_msg>Correctly set R values<commit_after>var allRecords = null;
var normalizeYAxis = false;
var curOverlay = null;

function fetchArrayBuffer(url, callback) {
  var oReq = new XMLHttpRequest();
  oReq.open("GET", url, true);
  oReq.responseType = "arraybuffer";

  oReq.onload = function (oEvent) {
    var arrayBuffer = oReq.response; // Note: not oReq.responseText
    if (arrayBuffer) {
      callback(arrayBuffer);
    } else {
      console.log("Couldn't fetch file " + url);
    }
  };

  oReq.send(null);
}

function readBtsfRecord(dataBuf, offset, H) {
  var dv = new DataView(dataBuf);
  var N = dv.getUint32(offset+4*0, true);
  var L = dv.getUint32(offset+4*1, true);

  var C = null;
  if(H > 8) {
    C = dv.getFloat32(offset+4*2, true);
  }

  var decoder = new TextDecoder();
  var strView = new DataView(dataBuf, offset+H, L);
  var str = decoder.decode(strView);

  var data = [];
  var datOffset = offset+H+L;
  for(var i = 0; i < N; i++) {
    var T = dv.getInt32(datOffset+i*8, true);
    var D = dv.getFloat32(datOffset+i*8+4, true);
    data.push({t: T, v: D});
  }

  return {
    size: H+L+N*8,
    record: {
      name: str,
      data: data,
      corr: C
    }
  };
}

function readBtsfFile(dataBuf) {
  var dv = new DataView(dataBuf);
  var V = dv.getUint32(0, true);
  var F = dv.getUint32(4*1, true);
  var H = dv.getUint32(4*2, true);
  var R = dv.getUint32(4*3, true);
  console.log("loaded file",[V,F,H,R]);

  var offset = F;
  var records = [];
  for(var i = 0; i < R; i++) {
    var res = readBtsfRecord(dataBuf, offset, H);
    offset += res.size;
    records.push(res.record);
  }
  return records;
}

function serializeBtsfRecord(record) {
  var encoder = new TextEncoder("utf-8");
  var nameBuf = encoder.encode(record.name);

  var length = 4*4+4*2+nameBuf.length+record.data.length*8;
  var dataBuf = new ArrayBuffer(length);
  var dv = new DataView(dataBuf);

  // header
  dv.setUint32(4*0, 1, true);
  dv.setUint32(4*1, 4*4, true);
  dv.setUint32(4*2, 4*2, true);
  dv.setUint32(4*3, 1, true);

  // record
  dv.setUint32(16+4*0, record.data.length, true);
  dv.setUint32(16+4*1, record.name.length, true);
  for (var i = 0; i < nameBuf.length; i++) {
    dv.setUint8(6*4+i, nameBuf[i]);
  }
  for (var i = 0; i < record.data.length; i++) {
    dv.setInt32(6*4+nameBuf.length+i*8, record.data[i].t, true);
    dv.setFloat32(6*4+nameBuf.length+i*8+4, record.data[i].v, true);
  }

  return dataBuf;
}

function maybeTrim(name, len) {
  if(name.length > len-3) {
    return name.slice(0,len-3)+"...";
  } else {
    return name;
  }
}

function drawGraphLine(ctx,w,h, data) {
  var maxV = _.max(data, function(p) { return p.v; }).v;
  var minV = _.min(data, function(p) { return p.v; }).v;
  var maxT = _.max(data, function(p) { return p.t; }).t;
  var minT = _.min(data, function(p) { return p.t; }).t;

  ctx.beginPath();
  ctx.moveTo(0,h);
  for(var i = 0; i < data.length; i++) {
    var x = (data[i].t-minT)/(maxT-minT)*w;
    var yFrac;
    if(normalizeYAxis) {
      yFrac = (data[i].v-minV)/(maxV-minV);
    } else {
      yFrac = (data[i].v)/(maxV);
    }
    var y = yFrac*(h-5)+2;
    if(i == 0) ctx.moveTo(x,h-y);
    ctx.lineTo(x,h-y);
  }
  ctx.stroke();
}

function drawGraph(graphNum, data) {
  var canvasEl = document.getElementById("canv-"+graphNum);
  var ctx = canvasEl.getContext("2d");

  ctx.fillStyle = "white";
  ctx.fillRect(0,0,canvasEl.width,canvasEl.height);

  if(curOverlay !== null) {
    ctx.strokeStyle = "grey";
    drawGraphLine(ctx,canvasEl.width,canvasEl.height, curOverlay);
  }
  ctx.strokeStyle = "#2196F3";
  drawGraphLine(ctx,canvasEl.width,canvasEl.height, data);
}

function displayRecords(records, maxRecords) {
  var numToDisplay = Math.min(maxRecords, records.length);
  setNumberOfGraphs(numToDisplay);

  for(var i = 0; i < numToDisplay; i++) {
    var label = document.getElementById("label-"+i);
    label.innerText = maybeTrim(records[i].name,60);
    label.title = records[i].name;

    var corrEl = document.getElementById("corr-"+i);
    if(records[i].corr !== null) {
      corrEl.style.display = "initial";
      corrEl.innerText = "r = " + records[i].corr.toFixed(3);
    } else {
      corrEl.style.display = "none";
    }

    var link = document.getElementById("btn-"+i);
    // needed because JS closures interact weirdly with loops
    (function(){
      var record = records[i];
      link.onclick = function() {
        findCorrelations(record);
      }
    })();

    drawGraph(i, records[i].data);
  }
}

// sets up the DOM with the right number of graph boxes
function setNumberOfGraphs(n) {
  var graphsDiv = document.getElementById("graphs");
  var numPresent = graphsDiv.children.length;
  var delta = n - numPresent;

  if(delta > 0) {
    for(var i = 0; i < delta; i++) {
      var graphDiv = document.createElement("div");
      graphDiv.className = "graph";

      var label = document.createElement("h4");
      label.id = "label-"+(numPresent+i);
      graphDiv.appendChild(label);

      var canvas = document.createElement("canvas");
      canvas.id = "canv-"+(numPresent+i);
      canvas.height = 160;
      canvas.width = 300;
      graphDiv.appendChild(canvas);

      var correlate = document.createElement("img");
      correlate.id = "btn-"+(numPresent+i);
      correlate.src = "graph-icon.svg";
      graphDiv.appendChild(correlate);

      var correlation = document.createElement("span");
      correlation.innerText = "r = 0.8";
      correlation.className = "correlation"
      correlation.id = "corr-"+(numPresent+i);
      graphDiv.appendChild(correlation);

      graphsDiv.appendChild(graphDiv);
    }
  } else if(delta < 0) {
    for(var i = 0; i < -delta; i++) {
      graphsDiv.children[numPresent-1-i].remove();
    }
  }
}

function filterGraphs() {
  var query = document.getElementById("filter-box").value;
  normalizeYAxis = !document.getElementById("zeroYAxis").checked;
  var records = _.filter(allRecords, function(r) {
    return r.name.includes(query);
  });
  displayRecords(records, 200);
}

function findCorrelations(record) {
  var dataBuf = serializeBtsfRecord(record);
  var xhr = new XMLHttpRequest;
  xhr.open("POST", "/find", true);
  xhr.responseType = "arraybuffer";
  xhr.onload = function (oEvent) {
    var arrayBuffer = xhr.response; // Note: not oReq.responseText
    if (arrayBuffer) {
      allRecords = readBtsfFile(arrayBuffer);

      curOverlay = record.data;
      document.getElementById('filter-box').value = "";
      document.getElementById('zeroYAxis').checked = false;

      filterGraphs();
    } else {
      console.log("Couldn't fetch file " + url);
    }
  };
  xhr.send(new DataView(dataBuf));
}

function loadBtsf(dataBuf) {
  allRecords = readBtsfFile(dataBuf);
  filterGraphs();
}

function init() {
  fetchArrayBuffer("btsf/mortality.btsf", loadBtsf);
  document.getElementById("filter-box").focus();
}
<|endoftext|>


<commit_before>$(function(){
  function resize() {
    var height = $(window).height() - $("#header").outerHeight() - 20;
    $("#text").height(height);
    $("#readme").height(height);
  }
  resize();
  $(window).resize(_.debounce(resize,300));
  $("#text").keyup(_.debounce(function(event) {
    $.ajax({
      type: "POST",
      url: "/render",
      data: {
        format: $('#format').val(),
        data: $("#text").val()
      },
      success: function(data) {
        $('#preview').empty().append(data);
      }
    });
  },300));
});
<commit_msg>render when change format<commit_after>$(function(){
  function resize() {
    var height = $(window).height() - $("#header").outerHeight() - 20;
    $("#text").height(height);
    $("#readme").height(height);
  }
  resize();
  $(window).resize(_.debounce(resize,300));

  function render() {
    $.ajax({
      type: "POST",
      url: "/render",
      data: {
        format: $('#format').val(),
        data: $("#text").val()
      },
      success: function(data) {
        $('#preview').empty().append(data);
      }
    });
  }
  $("#format").change(render);
  $("#text").keyup(_.debounce(render,300));
});
<|endoftext|>


<commit_before>var app = angular.module('myApp', ['ui.router']);

app.config(($stateProvider, $urlRouterProvider) => {

    $urlRouterProvider.otherwise("/");

    $stateProvider
        .state('out', {
            url: "/login",
            templateUrl: "views/login.html",
            controller: 'LoginCtrl'
        })
        .state('in', {
            url: '',
            templateUrl: "views/master.html"
        })
        .state('in.main', {
            url: "/main",
            templateUrl: "views/main.html",
            controller: 'MainCtrl'
        })
        .state('in.extra', {
            url: "/extra",
            templateUrl: "views/extra.html",
            controller: 'ExtraCtrl'
        })
});

app.config(($httpProvider) => {
    $httpProvider.interceptors.push('RespErrInjector');
});<commit_msg>default redirect to main in in state<commit_after>var app = angular.module('myApp', ['ui.router']);

app.config(($stateProvider, $urlRouterProvider) => {

    $urlRouterProvider.otherwise("/");

    $stateProvider
        .state('out', {
            url: "/login",
            templateUrl: "views/login.html",
            controller: 'LoginCtrl'
        })
        .state('in', {
            url: '',
            templateUrl: "views/master.html",
            redirectTo: 'in.main'
        })
        .state('in.main', {
            url: '',
            templateUrl: "views/main.html",
            controller: 'MainCtrl'
        })
        .state('in.extra', {
            url: "/extra",
            templateUrl: "views/extra.html",
            controller: 'ExtraCtrl'
        })
});

app.config(($httpProvider) => {
    $httpProvider.interceptors.push('RespErrInjector');
});

// enable "redirectTo" attribute in $stateProvider.state to acheive defaul child state
app.run(($rootScope, $state) => {
    $rootScope.$on('$stateChangeStart', function(evt, to, params) {
        if (to.redirectTo) {
            evt.preventDefault();
            $state.go(to.redirectTo, params)
        }
    });
});<|endoftext|>


<commit_before>const path = require('path');

const gulp = require('gulp');
const karma = require('karma');

<% if (modules === 'inject') { -%>
gulp.task('karma:single-run', gulp.series('scripts', karmaSingleRun));
gulp.task('karma:auto-run', gulp.series('watch', karmaAutoRun));
<% } else { -%>
gulp.task('karma:single-run', karmaSingleRun);
gulp.task('karma:auto-run', karmaAutoRun);
<% } -%>

function karmaFinishHandler(done) {
  return failCount => {
    done(failCount ? new Error(`Failed ${failCount} tests.`) : null);
  }
}

function karmaSingleRun(done) {
  const configFile = path.join(process.cwd(), 'conf', 'karma.conf.js');
  const karmaServer = new karma.Server({ configFile }, karmaFinishHandler(done));
  karmaServer.start();
}

function karmaAutoRun(done) {
  const configFile = path.join(process.cwd(), 'conf', 'karma-auto.conf.js');
  const karmaServer = new karma.Server({ configFile }, karmaFinishHandler(done));
  karmaServer.start();
}
<commit_msg>remove karma task deps in favor of the root gulpfile<commit_after>const path = require('path');

const gulp = require('gulp');
const karma = require('karma');

gulp.task('karma:single-run', karmaSingleRun);
gulp.task('karma:auto-run', karmaAutoRun);

function karmaFinishHandler(done) {
  return failCount => {
    done(failCount ? new Error(`Failed ${failCount} tests.`) : null);
  }
}

function karmaSingleRun(done) {
  const configFile = path.join(process.cwd(), 'conf', 'karma.conf.js');
  const karmaServer = new karma.Server({ configFile }, karmaFinishHandler(done));
  karmaServer.start();
}

function karmaAutoRun(done) {
  const configFile = path.join(process.cwd(), 'conf', 'karma-auto.conf.js');
  const karmaServer = new karma.Server({ configFile }, karmaFinishHandler(done));
  karmaServer.start();
}
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash'),
    PropTypes = require('prop-types');

/**
 * format propTypes according to react.PropTypes
 * @param fieldPropType
 * @returns {*}
 */
function formatPropTypes(fieldPropType) {
    for (var key in PropTypes) {
        if (fieldPropType.indexOf(key) > -1) {
            return 'PropTypes.' + key;
        }
    }
    return '';
}

/**
 * remove end comma
 * @param fieldDefaultProps
 * @returns {*}
 */
function formatDefaultProps(fieldDefaultProps) {

    var result = fieldDefaultProps;

    if (result.slice(-1) === ',') {
        result = result.slice(0, -1);
    }

    if ((result.slice(0, 1) === '\'' && result.slice(-1) === '\'')
        || (result.slice(0, 1) === '"' && result.slice(-1) === '"')) {
        result = result.slice(1, -1);
    }

    return result;

}

function splitField(fieldString) {
    return {
        key: _.trim(fieldString.slice(0, fieldString.indexOf(':'))),
        value: _.trim(fieldString.slice(fieldString.indexOf(':') + 1))
    };
}

/**
 * generate fieldName and comment into result
 * @param componentName
 * @param fileString
 * @param result
 */
function generatePropTypes(componentName, fileString, result) {

    var propTypesFileString = fileString.slice(fileString.indexOf(componentName + '.propTypes')),
        propTypesFileArray = propTypesFileString.split('\n'),
        braceCount = 0, commentStart, comment, fieldString, fieldObj;

    for (var i = 0, len = propTypesFileArray.length; i < len; i++) {

        var line = propTypesFileArray[i];

        if (commentStart && line.indexOf('*/') > -1) {

            if (propTypesFileArray[i + 1]) {

                fieldString = propTypesFileArray[i + 1];
                fieldObj = splitField(fieldString);
                comment += _.trim(line.slice(0, line.indexOf('*/')));

                result[fieldObj.key] = {
                    type: formatPropTypes(fieldObj.value),
                    desc: comment
                };

            }

            commentStart = comment = undefined;
            i++;

        } else if (commentStart) {
            comment += (comment === '' ? '' : ' ') + _.trim(line.slice(line.indexOf('*') + 1));
        } else if (line.indexOf('/**') > -1) {
            commentStart = i;
            comment = _.trim(line.slice(line.indexOf('/**') + 3));
        } else if (line.indexOf('PropTypes') > -1) {

            fieldString = line;
            fieldObj = splitField(fieldString);

            result[fieldObj.key] = {
                type: formatPropTypes(fieldObj.value)
            };

        } else {

            braceCount += (line.split('{').length - 1);
            braceCount -= (line.split('}').length - 1);

            if (braceCount == 0) {
                break;
            }

        }

    }

}

/**
 * generate defaultProps into result
 * @param componentName
 * @param fileString
 * @param result
 */
function generateDefaultProps(componentName, fileString, result) {

    var defaultPropsFileString = fileString.slice(fileString.indexOf(componentName + '.defaultProps')),
        defaultPropsFileArray = defaultPropsFileString.split('\n'),
        braceCount = 0, fieldObj, fieldName;

    for (var i = 0, len = defaultPropsFileArray.length; i < len; i++) {

        var line = defaultPropsFileArray[i];

        fieldObj = splitField(line);
        fieldName = fieldObj.key;

        if (result[fieldName]) {
            result[fieldName].default = formatDefaultProps(fieldObj.value);
        }

        braceCount += (line.split('{').length - 1);
        braceCount -= (line.split('}').length - 1);

        if (braceCount == 0) {
            break;
        }

    }

}

module.exports = function (componentName, fileString) {

    if (!fileString) {
        return fileString;
    }

    var result = {};

    generatePropTypes(componentName, fileString, result);
    generateDefaultProps(componentName, fileString, result);

    return JSON.stringify(result, null, 4);

};<commit_msg>update generateComponentPropTypeJson<commit_after>'use strict';

var _ = require('lodash'),
    PropTypes = require('prop-types');

/**
 * format propTypes according to react.PropTypes
 * @param fieldPropType
 * @returns {*}
 */
function formatPropTypes(fieldPropType) {
    for (var key in PropTypes) {
        if (fieldPropType.indexOf(key) > -1) {
            return 'PropTypes.' + key;
        }
    }
    return '';
}

/**
 * remove end comma
 * @param fieldDefaultProps
 * @returns {*}
 */
function formatDefaultProps(fieldDefaultProps) {

    var result = fieldDefaultProps;

    if (result.slice(-1) === ',') {
        result = result.slice(0, -1);
    }

    if ((result.slice(0, 1) === '\'' && result.slice(-1) === '\'')
        || (result.slice(0, 1) === '"' && result.slice(-1) === '"')) {
        result = result.slice(1, -1);
    }

    return result;

}

function splitField(fieldString) {
    return {
        key: _.trim(fieldString.slice(0, fieldString.indexOf(':'))),
        value: _.trim(fieldString.slice(fieldString.indexOf(':') + 1))
    };
}

/**
 * generate fieldName and comment into result
 * @param componentName
 * @param fileString
 * @param result
 */
function generatePropTypes(componentName, fileString, result) {

    var propTypesFileString = fileString.slice(fileString.indexOf(componentName + '.propTypes')),
        propTypesFileArray = propTypesFileString.split('\n'),
        lastLineBraceCount = 0, braceCount = 0, commentStart, comment, fieldString, fieldObj;

    for (var i = 0, len = propTypesFileArray.length; i < len; i++) {

        var line = propTypesFileArray[i];

        lastLineBraceCount = braceCount;

        braceCount += (line.split('(').length - 1);
        braceCount += (line.split('[').length - 1);
        braceCount += (line.split('{').length - 1);
        braceCount -= (line.split(')').length - 1);
        braceCount -= (line.split(']').length - 1);
        braceCount -= (line.split('}').length - 1);

        if (lastLineBraceCount > 1 || braceCount > 1) {
            continue;
        }

        if (braceCount < 1) {
            break;
        }

        if (commentStart && line.indexOf('*/') > -1) {

            if (propTypesFileArray[i + 1]) {

                fieldString = propTypesFileArray[i + 1];
                fieldObj = splitField(fieldString);
                comment += _.trim(line.slice(0, line.indexOf('*/')));

                result[fieldObj.key] = {
                    type: formatPropTypes(fieldObj.value),
                    desc: comment
                };

            }

            commentStart = comment = undefined;

        } else if (commentStart) {
            comment += (comment === '' ? '' : ' ') + _.trim(line.slice(line.indexOf('*') + 1));
        } else if (line.indexOf('/**') > -1) {
            commentStart = i;
            comment = _.trim(line.slice(line.indexOf('/**') + 3));
        } else if (line.indexOf('PropTypes') > -1) {

            fieldString = line;
            fieldObj = splitField(fieldString);

            result[fieldObj.key] = {
                type: formatPropTypes(fieldObj.value)
            };

        }

    }

}

/**
 * generate defaultProps into result
 * @param componentName
 * @param fileString
 * @param result
 */
function generateDefaultProps(componentName, fileString, result) {

    var defaultPropsFileString = fileString.slice(fileString.indexOf(componentName + '.defaultProps')),
        defaultPropsFileArray = defaultPropsFileString.split('\n'),
        braceCount = 0, fieldObj, fieldName;

    for (var i = 0, len = defaultPropsFileArray.length; i < len; i++) {

        var line = defaultPropsFileArray[i];

        fieldObj = splitField(line);
        fieldName = fieldObj.key;

        if (result[fieldName]) {
            result[fieldName].default = formatDefaultProps(fieldObj.value);
        }

        braceCount += (line.split('{').length - 1);
        braceCount -= (line.split('}').length - 1);

        if (braceCount == 0) {
            break;
        }

    }

}

module.exports = function (componentName, fileString) {

    if (!fileString) {
        return fileString;
    }

    var result = {};

    generatePropTypes(componentName, fileString, result);
    generateDefaultProps(componentName, fileString, result);

    return JSON.stringify(result, null, 4);

};<|endoftext|>


<commit_before>describe('ui.grid.resizeColumns', function () {
  var grid, $scope, $compile, recompile;

  var data = [
    { "name": "Ethel Price", "gender": "female", "company": "Enersol" },
    { "name": "Claudine Neal", "gender": "female", "company": "Sealoud" },
    { "name": "Beryl Rice", "gender": "female", "company": "Velity" },
    { "name": "Wilder Gonzales", "gender": "male", "company": "Geekko" }
  ];

  beforeEach(module('ui.grid'));
  beforeEach(module('ui.grid.resizeColumns'));

  beforeEach(inject(function(_$compile_, $rootScope) {
    $scope = $rootScope;
    $compile = _$compile_;

    $scope.gridOpts = {
      enableColumnResizing: true,
      data: data
    };

    grid = angular.element('

');
    document.body.appendChild(grid[0]);

    recompile = function() {
      $compile(grid)($scope);
      $scope.$digest();
    };

    recompile();
  }));

  afterEach(function() {
    angular.element(grid).remove();
    grid = null;
  });

  describe('setting enableColumnResizing', function() {
    it('should by default cause resizer to be attached to the header elements', function() {
      // $scope.gridOpts.enableColumnResizing = true;
      // recompile();

      var resizers = $(grid).find('[ui-grid-column-resizer]');

      expect(resizers.size()).toEqual(4);
    });

    it('should only attach a right resizer to the first column', function() {
      // $scope.gridOpts.enableColumnResizing = true;
      // recompile();

      var firstColumn = $(grid).find('[ui-grid-header-cell]').first();

      var resizers = $(firstColumn).find('[ui-grid-column-resizer]');

      expect(resizers.size()).toEqual(1);

      expect(resizers.first().attr('position')).toEqual('right');
      expect(resizers.first().hasClass('right')).toBe(true);
    });

    it('should only attach a left resizer to the last column', function() {
      // $scope.gridOpts.enableColumnResizing = true;
      // recompile();

      var firstColumn = $(grid).find('[ui-grid-header-cell]').last();

      var resizers = $(firstColumn).find('[ui-grid-column-resizer]');

      expect(resizers.size()).toEqual(1);

      expect(resizers.first().attr('position')).toEqual('left');
      expect(resizers.first().hasClass('left')).toBe(true);
    });
  });

  describe('setting enableColumnResizing to false', function() {
    it('should result in no resizer elements being attached to the column', function() {
      $scope.gridOpts.enableColumnResizing = false;
      recompile();

      var resizers = $(grid).find('[ui-grid-column-resizer]');

      expect(resizers.size()).toEqual(0);
    });
  });

  describe('setting flag on colDef to false', function() {
    it('should result in no resizer elements being attached to the column', function() {
      $scope.gridOpts.columnDefs = [
        { field: 'name' },
        { field: 'gender', enableColumnResizing: false },
        { field: 'company' }
      ];

      recompile();

      var middleCol = $(grid).find('[ui-grid-header-cell]:nth-child(2)');
      var resizer = middleCol.find('[ui-grid-column-resizer]');

      expect(resizer.size()).toEqual(0);
    });
  });

  // NOTE: these pixel sizes might fail in other browsers, due to font differences!
  describe('when double-clicking a resizer', function() {
    it('should resize the column to the maximum width of the rendered columns', function(done) {
      var firstResizer = $(grid).find('[ui-grid-column-resizer]').first();

      var colWidth = $(grid).find('.col0').first().width();

      expect(colWidth).toEqual(166);

      firstResizer.trigger('dblclick');

      $scope.$digest();

      var newColWidth = $(grid).find('.col0').first().width();

      // How to handle this here?
      expect(newColWidth).not.toEqual(colWidth);
    });
  });

  describe('clicking on a resizer', function() {
    it('should cause the column separator overlay to be added', function() {
      var firstResizer = $(grid).find('[ui-grid-column-resizer]').first();

      firstResizer.trigger('mousedown');
      $scope.$digest();

      var overlay = $(grid).find('.ui-grid-resize-overlay');

      expect(overlay.size()).toEqual(1);

      // The grid shouldn't have the resizing class
      expect(grid.hasClass('column-resizing')).toEqual(false);
    });

    describe('and moving the mouse', function() {
      var xDiff, initialWidth, initialX, overlay, initialOverlayX;

      beforeEach(function() {
        var firstResizer = $(grid).find('[ui-grid-column-resizer]').first();

        // Get the initial width of the column
        initialWidth = $(grid).find('.col0').first().width();

        initialX = firstResizer.position().left;

        $(firstResizer).simulate('mousedown', { clientX: initialX });
        $scope.$digest();

        // Get the overlay
        overlay = $(grid).find('.ui-grid-resize-overlay');
        initialOverlayX = $(overlay).position().left;

        xDiff = 100;
        $(document).simulate('mousemove', { clientX: initialX + xDiff });
        $scope.$digest();
      });

      it('should add the column-resizing class to the grid', function() {
        // The grid should have the resizing class
        expect(grid.hasClass('column-resizing')).toEqual(true);
      });

      it('should cause the overlay to appear', function() {
        expect(overlay.is(':visible')).toEqual(true);
      });

      it('should cause the overlay to move', function() {
        expect($(overlay).position().left).toEqual( (initialX + xDiff + 1) ); // Extra one pixel here for grid border
      });

      describe('then releasing the mouse', function() {
        beforeEach(function() {
          $(document).simulate('mouseup', { clientX: initialX + xDiff });
          $scope.$digest();
        });

        it('should cause the column to resize by the amount change in the X axis', function() {
          var newWidth = $(grid).find('.col0').first().width();

          expect(newWidth - initialWidth).toEqual(xDiff);
        });

        it('should remove the overlay', function() {
          var overlay = $(grid).find('.ui-grid-resize-overlay');

          expect(overlay.size()).toEqual(0);
        });
      });
    });
  });

  // TODO(c0bra): add tests for minWidth and maxWidth. Need to test on double-click too, and on default
});<commit_msg>Add tests for minWidth and maxWidth in column resizing<commit_after>describe('ui.grid.resizeColumns', function () {
  var grid, $scope, $compile, recompile;

  var data = [
    { "name": "Ethel Price", "gender": "female", "company": "Enersol" },
    { "name": "Claudine Neal", "gender": "female", "company": "Sealoud" },
    { "name": "Beryl Rice", "gender": "female", "company": "Velity" },
    { "name": "Wilder Gonzales", "gender": "male", "company": "Geekko" }
  ];

  beforeEach(module('ui.grid'));
  beforeEach(module('ui.grid.resizeColumns'));

  beforeEach(inject(function(_$compile_, $rootScope) {
    $scope = $rootScope;
    $compile = _$compile_;

    $scope.gridOpts = {
      enableColumnResizing: true,
      data: data
    };

    grid = angular.element('

');
    document.body.appendChild(grid[0]);

    recompile = function() {
      $compile(grid)($scope);
      $scope.$digest();
    };

    recompile();
  }));

  afterEach(function() {
    angular.element(grid).remove();
    grid = null;
  });

  describe('setting enableColumnResizing', function() {
    it('should by default cause resizer to be attached to the header elements', function() {
      // $scope.gridOpts.enableColumnResizing = true;
      // recompile();

      var resizers = $(grid).find('[ui-grid-column-resizer]');

      expect(resizers.size()).toEqual(4);
    });

    it('should only attach a right resizer to the first column', function() {
      // $scope.gridOpts.enableColumnResizing = true;
      // recompile();

      var firstColumn = $(grid).find('[ui-grid-header-cell]').first();

      var resizers = $(firstColumn).find('[ui-grid-column-resizer]');

      expect(resizers.size()).toEqual(1);

      expect(resizers.first().attr('position')).toEqual('right');
      expect(resizers.first().hasClass('right')).toBe(true);
    });

    it('should only attach a left resizer to the last column', function() {
      // $scope.gridOpts.enableColumnResizing = true;
      // recompile();

      var firstColumn = $(grid).find('[ui-grid-header-cell]').last();

      var resizers = $(firstColumn).find('[ui-grid-column-resizer]');

      expect(resizers.size()).toEqual(1);

      expect(resizers.first().attr('position')).toEqual('left');
      expect(resizers.first().hasClass('left')).toBe(true);
    });
  });

  describe('setting enableColumnResizing to false', function() {
    it('should result in no resizer elements being attached to the column', function() {
      $scope.gridOpts.enableColumnResizing = false;
      recompile();

      var resizers = $(grid).find('[ui-grid-column-resizer]');

      expect(resizers.size()).toEqual(0);
    });
  });

  describe('setting flag on colDef to false', function() {
    it('should result in no resizer elements being attached to the column', function() {
      $scope.gridOpts.columnDefs = [
        { field: 'name' },
        { field: 'gender', enableColumnResizing: false },
        { field: 'company' }
      ];

      recompile();

      var middleCol = $(grid).find('[ui-grid-header-cell]:nth-child(2)');
      var resizer = middleCol.find('[ui-grid-column-resizer]');

      expect(resizer.size()).toEqual(0);
    });
  });

  // NOTE: these pixel sizes might fail in other browsers, due to font differences!
  describe('when double-clicking a resizer', function() {
    it('should resize the column to the maximum width of the rendered columns', function(done) {
      var firstResizer = $(grid).find('[ui-grid-column-resizer]').first();

      var colWidth = $(grid).find('.col0').first().width();

      expect(colWidth).toEqual(166);

      firstResizer.trigger('dblclick');

      $scope.$digest();

      var newColWidth = $(grid).find('.col0').first().width();

      // How to handle this here?
      expect(newColWidth).not.toEqual(colWidth);
    });
  });

  describe('clicking on a resizer', function() {
    it('should cause the column separator overlay to be added', function() {
      var firstResizer = $(grid).find('[ui-grid-column-resizer]').first();

      firstResizer.trigger('mousedown');
      $scope.$digest();

      var overlay = $(grid).find('.ui-grid-resize-overlay');

      expect(overlay.size()).toEqual(1);

      // The grid shouldn't have the resizing class
      expect(grid.hasClass('column-resizing')).toEqual(false);
    });

    describe('and moving the mouse', function() {
      var xDiff, initialWidth, initialX, overlay, initialOverlayX;

      beforeEach(function() {
        var firstResizer = $(grid).find('[ui-grid-column-resizer]').first();

        // Get the initial width of the column
        initialWidth = $(grid).find('.col0').first().width();

        initialX = firstResizer.position().left;

        $(firstResizer).simulate('mousedown', { clientX: initialX });
        $scope.$digest();

        // Get the overlay
        overlay = $(grid).find('.ui-grid-resize-overlay');
        initialOverlayX = $(overlay).position().left;

        xDiff = 100;
        $(document).simulate('mousemove', { clientX: initialX + xDiff });
        $scope.$digest();
      });

      it('should add the column-resizing class to the grid', function() {
        // The grid should have the resizing class
        expect(grid.hasClass('column-resizing')).toEqual(true);
      });

      it('should cause the overlay to appear', function() {
        expect(overlay.is(':visible')).toEqual(true);
      });

      it('should cause the overlay to move', function() {
        expect($(overlay).position().left).toEqual( (initialX + xDiff + 1) ); // Extra one pixel here for grid border
      });

      describe('then releasing the mouse', function() {
        beforeEach(function() {
          $(document).simulate('mouseup', { clientX: initialX + xDiff });
          $scope.$digest();
        });

        it('should cause the column to resize by the amount change in the X axis', function() {
          var newWidth = $(grid).find('.col0').first().width();

          expect(newWidth - initialWidth).toEqual(xDiff);
        });

        it('should remove the overlay', function() {
          var overlay = $(grid).find('.ui-grid-resize-overlay');

          expect(overlay.size()).toEqual(0);
        });
      });
    });
  });

  describe('when a column has a minWidth', function() {
    var minWidth;

    beforeEach(function() {
      minWidth = 200;

      $scope.gridOpts.columnDefs = [
        { field: 'name', minWidth: minWidth },
        { field: 'gender' },
        { field: 'company' }
      ];

      recompile();
    });

    describe('and you double-click its resizer, the column width', function() {
      it('should not go below the minWidth', function() {
        var firstResizer = $(grid).find('[ui-grid-column-resizer]').first();

        $(firstResizer).simulate('dblclick');
        $scope.$digest();

        var newWidth = $(grid).find('.col0').first().width();

        dump(newWidth, minWidth);

        expect(newWidth >= minWidth).toEqual(true);
      });
    });

    describe('and you move its resizer left further than the minWidth, the column width', function() {
      var initialX;

      beforeEach(function() {
        var firstResizer = $(grid).find('[ui-grid-column-resizer]').first();
        initialX = firstResizer.position().left;

        $(firstResizer).simulate('mousedown', { clientX: initialX });
        $scope.$digest();

        $(document).simulate('mouseup', { clientX: initialX - minWidth });
        $scope.$digest();
      });

      it('should not go below the minWidth', function() {
        var newWidth = $(grid).find('.col0').first().width();

        expect(newWidth >= minWidth).toEqual(true);
      });
    });
  });

  describe('when a column has a maxWidth', function() {
    var maxWidth;

    beforeEach(function() {
      maxWidth = 60;

      $scope.gridOpts.columnDefs = [
        { field: 'name', maxWidth: maxWidth },
        { field: 'gender' },
        { field: 'company' }
      ];

      recompile();
    });

    describe('and you double-click its resizer', function() {
      it('the column width should not go above the maxWidth', function() {
        var firstResizer = $(grid).find('[ui-grid-column-resizer]').first();

        $(firstResizer).simulate('dblclick');
        $scope.$digest();

        var newWidth = $(grid).find('.col0').first().width();

        expect(newWidth <= maxWidth).toEqual(true);
      });
    });

    describe('and you move its resizer right further than the maxWidth, the column width', function() {
      var initialX;

      beforeEach(function() {
        var firstResizer = $(grid).find('[ui-grid-column-resizer]').first();
        initialX = firstResizer.position().left;

        $(firstResizer).simulate('mousedown', { clientX: initialX });
        $scope.$digest();

        $(document).simulate('mouseup', { clientX: initialX + maxWidth });
        $scope.$digest();
      });

      it('should not go above the maxWidth', function() {
        var newWidth = $(grid).find('.col0').first().width();

        expect(newWidth <= maxWidth).toEqual(true);
      });
    });
  });
});<|endoftext|>


<commit_before>CodeMirror.registerHelper("fold", "fitnesse", function(cm, start) {
  var tablePos = findTable(cm, start);
  if (tablePos)
    return tablePos;
  var blockPos = findBlock(cm, start);
  if (blockPos)
    return blockPos;
  return undefined;
});

function findBlock(cm, start) {
  var maxDepth = 100;
  var firstLine = cm.getLine(start.line);
  if (!cm.getLine(start.line).match(/!\*.*/))
    return undefined;

  var counter = 1;

  var lastLineNo = cm.lastLine();
  var end = start.line, nextLine = cm.getLine(end + 1), nextNextLine = cm.getLine(end + 2);
  while (end < lastLineNo && counter > 0) {
    if (nextLine.match(/!\*.*/))
      counter++;
    if (nextLine.match(/\*+!/))
      counter--;
    ++end;
    nextLine = nextNextLine;
    nextNextLine = cm.getLine(end + 2);
  }

  if (counter > 0)
    return undefined;

  return {
    from: CodeMirror.Pos(start.line, firstLine.length),
    to: CodeMirror.Pos(end, cm.getLine(end).length - 1)
  }
}

function findTable(cm, start) {
  var firstLine = cm.getLine(start.line);
  var previousLineIndex = start.line - 1;
  var tableRowRegexp = /\|.*/;
  if (!cm.getLine(start.line).match(tableRowRegexp) ||
      (cm.getLine(previousLineIndex) && cm.getLine(previousLineIndex).match(tableRowRegexp)))
    return undefined;
  console.log(cm.getLine(previousLineIndex));
  console.log(cm.getLine(previousLineIndex).match(tableRowRegexp));

  var lastLineNo = cm.lastLine();
  var end = start.line, nextLine = cm.getLine(end + 1);
  while (end < lastLineNo) {
    if (!nextLine.match(tableRowRegexp))
      break;
    ++end;
    nextLine = cm.getLine(end + 1);
  }

  return {
    from: CodeMirror.Pos(start.line, firstLine.length),
    to: CodeMirror.Pos(end, cm.getLine(end).length - 1)
  }
}

CodeMirror.defineSimpleMode("fitnesse", {
  // The start state contains the rules that are intially used
  start: [
    //Bold
    {regex: /'''(?:[^\\]|\\.)*?'''/, token: "variable-2"},
    //Italics
    {regex: /''(?:[^\\]|\\.)*?''/, token: "variable"},
    //Strike
    {regex: /--(?:[^\\]|\\.)*?--/, token: "variable-3"},
    //Strike
    {regex: /!style_/, token: "keyword"},
    //Cross Reference
    {regex: /!see [\.\w]+/, token: "link"},
    // The regex matches the token, the token property contains the type
    {regex: /"(?:[^\\]|\\.)*?"/, token: "string"},
    // You can match multiple tokens at once. Note that the captured
    // groups must span the whole string in this case
    {regex: /(function)(\s+)([a-z$][\w$]*)/,
     token: ["keyword", null, "variable-2"]},
    // Rules are matched in the order in which they appear, so there is
    // no ambiguity between this one and the one above
    {regex: /0x[a-f\d]+|[-+]?(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/i,
     token: "number"},
    {regex: /#.*/, token: "comment"},
    {regex: /\|.*/, token: "variable-3"},
    {regex: /[-+*\/=<>!]+/, token: "operator"},
    // indent and dedent properties guide autoindentation
    {regex: /[\{\[\(]/, indent: true},
    {regex: /[\}\]\)]/, dedent: true},
    {regex: /[a-z$][\w$]*/, token: "variable"},
    // You can embed other modes with the mode property. This rule
    // causes all code between << and >> to be highlighted with the XML
    // mode.
    {regex: /<</, token: "meta", mode: {spec: "xml", end: />>/}}
  ],
  // The meta property contains global information about the mode. It
  // can contain properties like lineComment, which are supported by
  // all modes, and also directives like dontIndentStates, which are
  // specific to simple modes.
  meta: {
    dontIndentStates: ["comment"],
    lineComment: "#"
  }
});<commit_msg>Install CodeMirror part three<commit_after>CodeMirror.registerHelper("fold", "fitnesse", function(cm, start) {
  var tablePos = findTable(cm, start);
  if (tablePos)
    return tablePos;
  var blockPos = findBlock(cm, start);
  if (blockPos)
    return blockPos;
  return undefined;
});

function findBlock(cm, start) {
  var maxDepth = 100;
  var firstLine = cm.getLine(start.line);
  if (!cm.getLine(start.line).match(/!\*.*/))
    return undefined;

  var counter = 1;

  var lastLineNo = cm.lastLine();
  var end = start.line, nextLine = cm.getLine(end + 1), nextNextLine = cm.getLine(end + 2);
  while (end < lastLineNo && counter > 0) {
    if (nextLine.match(/!\*.*/))
      counter++;
    if (nextLine.match(/\*+!/))
      counter--;
    ++end;
    nextLine = nextNextLine;
    nextNextLine = cm.getLine(end + 2);
  }

  if (counter > 0)
    return undefined;

  return {
    from: CodeMirror.Pos(start.line, firstLine.length),
    to: CodeMirror.Pos(end, cm.getLine(end).length - 1)
  }
}

function findTable(cm, start) {
  var firstLine = cm.getLine(start.line);
  var previousLineIndex = start.line - 1;
  var tableRowRegexp = /\|.*/;
  if (!cm.getLine(start.line).match(tableRowRegexp) ||
      (cm.getLine(previousLineIndex) && cm.getLine(previousLineIndex).match(tableRowRegexp)))
    return undefined;
  console.log(cm.getLine(previousLineIndex));
  console.log(cm.getLine(previousLineIndex).match(tableRowRegexp));

  var lastLineNo = cm.lastLine();
  var end = start.line, nextLine = cm.getLine(end + 1);
  while (end < lastLineNo) {
    if (!nextLine.match(tableRowRegexp))
      break;
    ++end;
    nextLine = cm.getLine(end + 1);
  }

  return {
    from: CodeMirror.Pos(start.line, firstLine.length),
    to: CodeMirror.Pos(end, cm.getLine(end).length - 1)
  }
}

CodeMirror.defineSimpleMode("fitnesse", {
  // The start state contains the rules that are intially used
  start: [
    //Bold
    {regex: /'''(?:[^\\]|\\.)*?'''/, token: "variable-2"},
    //Italics
    {regex: /''(?:[^\\]|\\.)*?''/, token: "variable"},
    //Strike
    {regex: /--(?:[^\\]|\\.)*?--/, token: "variable-3"},
    //Style
    {regex: /!style_/, token: "keyword"},
    //Cross Reference
    {regex: /!see [\.\w]+/, token: "link"},
    //Headers
    {regex: /!\d.*/, token: "header"},
    //Centering
    {regex: /!c/, token: "header"},
    //Note
    {regex: /!note/, token: "quote"},
    //Image
    {regex: /!img/, token: "quote"},
    //External links
    {regex: /https?:\/\/[\dA-Za-z\.\/\?#-]+/, token: "link"},
    //Lists
    {regex: /^\s+[*\d]+ .*/, token: "string"},
    //Variable
    {regex: /!define/, token: "quote"},
    //Classpath
    {regex: /!path/, token: "quote"},
    //Table
    {regex: /\|.*/, token: "variable-3"},
    //Hash-Table
    {regex: /!{.*}/, token: "link"},
    //Collapsable Sections
    {regex: /!\*+.*/, token: "header"},
    {regex: /\*+!/, token: "header"},
    //Table of contents
    {regex: /!contents.*/, token: "keyword"},
    //Include
    {regex: /!include +/, token: "keyword"},
    //Help
    {regex: /!help (-editable)?/, token: "keyword"},
    //Last modified
    {regex: /!lastmodified/, token: "keyword"},
    //Today
    {regex: /!today/, token: "keyword"},
    // The regex matches the token, the token property contains the type
    {regex: /"(?:[^\\]|\\.)*?"/, token: "string"},
    // You can match multiple tokens at once. Note that the captured
    // groups must span the whole string in this case
    {regex: /(function)(\s+)([a-z$][\w$]*)/,
     token: ["keyword", null, "variable-2"]},
    // Rules are matched in the order in which they appear, so there is
    // no ambiguity between this one and the one above
    {regex: /0x[a-f\d]+|[-+]?(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/i,
     token: "number"},
    {regex: /#.*/, token: "comment"},
    {regex: /[-+*\/=<>!]+/, token: "operator"},
  ]
});<|endoftext|>


<commit_before>/*!
 * mustache.js - Logic-less {{mustache}} templates with JavaScript
 * http://github.com/janl/mustache.js
 */

/*global define: false*/

(function (root, factory) {
  if (typeof exports === "object" && exports) {
    module.exports = factory; // CommonJS
  } else if (typeof define === "function" && define.amd) {
    define(factory); // AMD
  } else {
    root.Mustache = factory; // <script>
  }
}(this, (function () {

  var exports = {};

  exports.name = "mustache.js";
  exports.version = "0.7.2";
  exports.tags = ["{{", "}}"];

  exports.Scanner = Scanner;
  exports.Context = Context;
  exports.Writer = Writer;

  var whiteRe = /\s*/;
  var spaceRe = /\s+/;
  var nonSpaceRe = /\S/;
  var eqRe = /\s*=/;
  var curlyRe = /\s*\}/;
  var tagRe = /#|\^|\/|>|\{|&|=|!/;

  // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
  // See https://github.com/janl/mustache.js/issues/189
  function testRe(re, string) {
    return RegExp.prototype.test.call(re, string);
  }

  function isWhitespace(string) {
    return !testRe(nonSpaceRe, string);
  }

  var isArray = Array.isArray || function (obj) {
    return Object.prototype.toString.call(obj) === "[object Array]";
  };

  function escapeRe(string) {
    return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
  }

  var entityMap = {
    "&": "&",
    "<": "<",
    ">": ">",
    '"': '"',
    "'": ''',
    "/": '/'
  };

  function escapeHtml(string) {
    return String(string).replace(/[&<>"'\/]/g, function (s) {
      return entityMap[s];
    });
  }

  // Export the escaping function so that the user may override it.
  // See https://github.com/janl/mustache.js/issues/244
  exports.escape = escapeHtml;

  function Scanner(string) {
    this.string = string;
    this.tail = string;
    this.pos = 0;
  }

  /**
   * Returns `true` if the tail is empty (end of string).
   */
  Scanner.prototype.eos = function () {
    return this.tail === "";
  };

  /**
   * Tries to match the given regular expression at the current position.
   * Returns the matched text if it can match, the empty string otherwise.
   */
  Scanner.prototype.scan = function (re) {
    var match = this.tail.match(re);

    if (match && match.index === 0) {
      this.tail = this.tail.substring(match[0].length);
      this.pos += match[0].length;
      return match[0];
    }

    return "";
  };

  /**
   * Skips all text until the given regular expression can be matched. Returns
   * the skipped string, which is the entire tail if no match can be made.
   */
  Scanner.prototype.scanUntil = function (re) {
    var match, pos = this.tail.search(re);

    switch (pos) {
    case -1:
      match = this.tail;
      this.pos += this.tail.length;
      this.tail = "";
      break;
    case 0:
      match = "";
      break;
    default:
      match = this.tail.substring(0, pos);
      this.tail = this.tail.substring(pos);
      this.pos += pos;
    }

    return match;
  };

  function Context(view, parent) {
    this.view = view;
    this.parent = parent;
    this._cache = {};
  }

  Context.make = function (view) {
    return (view instanceof Context) ? view : new Context(view);
  };

  Context.prototype.push = function (view) {
    return new Context(view, this);
  };

  Context.prototype.lookup = function (name) {
    var value = this._cache[name];

    if (!value) {
      if (name === ".") {
        value = this.view;
      } else {
        var context = this;

        while (context) {
          if (name.indexOf(".") > 0) {
            var names = name.split("."), i = 0;

            value = context.view;

            while (value && i < names.length) {
              value = value[names[i++]];
            }
          } else {
            value = context.view[name];
          }

          if (value != null) break;

          context = context.parent;
        }
      }

      this._cache[name] = value;
    }

    if (typeof value === 'function') value = value.call(this.view);

    return value;
  };

  function Writer() {
    this.clearCache();
  }

  Writer.prototype.clearCache = function () {
    this._cache = {};
    this._partialCache = {};
  };

  Writer.prototype.compile = function (template, tags) {
    var fn = this._cache[template];

    if (!fn) {
      var tokens = exports.parse(template, tags);
      fn = this._cache[template] = this.compileTokens(tokens, template);
    }

    return fn;
  };

  Writer.prototype.compilePartial = function (name, template, tags) {
    var fn = this.compile(template, tags);
    this._partialCache[name] = fn;
    return fn;
  };

  Writer.prototype.getPartial = function (name) {
    if (!(name in this._partialCache) && this._loadPartial) {
      this.compilePartial(name, this._loadPartial(name));
    }

    return this._partialCache[name];
  };

  Writer.prototype.compileTokens = function (tokens, template) {
    var self = this;
    return function (view, partials) {
      if (partials) {
        if (typeof partials === 'function') {
          self._loadPartial = partials;
        } else {
          for (var name in partials) {
            self.compilePartial(name, partials[name]);
          }
        }
      }

      return renderTokens(tokens, self, Context.make(view), template);
    };
  };

  Writer.prototype.render = function (template, view, partials) {
    return this.compile(template)(view, partials);
  };

  /**
   * Low-level function that renders the given `tokens` using the given `writer`
   * and `context`. The `template` string is only needed for templates that use
   * higher-order sections to extract the portion of the original template that
   * was contained in that section.
   */
  function renderTokens(tokens, writer, context, template) {
    var buffer = '';

    var token, tokenValue, value;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      tokenValue = token[1];

      switch (token[0]) {
      case '#':
        value = context.lookup(tokenValue);

        if (typeof value === 'object') {
          if (isArray(value)) {
            for (var j = 0, jlen = value.length; j < jlen; ++j) {
              buffer += renderTokens(token[4], writer, context.push(value[j]), template);
            }
          } else if (value) {
            buffer += renderTokens(token[4], writer, context.push(value), template);
          }
        } else if (typeof value === 'function') {
          var text = template == null ? null : template.slice(token[3], token[5]);
          var result = value.call(context.view, text, function (template) {
            return writer.render(template, context);
          });
          if (result != null) buffer += result;
        } else if (value) {
          buffer += renderTokens(token[4], writer, context, template);
        }

        break;
      case '^':
        value = context.lookup(tokenValue);

        // Use JavaScript's definition of falsy. Include empty arrays.
        // See https://github.com/janl/mustache.js/issues/186
        if (!value || (isArray(value) && value.length === 0)) {
          buffer += renderTokens(token[4], writer, context, template);
        }

        break;
      case '>':
        value = writer.getPartial(tokenValue);
        if (typeof value === 'function') buffer += value(context);
        break;
      case '&':
        value = context.lookup(tokenValue);
        if (value != null) buffer += value;
        break;
      case 'name':
        value = context.lookup(tokenValue);
        if (value != null) buffer += exports.escape(value);
        break;
      case 'text':
        buffer += tokenValue;
        break;
      }
    }

    return buffer;
  }

  /**
   * Forms the given array of `tokens` into a nested tree structure where
   * tokens that represent a section have two additional items: 1) an array of
   * all tokens that appear in that section and 2) the index in the original
   * template that represents the end of that section.
   */
  function nestTokens(tokens) {
    var tree = [];
    var collector = tree;
    var sections = [];

    var token;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      switch (token[0]) {
      case '#':
      case '^':
        sections.push(token);
        collector.push(token);
        collector = token[4] = [];
        break;
      case '/':
        var section = sections.pop();
        section[5] = token[2];
        collector = sections.length > 0 ? sections[sections.length - 1][4] : tree;
        break;
      default:
        collector.push(token);
      }
    }

    return tree;
  }

  /**
   * Combines the values of consecutive text tokens in the given `tokens` array
   * to a single token.
   */
  function squashTokens(tokens) {
    var squashedTokens = [];

    var token, lastToken;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      if (token) {
        if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
          lastToken[1] += token[1];
          lastToken[3] = token[3];
        } else {
          lastToken = token;
          squashedTokens.push(token);
        }
      }
    }

    return squashedTokens;
  }

  function escapeTags(tags) {
    return [
      new RegExp(escapeRe(tags[0]) + "\\s*"),
      new RegExp("\\s*" + escapeRe(tags[1]))
    ];
  }

  /**
   * Breaks up the given `template` string into a tree of token objects. If
   * `tags` is given here it must be an array with two string values: the
   * opening and closing tags used in the template (e.g. ["<%", "%>"]). Of
   * course, the default is to use mustaches (i.e. Mustache.tags).
   */
  exports.parse = function (template, tags) {
    template = template || '';
    tags = tags || exports.tags;

    if (typeof tags === 'string') tags = tags.split(spaceRe);
    if (tags.length !== 2) {
      throw new Error('Invalid tags: ' + tags.join(', '));
    }

    var tagRes = escapeTags(tags);
    var scanner = new Scanner(template);

    var sections = [];     // Stack to hold section tokens
    var tokens = [];       // Buffer to hold the tokens
    var spaces = [];       // Indices of whitespace tokens on the current line
    var hasTag = false;    // Is there a {{tag}} on the current line?
    var nonSpace = false;  // Is there a non-space char on the current line?

    // Strips all whitespace tokens array for the current line
    // if there was a {{#tag}} on it and otherwise only space.
    function stripSpace() {
      if (hasTag && !nonSpace) {
        while (spaces.length) {
          delete tokens[spaces.pop()];
        }
      } else {
        spaces = [];
      }

      hasTag = false;
      nonSpace = false;
    }

    var start, type, value, chr, token;
    while (!scanner.eos()) {
      start = scanner.pos;
      value = scanner.scanUntil(tagRes[0]);

      if (value) {
        for (var i = 0, len = value.length; i < len; ++i) {
          chr = value.charAt(i);

          if (isWhitespace(chr)) {
            spaces.push(tokens.length);
          } else {
            nonSpace = true;
          }

          tokens.push(['text', chr, start, start + 1]);
          start += 1;

          // Check for whitespace on the current line.
          if (chr == '\n') stripSpace();
        }
      }

      start = scanner.pos;

      // Match the opening tag.
      if (!scanner.scan(tagRes[0])) break;
      hasTag = true;

      type = scanner.scan(tagRe) || 'name';

      // Skip any whitespace between tag and value.
      scanner.scan(whiteRe);

      // Extract the tag value.
      if (type === "=") {
        value = scanner.scanUntil(eqRe);
        scanner.scan(eqRe);
        scanner.scanUntil(tagRes[1]);
      } else if (type === "{") {
        var closeRe = new RegExp("\\s*" + escapeRe("}" + tags[1]));
        value = scanner.scanUntil(closeRe);
        scanner.scan(curlyRe);
        scanner.scanUntil(tagRes[1]);
        type = "&";
      } else {
        value = scanner.scanUntil(tagRes[1]);
      }

      // Match the closing tag.
      if (!scanner.scan(tagRes[1])) {
        throw new Error('Unclosed tag at ' + scanner.pos);
      }

      // Check section nesting.
      if (type === '/') {
        if (sections.length === 0) {
          throw new Error('Unopened section "' + value + '" at ' + start);
        }

        var section = sections.pop();

        if (section[1] !== value) {
          throw new Error('Unclosed section "' + section[1] + '" at ' + start);
        }
      }

      token = [type, value, start, scanner.pos];
      tokens.push(token);

      if (type === '#' || type === '^') {
        sections.push(token);
      } else if (type === "name" || type === "{" || type === "&") {
        nonSpace = true;
      } else if (type === "=") {
        // Set the tags for the next time around.
        tags = value.split(spaceRe);

        if (tags.length !== 2) {
          throw new Error('Invalid tags at ' + start + ': ' + tags.join(', '));
        }

        tagRes = escapeTags(tags);
      }
    }

    // Make sure there are no open sections when we're done.
    var section = sections.pop();
    if (section) {
      throw new Error('Unclosed section "' + section[1] + '" at ' + scanner.pos);
    }

    tokens = squashTokens(tokens);

    return nestTokens(tokens);
  };

  // All Mustache.* functions use this writer.
  var _writer = new Writer();

  /**
   * Clears all cached templates and partials in the default writer.
   */
  exports.clearCache = function () {
    return _writer.clearCache();
  };

  /**
   * Compiles the given `template` to a reusable function using the default
   * writer.
   */
  exports.compile = function (template, tags) {
    return _writer.compile(template, tags);
  };

  /**
   * Compiles the partial with the given `name` and `template` to a reusable
   * function using the default writer.
   */
  exports.compilePartial = function (name, template, tags) {
    return _writer.compilePartial(name, template, tags);
  };

  /**
   * Compiles the given array of tokens (the output of a parse) to a reusable
   * function using the default writer.
   */
  exports.compileTokens = function (tokens, template) {
    return _writer.compileTokens(tokens, template);
  };

  /**
   * Renders the `template` with the given `view` and `partials` using the
   * default writer.
   */
  exports.render = function (template, view, partials) {
    return _writer.render(template, view, partials);
  };

  // This is here for backwards compatibility with 0.4.x.
  exports.to_html = function (template, view, partials, send) {
    var result = exports.render(template, view, partials);

    if (typeof send === "function") {
      send(result);
    } else {
      return result;
    }
  };

  return exports;

}())));
<commit_msg>Style tweaks, added comments<commit_after>/*!
 * mustache.js - Logic-less {{mustache}} templates with JavaScript
 * http://github.com/janl/mustache.js
 */

/*global define: false*/

(function (root, factory) {
  if (typeof exports === "object" && exports) {
    module.exports = factory; // CommonJS
  } else if (typeof define === "function" && define.amd) {
    define(factory); // AMD
  } else {
    root.Mustache = factory; // <script>
  }
}(this, (function () {

  var exports = {};

  exports.name = "mustache.js";
  exports.version = "0.7.2";
  exports.tags = ["{{", "}}"];

  exports.Scanner = Scanner;
  exports.Context = Context;
  exports.Writer = Writer;

  var whiteRe = /\s*/;
  var spaceRe = /\s+/;
  var nonSpaceRe = /\S/;
  var eqRe = /\s*=/;
  var curlyRe = /\s*\}/;
  var tagRe = /#|\^|\/|>|\{|&|=|!/;

  // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
  // See https://github.com/janl/mustache.js/issues/189
  function testRe(re, string) {
    return RegExp.prototype.test.call(re, string);
  }

  function isWhitespace(string) {
    return !testRe(nonSpaceRe, string);
  }

  var isArray = Array.isArray || function (obj) {
    return Object.prototype.toString.call(obj) === "[object Array]";
  };

  function escapeRe(string) {
    return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
  }

  var entityMap = {
    "&": "&",
    "<": "<",
    ">": ">",
    '"': '"',
    "'": ''',
    "/": '/'
  };

  function escapeHtml(string) {
    return String(string).replace(/[&<>"'\/]/g, function (s) {
      return entityMap[s];
    });
  }

  // Export the escaping function so that the user may override it.
  // See https://github.com/janl/mustache.js/issues/244
  exports.escape = escapeHtml;

  function Scanner(string) {
    this.string = string;
    this.tail = string;
    this.pos = 0;
  }

  /**
   * Returns `true` if the tail is empty (end of string).
   */
  Scanner.prototype.eos = function () {
    return this.tail === "";
  };

  /**
   * Tries to match the given regular expression at the current position.
   * Returns the matched text if it can match, the empty string otherwise.
   */
  Scanner.prototype.scan = function (re) {
    var match = this.tail.match(re);

    if (match && match.index === 0) {
      this.tail = this.tail.substring(match[0].length);
      this.pos += match[0].length;
      return match[0];
    }

    return "";
  };

  /**
   * Skips all text until the given regular expression can be matched. Returns
   * the skipped string, which is the entire tail if no match can be made.
   */
  Scanner.prototype.scanUntil = function (re) {
    var match, pos = this.tail.search(re);

    switch (pos) {
    case -1:
      match = this.tail;
      this.pos += this.tail.length;
      this.tail = "";
      break;
    case 0:
      match = "";
      break;
    default:
      match = this.tail.substring(0, pos);
      this.tail = this.tail.substring(pos);
      this.pos += pos;
    }

    return match;
  };

  function Context(view, parent) {
    this.view = view;
    this.parent = parent;
    this._cache = {};
  }

  Context.make = function (view) {
    return (view instanceof Context) ? view : new Context(view);
  };

  Context.prototype.push = function (view) {
    return new Context(view, this);
  };

  Context.prototype.lookup = function (name) {
    var value = this._cache[name];

    if (!value) {
      if (name === ".") {
        value = this.view;
      } else {
        var context = this;

        while (context) {
          if (name.indexOf(".") > 0) {
            var names = name.split("."), i = 0;

            value = context.view;

            while (value && i < names.length) {
              value = value[names[i++]];
            }
          } else {
            value = context.view[name];
          }

          if (value != null) break;

          context = context.parent;
        }
      }

      this._cache[name] = value;
    }

    if (typeof value === 'function') value = value.call(this.view);

    return value;
  };

  function Writer() {
    this.clearCache();
  }

  Writer.prototype.clearCache = function () {
    this._cache = {};
    this._partialCache = {};
  };

  Writer.prototype.compile = function (template, tags) {
    var fn = this._cache[template];

    if (!fn) {
      var tokens = exports.parse(template, tags);
      fn = this._cache[template] = this.compileTokens(tokens, template);
    }

    return fn;
  };

  Writer.prototype.compilePartial = function (name, template, tags) {
    var fn = this.compile(template, tags);
    this._partialCache[name] = fn;
    return fn;
  };

  Writer.prototype.getPartial = function (name) {
    if (!(name in this._partialCache) && this._loadPartial) {
      this.compilePartial(name, this._loadPartial(name));
    }

    return this._partialCache[name];
  };

  Writer.prototype.compileTokens = function (tokens, template) {
    var self = this;
    return function (view, partials) {
      if (partials) {
        if (typeof partials === 'function') {
          self._loadPartial = partials;
        } else {
          for (var name in partials) {
            self.compilePartial(name, partials[name]);
          }
        }
      }

      return renderTokens(tokens, self, Context.make(view), template);
    };
  };

  Writer.prototype.render = function (template, view, partials) {
    return this.compile(template)(view, partials);
  };

  /**
   * Low-level function that renders the given `tokens` using the given `writer`
   * and `context`. The `template` string is only needed for templates that use
   * higher-order sections to extract the portion of the original template that
   * was contained in that section.
   */
  function renderTokens(tokens, writer, context, template) {
    var buffer = '';

    var token, tokenValue, value;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      tokenValue = token[1];

      switch (token[0]) {
      case '#':
        value = context.lookup(tokenValue);

        if (typeof value === 'object') {
          if (isArray(value)) {
            for (var j = 0, jlen = value.length; j < jlen; ++j) {
              buffer += renderTokens(token[4], writer, context.push(value[j]), template);
            }
          } else if (value) {
            buffer += renderTokens(token[4], writer, context.push(value), template);
          }
        } else if (typeof value === 'function') {
          var text = template == null ? null : template.slice(token[3], token[5]);
          var result = value.call(context.view, text, function (template) {
            return writer.render(template, context);
          });
          if (result != null) buffer += result;
        } else if (value) {
          buffer += renderTokens(token[4], writer, context, template);
        }

        break;
      case '^':
        value = context.lookup(tokenValue);

        // Use JavaScript's definition of falsy. Include empty arrays.
        // See https://github.com/janl/mustache.js/issues/186
        if (!value || (isArray(value) && value.length === 0)) {
          buffer += renderTokens(token[4], writer, context, template);
        }

        break;
      case '>':
        value = writer.getPartial(tokenValue);
        if (typeof value === 'function') buffer += value(context);
        break;
      case '&':
        value = context.lookup(tokenValue);
        if (value != null) buffer += value;
        break;
      case 'name':
        value = context.lookup(tokenValue);
        if (value != null) buffer += exports.escape(value);
        break;
      case 'text':
        buffer += tokenValue;
        break;
      }
    }

    return buffer;
  }

  /**
   * Forms the given array of `tokens` into a nested tree structure where
   * tokens that represent a section have two additional items: 1) an array of
   * all tokens that appear in that section and 2) the index in the original
   * template that represents the end of that section.
   */
  function nestTokens(tokens) {
    var tree = [];
    var collector = tree;
    var sections = [];

    var token;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      switch (token[0]) {
      case '#':
      case '^':
        sections.push(token);
        collector.push(token);
        collector = token[4] = [];
        break;
      case '/':
        var section = sections.pop();
        section[5] = token[2];
        collector = sections.length > 0 ? sections[sections.length - 1][4] : tree;
        break;
      default:
        collector.push(token);
      }
    }

    return tree;
  }

  /**
   * Combines the values of consecutive text tokens in the given `tokens` array
   * to a single token.
   */
  function squashTokens(tokens) {
    var squashedTokens = [];

    var token, lastToken;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      if (token) {
        if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
          lastToken[1] += token[1];
          lastToken[3] = token[3];
        } else {
          lastToken = token;
          squashedTokens.push(token);
        }
      }
    }

    return squashedTokens;
  }

  function escapeTags(tags) {
    return [
      new RegExp(escapeRe(tags[0]) + "\\s*"),
      new RegExp("\\s*" + escapeRe(tags[1]))
    ];
  }

  /**
   * Breaks up the given `template` string into a tree of token objects. If
   * `tags` is given here it must be an array with two string values: the
   * opening and closing tags used in the template (e.g. ["<%", "%>"]). Of
   * course, the default is to use mustaches (i.e. Mustache.tags).
   */
  exports.parse = function (template, tags) {
    template = template || '';
    tags = tags || exports.tags;

    if (typeof tags === 'string') tags = tags.split(spaceRe);
    if (tags.length !== 2) throw new Error('Invalid tags: ' + tags.join(', '));

    var tagRes = escapeTags(tags);
    var scanner = new Scanner(template);

    var sections = [];     // Stack to hold section tokens
    var tokens = [];       // Buffer to hold the tokens
    var spaces = [];       // Indices of whitespace tokens on the current line
    var hasTag = false;    // Is there a {{tag}} on the current line?
    var nonSpace = false;  // Is there a non-space char on the current line?

    // Strips all whitespace tokens array for the current line
    // if there was a {{#tag}} on it and otherwise only space.
    function stripSpace() {
      if (hasTag && !nonSpace) {
        while (spaces.length) {
          delete tokens[spaces.pop()];
        }
      } else {
        spaces = [];
      }

      hasTag = false;
      nonSpace = false;
    }

    var start, type, value, chr, token;
    while (!scanner.eos()) {
      start = scanner.pos;

      // Match any text between tags.
      value = scanner.scanUntil(tagRes[0]);
      if (value) {
        for (var i = 0, len = value.length; i < len; ++i) {
          chr = value.charAt(i);

          if (isWhitespace(chr)) {
            spaces.push(tokens.length);
          } else {
            nonSpace = true;
          }

          tokens.push(['text', chr, start, start + 1]);
          start += 1;

          // Check for whitespace on the current line.
          if (chr == '\n') stripSpace();
        }
      }

      // Match the opening tag.
      if (!scanner.scan(tagRes[0])) break;
      hasTag = true;

      // Get the tag type.
      type = scanner.scan(tagRe) || 'name';
      scanner.scan(whiteRe);

      // Get the tag value.
      if (type === '=') {
        value = scanner.scanUntil(eqRe);
        scanner.scan(eqRe);
        scanner.scanUntil(tagRes[1]);
      } else if (type === '{') {
        value = scanner.scanUntil(new RegExp('\\s*' + escapeRe('}' + tags[1])));
        scanner.scan(curlyRe);
        scanner.scanUntil(tagRes[1]);
        type = '&';
      } else {
        value = scanner.scanUntil(tagRes[1]);
      }

      // Match the closing tag.
      if (!scanner.scan(tagRes[1])) throw new Error('Unclosed tag at ' + scanner.pos);

      token = [type, value, start, scanner.pos];
      tokens.push(token);

      if (type === '#' || type === '^') {
        sections.push(token);
      } else if (type === '/') {
        // Check section nesting.
        if (sections.length === 0) throw new Error('Unopened section "' + value + '" at ' + start);
        var openSection = sections.pop();
        if (openSection[1] !== value) throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
      } else if (type === 'name' || type === '{' || type === '&') {
        nonSpace = true;
      } else if (type === '=') {
        // Set the tags for the next time around.
        tags = value.split(spaceRe);
        if (tags.length !== 2) throw new Error('Invalid tags at ' + start + ': ' + tags.join(', '));
        tagRes = escapeTags(tags);
      }
    }

    // Make sure there are no open sections when we're done.
    var openSection = sections.pop();
    if (openSection) throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);

    tokens = squashTokens(tokens);

    return nestTokens(tokens);
  };

  // All Mustache.* functions use this writer.
  var _writer = new Writer();

  /**
   * Clears all cached templates and partials in the default writer.
   */
  exports.clearCache = function () {
    return _writer.clearCache();
  };

  /**
   * Compiles the given `template` to a reusable function using the default
   * writer.
   */
  exports.compile = function (template, tags) {
    return _writer.compile(template, tags);
  };

  /**
   * Compiles the partial with the given `name` and `template` to a reusable
   * function using the default writer.
   */
  exports.compilePartial = function (name, template, tags) {
    return _writer.compilePartial(name, template, tags);
  };

  /**
   * Compiles the given array of tokens (the output of a parse) to a reusable
   * function using the default writer.
   */
  exports.compileTokens = function (tokens, template) {
    return _writer.compileTokens(tokens, template);
  };

  /**
   * Renders the `template` with the given `view` and `partials` using the
   * default writer.
   */
  exports.render = function (template, view, partials) {
    return _writer.render(template, view, partials);
  };

  // This is here for backwards compatibility with 0.4.x.
  exports.to_html = function (template, view, partials, send) {
    var result = exports.render(template, view, partials);

    if (typeof send === "function") {
      send(result);
    } else {
      return result;
    }
  };

  return exports;

}())));
<|endoftext|>


<commit_before>var cluster = require("cluster"),
	len = require("os").cpus().length,
	timeStamp = new Date(),
	queue = [],
	timeline = 6000,
	restartLimit = 10;

function tooFreequent() {
	var now = new Date(),
		tenth = 0,
		num = queue.length - 9;

	queue.push(now);
	tenth = queue[num];

	if (num <= 0) {
		return false;
	} else {
		if (tenth - now > 6000) {
			return false;
		}
		return true;
	}
}

cluster.setupMaster({
	exec: "app.js"
});

for (var i = 0; i < len; i++) {
	cluster.fork();
};

cluster.on("exit", function(worker, code, signal) {
	console.log("worker " + worker.process.pid + "dead");
	if (tooFreequent()) {
		setTimeout(function() {
			if (cluster.workers.length < len) {
				cluster.fork();
			}
		}, 6000)
	} else {
		cluster.fork();
	}
});<commit_msg>bug fix<commit_after>var cluster = require("cluster"),
	len = require("os").cpus().length,
	timeStamp = new Date(),
	queue = [],
	timeline = 6000,
	restartLimit = 10;

function tooFreequent() {
	var now = new Date(),
		tenth = 0,
		num = queue.length - 9;

	queue.push(now);
	tenth = queue[num];

	if (num <= 0) {
		return false;
	} else {
		if (tenth - now > 6000) {
			return false;
		}
		return true;
	}
}

cluster.on('fork', function(worker) {
	console.log("worker process id is "+worker.process.pid);

});

cluster.setupMaster({
	exec: "app.js"
});

for (var i = 0; i < len; i++) {
	cluster.fork();
};

cluster.on("exit", function(worker, code, signal) {
	console.log("worker " + worker.process.pid + "dead");
	if (tooFreequent()) {
		setTimeout(function() {
			if (cluster.workers.length < len) {
			var worker=cluster.fork();
			console.log("new worker process id is "+worker.process.pid);
			}
		}, 6000)
	} else {
		cluster.fork();
	}
});<|endoftext|>


<commit_before> /*!
 * jQuery PLugin Base v1.0
 * https://github.com/marcosfreitas/jquery-plugin-base/
 *
 * Copyright 2015, 2016 Marcos Freitas
 * Released under the MIT license
 */

;(function($) {
	'use strict'; // ecma script 5

	$.MyPlugin = function (nome_funcao, opcoes) {

		// objetos padrões
		var padrao = {
			'nome' : 'marcos',
			'sobrenome' : 'freitas',
			'idade' : 25
		},

		// mesclando opções aos valores padrão
		config = $.extend({}, padrao, opcoes),

		metodos = {

			init : function (param, param2) {
				console.info(param);
				console.info(param2);
			},

			b : function (param) {
				console.warn(param);
			},

			c : function (param) {
				console.error(param);
			}

		},

		eventos = {
			d : function (param) {
				console.log('--' + param)
			}
		};

		if (typeof opcoes !== 'undefined') {

	    	try{
				// Array.prototype.slice não funciona até o IE 8 e no chrome 14
		        // http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work
		        // se não for um array ele vai separar a string em letras
		        // para passar corretamente parâmetros para os métodos ou funçõesé preciso que opções seja um array,
		        // ou um array-like (um objeto com índices numéricos e uma propriedade 'length')
		        // repassa todos os elementos do array, mas depende de quantos a função está esperando receber
		        var array_argumentos = Array.prototype.slice.call(opcoes, 0);

		    } catch(err){

		        // lento mas funciona no IE
		        var array_argumentos = [],
		            length = opcoes.length;

		        for(var o=0; o < length; o++){
		            array_argumentos.push(opcoes[o]);
		        }
		    }
		};

		// as funções dos objetos de métodos e eventos podem ser retornadas com metodo['nome_metodo'] por exemplo
		if ( metodos[nome_funcao] ) {
			// O método apply() chama uma função com um dado valor this e arguments providos como array (ou um objeto array-like ).
			return metodos[nome_funcao].apply( this, array_argumentos);
	    }
	    else if ( eventos[nome_funcao] ) {
	    	return eventos[nome_funcao].apply( this, array_argumentos);
	    }
	    // não achou nenhum método e evento com o nome daquela função
	    // chama o método init passando opcoes se for um objeto
	    else if ( typeof opcoes === 'object' ) {
	    	return metodos.init.apply( this, opcoes );
	    }
	    // chama o método init passando o objeto jquery seletor
	    else if ( typeof nome_funcao === 'undefined' && typeof opcoes === 'undefined' ) {
	    	return metodos.init();
	    	// somente se a função do plugin for do do tipo $.fn
	    	// return metodos.init(this);
	    }
	    else {
	    	$.error( 'O Metodo ou Evento "' +  opcoes + '" nao existe em guia.min.js' );
	    }

	};

})(jQuery);
<commit_msg>updated the section of call for methods or events<commit_after> /*!
 * jQuery PLugin Base v1.0
 * https://github.com/marcosfreitas/jquery-plugin-base/
 *
 * Copyright 2015, 2016 Marcos Freitas
 * Released under the MIT license
 */

;(function($) {
	'use strict'; // ecma script 5

	$.MyPlugin = function (nome_funcao, opcoes) {

		// objetos padrões
		var padrao = {
			'nome' : 'marcos',
			'sobrenome' : 'freitas',
			'idade' : 25
		},

		// mesclando opções aos valores padrão
		config = $.extend({}, padrao, opcoes),

		metodos = {

			init : function (param, param2) {
				console.info(param);
				console.info(param2);
			},

			b : function (param) {
				console.warn(param);
			},

			c : function (param) {
				console.error(param);
			}

		},

		eventos = {
			d : function (param) {
				console.log('--' + param)
			}
		};

	   // call the methods or events
	   var array_argumentos = Array();

	    if (typeof opcoes !== 'undefined') {
	    	try {
			// Array.prototype.slice não funciona até o IE 8 e no chrome 14
		        // http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work
		        // se não for um array ele vai separar a string em letras
		        // para passar corretamente parâmetros para os métodos ou funçõesé preciso que opções seja um array,
		        // ou um array-like (um objeto com índices numéricos e uma propriedade 'length')
		        // repassa todos os elementos do array, mas depende de quantos a função está esperando receber
		        array_argumentos = Array.prototype.slice.call(opcoes, 0);
		} catch(err){

		        // lento mas funciona no IE
		            array_argumentos = [];
		        var length = opcoes.length;

		        for(var o=0; o < length; o++){
		            array_argumentos.push(opcoes[o]);
		        }
		    }
	    }

	    // as funções dos objetos de métodos e eventos podem ser retornadas com metodo['nome_metodo'] por exemplo
	    if ( metodos[nome_funcao] ) {
		// O método apply() chama uma função com um dado valor this e arguments providos como array (ou um objeto array-like ).
		return metodos[nome_funcao].apply( this, array_argumentos);
	    }
	    else if ( eventos[nome_funcao] ) {
	    	return eventos[nome_funcao].apply( this, array_argumentos);
	    }
	    // não achou nenhum método e evento com o nome daquela função
	    // chama o método init passando opcoes se for um objeto
	    else if ( typeof opcoes === 'object' ) {
	    	return metodos.init.apply( this, opcoes );
	    }
	    // chama o método init passando o objeto jquery seletor ou não
	    else if ( typeof nome_funcao === 'undefined' && typeof opcoes === 'undefined' ) {
	    	return metodos.init();
	    	// somente se a função do plugin for do do tipo $.fn
	    	// return metodos.init(this);
	    }
	    else {
	    	$.error( 'O Metodo ou Evento "' +  nome_funcao + '" nao existe em log.min.js' );
	    }

	};

})(jQuery);
<|endoftext|>