<commit_before>/*global CANNON:true */

/**
 * @class CANNON.Particle
 * @brief A body consisting of one point mass. Does not have orientation.
 * @param float mass
 * @param CANNON.Material material
 */
CANNON.Particle = function(mass,material){

    // Check input
    if(typeof(mass)!="number")
        throw new Error("Argument 1 (mass) must be a number.");
    if(typeof(material)!="undefined" && !(material instanceof(CANNON.Material)))
        throw new Error("Argument 3 (material) must be an instance of CANNON.Material.");

    CANNON.Body.call(this,"particle");

    var that = this;

    /**
    * @property CANNON.Vec3 position
    * @memberof CANNON.Particle
    */
    this.position = new CANNON.Vec3();

    /**
    * @property CANNON.Vec3 initPosition
    * @memberof CANNON.Particle
    * @brief Initial position of the body
    */
    this.initPosition = new CANNON.Vec3();

    /**
    * @property CANNON.Vec3 velocity
    * @memberof CANNON.Particle
    */
    this.velocity = new CANNON.Vec3();

    /**
    * @property CANNON.Vec3 initVelocity
    * @memberof CANNON.Particle
    */
    this.initVelocity = new CANNON.Vec3();

    /**
    * @property CANNON.Vec3 force
    * @memberof CANNON.Particle
    * @brief Linear force on the body
    */
    this.force = new CANNON.Vec3();

    /**
    * @property float mass
    * @memberof CANNON.Particle
    */
    this.mass = mass;

    /**
    * @property float invMass
    * @memberof CANNON.Particle
    */
    this.invMass = mass>0 ? 1.0/mass : 0;

    /**
    * @property CANNON.Material material
    * @memberof CANNON.Particle
    */
    this.material = material;

    /**
    * @property float linearDamping
    * @memberof CANNON.Particle
    */
    this.linearDamping = 0.01; // Perhaps default should be zero here?

    /**
    * @property int motionstate
    * @memberof CANNON.Particle
    * @brief One of the states CANNON.Body.DYNAMIC, CANNON.Body.STATIC and CANNON.Body.KINEMATIC
    */
    this.motionstate = (mass <= 0.0 ? CANNON.Body.STATIC : CANNON.Body.DYNAMIC);

    /**
    * @property bool allowSleep
    * @memberof CANNON.Particle
    * @brief If true, the body will automatically fall to sleep.
    */
    this.allowSleep = true;

    // 0:awake, 1:sleepy, 2:sleeping
    this.sleepState = 0;

    /**
    * @method isAwake
    * @memberof CANNON.Particle
    * @return bool
    */
    this.isAwake = function(){ return that.sleepState == 0; }

    /**
    * @method isSleepy
    * @memberof CANNON.Particle
    * @return bool
    */
    this.isSleepy = function(){ return that.sleepState == 1; }

    /**
    * @method isSleeping
    * @memberof CANNON.Particle
    * @return bool
    */
    this.isSleeping = function(){ return that.sleepState == 2; }

    /**
    * @property float sleepSpeedLimit
    * @memberof CANNON.Particle
    * @brief If the speed (the norm of the velocity) is smaller than this value, the body is considered sleepy.
    */
    this.sleepSpeedLimit = 0.1;

    /**
    * @property float sleepTimeLimit
    * @memberof CANNON.Particle
    * @brief If the body has been sleepy for this sleepTimeLimit seconds, it is considered sleeping.
    */
    this.sleepTimeLimit = 1;

    this.timeLastSleepy = 0;

    /**
    * @method wakeUp
    * @memberof CANNON.Particle
    * @brief Wake the body up.
    */
    this.wakeUp = function(){
        that.sleepState = 0;
        that.dispatchEvent({type:"wakeup"});
    };

    /**
    * @method sleep
    * @memberof CANNON.Particle
    * @brief Force body sleep
    */
    this.sleep = function(){
        that.sleepState = 2;
    };

    /**
    * @method sleepTick
    * @memberof CANNON.Particle
    * @param float time The world time in seconds
    * @brief Called every timestep to update internal sleep timer and change sleep state if needed.
    */
    this.sleepTick = function(time){
        if(that.allowSleep){
          if(that.sleepState==0 && that.velocity.norm()<that.sleepSpeedLimit){
              that.sleepState = 1; // Sleepy
              timeLastSleepy = time;
              that.dispatchEvent({type:"sleepy"});
          } else if(that.sleepState==1 && that.velocity.norm()>that.sleepSpeedLimit){
              that.wakeUp(); // Wake up
          } else if(that.sleepState==1 && (time - timeLastSleepy)>that.sleepTimeLimit){
              that.sleepState = 2; // Sleeping
              that.dispatchEvent({type:"sleep"});
          }
        }
    };
};
<commit_msg>Fix for sleeping objects never waking up. Refactored Particle methods into prototypes<commit_after>/*global CANNON:true */

/**
 * @class CANNON.Particle
 * @brief A body consisting of one point mass. Does not have orientation.
 * @param float mass
 * @param CANNON.Material material
 */
CANNON.Particle = function(mass,material){

    // Check input
    if(typeof(mass)!="number")
        throw new Error("Argument 1 (mass) must be a number.");
    if(typeof(material)!="undefined" && !(material instanceof(CANNON.Material)))
        throw new Error("Argument 3 (material) must be an instance of CANNON.Material.");

    CANNON.Body.call(this,"particle");

    /**
    * @property CANNON.Vec3 position
    * @memberof CANNON.Particle
    */
    this.position = new CANNON.Vec3();

    /**
    * @property CANNON.Vec3 initPosition
    * @memberof CANNON.Particle
    * @brief Initial position of the body
    */
    this.initPosition = new CANNON.Vec3();

    /**
    * @property CANNON.Vec3 velocity
    * @memberof CANNON.Particle
    */
    this.velocity = new CANNON.Vec3();

    /**
    * @property CANNON.Vec3 initVelocity
    * @memberof CANNON.Particle
    */
    this.initVelocity = new CANNON.Vec3();

    /**
    * @property CANNON.Vec3 force
    * @memberof CANNON.Particle
    * @brief Linear force on the body
    */
    this.force = new CANNON.Vec3();

    /**
    * @property float mass
    * @memberof CANNON.Particle
    */
    this.mass = mass;

    /**
    * @property float invMass
    * @memberof CANNON.Particle
    */
    this.invMass = mass>0 ? 1.0/mass : 0;

    /**
    * @property CANNON.Material material
    * @memberof CANNON.Particle
    */
    this.material = material;

    /**
    * @property float linearDamping
    * @memberof CANNON.Particle
    */
    this.linearDamping = 0.01; // Perhaps default should be zero here?

    /**
    * @property int motionstate
    * @memberof CANNON.Particle
    * @brief One of the states CANNON.Body.DYNAMIC, CANNON.Body.STATIC and CANNON.Body.KINEMATIC
    */
    this.motionstate = (mass <= 0.0 ? CANNON.Body.STATIC : CANNON.Body.DYNAMIC);

    /**
    * @property bool allowSleep
    * @memberof CANNON.Particle
    * @brief If true, the body will automatically fall to sleep.
    */
    this.allowSleep = true;

    // 0:awake, 1:sleepy, 2:sleeping
    this.sleepState = 0;

    /**
    * @property float sleepSpeedLimit
    * @memberof CANNON.Particle
    * @brief If the speed (the norm of the velocity) is smaller than this value, the body is considered sleepy.
    */
    this.sleepSpeedLimit = 0.1;

    /**
    * @property float sleepTimeLimit
    * @memberof CANNON.Particle
    * @brief If the body has been sleepy for this sleepTimeLimit seconds, it is considered sleeping.
    */
    this.sleepTimeLimit = 1;

    this.timeLastSleepy = 0;

};

CANNON.Particle.prototype = new CANNON.Body();
CANNON.Particle.prototype.constructor = CANNON.Particle;

/**
* @method isAwake
* @memberof CANNON.Particle
* @return bool
*/
CANNON.Particle.prototype.isAwake = function(){ return this.sleepState == 0; }

/**
* @method isSleepy
* @memberof CANNON.Particle
* @return bool
*/
CANNON.Particle.prototype.isSleepy = function(){ return this.sleepState == 1; }

/**
* @method isSleeping
* @memberof CANNON.Particle
* @return bool
*/
CANNON.Particle.prototype.isSleeping = function(){ return this.sleepState == 2; }

/**
* @method wakeUp
* @memberof CANNON.Particle
* @brief Wake the body up.
*/
CANNON.Particle.prototype.wakeUp = function(){
	this.sleepState = 0;
	this.dispatchEvent({type:"wakeup"});
};

/**
* @method sleep
* @memberof CANNON.Particle
* @brief Force body sleep
*/
CANNON.Particle.prototype.sleep = function(){
	this.sleepState = 2;
};

/**
* @method sleepTick
* @memberof CANNON.Particle
* @param float time The world time in seconds
* @brief Called every timestep to update internal sleep timer and change sleep state if needed.
*/
CANNON.Particle.prototype.sleepTick = function(time){
	if(this.allowSleep){
		if(this.sleepState==0 && this.velocity.norm()<this.sleepSpeedLimit){
			this.sleepState = 1; // Sleepy
			this.timeLastSleepy = time;
			this.dispatchEvent({type:"sleepy"});
		} else if(this.sleepState>0 && this.velocity.norm()>this.sleepSpeedLimit){
			this.wakeUp(); // Wake up
		} else if(this.sleepState==1 && (time - this.timeLastSleepy)>this.sleepTimeLimit){
			this.sleepState = 2; // Sleeping
			this.dispatchEvent({type:"sleep"});
		}
	}
};
<|endoftext|>


<commit_before>goog.provide('og.webgl.Handler');

goog.require('og.webgl');
goog.require('og.math');
goog.require('og.webgl.ShaderController');
goog.require('og.ImageCanvas');

og.webgl.Handler = function (htmlId) {
    this.lastAnimationFrameTime = 0;
    this.fps;
    this.delta;
    this.animSpeed = 1.0;
    this.backgroundColor = { r: 0.48, g: 0.48, b: 0.48, a: 1.0 };
    this.htmlCanvasId = htmlId;
    this.gl;
    this._initialized = false;
    this.emptyTexture = null;
    this.drawback = function (x) { };
    this.shaderPrograms = {};
    this.activeShaderProgram = null;
    this.anisotropicFilteringEnabled = false;
};

og.webgl.Handler.prototype.createTextureFromImage = function (image) {
    var gl = this.gl;
    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
    //if (!og.math.isPowerOfTwo(image.width) || !og.math.isPowerOfTwo(image.height)) {
    //    var canvas = document.createElement("canvas");
    //    canvas.width = og.math.nextHighestPowerOfTwo(image.width);
    //    canvas.height = og.math.nextHighestPowerOfTwo(image.height);
    //    var ctx = canvas.getContext("2d");
    //    ctx.drawImage(image, 0, 0, image.width, image.height);
    //    image = canvas;
    //}
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    gl.generateMipmap(gl.TEXTURE_2D);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
    if (this.anisotropicFilteringEnabled) {
        gl.texParameterf(gl.TEXTURE_2D, gl.ext.TEXTURE_MAX_ANISOTROPY_EXT, 4);
    }
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.bindTexture(gl.TEXTURE_2D, null);
    return texture;
};

