<commit_before>/* globals ajax updateFrameCount dom listenCanvas canvas getState setState setMoatUI dialogPolyfill QRCode timeago*/

(function(global) {
  "use strict";

  // CONFIGURATION
  const USE_MOAT = true;
  const MOAT_URL = "https://sd-moat.glitch.me/";

  var defaultCanvas = `<svg id="canvas" width="2560px" height="1116px" data-tool="pen" data-stroke-width="2" data-do-onionskin="true" data-fps="10" data-palette="0" data-color="#000000" data-bgcolor="#FFFFFF" data-color1="#FF0000" data-color2="#FFFF00" data-color3="#00FF00" data-color4="#00FFFF" data-color5="#0000FF" data-color6="#666666" data-color7="#000000" data-color8="#FFFFFF" data-tab_file="false" data-tab_draw="true" data-tab_frames="true" data-tab_animate="false"><g class="frame selected"></g></svg>`;

  // polyfill for dialog
  const dialog = document.querySelector('dialog');
  dialogPolyfill.registerDialog(dialog);

  function saveLocal() {
    localStorage._currentWork = saveFormat();
  }

  function updateSavedState() {
    let state = getState();
    for (let key in state) {
      canvas.dataset[key] = state[key];
    }
  }

  function restoreSavedState() {
    let state = {};
    for (let key in canvas.dataset) {
      state[key] = canvas.dataset[key];
    }
    setState(state);
  }

  function saveFormat() {
    if (canvas) {
      updateSavedState();
      return canvas.outerHTML;
    } else {
      return "";
    }
  }

  window.canvas = null;

  function restoreFormat(savetext) {
    window.canvas = document.querySelector("#canvas");
    if (!canvas) {
      canvas = dom.svg("svg");
      document.body.prepend(canvas);
    }
    if (!savetext) {
      savetext = defaultCanvas;
    }
    canvas.outerHTML = savetext;
    canvas = document.querySelector("#canvas");
    updateFrameCount();
    canvas.setAttribute("width", document.body.clientWidth + "px");
    canvas.setAttribute("height", document.body.clientHeight + "px");
    listenCanvas();
    restoreSavedState();
  }

  function restore() {
    var path = location.href.split("?");
    var query = location.search;
    if (query) {
      var queryparts = query.slice(1).split("=");
      if (queryparts[0] === "gist") {
        loadScriptsFromGistId(queryparts[1]);
        return;
      }
    }
    restoreLocal();
  }

  function restoreLocal() {
    restoreFormat(localStorage._currentWork || defaultCanvas);
  }

  function clear() {
    restoreFormat(defaultCanvas);
  }

  function saveFile(evt) {
    if (evt) {
      evt.preventDefault();
    }
    var title = prompt("Save file as: ");
    if (!title) {
      return;
    }
    saveAs(saveFormat(), `${title}.svg`);
  }

  const filetypes = {
    svg: "image/svg+xml",
    png: "image/png",
    gif: "image/gif"
  };

  function saveToCallback(data, filename, cb) {
    // Callback is shaped cb(blob, filename);
    console.log('saveToCallback(%s)', filename);
    let ext = filename.split(".").pop();
    let filetype = filetypes[ext];
    if (data.toBlob) {
      // ex: canvas.toBlob()
      data.toBlob(blob => cb(blob, filename), filetype);
    } else {
      cb(new Blob([data], { type: filetype }), filename);
    }
  }

  function sendToMoat(progid) {
    console.log('sendToMoat(%s)', progid);
    saveToCallback(saveFormat(), "shimmy.svg", (blob, filename) =>
      sendToMoatCB(blob, filename, progid)
    );
  }

  function sendToMoatCB(blob, filename, progid) {
    console.log('sendToMoatCB(%s)', filename);
    let formData = new FormData();
    formData.append("program", progid);
    formData.append("file", blob, filename);
    let request = new XMLHttpRequest();
    request.open("POST", MOAT_URL + 'file/create');
    request.setRequestHeader('X-Requested-With', 'XMLHTTPRequest');
    request.send(formData);
    request.onload = () => showFilePage(request.response);
    request.onerror = () => handleError('send file');
    request.ontimeout = () => handleTimeout('send file');
  }

  function handleError(step) {
    alert("Error uploading to Moat during " + step + " step, please try again.");
  }

  function handleTimeout(step) {
    alert("Timeout uploading to Moat during " + step + ", please try again.");
  }

  function showQRCode(){
  if (document.querySelector('#qrcode')){
      let qrcode = new QRCode("qrcode", {
          text: "{{urlbase}}/file/{{id}}",
          width: 128,
          height: 128,
          colorDark: "#000000",
          colorLight: "#ffffff",
          correctLevel: QRCode.CorrectLevel.H
        });
  }
}

function updateExpires(){
  let expires = document.querySelector('.expires');
  if (expires.length){
    expires.forEach(e => e.innerText = timeago.format(e.getAttribute('timestamp')));
    setTimeout(updateExpires, 1000);
  }
}

function updateDialog(){
  showQRCode();
  updateExpires();
}

  function showFilePage(res) {
    dialog.innerHTML = res;
    dialog.append(dom.html('button', {onClick: 'this.parentElement.close()'}, 'OK'));
    updateDialog();
    dialog.showModal();
  }

  function saveAs(data, filename) {
    saveToCallback(data, filename, saveBlob);
  }

  function saveBlob(blob, filename) {
    var reader = new FileReader();
    reader.onloadend = function() {
      var a = dom.html("a", {
        href: reader.result,
        download: filename,
        target: "_blank"
      });
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
    };
    reader.readAsDataURL(blob);
  }

  function readFile(file) {
    var fileName = file.name;
    if (fileName.indexOf(".svg", fileName.length - 5) === -1) {
      return alert("Not an SVG file");
    }
    var reader = new FileReader();
    reader.readAsText(file);
    reader.onload = function(evt) {
      restoreFormat(evt.target.result);
    };
  }

  function loadFile() {
    var input = dom.html("input", { type: "file", accept: "image/svg+xml" });
    if (!input) {
      return;
    }
    input.addEventListener("change", function(evt) {
      readFile(input.files[0]);
    });
    input.click();
  }

  // Save script to gist;
  function saveCurrentScriptsToGist(event) {
    event.preventDefault();
    // console.log("Saving to Gist");
    ajax.post(
      "https://api.github.com/gists",
      function(data) {
        //var raw_url = JSON.parse(data).files["script.json"].raw_url;
        gistID = JSON.parse(data)
          .url.split("/")
          .pop();
        var path = location.href.split("?")[0];
        path += "?gist=" + gistID;
        window.location = path;
      },
      JSON.stringify({
        description: "saved drawingboard file",
        public: true,
        files: {
          "animation.svg": {
            content: saveFormat()
          }
        }
      }),
      function(statusCode, x) {
        alert(
          "Can't save to Gist:\n" + statusCode + " (" + x.statusText + ") "
        );
      }
    );
  }

  var gistID = null;

  function loadScriptsFromGistId(id) {
    //we may get an event passed to this function so make sure we have a valid id or ask for one
    gistID = isNaN(parseInt(id))
      ? prompt(
          "What Gist would you like to load? Please enter the ID of the Gist: "
        )
      : id;
    if (!gistID) return;
    ajax.get(
      "https://api.github.com/gists/" + gistID,
      function(gist) {
        restoreFormat(JSON.parse(gist).files["animation.svg"].content);
      },
      function(statusCode, x) {
        alert(
          "Can't load from Gist:\n" + statusCode + " (" + x.statusText + ") "
        );
      }
    );
  }

  function newFile() {
    clear();
    onChange();
  }

  function onChange() {
    if (gistID) {
      gistID = null;
      var path = location.href.split("?")[0];
      history.replaceState(null, null, path);
    }
  }

  function queryMoat(cb) {
    fetch(MOAT_URL + "programs/?integration=shimmy").then(response =>
      response.json().then(cb)
    );
  }
  if (USE_MOAT) {
    window.addEventListener("load", e => queryMoat(setMoatUI), true);
  }

  window.file = {
    onChange: onChange,
    new: newFile,
    clear: clear,
    loadFile,
    saveFile,
    saveBlob,
    saveLocal,
    saveAs,
    sendToMoat
  };

  window.addEventListener("unload", saveLocal, false);
  window.addEventListener("load", restore, false);
})(window);
<commit_msg>🏵🍖 Checkpoint ./js/file.js:739936/3<commit_after>/* globals ajax updateFrameCount dom listenCanvas canvas getState setState setMoatUI dialogPolyfill QRCode timeago*/

