<commit_before>"use strict";

class Scene {
    constructor(canvasId, presentBtnId) {
        /* const */ this.DISTANCE = 80.0;

        this.webglCanvas = document.getElementById(canvasId);
        this.presentBtn = document.getElementById(presentBtnId);
        this.vrDisplay = null;
        this.gl = this.webglCanvas.getContext("webgl");
        this.projectionMat = mat4.create();
        this.viewMat = mat4.create();
        this.modelViewMat = mat4.create();
        this.modelMat = mat4.create();
        let options = {
            lines: WGLUUrl.getBool("lines", false),
            vertexShader: WGLUUrl.getString("vertex", "waves2"),
            fragmentShader: WGLUUrl.getString("fragment", "normal")
        };
        this.ocean = new Ocean(this.gl, 64, 100.0, options);

        this.init();
        this.initWebVr();
    }

    init() {
        this.gl.enable(this.gl.DEPTH_TEST);
        this.gl.clearColor(0.53, 0.81, 0.98, 1.0);

        let eye = vec3.create();
        vec3.set(eye, 0, 0, 0);
        let target = vec3.create();
        vec3.set(target, 0, -this.DISTANCE / 2.0, -this.DISTANCE);
        let up = vec3.create();
        vec3.set(up, 0, 1, 0);
        mat4.lookAt(this.viewMat, eye, target, up);
    }

    initWebVr() {
        if (navigator.getVRDisplays) {
            this.frameData = new VRFrameData();

			navigator.getVRDisplays().then((function(displays) {
				if (displays.length > 0) {
					this.vrDisplay = displays[displays.length - 1];
					this.vrDisplay.depthNear = 0.1;
					this.vrDisplay.depthFar = 1024.0;
					if (this.vrDisplay.capabilities.canPresent) {
						this.presentBtn.style.display = "block";
						this.presentBtn.addEventListener("click",
                                this.onVrRequestPresent.bind(this));
					}
					window.addEventListener('vrdisplaypresentchange', this.onVrPresentChange.bind(this), false);
					window.addEventListener('vrdisplayactivate', this.onVrRequestPresent.bind(this), false);
					window.addEventListener('vrdisplaydeactivate', this.onVrExitPresent.bind(this), false);
				} else {
					console.log("WebVr supported, but no VRDisplays found.");
				}
			}).bind(this));
        } else {
            console.log("WebVr not supported");
        }
    }

    onVrRequestPresent() {
        this.vrDisplay.requestPresent([{source: this.webglCanvas}]).then(
                function() {},
                function (err) {
                    var errMsg = "requestPresent failed.";
                    if (err && err.message) {
                        errMsg += " " + err.message;
                    }
                    console.log(errMsg);
                });
    }

    onVrExitPresent() {
        if (!this.vrDisplay.isPresenting)
            return;
        this.vrDisplay.exitPresent().then(
                function() {},
                function (err) {
                    var errMsg = "exitPresent failed.";
                    if (err && err.message) {
                        errMsg += " " + err.message
                    }
                    console.log(errMsg);
                });
    }

    onVrPresentChange() {
        this.onResize();
        if (this.vrDisplay.isPresenting) {
            this.presentBtn.style.display = "none";
        } else {
            this.presentBtn.style.display = "block";
        }
    }

    onResize() {
        if (this.vrDisplay && this.vrDisplay.isPresenting) {
          let leftEye = this.vrDisplay.getEyeParameters("left");
          let rightEye = this.vrDisplay.getEyeParameters("right");
          this.webglCanvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;
          this.webglCanvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);
        } else {
            this.webglCanvas.width = this.webglCanvas.offsetWidth * window.devicePixelRatio;
            this.webglCanvas.height = this.webglCanvas.offsetHeight * window.devicePixelRatio;
        }
    }

    onAnimationFrame(time) {
        let gl = this.gl;

        gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);

        mat4.identity(this.modelMat);
        mat4.translate(this.modelMat, this.modelMat, [0, -this.DISTANCE, 0]);

        if (this.vrDisplay) {
            this.vrDisplay.requestAnimationFrame(this.onAnimationFrame.bind(this));
            this.vrDisplay.getFrameData(this.frameData);

            if (this.vrDisplay.isPresenting) {
                gl.viewport(0, 0, this.webglCanvas.width * 0.5, this.webglCanvas.height);
                this.ocean.render(this.frameData.leftProjectionMatrix, this.frameData.leftViewMatrix,
                        this.modelMat, time / 1000.0);
                gl.viewport(this.webglCanvas.width * 0.5, 0, this.webglCanvas.width * 0.5, this.webglCanvas.height);
                this.ocean.render(this.frameData.rightProjectionMatrix, this.frameData.rightViewMatrix,
                        this.modelMat, time / 1000.0);
                this.vrDisplay.submitFrame();
            } else {
                gl.viewport(0, 0, this.webglCanvas.width, this.webglCanvas.height);
                mat4.perspective(this.projectionMat, Math.PI * 0.4,
                        this.webglCanvas.width / this.webglCanvas.height, 0.1, 1024.0);
                this.ocean.render(this.projectionMat, this.frameData.leftViewMatrix,
                        this.modelMat, time / 1000.0);
            }
        } else {
            window.requestAnimationFrame(this.onAnimationFrame.bind(this));

            gl.viewport(0, 0, this.webglCanvas.width, this.webglCanvas.height);
            mat4.perspective(this.projectionMat, Math.PI * 0.4,
                    this.webglCanvas.width / this.webglCanvas.height, 0.1, 1024.0);
            this.ocean.render(this.projectionMat, this.viewMat, this.modelMat, time / 1000.0);
        }
    }
}

window.onload = function () {
    let scene = new Scene("webgl-canvas", "present-btn");
    scene.onResize();

    window.addEventListener("resize", scene.onResize.bind(scene), false);
    window.requestAnimationFrame(scene.onAnimationFrame.bind(scene));
};
<commit_msg>parametizing rows<commit_after>"use strict";

class Scene {
    constructor(canvasId, presentBtnId) {
        /* const */ this.DISTANCE = 80.0;

        this.webglCanvas = document.getElementById(canvasId);
        this.presentBtn = document.getElementById(presentBtnId);
        this.vrDisplay = null;
        this.gl = this.webglCanvas.getContext("webgl");
        this.projectionMat = mat4.create();
        this.viewMat = mat4.create();
        this.modelViewMat = mat4.create();
        this.modelMat = mat4.create();
        let options = {
            lines: WGLUUrl.getBool("lines", false),
            vertexShader: WGLUUrl.getString("vertex", "waves2"),
            fragmentShader: WGLUUrl.getString("fragment", "normal")
        };
	let rows = WGLUUrl.getInt("rows", 64);
        this.ocean = new Ocean(this.gl, rows, 100.0, options);

        this.init();
        this.initWebVr();
    }

    init() {
        this.gl.enable(this.gl.DEPTH_TEST);
        this.gl.clearColor(0.53, 0.81, 0.98, 1.0);

        let eye = vec3.create();
        vec3.set(eye, 0, 0, 0);
        let target = vec3.create();
        vec3.set(target, 0, -this.DISTANCE / 2.0, -this.DISTANCE);
        let up = vec3.create();
        vec3.set(up, 0, 1, 0);
        mat4.lookAt(this.viewMat, eye, target, up);
    }

    initWebVr() {
        if (navigator.getVRDisplays) {
            this.frameData = new VRFrameData();

			navigator.getVRDisplays().then((function(displays) {
				if (displays.length > 0) {
					this.vrDisplay = displays[displays.length - 1];
					this.vrDisplay.depthNear = 0.1;
					this.vrDisplay.depthFar = 1024.0;
					if (this.vrDisplay.capabilities.canPresent) {
						this.presentBtn.style.display = "block";
						this.presentBtn.addEventListener("click",
                                this.onVrRequestPresent.bind(this));
					}
					window.addEventListener('vrdisplaypresentchange', this.onVrPresentChange.bind(this), false);
					window.addEventListener('vrdisplayactivate', this.onVrRequestPresent.bind(this), false);
					window.addEventListener('vrdisplaydeactivate', this.onVrExitPresent.bind(this), false);
				} else {
					console.log("WebVr supported, but no VRDisplays found.");
				}
			}).bind(this));
        } else {
            console.log("WebVr not supported");
        }
    }

    onVrRequestPresent() {
        this.vrDisplay.requestPresent([{source: this.webglCanvas}]).then(
                function() {},
                function (err) {
                    var errMsg = "requestPresent failed.";
                    if (err && err.message) {
                        errMsg += " " + err.message;
                    }
                    console.log(errMsg);
                });
    }

    onVrExitPresent() {
        if (!this.vrDisplay.isPresenting)
            return;
        this.vrDisplay.exitPresent().then(
                function() {},
                function (err) {
                    var errMsg = "exitPresent failed.";
                    if (err && err.message) {
                        errMsg += " " + err.message
                    }
                    console.log(errMsg);
                });
    }

    onVrPresentChange() {
        this.onResize();
        if (this.vrDisplay.isPresenting) {
            this.presentBtn.style.display = "none";
        } else {
            this.presentBtn.style.display = "block";
        }
    }

    onResize() {
        if (this.vrDisplay && this.vrDisplay.isPresenting) {
          let leftEye = this.vrDisplay.getEyeParameters("left");
          let rightEye = this.vrDisplay.getEyeParameters("right");
          this.webglCanvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;
          this.webglCanvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);
        } else {
            this.webglCanvas.width = this.webglCanvas.offsetWidth * window.devicePixelRatio;
            this.webglCanvas.height = this.webglCanvas.offsetHeight * window.devicePixelRatio;
        }
    }

    onAnimationFrame(time) {
        let gl = this.gl;

        gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);

        mat4.identity(this.modelMat);
        mat4.translate(this.modelMat, this.modelMat, [0, -this.DISTANCE, 0]);

        if (this.vrDisplay) {
            this.vrDisplay.requestAnimationFrame(this.onAnimationFrame.bind(this));
            this.vrDisplay.getFrameData(this.frameData);

            if (this.vrDisplay.isPresenting) {
                gl.viewport(0, 0, this.webglCanvas.width * 0.5, this.webglCanvas.height);
                this.ocean.render(this.frameData.leftProjectionMatrix, this.frameData.leftViewMatrix,
                        this.modelMat, time / 1000.0);
                gl.viewport(this.webglCanvas.width * 0.5, 0, this.webglCanvas.width * 0.5, this.webglCanvas.height);
                this.ocean.render(this.frameData.rightProjectionMatrix, this.frameData.rightViewMatrix,
                        this.modelMat, time / 1000.0);
                this.vrDisplay.submitFrame();
            } else {
                gl.viewport(0, 0, this.webglCanvas.width, this.webglCanvas.height);
                mat4.perspective(this.projectionMat, Math.PI * 0.4,
                        this.webglCanvas.width / this.webglCanvas.height, 0.1, 1024.0);
                this.ocean.render(this.projectionMat, this.frameData.leftViewMatrix,
                        this.modelMat, time / 1000.0);
            }
        } else {
            window.requestAnimationFrame(this.onAnimationFrame.bind(this));

            gl.viewport(0, 0, this.webglCanvas.width, this.webglCanvas.height);
            mat4.perspective(this.projectionMat, Math.PI * 0.4,
                    this.webglCanvas.width / this.webglCanvas.height, 0.1, 1024.0);
            this.ocean.render(this.projectionMat, this.viewMat, this.modelMat, time / 1000.0);
        }
    }
}

window.onload = function () {
    let scene = new Scene("webgl-canvas", "present-btn");
    scene.onResize();

    window.addEventListener("resize", scene.onResize.bind(scene), false);
    window.requestAnimationFrame(scene.onAnimationFrame.bind(scene));
};
<|endoftext|>


<commit_before>var myApp = angular.module("myApp", []);