og.webgl.Handler.prototype.loadCubeMapTexture = function (params) {
    var gl = this.gl;
    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

    var faces = [[params.positiveX, gl.TEXTURE_CUBE_MAP_POSITIVE_X],
                 [params.negativeX, gl.TEXTURE_CUBE_MAP_NEGATIVE_X],
                 [params.positiveY, gl.TEXTURE_CUBE_MAP_POSITIVE_Y],
                 [params.negativeY, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],
                 [params.positiveZ, gl.TEXTURE_CUBE_MAP_POSITIVE_Z],
                 [params.negativeZ, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]];

    var imageCanvas = new og.ImageCanvas();
    imageCanvas.fillEmpty();
    var emptyImage = imageCanvas.getImage();

    for (var i = 0; i < faces.length; i++) {
        var face = faces[i][1];
        gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
        gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, emptyImage);
    }

    for (var i = 0; i < faces.length; i++) {
        var face = faces[i][1];
        var image = new Image();
        image.crossOrigin = '';
        image.onload = function (texture, face, image) {
            return function () {
                gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
                gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
                gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
            }
        }(texture, face, image);
        image.src = faces[i][0];
    }
    return texture;
};

og.webgl.Handler.prototype.createEmptyTexture = function (url) {
    var imageCanvas = new og.ImageCanvas();
    imageCanvas.fillEmpty();
    this.emptyTexture = this.createTextureFromImage(imageCanvas.getImage());
};

og.webgl.Handler.prototype.addShaderProgram = function (program, notActivate) {
    if (!this.shaderPrograms[program.name]) {
        var sc = new og.webgl.ShaderController(this, program);
        this.shaderPrograms[program.name] = sc;
        this._initShaderController(sc);
        if (notActivate)
            sc._activated = false;
    } else {
        alert(program.name + " is allready exists.");
    }
};

og.webgl.Handler.prototype._initShaderController = function (sc) {
    if (this._initialized) {
        sc.initialize();
        if (!this.activeShaderProgram) {
            this.activeShaderProgram = sc;
            sc.activate();
        } else {
            this.activeShaderProgram._program.use();
        }
    }
};

og.webgl.Handler.prototype.addShaderPrograms = function (programsArr) {
    for (var i = 0; i < programsArr.length; i++) {
        this.addShaderProgram(programsArr[i]);
    }
};

og.webgl.Handler.prototype.initAnysotropicFiltering = function () {
    var ext = og.webgl.getExtension(this.gl, "EXT_texture_filter_anisotropic");
    if (!ext) {
        return null;
    }
    this.anisotropicFilteringEnabled = true;
    return ext;
};

og.webgl.Handler.prototype.initShaderPrograms = function () {
    for (var p in this.shaderPrograms) {
        this._initShaderController(this.shaderPrograms[p]);
    }
};

og.webgl.Handler.prototype.init = function () {
    this.gl = og.webgl.initCanvas(this.htmlCanvasId);
    this._initialized = true;
    this.createEmptyTexture();
    this.initShaderPrograms();
    this.setDefaults();
};

og.webgl.Handler.prototype.setDefaults = function () {
    this.gl.enable(this.gl.DEPTH_TEST);
    this.applyViewport(this.gl.canvas.width, this.gl.canvas.height);
    this.gl.frontFace(this.gl.CCW);
    this.gl.enable(this.gl.CULL_FACE);
    this.gl.cullFace(this.gl.BACK);
    // this.gl.enable(this.gl.BLEND);
    this.gl.ext = this.initAnysotropicFiltering();
};

og.webgl.Handler.prototype.createArrayBuffer = function (array, itemSize, numItems) {
    var buffer = this.gl.createBuffer();
    this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
    this.gl.bufferData(this.gl.ARRAY_BUFFER, array, this.gl.STATIC_DRAW);
    buffer.itemSize = itemSize;
    buffer.numItems = numItems;
    return buffer;
};

og.webgl.Handler.prototype.createElementArrayBuffer = function (array, itemSize, numItems) {
    var buffer = this.gl.createBuffer();
    this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, buffer);
    this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, array, this.gl.STATIC_DRAW);
    buffer.itemSize = itemSize;
    buffer.numItems = numItems;
    return buffer;
};

og.webgl.Handler.prototype.fillBackGroundColor = function (color) {
    this.gl.clearColor(color.r, color.g, color.b, color.a);
};

function print2d(id, text, x, y) {
    var el = document.getElementById(id);
    el.innerHTML = text;
    el.style.left = x;
    el.style.top = y;
};

og.webgl.Handler.prototype.calculateFPS = function (now) {
    this.fps = 1000 / (now - this.lastAnimationFrameTime);
    this.lastAnimationFrameTime = now;
    this.delta = this.animSpeed / this.fps;
};

og.webgl.Handler.prototype.setBackgroundColor = function (color) {
    this.backgroundColor.r = color.r;
    this.backgroundColor.g = color.g;
    this.backgroundColor.b = color.b;
    this.backgroundColor.a = color.a;
};

og.webgl.Handler.prototype.applyViewport = function (width, height) {
    var w = width, h = Math.max(1, height);
    this.gl.viewport(0, 0, w, h);
    this.gl.canvas.width = w;
    this.gl.canvas.height = h;
    this.gl.canvas.aspect = w / h;
};

og.webgl.Handler.prototype.viewportResized = function () {
    return this.gl.canvas.clientWidth != this.gl.canvas.width ||
            this.gl.canvas.clientHeight != this.gl.canvas.height;
};

og.webgl.Handler.prototype.drawFrame = function (now, sender) {
    if (sender.viewportResized()) {
        sender.applyViewport(sender.gl.canvas.clientWidth, sender.gl.canvas.clientHeight);
        sender.onCanvasResize(sender.gl.canvas);
    }
    sender.calculateFPS(now);
    sender.clearFrame();
    sender.drawback();
    og.webgl.requestAnimationFrame(sender.drawFrame, sender);
};

og.webgl.Handler.prototype.clearFrame = function () {
    var gl = this.gl;
    this.fillBackGroundColor(this.backgroundColor);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
};

og.webgl.Handler.prototype.start = function () {
    og.webgl.requestAnimationFrame(this.drawFrame, this);
};<commit_msg>Added useful functions.<commit_after>goog.provide('og.webgl.Handler');

goog.require('og.webgl');
goog.require('og.math');
goog.require('og.webgl.ShaderController');
goog.require('og.ImageCanvas');

og.webgl.Handler = function (htmlId) {
    this.lastAnimationFrameTime = 0;
    this.fps;
    this.delta;
    this.animSpeed = 1.0;
    this.backgroundColor = { r: 0.48, g: 0.48, b: 0.48, a: 1.0 };
    this.htmlCanvasId = htmlId;
    this.gl;
    this._initialized = false;
    this.emptyTexture = null;
    this.drawback = function (x) { };
    this.shaderPrograms = {};
    this.activeShaderProgram = null;
    this.anisotropicFilteringEnabled = false;
};

og.webgl.Handler.prototype.createTextureFromImage = function (image) {
    var gl = this.gl;
    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
    //if (!og.math.isPowerOfTwo(image.width) || !og.math.isPowerOfTwo(image.height)) {
    //    var canvas = document.createElement("canvas");
    //    canvas.width = og.math.nextHighestPowerOfTwo(image.width);
    //    canvas.height = og.math.nextHighestPowerOfTwo(image.height);
    //    var ctx = canvas.getContext("2d");
    //    ctx.drawImage(image, 0, 0, image.width, image.height);
    //    image = canvas;
    //}
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    gl.generateMipmap(gl.TEXTURE_2D);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
    if (this.anisotropicFilteringEnabled) {
        gl.texParameterf(gl.TEXTURE_2D, gl.ext.TEXTURE_MAX_ANISOTROPY_EXT, 4);
    }
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.bindTexture(gl.TEXTURE_2D, null);
    return texture;
};

og.webgl.Handler.prototype.loadCubeMapTexture = function (params) {
    var gl = this.gl;
    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

    var faces = [[params.positiveX, gl.TEXTURE_CUBE_MAP_POSITIVE_X],
                 [params.negativeX, gl.TEXTURE_CUBE_MAP_NEGATIVE_X],
                 [params.positiveY, gl.TEXTURE_CUBE_MAP_POSITIVE_Y],
                 [params.negativeY, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],
                 [params.positiveZ, gl.TEXTURE_CUBE_MAP_POSITIVE_Z],
                 [params.negativeZ, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]];

    var imageCanvas = new og.ImageCanvas();
    imageCanvas.fillEmpty();
    var emptyImage = imageCanvas.getImage();

    for (var i = 0; i < faces.length; i++) {
        var face = faces[i][1];
        gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
        gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, emptyImage);
    }

    for (var i = 0; i < faces.length; i++) {
        var face = faces[i][1];
        var image = new Image();
        image.crossOrigin = '';
        image.onload = function (texture, face, image) {
            return function () {
                gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
                gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
                gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
            }
        }(texture, face, image);
        image.src = faces[i][0];
    }
    return texture;
};

og.webgl.Handler.prototype.createEmptyTexture = function (url) {
    var imageCanvas = new og.ImageCanvas();
    imageCanvas.fillEmpty();
    this.emptyTexture = this.createTextureFromImage(imageCanvas.getImage());
};

og.webgl.Handler.prototype.addShaderProgram = function (program, notActivate) {
    if (!this.shaderPrograms[program.name]) {
        var sc = new og.webgl.ShaderController(this, program);
        this.shaderPrograms[program.name] = sc;
        this._initShaderController(sc);
        if (notActivate)
            sc._activated = false;
    } else {
        alert(program.name + " is allready exists.");
    }
};

og.webgl.Handler.prototype._initShaderController = function (sc) {
    if (this._initialized) {
        sc.initialize();
        if (!this.activeShaderProgram) {
            this.activeShaderProgram = sc;
            sc.activate();
        } else {
            this.activeShaderProgram._program.use();
        }
    }
};

og.webgl.Handler.prototype.addShaderPrograms = function (programsArr) {
    for (var i = 0; i < programsArr.length; i++) {
        this.addShaderProgram(programsArr[i]);
    }
};

og.webgl.Handler.prototype.initAnysotropicFiltering = function () {
    var ext = og.webgl.getExtension(this.gl, "EXT_texture_filter_anisotropic");
    if (!ext) {
        return null;
    }
    this.anisotropicFilteringEnabled = true;
    return ext;
};

og.webgl.Handler.prototype.initShaderPrograms = function () {
    for (var p in this.shaderPrograms) {
        this._initShaderController(this.shaderPrograms[p]);
    }
};

og.webgl.Handler.prototype.init = function () {
    this.gl = og.webgl.initCanvas(this.htmlCanvasId);
    this._initialized = true;
    this.createEmptyTexture();
    this.initShaderPrograms();
    this.setDefaults();
};