(function(global) {
  "use strict";

  // CONFIGURATION
  const USE_MOAT = true;
  const MOAT_URL = "https://sd-moat.glitch.me/";

  var defaultCanvas = `<svg id="canvas" width="2560px" height="1116px" data-tool="pen" data-stroke-width="2" data-do-onionskin="true" data-fps="10" data-palette="0" data-color="#000000" data-bgcolor="#FFFFFF" data-color1="#FF0000" data-color2="#FFFF00" data-color3="#00FF00" data-color4="#00FFFF" data-color5="#0000FF" data-color6="#666666" data-color7="#000000" data-color8="#FFFFFF" data-tab_file="false" data-tab_draw="true" data-tab_frames="true" data-tab_animate="false"><g class="frame selected"></g></svg>`;

  // polyfill for dialog
  const dialog = document.querySelector('dialog');
  dialogPolyfill.registerDialog(dialog);

  function saveLocal() {
    localStorage._currentWork = saveFormat();
  }

  function updateSavedState() {
    let state = getState();
    for (let key in state) {
      canvas.dataset[key] = state[key];
    }
  }

  function restoreSavedState() {
    let state = {};
    for (let key in canvas.dataset) {
      state[key] = canvas.dataset[key];
    }
    setState(state);
  }

  function saveFormat() {
    if (canvas) {
      updateSavedState();
      return canvas.outerHTML;
    } else {
      return "";
    }
  }

  window.canvas = null;

  function restoreFormat(savetext) {
    window.canvas = document.querySelector("#canvas");
    if (!canvas) {
      canvas = dom.svg("svg");
      document.body.prepend(canvas);
    }
    if (!savetext) {
      savetext = defaultCanvas;
    }
    canvas.outerHTML = savetext;
    canvas = document.querySelector("#canvas");
    updateFrameCount();
    canvas.setAttribute("width", document.body.clientWidth + "px");
    canvas.setAttribute("height", document.body.clientHeight + "px");
    listenCanvas();
    restoreSavedState();
  }

  function restore() {
    var path = location.href.split("?");
    var query = location.search;
    if (query) {
      var queryparts = query.slice(1).split("=");
      if (queryparts[0] === "gist") {
        loadScriptsFromGistId(queryparts[1]);
        return;
      }
    }
    restoreLocal();
  }

  function restoreLocal() {
    restoreFormat(localStorage._currentWork || defaultCanvas);
  }

  function clear() {
    restoreFormat(defaultCanvas);
  }

  function saveFile(evt) {
    if (evt) {
      evt.preventDefault();
    }
    var title = prompt("Save file as: ");
    if (!title) {
      return;
    }
    saveAs(saveFormat(), `${title}.svg`);
  }

  const filetypes = {
    svg: "image/svg+xml",
    png: "image/png",
    gif: "image/gif"
  };

  function saveToCallback(data, filename, cb) {
    // Callback is shaped cb(blob, filename);
    console.log('saveToCallback(%s)', filename);
    let ext = filename.split(".").pop();
    let filetype = filetypes[ext];
    if (data.toBlob) {
      // ex: canvas.toBlob()
      data.toBlob(blob => cb(blob, filename), filetype);
    } else {
      cb(new Blob([data], { type: filetype }), filename);
    }
  }

  function sendToMoat(progid) {
    console.log('sendToMoat(%s)', progid);
    saveToCallback(saveFormat(), "shimmy.svg", (blob, filename) =>
      sendToMoatCB(blob, filename, progid)
    );
  }

  function sendToMoatCB(blob, filename, progid) {
    console.log('sendToMoatCB(%s)', filename);
    let formData = new FormData();
    formData.append("program", progid);
    formData.append("file", blob, filename);
    let request = new XMLHttpRequest();
    request.open("POST", MOAT_URL + 'file/create');
    request.setRequestHeader('X-Requested-With', 'XMLHTTPRequest');
    request.send(formData);
    request.onload = () => showFilePage(request.response);
    request.onerror = () => handleError('send file');
    request.ontimeout = () => handleTimeout('send file');
  }

  function handleError(step) {
    alert("Error uploading to Moat during " + step + " step, please try again.");
  }

  function handleTimeout(step) {
    alert("Timeout uploading to Moat during " + step + ", please try again.");
  }

  function showQRCode(){
  if (document.querySelector('#qrcode')){
      let qrcode = new QRCode("qrcode", {
          text: "{{urlbase}}/file/{{id}}",
          width: 128,
          height: 128,
          colorDark: "#000000",
          colorLight: "#ffffff",
          correctLevel: QRCode.CorrectLevel.H
        });
  }
}

function updateExpires(){
  let expires = document.querySelectorAll('.expires');
  if (expires.length){
    expires.forEach(e => e.innerText = timeago.format(e.getAttribute('timestamp')));
    setTimeout(updateExpires, 1000);
  }
}

function updateDialog(){
  showQRCode();
  updateExpires();
}

  function showFilePage(res) {
    dialog.innerHTML = res;
    dialog.append(dom.html('button', {onClick: 'this.parentElement.close()'}, 'OK'));
    updateDialog();
    dialog.showModal();
  }

  function saveAs(data, filename) {
    saveToCallback(data, filename, saveBlob);
  }

  function saveBlob(blob, filename) {
    var reader = new FileReader();
    reader.onloadend = function() {
      var a = dom.html("a", {
        href: reader.result,
        download: filename,
        target: "_blank"
      });
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
    };
    reader.readAsDataURL(blob);
  }

  function readFile(file) {
    var fileName = file.name;
    if (fileName.indexOf(".svg", fileName.length - 5) === -1) {
      return alert("Not an SVG file");
    }
    var reader = new FileReader();
    reader.readAsText(file);
    reader.onload = function(evt) {
      restoreFormat(evt.target.result);
    };
  }

  function loadFile() {
    var input = dom.html("input", { type: "file", accept: "image/svg+xml" });
    if (!input) {
      return;
    }
    input.addEventListener("change", function(evt) {
      readFile(input.files[0]);
    });
    input.click();
  }

  // Save script to gist;
  function saveCurrentScriptsToGist(event) {
    event.preventDefault();
    // console.log("Saving to Gist");
    ajax.post(
      "https://api.github.com/gists",
      function(data) {
        //var raw_url = JSON.parse(data).files["script.json"].raw_url;
        gistID = JSON.parse(data)
          .url.split("/")
          .pop();
        var path = location.href.split("?")[0];
        path += "?gist=" + gistID;
        window.location = path;
      },
      JSON.stringify({
        description: "saved drawingboard file",
        public: true,
        files: {
          "animation.svg": {
            content: saveFormat()
          }
        }
      }),
      function(statusCode, x) {
        alert(
          "Can't save to Gist:\n" + statusCode + " (" + x.statusText + ") "
        );
      }
    );
  }

  var gistID = null;

  function loadScriptsFromGistId(id) {
    //we may get an event passed to this function so make sure we have a valid id or ask for one
    gistID = isNaN(parseInt(id))
      ? prompt(
          "What Gist would you like to load? Please enter the ID of the Gist: "
        )
      : id;
    if (!gistID) return;
    ajax.get(
      "https://api.github.com/gists/" + gistID,
      function(gist) {
        restoreFormat(JSON.parse(gist).files["animation.svg"].content);
      },
      function(statusCode, x) {
        alert(
          "Can't load from Gist:\n" + statusCode + " (" + x.statusText + ") "
        );
      }
    );
  }

  function newFile() {
    clear();
    onChange();
  }

  function onChange() {
    if (gistID) {
      gistID = null;
      var path = location.href.split("?")[0];
      history.replaceState(null, null, path);
    }
  }

  function queryMoat(cb) {
    fetch(MOAT_URL + "programs/?integration=shimmy").then(response =>
      response.json().then(cb)
    );
  }
  if (USE_MOAT) {
    window.addEventListener("load", e => queryMoat(setMoatUI), true);
  }

  window.file = {
    onChange: onChange,
    new: newFile,
    clear: clear,
    loadFile,
    saveFile,
    saveBlob,
    saveLocal,
    saveAs,
    sendToMoat
  };

  window.addEventListener("unload", saveLocal, false);
  window.addEventListener("load", restore, false);
})(window);
<|endoftext|>


<commit_before>var pen = null;
var offset = null;
var flag = 1;
var data = [];

function gameInit( id ){
	var html = '<canvas id = "five" width = "600px" height="600px"></canvas>';
	if(id){
		$("#"+id).append(html);
	}else{
		$("body").append(html);
	}

	pen = $("#five").get(0).getContext("2d");
	//横
	for(var i = 1;i < 15;i++){
		pen.beginPath();
		if(i==3||i==12){
			pen.lineWidth=3;
		}else{
			pen.lineWidth=1;
		}
		pen.moveTo(0,i*40);
		pen.lineTo(600,i*40);
		pen.stroke();
		pen.closePath();
	}
	//竖
	for(var i = 1;i < 15;i++){
		pen.beginPath();
		if(i==3||i==12){
			pen.lineWidth=3;
		}else{
			pen.lineWidth=1;
		}
		pen.moveTo(i*40,0);
		pen.lineTo(i*40,600);
		pen.stroke();
		pen.closePath();
	}

	for( var i = 0;i<15;i++){
		var temp = [];
		for( var j = 0;j<15;j++){
			temp.push(-1);
		}
		data.push(temp);
	}

	offset=$("#five").offset();

	$("#five").mousedown(function(event){
		var x = event.clientX - offset.left;
		var y = event.clientY - offset.top;

		var row = Math.floor(y/40);
		var col = Math.floor(x/40);

		if(data[row][col] == -1){
			data[row][col] = flag;
			pen.beginPath();
			if(flag == 1){
				pen.fillStyle = "white";

			}else{
				pen.fillStyle = "black";

			}
			pen.arc(col * 40 + 20,row * 40 + 20,15,0,2 * Math.PI);
			pen.fill();
			pen.closePath();
			gameOver(row,col,flag);
			flag = flag ==1?2:1;
		}
	});
}

function gameOver(row,col,flag){
	//上下找
	var count = 1;
	for(var i= row-1;i>=0;i--){
		if(data[i][col]==flag){
			count ++;
		}else{
			break;
		}
	}
	for(var i=row + 1;i<15;i++){
		if(data[i][col]==flag){
			count++;
		}else{
			break;
		}
	}
	if(count>=5){
		alert("游戏结束");
		return;
	}

	//左右找
	count = 1;
	for(var i= col-1;i>=0;i--){
		if(data[row][i]==flag){
			count ++;
		}else{
			break;
		}
	}
	for(var i=col + 1;i<15;i++){
		if(data[row][i]==flag){
			count++;
		}else{
			break;
		}
	}
	if(count>=5){
		alert("游戏结束");
		return;
	}

	//左上右下
	count = 1;
	for(var i= row-1,j=col-1;i>=0&&j>=0;i--,j--){
		if(data[i][j]==flag){
			count++;
		}else{
			break;
		}
	}
	for(var i=row+1,j=col+1;i<15&&j<15;i++,j++){
		if(data[i][j]==flag){
			count++;
		}else{
			break;
		}
	}
	if(count>=5){
		alert("游戏结束");
		return;
	}

	//右上左下
	count = 1;
	for(var i= row-1,j=col+1;i>=0&&j<15;i--,j++){
		if(data[i][j]==flag){
			count++;
		}else{
			break;
		}
	}
	for(var i=row+1,j=col-1;i<15&&j>=0;i++,j--){
		if(data[i][j]==flag){
			count++;
		}else{
			break;
		}
	}
	if(count>=5){
		alert("游戏结束");
		return;
	}
}

<commit_msg>Signed-off-by: wangzeyuan <739077130@qq.com><commit_after>var pen = null;
var offset = null;
var flag = 1;
var data = [];

function gameInit( id ){
	var html = '<canvas id = "five" width = "600px" height="600px"></canvas>';
	if(id){
		$("#"+id).append(html);
	}else{
		$("body").append(html);
	}

	pen = $("#five").get(0).getContext("2d");
	//横
	for(var i = 1;i < 15;i++){
		pen.beginPath();
		if(i==3||i==12){
			pen.lineWidth=3;
		}else{
			pen.lineWidth=1;
		}
		pen.moveTo(0,i*40);
		pen.lineTo(600,i*40);
		pen.stroke();
		pen.closePath();
	}
	//竖
	for(var i = 1;i < 15;i++){
		pen.beginPath();
		if(i==3||i==12){
			pen.lineWidth=3;
		}else{
			pen.lineWidth=1;
		}
		pen.moveTo(i*40,0);
		pen.lineTo(i*40,600);
		pen.stroke();
		pen.closePath();
	}

	for( var i = 0;i<15;i++){
		var temp = [];
		for( var j = 0;j<15;j++){
			temp.push(-1);
		}
		data.push(temp);
	}

	offset=$("#five").offset();

	$("#five").mousedown(function(event){
		var x = event.clientX - offset.left;
		var y = event.clientY - offset.top;

		var row = Math.floor(y/40);
		var col = Math.floor(x/40);

		if(data[row][col] == -1){
			data[row][col] = flag;
			pen.beginPath();
			if(flag == 1){
				pen.fillStyle = "white";
			}else{
				pen.fillStyle = "black";
			}
			pen.arc(col * 40 + 20,row * 40 + 20,15,0,2 * Math.PI);
			pen.fill();
			pen.stroke();
			pen.closePath();
			gameOver(row,col,flag);
			flag = flag ==1?2:1;
		}
	});
}

function gameOver(row,col,flag){
	//上下找
	var count = 1;
	for(var i= row-1;i>=0;i--){
		if(data[i][col]==flag){
			count ++;
		}else{
			break;
		}
	}
	for(var i=row + 1;i<15;i++){
		if(data[i][col]==flag){
			count++;
		}else{
			break;
		}
	}
	if(count>=5){
		alert("游戏结束");
		return;
	}

	//左右找
	count = 1;
	for(var i= col-1;i>=0;i--){
		if(data[row][i]==flag){
			count ++;
		}else{
			break;
		}
	}
	for(var i=col + 1;i<15;i++){
		if(data[row][i]==flag){
			count++;
		}else{
			break;
		}
	}
	if(count>=5){
		alert("游戏结束");
		return;
	}

	//左上右下
	count = 1;
	for(var i= row-1,j=col-1;i>=0&&j>=0;i--,j--){
		if(data[i][j]==flag){
			count++;
		}else{
			break;
		}
	}
	for(var i=row+1,j=col+1;i<15&&j<15;i++,j++){
		if(data[i][j]==flag){
			count++;
		}else{
			break;
		}
	}
	if(count>=5){
		alert("游戏结束");
		return;
	}

	//右上左下
	count = 1;
	for(var i= row-1,j=col+1;i>=0&&j<15;i--,j++){
		if(data[i][j]==flag){
			count++;
		}else{
			break;
		}
	}
	for(var i=row+1,j=col-1;i<15&&j>=0;i++,j--){
		if(data[i][j]==flag){
			count++;
		}else{
			break;
		}
	}
	if(count>=5){
		alert("游戏结束");
		return;
	}
}

<|endoftext|>