// Directive template for later usage
myApp.directive("editable", function () {
  return {
    restrict: 'E',
    link: function (scope, element, attrs) {
      element.html("
Hello there
")
    }
  }
});

// Global parameters for pagination
myApp.factory('pjFactory', function () {
  factory = {};
  factory.vars = {};
  // Vars
  factory.vars.attributes = {
    FOR: 0,
    CON: 0,
    DEX: 0,
    TAI: 0,
    INT: 0,
    POU: 0,
    CHA: 0,
  };
  factory.vars.calc = {};
  factory.vars.calc.ac = 0;
  factory.vars.calc.md = 0;
  factory.vars.calc.ma = 0;
  factory.vars.calc.mv = "";
  factory.vars.calc.pd = 0;
  factory.vars.calc.pm = 0;
  factory.vars.calc.ra = 0;
  factory.vars.body = {
    head: {pv: 0, pa: 0},
    chest: {pv: 0, pa: 0},
    bide: {pv: 0, pa: 0},
    rarm: {pv: 0, pa: 0},
    larm: {pv: 0, pa: 0},
    rfoot: {pv: 0, pa: 0},
    lfoot: {pv: 0, pa: 0},
  };
  factory.vars.edit = false;
  factory.vars.head = {};
  factory.vars.head.name = "";
  factory.vars.head.player = "";
  factory.vars.head.race = "";
  factory.vars.head.sex = "";
  factory.vars.head.culture = "";
  factory.vars.head.origin = "";
  factory.vars.head.job = "";
  factory.vars.head.family = "";
  factory.vars.head.age = "";
  factory.vars.head.hair = "";
  factory.vars.head.eyes = "";
  factory.vars.head.weight = "";
  factory.vars.skills = [
    {name: "Athlétisme", init:["FOR", "DEX"]},
    {name: "Bagarre", init:["FOR", "DEX"]},
    {name: "Chant", init:["CHA", "POU"]},
    {name: "Conduite", init:["DEX", "POU"]},
    {name: "Conn. (Régionale)", init:["INT", "INT"]},
    {name: "Culture (d'origine)", init:["INT", "INT"]},
    {name: "Danse", init:["DEX", "CHA"]},
    {name: "Discretion", init:["INT", "DEX"]},
    {name: "Endurance", init:["CON", "CON"]},
    {name: "Equitation", init:["DEX", "POU"]},
    {name: "Evaluer", init:["INT", "CHA"]},
    {name: "Evasion", init:["DEX", "DEX"]},
    {name: "Force Brute", init:["FOR", "TAI"]},
    {name: "Influence", init:["CHA", "CHA"]},
    {name: "Natation", init:["FOR", "CON"]},
    {name: "Passe-passe", init:["DEX", "CHA"]},
    {name: "Perception", init:["POU", "INT"]},
    {name: "Persévérance", init:["POU", "POU"]},
    {name: "Perspicacité", init:["INT", "POU"]},
    {name: "Premiers soins", init:["INT", "DEX"]},
  ];
  factory.vars.advskills = [];
  factory.vars.cmbskills = [];
  factory.vars.div = {};
  // Helpers
  factory.save = function () {
    localStorage["pjhead"] = JSON.stringify(factory.vars.head);
    localStorage["pjskills"] = JSON.stringify(factory.vars.skills);
    localStorage["pjadvskills"] = JSON.stringify(factory.vars.advskills);
    localStorage["pjcmbskills"] = JSON.stringify(factory.vars.cmbskills);
    localStorage["pjattributes"] = JSON.stringify(factory.vars.attributes);
    localStorage["pjcalc"] = JSON.stringify(factory.vars.calc);
    localStorage["pjbody"] = JSON.stringify(factory.vars.body);
    localStorage["pjdiv"] = JSON.stringify(factory.vars.div);
    console.log("Saved");
  };
  factory.load = function () {
    factory.vars.head = JSON.parse(localStorage["pjhead"]);
    factory.vars.skills = JSON.parse(localStorage["pjskills"]);
    factory.vars.advskills = JSON.parse(localStorage["pjadvskills"]);
    factory.vars.cmbskills = JSON.parse(localStorage["pjcmbskills"]);
    factory.vars.attributes = JSON.parse(localStorage["pjattributes"]);
    factory.vars.calc = JSON.parse(localStorage["pjcalc"]);
    factory.vars.body = JSON.parse(localStorage["pjbody"]);
    factory.vars.div = JSON.parse(localStorage["pjdiv"]);
    console.log("loaded");
  };
  factory.reset = function () {
    //localStorage.removeItem("pjhead");
    //localStorage.removeItem("pjskills");
    //localStorage.removeItem("pjattributes");
    angular.forEach(factory.vars.head, function (value, key) {
      factory.vars.head[key] = "";
    });
    angular.forEach(factory.vars.attributes, function (value, key) {
      factory.vars.attributes[key] = 0;
    });
    factory.vars.calc.pm = 0;
    factory.vars.calc.pd = 0;
    factory.vars.calc.mv = "";
    factory.vars.body = {
      head: {pv: 0, pa: 0},
      chest: {pv: 0, pa: 0},
      bide: {pv: 0, pa: 0},
      rarm: {pv: 0, pa: 0},
      larm: {pv: 0, pa: 0},
      rfoot: {pv: 0, pa: 0},
      lfoot: {pv: 0, pa: 0},
    }
    angular.forEach(factory.vars.skills, function (value, key) {
      obj = factory.vars.attributes[key];
      if (obj) {
        delete factory.vars.attributes[key]["base"];
        delete factory.vars.attributes[key]["value"];
      };
    });
    factory.vars.advskills.length = 0;
    factory.vars.cmbskills.length = 0;
    factory.vars.div = {}
    console.log("reset");
  };
  factory.example = function () {
    factory.vars.attributes = {
      FOR: 12,
      CON: 13,
      DEX: 14,
      TAI: 12,
      INT: 10,
      POU: 12,
      CHA: 14,
    };
    factory.vars.head.name = "Jon Snow";
    factory.vars.head.player = "Cyberj";
    factory.vars.head.race = "Humain";
    factory.vars.head.sex = "H";
    factory.vars.head.culture = "Civilisée";
    factory.vars.head.origin = "Nordique";
    factory.vars.head.job = "Patrouilleur";
    factory.vars.head.family = "Starck";
    factory.vars.head.age = "22";
    factory.vars.head.hair = "Noir";
    factory.vars.head.eyes = "Noirs";
    factory.vars.head.weight = "75Kg";
    factory.vars.calc.mv = "8m";
    factory.vars.body.chest.pa = 1;
    factory.vars.body.bide.pa = 1;
    factory.vars.body.head.pa = 1;
    factory.vars.body.larm.pa = 1;
    factory.vars.body.rarm.pa = 1;
    factory.vars.advskills = [
      {name: "Empathie", init:["CHA", "POU"], value:45, base: 26},
      {name: "Conn (Le mur)", init:["INT", "INT"], value:60, base: 20},
    ];
    factory.vars.cmbskills = [
      {name: "Épée a deux mains", init:["FOR", "DEX"], value:65, base: 26},
    ];
    factory.vars.div.armor = [
      {name: "Cuir souple"},
    ]

  };
  factory.cons = {};
  factory.cons.attrs = [
    "FOR", "CON", "DEX", "TAI", "INT", "POU", "CHA",
  ];
  factory.periods = [
    {key: "3days", value: "3 days"},
    {key: "curweek", value: "Current week"},
    {key: "curmonth", value: "Current month"},
    {key: "curyear", value: "Current year"},
    {key: "week", value: "A week"},
    {key: "month", value: "A month"},
    {key: "year", value: "A year"},
    {key: "all", value: "Whole mailbox"},
  ];
  return factory;
});

myApp.controller('skillsCtrl', function ($scope, pjFactory) {
  $scope.cons = pjFactory.cons;
  $scope.vars = pjFactory.vars;
  $scope.pj = pjFactory.vars;
  $scope.newskill = {base1:"FOR", base2:"FOR"};
  $scope.newcskill = {base1:"FOR", base2:"DEX"};
  $scope.getBase = function (skill) {
    var base = $scope.vars.attributes[skill.init[0]]+$scope.vars.attributes[skill.init[1]];
    var text = "";
    if (skill.base == null) {
      skill.base = base;
      skill.value = base;
    } else if (skill.base != base) {
      skill.value += base - skill.base;
      skill.base = base;
    };
    if ( skill.init[0] == skill.init[1]) {
      text = skill.init[0]+"x2";
    } else {
      text = skill.init[0]+"+"+skill.init[1];
    };
    return text + " ("+base+"%)"
  };
  $scope.addSkill = function () {
    nskill = {name: $scope.newskill.name, init: [$scope.newskill.base1, $scope.newskill.base2]}
    $scope.pj.advskills.push(nskill);
    $scope.newskill = {base1:"FOR", base2:"FOR"};

  };
  $scope.addcSkill = function () {
    ncskill = {name: $scope.newcskill.name, init: [$scope.newcskill.base1, $scope.newcskill.base2]}
    $scope.pj.cmbskills.push(ncskill);
    $scope.newcskill = {base1:"FOR", base2:"DEX"};

  };
  $scope.rmSkill = function (index) {
    $scope.pj.advskills.pop(index);
  };
  $scope.rmcSkill = function (index) {
    $scope.pj.cmbskills.pop(index);
  };
});

myApp.controller('attrCtrl', function ($scope, pjFactory) {
  $scope.vars = pjFactory.vars;
  $scope.pj = pjFactory.vars;
});

myApp.controller('headCtrl', function ($scope, pjFactory) {
  $scope.pj = pjFactory.vars;
  $scope.vars = pjFactory.vars;
  $scope.save = pjFactory.save;
  $scope.load = pjFactory.load;
  $scope.reset = pjFactory.reset;
  $scope.example = pjFactory.example;
  $scope.share = function () {
    var blob = new Blob(['<?xml version="1.0" encoding="UTF-8" standalone="no"?>'+$('.page1').html()], {type: "image/svg;charset=utf-8"});
    saveAs(blob, "recto.svg");
    var blob = new Blob(['<?xml version="1.0" encoding="UTF-8" standalone="no"?>'+$('.page2').html()], {type: "image/svg;charset=utf-8"});
    saveAs(blob, "verso.svg");
  };
});

myApp.controller('svgCtrl', function ($scope, pjFactory) {
  $scope.pj = pjFactory.vars;
  $scope.cons = pjFactory.cons;

  // TODO : Move the watchers in service/factory ?
  // Attributes watcher
  $scope.$watch('pj.attributes', function(newval, oldval) {
    // Combat Actions
    if (newval.DEX && newval.INT) {
      $scope.pj.calc.ac= Math.ceil(Math.ceil((newval.DEX + newval.INT)/2)/6);
    } else {
      $scope.pj.calc.ac = 0
    };
    // Damage Modifier
    if (newval.FOR || newval.TAI) {
      dicetable = [
        "-1D8", "-1D6", "-1D4", "-1D2",
        "+0",
        "+1D2", "+1D4", "+1D6", "+1D8", "+1D10", "+1D12",
        "+2D6", "+2D8", "+2D10", "+2D12",
        ];
      md = dicetable[Math.floor((newval.FOR + newval.TAI) / 5)];
      $scope.pj.calc.md = md;
    } else {
      $scope.pj.calc.md = "";
    };
    // Modificateur d'amélioration
    if (newval.CHA) {
      ma = Math.floor((newval.CHA -7) / 6);
      if (ma>0) {
        ma = "+" + ma;
      } else {
        ma = ""+ma
      }
      $scope.pj.calc.ma = ma;
    } else {
      $scope.pj.calc.ma = "0";
    };
    // Points de magie
    if (newval.POU) {
      $scope.pj.calc.pm = newval.POU - $scope.pj.calc.pd;
    };
    // Points de vie
    if (newval.CON || newval.TAI) {
      contai = newval.CON + newval.TAI;
      $scope.pj.body.head.pv = Math.ceil(contai/5);
      $scope.pj.body.chest.pv = Math.ceil((contai+10)/5);
      $scope.pj.body.bide.pv = Math.ceil((contai+5)/5);
      $scope.pj.body.rarm.pv = Math.ceil(contai/5);
      $scope.pj.body.larm.pv = Math.ceil(contai/5);
      if (contai < 6) {
        $scope.pj.body.rfoot.pv = 1;
        $scope.pj.body.lfoot.pv = 1;
      } else {
        $scope.pj.body.rfoot.pv = Math.ceil((contai-5)/5);
        $scope.pj.body.lfoot.pv = Math.ceil((contai-5)/5);
      };
    } else {
      $scope.pj.body.head.pv = 0;
      $scope.pj.body.chest.pv = 0;
      $scope.pj.body.bide.pv = 0;
      $scope.pj.body.rarm.pv = 0;
      $scope.pj.body.larm.pv = 0;
    };
    // Rang d'action
    if (newval.DEX || newval.INT) {
      $scope.pj.calc.ra = Math.ceil((newval.INT+newval.DEX)/2);
    } else {
      $scope.pj.calc.ra = 0;
    };
  }, true);

  // Attributes body
  $scope.$watch('pj.body', function(newval, oldval) {
    // Pénalité d'armure
    totalpa = newval.head.pa +
      newval.chest.pa +
      newval.bide.pa +
      newval.rarm.pa +
      newval.larm.pa +
      newval.rfoot.pa +
      newval.lfoot.pa;
    $scope.pj.calc.pa = Math.ceil(totalpa/5);
  }, true);

  $scope.getBase = function (skill) {
    var base = $scope.pj.attributes[skill.init[0]]+$scope.pj.attributes[skill.init[1]];
    var text = "";
    if (skill.base == null) {
      skill.base = base;
      skill.value = base;
    } else if (skill.base != base) {
      skill.value += base - skill.base;
      skill.base = base;
    };
    if ( skill.init[0] == skill.init[1]) {
      text = skill.init[0]+"x2";
    } else {
      text = skill.init[0]+"+"+skill.init[1];
    };
    if (base != 0) {
      return text + " ("+base+"%)";
    } else {
      return text
    };
  };
});
<commit_msg>fix foot/arms<commit_after>var myApp = angular.module("myApp", []);

// Directive template for later usage
myApp.directive("editable", function () {
  return {
    restrict: 'E',
    link: function (scope, element, attrs) {
      element.html("
Hello there
")
    }
  }
});

// Global parameters for pagination
myApp.factory('pjFactory', function () {
  factory = {};
  factory.vars = {};
  // Vars
  factory.vars.attributes = {
    FOR: 0,
    CON: 0,
    DEX: 0,
    TAI: 0,
    INT: 0,
    POU: 0,
    CHA: 0,
  };
  factory.vars.calc = {};
  factory.vars.calc.ac = 0;
  factory.vars.calc.md = 0;
  factory.vars.calc.ma = 0;
  factory.vars.calc.mv = "";
  factory.vars.calc.pd = 0;
  factory.vars.calc.pm = 0;
  factory.vars.calc.ra = 0;
  factory.vars.body = {
    head: {pv: 0, pa: 0},
    chest: {pv: 0, pa: 0},
    bide: {pv: 0, pa: 0},
    rarm: {pv: 0, pa: 0},
    larm: {pv: 0, pa: 0},
    rfoot: {pv: 0, pa: 0},
    lfoot: {pv: 0, pa: 0},
  };
  factory.vars.edit = false;
  factory.vars.head = {};
  factory.vars.head.name = "";
  factory.vars.head.player = "";
  factory.vars.head.race = "";
  factory.vars.head.sex = "";
  factory.vars.head.culture = "";
  factory.vars.head.origin = "";
  factory.vars.head.job = "";
  factory.vars.head.family = "";
  factory.vars.head.age = "";
  factory.vars.head.hair = "";
  factory.vars.head.eyes = "";
  factory.vars.head.weight = "";
  factory.vars.skills = [
    {name: "Athlétisme", init:["FOR", "DEX"]},
    {name: "Bagarre", init:["FOR", "DEX"]},
    {name: "Chant", init:["CHA", "POU"]},
    {name: "Conduite", init:["DEX", "POU"]},
    {name: "Conn. (Régionale)", init:["INT", "INT"]},
    {name: "Culture (d'origine)", init:["INT", "INT"]},
    {name: "Danse", init:["DEX", "CHA"]},
    {name: "Discretion", init:["INT", "DEX"]},
    {name: "Endurance", init:["CON", "CON"]},
    {name: "Equitation", init:["DEX", "POU"]},
    {name: "Evaluer", init:["INT", "CHA"]},
    {name: "Evasion", init:["DEX", "DEX"]},
    {name: "Force Brute", init:["FOR", "TAI"]},
    {name: "Influence", init:["CHA", "CHA"]},
    {name: "Natation", init:["FOR", "CON"]},
    {name: "Passe-passe", init:["DEX", "CHA"]},
    {name: "Perception", init:["POU", "INT"]},
    {name: "Persévérance", init:["POU", "POU"]},
    {name: "Perspicacité", init:["INT", "POU"]},
    {name: "Premiers soins", init:["INT", "DEX"]},
  ];
  factory.vars.advskills = [];
  factory.vars.cmbskills = [];
  factory.vars.div = {};
  // Helpers
  factory.save = function () {
    localStorage["pjhead"] = JSON.stringify(factory.vars.head);
    localStorage["pjskills"] = JSON.stringify(factory.vars.skills);
    localStorage["pjadvskills"] = JSON.stringify(factory.vars.advskills);
    localStorage["pjcmbskills"] = JSON.stringify(factory.vars.cmbskills);
    localStorage["pjattributes"] = JSON.stringify(factory.vars.attributes);
    localStorage["pjcalc"] = JSON.stringify(factory.vars.calc);
    localStorage["pjbody"] = JSON.stringify(factory.vars.body);
    localStorage["pjdiv"] = JSON.stringify(factory.vars.div);
    console.log("Saved");
  };
  factory.load = function () {
    factory.vars.head = JSON.parse(localStorage["pjhead"]);
    factory.vars.skills = JSON.parse(localStorage["pjskills"]);
    factory.vars.advskills = JSON.parse(localStorage["pjadvskills"]);
    factory.vars.cmbskills = JSON.parse(localStorage["pjcmbskills"]);
    factory.vars.attributes = JSON.parse(localStorage["pjattributes"]);
    factory.vars.calc = JSON.parse(localStorage["pjcalc"]);
    factory.vars.body = JSON.parse(localStorage["pjbody"]);
    factory.vars.div = JSON.parse(localStorage["pjdiv"]);
    console.log("loaded");
  };
  factory.reset = function () {
    //localStorage.removeItem("pjhead");
    //localStorage.removeItem("pjskills");
    //localStorage.removeItem("pjattributes");
    angular.forEach(factory.vars.head, function (value, key) {
      factory.vars.head[key] = "";
    });
    angular.forEach(factory.vars.attributes, function (value, key) {
      factory.vars.attributes[key] = 0;
    });
    factory.vars.calc.pm = 0;
    factory.vars.calc.pd = 0;
    factory.vars.calc.mv = "";
    factory.vars.body = {
      head: {pv: 0, pa: 0},
      chest: {pv: 0, pa: 0},
      bide: {pv: 0, pa: 0},
      rarm: {pv: 0, pa: 0},
      larm: {pv: 0, pa: 0},
      rfoot: {pv: 0, pa: 0},
      lfoot: {pv: 0, pa: 0},
    }
    angular.forEach(factory.vars.skills, function (value, key) {
      obj = factory.vars.attributes[key];
      if (obj) {
        delete factory.vars.attributes[key]["base"];
        delete factory.vars.attributes[key]["value"];
      };
    });
    factory.vars.advskills.length = 0;
    factory.vars.cmbskills.length = 0;
    factory.vars.div = {}
    console.log("reset");
  };
  factory.example = function () {
    factory.vars.attributes = {
      FOR: 12,
      CON: 13,
      DEX: 14,
      TAI: 12,
      INT: 10,
      POU: 12,
      CHA: 14,
    };
    factory.vars.head.name = "Jon Snow";
    factory.vars.head.player = "Cyberj";
    factory.vars.head.race = "Humain";
    factory.vars.head.sex = "H";
    factory.vars.head.culture = "Civilisée";
    factory.vars.head.origin = "Nordique";
    factory.vars.head.job = "Patrouilleur";
    factory.vars.head.family = "Starck";
    factory.vars.head.age = "22";
    factory.vars.head.hair = "Noir";
    factory.vars.head.eyes = "Noirs";
    factory.vars.head.weight = "75Kg";
    factory.vars.calc.mv = "8m";
    factory.vars.body.chest.pa = 1;
    factory.vars.body.bide.pa = 1;
    factory.vars.body.head.pa = 1;
    factory.vars.body.larm.pa = 1;
    factory.vars.body.rarm.pa = 1;
    factory.vars.advskills = [
      {name: "Empathie", init:["CHA", "POU"], value:45, base: 26},
      {name: "Conn (Le mur)", init:["INT", "INT"], value:60, base: 20},
    ];
    factory.vars.cmbskills = [
      {name: "Épée a deux mains", init:["FOR", "DEX"], value:65, base: 26},
    ];
    factory.vars.div.armor = [
      {name: "Cuir souple"},
    ]

  };
  factory.cons = {};
  factory.cons.attrs = [
    "FOR", "CON", "DEX", "TAI", "INT", "POU", "CHA",
  ];
  factory.periods = [
    {key: "3days", value: "3 days"},
    {key: "curweek", value: "Current week"},
    {key: "curmonth", value: "Current month"},
    {key: "curyear", value: "Current year"},
    {key: "week", value: "A week"},
    {key: "month", value: "A month"},
    {key: "year", value: "A year"},
    {key: "all", value: "Whole mailbox"},
  ];
  return factory;
});

myApp.controller('skillsCtrl', function ($scope, pjFactory) {
  $scope.cons = pjFactory.cons;
  $scope.vars = pjFactory.vars;
  $scope.pj = pjFactory.vars;
  $scope.newskill = {base1:"FOR", base2:"FOR"};
  $scope.newcskill = {base1:"FOR", base2:"DEX"};
  $scope.getBase = function (skill) {
    var base = $scope.vars.attributes[skill.init[0]]+$scope.vars.attributes[skill.init[1]];
    var text = "";
    if (skill.base == null) {
      skill.base = base;
      skill.value = base;
    } else if (skill.base != base) {
      skill.value += base - skill.base;
      skill.base = base;
    };
    if ( skill.init[0] == skill.init[1]) {
      text = skill.init[0]+"x2";
    } else {
      text = skill.init[0]+"+"+skill.init[1];
    };
    return text + " ("+base+"%)"
  };
  $scope.addSkill = function () {
    nskill = {name: $scope.newskill.name, init: [$scope.newskill.base1, $scope.newskill.base2]}
    $scope.pj.advskills.push(nskill);
    $scope.newskill = {base1:"FOR", base2:"FOR"};

  };
  $scope.addcSkill = function () {
    ncskill = {name: $scope.newcskill.name, init: [$scope.newcskill.base1, $scope.newcskill.base2]}
    $scope.pj.cmbskills.push(ncskill);
    $scope.newcskill = {base1:"FOR", base2:"DEX"};

  };
  $scope.rmSkill = function (index) {
    $scope.pj.advskills.pop(index);
  };
  $scope.rmcSkill = function (index) {
    $scope.pj.cmbskills.pop(index);
  };
});

myApp.controller('attrCtrl', function ($scope, pjFactory) {
  $scope.vars = pjFactory.vars;
  $scope.pj = pjFactory.vars;
});

myApp.controller('headCtrl', function ($scope, pjFactory) {
  $scope.pj = pjFactory.vars;
  $scope.vars = pjFactory.vars;
  $scope.save = pjFactory.save;
  $scope.load = pjFactory.load;
  $scope.reset = pjFactory.reset;
  $scope.example = pjFactory.example;
  $scope.share = function () {
    var blob = new Blob(['<?xml version="1.0" encoding="UTF-8" standalone="no"?>'+$('.page1').html()], {type: "image/svg;charset=utf-8"});
    saveAs(blob, "recto.svg");
    var blob = new Blob(['<?xml version="1.0" encoding="UTF-8" standalone="no"?>'+$('.page2').html()], {type: "image/svg;charset=utf-8"});
    saveAs(blob, "verso.svg");
  };
});

myApp.controller('svgCtrl', function ($scope, pjFactory) {
  $scope.pj = pjFactory.vars;
  $scope.cons = pjFactory.cons;

  // TODO : Move the watchers in service/factory ?
  // Attributes watcher
  $scope.$watch('pj.attributes', function(newval, oldval) {
    // Combat Actions
    if (newval.DEX && newval.INT) {
      $scope.pj.calc.ac= Math.ceil(Math.ceil((newval.DEX + newval.INT)/2)/6);
    } else {
      $scope.pj.calc.ac = 0
    };
    // Damage Modifier
    if (newval.FOR || newval.TAI) {
      dicetable = [
        "-1D8", "-1D6", "-1D4", "-1D2",
        "+0",
        "+1D2", "+1D4", "+1D6", "+1D8", "+1D10", "+1D12",
        "+2D6", "+2D8", "+2D10", "+2D12",
        ];
      md = dicetable[Math.floor((newval.FOR + newval.TAI) / 5)];
      $scope.pj.calc.md = md;
    } else {
      $scope.pj.calc.md = "";
    };
    // Modificateur d'amélioration
    if (newval.CHA) {
      ma = Math.floor((newval.CHA -7) / 6);
      if (ma>0) {
        ma = "+" + ma;
      } else {
        ma = ""+ma
      }
      $scope.pj.calc.ma = ma;
    } else {
      $scope.pj.calc.ma = "0";
    };
    // Points de magie
    if (newval.POU) {
      $scope.pj.calc.pm = newval.POU - $scope.pj.calc.pd;
    };
    // Points de vie
    if (newval.CON || newval.TAI) {
      contai = newval.CON + newval.TAI;
      $scope.pj.body.head.pv = Math.ceil(contai/5);
      $scope.pj.body.chest.pv = Math.ceil((contai+10)/5);
      $scope.pj.body.bide.pv = Math.ceil((contai+5)/5);
      $scope.pj.body.rfoot.pv = Math.ceil(contai/5);
      $scope.pj.body.lfoot.pv = Math.ceil(contai/5);
      if (contai < 6) {
        $scope.pj.body.rarm.pv = 1;
        $scope.pj.body.larm.pv = 1;
      } else {
        $scope.pj.body.rarm.pv = Math.ceil((contai-5)/5);
        $scope.pj.body.larm.pv = Math.ceil((contai-5)/5);
      };
    } else {
      $scope.pj.body.head.pv = 0;
      $scope.pj.body.chest.pv = 0;
      $scope.pj.body.bide.pv = 0;
      $scope.pj.body.rarm.pv = 0;
      $scope.pj.body.larm.pv = 0;
    };
    // Rang d'action
    if (newval.DEX || newval.INT) {
      $scope.pj.calc.ra = Math.ceil((newval.INT+newval.DEX)/2);
    } else {
      $scope.pj.calc.ra = 0;
    };
  }, true);

  // Attributes body
  $scope.$watch('pj.body', function(newval, oldval) {
    // Pénalité d'armure
    totalpa = newval.head.pa +
      newval.chest.pa +
      newval.bide.pa +
      newval.rarm.pa +
      newval.larm.pa +
      newval.rfoot.pa +
      newval.lfoot.pa;
    $scope.pj.calc.pa = Math.ceil(totalpa/5);
  }, true);

  $scope.getBase = function (skill) {
    var base = $scope.pj.attributes[skill.init[0]]+$scope.pj.attributes[skill.init[1]];
    var text = "";
    if (skill.base == null) {
      skill.base = base;
      skill.value = base;
    } else if (skill.base != base) {
      skill.value += base - skill.base;
      skill.base = base;
    };
    if ( skill.init[0] == skill.init[1]) {
      text = skill.init[0]+"x2";
    } else {
      text = skill.init[0]+"+"+skill.init[1];
    };
    if (base != 0) {
      return text + " ("+base+"%)";
    } else {
      return text
    };
  };
});
<|endoftext|>


<commit_before>$(window).resize(resizeAndRedrawCanvas);
$(document).ready(resizeAndRedrawCanvas);

function resizeAndRedrawCanvas() {
    var desiredWidth = $(window).width();
    var desiredHeight = $(window).height();

    canvas.width = desiredWidth;
    canvas.height = desiredHeight

    view.viewSize = new Size(desiredWidth, desiredHeight);
    view.draw();
}

var pxRatio = window.devicePixelRatio;

// Matter.js module aliases
var Engine = Matter.Engine,
    World = Matter.World,
    Bodies = Matter.Bodies,
    Composites = Matter.Composites,
    Common = Matter.Common,
    Vertices = Matter.Vertices;

engine = Engine.create(document.body);
// engine = Engine.create({render: {visible: false}});

// init objects
var Objects = [];
var bodyOptions = {
  // frictionAir: 0.001,
  // friction: 0.8,
  // restitution: 0.4,
  isStatic: false
};

// create rectangle
function addRectangle(x, y, w, h, isStatic){
  // matterjs
  bodyOptions.isStatic = isStatic;
  World.add(engine.world, Bodies.rectangle(x, y, w, h, bodyOptions));
  // paperjs
  return new Path.Rectangle({
  	point: [x, y],
  	size: [w, h],
    fillColor: new Color(Math.random(), Math.random(), Math.random(), 1)
  });
}
// create circle
function addCircle(x, y, r, isStatic){
  // matterjs
  bodyOptions.isStatic = isStatic;
  World.add(engine.world, Bodies.circle(x, y, r, bodyOptions));
  // paperjs
  var circle = new Path.Circle(new Point(x, y), r);
  circle.fillColor = new Color(Math.random(), Math.random(), Math.random(), 1)
  return circle;
}

function boundsCenter(minX, minY, maxX, maxY){
  return new Point((maxX + minX)/2, (maxY + minY)/2);
}

function addVertices(string){
  var vertices = Vertices.fromPath(string);
  object = Bodies.fromVertices(Matter.Vertices.centre(vertices).x, Matter.Vertices.centre(vertices).y, vertices, {
                isStatic: true,
                render: {
                    fillStyle: 'red',
                    strokeStyle: 'red'
                }
            }, true);
  Matter.World.add(engine.world, object);

  var path = new Path();
  for(i = 0; i < vertices.length; i++){
    path.add(new Point(vertices[i].x, vertices[i].y));
  }
  path.fillColor = new Color(Math.random(), Math.random(), Math.random(), 1);
  path.closed = true;
  path.selected = true;

  return path;
}

// add random objects
for (var i = 0; i < 5; i++){
  random = Math.random() * 100;
  Objects.push(addRectangle(random + 300, random, random, random, false));
  Objects.push(addCircle(random + 300, random, random, false));
}

// add ground
Objects.push(addRectangle(canvas.width/pxRatio/2, canvas.height/pxRatio -10, canvas.width/pxRatio, 20, true));

function notInView(body, w, h){
  if(body.bounds.max.x < 0  || body.bounds.min.x > canvas.width/pxRatio){
      return true;
  }
  return false;
}

// vertices= [{ x: 300, y: 300 }, { x: 270, y: 400 }, { x: 400, y: 400 }, {x:400, y:300}];
// Objects.push(addVertices(vertices));

// vertices= [{ x: 600, y: 600 }, { x: 700, y: 700 }, { x: 800, y: 600 }];
// Objects.push(addPath(vertices));

function onFrame(event) {
  for(it in engine.world.bodies){
    var body = engine.world.bodies[it];
    var render = Objects[it];

    bounds = body.bounds;
    // paperjs calculates position as the center of the bounding rectangle
    // matterjs calculates position as the centroid of the object
    render.position = boundsCenter(bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y);
    // render.position = body.position;
    rotation = -(body.anglePrev - body.angle) * 180 / Math.PI;
    render.rotate(rotation);

    if(notInView(body)){
      World.remove(engine.world, body);
      Objects[it].remove();
      Objects.splice(it, 1);
    }
  }
}

// run the engine
Engine.run(engine);

var mousePath;

function onMouseDrag(event) {
  var step = event.delta / 2;
  step.angle += 90;
  step.length = 10;

  var top = event.middlePoint + step;
  var bottom = event.middlePoint - step;

  mousePath.add(top);
  mousePath.insert(0, bottom);

  // random = Math.random() * 100;
  // Objects.push(addRectangle(event.point.x, event.point.y, random, random, false));
  // Objects.push(addCircle(event.point.x, event.point.y, random, false));
}

function onMouseDown(event) {
  mousePath = new Path();
  mousePath.fillColor = {
    hue: Math.random() * 360,
    saturation: 1,
    brightness: 1
  };

  // mousePath.add(event.point);

  random = Math.random() * 100;
  Objects.push(addRectangle(event.point.x, event.point.y, random, random, false));
  Objects.push(addCircle(event.point.x, event.point.y, random, false));
}

function onMouseUp(event) {
	mousePath.add(event.point);
	mousePath.closed = true;
	// mousePath.smooth();
  // mousePath.simpl  ify();

  var pathVertices = '';
  for(i = 0; i < mousePath.segments.length; i++){
    pathVertices += ' ' + mousePath.segments[i].point.x.toString();
    pathVertices += ' ' + mousePath.segments[i].point.y.toString();
  }
  Objects.push(addVertices(pathVertices));
}
<commit_msg>debug<commit_after>$(window).resize(resizeAndRedrawCanvas);
$(document).ready(resizeAndRedrawCanvas);

function resizeAndRedrawCanvas() {
    var desiredWidth = $(window).width();
    var desiredHeight = $(window).height();

    canvas.width = desiredWidth;
    canvas.height = desiredHeight

    view.viewSize = new Size(desiredWidth, desiredHeight);
    view.draw();
}

var pxRatio = window.devicePixelRatio;

// Matter.js module aliases
var Engine = Matter.Engine,
    World = Matter.World,
    Bodies = Matter.Bodies,
    Composites = Matter.Composites,
    Common = Matter.Common,
    Vertices = Matter.Vertices;

engine = Engine.create(document.body);
// engine = Engine.create({render: {visible: false}});

// init objects
var Objects = [];
var bodyOptions = {
  // frictionAir: 0.001,
  // friction: 0.8,
  // restitution: 0.4,
  isStatic: false
};

// create rectangle
function addRectangle(x, y, w, h, isStatic){
  // matterjs
  bodyOptions.isStatic = isStatic;
  World.add(engine.world, Bodies.rectangle(x, y, w, h, bodyOptions));
  // paperjs
  return new Path.Rectangle({
  	point: [x, y],
  	size: [w, h],
    fillColor: new Color(Math.random(), Math.random(), Math.random(), 1)
  });
}
// create circle
function addCircle(x, y, r, isStatic){
  // matterjs
  bodyOptions.isStatic = isStatic;
  World.add(engine.world, Bodies.circle(x, y, r, bodyOptions));
  // paperjs
  var circle = new Path.Circle(new Point(x, y), r);
  circle.fillColor = new Color(Math.random(), Math.random(), Math.random(), 1)
  return circle;
}

function boundsCenter(minX, minY, maxX, maxY){
  return new Point((maxX + minX)/2, (maxY + minY)/2);
}

function addVertices(string){
  var vertices = Vertices.fromPath(string);
  object = Bodies.fromVertices(Matter.Vertices.centre(vertices).x, Matter.Vertices.centre(vertices).y, vertices, {
                isStatic: true,
                render: {
                    fillStyle: 'red',
                    strokeStyle: 'red'
                }
            }, true);
  Matter.World.add(engine.world, object);

  var path = new Path();
  for(i = 0; i < vertices.length; i++){
    path.add(new Point(vertices[i].x, vertices[i].y));
  }
  path.fillColor = new Color(Math.random(), Math.random(), Math.random(), 1);
  path.closed = true;
  path.selected = true;
  path.visible = false;

  return path;
}

// add random objects
for (var i = 0; i < 5; i++){
  random = Math.random() * 100;
  // Objects.push(addRectangle(random + 300, random, random, random, false));
  // Objects.push(addCircle(random + 300, random, random, false));
}

// add ground
// Objects.push(addRectangle(canvas.width/pxRatio/2, canvas.height/pxRatio -10, canvas.width/pxRatio, 20, true));

function notInView(body, w, h){
  if(body.bounds.max.x < 0  || body.bounds.min.x > canvas.width/pxRatio){
      return true;
  }
  return false;
}

vertices= "600, 600, 700, 700, 800, 600";
// Objects.push(addVertices(vertices));

// vertices= [{ x: 600, y: 600 }, { x: 700, y: 700 }, { x: 800, y: 600 }];
// Objects.push(addPath(vertices));

var c = 0;
function onFrame(event) {
  for(it in engine.world.bodies){
    var body = engine.world.bodies[it];
    var render = Objects[it];

    bounds = body.bounds;
    // paperjs calculates position as the center of the bounding rectangle
    // matterjs calculates position as the centroid of the object
    if(c==0){
      console.log(render);
      console.log("matterjs by bounds " + boundsCenter(bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y));
      console.log("bounds: " + Math.floor(bounds.min.x) + " " + Math.floor(bounds.min.y) + " " + Math.floor(bounds.max.x) + " " + Math.floor(bounds.max.y));
      console.log("matterjs by center " + Math.floor(body.position.x) + " " + Math.floor(body.position.y));
      console.log("paperjs" + render.position);
      c = 1;

      console.log(boundsCenter(bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y) - body.position);
    }
    render.position = boundsCenter(bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y);
    // render.position = body.position;
    rotation = -(body.anglePrev - body.angle) * 180 / Math.PI;
    render.rotate(rotation);

    if(notInView(body)){
      World.remove(engine.world, body);
      Objects[it].remove();
      Objects.splice(it, 1);
    }
  }
}

// run the engine
Engine.run(engine);

var mousePath;

function onMouseDrag(event) {
  var step = event.delta / 2;
  step.angle += 90;
  step.length = 4;

  var top = event.middlePoint + step;
  var bottom = event.middlePoint - step;

  mousePath.add(top);
  mousePath.insert(0, bottom);

  // random = Math.random() * 100;
  // Objects.push(addRectangle(event.point.x, event.point.y, random, random, false));
  // Objects.push(addCircle(event.point.x, event.point.y, random, false));
}

function onMouseDown(event) {
  mousePath = new Path();
  mousePath.fillColor = {
    hue: Math.random() * 360,
    saturation: 1,
    brightness: 1
  };

  // mousePath.add(event.point);

  random = Math.random() * 100;
  // Objects.push(addRectangle(event.point.x, event.point.y, random, random, false));
  // Objects.push(addCircle(event.point.x, event.point.y, random, false));
}

function onMouseUp(event) {
	mousePath.add(event.point);
	mousePath.closed = true;
	// mousePath.smooth();
  // mousePath.simplify();

  var pathVertices = '';
  for(i = 0; i < mousePath.segments.length; i++){
    pathVertices += ' ' + mousePath.segments[i].point.x.toString();
    pathVertices += ' ' + mousePath.segments[i].point.y.toString();
  }
  Objects.push(addVertices(pathVertices));
}
<|endoftext|>


<commit_before>var sys, timeout = null;

const CowChatCommand = {
  isCommand : function(data){
    return data.message.indexOf("/") === 0;
  },
  getCommand : function(data){
    if(this.isCommand(data)){
      return data.message.split(" ")[0].substr(1);
    }
    return null;
  },
  getContext : function(data){
    if(this.isCommand(data)){
      var start = this.getCommand(data).length+1;
      if(data.message.indexOf(" ") != -1){
        return data.message.substr(start+1);
      }
    }
    return data.message;
  }
};

const System = (function(){
  function System(input, gui){
    this.callback    = {};
    this.pages       = {};
    this.input       = input;
    this.gui         = gui;
    this.current = null;

    this.validCommand = [
       "join"
    ];
  }

  System.prototype.event = function(name, callback){
    if(typeof this.callback[name] === "undefined")
      this.callback[name] = [];
    this.callback[name].push(callback);
  }

  System.prototype.trigger = function(name, data){
    if(typeof this.callback[name] === "undefined")
      return;

    for(var i=0;i<this.callback[name].length;i++){
      this.callback[name][i].apply(this, data);
    }
  };

  System.prototype.inputText = function(){
     return this.input.value;
  };

  System.prototype.setInputText = function(text){
     this.input.value = text;
  };

  System.prototype.getPage = function(name){
    if(typeof this.pages[name] === "undefined")
      return null;
    return this.pages[name];
  };

  System.prototype.currentPage = function(){
    if(typeof this.pages[this.current] !== "undefined"){
      return this.pages[this.current];
    }
    return null;
  };

  System.prototype.appendPage = function(name){
     this.createPage(name);
     send(name, "/title");
     send(name, "/online");
  };

  System.prototype.createPage = function(name){
    var page = new Page(
      name,
      this.gui.createButtom(name, this),
      new UserList(this),
      this.gui.initContextContainer(),
      this
    );
    this.pages[name] = page;
    this.selectPage(name);
    return page;
  };

  System.prototype.selectPage = function(name){
    if(typeof this.pages[name] === "undefined"){
      return false;
    }

    if(typeof this.pages[this.current] !== "undefined"){
      this.pages[this.current].hide();
    }

    this.pages[name].show();
    this.current = name;
    return true;
  };

  System.prototype.isFocus = function(name){
    return this.current == name;
  };

  return System;
})();

function startChat(input, gui){
  sys = new System(input, gui);
  input.onkeyup = function(e){
    sys.trigger("input.keyup", [e]);
  };
  sys.event("input.keyup", handleInput);
  var page = sys.createPage("console");
  connect();
}

function connect(){
    stopUpdate();
    var ajax = new XMLHttpRequest();
    var chan;
    if(sys.currentPage().name == "console"){
      chan = "";
    }else{
      chan = "&channel="+sys.currentPage();
    }
    ajax.open("GET", "?_ajax=true"+chan, true);
    ajax.onreadystatechange = onAjaxRespons;
    ajax.send();
}

function onAjaxRespons(){
  if(this.readyState == 4){
    if(this.status != 200){
      sys.getPage("console").line("", "Ajax", "", "[color=red]"+encodeURI(this.responseText)+"[/color]");
      setUpdate();
      return;
    }
    var j;
    try{
      j = JSON.parse(this.responseText);
    }catch(e){
      if(e.responseText == "login"){
        location.reload();
        return;
      }else{
        sys.getPage("console").line("","","AjaxError", "[color=red]There happend a error: "+this.responseText+"[/color]");
        setUpdate();
        return;
      }
    }
    for(var i=0;i<j.message.length;i++){
       handleResponsPart(j.message[i]);
    }
    setUpdate();
  }
}

function handleResponsPart(data){
  if(data.channel == "Bot"){
    if(CowChatCommand.isCommand(data) && handleResponsPartBotCommand(data)){
      return;
    }
  }

  const p = sys.getPage(data.channel == "Bot" ? "console" : data.message);
  if(!p){
    sys.getPage("console").line("", "", "Bot", "[color=red]Unknown channel "+j.message[i].channel+"[/color]");
    sys.getPage("console").line(j.message[i].time, "", j.message[i].nick, j.message[i].message);
    return;
  }
  p.onRespons(data);
}

function handleResponsPartBotCommand(data){
  switch(CowChatCommand.getCommand(data)){
    case "ban":
      onMyBan(data);
    break;
    case "kick":
      onMyKick(data);
    break;
    case "exit":
      location.reload();
    break;
    case "join":
      sys.createPage(CowScriptCommand.getContext(data));
    break;
    case "leave":
      onLeave(data);
    break;
    case "avatar":
      document.getElementById("user-avatar").style.backgroundImage = "url('"+CowScriptCommand.getContext(data)+"')";
      sys.getPage("console").line(
             j.message[i].time,
             "",
             "Bot",
             language["onAvatar"]
           );
    break;
    default:
      return false;
  }
  return true;
}

function setUpdate(){
  timeout = setTimeout(connect, updateFrame);
}

function stopUpdate(){
  if(timeout !== null){
    clearTimeout(timeout);
  }
}

function onMyBan(data){
  var channel = CowChatCommand.getContext(data);
  var page = sys.getPage(channel);
  if(!page){
    sys.getPage("console").line(
      data.time,
      "",
      "Bot",
      "[color=red]Unknown channel: "+channel+"[/color]"
    );
    return;
  }
  page.remove();
  sys.getPage("console").line(
    data.time,
    "",
    "Bot",
    "[color=red]You are bannet from the channel "+channel+"[/color]"
  );
}

function onMyKick(data){
  var message = CowChatCommand.getContext(data);
  var pos = message.indexOf(" ");
  var nick = message.substr(0, pos);
  message = message.substr(pos+1);
  pos = message.indexOf(" ");
  var channel = message.substr(0, pos);
  message = message.substr(pos+1);
  const page = sys.getPage(channel);
  if(page == null){
    sys.getPage("console").line(data.time, "", "Bot", "[color=red]Unknown channel: "+channel+"[/color]");
  }
  page.remove();
  delete sys.pages[channel];
  sys.getPage("console").line(
    data.time,
    "",
    "Bot",
    "[color=red]"+language["myKick"].replace("%nick", nick).replace("%channel", channel).replace("%message", message)+"[/color]"
  );
}

function onLeave(time, channel){
  const page = sys.getPage(channel);
  if(page == null){
    sys.getPage("console").line(time, "", "Bot", "[color=red]Unknown channel: "+channel+"[/color]");
    return;
  }
  page.remove();
  delete sys.pages[channel];
  sys.getPage("console").line(time, "", "Bot", "[color=red]"+language["myLeave"].replace("%channel", channel)+"[/color]");
}

function send(channel, message){
  stopUpdate();
  var ajax = new XMLHttpRequest();
  ajax.open("POST", "?_ajax=true&isPost=true&channel="+encodeURIComponent(channel), true);
  ajax.onreadystatechange = onAjaxRespons;
  ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  ajax.send("message="+encodeURIComponent(message));
}

//handle input from the input o.O
function handleInput(e){
  if(e.keyCode == 13 && this.inputText().trim().length != 0){
    const text = this.inputText();

    if(text.charAt(0) == "/"){
      var command;
      if((pos = text.indexOf(" ")) != -1){
        command = text.substr(1, pos-1);
      }else{
        command = text.substr(1);
      }
      if(sys.validCommand.indexOf(command) != -1){
         send("", text);
         this.setInputText("");
         return;
      }
    }

    if(this.currentPage().name == "console"){
       this.currentPage().line("", "", "Bot", "[color=red]"+language["writeConsole"]+"[/color]");
       this.setInputText("");
       return;
    }

     send(this.currentPage().name, this.inputText());
    this.setInputText("");
  }
}
<commit_msg>Update main.js<commit_after>var sys, timeout = null;

const CowChatCommand = {
  isCommand : function(data){
    return data.message.indexOf("/") === 0;
  },
  getCommand : function(data){
    if(this.isCommand(data)){
      return data.message.split(" ")[0].substr(1);
    }
    return null;
  },
  getContext : function(data){
    if(this.isCommand(data)){
      var start = this.getCommand(data).length+1;
      if(data.message.indexOf(" ") != -1){
        return data.message.substr(start+1);
      }
    }
    return data.message;
  }
};

const System = (function(){
  function System(input, gui){
    this.callback    = {};
    this.pages       = {};
    this.input       = input;
    this.gui         = gui;
    this.current = null;

    this.validCommand = [
       "join"
    ];
  }

  System.prototype.event = function(name, callback){
    if(typeof this.callback[name] === "undefined")
      this.callback[name] = [];
    this.callback[name].push(callback);
  }

  System.prototype.trigger = function(name, data){
    if(typeof this.callback[name] === "undefined")
      return;

    for(var i=0;i<this.callback[name].length;i++){
      this.callback[name][i].apply(this, data);
    }
  };

  System.prototype.inputText = function(){
     return this.input.value;
  };

  System.prototype.setInputText = function(text){
     this.input.value = text;
  };

  System.prototype.getPage = function(name){
    if(typeof this.pages[name] === "undefined")
      return null;
    return this.pages[name];
  };

  System.prototype.currentPage = function(){
    if(typeof this.pages[this.current] !== "undefined"){
      return this.pages[this.current];
    }
    return null;
  };

  System.prototype.appendPage = function(name){
     this.createPage(name);
     send(name, "/title");
     send(name, "/online");
  };

  System.prototype.createPage = function(name){
    var page = new Page(
      name,
      this.gui.createButtom(name, this),
      new UserList(this),
      this.gui.initContextContainer(),
      this
    );
    this.pages[name] = page;
    this.selectPage(name);
    return page;
  };

  System.prototype.selectPage = function(name){
    if(typeof this.pages[name] === "undefined"){
      return false;
    }

    if(typeof this.pages[this.current] !== "undefined"){
      this.pages[this.current].hide();
    }

    this.pages[name].show();
    this.current = name;
    return true;
  };

  System.prototype.isFocus = function(name){
    return this.current == name;
  };

  return System;
})();

function startChat(input, gui){
  sys = new System(input, gui);
  input.onkeyup = function(e){
    sys.trigger("input.keyup", [e]);
  };
  sys.event("input.keyup", handleInput);
  var page = sys.createPage("console");
  connect();
}

function connect(){
    stopUpdate();
    var ajax = new XMLHttpRequest();
    var chan;
    if(sys.currentPage().name == "console"){
      chan = "";
    }else{
      chan = "&channel="+sys.currentPage();
    }
    ajax.open("GET", "?_ajax=true"+chan, true);
    ajax.onreadystatechange = onAjaxRespons;
    ajax.send();
}

function onAjaxRespons(){
  if(this.readyState == 4){
    if(this.status != 200){
      sys.getPage("console").line("", "Ajax", "", "[color=red]"+encodeURI(this.responseText)+"[/color]");
      setUpdate();
      return;
    }
    var j;
    try{
      j = JSON.parse(this.responseText);
    }catch(e){
      if(e.responseText == "login"){
        location.reload();
        return;
      }else{
        sys.getPage("console").line("","","AjaxError", "[color=red]There happend a error: "+this.responseText+"[/color]");
        setUpdate();
        return;
      }
    }
    for(var i=0;i<j.message.length;i++){
       handleResponsPart(j.message[i]);
    }
    setUpdate();
  }
}

function handleResponsPart(data){
  if(data.channel == "Bot"){
    if(CowChatCommand.isCommand(data) && handleResponsPartBotCommand(data)){
      return;
    }
  }

  const p = sys.getPage(data.channel == "Bot" ? "console" : data.channel);
  if(!p){
    sys.getPage("console").line("", "", "Bot", "[color=red]Unknown channel "+data.channel+"[/color]");
    sys.getPage("console").line(data.time, "", data.nick, data.message);
    return;
  }
  p.onRespons(data);
}

function handleResponsPartBotCommand(data){
  switch(CowChatCommand.getCommand(data)){
    case "ban":
      onMyBan(data);
    break;
    case "kick":
      onMyKick(data);
    break;
    case "exit":
      location.reload();
    break;
    case "join":
      sys.createPage(CowScriptCommand.getContext(data));
    break;
    case "leave":
      onLeave(data);
    break;
    case "avatar":
      document.getElementById("user-avatar").style.backgroundImage = "url('"+CowScriptCommand.getContext(data)+"')";
      sys.getPage("console").line(
             j.message[i].time,
             "",
             "Bot",
             language["onAvatar"]
           );
    break;
    default:
      return false;
  }
  return true;
}

function setUpdate(){
  timeout = setTimeout(connect, updateFrame);
}

function stopUpdate(){
  if(timeout !== null){
    clearTimeout(timeout);
  }
}

function onMyBan(data){
  var channel = CowChatCommand.getContext(data);
  var page = sys.getPage(channel);
  if(!page){
    sys.getPage("console").line(
      data.time,
      "",
      "Bot",
      "[color=red]Unknown channel: "+channel+"[/color]"
    );
    return;
  }
  page.remove();
  sys.getPage("console").line(
    data.time,
    "",
    "Bot",
    "[color=red]You are bannet from the channel "+channel+"[/color]"
  );
}

function onMyKick(data){
  var message = CowChatCommand.getContext(data);
  var pos = message.indexOf(" ");
  var nick = message.substr(0, pos);
  message = message.substr(pos+1);
  pos = message.indexOf(" ");
  var channel = message.substr(0, pos);
  message = message.substr(pos+1);
  const page = sys.getPage(channel);
  if(page == null){
    sys.getPage("console").line(data.time, "", "Bot", "[color=red]Unknown channel: "+channel+"[/color]");
  }
  page.remove();
  delete sys.pages[channel];
  sys.getPage("console").line(
    data.time,
    "",
    "Bot",
    "[color=red]"+language["myKick"].replace("%nick", nick).replace("%channel", channel).replace("%message", message)+"[/color]"
  );
}

function onLeave(time, channel){
  const page = sys.getPage(channel);
  if(page == null){
    sys.getPage("console").line(time, "", "Bot", "[color=red]Unknown channel: "+channel+"[/color]");
    return;
  }
  page.remove();
  delete sys.pages[channel];
  sys.getPage("console").line(time, "", "Bot", "[color=red]"+language["myLeave"].replace("%channel", channel)+"[/color]");
}

function send(channel, message){
  stopUpdate();
  var ajax = new XMLHttpRequest();
  ajax.open("POST", "?_ajax=true&isPost=true&channel="+encodeURIComponent(channel), true);
  ajax.onreadystatechange = onAjaxRespons;
  ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  ajax.send("message="+encodeURIComponent(message));
}

//handle input from the input o.O
function handleInput(e){
  if(e.keyCode == 13 && this.inputText().trim().length != 0){
    const text = this.inputText();

    if(text.charAt(0) == "/"){
      var command;
      if((pos = text.indexOf(" ")) != -1){
        command = text.substr(1, pos-1);
      }else{
        command = text.substr(1);
      }
      if(sys.validCommand.indexOf(command) != -1){
         send("", text);
         this.setInputText("");
         return;
      }
    }

    if(this.currentPage().name == "console"){
       this.currentPage().line("", "", "Bot", "[color=red]"+language["writeConsole"]+"[/color]");
       this.setInputText("");
       return;
    }

     send(this.currentPage().name, this.inputText());
    this.setInputText("");
  }
}
<|endoftext|>


<commit_before>(function($, _){

  var Settings = {
    INTERVAL: 100,

    ui: {
      sudokuContainer: '#sudoku-container',
      speedText: '#speed',
      speedSelector: '#speed-selector',
      boardOptions: 'input[name=board]',
      startButton: '#start-button',
      resetButton: '#reset-button'
    },

    sudokuBoards: {
      board1: [
        [6,null,null,null,null,5,null,3,null],
        [4,8,null,2,7,null,null,null,null],
        [null,null,null,8,null,1,null,null,9],
        [null,null,null,null,1,null,8,4,null],
        [9,4,null,null,3,null,null,1,5],
        [null,3,1,null,2,null,null,null,null],
        [3,null,null,6,null,2,null,null,null],
        [null,null,null,null,5,7,null,8,2],
        [null,5,null,1,null,null,null,null,6]
      ],
      board2: [
        [1,null,null,null,null,null,4,null,null],
        [7,3,9,null,8,null,2,null,null],
        [6,null,4,3,null,null,null,null,null],
        [null,null,2,5,null,null,7,null,9],
        [null,9,1,7,null,4,3,6,null],
        [8,null,3,null,null,6,5,null,null],
        [null,null,null,null,null,7,6,null,3],
        [null,null,7,null,6,null,8,9,2],
        [null,null,6,null,null,null,null,null,5]
      ],
      board3: [
        [null,null,null,8,null,null,null,null,5],
        [3,7,null,null,null,null,null,8,null],
        [null,null,null,4,null,null,null,null,7],
        [8,null,7,6,null,2,null,1,3],
        [null,2,null,null,null,null,null,4,null],
        [5,1,null,3,null,4,2,null,8],
        [2,null,null,null,null,6,null,null,null],
        [null,8,null,null,null,null,null,5,4],
        [9,null,null,null,null,3,null,null,null]
      ],
      board4: [
        [null,9,8,null,null,null,4,7,null],
        [null,null,null,null,null,null,1,null,5],
        [null,null,null,7,null,null,9,6,null],
        [null,6,null,null,null,null,null,9,null],
        [null,null,null,1,null,null,null,2,null],
        [null,null,3,null,2,4,null,null,null],
        [4,null,null,null,null,null,null,null,8],
        [2,null,null,null,5,9,null,null,null],
        [null,null,null,null,7,null,null,1,null]
      ]
    }
  }

  function Application() {

    this.Sudoku = function(board) {

      this.__init__ = function() {
        this.board = board;
      };
      this.__init__();

      this.getSuccessors = function() {
        var empty = this._getFirstEmpty();
        var possibleVals = this._getPossibleVals(empty);

        var successors = [];
        for (var i = 0; i < possibleVals.length; i += 1) {
          var val = possibleVals[i];
          var successor = this._getSuccessor(empty, val);
          successors.push(successor);
        }
        return successors.reverse();
      }

      this._getFirstEmpty = function() {
        for (var row = 0; row < 9; row += 1){
          for (var col = 0; col < 9; col += 1) {
            if (this.board[row][col] === null)
              return {row: row, col: col};
          }
        }
        return null;
      }

      this._getRowNums = function(empty) {
        var x = empty.row;
        return this.board[x];
      }

      this._getColNums = function(empty) {
        var y = empty.col;
        return _.map(this.board, function(row){ return row[y]; });
      }

      this._getBoxNums = function(empty) {
        var rowMin = Math.floor(empty.row / 3) * 3,
            rowMax = rowMin + 3,
            colMin = Math.floor(empty.col / 3) * 3,
            colMax = colMin + 3;

        var box = [];
        for (var x = rowMin; x < rowMax; x += 1) {
          for (var y = colMin; y < colMax; y += 1) {
            box.push(this.board[x][y]);
          }
        }
        return box;
      }

      this._getPossibleVals = function(empty) {
        var values = _.range(1,10),
            row = this._getRowNums(empty),
            col = this._getColNums(empty),
            box = this._getBoxNums(empty);
        _.remove(values, function(v){
          return _.indexOf(row, v) != -1 || _.indexOf(col, v) != -1 || _.indexOf(box, v) != -1;
        });
        return values;
      }

      this._getSuccessor = function(empty, val) {
        var successor = _.cloneDeep(this);
        successor.board[empty.row][empty.col] = val;
        return successor
      }

      this.isFinalState = function() {
        return this._getFirstEmpty() === null;
      }
    }

    this.DepthFirstSearchModule = function(startState) {

      this._exploreNode = function(){
        if (this.fringe.length){
          this.currentState = this.fringe.pop();
          this.nodesExplored += 1;
          if (this.currentState.isFinalState()){
            return "solved";
          }
          else {
            successors = this.currentState.getSuccessors();
            this.fringe = this.fringe.concat(successors);
          }
        }
        else return "failed";
      }

      this._exploreNodes = function(){
        var speed = parseInt( $('#speed-selector').val() );
        var numberOfNodes = speed * Settings.INTERVAL / 1000;
        for (var x = 0; x < numberOfNodes; x += 1) {

          var result = this._exploreNode();
          if (result === "solved" || result === "failed") {
            this._printState(this.currentState);
            this.stopSearch();
            return;
          }
        }
        this._printState(this.currentState);
      }

      this._printState = function(state) {
        var board = state.board;
        var $html = $('

').addClass('sudoku');
        for (var row = 0; row < 9; row += 1) {
          var $rowHtml = $('

').addClass('row' + row);
          for (var col = 0; col < 9; col += 1) {
            var num = board[row][col]
            var elString = num ? num : ' ';
            var $blockHtml = $('

').addClass('block')
                                             .addClass('col' + col)
                                             .html('
' + elString + '
');
            $rowHtml.append($blockHtml);
          }
          $html.append($rowHtml);
        }

        $nodesHtml = $('

').addClass('nodes-explored')
                                     .html('
Nodes Explored: ' + this.nodesExplored + '
');

        $html.append($nodesHtml);
        $(Settings.ui.sudokuContainer).html($html);

      }

      this.__init__ = function() {
        this.nodesExplored = 0;
      };
      this.__init__();

      this.search = function() {
        this.fringe = [startState];
        this.currentState = null;

        this.id = setInterval( this._exploreNodes.bind(this), Settings.INTERVAL );
      }

      this.stopSearch = function() {
        clearInterval(this.id);
      }
    }

    this.startState = null;
    this.DFSModule = null;

    this._updateSpeedText = function(){
      var speedText = $(Settings.ui.speedSelector).val();
      $(Settings.ui.speedText).text(speedText);
    };

    this._start = function() {
      this.DFSModule.search();
    }

    this._reset = function() {
      this.DFSModule.stopSearch();
      this.DFSModule.nodesExplored = 0;
      this.DFSModule._printState(this.startState);
    }

    this._initializeBoard = function(boardKey) {
      this.startState = new this.Sudoku(Settings.sudokuBoards[boardKey]);
      this.DFSModule = new this.DepthFirstSearchModule(this.startState);
      this.DFSModule._printState(this.startState);
    }

    this._changeBoard = function() {
      this._reset();
      var boardKey = $(Settings.ui.boardOptions + ':checked').val();
      this._initializeBoard(boardKey);
    }

    this.initialize = function(){

      this._initializeBoard('board1');

      $(Settings.ui.speedSelector).on('input', this._updateSpeedText );
      $(Settings.ui.startButton).on('click', this._start.bind(this) );
      $(Settings.ui.resetButton).on('click', this._reset.bind(this) );
      $(Settings.ui.boardOptions).on('change', this._changeBoard.bind(this) );
    }
  };

  var application = new Application();
  application.initialize();

})(jQuery, _);
<commit_msg>fix bug<commit_after>(function($, _){

  var Settings = {
    INTERVAL: 100,

    ui: {
      sudokuContainer: '#sudoku-container',
      speedText: '#speed',
      speedSelector: '#speed-selector',
      boardOptions: 'input[name=board]',
      startButton: '#start-button',
      resetButton: '#reset-button'
    },

    sudokuBoards: {
      board1: [
        [6,null,null,null,null,5,null,3,null],
        [4,8,null,2,7,null,null,null,null],
        [null,null,null,8,null,1,null,null,9],
        [null,null,null,null,1,null,8,4,null],
        [9,4,null,null,3,null,null,1,5],
        [null,3,1,null,2,null,null,null,null],
        [3,null,null,6,null,2,null,null,null],
        [null,null,null,null,5,7,null,8,2],
        [null,5,null,1,null,null,null,null,6]
      ],
      board2: [
        [1,null,null,null,null,null,4,null,null],
        [7,3,9,null,8,null,2,null,null],
        [6,null,4,3,null,null,null,null,null],
        [null,null,2,5,null,null,7,null,9],
        [null,9,1,7,null,4,3,6,null],
        [8,null,3,null,null,6,5,null,null],
        [null,null,null,null,null,7,6,null,3],
        [null,null,7,null,6,null,8,9,2],
        [null,null,6,null,null,null,null,null,5]
      ],
      board3: [
        [null,null,null,8,null,null,null,null,5],
        [3,7,null,null,null,null,null,8,null],
        [null,null,null,4,null,null,null,null,7],
        [8,null,7,6,null,2,null,1,3],
        [null,2,null,null,null,null,null,4,null],
        [5,1,null,3,null,4,2,null,8],
        [2,null,null,null,null,6,null,null,null],
        [null,8,null,null,null,null,null,5,4],
        [9,null,null,null,null,3,null,null,null]
      ],
      board4: [
        [null,9,8,null,null,null,4,7,null],
        [null,null,null,null,null,null,1,null,5],
        [null,null,null,7,null,null,9,6,null],
        [null,6,null,null,null,null,null,9,null],
        [null,null,null,1,null,null,null,2,null],
        [null,null,3,null,2,4,null,null,null],
        [4,null,null,null,null,null,null,null,8],
        [2,null,null,null,5,9,null,null,null],
        [null,null,null,null,7,null,null,1,null]
      ]
    }
  }

  function Application() {

    this.Sudoku = function(board) {

      this.__init__ = function() {
        this.board = board;
      };
      this.__init__();

      this.getSuccessors = function() {
        var empty = this._getFirstEmpty();
        var possibleVals = this._getPossibleVals(empty);

        var successors = [];
        for (var i = 0; i < possibleVals.length; i += 1) {
          var val = possibleVals[i];
          var successor = this._getSuccessor(empty, val);
          successors.push(successor);
        }
        return successors.reverse();
      }

      this._getFirstEmpty = function() {
        for (var row = 0; row < 9; row += 1){
          for (var col = 0; col < 9; col += 1) {
            if (this.board[row][col] === null)
              return {row: row, col: col};
          }
        }
        return null;
      }

      this._getRowNums = function(empty) {
        var x = empty.row;
        return this.board[x];
      }

      this._getColNums = function(empty) {
        var y = empty.col;
        return _.map(this.board, function(row){ return row[y]; });
      }

      this._getBoxNums = function(empty) {
        var rowMin = Math.floor(empty.row / 3) * 3,
            rowMax = rowMin + 3,
            colMin = Math.floor(empty.col / 3) * 3,
            colMax = colMin + 3;

        var box = [];
        for (var x = rowMin; x < rowMax; x += 1) {
          for (var y = colMin; y < colMax; y += 1) {
            box.push(this.board[x][y]);
          }
        }
        return box;
      }

      this._getPossibleVals = function(empty) {
        var values = _.range(1,10),
            row = this._getRowNums(empty),
            col = this._getColNums(empty),
            box = this._getBoxNums(empty);
        _.remove(values, function(v){
          return _.indexOf(row, v) != -1 || _.indexOf(col, v) != -1 || _.indexOf(box, v) != -1;
        });
        return values;
      }

      this._getSuccessor = function(empty, val) {
        var successor = _.cloneDeep(this);
        successor.board[empty.row][empty.col] = val;
        return successor
      }

      this.isFinalState = function() {
        return this._getFirstEmpty() === null;
      }
    }

    this.DepthFirstSearchModule = function(startState) {

      this._exploreNode = function(){
        if (this.fringe.length){
          this.currentState = this.fringe.pop();
          this.nodesExplored += 1;
          if (this.currentState.isFinalState()){
            return "solved";
          }
          else {
            successors = this.currentState.getSuccessors();
            this.fringe = this.fringe.concat(successors);
          }
        }
        else return "failed";
      }

      this._exploreNodes = function(){
        var speed = parseInt( $('#speed-selector').val() );
        var numberOfNodes = speed * Settings.INTERVAL / 1000;
        for (var x = 0; x < numberOfNodes; x += 1) {

          var result = this._exploreNode();
          if (result === "solved" || result === "failed") {
            this._printState(this.currentState);
            this.stopSearch();
            return;
          }
        }
        this._printState(this.currentState);
      }

      this._printState = function(state) {
        var board = state.board;
        var $html = $('

').addClass('sudoku');
        for (var row = 0; row < 9; row += 1) {
          var $rowHtml = $('

').addClass('row' + row);
          for (var col = 0; col < 9; col += 1) {
            var num = board[row][col]
            var elString = num ? num : ' ';
            var $blockHtml = $('

').addClass('block')
                                             .addClass('col' + col)
                                             .html('
' + elString + '
');
            $rowHtml.append($blockHtml);
          }
          $html.append($rowHtml);
        }

        $nodesHtml = $('

').addClass('nodes-explored')
                                     .html('
Nodes Explored: ' + this.nodesExplored + '
');

        $html.append($nodesHtml);
        $(Settings.ui.sudokuContainer).html($html);

      }

      this.__init__ = function() {
        this.nodesExplored = 0;
      };
      this.__init__();

      this.search = function() {
        this.fringe = [startState];
        this.currentState = null;

        this.id = setInterval( this._exploreNodes.bind(this), Settings.INTERVAL );
      }

      this.stopSearch = function() {
        clearInterval(this.id);
      }
    }

    this.startState = null;
    this.DFSModule = null;

    this._updateSpeedText = function(){
      var speedText = $(Settings.ui.speedSelector).val();
      $(Settings.ui.speedText).text(speedText);
    };

    this._start = function() {
      this._reset();
      this.DFSModule.search();
    }

    this._reset = function() {
      this.DFSModule.stopSearch();
      this.DFSModule.nodesExplored = 0;
      this.DFSModule._printState(this.startState);
    }

    this._initializeBoard = function(boardKey) {
      this.startState = new this.Sudoku(Settings.sudokuBoards[boardKey]);
      this.DFSModule = new this.DepthFirstSearchModule(this.startState);
      this.DFSModule._printState(this.startState);
    }

    this._changeBoard = function() {
      this._reset();
      var boardKey = $(Settings.ui.boardOptions + ':checked').val();
      this._initializeBoard(boardKey);
    }

    this.initialize = function(){

      this._initializeBoard('board1');

      $(Settings.ui.speedSelector).on('input', this._updateSpeedText );
      $(Settings.ui.startButton).on('click', this._start.bind(this) );
      $(Settings.ui.resetButton).on('click', this._reset.bind(this) );
      $(Settings.ui.boardOptions).on('change', this._changeBoard.bind(this) );
    }
  };

  var application = new Application();
  application.initialize();

})(jQuery, _);
<|endoftext|>


<commit_before>$(function() {
    $( "#datepicker" ).datepicker({
        minDate: -365,
        maxDate: "+0M",
        //showOn: "button",
        dateFormat: 'dd-mm-yy',
        //showButtonPanel: true,
        //buttonText: "Calendar",
        //inline: true
        showOtherMonths: true,
        changeMonth: true,
        selectOtherMonths: true,
        required: true,
        showOn: "focus",
        numberOfMonths: 1
    });
    $('#datepicker').keyup(function () {
        $('#datepicker').val('');
        alert('Please select date from Calendar');
    });
});
<commit_msg>add new datetinme<commit_after>$(function() {
    $( "#datepicker" ).datepicker({
        minDate: -365,
        maxDate: "+0M",
        //showOn: "button",
        dateFormat: 'dd-mm-yy',
        //showButtonPanel: true,
        //buttonText: "Calendar",
        //inline: true
        showOtherMonths: true,
        changeYears: true,
        selectOtherYears: true,
        showOtherYears: true,
        changeMonth: true,
        selectOtherMonths: true,
        required: true,
        showOn: "focus",
        numberOfMonths: 1
    });
    $('#datepicker').keyup(function () {
        $('#datepicker').val('');
        alert('Please select date from Calendar');
    });
});
<|endoftext|>


<commit_before>// GENERAL INIT
var socket = io.connect('http://localhost:8080');
var modType = 'amp';
var waveType = 'sine';
var defaultTone = 440;  // Hz (concert A)
var baseTone = defaultTone;

$(document).ready(function() {
  initSocket();
  initGUI();
});

function initSocket() {
  socket.emit('clrBuffer', null);
  socket.on('newDataRcvd', newDataRcvd);
}

function initGUI() {
  $('#stopButton').hide();

  // Associate wave type buttons w/ corresponding funcs
  $('#waveTypeSelect').children().each(function() {
    this.onclick = function() {
      setWaveType(this.value);
    };
  });

  // Associate mod type buttons w/ corresponding funcs
  $('#modTypeSelect').children().each(function() {
    this.onclick = function() {
      setModType(this.value);
    };
  });
}

function startButtonPressed() {
  startSound();

  $('#startButton').hide();
  $('#stopButton').show();
}

function stopButtonPressed() {
  stopSound();

  $('#startButton').show();
  $('#stopButton').hide();
}

function setWaveType(inWaveType) {
  waveType = inWaveType;
  frameBuffer = [];
}

function setModType(inModType) {
  modType = inModType;
  frameBuffer = [];
}

// BUFFERS
var modDataBuffer = [];
var frameBuffer = [];
var waveBuffer = [];  // 2d: holds individual waves of different freqs

var bufferResetTimer;
var bufferResetInterval = 1000;

// Clear old data occasionally to prevent latency woes
function resetBuffers() {
  modDataBuffer.length = 0;
  frameBuffer.length = 0;
  waveBuffer.length = 0;
}

// IN MODULATION DATA
function newDataRcvd(inBuffer) {
  if (!playing) return;

  // Being called asynchronously, so push rather than concat (may not matter...)
  for (var i in inBuffer) {
    modDataBuffer.push(inBuffer[i]);
  }

  bufferWaves();
}

function bufferWaves() {
  for (var i = 0; i < modDataBuffer.length; i++) {
    switch (modType) {
      case 'freq':
        waveBuffer.push(makeCleanWave(waveType, (baseTone / modDataBuffer.shift()), sampleRate));
        break;

      default:
        while (frameBuffer.length < frameSize) {
          frameBuffer = frameBuffer.concat(makeWave(waveType, baseTone, sampleRate));
        }
    }
  }
}

// AUDIO SETUP
var audioCtx = getAudioCtx();

var channels = 1;  // mono
var sampleRate = audioCtx.sampleRate;  // typically 44.1k
var frameSize = 512;  // use factor of sample rate??? (e.g. 1050)

var sourceBuffer = audioCtx.createBuffer(channels, frameSize, sampleRate);
var source;

var playing = false;

function playSound() {
  // Init buffer source
  source = audioCtx.createBufferSource();
  source.loop = false;
  source.buffer = sourceBuffer;
  source.connect(audioCtx.destination);
  source.onended = function() {
    if (playing) playSound();
  };

  source.start();

  // Modulate
  switch (modType) {
    case 'none':
      noMod();
      break;
    case 'amp':
      modAmp();
      break;
    case 'freq':
      modFreq();
      break;
    default:
      console.log('Unknown modulation type');
  }
}

function startSound() {
  playing = true;
  resetBuffers();

  playSound();

  bufferResetTimer = window.setInterval(resetBuffers, bufferResetInterval);
  drawTimer = window.setInterval(updateVisualization, drawInterval);
}

function stopSound() {
  playing = false;

  clearInterval(bufferResetTimer);
  clearInterval(drawTimer);
}

// MODULATION
function noMod() {
  var nowBuffering = sourceBuffer.getChannelData(0);

  for (var i in nowBuffering) {
    nowBuffering[i] = frameBuffer.shift();
  }
}

function modAmp() {
  var nowBuffering = sourceBuffer.getChannelData(0);

  var chunkSize = frameSize/modDataBuffer.length;

  var nextDatum = modDataBuffer[0];
  for (var i in nowBuffering) {
    nowBuffering[i] = frameBuffer.shift() * nextDatum;  // Modulate amplitude

    // Leave at least 1 in modDataBuffer to account for input lag
    if (i%chunkSize < 1 && modDataBuffer.length > 1) {
      nextDatum = modDataBuffer.shift();
    }
  }
}

function modFreq() {
  var numChunks = (waveBuffer.length === 0 ? 1 : waveBuffer.length);
  var chunkSize = frameSize / numChunks;

  for (var k = 0; k < numChunks && waveBuffer.length > 0; k++) {
    var curChunkSize = waveBuffer[0].length; // how big is this single wave
    var curChunkCnt = Math.ceil(chunkSize/curChunkSize);  // how many waves to fill a chunk

    var translatedWave = [];
    if (frameBuffer.length > 1) {  // dont try translating if wavebuffer is empty
      // before you create the chunk, translate the small wave based on the
      // last couple values of the wavebuffer
      var firstSample = frameBuffer[frameBuffer.length-2];
      var lastSample = frameBuffer[frameBuffer.length-1];

      var goingUp = (firstSample < lastSample ? true : false);
      var startPoint = 0;
      if (goingUp && lastSample >= 0) {
        while (waveBuffer[0][startPoint] < lastSample) {
          startPoint++;
        }
      } else if (goingUp && lastSample < 0) {
        // start at the end and decrease until less than
        startPoint = waveBuffer[0].length - 1;
        while (waveBuffer[0][startPoint] > lastSample) {
          startPoint--;
        }
      } else { // going down
        while (waveBuffer[0][startPoint] < 0.98) {
          startPoint++;
        }
        while (waveBuffer[0][startPoint] > lastSample) {
          startPoint++;
        }
      }

      for (var m = startPoint; m < waveBuffer[0].length; m++) {
        translatedWave.push(waveBuffer[0][m]);
      }
      for (m = 0; m < startPoint; m++) {
        translatedWave.push(waveBuffer[0][m]);
      }

      //waveBuffer[0] = translatedWave.slice();
    } else {
      //translatedWave = waveBuffer[0].slice();
    }
    translatedWave = waveBuffer[0].slice();

    var waveChunkBuffer = [];
    for (var n = 0; n < curChunkCnt; n++) {
      //waveChunkBuffer = waveChunkBuffer.concat(waveBuffer[0]);
      waveChunkBuffer = waveChunkBuffer.concat(translatedWave);
    }
    frameBuffer = frameBuffer.concat(waveChunkBuffer);

    // Always keep at least 1 user input to account for input lag
    if (waveBuffer.length > 1) waveBuffer.shift();
  }

  var nowBuffering = sourceBuffer.getChannelData(0);
  for (var j in nowBuffering) {
    nowBuffering[j] = frameBuffer.shift();
  }
}

// MISC AUDIO FUNCS
function getAudioCtx() {
  if (window.AudioContext) return new window.AudioContext();
  else if (window.webkitAudioContext) return new window.webkitAudioContext();
  else if (window.audioContext) return new window.audioContext();
  else alert('Browser audio requirements not met');
}

// e.g. beep(500, 2000, 1, 'sine', function() {} );
function beep(duration, frequency, volume, type, callback) {
  var oscillator = audioCtx.createOscillator();
  var gainNode = audioCtx.createGain();

  oscillator.connect(gainNode);
  gainNode.connect(audioCtx.destination);

  gainNode.gain.value = volume;
  oscillator.frequency.value = frequency;
  oscillator.type = type;
  oscillator.onended = callback;

  oscillator.start();
  setTimeout(function(){ oscillator.stop(); }, duration);
}

// VISUALIZATION
var drawPoints = 300;
var drawTimer;
var drawInterval = 50; // use (frameSize / sampleRate) to redraw every frame

function updateVisualization() {
  var outBuffer = sourceBuffer.getChannelData(0);

  // Trim number of points that will be drawn
  var drawBuffer = [];
  var drawInterval = parseInt(outBuffer.length/drawPoints);
  for (var i = 0; i < outBuffer.length; i += drawInterval) {
    drawBuffer.push(outBuffer[i]);
  }
  draw(drawBuffer, 0, 'timeDomainCanvas');
}
<commit_msg>proper MFSK<commit_after>// GENERAL INIT
var socket = io.connect('http://localhost:8080');
var modType = 'amp';
var waveType = 'sine';
var defaultTone = 440;  // Hz (concert A)
var baseTone = defaultTone;

$(document).ready(function() {
  initSocket();
  initGUI();
});

function initSocket() {
  socket.emit('clrBuffer', null);
  socket.on('newDataRcvd', newDataRcvd);
}

function initGUI() {
  $('#stopButton').hide();

  // Associate wave type buttons w/ corresponding funcs
  $('#waveTypeSelect').children().each(function() {
    this.onclick = function() {
      setWaveType(this.value);
    };
  });

  // Associate mod type buttons w/ corresponding funcs
  $('#modTypeSelect').children().each(function() {
    this.onclick = function() {
      setModType(this.value);
    };
  });
}

function startButtonPressed() {
  startSound();

  $('#startButton').hide();
  $('#stopButton').show();
}

function stopButtonPressed() {
  stopSound();

  $('#startButton').show();
  $('#stopButton').hide();
}

function setWaveType(inWaveType) {
  waveType = inWaveType;
  frameBuffer = [];
}

function setModType(inModType) {
  modType = inModType;
  frameBuffer = [];
}

// BUFFERS
var modDataBuffer = [];
var frameBuffer = [];
var waveBuffer = [];  // 2d: holds individual waves of different freqs

var bufferResetTimer;
var bufferResetInterval = 1000;

// Clear old data occasionally to prevent latency woes
function resetBuffers() {
  modDataBuffer.length = 0;
  frameBuffer.length = 0;
  waveBuffer.length = 0;
}

// IN MODULATION DATA
function newDataRcvd(inBuffer) {
  if (!playing) return;

  // Being called asynchronously, so push rather than concat (may not matter...)
  for (var i in inBuffer) {
    modDataBuffer.push(inBuffer[i]);
  }

  bufferWaves();
}

function bufferWaves() {
  for (var i = 0; i < modDataBuffer.length; i++) {
    switch (modType) {
      case 'freq':
        waveBuffer.push(makeCleanWave(waveType, (baseTone / modDataBuffer.shift()), sampleRate));
        break;

      default:
        while (frameBuffer.length < frameSize) {
          frameBuffer = frameBuffer.concat(makeWave(waveType, baseTone, sampleRate));
        }
    }
  }
}

// AUDIO SETUP
var audioCtx = getAudioCtx();

var channels = 1;  // mono
var sampleRate = audioCtx.sampleRate;  // typically 44.1k
var frameSize = 512;  // use factor of sample rate??? (e.g. 1050)

var sourceBuffer = audioCtx.createBuffer(channels, frameSize, sampleRate);
var source;

var playing = false;

function playSound() {
  // Init buffer source
  source = audioCtx.createBufferSource();
  source.loop = false;
  source.buffer = sourceBuffer;
  source.connect(audioCtx.destination);
  source.onended = function() {
    if (playing) playSound();
  };

  source.start();

  // Modulate
  switch (modType) {
    case 'none':
      noMod();
      break;
    case 'amp':
      modAmp();
      break;
    case 'freq':
      modFreq();
      break;
    default:
      console.log('Unknown modulation type');
  }
}

function startSound() {
  playing = true;
  resetBuffers();

  playSound();

  bufferResetTimer = window.setInterval(resetBuffers, bufferResetInterval);
  drawTimer = window.setInterval(updateVisualization, drawInterval);
}

function stopSound() {
  playing = false;

  clearInterval(bufferResetTimer);
  clearInterval(drawTimer);
}

// MODULATION
function noMod() {
  var nowBuffering = sourceBuffer.getChannelData(0);

  for (var i in nowBuffering) {
    nowBuffering[i] = frameBuffer.shift();
  }
}

function modAmp() {
  var nowBuffering = sourceBuffer.getChannelData(0);

  var chunkSize = frameSize/modDataBuffer.length;

  var nextDatum = modDataBuffer[0];
  for (var i in nowBuffering) {
    nowBuffering[i] = frameBuffer.shift() * nextDatum;  // Modulate amplitude

    // Leave at least 1 in modDataBuffer to account for input lag
    if (i%chunkSize < 1 && modDataBuffer.length > 1) {
      nextDatum = modDataBuffer.shift();
    }
  }
}

function modFreq() {
  var numChunks = (waveBuffer.length === 0 ? 1 : waveBuffer.length);
  var chunkSize = frameSize / numChunks;

  // Fill the frameBuffer w/ numChunks # of chunks
  for (var k = 0; k < numChunks && waveBuffer.length > 0; k++) {

    // If frameBuffer has contents translate the new chunk to match the end of the current frameBuffer
    var translatedWave = [];
    if (frameBuffer.length > 1) {  // dont try translating if frameBuffer is empty
      // before you create the chunk, translate the single wave based on the
      // last couple values of the frameBuffer
      var firstSample = frameBuffer[frameBuffer.length - 2];
      var lastSample = frameBuffer[frameBuffer.length - 1];

      var goingUp = (firstSample < lastSample ? true : false);
      var startPoint = 0;
      if (goingUp && lastSample >= 0) {
        while (waveBuffer[0][startPoint] < lastSample) {  // !!!!
          startPoint++;
        }
      } else if (goingUp && lastSample < 0) {
        // start at the end and decrease until less than
        startPoint = waveBuffer[0].length - 1;
        while (waveBuffer[0][startPoint] > lastSample) {  // !!!!
          startPoint--;
        }
      } else { // going down
        while (waveBuffer[0][startPoint] < 0.98) {
          startPoint++;
        }
        while (waveBuffer[0][startPoint] >= lastSample) {
          startPoint++;
        }
      }

      for (var m = startPoint; m < waveBuffer[0].length; m++) {
        translatedWave.push(waveBuffer[0][m]);
      }
      for (m = 0; m < startPoint; m++) {
        translatedWave.push(waveBuffer[0][m]);
      }

    } else {
      translatedWave = waveBuffer[0].slice();
    }

    var curWaveSize = translatedWave.length;  // How big is this single wave
    var curChunkCnt = Math.ceil(chunkSize / curWaveSize);  // How many waves to fill a chunk

    var waveChunkBuffer = [];
    for (var n = 0; n < curChunkCnt; n++) {
      //waveChunkBuffer = waveChunkBuffer.concat(waveBuffer[0]);
      waveChunkBuffer = waveChunkBuffer.concat(translatedWave);
    }

    waveChunkBuffer = waveChunkBuffer.splice(0, chunkSize);
    //console.log('first 3: ' + translatedWave[0] + ' ' + translatedWave[1] + ' ' + translatedWave[2]);
    //console.log('last 3: ' + translatedWave[translatedWave.length-3] + ' ' + translatedWave[translatedWave.length-2] + ' ' + translatedWave[translatedWave.length-1]);
    //console.log( waveBuffer[0][waveBuffer.length-3] + ' ' +  waveBuffer[0][waveBuffer.length-2] + ' ' +  waveBuffer[0][waveBuffer.length-1]);
    //console.log( waveBuffer[0][0] + ' ' +  waveBuffer[0][1] + ' ' +  waveBuffer[0][2]);
    //console.log('curWaveSize: ' + curWaveSize + ' wcb.len: ' + waveChunkBuffer.length + ' chunksize: ' + chunkSize);
    //console.log('first 3: ' + waveChunkBuffer[0] + ' ' + waveChunkBuffer[1] + ' ' + waveChunkBuffer[2]);
    //console.log('last 3: ' + waveChunkBuffer[waveChunkBuffer.length-3] + ' ' + waveChunkBuffer[waveChunkBuffer.length-2] + ' ' + waveChunkBuffer[waveChunkBuffer.length-1]);

    frameBuffer = frameBuffer.concat(waveChunkBuffer);

    // Always keep at least 1 user input to account for input lag
    if (waveBuffer.length > 1) waveBuffer.shift();
  }

  var nowBuffering = sourceBuffer.getChannelData(0);
  for (var j in nowBuffering) {
    // Keep at least 2 in frameBuffer MFSK translation has data to work from
    var nextSample = frameBuffer[0];
    if (frameBuffer.length > 2) frameBuffer.shift();

    nowBuffering[j] = nextSample;
  }

}

// MISC AUDIO FUNCS
function getAudioCtx() {
  if (window.AudioContext) return new window.AudioContext();
  else if (window.webkitAudioContext) return new window.webkitAudioContext();
  else if (window.audioContext) return new window.audioContext();
  else alert('Browser audio requirements not met');
}

// e.g. beep(500, 2000, 1, 'sine', function() {} );
function beep(duration, frequency, volume, type, callback) {
  var oscillator = audioCtx.createOscillator();
  var gainNode = audioCtx.createGain();

  oscillator.connect(gainNode);
  gainNode.connect(audioCtx.destination);

  gainNode.gain.value = volume;
  oscillator.frequency.value = frequency;
  oscillator.type = type;
  oscillator.onended = callback;

  oscillator.start();
  setTimeout(function(){ oscillator.stop(); }, duration);
}

// VISUALIZATION
var drawPoints = 500;
var drawTimer;
var drawInterval = 50; // use (frameSize / sampleRate) to redraw every frame

function updateVisualization() {
  var outBuffer = sourceBuffer.getChannelData(0);

  // Trim number of points that will be drawn
  var drawBuffer = [];
  var drawInterval = parseInt(outBuffer.length/drawPoints);
  for (var i = 0; i < outBuffer.length; i += drawInterval) {
    drawBuffer.push(outBuffer[i]);
  }
  draw(drawBuffer, 0, 'timeDomainCanvas');
}
<|endoftext|>