og.webgl.Handler.prototype.setDefaults = function () {
    this.activateDepthTest();
    this.applyViewport(this.gl.canvas.width, this.gl.canvas.height);
    this.gl.frontFace(this.gl.CCW);
    this.gl.cullFace(this.gl.BACK);
    this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE);
    this.activateFaceCulling();
    this.deactivateBlending();
    this.gl.ext = this.initAnysotropicFiltering();
};

og.webgl.Handler.prototype.activateDepthTest = function () {
    this.gl.enable(this.gl.DEPTH_TEST);
};

og.webgl.Handler.prototype.deactivateDepthTest = function () {
    this.gl.disable(this.gl.DEPTH_TEST);
};

og.webgl.Handler.prototype.activateFaceCulling = function () {
    this.gl.enable(this.gl.CULL_FACE);
};

og.webgl.Handler.prototype.deactivateFaceCulling = function () {
    this.gl.disable(this.gl.CULL_FACE);
};

og.webgl.Handler.prototype.activateBlending = function () {
    this.gl.enable(this.gl.BLEND);
};

og.webgl.Handler.prototype.deactivateBlending = function () {
    this.gl.disable(this.gl.BLEND);
};

og.webgl.Handler.prototype.createArrayBuffer = function (array, itemSize, numItems) {
    var buffer = this.gl.createBuffer();
    this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
    this.gl.bufferData(this.gl.ARRAY_BUFFER, array, this.gl.STATIC_DRAW);
    buffer.itemSize = itemSize;
    buffer.numItems = numItems;
    return buffer;
};

og.webgl.Handler.prototype.createElementArrayBuffer = function (array, itemSize, numItems) {
    var buffer = this.gl.createBuffer();
    this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, buffer);
    this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, array, this.gl.STATIC_DRAW);
    buffer.itemSize = itemSize;
    buffer.numItems = numItems;
    return buffer;
};

og.webgl.Handler.prototype.fillBackGroundColor = function (color) {
    this.gl.clearColor(color.r, color.g, color.b, color.a);
};

function print2d(id, text, x, y) {
    var el = document.getElementById(id);
    el.innerHTML = text;
    el.style.left = x;
    el.style.top = y;
};

og.webgl.Handler.prototype.calculateFPS = function (now) {
    this.fps = 1000 / (now - this.lastAnimationFrameTime);
    this.lastAnimationFrameTime = now;
    this.delta = this.animSpeed / this.fps;
};

og.webgl.Handler.prototype.setBackgroundColor = function (color) {
    this.backgroundColor.r = color.r;
    this.backgroundColor.g = color.g;
    this.backgroundColor.b = color.b;
    this.backgroundColor.a = color.a;
};

og.webgl.Handler.prototype.applyViewport = function (width, height) {
    var w = width, h = Math.max(1, height);
    this.gl.viewport(0, 0, w, h);
    this.gl.canvas.width = w;
    this.gl.canvas.height = h;
    this.gl.canvas.aspect = w / h;
};

og.webgl.Handler.prototype.viewportResized = function () {
    return this.gl.canvas.clientWidth != this.gl.canvas.width ||
            this.gl.canvas.clientHeight != this.gl.canvas.height;
};

og.webgl.Handler.prototype.drawFrame = function (now, sender) {
    if (sender.viewportResized()) {
        sender.applyViewport(sender.gl.canvas.clientWidth, sender.gl.canvas.clientHeight);
        sender.onCanvasResize(sender.gl.canvas);
    }
    sender.calculateFPS(now);
    sender.clearFrame();
    sender.drawback();
    og.webgl.requestAnimationFrame(sender.drawFrame, sender);
};

og.webgl.Handler.prototype.clearFrame = function () {
    var gl = this.gl;
    this.fillBackGroundColor(this.backgroundColor);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
};

og.webgl.Handler.prototype.start = function () {
    og.webgl.requestAnimationFrame(this.drawFrame, this);
};<|endoftext|>


<commit_before>var utilities = require('./utilities');

// argv[2] (required): the name of the active file
// argv[3] (required): the ipv4 address of the server to contact first

var activeFileName = process.argv[2];

var fileContents;

var otherServerUri = "http://" + process.argv[3] + ':' +
  utilities.SERVER_HTTP_PORT;

var p = new utilities.p2p.peer(otherServerUri, utilities.SERVER_HTTP_PORT);

// TODO: make proxy solution for network with firewall which blocks all ports

utilities.fs.writeFile(activeFileName, "", function(error) {
  if (error) {
    console.log(error);
  }
  openFileInEmacs(activeFileName);
  p.start(
    // client init function
    function() {
      console.log("speaking on " + utilities.os.hostname() + ':' +
        utilities.SERVER_HTTP_PORT);
    },
    // client socket function
    function(socket) {
      // get user id, filename, and file contents; write to file
      socket.on('connection_info', function(sentFileName) {
        activeFileName = sentFileName;
      });
      socket.on('file_send', function(sentFileContents) {
        // if not self socket
        if ("http://127.0.0.1:" + utilities.SERVER_HTTP_PORT !=
          utilities.p2p.client.getUriOfSocket(socket)) {
          utilities.fs.writeFile(
            activeFileName + utilities.CLIENT_COPY_FILE_SUFFIX,
            sentFileContents,
            function(error) {
              if (error) {
                console.log(error);
              }
              updateBufferInEmacs(activeFileName);
            });
        }
      });
      socket.on('file_diff', function(sentFilePatch) {
        // if not self socket
        if ("http://127.0.0.1:" + utilities.SERVER_HTTP_PORT !=
          utilities.p2p.client.getUriOfSocket(socket)) {
          utilities.fs.readFile(
            activeFileName + utilities.CLIENT_COPY_FILE_SUFFIX,
            function(error,
              readFileContents) {
              if (error) {
                console.log(error);
              }
              utilities.fs.writeFile(
                activeFileName + utilities.CLIENT_COPY_FILE_SUFFIX,
                utilities.diff_match_patch.patch_apply(
                  sentFilePatch,
                  readFileContents)[0],
                function(error) {
                  if (error) {
                    console.log(error);
                  }
                  updateBufferInEmacs(activeFileName);
                });
            });
        }
      });
    },
    // server init function
    function() {
      console.log("listening on " + utilities.os.hostname() + ':' +
        utilities.SERVER_HTTP_PORT);
      if ("127.0.0.1" == process.argv[3]) { // if initial server
        setInterval(broadcastBuffer, utilities.FILE_SYNC_TIME);
        setInterval(broadcastDiff, utilities.DIFF_SYNC_TIME);
      }
    },
    // server socket function
    function(socket) {
      socket.emit('connection_info', activeFileName);
    });
});

// requires emacs to be open and server to be on
function openFileInEmacs(filename) {
  var emacsOpenFile = utilities.spawn('emacsclient', ['-n', filename]);
  emacsOpenFile.stdout.on('data', function(data) {
    console.log("emacs stdout: " + data);
  });
  emacsOpenFile.stderr.on('data', function(data) {
    console.log("emacs stderr: " + data);
  });
  emacsOpenFile.on('exit', function(return_code, signal) {
    if (return_code != 0) {
      console.log("error: file could not be opened.");
    } else {
      console.log("FILE OPENED :DDDDDDDDDDDDDDDDDD");
    }
  });
}

function broadcastBuffer() {
  var emacsWriteFile = spawnEmacsCommand(
    "send-buffer-to-file", "\"" + activeFileName + "\"",
    "\"" + utilities.TMP_FILENAME_SUFFIX + "\"");
  emacsWriteFile.stdout.on('data', function(data) {
    console.log("emacs stdout: " + data);
  });
  emacsWriteFile.stderr.on('data', function(data) {
    console.log("emacs stderr: " + data);
  });
  emacsWriteFile.on('exit', function(
    return_code, signal) {
    if (0 != return_code) {
      console.log("error: buffer could not be saved.");
    } else {
      utilities.fs.readFile(
        activeFileName + utilities.TMP_FILENAME_SUFFIX,
        function(error, fileContents) {
          if (error) {
            console.log(error);
          }
          p.emit('file_send', fileContents.toString());
        });
      console.log("file broadcasted");
    }
  });
}

function broadcastDiff() {
  var emacsWriteFile = spawnEmacsCommand(
    "send-buffer-to-file", "\"" + activeFileName + "\"",
    "\"" + utilities.TMP_FILENAME_SUFFIX + "\"");
  emacsWriteFile.stdout.on('data', function(data) {
    console.log("emacs stdout: " + data)
  });
  emacsWriteFile.stderr.on('data', function(data) {
    console.log("emacs stderr: " + data);
  });
  emacsWriteFile.on('exit', function(return_code, signal) {
    if (0 != return_code) {
      console.log("error: buffer could not be saved.");
    } else {
      utilities.fs.readFile(
        activeFileName + utilities.TMP_FILENAME_SUFFIX,
        function(tmpError, tmpFileContents) {
          if (tmpError) {
            console.log(tmpError);
          }
          utilities.fs.readFile(
            activeFileName,
            function(curError, curFileContents) {
              if (curError) {
                console.log(curError);
              }
              utilities.fs.writeFile(
                activeFileName,
                tmpFileContents,
                function(error) {
                  console.log(error);
                  p.emit('file_diff',
                    utilities.diff_match_patch.patch_make(
                      curFileContents, tmpFileContents));
                }
              )
            });
        });
    }
  });
}

function updateBufferInEmacs(filename) {
  var emacsReadFile = spawnEmacsCommand(
    "read-buffer-from-file", "\"" + filename + "\"");
  emacsReadFile.stdout.on('data', function(data) {
    console.log("emacs stdout: " + data);
  });
  emacsReadFile.stderr.on('data', function(data) {
    console.log("emacs stderr: " + data);
  });
  emacsReadFile.on('exit', function(return_code, signal) {
    if (return_code != 0) {
      console.log("error: file could not be read.");
    }
    console.log("file read");
  });
}

// takes variable number of arguments
// returns spawn object
function spawnEmacsCommand() {
  var evalArg = "(";
  for (var i = 0; i < arguments.length; ++i) {
    evalArg += arguments[i] + " ";
  }
  evalArg += ")";
  return utilities.spawn('emacsclient', ['-e', evalArg]);
}
<commit_msg>file transfer<commit_after>var utilities = require('./utilities');

// argv[2] (required): the name of the active file
// argv[3] (required): the ipv4 address of the server to contact first

var activeFileName = process.argv[2];

var fileContents;

var otherServerUri = "http://" + process.argv[3] + ':' +
  utilities.SERVER_HTTP_PORT;

var p = new utilities.p2p.peer(otherServerUri, utilities.SERVER_HTTP_PORT);

// TODO: make proxy solution for network with firewall which blocks all ports