<commit_before>NSB.FormView = function(formContainerId){
  var form = $(formContainerId + ' form');
  var formQuestions = $('#questions');
  var repeatCounter = {};

  this.init = function(){
    console.log("Initialize form");

    // Listen for objectedSelected, triggered when items on the map are tapped
    $.subscribe("objectSelected", setSelectedObjectInfo);

    // Render the form
    NSB.API.getForm(renderForm);

    // Add a function to serialize the form for submission to the API
    // usage: form.serializeObject();
    form.serializeObject = function() {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function() {
            if (o[this.name] !== undefined) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else {
                o[this.name] = this.value || '';
            }
        });
        return o;
    };
  };

  // Update the form with information about the selected object.
  // Then, display the form.
  var setSelectedObjectInfo = function(e) {
    console.log("Showing the form");
    var $addressDOM = $('h2 .parcel_id');

    $addressDOM.fadeOut(400, function() {
      $addressDOM.text(NSB.selectedObject.humanReadableName.titleCase());
      $addressDOM.fadeIn(400);
    });

    if(!$('#form').is(":visible")) {
        $('#form').slideToggle();
    }
    if($('#startpoint').is(":visible")) {
      $('#startpoint').hide();
    }
    if($('#thanks').is(":visible")) {
      $('#thanks').slideToggle();
    }
  };

  // Form submission ...........................................................

  // Handle the parcel survey form being submitted
  form.submit(function(event) {
    console.log("Submitting survey results");

    // Stop form from submitting normally
    event.preventDefault();

    var url = NSB.API.getSurveyURL() + form.attr('action');

    // Serialize the form
    serialized = form.serializeObject();

    // Get some info about the centroid as floats.
    var selectedCentroid = NSB.selectedObject.centroid;
    console.log(selectedCentroid);
    var centroidLat = parseFloat(selectedCentroid.coordinates[0]);
    var centroidLng = parseFloat(selectedCentroid.coordinates[1]);

    console.log("Selected object ID");
    console.log(NSB.selectedObject.id);

    // Construct a response in the format we need it.
    responses = {responses: [{
        "source": {
          "type":"mobile",
          "collector":NSB.collectorName
        },
        "geo_info": {
          "centroid":[centroidLng, centroidLat],
          "geometry": NSB.selectedObject.geometry,
          "humanReadableName": NSB.selectedObject.humanReadableName,
          parcel_id: NSB.selectedObject.id // Soon to be deprecated
        },
        "parcel_id": NSB.selectedObject.id, // Soon to be deprecated
        "object_id": NSB.selectedObject.id, // Replaces parcel_id
        "responses": serialized
    }]};

    console.log("Serialized & responses:");
    console.log(serialized);
    console.log(responses);
    console.log(url);

    // Post the form
    // TODO: This will need to use Prashant's browser-safe POSTing
    var jqxhr = $.post(url, responses, function() {
        console.log("Form successfully posted");
      },"text").error(function(){
        var key;
        var result = "";
        for (key in jqxhr) {
          result += key + ": " + jqxhr[key] + "\n";
        }
        console.log("error: " + result);
      }).success(function(){
      successfulSubmit();
    });
  });

  // Clear the form and thank the user after a successful submission
  // TODO: pass in selected_parcel_json
  function successfulSubmit() {
    console.log("Successful submit");

    // Publish  a "form submitted" event
    $.publish("successfulSubmit");

    // Hide the form and show the thanks
    $('#form').slideToggle();
    $('#thanks').slideToggle();

    if($('#address-search-prompt').is(":hidden")) {
      $('#address-search-prompt').slideToggle();
    }
    if($('#address-search').is(":visible")) {
      $('#address-search').slideToggle();
    }

    // Reset the form for the next submission.
    resetForm();
  }

  // Reset the form: clear checkboxes, remove added option groups, hide
  // sub options.
  function resetForm() {
    console.log("Resetting form");

    // Clear all checkboxes and radio buttons
    $('input:checkbox').each(function(index){
      try {
        $(this).attr('checked', false).checkboxradio('refresh',true);
      } catch(e){}
    });
    $('input:radio').each(function(index){
      try {
        $(this).attr('checked', false).checkboxradio('refresh',true);
      } catch(e){}
    });
    $('fieldset').each(function(index){
      hideSubQ($(this).attr('id'));
    });

    // Remove additional repeating groups
    $('.append-to').empty();
  }

  // Render the form ...........................................................
  var renderForm = function() {
    console.log("Form data:");
    console.log(NSB.settings.formData);
    $.each(NSB.settings.formData.questions, function (index, question) {
      addQuestion(question);
    });
    form.trigger("create");
  };

  /*
   * Keep track of how many times we've seen a question with a given name
   * Return a suffix if we've seen it more than once times
   */
  function suffix(name) {
    if(_.has(repeatCounter, name)) {
      repeatCounter[name] += 1;
      return "-" + repeatCounter[name].toString();
    }

    repeatCounter[name] = 1;
    return "";
  }

  /*
   * Render questions
   */
  window.NSB.boxAnswersByQuestionId = {};
  window.NSB.questionsByParentId = {};
  function addQuestion(question, visible, parentID, triggerID, appendTo) {
    // Set default values for questions
    if (visible === undefined) {
      visible = true;
    }
    if (parentID === undefined) {
      parentID = '';
    }
    if (triggerID === undefined) {
      triggerID = '';
    }

    // Give the question an ID based on its name
    var id = _.uniqueId(question.name);

    // Collected the data needed to render the question
    var questionData = {
      text: question.text,
      info: question.info,
      id: id,
      parentID: parentID,
      triggerID: triggerID
    };

    // Render the questions's fieldset
    var $question = $(_.template($('#question').html(), questionData));
    if (!visible) {
      $question.hide();
    }

    //
    var siblings = window.NSB.questionsByParentId[parentID];
    if (siblings === undefined) {
      siblings = [];
      window.NSB.questionsByParentId[parentID] = siblings;
    }
    siblings.push($question);

    if (appendTo !== undefined) {
      $(appendTo).append($question);
    }else {
      formQuestions.append($question);
    }

    var suffixed_name = question.name + suffix(question.name);

    // Infoboxes (aka help text for questions)
    if(question.info !== undefined) {
      $question.find(".show-info").click(function(e) {
        var toShow = $(this).attr("data-trigger");
        console.log($("#" + toShow));
        $("#" + toShow).slideToggle('slow');
      });

      $question.find(".box-close").click(function(e) {
        var $toHide = $(this).parent();
        $toHide.slideUp('slow');
      });
    }

    // TODO: Titles for question groups
    // if(answer.title != undefined) {
    //   console.log("TITLE!------");
    //   var $title = $(_.template($('#title').html(), {title: answer.title} ));
    //   $question.append($title);
    // }

    var questionID = id;
    // Add each answer to the question
    _.each(question.answers, function (answer) {
      // The triggerID is used to hide/show other question groups
      var triggerID = _.uniqueId(question.name);

      // TODO: checkbox questions should be consistent with other answer groups
      if(question.type === "checkbox") {
        suffixed_name = answer.name + suffix(answer.name);
        triggerID = suffixed_name; //_.uniqueId(answer.name);
        id = suffixed_name; //_.uniqueId(answer.name);
      }

      // Set the data used to render the answer
      var data = {
        questionName: suffixed_name,
        id: triggerID,
        theme: (answer.theme || "c"),
        value: answer.value,
        text: answer.text
      };

      // Render the answer and append it to the fieldset.
      var $answer;

      var boxes;

      // If there is more than one answer, this could be multiple choice
      // or a radio group.
      if (question.answers.length > 1) {

        if(question.type === "checkbox") {
          $answer = $(_.template($('#answer-checkbox').html(), data));
        }else {
          $answer = $(_.template($('#answer-radio').html(), data));
        }

        // Store references to the questions for quick retrieval later
        boxes = window.NSB.boxAnswersByQuestionId[questionID];
        if (boxes === undefined) {
          boxes = [];
          window.NSB.boxAnswersByQuestionId[questionID] = boxes;
        }
        $answer.filter('input[type="radio"]').each(function (i, el) {
          boxes.push($(el));
        });
        $answer.filter('input[type="checkbox"]').each(function (i, el) {
          boxes.push($(el));
        });

      }else {
        if(question.type === "text") {
          $answer = $(_.template($('#answer-text').html(), data));
        }else {
          $answer = $(_.template($('#answer-checkbox').html(), data));

          // Store references to answers for quick retrieval later
          boxes = window.NSB.boxAnswersByQuestionId[questionID];
          if (boxes === undefined) {
            boxes = [];
            window.NSB.boxAnswersByQuestionId[questionID] = boxes;
          }
          $answer.filter('input[type="radio"]').each(function (i, el) {
            boxes.push($(el));
          });
          $answer.filter('input[type="checkbox"]').each(function (i, el) {
            boxes.push($(el));
          });

        }
      }

      $question.append($answer);

      // Add the click handlers
      var input = $answer.parent().find('input#' + triggerID);
      if (input.length === 0) {
        input = $answer;
      }
      var controlGroupElements = $('.control-group[data-trigger=' + triggerID + ']');
      var repeatingButtonElements = $('.repeating-button[data-trigger=' + triggerID + ']');
      input.click(function handleClick(e) {
        // Hide all of the conditional questions, recursively.
        hideSubQ(id);

        if($(this).prop("checked")) {
          // Show the conditional questions for this response.
          $('.control-group[data-trigger=' + triggerID + ']').each(function (i) {
            $(this).show();
          });

          $('.repeating-button[data-trigger=' + id + ']').each(function (i) {
            $(this).show();
          });
        }else {
          $('.control-group[data-trigger=' + triggerID + ']').each(function (i) {
            $(this).hide();
          });

          $('.repeating-button[data-trigger=' + id + ']').each(function (i) {
            $(this).hide();
          });
        }
      });

      // If there are conditional questions, add them.
      // They are hidden by default.
      if (answer.questions !== undefined) {
        var $repeatButton;

        // If users can repeat those conditional questions:
        if(answer.repeatQuestions !== undefined) {
          $repeatBox = $(_.template($('#repeat-button').html(), {
            parentID: id,
            triggerID: id
          }));
          formQuestions.append($repeatBox);
          var $repeatButton = $repeatBox.find('a');
          var $appendTo = $repeatBox.find('.append-to');
          console.log($appendTo);

          // If we click the repeat button, add the questions again
          $repeatButton.click(function handleClick(e) {
            e.preventDefault();

            // Append the questions to this answer again!
            _.each(answer.questions, function (subq) {
              addQuestion(subq, true, id, triggerID, $appendTo);
            });

            form.trigger("create");
          });

          _.each(answer.questions, function (subq) {
            // Add the sub questions before the repeatButton
            addQuestion(subq, false, id, triggerID, $appendTo);
          });

        }else {
          _.each(answer.questions, function (subq) {
            // Add the sub questions before the repeatButton
            if(appendTo !== undefined){
              addQuestion(subq, false, id, triggerID, appendTo);
            }else {
              addQuestion(subq, false, id, triggerID);
            }
          });

        } // end repeating answers

      } // end check for sub-answers

    });
  }

  // Option group stuff ........................................................

  // Show / hide sub questions
  function hideSubQ(parent) {
    var cgroupQueue = window.NSB.questionsByParentId[parent];
    var boxQueue = [];

    function handleCGroup(cgroup) {
      var $el = $(cgroup);
      $el.hide();

      // Uncheck the answers
      var id = $el.attr('id');
      var boxAnswers = window.NSB.boxAnswersByQuestionId[id];
      if (boxAnswers !== undefined) {
        boxQueue = boxQueue.concat(boxAnswers);
      }

      // Handle conditional questions.
      //cgroupQueue = cgroupQueue.concat($('.control-group[data-parent=' + $el.attr('id') + ']').toArray());
      var children = window.NSB.questionsByParentId[$el.attr('id')];
      if (children !== undefined) {
        cgroupQueue = cgroupQueue.concat(children);
      }
    }

    var i = 0;
    var cgroup;
    while (cgroupQueue !== undefined && i < cgroupQueue.length) {
      cgroup = cgroupQueue[i];
      handleCGroup(cgroup);
      i += 1;
    }

    var j;
    var len = boxQueue.length;
    for (j = 0; j < len; j += 1) {
      boxQueue[j].attr('checked', false).checkboxradio("refresh");
    }

    $('.repeating-button[data-parent=' + parent + ']').hide();
  }

  // Trigger form init .........................................................
  this.init();

};<commit_msg>More descriptive variable name<commit_after>NSB.FormView = function(formContainerId){
  var form = $(formContainerId + ' form');
  var formQuestions = $('#questions');
  var repeatCounter = {};

  this.init = function(){
    console.log("Initialize form");

    // Listen for objectedSelected, triggered when items on the map are tapped
    $.subscribe("objectSelected", setSelectedObjectInfo);

    // Render the form
    NSB.API.getForm(renderForm);

    // Add a function to serialize the form for submission to the API
    // usage: form.serializeObject();
    form.serializeObject = function() {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function() {
            if (o[this.name] !== undefined) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else {
                o[this.name] = this.value || '';
            }
        });
        return o;
    };
  };

  // Update the form with information about the selected object.
  // Then, display the form.
  var setSelectedObjectInfo = function(e) {
    console.log("Showing the form");
    var $addressDOM = $('h2 .parcel_id');

    $addressDOM.fadeOut(400, function() {
      $addressDOM.text(NSB.selectedObject.humanReadableName.titleCase());
      $addressDOM.fadeIn(400);
    });

    if(!$('#form').is(":visible")) {
        $('#form').slideToggle();
    }
    if($('#startpoint').is(":visible")) {
      $('#startpoint').hide();
    }
    if($('#thanks').is(":visible")) {
      $('#thanks').slideToggle();
    }
  };

  // Form submission ...........................................................

  // Handle the parcel survey form being submitted
  form.submit(function(event) {
    console.log("Submitting survey results");

    // Stop form from submitting normally
    event.preventDefault();

    var url = NSB.API.getSurveyURL() + form.attr('action');

    // Serialize the form
    serialized = form.serializeObject();

    // Get some info about the centroid as floats.
    var selectedCentroid = NSB.selectedObject.centroid;
    console.log(selectedCentroid);
    var centroidLat = parseFloat(selectedCentroid.coordinates[0]);
    var centroidLng = parseFloat(selectedCentroid.coordinates[1]);

    console.log("Selected object ID");
    console.log(NSB.selectedObject.id);

    // Construct a response in the format we need it.
    responses = {responses: [{
        "source": {
          "type":"mobile",
          "collector":NSB.collectorName
        },
        "geo_info": {
          "centroid":[centroidLng, centroidLat],
          "geometry": NSB.selectedObject.geometry,
          "humanReadableName": NSB.selectedObject.humanReadableName,
          parcel_id: NSB.selectedObject.id // Soon to be deprecated
        },
        "parcel_id": NSB.selectedObject.id, // Soon to be deprecated
        "object_id": NSB.selectedObject.id, // Replaces parcel_id
        "responses": serialized
    }]};

    console.log("Serialized & responses:");
    console.log(serialized);
    console.log(responses);
    console.log(url);

    // Post the form
    // TODO: This will need to use Prashant's browser-safe POSTing
    var jqxhr = $.post(url, responses, function() {
        console.log("Form successfully posted");
      },"text").error(function(){
        var key;
        var result = "";
        for (key in jqxhr) {
          result += key + ": " + jqxhr[key] + "\n";
        }
        console.log("error: " + result);
      }).success(function(){
      successfulSubmit();
    });
  });

  // Clear the form and thank the user after a successful submission
  // TODO: pass in selected_parcel_json
  function successfulSubmit() {
    console.log("Successful submit");

    // Publish  a "form submitted" event
    $.publish("successfulSubmit");

    // Hide the form and show the thanks
    $('#form').slideToggle();
    $('#thanks').slideToggle();

    if($('#address-search-prompt').is(":hidden")) {
      $('#address-search-prompt').slideToggle();
    }
    if($('#address-search').is(":visible")) {
      $('#address-search').slideToggle();
    }

    // Reset the form for the next submission.
    resetForm();
  }

  // Reset the form: clear checkboxes, remove added option groups, hide
  // sub options.
  function resetForm() {
    console.log("Resetting form");

    // Clear all checkboxes and radio buttons
    $('input:checkbox').each(function(index){
      try {
        $(this).attr('checked', false).checkboxradio('refresh',true);
      } catch(e){}
    });
    $('input:radio').each(function(index){
      try {
        $(this).attr('checked', false).checkboxradio('refresh',true);
      } catch(e){}
    });
    $('fieldset').each(function(index){
      hideSubQ($(this).attr('id'));
    });

    // Remove additional repeating groups
    $('.append-to').empty();
  }

  // Render the form ...........................................................
  var renderForm = function() {
    console.log("Form data:");
    console.log(NSB.settings.formData);
    $.each(NSB.settings.formData.questions, function (index, question) {
      addQuestion(question);
    });
    form.trigger("create");
  };

  /*
   * Keep track of how many times we've seen a question with a given name
   * Return a suffix if we've seen it more than once times
   */
  function suffix(name) {
    if(_.has(repeatCounter, name)) {
      repeatCounter[name] += 1;
      return "-" + repeatCounter[name].toString();
    }

    repeatCounter[name] = 1;
    return "";
  }

  /*
   * Render questions
   */
  window.NSB.boxAnswersByQuestionId = {};
  window.NSB.questionsByParentId = {};
  function addQuestion(question, visible, parentID, triggerID, appendTo) {
    // Set default values for questions
    if (visible === undefined) {
      visible = true;
    }
    if (parentID === undefined) {
      parentID = '';
    }
    if (triggerID === undefined) {
      triggerID = '';
    }

    // Give the question an ID based on its name
    var id = _.uniqueId(question.name);

    // Collected the data needed to render the question
    var questionData = {
      text: question.text,
      info: question.info,
      id: id,
      parentID: parentID,
      triggerID: triggerID
    };

    // Render the questions's fieldset
    var $question = $(_.template($('#question').html(), questionData));
    if (!visible) {
      $question.hide();
    }

    //
    var siblings = window.NSB.questionsByParentId[parentID];
    if (siblings === undefined) {
      siblings = [];
      window.NSB.questionsByParentId[parentID] = siblings;
    }
    siblings.push($question);

    if (appendTo !== undefined) {
      $(appendTo).append($question);
    }else {
      formQuestions.append($question);
    }

    var suffixed_name = question.name + suffix(question.name);

    // Infoboxes (aka help text for questions)
    if(question.info !== undefined) {
      $question.find(".show-info").click(function(e) {
        var toShow = $(this).attr("data-trigger");
        console.log($("#" + toShow));
        $("#" + toShow).slideToggle('slow');
      });

      $question.find(".box-close").click(function(e) {
        var $toHide = $(this).parent();
        $toHide.slideUp('slow');
      });
    }

    // TODO: Titles for question groups
    // if(answer.title != undefined) {
    //   console.log("TITLE!------");
    //   var $title = $(_.template($('#title').html(), {title: answer.title} ));
    //   $question.append($title);
    // }

    var questionID = id;
    // Add each answer to the question
    _.each(question.answers, function (answer) {
      // The triggerID is used to hide/show other question groups
      var triggerID = _.uniqueId(question.name);

      // TODO: checkbox questions should be consistent with other answer groups
      if(question.type === "checkbox") {
        suffixed_name = answer.name + suffix(answer.name);
        triggerID = suffixed_name; //_.uniqueId(answer.name);
        id = suffixed_name; //_.uniqueId(answer.name);
      }

      // Set the data used to render the answer
      var data = {
        questionName: suffixed_name,
        id: triggerID,
        theme: (answer.theme || "c"),
        value: answer.value,
        text: answer.text
      };

      // Render the answer and append it to the fieldset.
      var $answer;

      var referencesToAnswersForQuestion;

      // If there is more than one answer, this could be multiple choice
      // or a radio group.
      if (question.answers.length > 1) {

        if(question.type === "checkbox") {
          $answer = $(_.template($('#answer-checkbox').html(), data));
        }else {
          $answer = $(_.template($('#answer-radio').html(), data));
        }

        // Store references to the questions for quick retrieval later
        referencesToAnswersForQuestion = window.NSB.boxAnswersByQuestionId[questionID];
        if (referencesToAnswersForQuestion === undefined) {
          referencesToAnswersForQuestion = [];
          window.NSB.boxAnswersByQuestionId[questionID] = referencesToAnswersForQuestion;
        }
        $answer.filter('input[type="radio"]').each(function (i, el) {
          referencesToAnswersForQuestion.push($(el));
        });
        $answer.filter('input[type="checkbox"]').each(function (i, el) {
          referencesToAnswersForQuestion.push($(el));
        });

      }else {
        if(question.type === "text") {
          $answer = $(_.template($('#answer-text').html(), data));
        }else {
          $answer = $(_.template($('#answer-checkbox').html(), data));

          // Store references to answers for quick retrieval later
          referencesToAnswersForQuestion = window.NSB.boxAnswersByQuestionId[questionID];
          if (referencesToAnswersForQuestion === undefined) {
            referencesToAnswersForQuestion = [];
            window.NSB.boxAnswersByQuestionId[questionID] = referencesToAnswersForQuestion;
          }
          $answer.filter('input[type="radio"]').each(function (i, el) {
            referencesToAnswersForQuestion.push($(el));
          });
          $answer.filter('input[type="checkbox"]').each(function (i, el) {
            referencesToAnswersForQuestion.push($(el));
          });

        }
      }

      $question.append($answer);

      // Add the click handlers
      var input = $answer.parent().find('input#' + triggerID);
      if (input.length === 0) {
        input = $answer;
      }
      var controlGroupElements = $('.control-group[data-trigger=' + triggerID + ']');
      var repeatingButtonElements = $('.repeating-button[data-trigger=' + triggerID + ']');
      input.click(function handleClick(e) {
        // Hide all of the conditional questions, recursively.
        hideSubQ(id);

        if($(this).prop("checked")) {
          // Show the conditional questions for this response.
          $('.control-group[data-trigger=' + triggerID + ']').each(function (i) {
            $(this).show();
          });

          $('.repeating-button[data-trigger=' + id + ']').each(function (i) {
            $(this).show();
          });
        }else {
          $('.control-group[data-trigger=' + triggerID + ']').each(function (i) {
            $(this).hide();
          });

          $('.repeating-button[data-trigger=' + id + ']').each(function (i) {
            $(this).hide();
          });
        }
      });

      // If there are conditional questions, add them.
      // They are hidden by default.
      if (answer.questions !== undefined) {
        var $repeatButton;

        // If users can repeat those conditional questions:
        if(answer.repeatQuestions !== undefined) {
          $repeatBox = $(_.template($('#repeat-button').html(), {
            parentID: id,
            triggerID: id
          }));
          formQuestions.append($repeatBox);
          var $repeatButton = $repeatBox.find('a');
          var $appendTo = $repeatBox.find('.append-to');
          console.log($appendTo);

          // If we click the repeat button, add the questions again
          $repeatButton.click(function handleClick(e) {
            e.preventDefault();

            // Append the questions to this answer again!
            _.each(answer.questions, function (subq) {
              addQuestion(subq, true, id, triggerID, $appendTo);
            });

            form.trigger("create");
          });

          _.each(answer.questions, function (subq) {
            // Add the sub questions before the repeatButton
            addQuestion(subq, false, id, triggerID, $appendTo);
          });

        }else {
          _.each(answer.questions, function (subq) {
            // Add the sub questions before the repeatButton
            if(appendTo !== undefined){
              addQuestion(subq, false, id, triggerID, appendTo);
            }else {
              addQuestion(subq, false, id, triggerID);
            }
          });

        } // end repeating answers

      } // end check for sub-answers

    });
  }

  // Option group stuff ........................................................

  // Show / hide sub questions
  function hideSubQ(parent) {
    var cgroupQueue = window.NSB.questionsByParentId[parent];
    var boxQueue = [];

    function handleCGroup(cgroup) {
      var $el = $(cgroup);
      $el.hide();

      // Uncheck the answers
      var id = $el.attr('id');
      var boxAnswers = window.NSB.boxAnswersByQuestionId[id];
      if (boxAnswers !== undefined) {
        boxQueue = boxQueue.concat(boxAnswers);
      }

      // Handle conditional questions.
      //cgroupQueue = cgroupQueue.concat($('.control-group[data-parent=' + $el.attr('id') + ']').toArray());
      var children = window.NSB.questionsByParentId[$el.attr('id')];
      if (children !== undefined) {
        cgroupQueue = cgroupQueue.concat(children);
      }
    }

    var i = 0;
    var cgroup;
    while (cgroupQueue !== undefined && i < cgroupQueue.length) {
      cgroup = cgroupQueue[i];
      handleCGroup(cgroup);
      i += 1;
    }

    var j;
    var len = boxQueue.length;
    for (j = 0; j < len; j += 1) {
      boxQueue[j].attr('checked', false).checkboxradio("refresh");
    }

    $('.repeating-button[data-parent=' + parent + ']').hide();
  }

  // Trigger form init .........................................................
  this.init();

};<|endoftext|>


