<commit_before>describe("About Functions", function() {

  it("should declare functions", function() {

    function add(a, b) {
      return a + b;
    }

    expect(add(1, 2)).toBe(FILL_ME_IN);
  });

  it("should know internal variables override outer variables", function () {
    var message = "Outer";

    function getMessage() {
      return message;
    }

    function overrideMessage() {
      var message = "Inner";
      return message;
    }

    expect(getMessage()).toBe(FILL_ME_IN);
    expect(overrideMessage()).toBe(FILL_ME_IN);
    expect(message).toBe(FILL_ME_IN);
  });

  it("should have lexical scoping", function () {
    var variable = "top-level";
    function parentfunction() {
        var variable = "local";
      function childfunction() {
          return variable;
      }
      return childfunction();
    }
    expect(parentfunction()).toBe(FILL_ME_IN);
  });

  it("should use lexical scoping to synthesise functions", function () {

    function makeIncreaseByFunction(increaseByAmount) {
      return function (numberToIncrease) {
        return numberToIncrease + increaseByAmount;
      };
    }

    var increaseBy3 = makeIncreaseByFunction(3);
    var increaseBy5 = makeIncreaseByFunction(5);

    expect(increaseBy3(10) + increaseBy5(10)).toBe(FILL_ME_IN);
  });

  it("should allow extra function arguments", function () {

    function returnFirstArg(firstArg) {
      return firstArg;
    }

    expect(returnFirstArg("first", "second", "third")).toBe(FILL_ME_IN);

    function returnSecondArg(firstArg, secondArg) {
      return secondArg;
    }

    expect(returnSecondArg("only give first arg")).toBe(FILL_ME_IN);

    function returnAllArgs() {
      var argsArray = [];
      for (var i = 0; i < arguments.length; i += 1) {
        argsArray.push(arguments[i]);
      }
      return argsArray.join(",");
    }

    expect(returnAllArgs("first", "second", "third")).toBe(FILL_ME_IN);
  });

  it("should pass functions as values", function () {

    var appendRules = function (name) {
      return name + " rules!";
    };

    var appendDoubleRules = function (name) {
      return name + " totally rules!";
    };

    var praiseSinger = { givePraise: appendRules };
    expect(praiseSinger.givePraise("John")).toBe(FILL_ME_IN);

    praiseSinger.givePraise = appendDoubleRules;
    expect(praiseSinger.givePraise("Mary")).toBe(FILL_ME_IN);

  });

  it("should use function body as a string", function () {
    var add = new Function("a", "b", "return a + b;");
    expect(add(1, 2)).toBe(FILL_ME_IN);

    var multiply = function (a, b) {
      //An internal comment
      return a * b;
    };
    expect(multiply.toString()).toBe(FILL_ME_IN);
  });
});
<commit_msg>"Finished AboutFunctions.js"<commit_after>describe("About Functions", function() {

  it("should declare functions", function() {

    function add(a, b) {
      return a + b;
    }

    expect(add(1, 2)).toBe(3);
  });

  it("should know internal variables override outer variables", function () {
    var message = "Outer";

    function getMessage() {
      return message;
    }

    function overrideMessage() {
      var message = "Inner";
      return message;
    }

    expect(getMessage()).toBe(message);
    expect(overrideMessage()).toBe("Inner");
    expect(message).toBe(message);
  });

  it("should have lexical scoping", function () {
    var variable = "top-level";
    function parentfunction() {
        var variable = "local";
      function childfunction() {
          return variable;
      }
      return childfunction();
    }
    expect(parentfunction()).toBe("local");
  });

  it("should use lexical scoping to synthesise functions", function () {

    function makeIncreaseByFunction(increaseByAmount) {
      return function (numberToIncrease) {
        return numberToIncrease + increaseByAmount;
      };
    }

    var increaseBy3 = makeIncreaseByFunction(3);
    var increaseBy5 = makeIncreaseByFunction(5);

    expect(increaseBy3(10) + increaseBy5(10)).toBe(28);
  });

  it("should allow extra function arguments", function () {

    function returnFirstArg(firstArg) {
      return firstArg;
    }

    expect(returnFirstArg("first", "second", "third")).toBe("first");

    function returnSecondArg(firstArg, secondArg) {
      return secondArg;
    }

    expect(returnSecondArg("only give first arg")).toBe(undefined);

    function returnAllArgs() {
      var argsArray = [];
      for (var i = 0; i < arguments.length; i += 1) {
        argsArray.push(arguments[i]);
      }
      return argsArray.join(",");
    }

    expect(returnAllArgs("first", "second", "third")).toBe("first,second,third");
  });

  it("should pass functions as values", function () {

    var appendRules = function (name) {
      return name + " rules!";
    };

    var appendDoubleRules = function (name) {
      return name + " totally rules!";
    };

    var praiseSinger = { givePraise: appendRules };
    expect(praiseSinger.givePraise("John")).toBe("John rules!");

    praiseSinger.givePraise = appendDoubleRules;
    expect(praiseSinger.givePraise("Mary")).toBe("Mary totally rules!");

  });

  it("should use function body as a string", function () {
    var add = new Function("a", "b", "return a + b;");
    expect(add(1, 2)).toBe(3);

    var multiply = function (a, b) {
      //An internal comment
      return a * b;
    };
    expect(multiply.toString()).toBe("function (a, b) {
      //An internal comment
      return a * b;
    }");
  });
});
<|endoftext|>


<commit_before>// Contact Form Scripts