utilities.fs.writeFile(activeFileName, "", function(error) {
  if (error) {
    console.log(error);
  }
  openFileInEmacs(activeFileName);
  p.start(
    // client init function
    function() {
      console.log("speaking on " + utilities.os.hostname() + ':' +
        utilities.SERVER_HTTP_PORT);
    },
    // client socket function
    function(socket) {
      // get user id, filename, and file contents; write to file
      socket.on('connection_info', function(sentFileName) {
        activeFileName = sentFileName;
      });
      socket.on('file_send', function(sentFileContents) {
        // if not self socket
        if ("http://127.0.0.1:" + utilities.SERVER_HTTP_PORT !=
          utilities.p2p.client.getUriOfSocket(socket)) {
          utilities.fs.writeFile(
            activeFileName + utilities.CLIENT_COPY_FILE_SUFFIX,
            sentFileContents,
            function(error) {
              if (error) {
                console.log(error);
              }
              updateBufferInEmacs(activeFileName);
            });
        }
      });
      socket.on('file_diff', function(sentFilePatch) {
        // if not self socket
        if ("http://127.0.0.1:" + utilities.SERVER_HTTP_PORT !=
          utilities.p2p.client.getUriOfSocket(socket)) {
          utilities.fs.readFile(
            activeFileName + utilities.CLIENT_COPY_FILE_SUFFIX,
            function(error,
              readFileContents) {
              if (error) {
                console.log(error);
              }
              utilities.fs.writeFile(
                activeFileName + utilities.CLIENT_COPY_FILE_SUFFIX,
                utilities.diff_match_patch.patch_apply(
                  sentFilePatch,
                  readFileContents)[0],
                function(error) {
                  if (error) {
                    console.log(error);
                  }
                  updateBufferInEmacs(activeFileName);
                });
            });
        }
      });
    },
    // server init function
    function() {
      console.log("listening on " + utilities.os.hostname() + ':' +
        utilities.SERVER_HTTP_PORT);
      if ("127.0.0.1" == process.argv[3]) { // if initial server
        setInterval(broadcastBuffer, utilities.FILE_SYNC_TIME);
        setInterval(broadcastDiff, utilities.DIFF_SYNC_TIME);
      }
    },
    // server socket function
    function(socket) {
      socket.emit('connection_info', activeFileName);
      broadcastBuffer();
    });
});

// requires emacs to be open and server to be on
function openFileInEmacs(filename) {
  var emacsOpenFile = utilities.spawn('emacsclient', ['-n', filename]);
  emacsOpenFile.stdout.on('data', function(data) {
    console.log("emacs stdout: " + data);
  });
  emacsOpenFile.stderr.on('data', function(data) {
    console.log("emacs stderr: " + data);
  });
  emacsOpenFile.on('exit', function(return_code, signal) {
    if (return_code != 0) {
      console.log("error: file could not be opened.");
    } else {
      console.log("FILE OPENED :DDDDDDDDDDDDDDDDDD");
    }
  });
}

function broadcastBuffer() {
  var emacsWriteFile = spawnEmacsCommand(
    "send-buffer-to-file", "\"" + activeFileName + "\"",
    "\"" + utilities.TMP_FILENAME_SUFFIX + "\"");
  emacsWriteFile.stdout.on('data', function(data) {
    console.log("emacs stdout: " + data);
  });
  emacsWriteFile.stderr.on('data', function(data) {
    console.log("emacs stderr: " + data);
  });
  emacsWriteFile.on('exit', function(
    return_code, signal) {
    if (0 != return_code) {
      console.log("error: buffer could not be saved.");
    } else {
      utilities.fs.readFile(
        activeFileName + utilities.TMP_FILENAME_SUFFIX,
        function(error, fileContents) {
          if (error) {
            console.log(error);
          }
          p.emit('file_send', fileContents.toString());
        });
      console.log("file broadcasted");
    }
  });
}

function broadcastDiff() {
  var emacsWriteFile = spawnEmacsCommand(
    "send-buffer-to-file", "\"" + activeFileName + "\"",
    "\"" + utilities.TMP_FILENAME_SUFFIX + "\"");
  emacsWriteFile.stdout.on('data', function(data) {
    console.log("emacs stdout: " + data)
  });
  emacsWriteFile.stderr.on('data', function(data) {
    console.log("emacs stderr: " + data);
  });
  emacsWriteFile.on('exit', function(return_code, signal) {
    if (0 != return_code) {
      console.log("error: buffer could not be saved.");
    } else {
      utilities.fs.readFile(
        activeFileName + utilities.TMP_FILENAME_SUFFIX,
        function(tmpError, tmpFileContents) {
          if (tmpError) {
            console.log(tmpError);
          }
          utilities.fs.readFile(
            activeFileName,
            function(curError, curFileContents) {
              if (curError) {
                console.log(curError);
              }
              utilities.fs.writeFile(
                activeFileName,
                tmpFileContents,
                function(error) {
                  console.log(error);
                  p.emit('file_diff',
                    utilities.diff_match_patch.patch_make(
                      curFileContents, tmpFileContents));
                }
              )
            });
        });
    }
  });
}

function updateBufferInEmacs(filename) {
  var emacsReadFile = spawnEmacsCommand(
    "read-buffer-from-file", "\"" + filename + "\"");
  emacsReadFile.stdout.on('data', function(data) {
    console.log("emacs stdout: " + data);
  });
  emacsReadFile.stderr.on('data', function(data) {
    console.log("emacs stderr: " + data);
  });
  emacsReadFile.on('exit', function(return_code, signal) {
    if (return_code != 0) {
      console.log("error: file could not be read.");
    }
    console.log("file read");
  });
}

// takes variable number of arguments
// returns spawn object
function spawnEmacsCommand() {
  var evalArg = "(";
  for (var i = 0; i < arguments.length; ++i) {
    evalArg += arguments[i] + " ";
  }
  evalArg += ")";
  return utilities.spawn('emacsclient', ['-e', evalArg]);
}
<|endoftext|>


<commit_before>var fs = require("fs");
var path = require("path");
var compile = require("./compile");

var argvs = process.argv.splice(2);

var dirPath = argvs.length ? argvs[0] : path.dirname(process.argv.splice(1));

var traverseDir = function(rootPath, dirPath, filesDict) {
	var filesList = [];
	var thisPath = path.join(rootPath, dirPath);
	var files = fs.readdirSync(thisPath);
	files.forEach(function(file) {
		var statObj = fs.statSync(path.join(thisPath, file));
		if (statObj.isDirectory()) traverseDir(rootPath, path.join(dirPath, file), filesDict);
		else filesList.push(file);
	});
	filesDict[dirPath] = filesList;
};

var compileDir = function(dirPath) {
	var funcStr = "var templateDict = {";
	var filesDict = {};
	traverseDir(dirPath, "", filesDict);
	var isFirst = true;
	for (var each in filesDict) {
		filesDict[each].forEach(function(file) {
			var thisPath = path.join(dirPath,each, file);
			if (path.extname(file) == ".html") {
				if (!isFirst) funcStr += ",";
				else isFirst = false;
				funcStr += "'" + path.join(each, file) + "':function(args){" + compile.compile(fs.readFileSync(thisPath, {
					encoding: "utf8"
				})) + "}";
			}
		});
	}
	funcStr += "}";

	fs.writeFileSync("template.js", funcStr);
};

compileDir(dirPath);<commit_msg>update<commit_after>var fs = require("fs");
var path = require("path");
var compile = require("./compile");

var argvs = process.argv.splice(2);

var dirPath = argvs[0] ? argvs[0] : path.dirname(process.argv.splice(1));
var outPath = argvs[1] ? argvs[1] : dirPath;

var traverseDir = function(rootPath, dirPath, filesDict) {
	var filesList = [];
	var thisPath = path.join(rootPath, dirPath);
	var files = fs.readdirSync(thisPath);
	files.forEach(function(file) {
		var statObj = fs.statSync(path.join(thisPath, file));
		if (statObj.isDirectory()) traverseDir(rootPath, path.join(dirPath, file), filesDict);
		else filesList.push(file);
	});
	filesDict[dirPath] = filesList;
};

var compileDir = function(dirPath) {
	var funcStr = "var templateDict = {";
	var filesDict = {};
	traverseDir(dirPath, "", filesDict);
	var isFirst = true;
	for (var each in filesDict) {
		filesDict[each].forEach(function(file) {
			var thisPath = path.join(dirPath,each, file);
			if (path.extname(file) == ".html") {
				if (!isFirst) funcStr += ",";
				else isFirst = false;
				funcStr += "'" + path.join(each, file) + "':function(args){" + compile.compile(fs.readFileSync(thisPath, {
					encoding: "utf8"
				})) + "}";
			}
		});
	}
	funcStr += "}";

	fs.writeFileSync(path.join(outPath,"template.js"), funcStr);
};

compileDir(dirPath);<|endoftext|>


<commit_before>var util = require( "util" );
var events = require( "events" );
var extend = require( "extend" );
var conn = require( "dbstream-memory" ).connect();

module.exports = duty;
duty.add = duty;
duty.register = register;
duty.unregister = unregister;
duty.get = get;
duty.cancel = cancel;
duty.db = db;
duty.expire = expire;

function duty ( name, data, done ) {
    done || ( done = function () {} );
    var id = Math.random().toString( 36 ).substr( 2 );
    var job = {
        name: name,
        id: id,
        status: "pending",
        data: data
    };

    var added_on = new Date().toISOString();
    var cursor = new conn.Cursor()
        .on( "error", done )
        .on( "finish", function () {
            job.added_on = added_on;
            done( null, job )
        });

    if ( data.id ) {
        var duplicate = false;
        cursor.on( "data", function ( job ) {
            var err = "Duplicate running job detected in Job #" + job.id;
            err = extend( new Error( err ), {
                code: "duplicate",
                dataid: data.id,
                jobid: job.id,
                status: job.status,
                description: "Cancel the running job first, before adding " +
                "a new one with the same data.id"
            })

            this.removeAllListeners()
            done( err )
        })
        .on( "end", push )
        .find({ status: { $nin: [ "success", "error" ] }, dataid: data.id })
    } else {
        push();
    }
    return job;

    function push() {
        cursor.end( extend( { added_on: added_on, dataid: data.id }, job ) );
    }
}

// register a listener
var listeners = {};
function register ( name, fn, options ) {
    listeners[ name ] = fn;
    options = extend({
        delay: 60000, // 1-minute?
        timeout: Infinity,
        concurrency: 1,
        retries: 0,
        backoff: 0
    }, options );

    if ( options.concurrency == Infinity || options.concurrency <= 0 ) {
        throw new Error( "Concurrency must be a finite positive number" );
    }

    for ( var i = 0 ; i < options.concurrency ; i += 1 ) {
        // space out the concurrent runloops to reduce the likelihood of
        // claim conflicts
        setTimeout( function () {
            console.log( 'Duty starting Run Loop', name );
            runloop( name, fn, options );
        }, 10 * i );
    }
}

function unregister( name ) {
    if ( arguments.length == 0 ) {
        listeners = {};
    } else {
        delete listeners[ name ];
    }
}