<commit_before>(function(module) {

  formHandler = {};
  formHandler.userName = '';
  formHandler.el = {};
  formHandler.el.$nameAlert = $('#nameAlert');
  formHandler.el.$output = $('#output');
  formHandler.el.$outputText = $('#outputText');
  formHandler.el.$nameForm = $('#nameForm');
  formHandler.el.$locationForm = $('#locationForm');
  formHandler.el.$submitName = $('#submitName');
  formHandler.el.$submitLocation = $('#submitLocation');

  formHandler.init = function(){
    if (localStorage.currentUser) {
      // console.log('Name was already there.');
      userName = localStorage.currentUser;
      formHandler.el.$nameForm.hide();
      formHandler.el.$locationForm.show();
    } else {

      $('button').click(function(e){
        e.preventDefault();
        userName = $('input:text').val();
        localStorage.currentUser = userName;
      });
    }

  };

  formHandler.recommendation= function(temp){
    console.log(temp + 'hi there');
    var response = '';
    if (temp < 50){
      response = 'cold';
    } else if ((temp >= 50) && (temp < 75)) {
      response = 'good';
    } else {
      resonse = 'hot';
    }

    return response;
  };

  formHandler.showRec = function (){
    formHandler.el.$output.text(formHandler.recommendation(userLocation.all[0].temperature));
  };

  //Event Listeners for Submit Button
  formHandler.el.$submitName.click(validateUserName);

  function validateUserName(e) {
    e.preventDefault();
    // $nfValidator.element('#fname');
    var userName = document.forms['nameInput']['fname'].value;
    if (!userName) { // if userName is falsy
      formHandler.el.$nameAlert.show();
      // $output.hide();
    }else {

      formHandler.el.$nameAlert.hide();
      formHandler.el.$nameForm.hide();
      // $output.show();
      formHandler.el.$locationForm.show();
    }
  };

  //Event Listener for Submit Button2
  formHandler.el.$submitLocation.click(validateLocation);

  //Validating the input for the Location Form

  function validateLocation(e){
    e.preventDefault();
    var error = false;
    var ldf = document.getElementById('locationForm');
    var inputLocation = {};
    $('fieldset > p').hide();
    inputLocation.locationName = ldf.elements.flocationname.value;
    inputLocation.streetAddress = ldf.elements.fstreetaddress.value;
    inputLocation.city = ldf.elements.fcity.value;
    inputLocation.state = ldf.elements.fstate.value;
    inputLocation.zipcode = ldf.elements.fzip.value;

    if (!inputLocation.locationName){ // if location name falsy
      $('#locationNameAlert').show();
      error = true;
    }
    if (!inputLocation.streetAddress) { // if location address falsy
      $('#locationAddressAlert').show();
      error = true;
    }
    if (!inputLocation.city) { // if location city falsy
      $('#locationCityAlert').show();
      error = true;
    }
    if (!inputLocation.state) { // if location state falsy
      $('#locationStateAlert').show();
      error = true;
    }
    if (!inputLocation.zipcode) { // if location zipcode falsy
      $('#locationZipAlert').show();
      error = true;
    }
    if (!error) {
      var obj = new userLocation(inputLocation);
      obj.insertRecord(userLocation.merge);
      ldf.reset();
    }
  };

//tooltips

  // var $nfValidator = $('#nameForm').validate({
  //   debug: true,
  //   showErrors: function(errorMap, errorList) {
  //     console.log('got to showErrors.');
  //     $.each(this.validElements(), function (index, element) {
  //       var $element = $(element);
  //       $element.data('title', '')
  //       .removeClass('error')
  //       .tooltip('destroy');
  //     });
  //
  //     $.each(errorList, function (index, error) {
  //       var $element = $(error.element);
  //       $element.parent().addClass('has-error');
  //       $element.tooltip('destroy')
  //       .data('title', error.message)
  //       // .addClass('error')
  //       .tooltip();
  //     });
  //   },
  //   submitHandler: function(form) {
  //     alert('This is a valid form!');
  //   }
  // });

  formHandler.init();

  module.formHandler = formHandler;
})(window);
<commit_msg>expanded the recommendations based on temperature<commit_after>(function(module) {

  formHandler = {};
  formHandler.userName = '';
  formHandler.el = {};
  formHandler.el.$nameAlert = $('#nameAlert');
  formHandler.el.$output = $('#output');
  formHandler.el.$outputText = $('#outputText');
  formHandler.el.$nameForm = $('#nameForm');
  formHandler.el.$locationForm = $('#locationForm');
  formHandler.el.$submitName = $('#submitName');
  formHandler.el.$submitLocation = $('#submitLocation');

  formHandler.init = function(){
    if (localStorage.currentUser) {
      // console.log('Name was already there.');
      userName = localStorage.currentUser;
      formHandler.el.$nameForm.hide();
      formHandler.el.$locationForm.show();
    } else {

      $('button').click(function(e){
        e.preventDefault();
        userName = $('input:text').val();
        localStorage.currentUser = userName;
      });
    }

  };

  formHandler.recommendation= function(temp){
    var response = '';
    if (temp < 50){
      response = 'It\'s very cold';
    } else if ((temp >= 50) && (temp < 61)) {
      response = 'It\s pleasantly cool';
    } else if ((temp >= 61) && (temp < 70)) {
      response = 'It\'s nice and warm, perfect biking temperatures ';
    } else if ((temp >= 70) && (temp < 79)) {
      response = 'It\'s pretty warm, should be a nice ride';
    } else if ((temp >= 79) && (temp < 88)) {
      response = 'It\'s very warm out there';
    } else {
      response = 'It\'s very hot';
    }
    return response;
  };

  formHandler.showRec = function (){
    formHandler.el.$output.text(formHandler.recommendation(userLocation.all[0].temperature));
  };

  //Event Listeners for Submit Button
  formHandler.el.$submitName.click(validateUserName);

  function validateUserName(e) {
    e.preventDefault();
    // $nfValidator.element('#fname');
    var userName = document.forms['nameInput']['fname'].value;
    if (!userName) { // if userName is falsy
      formHandler.el.$nameAlert.show();
      // $output.hide();
    }else {

      formHandler.el.$nameAlert.hide();
      formHandler.el.$nameForm.hide();
      // $output.show();
      formHandler.el.$locationForm.show();
    }
  };

  //Event Listener for Submit Button2
  formHandler.el.$submitLocation.click(validateLocation);

  //Validating the input for the Location Form

  function validateLocation(e){
    e.preventDefault();
    var error = false;
    var ldf = document.getElementById('locationForm');
    var inputLocation = {};
    $('fieldset > p').hide();
    inputLocation.locationName = ldf.elements.flocationname.value;
    inputLocation.streetAddress = ldf.elements.fstreetaddress.value;
    inputLocation.city = ldf.elements.fcity.value;
    inputLocation.state = ldf.elements.fstate.value;
    inputLocation.zipcode = ldf.elements.fzip.value;

    if (!inputLocation.locationName){ // if location name falsy
      $('#locationNameAlert').show();
      error = true;
    }
    if (!inputLocation.streetAddress) { // if location address falsy
      $('#locationAddressAlert').show();
      error = true;
    }
    if (!inputLocation.city) { // if location city falsy
      $('#locationCityAlert').show();
      error = true;
    }
    if (!inputLocation.state) { // if location state falsy
      $('#locationStateAlert').show();
      error = true;
    }
    if (!inputLocation.zipcode) { // if location zipcode falsy
      $('#locationZipAlert').show();
      error = true;
    }
    if (!error) {
      var obj = new userLocation(inputLocation);
      obj.insertRecord(userLocation.merge);
      ldf.reset();
    }
  };

//tooltips

  // var $nfValidator = $('#nameForm').validate({
  //   debug: true,
  //   showErrors: function(errorMap, errorList) {
  //     console.log('got to showErrors.');
  //     $.each(this.validElements(), function (index, element) {
  //       var $element = $(element);
  //       $element.data('title', '')
  //       .removeClass('error')
  //       .tooltip('destroy');
  //     });
  //
  //     $.each(errorList, function (index, error) {
  //       var $element = $(error.element);
  //       $element.parent().addClass('has-error');
  //       $element.tooltip('destroy')
  //       .data('title', error.message)
  //       // .addClass('error')
  //       .tooltip();
  //     });
  //   },
  //   submitHandler: function(form) {
  //     alert('This is a valid form!');
  //   }
  // });

  formHandler.init();

  module.formHandler = formHandler;
})(window);
<|endoftext|>