$(function() {

    $("#gform input,#gform textarea").jqBootstrapValidation({
        preventSubmit: true,
        submitError: function($form, event, errors) {
            // additional error messages or events
        },
        submitSuccess: function($form, event) {
            event.preventDefault(); // prevent default submit behaviour
            // get values from FORM
            var name = $('input[name="entry.833710143"]').val();
            var email = $('input[name="#entry.1376413320"]').val();
            var message = $('textarea[name="entry.752045271"]').val();
            var firstName = name; // For Success/Failure Message
            // Check for white space in name for Success/Fail message
            if (firstName.indexOf(' ') >= 0) {
                firstName = name.split(' ').slice(0, -1).join(' ');
            }

            $.ajax({
                url: "https://docs.google.com/forms/d/e/1FAIpQLSc-ENYyT8tL53oSxCMH8al-h2ObLuhYf45QFrdimuDlCKJN_g/formResponse",
                data: {"entry.833710143" : name, "entry.1376413320" : email, "entry.752045271" : message},
				type: "POST",
				dataType: "html",
				statusCode: {
					0: function() {
						// Success message
						$('#success').html("
");
						$('#success > .alert-success').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×")
							.append("</button>");
						$('#success > .alert-success')
							.append("Your message has been sent. ");
						$('#success > .alert-success')
							.append('
');

						//clear all fields
						$('#gform').trigger("reset");
					},
					200: function() {
						// Fail message
						$('#success').html("
");
						$('#success > .alert-danger').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×")
							.append("</button>");
						$('#success > .alert-danger').append("Sorry " + firstName + ", there was an error sending the e-mail. Please try again!");
						$('#success > .alert-danger').append('
');
						//clear all fields
						$('#gform').trigger("reset");
					}
				}
            });
        },
        filter: function() {
            return $(this).is(":visible");
        },
    });

    $("a[data-toggle=\"tab\"]").click(function(e) {
        e.preventDefault();
        $(this).tab("show");
    });
});

/*When clicking on Full hide fail/success boxes */
$('#entry.833710143').focus(function() {
    $('#success').html('');
});
<commit_msg>Removed #<commit_after>// Contact Form Scripts

$(function() {

    $("#gform input,#gform textarea").jqBootstrapValidation({
        preventSubmit: true,
        submitError: function($form, event, errors) {
            // additional error messages or events
        },
        submitSuccess: function($form, event) {
            event.preventDefault(); // prevent default submit behaviour
            // get values from FORM
            var name = $('input[name="entry.833710143"]').val();
            var email = $('input[name="entry.1376413320"]').val();
            var message = $('textarea[name="entry.752045271"]').val();
            var firstName = name; // For Success/Failure Message
            // Check for white space in name for Success/Fail message
            if (firstName.indexOf(' ') >= 0) {
                firstName = name.split(' ').slice(0, -1).join(' ');
            }

            $.ajax({
                url: "https://docs.google.com/forms/d/e/1FAIpQLSc-ENYyT8tL53oSxCMH8al-h2ObLuhYf45QFrdimuDlCKJN_g/formResponse",
                data: {"entry.833710143" : name, "entry.1376413320" : email, "entry.752045271" : message},
				type: "POST",
				dataType: "html",
				statusCode: {
					0: function() {
						// Success message
						$('#success').html("
");
						$('#success > .alert-success').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×")
							.append("</button>");
						$('#success > .alert-success')
							.append("Your message has been sent. ");
						$('#success > .alert-success')
							.append('
');

						//clear all fields
						$('#gform').trigger("reset");
					},
					200: function() {
						// Fail message
						$('#success').html("
");
						$('#success > .alert-danger').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×")
							.append("</button>");
						$('#success > .alert-danger').append("Sorry " + firstName + ", there was an error sending the e-mail. Please try again!");
						$('#success > .alert-danger').append('
');
						//clear all fields
						$('#gform').trigger("reset");
					}
				}
            });
        },
        filter: function() {
            return $(this).is(":visible");
        },
    });

    $("a[data-toggle=\"tab\"]").click(function(e) {
        e.preventDefault();
        $(this).tab("show");
    });
});

/*When clicking on Full hide fail/success boxes */
$('#entry.833710143').focus(function() {
    $('#success').html('');
});
<|endoftext|>


<commit_before>describe("About Functions", function() {

  it("should declare functions", function() {

    function add(a, b) {
      return a + b;
    }

    expect(add(1, 2)).toBe(FILL_ME_IN);
  });

  it("should know internal variables override outer variables", function () {
    var message = "Outer";

    function getMessage() {
      return message;
    }

    function overrideMessage() {
      var message = "Inner";
      return message;
    }

    expect(getMessage()).toBe(FILL_ME_IN);
    expect(overrideMessage()).toBe(FILL_ME_IN);
    expect(message).toBe(FILL_ME_IN);
  });

  it("should have lexical scoping", function () {
    var variable = "top-level";
    function parentfunction() {
        var variable = "local";
      function childfunction() {
          return variable;
      }
      return childfunction();
    }
    expect(parentfunction()).toBe(FILL_ME_IN);
  });

  it("should use lexical scoping to synthesise functions", function () {

    function makeIncreaseByFunction(increaseByAmount) {
      return function (numberToIncrease) {
        return numberToIncrease + increaseByAmount;
      };
    }

    var increaseBy3 = makeIncreaseByFunction(3);
    var increaseBy5 = makeIncreaseByFunction(5);

    expect(increaseBy3(10) + increaseBy5(10)).toBe(FILL_ME_IN);
  });

  it("should allow extra function arguments", function () {

    function returnFirstArg(firstArg) {
      return firstArg;
    }

    expect(returnFirstArg("first", "second", "third")).toBe(FILL_ME_IN);

    function returnSecondArg(firstArg, secondArg) {
      return secondArg;
    }

    expect(returnSecondArg("only give first arg")).toBe(FILL_ME_IN);

    function returnAllArgs() {
      var argsArray = [];
      for (var i = 0; i < arguments.length; i += 1) {
        argsArray.push(arguments[i]);
      }
      return argsArray.join(",");
    }

    expect(returnAllArgs("first", "second", "third")).toBe(FILL_ME_IN);
  });

  it("should pass functions as values", function () {

    var appendRules = function (name) {
      return name + " rules!";
    };

    var appendDoubleRules = function (name) {
      return name + " totally rules!";
    };

    var praiseSinger = { givePraise: appendRules };
    expect(praiseSinger.givePraise("John")).toBe(FILL_ME_IN);

    praiseSinger.givePraise = appendDoubleRules;
    expect(praiseSinger.givePraise("Mary")).toBe(FILL_ME_IN);

  });

  it("should use function body as a string", function () {
    var add = new Function("a", "b", "return a + b;");
    expect(add(1, 2)).toBe(FILL_ME_IN);

    var multiply = function (a, b) {
      //An internal comment
      return a * b;
    };
    expect(multiply.toString()).toBe(FILL_ME_IN);
  });
});
<commit_msg>Functions Koans Enlightened, suggestions made to Zen Master<commit_after>describe("About Functions", function() {

  it("should declare functions", function() {

    function add(a, b) {
      return a + b;
    }

    expect(add(1, 2)).toBe(3);
  });

  it("should know internal variables override outer variables", function () {
    var message = "Outer";

    function getMessage() {
      return message;
    }

    function overrideMessage() {
      var message = "Inner";
      return message;
    }

    expect(getMessage()).toBe("Outer");
    expect(overrideMessage()).toBe("Inner");
    expect(message).toBe("Outer");
  });

  it("should have lexical scoping", function () {
    var variable = "top-level";
    function parentfunction() {
        var variable = "local";
      function childfunction() {
          return variable;
      }
      return childfunction();
    }
    expect(parentfunction()).toBe('local');
  });

  it("should use lexical scoping to synthesise functions", function () {

    function makeIncreaseByFunction(increaseByAmount) {
      return function (numberToIncrease) {
        return numberToIncrease + increaseByAmount;
      };
    }

    var increaseBy3 = makeIncreaseByFunction(3);
    var increaseBy5 = makeIncreaseByFunction(5);

    expect(increaseBy3(10) + increaseBy5(10)).toBe(28);

    /* this would make a great expect statement to improve understanding */
    /* when a function returns a function, and both are called in sequence as below, */
    	/* the original function's arguments are available in the second call */
    /* expect(makeIncreaseByFunction(3)(10)).toBe(13); */
  });

  it("should allow extra function arguments", function () {

    function returnFirstArg(firstArg) {
      return firstArg;
    }

    expect(returnFirstArg("first", "second", "third")).toBe('first');

    function returnSecondArg(firstArg, secondArg) {
      return secondArg;
    }

    expect(returnSecondArg("only give first arg")).toBe(undefined);

    function returnAllArgs() {
      var argsArray = [];
      for (var i = 0; i < arguments.length; i += 1) {
        argsArray.push(arguments[i]);
      }
      return argsArray.join(",");
    }

    expect(returnAllArgs("first", "second", "third")).toBe("first,second,third");
  });

  it("should pass functions as values", function () {

    var appendRules = function (name) {
      return name + " rules!";
    };

    var appendDoubleRules = function (name) {
      return name + " totally rules!";
    };

    var praiseSinger = { givePraise: appendRules };
    expect(praiseSinger.givePraise("John")).toBe("John rules!");

    praiseSinger.givePraise = appendDoubleRules;
    expect(praiseSinger.givePraise("Mary")).toBe("Mary totally rules!");

  });

  /* multi line text is a hassle in JS, there should be a warning! I just shrunk the function to fit on 1 line */
  it("should use function body as a string", function () {
    var add = new Function("a", "b", "return a + b;");
    expect(add(1, 2)).toBe(3);

    var multiply = function (a, b) {return a * b;};
    expect(multiply.toString()).toBe('function (a, b) {return a * b;}');
  });
});
<|endoftext|>


<commit_before>describe("About Functions", function() {

  it("should declare functions", function() {

    function add(a, b) {
      return a + b;
    }

    expect(add(1, 2)).toBe(FILL_ME_IN);
  });

  it("should know internal variables override outer variables", function () {
    var message = "Outer";

    function getMessage() {
      return message;
    }

    function overrideMessage() {
      var message = "Inner";
      return message;
    }

    expect(getMessage()).toBe(FILL_ME_IN);
    expect(overrideMessage()).toBe(FILL_ME_IN);
    expect(message).toBe(FILL_ME_IN);
  });

  it("should have lexical scoping", function () {
    var variable = "top-level";
    function parentfunction() {
        var variable = "local";
      function childfunction() {
          return variable;
      }
      return childfunction();
    }
    expect(parentfunction()).toBe(FILL_ME_IN);
  });

  it("should use lexical scoping to synthesise functions", function () {

    function makeIncreaseByFunction(increaseByAmount) {
      return function (numberToIncrease) {
        return numberToIncrease + increaseByAmount;
      };
    }

    var increaseBy3 = makeIncreaseByFunction(3);
    var increaseBy5 = makeIncreaseByFunction(5);

    expect(increaseBy3(10) + increaseBy5(10)).toBe(FILL_ME_IN);
  });

  it("should allow extra function arguments", function () {

    function returnFirstArg(firstArg) {
      return firstArg;
    }

    expect(returnFirstArg("first", "second", "third")).toBe(FILL_ME_IN);

    function returnSecondArg(firstArg, secondArg) {
      return secondArg;
    }

    expect(returnSecondArg("only give first arg")).toBe(FILL_ME_IN);

    function returnAllArgs() {
      var argsArray = [];
      for (var i = 0; i < arguments.length; i += 1) {
        argsArray.push(arguments[i]);
      }
      return argsArray.join(",");
    }

    expect(returnAllArgs("first", "second", "third")).toBe(FILL_ME_IN);
  });

  it("should pass functions as values", function () {

    var appendRules = function (name) {
      return name + " rules!";
    };

    var appendDoubleRules = function (name) {
      return name + " totally rules!";
    };

    var praiseSinger = { givePraise: appendRules };
    expect(praiseSinger.givePraise("John")).toBe(FILL_ME_IN);

    praiseSinger.givePraise = appendDoubleRules;
    expect(praiseSinger.givePraise("Mary")).toBe(FILL_ME_IN);

  });

  it("should use function body as a string", function () {
    var add = new Function("a", "b", "return a + b;");
    expect(add(1, 2)).toBe(FILL_ME_IN);

    var multiply = function (a, b) {
      //An internal comment
      return a * b;
    };
    expect(multiply.toString()).toBe(FILL_ME_IN);
  });
});
<commit_msg>Completed About Functions<commit_after>describe("About Functions", function() {

  it("should declare functions", function() {

    function add(a, b) {
      return a + b;
    }

    expect(add(1, 2)).toBe(3);
  });

  it("should know internal variables override outer variables", function () {
    var message = "Outer";

    function getMessage() {
      return message;
    }

    function overrideMessage() {
      var message = "Inner";
      return message;
    }

    expect(getMessage()).toBe("Outer");
    expect(overrideMessage()).toBe("Inner");
    expect(message).toBe("Outer");
  });

  it("should have lexical scoping", function () {
    var variable = "top-level";
    function parentfunction() {
        var variable = "local";
      function childfunction() {
          return variable;
      }
      return childfunction();
    }
    expect(parentfunction()).toBe("local");
  });

  it("should use lexical scoping to synthesise functions", function () {

    function makeIncreaseByFunction(increaseByAmount) {
      return function (numberToIncrease) {
        return numberToIncrease + increaseByAmount;
      };
    }

    var increaseBy3 = makeIncreaseByFunction(3);
    var increaseBy5 = makeIncreaseByFunction(5);

    expect(increaseBy3(10) + increaseBy5(10)).toBe(28);
  });

  it("should allow extra function arguments", function () {

    function returnFirstArg(firstArg) {
      return firstArg;
    }

    expect(returnFirstArg("first", "second", "third")).toBe("first");

    function returnSecondArg(firstArg, secondArg) {
      return secondArg;
    }

    expect(returnSecondArg("only give first arg")).toBe(undefined);

    function returnAllArgs() {
      var argsArray = [];
      for (var i = 0; i < arguments.length; i += 1) {
        argsArray.push(arguments[i]);
      }
      return argsArray.join(",");
    }

    expect(returnAllArgs("first", "second", "third")).toBe("first,second,third");
  });

  it("should pass functions as values", function () {

    var appendRules = function (name) {
      return name + " rules!";
    };

    var appendDoubleRules = function (name) {
      return name + " totally rules!";
    };

    var praiseSinger = { givePraise: appendRules };
    expect(praiseSinger.givePraise("John")).toBe("John rules!");

    praiseSinger.givePraise = appendDoubleRules;
    expect(praiseSinger.givePraise("Mary")).toBe("Mary totally rules!");

  });

  it("should use function body as a string", function () {
    var add = new Function("a", "b", "return a + b;");
    expect(add(1, 2)).toBe(3);

    var multiply = function (a, b) {
      //An internal comment
      return a * b;
    };
    expect(multiply.toString()).toBe('function (a, b) {
      //An internal comment
      return a * b;
    }');
  });
});
<|endoftext|>


<commit_before>$(function() {

	$("input,textarea").jqBootstrapValidation({
		preventSubmit : true,
		submitError : function($form, event, errors) {
			// additional error messages or events
		},
		submitSuccess : function($form, event) {
			event.preventDefault();
			// prevent default submit behaviour
			// get values from FORM
			var name = $("input#name").val();
			var email = $("input#email").val();
			var phone = $("input#phone").val();
			var message = $("textarea#message").val();
			var firstName = name;
			// For Success/Failure Message
			// Check for white space in name for Success/Fail message
			if (firstName.indexOf(' ') >= 0) {
				firstName = name.split(' ').slice(0, -1).join(' ');
			}
			var formData = $('#contactForm').serialize();
			$.ajax({
				//url: "././mail/contact_me.php",
				url : "//formspree.io/yimintsai@gmail.com",
				method : "POST",
				data : formData,
				/*
				data : {
					name : name,
					phone : phone,
					email : email,
					message : message
				},
				*/
				dataType : "json",
				cache : false,
				success : function() {
					// Success message
					$('#success').html("
");
					$('#success > .alert-success').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×").append("</button>");
					$('#success > .alert-success').append("Your message has been sent. ");
					$('#success > .alert-success').append('
');

					//clear all fields
					$('#contactForm').trigger("reset");
				},
				error : function() {
					// Fail message
					$('#success').html("
");
					$('#success > .alert-danger').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×").append("</button>");
					$('#success > .alert-danger').append("Sorry " + firstName + ", it seems that my mail server is not responding. Please try again later!");
					$('#success > .alert-danger').append('
');
					//clear all fields
					$('#contactForm').trigger("reset");
				},
			})

		},
		filter : function() {
			return $(this).is(":visible");
		},
	});

	$("a[data-toggle=\"tab\"]").click(function(e) {
		e.preventDefault();
		$(this).tab("show");
	});
});

/*When clicking on Full hide fail/success boxes */
$('#name').focus(function() {
	$('#success').html('');
});
<commit_msg>Do not use serialize<commit_after>$(function() {

	$("input,textarea").jqBootstrapValidation({
		preventSubmit : true,
		submitError : function($form, event, errors) {
			// additional error messages or events
		},
		submitSuccess : function($form, event) {
			event.preventDefault();
			// prevent default submit behaviour
			// get values from FORM
			var name = $("input#name").val();
			var email = $("input#email").val();
			var phone = $("input#phone").val();
            var subject = $("input#subject").val();
			var message = $("textarea#message").val();
			var firstName = name;
			// For Success/Failure Message
			// Check for white space in name for Success/Fail message
			if (firstName.indexOf(' ') >= 0) {
				firstName = name.split(' ').slice(0, -1).join(' ');
			}
			//var formData = $('#contactForm').serialize();
			$.ajax({
				//url: "././mail/contact_me.php",
				url : "//formspree.io/yimintsai@gmail.com",
				method : "POST",
				//data : formData,
				data : {
					name : name,
					phone : phone,
					email : email,
                    subject : subject,
					message : message
				},
				dataType : "json",
				cache : false,
				success : function() {
					// Success message
					$('#success').html("
");
					$('#success > .alert-success').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×").append("</button>");
					$('#success > .alert-success').append("Your message has been sent. ");
					$('#success > .alert-success').append('
');

					//clear all fields
					$('#contactForm').trigger("reset");
				},
				error : function() {
					// Fail message
					$('#success').html("
");
					$('#success > .alert-danger').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×").append("</button>");
					$('#success > .alert-danger').append("Sorry " + firstName + ", it seems that my mail server is not responding. Please try again later!");
					$('#success > .alert-danger').append('
');
					//clear all fields
					$('#contactForm').trigger("reset");
				},
			})

		},
		filter : function() {
			return $(this).is(":visible");
		},
	});

	$("a[data-toggle=\"tab\"]").click(function(e) {
		e.preventDefault();
		$(this).tab("show");
	});
});

/*When clicking on Full hide fail/success boxes */
$('#name').focus(function() {
	$('#success').html('');
});
<|endoftext|>


<commit_before>/*global updateCount x*/

/**
 * User interface connection to the simulation.
 * @constructor
 */
function Controller(particles) {
    this.particles = particles;
    this.obstacle = null;
    this.init();

    var _this = this,
        canvas = particles.igloo.gl.canvas;
    $(canvas).on('mousemove', function(event) {
        var coords = Controller.coords(event);
        _this.obstacle.position[0] = coords[0];
        _this.obstacle.position[1] = coords[1];
        _this.obstacle.enabled = true;
        particles.updateObstacles();
    });
    $(canvas).on('mouseout', function() {
        _this.obstacle.enabled = false;
        particles.updateObstacles();
    });
    $(canvas).on('mouseup', function(event) {
        if (event.which === 1) {
            var center = _this.obstacle.position,
            radius = _this.obstacle.size;
            particles.addObstacle(center.slice(0), radius);
            particles.updateObstacles();
        }
    });
    $(canvas).on('mousedown', function(event) {
        if (event.which === 2) {
            _this.clear();
            event.preventDefault();
            return false;
        } else {
            return true;
        }
    });
    $(window).on('keyup', function(event) {
        switch (event.which) {
        case 67: // c
            _this.clear();
            break;
        case 68: // d
            _this.adjust(2);
            break;
        case 72: // h
            _this.adjust(0.5);
            break;
        }
    });
    $('.controls .increase').on('click', function() {
        _this.adjust(2);
    });
    $('.controls .decrease').on('click', function() {
        _this.adjust(0.5);
    });
    $('.controls .clear').on('click', function() {
        _this.clear();
    });
}

/**
 * Create and capture the mouse obstacle.
 * @returns {Controller} this
 */
Controller.prototype.init = function() {
    this.obstacle = this.particles.addObstacle([0, 0], 20);
    this.obstacle.enabled = false;
    this.particles.updateObstacles();
    return this;
};

/**
 * Clear all obstacles.
 * @returns {Controller} this
 */
Controller.prototype.clear = function() {
    this.particles.obstacles.length = 0;
    this.init();
    return this;
};

/**
 * Immediately adjust the particle count.
 * @param {number} factor multiplies the particle count
 * @returns {Controller} this
 */
Controller.prototype.adjust = function(factor) {
    this.particles.setCount(this.particles.getCount() * factor);
    updateCount();
};

/**
 * @param {Object} event
 * @returns {Array} the simulation coodinates from the event
 */
Controller.coords = function(event) {
    var $target = $(event.target),
        offset = $target.offset(),
        border = 1,
        x = event.pageX - offset.left - border,
        y = $target.height() - (event.pageY - offset.top - border);
    return [x, y];
};
<commit_msg>Allow painting obstacles.<commit_after>/*global updateCount x*/

/**
 * User interface connection to the simulation.
 * @constructor
 */
function Controller(particles) {
    this.particles = particles;
    this.obstacle = null;
    this.init();
    this.mousedown = false;

    var _this = this,
        canvas = particles.igloo.gl.canvas;
    $(canvas).on('mousemove', function(event) {
        var coords = Controller.coords(event);
        _this.obstacle.position[0] = coords[0];
        _this.obstacle.position[1] = coords[1];
        _this.obstacle.enabled = true;
        particles.updateObstacles();
        if (_this.mousedown) _this.place();
    });
    $(canvas).on('mouseout', function() {
        _this.obstacle.enabled = false;
        particles.updateObstacles();
        _this.mousedown = false;
    });
    $(canvas).on('mousedown', function() {
        _this.mousedown = true;
    });
    $(canvas).on('mouseup', function(event) {
        if (event.which === 1) {
            _this.place();
            _this.mousedown = false;
        }
    });
    $(canvas).on('mousedown', function(event) {
        if (event.which === 2) {
            _this.clear();
            event.preventDefault();
            return false;
        } else {
            return true;
        }
    });
    $(window).on('keyup', function(event) {
        switch (event.which) {
        case 67: // c
            _this.clear();
            break;
        case 68: // d
            _this.adjust(2);
            break;
        case 72: // h
            _this.adjust(0.5);
            break;
        }
    });
    $('.controls .increase').on('click', function() {
        _this.adjust(2);
    });
    $('.controls .decrease').on('click', function() {
        _this.adjust(0.5);
    });
    $('.controls .clear').on('click', function() {
        _this.clear();
    });
}

/**
 * Create and capture the mouse obstacle.
 * @returns {Controller} this
 */
Controller.prototype.init = function() {
    this.obstacle = this.particles.addObstacle([0, 0], 20);
    this.obstacle.enabled = false;
    this.particles.updateObstacles();
    return this;
};

/**
 * Place a new obstacle at the mouse location.
 * @returns {Controller} this
 */
Controller.prototype.place = function() {
    var center = this.obstacle.position,
        radius = this.obstacle.size;
    this.particles.addObstacle(center.slice(0), radius);
    this.particles.updateObstacles();
    return this;
};

/**
 * Clear all obstacles.
 * @returns {Controller} this
 */
Controller.prototype.clear = function() {
    this.particles.obstacles.length = 0;
    this.init();
    return this;
};

/**
 * Immediately adjust the particle count.
 * @param {number} factor multiplies the particle count
 * @returns {Controller} this
 */
Controller.prototype.adjust = function(factor) {
    this.particles.setCount(this.particles.getCount() * factor);
    updateCount();
};

/**
 * @param {Object} event
 * @returns {Array} the simulation coodinates from the event
 */
Controller.coords = function(event) {
    var $target = $(event.target),
        offset = $target.offset(),
        border = 1,
        x = event.pageX - offset.left - border,
        y = $target.height() - (event.pageY - offset.top - border);
    return [x, y];
};
<|endoftext|>


<commit_before>(function (window) {
  'use strict';

  /**
   * Take a model and view and acts as the controller between them
   * @param {object} model The model instance
   * @param {object} view The view instance
   */
  var Controller = function (model, view) {
    var _self = this;
    _self.model = model;
    _self.view = view;
    _self.config = _self.view.config;

    /**
     * Show the selected section
     * @param {string} locationHash
     */
    this.setSection = function (locationHash) {
      var args = locationHash.split('/');
      args.shift();
      var section = args.shift();
      _self.view.render('section', _self.model, section, args);
    };

    /**
     * Insert data into the views
     */
    this.setData = function () {
      _self.view.render('chrome');
      _self.view.render('home', _self.model);
      _self.view.render('log', _self.model);
      _self.view.render('settings');
    };

    this.addItem = function (date) {
      var res = _self.model.add(date);
      if (res !== -1) {
        _self.setData();
      } else {
        _self.view.render('error', 'Error adding entry');
      }
      return res;
    };

    this.removeItem = function (id) {
      var res = _self.model.remove(id);
      if (res !== -1) {
        _self.setData();
      } else {
        _self.view.render('error', 'Error removing entry');
      }
      return res;
    };

    this.editItem = function (id, date) {
      var res = _self.model.edit(id, date);
      if (res !== -1) {
        _self.setData();
      } else {
        _self.view.render('error', 'Error editing entry');
      }
      return res;
    };

    this.removeAllItem = function () {
      _self.config.reset();
      _self.model.clear();
      _self.setData();
      _self.view.render('success', 'Data deleted successfully');
    };

    this.updateSettings = function (data) {
      _self.config.update(data);
      _self.model.calc();
      _self.setData();
    };

    // TODO clean
    this.importData = function (file) {
      if (!supported.fileReader) {
        throw 'not supported';
      }

      const reader = new FileReader();
      if (file) {
        reader.readAsText(file);
      }
      reader.addEventListener(
        'load',
        function () {
          const data = JSON.parse(reader.result);

          _self.model.update(data.periodTracker.list);
          _self.config.update(data.periodTracker.config);
          // update the ui
          _self.setData();
          _self.view.render('success', 'Data imported successfully');
        },
        false
      );
    };

    const prepareDataForExport = function () {
      const data = JSON.stringify({
        periodTracker: {
          version: version,
          list: _self.model.list,
          config: _self.config.getAll(),
        },
      });
      const now = moment().format('YYYY-MM-DD');
      const filename = 'period-tracker_' + now + '.txt';
      const type = 'text/plain';

      return { data, filename };
    };

    // TODO clean
    this.exportData = async function () {
      const { data, filename } = prepareDataForExport();

      if (!supported.showSaveFilePicker) {
        oldDownload(filename, data);
        return;
      }

      const options = {
        suggestedName: filename,
        types: [{ accept: { 'text/plain': ['.txt'] } }],
      };

      try {
        const fileHandle = await window.showSaveFilePicker(options);
        const writable = await fileHandle.createWritable();
        await writable.write(data);
        await writable.close();
      } catch (e) {
        // if the user doesn't save the file, swallow the relative browser error
      }
    };

    // TODO clean
    this.shareData = function () {
      const { data, filename } = prepareDataForExport();
      const file = new File([data], filename, { type: 'text/plain' });

      if (navigator.canShare && navigator.canShare({ files: [file] })) {
        navigator
          .share({
            files: [file],
            title: 'Dummy title',
            text: 'Some dummy text file',
          })
          .then(() => console.log('Share was successful.'))
          .catch((e) => {
            // if the user doesn't share the file, swallow the relative browser error
            // console.log('Sharing failed', e.message);
          });
      } else {
        _self.view.render(
          'error',
          'This functionality is not supported in your browser/os/device'
        );
      }
    };

    _self.view.bind('itemAdd', function (date) {
      return _self.addItem(date);
    });

    _self.view.bind('itemRemove', function (id) {
      return _self.removeItem(id);
    });

    _self.view.bind('itemEdit', function (id) {
      return _self.editItem(id);
    });

    _self.view.bind('importData', function (file) {
      return _self.importData(file);
    });

    _self.view.bind('exportData', function () {
      return _self.exportData();
    });

    _self.view.bind('shareData', function () {
      return _self.shareData();
    });

    _self.view.bind('itemRemoveAll', function () {
      return _self.removeAllItem();
    });

    _self.view.bind('settingsUpdate', function (data) {
      _self.updateSettings(data);
    });

    // _self.view.bind('alert', function() {
    // });
  };

  // export to window
  window.app = window.app || {};
  window.app.Controller = Controller;
})(window);
<commit_msg>Better share to functionality<commit_after>(function (window) {
  'use strict';

  /**
   * Take a model and view and acts as the controller between them
   * @param {object} model The model instance
   * @param {object} view The view instance
   */
  var Controller = function (model, view) {
    var _self = this;
    _self.model = model;
    _self.view = view;
    _self.config = _self.view.config;

    /**
     * Show the selected section
     * @param {string} locationHash
     */
    this.setSection = function (locationHash) {
      var args = locationHash.split('/');
      args.shift();
      var section = args.shift();
      _self.view.render('section', _self.model, section, args);
    };

    /**
     * Insert data into the views
     */
    this.setData = function () {
      _self.view.render('chrome');
      _self.view.render('home', _self.model);
      _self.view.render('log', _self.model);
      _self.view.render('settings');
    };

    this.addItem = function (date) {
      var res = _self.model.add(date);
      if (res !== -1) {
        _self.setData();
      } else {
        _self.view.render('error', 'Error adding entry');
      }
      return res;
    };

    this.removeItem = function (id) {
      var res = _self.model.remove(id);
      if (res !== -1) {
        _self.setData();
      } else {
        _self.view.render('error', 'Error removing entry');
      }
      return res;
    };

    this.editItem = function (id, date) {
      var res = _self.model.edit(id, date);
      if (res !== -1) {
        _self.setData();
      } else {
        _self.view.render('error', 'Error editing entry');
      }
      return res;
    };

    this.removeAllItem = function () {
      _self.config.reset();
      _self.model.clear();
      _self.setData();
      _self.view.render('success', 'Data deleted successfully');
    };

    this.updateSettings = function (data) {
      _self.config.update(data);
      _self.model.calc();
      _self.setData();
    };

    // TODO clean
    this.importData = function (file) {
      if (!supported.fileReader) {
        throw 'not supported';
      }

      const reader = new FileReader();
      if (file) {
        reader.readAsText(file);
      }
      reader.addEventListener(
        'load',
        function () {
          const data = JSON.parse(reader.result);

          _self.model.update(data.periodTracker.list);
          _self.config.update(data.periodTracker.config);
          // update the ui
          _self.setData();
          _self.view.render('success', 'Data imported successfully');
        },
        false
      );
    };

    const prepareDataForExport = function () {
      const data = JSON.stringify({
        periodTracker: {
          version: version,
          list: _self.model.list,
          config: _self.config.getAll(),
        },
      });
      const now = moment().format('YYYY-MM-DD');
      const filename = 'period-tracker_' + now + '.txt';
      const title = 'Period Tracker Backup ' + now;

      return { data, filename, title };
    };

    // TODO clean
    this.exportData = async function () {
      const { data, filename } = prepareDataForExport();

      if (!supported.showSaveFilePicker) {
        oldDownload(filename, data);
        return;
      }

      const options = {
        suggestedName: filename,
        types: [{ accept: { 'text/plain': ['.txt'] } }],
      };

      try {
        const fileHandle = await window.showSaveFilePicker(options);
        const writable = await fileHandle.createWritable();
        await writable.write(data);
        await writable.close();
      } catch (e) {
        // if the user doesn't save the file, swallow the relative browser error
      }
    };

    // TODO clean
    this.shareData = function () {
      const { data, filename, title } = prepareDataForExport();
      const file = new File([data], filename, { type: 'text/plain' });

      if (navigator.canShare && navigator.canShare({ files: [file] })) {
        navigator
          .share({
            title: title,
            files: [file],
          })
          .then(() => {
            // console.log('Share was successful.');
          })
          .catch((e) => {
            // if the user doesn't share the file, swallow the relative browser error
            // console.log('Sharing failed', e.message);
          });
      } else if (
        navigator.canShare &&
        navigator.canShare({ title: title, text: data })
      ) {
        navigator
          .share({
            title: title,
            text: data,
          })
          .then(() => {
            // console.log('Share was successful.');
          })
          .catch((e) => {
            // if the user doesn't share the file, swallow the relative browser error
            // console.log('Sharing failed', e.message);
          });
      } else {
        _self.view.render(
          'error',
          'This functionality is not supported in your browser/os/device'
        );
      }
    };

    _self.view.bind('itemAdd', function (date) {
      return _self.addItem(date);
    });

    _self.view.bind('itemRemove', function (id) {
      return _self.removeItem(id);
    });

    _self.view.bind('itemEdit', function (id) {
      return _self.editItem(id);
    });

    _self.view.bind('importData', function (file) {
      return _self.importData(file);
    });

    _self.view.bind('exportData', function () {
      return _self.exportData();
    });

    _self.view.bind('shareData', function () {
      return _self.shareData();
    });

    _self.view.bind('itemRemoveAll', function () {
      return _self.removeAllItem();
    });

    _self.view.bind('settingsUpdate', function (data) {
      _self.updateSettings(data);
    });

    // _self.view.bind('alert', function() {
    // });
  };

  // export to window
  window.app = window.app || {};
  window.app.Controller = Controller;
})(window);
<|endoftext|>


<commit_before>(function() {
    $(document).ready(function() {
        /*
         * Loads List of TV-Shows direct from monitored RSS
         *
         */
        var loadRssTV = function(type) {
            var div, rssTV = document.getElementById('rss_TV');
            $.ajax({
                url: '/tv',
                type: 'get',
                dataType: 'json',
                cache: false
            }).done(function(data) {
                for(var i in data) {
                    rssTV.appendChild(siteRow(data[i]));
                }
            }).fail(function(data) {
                msg.set('Error loading TV-Shows');
            });
        };
        /*
         * Loads list of Movies as Thumbnails from db
         *
         */
        var loadRssMovies = function() {
            $.ajax({
                url: '/movies',
                type: 'get',
                dataType: 'json',
                cache: false,
            }).done(function(json) {
                var div, i;
                json.sort(function(a, b) {
                    a = new Date(a.lastUpdate);
                    b = new Date(b.lastUpdate);
                    return a > b ? -1 : a < b ? 1 : 0;
                });
                // Start creating Movie-Thumbs
                var li;
                for(i = 0; i < json.length; i++) {
                    div = thumbPosterWithInfoClickable(json[i]);
                    li = document.createElement('li');
                    li.className = 'col-lg-1 col-md-2 col-sm-3 col-xs-4';
                    li.appendChild(div);
                    //div.style.float = 'left';
                    $('#rss_Movies').append(li);
                }
            }).fail(function(data) {
                msg.set('Error while loading movies');
            });
        };
        loadRssTV();
        loadRssMovies();
        loadFiles();
        /*
         * Creates a siteRow which can be parsed
         *
         * @param site  {object} {title, pubdate, link, description}
         *
         *
         */
        var siteRow = function(sites) {
            var div = document.createElement('div');
            div.className = 'hyperlinkParse';
            if(sites.title !== undefined) {
                var domain = sites.link.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
                var date = new Date(sites.pubdate);
                div.innerHTML = sites.title + ' (' + date.easy() + ' @' + domain[1] + ')';
                sites = [sites];
            } else {
                div.textContent = '>- rip All Sites -<';
            }
            div.onclick = (function(sites) {
                return function() {
                    msg.set('parsing site...');
                    $.ajax({
                        url: '/site/links',
                        type: 'POST',
                        data: {
                            sites: sites
                        },
                        cache: false,
                        dataType: 'json'
                    }).done(function(onlineLinks){processLinks(onlineLinks)}).fail(function() {
                        msg.set('Error when checking links!');
                    });
                };
            })(sites);
            return div;
        };
        /*
         * Process returned online links
         */
        var processLinks = function(data) {
            /* structure of data; example
                [
                  {
                    "status": "0",
                    "filename": "Sm.2013.720p-iFT",
                    "extension": "mkv",
                    "size": "4920000000",
                    "link": "http://ul.to/08otd5be"
                  }
                  { etc. }
                ]
            */
            msg.set('found ' + data.length + ' links.')
            makeTableChecked(data);
            // Add links to textarea for exporting
            $('#paste').html(data.map(function(elem) {
                return elem.link;
            }).join(' '));
            $('.nav-tabs a[href="#tabLinks"]').tab('show');
        };
        /*
         * One Row of FileExplorer
         */
        var fileRow = function(file) {
            var tr = document.createElement('tr');
            var td = [];
            for(s = 0; s < 4; s++) {
                td.push(document.createElement('td'));
            }
            var a = null,
                icon = null,
                del = null,
                s = 0,
                i = 0;
            // Filename Link
            a = document.createElement('a');
            a.href = 'files/' + file.link;
            a.textContent = file.filename;
            td[0].appendChild(a);
            td[1].textContent = bytesToSize(file.size);
            // Filetype Icon
            icon = document.createElement('div');
            icon.className = 'icon icon' + file.extension;
            icon.title = file.extension;
            td[2].appendChild(icon);
            // DELETE Link
            del = document.createElement('div');
            del.className = 'a';
            del.onclick = function() {
                $.ajax({
                    url: 'files/' + file.link + '/delete',
                    type: 'DELETE',
                    dataType: 'json'
                }).done(function(err) {
                    err === null && msg.set('File Deleted', 'fadeout');
                    loadFiles(); // reload files-table
                }).fail(function() {
                    msg.set('Problem with connection; try again.', 'fadeout');
                });
            };
            del.textContent = 'delete';
            td[3].appendChild(del);
            for(s = 0; s < 4; s++) {
                tr.appendChild(td[s]);
            }
            return tr;
        };

        /**
         * Creates a HTML Movie-Thumb from the Movie-Poster
         *
         * @param {string} imageUrl The Url of the Movie-Poster-Image
         * @param {string} title Title of the Movie as title-tag
         *
         * @returns {Object} the DOM-Object of the div
         */
        var thumbPoster = function(imageUrl, title, year) {
            var img = document.createElement('img');
            img.src = imageUrl;
            img.className = 'thumbPosterImg thumb thumbnail';
            img.style.height = '150px';
            var divTitle = document.createElement('div');
            var div = document.createElement('div');
            div.className = 'thumbPoster';
            divTitle.title = title + ' (' + year + ')';
            divTitle.className = 'thumbPosterTitle';
            divTitle.textContent = title;
            if(imageUrl === 'http://image.tmdb.org/t/p/w500null' || (/poster_default/).test(imageUrl)) {
                div.width = '100px';
                div.style.minHeight = '150px';
                //div.appendChild(divTitle);

            } else {
                div.appendChild(img);
            }
            return div;
        };
        /**
         * Adds info to the movie-Thumb (Resolution, etc.)
         */
        var thumbPosterWithInfo = function(imageUrl, title, year, resolutions) {
            var thumb = thumbPoster(imageUrl, title, year);
            var divRes = document.createElement('div');
            divRes.className = 'resolutionBar';
            divRes.textContent = resolutions.join(', ');
            //thumb.appendChild(divRes);
            return thumb;
        };
        var thumbPosterWithInfoClickable = function(mData) {
            imgUrl = mData.info.posters !== undefined ? mData.info.posters.thumbnail : '';
            var div = thumbPosterWithInfo(imgUrl, mData.title, mData.info.year, mData.resolutions);
            div.style.cursor = 'pointer';
            div.onclick = (function(_id, title, info, image, sites, div) {
                return function() {
                    $('.nav-tabs a[href="#tabLinks"]').tab('show');
                    $('#linksDetails').empty();
                    $('#linksDetails').append(divMovieInfo(_id, title, image, info.runtime ? info.runtime : '?', info.year, 'imdb-Rating', info.synopsis === '' ? 'no synopsis' : info.synopsis, 'actors', div));
                    // Site-Links for ripping links
                    var linkList = document.getElementById('linksDetails');
                    // Link to Rip all links at the same time
                    linkList.appendChild(siteRow(sites));
                    // Single Links that can be parsed
                    for(var key in sites) {
                        linkList.appendChild(siteRow(sites[key]));
                    }
                };
            })(mData._id, mData.title, mData.info, imgUrl, mData.sites, div);
            return div;
        };
        /**
         * Creates the Movie-Info-Card
         */
        var divMovieInfo = function(_id, title, posterUrl, runtime, year, imdb, synopsis, actors, thumbDiv) {
            var div = document.createElement('div');
            div.className = 'movieDigest';
            var divOuter = document.createElement('div');
            divOuter.className = 'movieInfo';
            var divTitle = document.createElement('div');
            divTitle.className = 'movieInfoTitle';
            divTitle.textContent = title;
            var divDetails = document.createElement('div');
            divDetails.className = 'movieInfoLine';
            divDetails.textContent = 'Length: ' + runtime + 'min, Year: ' + year + ', ';
            var spanRemove = createElementSpanRemove(_id, thumbDiv);
            divDetails.appendChild(spanRemove);
            divDetails.appendChild(createElementSpanSpace());
            var spanUpdate = createElementSpanUpdate(_id);
            divDetails.appendChild(spanUpdate);
            var divSynopsis = document.createElement('div');
            divSynopsis.className = 'movieInfoLine';
            divSynopsis.textContent = synopsis;
            divSynopsis.style.fontStyle = 'italic';
            var poster = thumbPoster(posterUrl, title, year);
            poster.style.float = 'left';
            divOuter.appendChild(divTitle);
            divOuter.appendChild(divDetails);
            divOuter.appendChild(divSynopsis);
            div.appendChild(poster);
            div.appendChild(divOuter);
            return div;
        };
        /**
         * creates a space-span of len white spaces
         */
        var createElementSpanSpace = function(len) {
            if(len === undefined) len = 1;
            var span = document.createElement('span');
            var space = '';
            for(var i = 0; i < len; i++) {
                space += ' ';
            }
            span.textContent = space;
            return span;
        };
        /**
         * Creates a link which removes a movie from future display
         */
        var createElementSpanRemove = function(id, thumbDiv) {
            var button = document.createElement('div');
            button.className = 'btn btn-default btn-sm';
            var span = document.createElement('span');
            span.textContent = 'remove';
            span.title = 'don\'t display this movie anymore.';
            span.className = 'glyphicon glyphicon-trash';
            button.onclick = function() {
                $.getJSON('/movie/' + id + '/hide', function(data) {
                    msg.set('Movie will not be shown anymore!', 'fadeout');
                    $('.nav-tabs a[href="#tabHome"]').tab('show');
                    thumbDiv.parentNode.removeChild(thumbDiv);
                });
            };
            button.appendChild(span)
            return button;
        };

        /*
         * Creates a link which updates a movie-info
         */
        var createElementSpanUpdate = function(id) {
            var button = document.createElement('div');
            button.className = 'btn btn-default btn-sm';
            var span = document.createElement('span');
            span.textContent = 'update';
            span.title = 'update info to this movie';
            span.className = 'glyphicon glyphicon-trash';
            button.onclick = function() {
                $.getJSON('/movie/' + id + '/update', function(data) {
                    msg.set('Movie-Info Updated', 'fadeout');
                });
            };
            button.appendChild(span)
            return button;
        };

        /*
         * Create a Link that can be parsed (for one or multiple Links)
         */
        var parseLink = function(text, sites, clickEvent) {
            var div = document.createElement('div');
            div.className = 'hyperlinkParse';
            div.textContent = text;
            div.onclick = function() {
                clickEvent(sites);
            };
            return div;
        };

        /*
         * Table with ul.to links that have been checked for availability
         *
         * @param {array} files an Array containing all checked ul.to links
         */
        var makeTableChecked = function(files) {
            // one tab for every extension; integer is filecount per extension
            var extensions = {
                mp4: 0,
                mkv: 0,
                avi: 0,
                rar: 0,
                default: 0
            };
            var rowcols = ['link', 'size', 'extension', 'jd', 'cloud'];
            var target = '#tabs-links-';
            // empty all tabs
            for(var i in extensions) $(target + i + ' tbody').empty();
            var cols = function() {
                var tds = [];
                for(var i in rowcols) tds.push(document.createElement('td'));
                return tds;
            };
            // sort files by extension
            files.sort(function(a, b) {
                return a.extension  b.extension ? -1 : 0;
            });
            var makeRow = function(filename, href, extension, size) {
                // create new DOM-table-row
                var tr = document.createElement('tr');
                // create cells
                var tds = [];
                for(var i in rowcols) tds.push(document.createElement('td'));
                // Link/Name Col
                var link = document.createElement('a');
                link.href = href;
                link.textContent = filename;
                tds[0].appendChild(link);
                // Size Col
                tds[1].textContent = bytesToSize(size);
                // Extension Col
                var extension = document.createElement('div');
                extension.className = 'icon icon' + extension;
                extension.title = extension;
                tds[2].appendChild(extension);
                // J-Downloader Col
                tds[3].appendChild(jDLink(link));
                // Download to Server Col
                var cloud = document.createElement('div');
                cloud.className = 'icon iconcloud';
                cloud.title = 'download to diskstation';
                cloud.onclick = (function(link) {
                    return function() {
                        DownloadStation(link);
                    };
                })(href);
                tds[4].appendChild(cloud);
                for(var key in tds) tr.appendChild(tds[key]);
                return tr;
            };
            // Loop through all files
            for(i in files) {
                var t = (extensions[files[i].extension] !== undefined) ? files[i].extension : 'default';
                extensions[t]++;
                var tr = makeRow(files[i].filename, files[i].link, files[i].extension, files[i].size);
                $(target + t + ' tbody').append(tr);
            }
            // update files per extension
            if(extensions.mp4 === 0) {
                $('.nav-tabs a[href="#tabLinks"]').tab('show');
            } else {
                $('.nav-tabs a[href="#tabs-links-mkv"]').tab('show');
            }
            // Update Tab-title counter
            for(var i in extensions) {
                $('#rssLinks ul:first li:eq(' + (Object.keys(extensions)).indexOf(i) + ') a').text(i + '(' + extensions[i] + ')');
            }
        };
    });
})();<commit_msg>jquery error<commit_after>(function() {
    $(document).ready(function() {
        /*
         * Loads List of TV-Shows direct from monitored RSS
         *
         */
        var loadRssTV = function(type) {
            var div, rssTV = document.getElementById('rss_TV');
            $.ajax({
                url: '/tv',
                type: 'get',
                dataType: 'json',
                cache: false
            }).done(function(data) {
                for(var i in data) {
                    rssTV.appendChild(siteRow(data[i]));
                }
            }).fail(function(data) {
                msg.set('Error loading TV-Shows');
            });
        };
        /*
         * Loads list of Movies as Thumbnails from db
         *
         */
        var loadRssMovies = function() {
            $.ajax({
                url: '/movies',
                type: 'get',
                dataType: 'json',
                cache: false,
            }).done(function(json) {
                var div, i;
                json.sort(function(a, b) {
                    a = new Date(a.lastUpdate);
                    b = new Date(b.lastUpdate);
                    return a > b ? -1 : a < b ? 1 : 0;
                });
                // Start creating Movie-Thumbs
                var li;
                for(i = 0; i < json.length; i++) {
                    div = thumbPosterWithInfoClickable(json[i]);
                    li = document.createElement('li');
                    li.className = 'col-lg-1 col-md-2 col-sm-3 col-xs-4';
                    li.appendChild(div);
                    //div.style.float = 'left';
                    $('#rss_Movies').append(li);
                }
            }).fail(function(data) {
                msg.set('Error while loading movies');
            });
        };
        loadRssTV();
        loadRssMovies();
        loadFiles();
        /*
         * Creates a siteRow which can be parsed
         *
         * @param site  {object} {title, pubdate, link, description}
         *
         *
         */
        var siteRow = function(sites) {
            var div = document.createElement('div');
            div.className = 'hyperlinkParse';
            if(sites.title !== undefined) {
                var domain = sites.link.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
                var date = new Date(sites.pubdate);
                div.innerHTML = sites.title + ' (' + date.easy() + ' @' + domain[1] + ')';
                sites = [sites];
            } else {
                div.textContent = '>- rip All Sites -<';
            }
            div.onclick = (function(sites) {
                return function() {
                    msg.set('parsing site...');
                    $.ajax({
                        url: '/site/links',
                        type: 'POST',
                        data: {
                            sites: sites
                        },
                        cache: false,
                        dataType: 'json'
                    }).done(function(onlineLinks){processLinks(onlineLinks)}).fail(function() {
                        msg.set('Error when checking links!');
                    });
                };
            })(sites);
            return div;
        };
        /*
         * Process returned online links
         */
        var processLinks = function(data) {
            /* structure of data; example
                [
                  {
                    "status": "0",
                    "filename": "Sm.2013.720p-iFT",
                    "extension": "mkv",
                    "size": "4920000000",
                    "link": "http://ul.to/08otd5be"
                  }
                  { etc. }
                ]
            */
            msg.set('found ' + data.length + ' links.')
            makeTableChecked(data);
            // Add links to textarea for exporting
            $('#paste').html(data.map(function(elem) {
                return elem.link;
            }).join(' '));
            $('.nav-tabs a[href="#tabLinks"]').tab('show');
        };
        /*
         * One Row of FileExplorer
         */
        var fileRow = function(file) {
            var tr = document.createElement('tr');
            var td = [];
            for(s = 0; s < 4; s++) {
                td.push(document.createElement('td'));
            }
            var a = null,
                icon = null,
                del = null,
                s = 0,
                i = 0;
            // Filename Link
            a = document.createElement('a');
            a.href = 'files/' + file.link;
            a.textContent = file.filename;
            td[0].appendChild(a);
            td[1].textContent = bytesToSize(file.size);
            // Filetype Icon
            icon = document.createElement('div');
            icon.className = 'icon icon' + file.extension;
            icon.title = file.extension;
            td[2].appendChild(icon);
            // DELETE Link
            del = document.createElement('div');
            del.className = 'a';
            del.onclick = function() {
                $.ajax({
                    url: 'files/' + file.link + '/delete',
                    type: 'DELETE',
                    dataType: 'json'
                }).done(function(err) {
                    err === null && msg.set('File Deleted', 'fadeout');
                    loadFiles(); // reload files-table
                }).fail(function() {
                    msg.set('Problem with connection; try again.', 'fadeout');
                });
            };
            del.textContent = 'delete';
            td[3].appendChild(del);
            for(s = 0; s < 4; s++) {
                tr.appendChild(td[s]);
            }
            return tr;
        };

        /**
         * Creates a HTML Movie-Thumb from the Movie-Poster
         *
         * @param {string} imageUrl The Url of the Movie-Poster-Image
         * @param {string} title Title of the Movie as title-tag
         *
         * @returns {Object} the DOM-Object of the div
         */
        var thumbPoster = function(imageUrl, title, year) {
            var img = document.createElement('img');
            img.src = imageUrl;
            img.className = 'thumbPosterImg thumb thumbnail';
            img.style.height = '150px';
            var divTitle = document.createElement('div');
            var div = document.createElement('div');
            div.className = 'thumbPoster';
            divTitle.title = title + ' (' + year + ')';
            divTitle.className = 'thumbPosterTitle';
            divTitle.textContent = title;
            if(imageUrl === 'http://image.tmdb.org/t/p/w500null' || (/poster_default/).test(imageUrl)) {
                div.width = '100px';
                div.style.minHeight = '150px';
                //div.appendChild(divTitle);

            } else {
                div.appendChild(img);
            }
            return div;
        };
        /**
         * Adds info to the movie-Thumb (Resolution, etc.)
         */
        var thumbPosterWithInfo = function(imageUrl, title, year, resolutions) {
            var thumb = thumbPoster(imageUrl, title, year);
            var divRes = document.createElement('div');
            divRes.className = 'resolutionBar';
            divRes.textContent = resolutions.join(', ');
            //thumb.appendChild(divRes);
            return thumb;
        };
        var thumbPosterWithInfoClickable = function(mData) {
            imgUrl = mData.info.posters !== undefined ? mData.info.posters.thumbnail : '';
            var div = thumbPosterWithInfo(imgUrl, mData.title, mData.info.year, mData.resolutions);
            div.style.cursor = 'pointer';
            div.onclick = (function(_id, title, info, image, sites, div) {
                return function() {
                    $('.nav-tabs a[href="#tabLinks"]').tab('show');
                    $('#linksDetails').empty();
                    $('#linksDetails').append(divMovieInfo(_id, title, image, info.runtime ? info.runtime : '?', info.year, 'imdb-Rating', info.synopsis === '' ? 'no synopsis' : info.synopsis, 'actors', div));
                    // Site-Links for ripping links
                    var linkList = document.getElementById('linksDetails');
                    // Link to Rip all links at the same time
                    linkList.appendChild(siteRow(sites));
                    // Single Links that can be parsed
                    for(var key in sites) {
                        linkList.appendChild(siteRow(sites[key]));
                    }
                };
            })(mData._id, mData.title, mData.info, imgUrl, mData.sites, div);
            return div;
        };
        /**
         * Creates the Movie-Info-Card
         */
        var divMovieInfo = function(_id, title, posterUrl, runtime, year, imdb, synopsis, actors, thumbDiv) {
            var div = document.createElement('div');
            div.className = 'movieDigest';
            var divOuter = document.createElement('div');
            divOuter.className = 'movieInfo';
            var divTitle = document.createElement('h2');
            divTitle.className = 'movieInfoTitle';
            divTitle.textContent = title;
            var divDetails = document.createElement('div');
            divDetails.className = 'movieInfoLine';
            divDetails.textContent = 'Length: ' + runtime + 'min, Year: ' + year + ', ';
            var spanRemove = createElementSpanRemove(_id, thumbDiv);
            divDetails.appendChild(spanRemove);
            divDetails.appendChild(createElementSpanSpace());
            var spanUpdate = createElementSpanUpdate(_id);
            divDetails.appendChild(spanUpdate);
            var divSynopsis = document.createElement('div');
            divSynopsis.className = 'movieInfoLine';
            divSynopsis.textContent = synopsis;
            divSynopsis.style.fontStyle = 'italic';
            var poster = thumbPoster(posterUrl, title, year);
            poster.style.float = 'left';
            divOuter.appendChild(divTitle);
            divOuter.appendChild(divDetails);
            divOuter.appendChild(divSynopsis);
            div.appendChild(poster);
            div.appendChild(divOuter);
            return div;
        };
        /**
         * creates a space-span of len white spaces
         */
        var createElementSpanSpace = function(len) {
            if(len === undefined) len = 1;
            var span = document.createElement('span');
            var space = '';
            for(var i = 0; i < len; i++) {
                space += ' ';
            }
            span.textContent = space;
            return span;
        };
        /**
         * Creates a link which removes a movie from future display
         */
        var createElementSpanRemove = function(id, thumbDiv) {
            var button = document.createElement('div');
            button.className = 'btn btn-default btn-sm';
            var span = document.createElement('span');
            span.textContent = 'remove';
            span.title = 'don\'t display this movie anymore.';
            span.className = 'glyphicon glyphicon-trash';
            button.onclick = function() {
                $.getJSON('/movie/' + id + '/hide', function(data) {
                    msg.set('Movie will not be shown anymore!', 'fadeout');
                    $('.nav-tabs a[href="#tabHome"]').tab('show');
                    thumbDiv.parentNode.removeChild(thumbDiv);
                });
            };
            button.appendChild(span)
            return button;
        };

        /*
         * Creates a link which updates a movie-info
         */
        var createElementSpanUpdate = function(id) {
            var button = document.createElement('div');
            button.className = 'btn btn-default btn-sm';
            var span = document.createElement('span');
            span.textContent = 'update';
            span.title = 'update info to this movie';
            span.className = 'glyphicon glyphicon-trash';
            button.onclick = function() {
                $.getJSON('/movie/' + id + '/update', function(data) {
                    msg.set('Movie-Info Updated', 'fadeout');
                });
            };
            button.appendChild(span)
            return button;
        };

        /*
         * Create a Link that can be parsed (for one or multiple Links)
         */
        var parseLink = function(text, sites, clickEvent) {
            var div = document.createElement('div');
            div.className = 'hyperlinkParse';
            div.textContent = text;
            div.onclick = function() {
                clickEvent(sites);
            };
            return div;
        };

        /*
         * Table with ul.to links that have been checked for availability
         *
         * @param {array} files an Array containing all checked ul.to links
         */
        var makeTableChecked = function(files) {
            // one tab for every extension; integer is filecount per extension
            var extensions = {
                mp4: 0,
                mkv: 0,
                avi: 0,
                rar: 0,
                default: 0
            };
            var rowcols = ['link', 'size', 'extension', 'jd', 'cloud'];
            var target = '#tabs-links-';
            // empty all tabs
            for(var i in extensions) $(target + i + ' tbody').empty();
            var cols = function() {
                var tds = [];
                for(var i in rowcols) tds.push(document.createElement('td'));
                return tds;
            };
            // sort files by extension
            files.sort(function(a, b) {
                return a.extension  b.extension ? -1 : 0;
            });
            var makeRow = function(filename, href, extension, size) {
                // create new DOM-table-row
                var tr = document.createElement('tr');
                // create cells
                var tds = [];
                for(var i in rowcols) tds.push(document.createElement('td'));
                // Link/Name Col
                var link = document.createElement('a');
                link.href = href;
                link.textContent = filename;
                tds[0].appendChild(link);
                // Size Col
                tds[1].textContent = bytesToSize(size);
                // Extension Col
                var extension = document.createElement('div');
                extension.className = 'icon icon' + extension;
                extension.title = extension;
                tds[2].appendChild(extension);
                // J-Downloader Col
                tds[3].appendChild(jDLink(link));
                // Download to Server Col
                var cloud = document.createElement('div');
                cloud.className = 'icon iconcloud';
                cloud.title = 'download to diskstation';
                cloud.onclick = (function(link) {
                    return function() {
                        DownloadStation(link);
                    };
                })(href);
                tds[4].appendChild(cloud);
                for(var key in tds) tr.appendChild(tds[key]);
                return tr;
            };
            // Loop through all files
            for(i in files) {
                var t = (extensions[files[i].extension] !== undefined) ? files[i].extension : 'default';
                extensions[t]++;
                var tr = makeRow(files[i].filename, files[i].link, files[i].extension, files[i].size);
                $(target + t + ' tbody').append(tr);
            }
            // update files per extension
            if(extensions.mp4 === 0) {
                $('.nav-tabs a[href="#tabLinks"]').tab('show');
            } else {
                $('.nav-tabs a[href="#tabs-links-mkv"]').tab('show');
            }
            // Update Tab-title counter
            for(var i in extensions) {
                $('#rssLinks ul:first li:eq(' + (Object.keys(extensions)).indexOf(i) + ') a').text(i + '(' + extensions[i] + ')');
            }
        };
    });
})();<|endoftext|>