var running = {};
function runloop ( name, fn, options ) {

    // listener was unregistered or overridden
    if ( listeners[ name ] != fn ) return;
    var timeout = ( options.timeout && options.timeout != Infinity )
        ? options.timeout : null;

    // run the next job in the queue
    next( name, options, function ( err, job ) {

        if ( err ) {
            console.error( new Date().toISOString(), err, err.stack );
        }

        // no job found, try again after `delay` seconds
        if ( !job ) {
            return setTimeout( function () {
                console.log( 'Duty restarting run loop after delay', name );
                runloop( name, fn, options )
            }, options.delay );
        }

        // create the job emitter and bind the event listeners used to control
        // the life-cycle of the job
        running[ job.id ] = job = extend( new events.EventEmitter(), job )
            .on( "progress", function ( loaded, total, msg ) {
                if ( !running[ job.id ] ) return; // already done
                var expires_on;
                if ( timeout ) {
                    expires_on = new Date( new Date().getTime() + timeout )
                        .toISOString();
                }

                var changes = {
                    id: this.id,
                    expires_on: expires_on
                };

                if ( loaded ) {
                    changes.loaded = loaded;
                }

                if ( total ) {
                    changes.total = total;
                }

                if ( msg ) {
                    changes.progress = msg;
                }

                update( changes, function ( err, found ) {
                    extend( this, found );
                    if ( err || this.status == "error" ) {
                        this.emit( "error", err || this.error );
                    }
                }.bind( this ) );
            })
            .on( "error", done ) // captures all errors
            .once( "success", done.bind( job, undefined ) )

        // start running it
        job.emit( "progress", null, null )
        try {
            fn.call( job, job.data, function ( err, result ) {
                if ( err ) {
                    job.emit( "error", err );
                } else {
                    job.emit( "success", result )
                }
            });
        } catch ( err ) {
            job.emit( "error", err );
        }

        // did it start with an error?
        // it's possible when the job is cancelled before it started running
        if ( job.status == "error" ) {
            job.emit( "error", job.error );
        }

        function done ( err, result ) {
            if ( !running[ job.id ] ) return; // disregard multiple completions
            delete running[ job.id ];

            if ( err == "Canceled" ) {
                err = new Error( err );
                err.retryable = false;
            }

            if ( err ) {
                handleJobError( job, err, options );
            } else {
                update({
                    id: job.id,
                    status: "success",
                    result: result,
                    end_on: new Date().toISOString()
                }, function ( err ) {
                    if ( err ) job.emit( "error", err );
                })
            }

            runloop( name, fn, options );
        }
    })
}

// claim and return the next available job in the queue
function next( name, options, done ) {
    var jobs = [];
    return new conn.Cursor()
        .find({ name: name, status: "pending" })
        .on( "data", function ( data ) { jobs.push( data ) } )
        .once( "error", function ( err ) {
            this.removeAllListeners();
            done( err );
        })
        .once( "end", function () {
            var now = new Date();
            var job = jobs.filter( function ( job ) {
                return !job.startAfter || new Date( job.startAfter ) <= now;
            })[ 0 ];

            if ( !job ) return done();

            // claim ownership of this job to prevent concurrently
            // running the same job by multiple processes
            claim( job, options, function ( err, job ) {
                if ( err ) return done( err );

                // job is already claimed by concurrent process,
                // continue to the next job
                if ( job == null ) return next( name, options, done );

                // claimed successfuly, return it
                done( null, job )
            })
        })
}

// attempts to claim ownership on a job by tagging it with a claim id
// and optimistically verifying that no other process has claimed it
// concurrently. This is required in order for the library to remain database
// agnostic and not reliable on any underlying locking mechanism
function claim( job, options, done ) {
    var claim = Math.random().toString( 36 ).substr( 2 );
    update({
        id: job.id,
        status: "running",
        start_on: new Date().toISOString(),
        claim: claim,
        options: options
    }, function ( err, j ) {
        if ( err ) return done( err );

        // give some time for competing claims to update
        // this is still not bulletproof. should re-think it, but it passes
        // for the bad-case test of a very slow write, and very fast read
        setTimeout( function () {
            console.log( 'Duty verifying job was claimed' );
            get( job.id, function ( err, job ) {
                if ( err ) return done( err );

                // job is already claimed by a concurrent process
                done( null, job.claim == claim ? job : null )
            })
        }, 100 )

    })
}

function get( job, done ) {
    var id = job.id || job, found;
    new conn.Cursor()
        .find({ id: id })
        .limit( 1 )
        .once( "error", done )
        .once( "end", function() { done( null, found ) } )
        .once( "data", function ( job ) {
            found = job;
        })
}

function update( job, done ) {
    var found = {};
    var updated_on = new Date().toISOString();
    new conn.Cursor()
        .find({ id: job.id })
        .once( "error", done )
        .once( "finish", done.bind( null, null, found ) )
        .once( "data", extend.bind( null, found ) )
        .once( "end", function () {
            this.end( extend( found, job, { updated_on: updated_on } ) )
        })
}

function cancel( job, done ) {
    update({
        id: job.id || job,
        status: "error",
        error: "Canceled",
    }, done )
}

// get or set the dbstream connection
function db( conn_ ) {
    if ( typeof conn_ == "undefined" ) {
        return conn;
    }
    return conn = conn_;
}

// Handle job error
function handleJobError( job, err, options ) {
    var retries = job.retries || 0;
    var retryable = err && err.retryable !== false;

    if ( retryable && retries < options.retries ) {
        var startAfter = new Date();
        startAfter.setTime( startAfter.getTime() + options.backoff );

        update( {
            id: job.id,
            status: "pending",
            retries: retries + 1,
            startAfter: startAfter.toISOString(),
            lastError: err.toString(),
        }, function( err ) {
            if ( err ) job.emit( "error", err );
        })
    } else if ( err ) {
        update( {
            id: job.id,
            status: "error",
            error: err instanceof Error ? err.toString() : err,
            end_on: new Date().toISOString()
        }, function( err ) {
            if ( err ) job.emit( "error", err );
        })
    }
}

// find and remove jobs that were expired
function expire( done ) {
    var now = new Date();

    new conn.Cursor()
        .find( { status: "running" } )
        .once( "error", done )
        .once( "finish", done )
        .on( "data", function( job ) {
            if ( job.expires_on && new Date( job.expires_on ) < now ) {
                var error = new Error( "Expired due to inactivity" );
                error.retryable = true;

                handleJobError( job, error, job.options );
            }
        })
        .once( "end", function() {
            this.end();
        });
}

// clear expired jobs once a minute
setInterval( function () {
    console.log( 'Duty expiring zombie jobs...' );
    expire( function ( err ) {
        if ( err ) {
            console.error( "Duty Error: ", err.stack || err );
        }
    })
}, 60000 ).unref();

<commit_msg>emit final- error<commit_after>var util = require( "util" );
var events = require( "events" );
var extend = require( "extend" );
var conn = require( "dbstream-memory" ).connect();

module.exports = duty;
duty.add = duty;
duty.register = register;
duty.unregister = unregister;
duty.get = get;
duty.cancel = cancel;
duty.db = db;
duty.expire = expire;

function duty ( name, data, done ) {
    done || ( done = function () {} );
    var id = Math.random().toString( 36 ).substr( 2 );
    var job = {
        name: name,
        id: id,
        status: "pending",
        data: data
    };

    var added_on = new Date().toISOString();
    var cursor = new conn.Cursor()
        .on( "error", done )
        .on( "finish", function () {
            job.added_on = added_on;
            done( null, job )
        });

    if ( data.id ) {
        var duplicate = false;
        cursor.on( "data", function ( job ) {
            var err = "Duplicate running job detected in Job #" + job.id;
            err = extend( new Error( err ), {
                code: "duplicate",
                dataid: data.id,
                jobid: job.id,
                status: job.status,
                description: "Cancel the running job first, before adding " +
                "a new one with the same data.id"
            })

            this.removeAllListeners()
            done( err )
        })
        .on( "end", push )
        .find({ status: { $nin: [ "success", "error" ] }, dataid: data.id })
    } else {
        push();
    }
    return job;

    function push() {
        cursor.end( extend( { added_on: added_on, dataid: data.id }, job ) );
    }
}

// register a listener
var listeners = {};
function register ( name, fn, options ) {
    listeners[ name ] = fn;
    options = extend({
        delay: 60000, // 1-minute?
        timeout: Infinity,
        concurrency: 1,
        retries: 0,
        backoff: 0
    }, options );

    if ( options.concurrency == Infinity || options.concurrency <= 0 ) {
        throw new Error( "Concurrency must be a finite positive number" );
    }

    for ( var i = 0 ; i < options.concurrency ; i += 1 ) {
        // space out the concurrent runloops to reduce the likelihood of
        // claim conflicts
        setTimeout( function () {
            console.log( 'Duty starting Run Loop', name );
            runloop( name, fn, options );
        }, 10 * i );
    }
}

function unregister( name ) {
    if ( arguments.length == 0 ) {
        listeners = {};
    } else {
        delete listeners[ name ];
    }
}

var running = {};
function runloop ( name, fn, options ) {

    // listener was unregistered or overridden
    if ( listeners[ name ] != fn ) return;
    var timeout = ( options.timeout && options.timeout != Infinity )
        ? options.timeout : null;

    // run the next job in the queue
    next( name, options, function ( err, job ) {

        if ( err ) {
            console.error( new Date().toISOString(), err, err.stack );
        }

        // no job found, try again after `delay` seconds
        if ( !job ) {
            return setTimeout( function () {
                console.log( 'Duty restarting run loop after delay', name );
                runloop( name, fn, options )
            }, options.delay );
        }

        // create the job emitter and bind the event listeners used to control
        // the life-cycle of the job
        running[ job.id ] = job = extend( new events.EventEmitter(), job )
            .on( "progress", function ( loaded, total, msg ) {
                if ( !running[ job.id ] ) return; // already done
                var expires_on;
                if ( timeout ) {
                    expires_on = new Date( new Date().getTime() + timeout )
                        .toISOString();
                }

                var changes = {
                    id: this.id,
                    expires_on: expires_on
                };

                if ( loaded ) {
                    changes.loaded = loaded;
                }

                if ( total ) {
                    changes.total = total;
                }

                if ( msg ) {
                    changes.progress = msg;
                }

                update( changes, function ( err, found ) {
                    extend( this, found );
                    if ( err || this.status == "error" ) {
                        this.emit( "error", err || this.error );
                    }
                }.bind( this ) );
            })
            .on( "error", done ) // captures all errors
            .once( "success", done.bind( job, undefined ) )

        // start running it
        job.emit( "progress", null, null )
        try {
            fn.call( job, job.data, function ( err, result ) {
                if ( err ) {
                    job.emit( "error", err );
                } else {
                    job.emit( "success", result )
                }
            });
        } catch ( err ) {
            job.emit( "error", err );
        }

        // did it start with an error?
        // it's possible when the job is cancelled before it started running
        if ( job.status == "error" ) {
            job.emit( "error", job.error );
        }

        function done ( err, result ) {
            if ( !running[ job.id ] ) return; // disregard multiple completions
            delete running[ job.id ];

            if ( err == "Canceled" ) {
                err = new Error( err );
                err.retryable = false;
            }

            if ( err ) {
                handleJobError( job, err, options );
            } else {
                update({
                    id: job.id,
                    status: "success",
                    result: result,
                    end_on: new Date().toISOString()
                }, function ( err ) {
                    if ( err ) job.emit( "error", err );
                })
            }

            runloop( name, fn, options );
        }
    })
}