<commit_before>/*globals define*/
define([
  'input',
  'physics/collision',
  'physics/intersection',
  'utils'
], function( Input, Collision, Intersection, Utils ) {
  'use strict';

  function Game() {
    this.prevTime = Date.now();
    this.currTime = this.prevTime;

    this.running = true;

    this.element = document.createElement( 'div' );
    this.canvas  = document.createElement( 'canvas' );
    this.ctx     = this.canvas.getContext( '2d' );

    this.element.appendChild( this.canvas );

    this.WIDTH  = 640;
    this.HEIGHT = 480;

    this.canvas.width  = this.WIDTH;
    this.canvas.height = this.HEIGHT;

    this.entities = [];
    this.player = null;

    this.level = null;

    this.input = new Input();
    this.input.game = this;
  }

  Game.instance = null;

  Game.prototype.update = function() {
    this.input.update();

    this.currTime = Date.now();
    var dt = this.currTime - this.prevTime;
    this.prevTime = this.currTime;

    if ( dt > 1e2 ) {
      dt = 1e2;
    }

    dt *= 1e-3;

    this.entities.forEach(function( entity ) {
      entity.update( dt );
    });

    Collision.broadphase( this.entities );
  };

  Game.prototype.draw = function() {
    var ctx = this.ctx;

    var level = this.level;
    if ( level.fill.alpha ) {
      ctx.fillStyle = level.fill.rgba();
      ctx.fillRect( 0, 0, ctx.canvas.width, ctx.canvas.height );
    } else {
      ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height );
    }

    this.entities.forEach(function( entity ) {
      entity.draw( ctx );
    });

    this.drawDebug();
  };

  Game.prototype.drawDebug = function() {
    var ctx = this.ctx;

    function isCircle( shape ) {
      return shape.type === 'Circle';
    }

    var circleEntities = this.entities.filter(function( entity ) {
      return entity.shapes.some( isCircle );
    });

    var x0 = 300,
        y0 = 250,
        x1 = 20,
        y1 = 200;

    // Draw line.
    ctx.beginPath();
    ctx.moveTo( x0, y0 );
    ctx.lineTo( x1, y1 );
    ctx.lineWidth = 2;
    ctx.strokeStyle = '#f00';
    ctx.stroke();

    // Draw normals.
    var mx = 0.5 * ( x0 + x1 ),
        my = 0.5 * ( y0 + y1 );

    var normal = Utils.lineNormal( x0, y0, x1, y1 );
    ctx.beginPath();
    ctx.moveTo( mx, my );
    ctx.lineTo( mx + normal.x * 10, my + normal.y * 10 );
    ctx.strokeStyle = '#0f0';
    ctx.stroke();

    // Get intersection points.
    var points = circleEntities.map(function( circleEntity ) {
      var x = circleEntity.x,
          y = circleEntity.y;

      var circles = circleEntity.shapes.filter( isCircle );

      var intersections = circles.map(function( circle ) {
        return Intersection.segmentCircleIntersection( x0, y0, x1, y1, circle.x + x, circle.y + y, circle.radius );
      })[0];

      var xi = 0, yi = 0;
      intersections.forEach(function( intersection, index, array ) {
        xi += intersection.x / array.length;
        yi += intersection.y / array.length;
      });

      if ( intersections.length ) {
        ctx.beginPath();
        ctx.rect( xi - 6, yi - 6, 12, 12 );
        ctx.fillStyle = '#f00';
        ctx.fill();

        var dx = xi - circleEntity.x,
            dy = yi - circleEntity.y;
        var distance = Math.sqrt( dx * dx + dy * dy );

        var moveDistance = circleEntity.shapes[0].radius - distance;
        if ( moveDistance >= 0 ) {
          circleEntity.x += moveDistance * normal.x;
          circleEntity.y += moveDistance * normal.y;
        }
      }

      return intersections;
    }).reduce(function( array, points ) {
      return array.concat( points );
    }, [] );

    // Draw intersection points.
    points.forEach(function( point ) {
      ctx.beginPath();
      ctx.rect( point.x - 5, point.y - 5, 10, 10 );
      ctx.fillStyle = '#0f0';
      ctx.fill();
    });
  };

  Game.prototype.tick = function() {
    if ( !this.running ) {
      return;
    }

    this.update();
    this.draw();

    window.requestAnimationFrame( this.tick.bind( this ) );
  };

  Game.prototype.add = function( entity ) {
    this.entities.push( entity );
    entity.world = this;
  };

  Game.prototype.remove = function( entity ) {
    var index = this.entities.indexOf( entity );
    if ( index !== -1 ) {
      this.entities.splice( index, 1 );
      entity.world = null;
    }
  };

  return Game;
});
<commit_msg>Test multiple edges chained together.<commit_after>/*globals define*/
define([
  'input',
  'physics/collision',
  'physics/intersection',
  'utils'
], function( Input, Collision, Intersection, Utils ) {
  'use strict';

  function Game() {
    this.prevTime = Date.now();
    this.currTime = this.prevTime;

    this.running = true;

    this.element = document.createElement( 'div' );
    this.canvas  = document.createElement( 'canvas' );
    this.ctx     = this.canvas.getContext( '2d' );

    this.element.appendChild( this.canvas );

    this.WIDTH  = 640;
    this.HEIGHT = 480;

    this.canvas.width  = this.WIDTH;
    this.canvas.height = this.HEIGHT;

    this.entities = [];
    this.player = null;

    this.level = null;

    this.input = new Input();
    this.input.game = this;
  }

  Game.instance = null;

  Game.prototype.update = function() {
    this.input.update();

    this.currTime = Date.now();
    var dt = this.currTime - this.prevTime;
    this.prevTime = this.currTime;

    if ( dt > 1e2 ) {
      dt = 1e2;
    }

    dt *= 1e-3;

    this.entities.forEach(function( entity ) {
      entity.update( dt );
    });

    Collision.broadphase( this.entities );
  };

  Game.prototype.draw = function() {
    var ctx = this.ctx;

    var level = this.level;
    if ( level.fill.alpha ) {
      ctx.fillStyle = level.fill.rgba();
      ctx.fillRect( 0, 0, ctx.canvas.width, ctx.canvas.height );
    } else {
      ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height );
    }

    this.entities.forEach(function( entity ) {
      entity.draw( ctx );
    });

    this.drawDebug();
  };

  Game.prototype.drawDebug = function() {
    var ctx = this.ctx;

    function isCircle( shape ) {
      return shape.type === 'Circle';
    }

    var circleEntities = this.entities.filter(function( entity ) {
      return entity.shapes.some( isCircle );
    });

    var segments = [
      [ 500, 150, 300, 250 ],
      [ 300, 250,  20, 200 ]
    ];

    segments.forEach(function( segment ) {
      var x0 = segment[0],
          y0 = segment[1],
          x1 = segment[2],
          y1 = segment[3];

      // Draw segment.
      ctx.beginPath();
      ctx.moveTo( x0, y0 );
      ctx.lineTo( x1, y1 );
      ctx.lineWidth = 2;
      ctx.strokeStyle = '#f00';
      ctx.stroke();

      // Draw normals.
      var mx = 0.5 * ( x0 + x1 ),
          my = 0.5 * ( y0 + y1 );

      var normal = Utils.lineNormal( x0, y0, x1, y1 );
      ctx.beginPath();
      ctx.moveTo( mx, my );
      ctx.lineTo( mx + normal.x * 10, my + normal.y * 10 );
      ctx.strokeStyle = '#0f0';
      ctx.stroke();

      // Get intersection points.
      var points = circleEntities.map(function( circleEntity ) {
        var x = circleEntity.x,
            y = circleEntity.y;

        var circles = circleEntity.shapes.filter( isCircle );

        var intersections = circles.map(function( circle ) {
          return Intersection.segmentCircleIntersection( x0, y0, x1, y1, circle.x + x, circle.y + y, circle.radius );
        })[0];

        var xi = 0, yi = 0;
        intersections.forEach(function( intersection, index, array ) {
          xi += intersection.x / array.length;
          yi += intersection.y / array.length;
        });

        if ( intersections.length ) {
          ctx.beginPath();
          ctx.rect( xi - 6, yi - 6, 12, 12 );
          ctx.fillStyle = '#f00';
          ctx.fill();

          var dx = xi - circleEntity.x,
              dy = yi - circleEntity.y;
          var distance = Math.sqrt( dx * dx + dy * dy );

          var moveDistance = circleEntity.shapes[0].radius - distance;
          if ( moveDistance > 0 ) {
            circleEntity.x += moveDistance * normal.x;
            circleEntity.y += moveDistance * normal.y;
          }
        }

        return intersections;
      }).reduce(function( array, points ) {
        return array.concat( points );
      }, [] );

      // Draw intersection points.
      points.forEach(function( point ) {
        ctx.beginPath();
        ctx.rect( point.x - 5, point.y - 5, 10, 10 );
        ctx.fillStyle = '#0f0';
        ctx.fill();
      });
    });
  };

  Game.prototype.tick = function() {
    if ( !this.running ) {
      return;
    }

    this.update();
    this.draw();

    window.requestAnimationFrame( this.tick.bind( this ) );
  };

  Game.prototype.add = function( entity ) {
    this.entities.push( entity );
    entity.world = this;
  };

  Game.prototype.remove = function( entity ) {
    var index = this.entities.indexOf( entity );
    if ( index !== -1 ) {
      this.entities.splice( index, 1 );
      entity.world = null;
    }
  };

  return Game;
});
<|endoftext|>