// claim and return the next available job in the queue
function next( name, options, done ) {
    var jobs = [];
    return new conn.Cursor()
        .find({ name: name, status: "pending" })
        .on( "data", function ( data ) { jobs.push( data ) } )
        .once( "error", function ( err ) {
            this.removeAllListeners();
            done( err );
        })
        .once( "end", function () {
            var now = new Date();
            var job = jobs.filter( function ( job ) {
                return !job.startAfter || new Date( job.startAfter ) <= now;
            })[ 0 ];

            if ( !job ) return done();

            // claim ownership of this job to prevent concurrently
            // running the same job by multiple processes
            claim( job, options, function ( err, job ) {
                if ( err ) return done( err );

                // job is already claimed by concurrent process,
                // continue to the next job
                if ( job == null ) return next( name, options, done );

                // claimed successfuly, return it
                done( null, job )
            })
        })
}

// attempts to claim ownership on a job by tagging it with a claim id
// and optimistically verifying that no other process has claimed it
// concurrently. This is required in order for the library to remain database
// agnostic and not reliable on any underlying locking mechanism
function claim( job, options, done ) {
    var claim = Math.random().toString( 36 ).substr( 2 );
    update({
        id: job.id,
        status: "running",
        start_on: new Date().toISOString(),
        claim: claim,
        options: options
    }, function ( err, j ) {
        if ( err ) return done( err );

        // give some time for competing claims to update
        // this is still not bulletproof. should re-think it, but it passes
        // for the bad-case test of a very slow write, and very fast read
        setTimeout( function () {
            console.log( 'Duty verifying job was claimed' );
            get( job.id, function ( err, job ) {
                if ( err ) return done( err );

                // job is already claimed by a concurrent process
                done( null, job.claim == claim ? job : null )
            })
        }, 100 )

    })
}

function get( job, done ) {
    var id = job.id || job, found;
    new conn.Cursor()
        .find({ id: id })
        .limit( 1 )
        .once( "error", done )
        .once( "end", function() { done( null, found ) } )
        .once( "data", function ( job ) {
            found = job;
        })
}

function update( job, done ) {
    var found = {};
    var updated_on = new Date().toISOString();
    new conn.Cursor()
        .find({ id: job.id })
        .once( "error", done )
        .once( "finish", done.bind( null, null, found ) )
        .once( "data", extend.bind( null, found ) )
        .once( "end", function () {
            this.end( extend( found, job, { updated_on: updated_on } ) )
        })
}

function cancel( job, done ) {
    update({
        id: job.id || job,
        status: "error",
        error: "Canceled",
    }, done )
}

// get or set the dbstream connection
function db( conn_ ) {
    if ( typeof conn_ == "undefined" ) {
        return conn;
    }
    return conn = conn_;
}

// Handle job error
function handleJobError( job, err, options ) {
    var retries = job.retries || 0;
    var retryable = err && err.retryable !== false;

    if ( retryable && retries < options.retries ) {
        var startAfter = new Date();
        startAfter.setTime( startAfter.getTime() + options.backoff );

        update( {
            id: job.id,
            status: "pending",
            retries: retries + 1,
            startAfter: startAfter.toISOString(),
            lastError: err.toString(),
        }, function( err ) {
            if ( err ) job.emit( "error", err );
        })
    } else if ( err ) {
        job.emit( "final-error", err );
        update( {
            id: job.id,
            status: "error",
            error: err instanceof Error ? err.toString() : err,
            end_on: new Date().toISOString()
        }, function( err ) {
            if ( err ) job.emit( "error", err );
        })
    }
}

// find and remove jobs that were expired
function expire( done ) {
    var now = new Date();

    new conn.Cursor()
        .find( { status: "running" } )
        .once( "error", done )
        .once( "finish", done )
        .on( "data", function( job ) {
            if ( job.expires_on && new Date( job.expires_on ) < now ) {
                var error = new Error( "Expired due to inactivity" );
                error.retryable = true;

                handleJobError( job, error, job.options );
            }
        })
        .once( "end", function() {
            this.end();
        });
}

// clear expired jobs once a minute
setInterval( function () {
    console.log( 'Duty expiring zombie jobs...' );
    expire( function ( err ) {
        if ( err ) {
            console.error( "Duty Error: ", err.stack || err );
        }
    })
}, 60000 ).unref();

<|endoftext|>


<commit_before>var IDLE_RATE = 200;
var RATE = 10;

function initMemory() {
  if (!Memory.rooms) {
    Memory.rooms = {};
  }
  for (var room in Game.rooms) {
    if (!Memory.rooms[room]) {
      var defaults = {
        maxCreeps: 7
      };
      Memory.rooms[room] = defaults;
    }
  }
}

function checkIdle() {
  for (var name in Game.rooms) {
    var room = Game.rooms[name];
    var creeps = room.find(FIND_MY_CREEPS);
    var idle = 0;
    for (var creep of creeps) {
      idle += creep.idlePercent();
    }
    var numCreeps = creeps.length
    idle = idle / numCreeps;

    if (idle > 30) {
      room.log('Creep idle rate over 30%, decreasing creeps. Saw ' + idle + '%');
      Memory.rooms[name].maxCreeps = numCreeps - 1;
    }
  }
}

function checkEnergy() {
  if (Game.time % IDLE_RATE == 0) {
    checkIdle();
  }
  if (Game.time % RATE != 0) {
    return;
  }
  for (var name in Game.rooms) {
    var room = Game.rooms[name];
    if (room.find(FIND_MY_SPAWNS).length === 0) continue;
    var sources = room.find(FIND_SOURCES);
    var wastedEnergy = 0;
    var wastedTicks = 999;

    for (var source of sources) {
      var energy = source.energy;
      var toRegen = source.ticksToRegeneration;

      // if a source is about to regen, see if it has wasted energy
      if (toRegen <= RATE) {
        wastedEnergy += energy;
      }
      // if a source has energy we haven't wasted any ticks
      if (energy > 0) {
        wastedTicks = 0;
      } else if (energy === 0) {
        wastedTicks = Math.min(wastedTicks, toRegen);
      }
    }

    // make adjustments if necessary
    var numCreeps = room.find(FIND_MY_CREEPS).length;
    if (wastedEnergy > 500) {
      room.log('Too much wasted energy, increasing creeps. Saw ' + wastedEnergy);
      Memory.rooms[name].maxCreeps = numCreeps + 1;
    } else if (wastedTicks > 50) {
      room.log('Too many wasted ticks, decreasing creeps. Saw ' + wastedTicks);
      Memory.rooms[name].maxCreeps = numCreeps - 1;
    }
  }
}

function getMaxCreeps(roomName) {
  return Memory.rooms[roomName].maxCreeps;
}

module.exports = {
  initMemory: initMemory,
  checkEnergy: checkEnergy,
  getMaxCreeps: getMaxCreeps
};
<commit_msg>tighten idle lower bound<commit_after>var IDLE_RATE = 200;
var RATE = 10;

function initMemory() {
  if (!Memory.rooms) {
    Memory.rooms = {};
  }
  for (var room in Game.rooms) {
    if (!Memory.rooms[room]) {
      var defaults = {
        maxCreeps: 7
      };
      Memory.rooms[room] = defaults;
    }
  }
}

function checkIdle() {
  for (var name in Game.rooms) {
    var room = Game.rooms[name];
    var creeps = room.find(FIND_MY_CREEPS);
    var idle = 0;
    for (var creep of creeps) {
      idle += creep.idlePercent();
    }
    var numCreeps = creeps.length
    idle = idle / numCreeps;

    if (idle > 25) {
      room.log('Creep idle rate over 25%, decreasing creeps. Saw ' + idle + '%');
      Memory.rooms[name].maxCreeps = numCreeps - 1;
    }
  }
}

function checkEnergy() {
  if (Game.time % IDLE_RATE == 0) {
    checkIdle();
  }
  if (Game.time % RATE != 0) {
    return;
  }
  for (var name in Game.rooms) {
    var room = Game.rooms[name];
    if (room.find(FIND_MY_SPAWNS).length === 0) continue;
    var sources = room.find(FIND_SOURCES);
    var wastedEnergy = 0;
    var wastedTicks = 999;

    for (var source of sources) {
      var energy = source.energy;
      var toRegen = source.ticksToRegeneration;

      // if a source is about to regen, see if it has wasted energy
      if (toRegen <= RATE) {
        wastedEnergy += energy;
      }
      // if a source has energy we haven't wasted any ticks
      if (energy > 0) {
        wastedTicks = 0;
      } else if (energy === 0) {
        wastedTicks = Math.min(wastedTicks, toRegen);
      }
    }

    // make adjustments if necessary
    var numCreeps = room.find(FIND_MY_CREEPS).length;
    if (wastedEnergy > 500) {
      room.log('Too much wasted energy, increasing creeps. Saw ' + wastedEnergy);
      Memory.rooms[name].maxCreeps = numCreeps + 1;
    } else if (wastedTicks > 50) {
      room.log('Too many wasted ticks, decreasing creeps. Saw ' + wastedTicks);
      Memory.rooms[name].maxCreeps = numCreeps - 1;
    }
  }
}

function getMaxCreeps(roomName) {
  return Memory.rooms[roomName].maxCreeps;
}

module.exports = {
  initMemory: initMemory,
  checkEnergy: checkEnergy,
  getMaxCreeps: getMaxCreeps
};
<|endoftext|>


<commit_before>import {
    INSTALL_STATE,
    UPDATE_STATE,
    NORMAL_STATE
} from '../.utils/chrome/extension-state'

const messages = [
    /*{
        state: INSTALL_STATE,
        value: 'Thank you. This extension is free, but if you want to support development of this or my other projects, [buy me a beer](https://www.google.com)'
    },*/
    {
        state: UPDATE_STATE,
        value: 'The extension has been successfully updated!'
    }
]

export default messages
<commit_msg>add link to the description of extension<commit_after>import {
    INSTALL_STATE,
    UPDATE_STATE,
    NORMAL_STATE
} from '../.utils/chrome/extension-state'

const messages = [
    /*{
        state: INSTALL_STATE,
        value: 'Thank you. This extension is free, but if you want to support development of this or my other projects, [buy me a beer](https://www.google.com)'
    },*/
    {
        state: UPDATE_STATE,
        value: 'The extension has been successfully updated! [more details in description](https://chrome.google.com/webstore/detail/change-case/lpakoahdokkkonadfppfgmednkknpgbm)'
    }
]

export default messages
<|endoftext|>


<commit_before>
FacebookAlbumSelector = {
  albums: new Array(),
  inited: false,
  block_id: 'facebook_albums',
  login_id: 'facebook_login',
  heading_id: 'facebook_heading',
  form_name: 'facebook_media_',

  init: function(form_name) {
    if(this.inited) {  return; }
    this.inited = true;

    this.form_name = form_name;

    $(this.block_id).hide();

    $(this.heading_id).innerHTML = 'Fetching Facebook photo albums ...';

    this.fetch();
  },

  fetch: function() {
    new Ajax.Request('/website/facebooked/api/albums', {onComplete: function(transport) {
      var response = transport.responseText.evalJSON();

      if( ! response  ) {
        $(FacebookAlbumSelector.heading_id).hide();
        $(FacebookAlbumSelector.login_id).show();
        return;
      }

      for( var i=0; i<response.length; i++ ) {
        var name = response[i].name;
        var id = response[i].id;
        if( ! name ) { name = "Photo Album " + (i+1); }

        FacebookAlbumSelector.albums.push({
          id: id,
          name: name,
          type: 'album',
          link: response[i].link,
          count: response[i].count,
          author_id: response[i].author_id,
          author_name: response[i].author_name,
          picture: response[i].picture,
          thumbnail: response[i].thumbnail,
          width: response[i].width,
          height: response[i].height
        });
      }

      FacebookAlbumSelector.ready();
    }});
  },

  album: function(id) {
    for(var i=0; i<this.albums.length; i++) {
      if( this.albums[i].id == id ) {
        return this.albums[i];
      }
    }
    return null;
  },

  select: function(id) {
    $$('.fb_album_image').each(function(e) { e.className = 'fb_album_image' });
    $$('.fb_album_name').each(function(e) { e.className = 'fb_album_name' });
    $(this.block_id).className = '';

    var album = this.album(id);
    if(album == null) { return; }

    if( $(this.form_name + '_id').value == id ) {
      $(this.form_name + '_id').value = '';
    } else {
      $(this.form_name + '_id').value = id;
      $(this.form_name + '_name').value = album.name;
      $(this.form_name + '_link').value = album.link;
      $(this.form_name + '_count').value = album.count;
      $(this.form_name + '_type').value = album.type;
      $(this.form_name + '_picture').value = album.picture;
      $(this.form_name + '_width').value = album.width;
      $(this.form_name + '_height').value = album.height;
      $(this.form_name + '_author_name').value = album.author_name;
      $(this.form_name + '_author_id').value = album.author_id;
      $('fb_album_image_' + id).className = 'fb_album_image fb_album_image_selected';
      $('fb_album_name_' + id).className = 'fb_album_name fb_album_name_selected';
    }
  },

  ready: function(id) {
    if(this.inited == false) { return; }

    var imageRow = Builder.node('tr', {className: 'fb_album_images'});
    var nameRow = Builder.node('tr', {className: 'fb_album_names'});

    for( var i=0; i<this.albums.length; i++ ) {
      var onclick = 'FacebookAlbumSelector.select("' + this.albums[i].id + '");';

      var className = this.albums[i].id == id ? 'fb_album_image fb_album_image_selected' : 'fb_album_image';
      imageRow.insert(Builder.node('td', {className: className, id: 'fb_album_image_' + this.albums[i].id},
                                   Builder.node('a', {className: 'fb_album_photo', href: 'javascript:void(0);', onclick: onclick},
                                                Builder.node('img', {src: this.albums[i].thumbnail, width: 90, alt: this.albums[i].name, title: this.albums[i].name}))));

      className = this.albums[i].id == id ? 'fb_album_name fb_album_name_selected' : 'fb_album_name';
      nameRow.insert(Builder.node('td', {className: className, id: 'fb_album_name_' + this.albums[i].id},
                                  Builder.node('a', {className: 'fb_album_name', href: 'javascript:void(0);', onclick: onclick}, this.albums[i].name)));
    }

    $(this.heading_id).innerHTML = 'Share your Facebook photo albums';
    $(this.block_id).insert(Builder.node('table', {}, [imageRow, nameRow]));
    $(this.block_id).show();
  }
}
<commit_msg>Display you have no public albums if no albums are returned.<commit_after>
FacebookAlbumSelector = {
  albums: new Array(),
  inited: false,
  block_id: 'facebook_albums',
  login_id: 'facebook_login',
  heading_id: 'facebook_heading',
  form_name: 'facebook_media_',

  init: function(form_name) {
    if(this.inited) {  return; }
    this.inited = true;

    this.form_name = form_name;

    $(this.block_id).hide();

    $(this.heading_id).innerHTML = 'Fetching Facebook photo albums ...';

    this.fetch();
  },

  fetch: function() {
    new Ajax.Request('/website/facebooked/api/albums', {onComplete: function(transport) {
      var response = transport.responseText.evalJSON();

      if( ! response  ) {
        $(FacebookAlbumSelector.heading_id).hide();
        $(FacebookAlbumSelector.login_id).show();
        return;
      }

      for( var i=0; i<response.length; i++ ) {
        var name = response[i].name;
        var id = response[i].id;
        if( ! name ) { name = "Photo Album " + (i+1); }

        FacebookAlbumSelector.albums.push({
          id: id,
          name: name,
          type: 'album',
          link: response[i].link,
          count: response[i].count,
          author_id: response[i].author_id,
          author_name: response[i].author_name,
          picture: response[i].picture,
          thumbnail: response[i].thumbnail,
          width: response[i].width,
          height: response[i].height
        });
      }

      FacebookAlbumSelector.ready();
    }});
  },

  album: function(id) {
    for(var i=0; i<this.albums.length; i++) {
      if( this.albums[i].id == id ) {
        return this.albums[i];
      }
    }
    return null;
  },

  select: function(id) {
    $$('.fb_album_image').each(function(e) { e.className = 'fb_album_image' });
    $$('.fb_album_name').each(function(e) { e.className = 'fb_album_name' });
    $(this.block_id).className = '';

    var album = this.album(id);
    if(album == null) { return; }

    if( $(this.form_name + '_id').value == id ) {
      $(this.form_name + '_id').value = '';
    } else {
      $(this.form_name + '_id').value = id;
      $(this.form_name + '_name').value = album.name;
      $(this.form_name + '_link').value = album.link;
      $(this.form_name + '_count').value = album.count;
      $(this.form_name + '_type').value = album.type;
      $(this.form_name + '_picture').value = album.picture;
      $(this.form_name + '_width').value = album.width;
      $(this.form_name + '_height').value = album.height;
      $(this.form_name + '_author_name').value = album.author_name;
      $(this.form_name + '_author_id').value = album.author_id;
      $('fb_album_image_' + id).className = 'fb_album_image fb_album_image_selected';
      $('fb_album_name_' + id).className = 'fb_album_name fb_album_name_selected';
    }
  },

  ready: function(id) {
    if(this.inited == false) { return; }

    var imageRow = Builder.node('tr', {className: 'fb_album_images'});
    var nameRow = Builder.node('tr', {className: 'fb_album_names'});

    for( var i=0; i<this.albums.length; i++ ) {
      var onclick = 'FacebookAlbumSelector.select("' + this.albums[i].id + '");';

      var className = this.albums[i].id == id ? 'fb_album_image fb_album_image_selected' : 'fb_album_image';
      imageRow.insert(Builder.node('td', {className: className, id: 'fb_album_image_' + this.albums[i].id},
                                   Builder.node('a', {className: 'fb_album_photo', href: 'javascript:void(0);', onclick: onclick},
                                                Builder.node('img', {src: this.albums[i].thumbnail, width: 90, alt: this.albums[i].name, title: this.albums[i].name}))));

      className = this.albums[i].id == id ? 'fb_album_name fb_album_name_selected' : 'fb_album_name';
      nameRow.insert(Builder.node('td', {className: className, id: 'fb_album_name_' + this.albums[i].id},
                                  Builder.node('a', {className: 'fb_album_name', href: 'javascript:void(0);', onclick: onclick}, this.albums[i].name)));
    }

    $(this.heading_id).innerHTML = 'Share your Facebook photo albums';
    if(this.albums.length == 0) {
      $(this.block_id).insert(Builder.node('p', {style: "text-align:center;"}, "You have no Public Photo Albums, make an Album public to post it."));
    } else {
      $(this.block_id).insert(Builder.node('table', {}, [imageRow, nameRow]));
    }
    $(this.block_id).show();
  }
}
<|endoftext|>