<commit_before>var Drac = {};
Drac.MainGame = function(game) {};
Drac.MainGame.prototype = {
    preload: function() {
        this.load.image
    }
}<commit_msg>Removing unnecessary Drac init from top of file<commit_after>Drac.MainGame = function(game) {};
Drac.MainGame.prototype = {
    preload: function() {
        this.load.image
    }
}<|endoftext|>


<commit_before>(Phaser => {
  const GAME_WIDTH = 460;
  const GAME_HEIGHT = 600;
  const GAME_CONTAINER_ID = 'game';
  const GFX = 'gfx';
  const INITIAL_MOVESPEED = 4;
  const PLAYER_BULLET_SPEED = 6;
  let cursors;
  let player;
  let playerBullets;

  const preload = _ => {
    game.load.spritesheet(GFX, 'assets/shmup-spritesheet-140x56-28x28-tile.png', 28, 28);
  };

  const handlePlayerFire = _ => {
    playerBullets.add( game.add.sprite(player.x, player.y, GFX, 7) );
  };

  const create = _ => {
    cursors = game.input.keyboard.createCursorKeys();
    cursors.fire = game.input.keyboard.addKey(Phaser.KeyCode.SPACEBAR);
    cursors.fire.onUp.add( handlePlayerFire );

    player = game.add.sprite(100, 100, GFX, 8);
    player.moveSpeed = INITIAL_MOVESPEED;
    playerBullets = game.add.group();
  };

  const handlePlayerMovement = _ => {
    let movingH = Math.sqrt(2);
    let movingV = Math.sqrt(2);
    if( cursors.up.isDown || cursors.down.isDown){
      movingH = 1; // slow down diagonal movement
    }
    if( cursors.left.isDown || cursors.right.isDown){
      movingV = 1; // slow down diagonal movement
    }
    switch( true ){
      case cursors.left.isDown:
        player.x -= player.moveSpeed * movingH;
        break;
      case cursors.right.isDown:
        player.x += player.moveSpeed * movingH;
        break;
    }
    switch( true ){
      case cursors.down.isDown:
        player.y += player.moveSpeed * movingV;
        break;
      case cursors.up.isDown:
        player.y -= player.moveSpeed * movingV;
        break;
    }
  };

  const handleBulletAnimations = _ => {
    playerBullets.children.forEach( bullet => bullet.y -= PLAYER_BULLET_SPEED );
  };

  const cleanup = _ => {
    playerBullets.children
      .filter( bullet => bullet.y < 0 )
      .forEach( bullet => bullet.destroy() );
  };

  const update = _ => {
    handlePlayerMovement();
    handleBulletAnimations();

    cleanup();
  };

  const game = new Phaser.Game(GAME_WIDTH, GAME_HEIGHT, Phaser.AUTO, GAME_CONTAINER_ID, { preload, create, update });

})(window.Phaser);
<commit_msg>randomly spawn enemies<commit_after>(Phaser => {
  const GAME_WIDTH = 460;
  const GAME_HEIGHT = 600;
  const GAME_CONTAINER_ID = 'game';
  const GFX = 'gfx';
  const INITIAL_MOVESPEED = 4;
  const PLAYER_BULLET_SPEED = 6;
  const ENEMY_SPAWN_FREQ = 100; // higher is less frequent
  const ENEMY_SPEED = 4.5;
  let cursors;
  let player;
  let playerBullets;
  let enemies;

  const preload = _ => {
    game.load.spritesheet(GFX, 'assets/shmup-spritesheet-140x56-28x28-tile.png', 28, 28);
  };

  const handlePlayerFire = _ => {
    playerBullets.add( game.add.sprite(player.x, player.y, GFX, 7) );
  };

  const create = _ => {
    cursors = game.input.keyboard.createCursorKeys();
    cursors.fire = game.input.keyboard.addKey(Phaser.KeyCode.SPACEBAR);
    cursors.fire.onUp.add( handlePlayerFire );

    player = game.add.sprite(100, 100, GFX, 8);
    player.moveSpeed = INITIAL_MOVESPEED;
    playerBullets = game.add.group();
    enemies = game.add.group();
  };

  const handlePlayerMovement = _ => {
    let movingH = Math.sqrt(2);
    let movingV = Math.sqrt(2);
    if( cursors.up.isDown || cursors.down.isDown){
      movingH = 1; // slow down diagonal movement
    }
    if( cursors.left.isDown || cursors.right.isDown){
      movingV = 1; // slow down diagonal movement
    }
    switch( true ){
      case cursors.left.isDown:
        player.x -= player.moveSpeed * movingH;
        break;
      case cursors.right.isDown:
        player.x += player.moveSpeed * movingH;
        break;
    }
    switch( true ){
      case cursors.down.isDown:
        player.y += player.moveSpeed * movingV;
        break;
      case cursors.up.isDown:
        player.y -= player.moveSpeed * movingV;
        break;
    }
  };

  const handleBulletAnimations = _ => {
    playerBullets.children.forEach( bullet => bullet.y -= PLAYER_BULLET_SPEED );
  };

  const handleEnemyActions = _ => {
    enemies.children.forEach( enemy => enemy.y += ENEMY_SPEED );
  };

  const randomlySpawnEnemy = _ => {
    if( Math.floor(Math.random()*ENEMY_SPAWN_FREQ) === 0 ){
      let randomX = Math.floor( Math.random()*GAME_WIDTH );
      enemies.add( game.add.sprite(randomX, -24, GFX, 0) );
    }
  };

  const cleanup = _ => {
    playerBullets.children
      .filter( bullet => bullet.y < 0 )
      .forEach( bullet => bullet.destroy() );
  };

  const update = _ => {
    handlePlayerMovement();
    handleBulletAnimations();
    handleEnemyActions();
    randomlySpawnEnemy();

    cleanup();
  };

  const game = new Phaser.Game(GAME_WIDTH, GAME_HEIGHT, Phaser.AUTO, GAME_CONTAINER_ID, { preload, create, update });

})(window.Phaser);
<|endoftext|>


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

var scale = 0;
var hiscore = window.localStorage.getItem("net.usebox.submarine.score")||0, score = 0;
var resources = {};

// some utils

function render_text(text) {
	var W = 6, H = 10;
	var map = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!?()@:/'., ";
	var c = document.createElement("canvas");
	c.width = text.length*W;
	c.height = H;
	var ctx = c.getContext("2d");

	ctx.clearRect(0, 0, c.width, c.height);
	for(var i=0; i<text.length; i++) {
		var index = map.indexOf(text.charAt(i));
		ctx.drawImage(resources["font"], index*W, 0, W, H, i*W, 0, W, H);
	}

	return c;
}

function no_smooth(ctx) {
	// avoid smooth-scaling
	var smoothing = ['imageSmoothingEnabled', 'mozImageSmoothingEnabled', 'webkitImageSmoothingEnabled'];
	smoothing.every(function(element, index, array) {
		if(ctx[element]) {
			ctx[element] = false;
			return false;
		}
		return true;
	});
};

function draw_frame(ctx, base, frame, x, y) {
	ctx.drawImage(base, frame*32, 0, 32, 32, Math.floor(x), Math.floor(y), 32, 32);
}

var Loader = function(width, height, cb_done) {
	var self = {
		width: width,
		height: height,
		cb_done: cb_done,
		count: 0,
		total: 4
	};

	self.init = function() {
		var src = {
			sub: "img/submarine.png",
			wline: "img/water-line.png",
			title: "img/title.png",
			font: "img/font.png"
		};

		for(s in src) {
			resources[s] = new Image();
			resources[s].src = src[s];
			resources[s].onload = function() { self.count++; if(self.count == self.total) { self.cb_done(); }};
		}
	};

	self.draw = function(ctx) {
		ctx.save();
		ctx.fillStyle = "rgb(66, 66, 66)";
		ctx.fillRect(20, Math.floor(self.height/2)-5, self.width-40, 10);
		ctx.fillStyle = "rgb(0, 0, 128)";
		ctx.fillRect(21, Math.floor(self.height/2)-4, Math.floor((self.count*(self.width-42))/self.total), 8);
		ctx.restore();
	};

	self.init();
	return self;
};

// main game object