<commit_before>window.chanakya = window.chanakya || {};
(function ($) {

  // get city http://maps.googleapis.com/maps/api/geocode/json?latlng=12.9667,77.5667
  // chanakya.Map.Details.source
  //  var url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng=12.9667,77.5667';
  //  $.ajax({
  //    type: 'GET',
  //    url: url,
  //    async: false,
  //    contentType: "application/json",
  //    dataType: 'jsonp'
  //  });
  //

  window.chanakya.cost = (function () {
    var rates = (function () {
      var city = "Bengaluru";
      var auto = function () {
        if (city === "Bengaluru")
          return 13;
        else return 10;
      }
      var ola = function (type) {
        if (city === "Bengaluru") {
          if (type === "mini") return 10;
          if (type === "sedan") return 13;
          if (type === "prime") return 18;
          if (type === "airportmini") return 13;
          if (type === "airportsedan") return 16;
          if (type === "airportprime") return 18;
          return -1;
        }
        return -1;
      }
      var tfs = function (type) {
        if (city === "Bengaluru") {
          if (type === "nano") return 10;
          if (type === "indica") return 14;
          if (type === "sedan") return 16;
          //          if (type === "airportmini") return 13;
          //          if (type === "airportsedan") return 16;
          //          if (type === "airportprime") return 18;
          return -1;
        }
        return -1;
      }
      return {
        auto: auto,
        ola: ola,
        tfs: tfs
      };
    })();

    var auto = function (dist) {
      if (dist <= 1.9) return 25;
      return dist * rates.auto();
    }
    var ola = function dist(dist, type) {
      if (type === "mini") {
        if (dist <= 6) return 100;
        return 100 + (dist - 6) * rates.ola(type);
      }
      if (type === "sedan") {
        if (dist <= 8) return 150;
        return 150 + (dist - 6) * rates.ola(type);
      }
      if (type === "prime") {
        if (dist <= 5) return 200;
        return 200 + (dist - 5) * rates.ola(type);
      }
      if (type === "airportmini") {
        if (dist <= 30) return 540;
        return 540 + (dist - 30) * rates.ola(type);
      }
      if (type === "airportsedan") {
        if (dist <= 30) return 600;
        return 600 + (dist - 30) * rates.ola(type);
      }
      if (type === "airportprime") {
        if (dist <= 30) return 800;
        return 800 + (dist - 30) * rates.ola(type);
      }
      return -1;
    }
    var tfs = function dist(dist, type) {
      if (type === "nano") {
        if (dist <= 2) return 25;
        return 25 + (dist - 2) * rates.tfs(type);
      }
      if (type === "indica") {
        if (dist <= 4) return 49;
        return 49 + (dist - 4) * rates.tfs(type);
      }
      if (type === "sedan") {
        if (dist <= 4) return 49;
        return 49 + (dist - 4) * rates.tfs(type);
      }
      return -1;
    }
    var cheapest = function (dist) {
      var service = ["", 1000000];
      if (auto(dist) < service[1]) {
        service = ["auto", auto(dist)];
      }
      if (ola(dist, "mini") < service[1]) {
        service = ["ola", ola(dist, "mini")];
      }
      if (tfs(dist, "nano") < service[1]) {
        service = ["tfs", tfs(dist, "nano")];
      }
      return service;
    }
    return {
      auto: auto,
      ola: ola,
      tfs: tfs,
      cheapest: cheapest
    };
  })();
})(jQuery);<commit_msg>adding comment for airport<commit_after>window.chanakya = window.chanakya || {};
(function ($) {

  // get city http://maps.googleapis.com/maps/api/geocode/json?latlng=12.9667,77.5667
  // chanakya.Map.Details.source
  //  var url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng=12.9667,77.5667';
  //  $.ajax({
  //    type: 'GET',
  //    url: url,
  //    async: false,
  //    contentType: "application/json",
  //    dataType: 'jsonp'
  //  });
  //

  window.chanakya.cost = (function () {
    var rates = (function () {
      var city = "Bengaluru";
      var auto = function () {
        if (city === "Bengaluru")
          return 13;
        else return 10;
      }
      var ola = function (type) {
        if (city === "Bengaluru") {
          if (type === "mini") return 10;
          if (type === "sedan") return 13;
          if (type === "prime") return 18;
          if (type === "airportmini") return 13;
          if (type === "airportsedan") return 16;
          if (type === "airportprime") return 18;
          return -1;
        }
        return -1;
      }
      var tfs = function (type) {
        if (city === "Bengaluru") {
          if (type === "nano") return 10;
          if (type === "indica") return 14;
          if (type === "sedan") return 16;
          // TODO: for airport
          //          if (type === "airportmini") return 13;
          //          if (type === "airportsedan") return 16;
          //          if (type === "airportprime") return 18;
          return -1;
        }
        return -1;
      }
      return {
        auto: auto,
        ola: ola,
        tfs: tfs
      };
    })();

    var auto = function (dist) {
      if (dist <= 1.9) return 25;
      return dist * rates.auto();
    }
    var ola = function dist(dist, type) {
      if (type === "mini") {
        if (dist <= 6) return 100;
        return 100 + (dist - 6) * rates.ola(type);
      }
      if (type === "sedan") {
        if (dist <= 8) return 150;
        return 150 + (dist - 6) * rates.ola(type);
      }
      if (type === "prime") {
        if (dist <= 5) return 200;
        return 200 + (dist - 5) * rates.ola(type);
      }
      if (type === "airportmini") {
        if (dist <= 30) return 540;
        return 540 + (dist - 30) * rates.ola(type);
      }
      if (type === "airportsedan") {
        if (dist <= 30) return 600;
        return 600 + (dist - 30) * rates.ola(type);
      }
      if (type === "airportprime") {
        if (dist <= 30) return 800;
        return 800 + (dist - 30) * rates.ola(type);
      }
      return -1;
    }
    var tfs = function dist(dist, type) {
      if (type === "nano") {
        if (dist <= 2) return 25;
        return 25 + (dist - 2) * rates.tfs(type);
      }
      if (type === "indica") {
        if (dist <= 4) return 49;
        return 49 + (dist - 4) * rates.tfs(type);
      }
      if (type === "sedan") {
        if (dist <= 4) return 49;
        return 49 + (dist - 4) * rates.tfs(type);
      }
      return -1;
    }
    var cheapest = function (dist) {
      var service = ["", 1000000];
      if (auto(dist) < service[1]) {
        service = ["auto", auto(dist)];
      }
      if (ola(dist, "mini") < service[1]) {
        service = ["ola", ola(dist, "mini")];
      }
      if (tfs(dist, "nano") < service[1]) {
        service = ["tfs", tfs(dist, "nano")];
      }
      return service;
    }
    return {
      auto: auto,
      ola: ola,
      tfs: tfs,
      cheapest: cheapest
    };
  })();
})(jQuery);<|endoftext|>


<commit_before>$(document).ready(function() {

    $('.newfield').click(function(event) {
        event.preventDefault();
        $('form .' + $(this).attr('target')).parent().append(newField($(this).attr('target')));
    });

    $('.new').click(function() {
        $('#mode').attr('value', 'new');
    });

    $('.edit').click(function() {
        $('#mode').attr('value', $(this).attr('id'));
        $.ajax({
            url: '/itemdata/edit',
            data: {'id': $(this).attr('id')},
            type: 'POST',
            success: function (data) {
                deleteFields();
                insertFields(data);
            }
        });
    });

    $('.delete').click(function() {
        $.ajax({
            url: '/itemdata/delete',
            data: {'id': $(this).attr('id')},
            type: 'POST'
        });
    });

    function newField(field) {
        var target = 'form .'+ field,
            newField = $(target).clone();
        newField.attr({
            'name': $(target).attr('name'),
            'class': field + $('form input[name="'+ $(target).attr('name') + '"]').length,
            'new': true
        });
        newField.val('');
        return newField;
    }

    function deleteFields() {
        var fields = $('input');
        for (var i = 0; i < fields.length; i++) {
            if ($(fields[i]).attr('new')) {
                $(fields[i]).remove();
            }
        }
    }

    function insertFields(data) {
        var dataKeys = Object.keys(data);
        for (var i = 0; i < dataKeys.length; i++) {
            if (typeof(data[dataKeys[i]]) === 'string') {
                var field = $('form').find('[name=' + dataKeys[i] + ']');
                field.val(data[dataKeys[i]]);
            }
            else if (typeof(data[dataKeys[i]]) === 'object') {
                if (dataKeys[i] === 'Images') {
                    $('form').find('[name=' + dataKeys[i] + ']').val(data[dataKeys[i]].shift());
                    data[dataKeys[i]].forEach(function(element) {
                        $('#Images').append(newField(dataKeys[i]).val(element));
                    }, this);
                }
                else {
                    var keys = Object.keys(data[dataKeys[i]]),
                        subData = data[dataKeys[i]];
                    for (var j = 0; j < keys.length; j++) {
                        var selec = $('button[target="' + keys[j] + '"]'),
                            name = '[name="sub' + keys[j] + ',' + dataKeys[i] + '"]',
                            field = $('form').find(name);
                        if (typeof(subData[keys[j]]) === 'object') {
                            $(field).val(subData[keys[j]].shift());
                            subData[keys[j]].forEach(function(element) {
                                selec.parent().append(newField(keys[j]).val(element));
                            }, this);
                        }
                        else {
                            field.val(subData[keys[j]]);
                        }
                    }
                }
            }

        }
    }

});<commit_msg>Reworked frontend item data methods<commit_after>$(document).ready(function () {
  'use strict';

  $('.newfield').click(function () {
    var field = $(this).parent().find('input:first-of-type');
    $(field).after($(field).clone().css('display', 'block').attr('extra', true).val(''));
  });

  $('.new').click(function () {
    $('#mode-display').text('Create new item');
    $('#mode').attr('value', 'new');
    clearFields();
  });

  $('.edit').click(function () {
    var parentId = $(this).parent().attr('id');
    $('#mode-display').text('Editing '+parentId );
    $('#mode').attr('value', parentId.split(':')[1]);
    $.ajax({
      url: '/itemdata/edit',
      data: { 'id': parentId.split(':')[1] },
      type: 'POST',
      success: function (data) {
        //console.log(data)
        clearFields();
        insertFields(data);
      }
    });
  });

  $('.delete').click(function () {
    var parentId = $(this).parent().attr('id');
    $.ajax({
      url: '/itemdata/delete',
      data: { 'id': parentId.split(':')[1] },
      type: 'POST'
    });
  });

  function clearFields() {
    var fields = $('input, textarea');
    for (var i = 0; i < fields.length; i++) {
      if ($(fields[i]).attr('type') !== 'hidden') {
        $(fields[i]).val('');
      }
      if ($(fields[i]).attr('extra')) {
        $(fields[i]).remove();
      }
    }
  }

  function insertFields(data) {
    var dataKeys = Object.keys(data);
    for (var i = 0; i < dataKeys.length; i++) {
      var key = dataKeys[i]
      var keyData = data[key]
      if (typeof (keyData) === 'string' || key === 'Images') {
        addFieldData(key, keyData)
      }
      else if (typeof (keyData) === 'object') {
        var key_2 = Object.keys(keyData)
        var keyData_2 = keyData
        for (var j = 0; j < key_2.length; j++) {
          console.log(key_2[j])
          addFieldData(key +'\\:'+ key_2[j], keyData_2[key_2[j]]);
        }
      }
    }
  }

  function addFieldData(key, data) {
    var field = $('form').find('#'+key).children('[name='+key+']');
    if (!Array.isArray(data)) {
      field.val(data);
    }
    else {
      data = data.reverse()
      $(field).val(data.pop())
      for (var i = 0; i < data.length; i++) {
        $(field).after($(field).clone().css('display', 'block').attr('extra', true).val(data[i]));
      }
    }
  }

});<|endoftext|>


<commit_before>window.onload = function() {
	var editorTextarea = document.getElementsByName("source")[0];
	editorTextarea.style.display = "none";
	var addSourceDiv = function() {
		var editorTextareaParent = editorTextarea.parentNode;
		var editorDiv = document.createElement("div");
		editorDiv.id = "source";
		editorTextareaParent.appendChild(editorDiv);
	};
	var setUpFormOnSubmit = function(editor) {
		var markleterForm = document.getElementsByTagName("form")[0];
		markleterForm.onsubmit = function() {
			editorTextarea.innerHTML = editor.getSession().getValue();
		};
	};
	var replaceTextarea = function() {
		addSourceDiv();
		var editor = ace.edit("source");
		setUpFormOnSubmit(editor);
		editor.getSession().setMode("ace/mode/javascript");
		editor.getSession().setValue(editorTextarea.innerHTML);
	};
	var getIEVersion = function() {
		var ua = window.navigator.userAgent;
		var msie = ua.indexOf("MSIE ");
		if (msie > 0) {
			return parseInt(ua.substring(msie+5, ua.indexOf(".", msie)));
		} else {
			return 0;
		}
	};
	var msie = getIEVersion();
	if (msie == 0 || msie > 7) {
		replaceTextarea();
	}
};
<commit_msg>Fixed fix in IE7.<commit_after>window.onload = function() {
	var editorTextarea = document.getElementsByName("source")[0];
	var addSourceDiv = function() {
		var editorTextareaParent = editorTextarea.parentNode;
		var editorDiv = document.createElement("div");
		editorDiv.id = "source";
		editorTextareaParent.appendChild(editorDiv);
	};
	var setUpFormOnSubmit = function(editor) {
		var markleterForm = document.getElementsByTagName("form")[0];
		markleterForm.onsubmit = function() {
			editorTextarea.innerHTML = editor.getSession().getValue();
		};
	};
	var replaceTextarea = function() {
		editorTextarea.style.display = "none";
		addSourceDiv();
		var editor = ace.edit("source");
		setUpFormOnSubmit(editor);
		editor.getSession().setMode("ace/mode/javascript");
		editor.getSession().setValue(editorTextarea.innerHTML);
	};
	var getIEVersion = function() {
		var ua = window.navigator.userAgent;
		var msie = ua.indexOf("MSIE ");
		if (msie > 0) {
			return parseInt(ua.substring(msie+5, ua.indexOf(".", msie)));
		} else {
			return 0;
		}
	};
	var msie = getIEVersion();
	if (msie == 0 || msie > 7) {
		replaceTextarea();
	}
};
<|endoftext|>