var Game = function(id) {
	var self = {
		id : id,
		canvas : undefined,
		ctx : undefined,
		buffer : undefined,
		bctx : undefined,

		width : 240,
		height : 240,

		state: "loading",
		paused : false,

		delay : 0,

		then : 0
	};

	self.init = function() {
		self.canvas = document.getElementById(self.id);
		if(!self.canvas.getContext) {
			self.canvas.insertAdjacentHTML("afterend", "
This game requires canvas 2D support in your browser :(
");
			return undefined;
		}

		self.canvas.style.background = "rgb(33, 22, 64)";

		self.buffer = document.createElement("canvas");
		self.buffer.width = self.width;
		self.buffer.height = self.height;
		self.buffer.style.background = "rgb(33, 22, 64)";

		self.ctx = self.canvas.getContext("2d");
		self.bctx = self.buffer.getContext("2d");

		// requires self.ctx!
		self.onresize();

		document.addEventListener("keydown", self.key_down, false);
		document.addEventListener("keyup", self.key_up, false);

		window.onresize = self.onresize;

		self.loader = Loader(self.width, self.height, self.loading_done);

		return self;
	};

	self.onresize = function() {
		var factor = window.innerHeight/self.height;
		scale = Math.floor(factor);
		self.canvas.width = self.width*scale;
		self.canvas.height = self.height*scale;

		// after scaling, smooth will be back!
		no_smooth(self.ctx);
	};

	self.loading_done = function() {
		resources["hi-score"] = render_text("hi-score: " + hiscore);
		resources["paused"] = render_text("P A U S E D");
		resources["resume"] = render_text("(press 'p' to resume)");
		resources["start"] = render_text("Press 's' to Start!");
		resources["how-to"] = render_text("(use the arrows to move, 'z' to fire)");
		resources["by"] = render_text("A game by @reidrac for LD 29");

		self.x = self.width/2-16;
		self.y = 165;

		self.state = "menu";
	};

	self.draw_menu = function(ctx) {
		ctx.drawImage(resources["title"], 0, 0);
		ctx.drawImage(resources["hi-score"], self.width/2-Math.floor(resources["hi-score"].width/2), 4);
		ctx.drawImage(resources["start"], self.width/2-Math.floor(resources["start"].width/2), 80);
		ctx.drawImage(resources["how-to"], self.width/2-Math.floor(resources["how-to"].width/2), 92);
		ctx.drawImage(resources["by"], self.width/2-Math.floor(resources["by"].width/2), self.height-16);
		draw_frame(ctx, resources["sub"], 0, self.x, self.y);
		draw_frame(ctx, resources["wline"], 0, self.width/2-16, 165);
	};

	self.draw_paused = function(ctx) {
		ctx.save();
		ctx.fillStyle = "rgba(66, 66, 66, 0.8)";
		ctx.fillRect(0, 0, self.width, self.height);
		ctx.drawImage(resources["paused"], self.width/2-Math.floor(resources["paused"].width/2), self.height/2-8);
		ctx.drawImage(resources["resume"], self.width/2-Math.floor(resources["resume"].width/2), self.height/2+8);
		ctx.restore();
	};

	self.draw = function() {
		self.bctx.clearRect(0, 0, self.width, self.height);

		switch(self.state) {
			case "loading":
				self.loader.draw(self.bctx);
			break;
			case "menu":
				// window.localStorage.setItem("net.usebox.submarine.score", score.toString());
				self.draw_menu(self.bctx);
			break;
			default:
				if(self.paused) {
					self.draw_paused(self.bctx);
				}
			break;
		};

		self.ctx.clearRect(0, 0, self.width*scale, self.height*scale);
		self.ctx.drawImage(self.buffer, 0, 0, self.width, self.height, 0, 0, self.width*scale, self.height*scale);
	};

	self.update = function(dt) {
		if(self.paused) {
			return;
		}

		switch(self.state) {
			case "loading":
			break;
			case "menu":
				self.delay += dt;
				if(self.delay > 1) {
					self.y = self.y == 165 ? 166 : 165;
					self.delay = 0;
				}
			break;
			default:
			break;
		};

	};

	self.loop = function(now) {
		var dt = Math.min(1000/60, now-self.then);
		self.update(dt/1000);
		self.draw();
		self.then = now;

		requestAnimationFrame(self.loop);
	};

	self.key_down = function(event) {
		switch(self.state) {
			case "loading":
			break;
			case "menu":
			break;
			default:
				if(event.keyCode == 80) {
					self.paused = !self.paused;
					return;
				}
			break;
		};
	};

	self.init();
	return self;
};

window.onload = function () {
	var game = Game("submarine");
	if(game != undefined) {
		game.loop();
	}
};

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

var scale = 0;
var hiscore = window.localStorage.getItem("net.usebox.submarine.score")||0, score = 0;
var resources = {};

// some utils

function render_text(text) {
	var W = 6, H = 10;
	var map = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!?()@:/'., ";
	var c = document.createElement("canvas");
	c.width = text.length*W;
	c.height = H;
	var ctx = c.getContext("2d");

	ctx.clearRect(0, 0, c.width, c.height);
	for(var i=0; i<text.length; i++) {
		var index = map.indexOf(text.charAt(i));
		if(index>=0) {
			ctx.drawImage(resources["font"], index*W, 0, W, H, i*W, 0, W, H);
		} else {
			console.log("ERROR: " + text.charAt(i) + " not in map, from: " + text);
		}
	}

	return c;
}

function no_smooth(ctx) {
	// avoid smooth-scaling
	var smoothing = ['imageSmoothingEnabled', 'mozImageSmoothingEnabled', 'webkitImageSmoothingEnabled'];
	smoothing.every(function(element, index, array) {
		if(ctx[element]) {
			ctx[element] = false;
			return false;
		}
		return true;
	});
};

function draw_frame(ctx, base, frame, x, y) {
	ctx.drawImage(base, frame*32, 0, 32, 32, Math.floor(x), Math.floor(y), 32, 32);
}

var Loader = function(width, height, cb_done) {
	var self = {
		width: width,
		height: height,
		cb_done: cb_done,
		count: 0,
		total: 4
	};

	self.init = function() {
		var src = {
			sub: "img/submarine.png",
			wline: "img/water-line.png",
			title: "img/title.png",
			font: "img/font.png"
		};

		for(s in src) {
			resources[s] = new Image();
			resources[s].src = src[s];
			resources[s].onload = function() { self.count++; if(self.count == self.total) { self.cb_done(); }};
		}
	};

	self.draw = function(ctx) {
		ctx.save();
		ctx.fillStyle = "rgb(66, 66, 66)";
		ctx.fillRect(20, Math.floor(self.height/2)-5, self.width-40, 10);
		ctx.fillStyle = "rgb(0, 0, 128)";
		ctx.fillRect(21, Math.floor(self.height/2)-4, Math.floor((self.count*(self.width-42))/self.total), 8);
		ctx.restore();
	};

	self.init();
	return self;
};

// main game object

var Game = function(id) {
	var self = {
		id : id,
		canvas : undefined,
		ctx : undefined,
		buffer : undefined,
		bctx : undefined,

		width : 240,
		height : 240,

		state: "loading",
		paused : false,

		delay : 0,

		dt : 0,
		then : 0
	};

	self.init = function() {
		self.canvas = document.getElementById(self.id);
		if(!self.canvas.getContext) {
			self.canvas.insertAdjacentHTML("afterend", "
This game requires canvas 2D support in your browser :(
");
			return undefined;
		}

		self.canvas.style.background = "rgb(33, 22, 64)";

		self.buffer = document.createElement("canvas");
		self.buffer.width = self.width;
		self.buffer.height = self.height;
		self.buffer.style.background = "rgb(33, 22, 64)";

		self.ctx = self.canvas.getContext("2d");
		self.bctx = self.buffer.getContext("2d");

		// requires self.ctx!
		self.onresize();

		document.addEventListener("keydown", self.key_down, false);
		document.addEventListener("keyup", self.key_up, false);

		window.onresize = self.onresize;

		self.loader = Loader(self.width, self.height, self.loading_done);

		return self;
	};

	self.onresize = function() {
		var factor = window.innerHeight/self.height;
		scale = Math.floor(factor);
		self.canvas.width = self.width*scale;
		self.canvas.height = self.height*scale;

		// after scaling, smooth will be back!
		no_smooth(self.ctx);
	};

	self.loading_done = function() {
		resources["hi-score"] = render_text("hi score: " + hiscore);
		resources["paused"] = render_text("P A U S E D");
		resources["resume"] = render_text("(press 'p' to resume)");
		resources["start"] = render_text("Press 's' to Start!");
		resources["how-to"] = render_text("(use the arrows to move, 'z' to fire)");
		resources["by"] = render_text("A game by @reidrac for LD 29");

		self.x = self.width/2-16;
		self.y = 165;

		self.state = "menu";
	};

	self.draw_menu = function(ctx, no_transition) {
		ctx.drawImage(resources["title"], 0, 0);
		ctx.drawImage(resources["hi-score"], self.width/2-Math.floor(resources["hi-score"].width/2), 4);
		ctx.drawImage(resources["start"], self.width/2-Math.floor(resources["start"].width/2), 80);
		ctx.drawImage(resources["how-to"], self.width/2-Math.floor(resources["how-to"].width/2), 92);
		ctx.drawImage(resources["by"], self.width/2-Math.floor(resources["by"].width/2), self.height-16);
		if(no_transition == undefined) {
			draw_frame(ctx, resources["sub"], 0, self.x, self.y);
			draw_frame(ctx, resources["wline"], 0, self.width/2-16, 165);
		}
	};

	self.draw_transition = function(ctx) {
		ctx.drawImage(resources["snapshot"], 0, 0, self.width, self.height, 0, Math.floor(self.trans_y), self.width, self.height);
		draw_frame(ctx, resources["sub"], 0, self.x, Math.floor(self.y));
	};

	self.draw_paused = function(ctx) {
		ctx.save();
		ctx.fillStyle = "rgba(66, 66, 66, 0.8)";
		ctx.fillRect(0, 0, self.width, self.height);
		ctx.drawImage(resources["paused"], self.width/2-Math.floor(resources["paused"].width/2), self.height/2-8);
		ctx.drawImage(resources["resume"], self.width/2-Math.floor(resources["resume"].width/2), self.height/2+8);
		ctx.restore();
	};

	self.draw = function() {
		self.bctx.clearRect(0, 0, self.width, self.height);

		switch(self.state) {
			case "loading":
				self.loader.draw(self.bctx);
			break;
			case "menu":
				// window.localStorage.setItem("net.usebox.submarine.score", score.toString());
				self.draw_menu(self.bctx);
			break;
			case "transition":
				self.draw_transition(self.bctx);
			break;
			case "play":
				draw_frame(self.bctx, resources["sub"], 0, self.x, self.y);
				if(self.paused) {
					self.draw_paused(self.bctx);
				}
			break;
			default:
			break;
		};

		self.ctx.clearRect(0, 0, self.width*scale, self.height*scale);
		self.ctx.drawImage(self.buffer, 0, 0, self.width, self.height, 0, 0, self.width*scale, self.height*scale);
	};

	self.update = function(dt) {
		if(self.paused) {
			return;
		}

		switch(self.state) {
			case "menu":
				self.delay += dt;
				if(self.delay > 1) {
					self.y = self.y == 165 ? 166 : 165;
					self.delay = 0;
				}
			break;
			case "transition":
				if(self.y > self.height/2) {
					self.y -= dt*60;
				}
				if(self.trans_y > -self.height) {
					self.trans_y -= dt*180;
				} else {
					self.y = Math.floor(self.y)
					self.state = "play";
				}
			default:
			break;
		};

	};

	self.loop = function(now) {
		self.dt += Math.min(1000/30, now-self.then)||0;
		while(self.dt >= 1000/80) {
			self.update(1/80);
			self.dt -= 1000/80;
		}
		self.draw();
		self.then = now;

		requestAnimationFrame(self.loop);
	};

	self.key_down = function(event) {
		switch(self.state) {
			default:
			break;
			case "menu":
				if(event.keyCode == 83) {
					var c = document.createElement("canvas");
					c.width = self.width;
					c.height = self.height;
					var ctx = c.getContext("2d");
					ctx.clearRect(0, 0, c.width, c.height);
					self.draw_menu(ctx, false);
					resources["snapshot"] = c;
					self.trans_y = 0;
					self.state = "transition";
				}
			break;
			case "play":
				if(event.keyCode == 80) {
					self.paused = !self.paused;
					return;
				}
			break;
		};
	};

	self.init();
	return self;
};

window.onload = function () {
	var game = Game("submarine");
	if(game != undefined) {
		game.loop();
	}
};

<|endoftext|>


<commit_before>class Dice extends React.Component {
  constructor() {
    super();
    this.state = {
    	value: '',
			input: decodeURIComponent(location.search.substring(5))
		};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  parseInput(input) {
    return input.split('\n\r').map(x => x.split('\n').filter(Boolean));
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ReactDOM.render(
  <Dice />,
  document.getElementById('root')
);<commit_msg>Fix random word generator<commit_after>class Dice extends React.Component {
  constructor() {
    super();
    this.state = {
    	value: '',
      words: this.parseInput(decodeURIComponent(location.search.substring(5))),
      div: document.createElement("div")
		};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  parseInput(input) {
    return input.split('\n\r').map(x => x.split('\n').filter(Boolean));
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  createChild(text) {
    var p = document.createElement("p");
    p.appendChild(document.createTextNode(text));
  return p;
  }

  handleSubmit() {
      var div = this.state.div;
      while (div.hasChildNodes()) {
        div.removeChild(div.lastChild);
      }
      var words = this.state.words;
      for(var i = 0; i < words.length; i++) {
        var random = words[i][Math.floor(Math.random()*(words.length-1))];
        div.appendChild(this.createChild(random));
      }
      document.body.appendChild(div);
  }

  render() {
    return (
      <div>
        <input type="button" value="Throw dice" onClick={this.handleSubmit}/>
      </div>
    );
  }
}

ReactDOM.render(
  <Dice />,
  document.getElementById('root')
);<|endoftext|>


<commit_before>var gameScreen = {
  width: 800,
  height: 600
};

var block = {
  width: 64,
  height: 32,
  blockPerRow: function() {
    return parseInt(gameScreen.width / this.width);
  }
};

var blocks;
var platform;
var ball;
var game = new Phaser.Game(gameScreen.width, gameScreen.height, Phaser.AUTO, '', { preload: preload, create: create, update: update });
var cursor;
var text;
var gameState = "start";

function preload() {
  game.load.image("blueBlock" , "assets/blueBlock.png");
  game.load.image("redBlock","assets/redBlock.png");
  game.load.image("greenBlock","assets/greenBlock.png");
  game.load.spritesheet("mediumPlatform","assets/mediumPlatform.png");
  game.load.spritesheet("redBall","assets/redBall.png");
}

function create() {
  game.physics.startSystem(Phaser.Physics.ARCADE);
  cursor = game.input.keyboard.createCursorKeys();

  blocks = game.add.group();
  blocks.enableBody = true;
  blocks.physicsBodyType = Phaser.Physics.ARCADE;

  var style = { font: "bold 32px Arial", fill: "#fff", boundsAlignH: "center", boundsAlignV: "middle" };
  text = game.add.text(0, 250, "Click on the screen to start the game", style);

  text.setShadow(3, 3, 'rgba(0,0,0,0.5)', 2);

  //  We'll set the bounds to be from x0, y100 and be 800px wide by 100px high
  text.setTextBounds(0, 100, 800, 100);

  ball = game.add.sprite(71.5,410,"redBall");
  platform = game.add.sprite(20,436,"mediumPlatform");

  game.physics.arcade.enable([ball,platform,blocks]);
  initBlock();

}

function update() {

    if(game.input.activePointer.isDown && gameState == "start"){
        text.setText("");
        startGame();
    }
    game.physics.arcade.collide(platform,ball);
    game.physics.arcade.collide(ball,blocks,destroyBlock,null,this)
    platform.body.velocity.x = 0;

    if(cursor.left.isDown){
      platform.body.velocity.x = -450;
    }else if(cursor.right.isDown){
      platform.body.velocity.x = 450;
    }

    if(ball.body.blocked.down === true){
      gameState = "finished";
      text.setText("You Lose! Click on the screen to restart the game!");
      finishGame();
    }else if (blocks.countLiving() == 0){
      gameState = "finished";
      text.setText("You Win!\n Click on the screen to restart the game!");
      finishGame();
    }
}

function startGame(){
  initPlatform();
  initBall();
}

function finishGame(){
  ball.kill();
  platform.kill();
}

function initBlock(){
  createBlocks("green",12,100);
}

function initPlatform(){
  platform.body.collideWorldBounds = true;
  platform.body.immovable = true;
}

function initBall(){
    ball.body.velocity.setTo(300, 300);
    ball.body.bounce.setTo(1);
    ball.body.collideWorldBounds = true;
}

function createBlocks(color,number,startHeight,distanceBetweenRow = block.height + 2 ){
  var height = startHeight;
  var width = 0;
  var blockPerRow = block.blockPerRow();
  for(var i = 1; i <= number ; i++){
      //Check if it need to create a new row
      if((i - 1) != 0  && ((i - 1) % blockPerRow) === 0){
        height += distanceBetweenRow;
        width = 0;
      }
      var b = game.add.sprite(width,height,color + "Block");
      blocks.add(b);
      b.body.immovable = true;
      width += (block.width + 2);
  }
}

function destroyBlock(ball,block){
  block.kill();
}
<commit_msg>Now, the player can restart the game<commit_after>var gameScreen = {
  width: 800,
  height: 600
};

var block = {
  width: 64,
  height: 32,
  blockPerRow: function() {
    return parseInt(gameScreen.width / this.width);
  }
};

var blocks;
var platform;
var ball;
var game = new Phaser.Game(gameScreen.width, gameScreen.height, Phaser.AUTO, '', { preload: preload, create: create, update: update });
var cursor;
var text;
var gameState = "start";

function preload() {
  game.load.image("blueBlock" , "assets/blueBlock.png");
  game.load.image("redBlock","assets/redBlock.png");
  game.load.image("greenBlock","assets/greenBlock.png");
  game.load.spritesheet("mediumPlatform","assets/mediumPlatform.png");
  game.load.spritesheet("redBall","assets/redBall.png");
}

function create() {
  game.physics.startSystem(Phaser.Physics.ARCADE);
  cursor = game.input.keyboard.createCursorKeys();

  blocks = game.add.group();
  blocks.enableBody = true;
  blocks.physicsBodyType = Phaser.Physics.ARCADE;

  var style = { font: "bold 32px Arial", fill: "#fff", boundsAlignH: "center", boundsAlignV: "middle" };
  text = game.add.text(0, 250, "Click on the screen to start the game", style);

  text.setShadow(3, 3, 'rgba(0,0,0,0.5)', 2);
  text.setTextBounds(0, 100, 800, 100);
  ball = game.add.sprite(71.5,410,"redBall");
  platform = game.add.sprite(20,436,"mediumPlatform");

  game.physics.arcade.enable([ball,platform,blocks]);
  initBlock();

}

function update() {

    if(game.input.activePointer.isDown && gameState === "start"){
        gameState = "started";
        startGame();
    }else if(game.input.activePointer.isDown && gameState === "finished"){
        gameState = "started";
        startGame();
    }

    game.physics.arcade.collide(platform,ball);
    game.physics.arcade.collide(ball,blocks,destroyBlock,null,this)
    platform.body.velocity.x = 0;

    if(cursor.left.isDown && gameState === "started"){
      platform.body.velocity.x = -450;
    }else if(cursor.right.isDown && gameState === "started"){
      platform.body.velocity.x = 450;
    }

    if(ball.body.blocked.down === true){
      gameState = "finished";
      text.setText("You Lose! Click on the screen to restart the game!");
      finishGame();
    }else if (blocks.countLiving() == 0){
      gameState = "finished";
      text.setText("You Win! Click on the screen to restart the game!");
      finishGame();
    }
}

function startGame(){
  text.setText("");
  initPlatform();
  initBall();
}

function finishGame(){
  ball.kill();
  platform.kill();
  ball = game.add.sprite(71.5,410,"redBall");
  platform = game.add.sprite(20,436,"mediumPlatform");

  game.physics.arcade.enable([ball,platform,blocks]);
  initBlock();
}

function initBlock(){
  createBlocks("green",12,100);
}

function initPlatform(){
  platform.body.collideWorldBounds = true;
  platform.body.immovable = true;
}

function initBall(){
    ball.body.velocity.setTo(300, 300);
    ball.body.bounce.setTo(1);
    ball.body.collideWorldBounds = true;
}

function createBlocks(color,number,startHeight,distanceBetweenRow = block.height + 2 ){
  var height = startHeight;
  var width = 0;
  var blockPerRow = block.blockPerRow();
  for(var i = 1; i <= number ; i++){
      //Check if it need to create a new row
      if((i - 1) != 0  && ((i - 1) % blockPerRow) === 0){
        height += distanceBetweenRow;
        width = 0;
      }
      var b = game.add.sprite(width,height,color + "Block");
      blocks.add(b);
      b.body.immovable = true;
      width += (block.width + 2);
  }
}

function destroyBlock(ball,block){
  block.kill();
}
<|endoftext|>