<commit_before>/**
 * A class to represent the memory layout for a vertex attribute array. Used by
 * {@link Mesh}'s TBD(...) method to generate a packed array from mesh data.
 *

 * Layout can sort of be thought of as a C-style struct declaration.
 * {@link Mesh}'s TBD(...) method will use the {@link Layout} instance to
 * pack an array in the given attribute order.
 *

 * Layout also is very helpful when calling a WebGL context's
 * vertexAttribPointer method. If you've created a buffer using
 * a Layout instance, then the same Layout instance can be used to determine
 * the size, type, normalized, stride, and offset parameters for
 * vertexAttribPointer.
 *

 * For example:
 *

 *
 * let index = glctx.getAttribLocation(shaderProgram, "pos");
 * glctx.vertexAttribPointer(
 *   layout.position.size,
 *   glctx[layout.position.type],
 *   layout.position.normalized,
 *   layout.position.stride,
 *   layout.position.offset);
 *

 * @see {@link Mesh}
 */
export class Layout {
    /**
     * Create a Layout object. This constructor will throw if any duplicate
     * attributes are given.
     * @param {Array} ...attributes - An ordered list of attributes that
     *        describe the desired memory layout for each vertex attribute.
     *

     *
     * @see {@link Mesh}
     */
    constructor(...attributes) {
        this.attributes = {};
        let offset = 0;
        for (let attribute of attributes) {
            if (this[attribute.key]) {
                throw new DuplicateAttributeException(attribute);
            }
            this[attribute.key] = {
                'attribute': attribute,
                'size': attribute.size,
                'type': attribute.type,
                'normalized': attribute.normalized,
                'offset': offset,
            };
            offset += attribute.sizeInBytes;
        }
        this.stride = offset;
        for (let attribute of attributes) {
            this[attribute.key].stride = this.stride;
        }
    }
}

/**
 * An exception for when two or more of the same attributes are found in the
 * same layout.
 * @private
 */
class DuplicateAttributeException {
    /**
     * Create a DuplicateAttributeException
     * @param {Attribute} attribute - The attribute that was found more than
     *        once in the {@link Layout}
     */
    constructor(attribute) {
        this.message = 'found duplicate attribute: ' + attribute.key;
    }
}

/**
 * Represents how a vertex attribute should be packed into an buffer.
 * @private
 */
class Attribute {
    /**
     * Create an attribute. Do not call this directly, use the predefined
     * constants.
     * @param {string} key - The name of this attribute as if it were a key in
     *        an Object. Use the camel case version of the upper snake case
     *        const name.
     * @param {number} size - The number of components per vertex attribute.
     *        Must be 1, 2, 3, or 4.
     * @param {string} type - The data type of each component for this
     *        attribute. Possible values:

     *        "BYTE": signed 8-bit integer, with values in [-128, 127]

     *        "SHORT": signed 16-bit integer, with values in
     *            [-32768, 32767]

     *        "UNSIGNED_BYTE": unsigned 8-bit integer, with values in
     *            [0, 255]

     *        "UNSIGNED_SHORT": unsigned 16-bit integer, with values in
     *            [0, 65535]

     *        "FLOAT": 32-bit floating point number
     * @param {boolean} normalized - Whether integer data values should be
     *        normalized when being casted to a float.

     *        If true, signed integers are normalized to [-1, 1].

     *        If true, unsigned integers are normalized to [0, 1].

     *        For type "FLOAT", this parameter has no effect.
     */
    constructor(key, size, type, normalized=false) {
        this.key = key;
        this.size = size;
        this.type = type;
        this.normalized = false;
        this.sizeInBytes = sizeInBytesOfType(type) * size;
    }
}

/**
 * @param {string} type - A type accepted by {@link Attribute}.
 * @return The size (in bytes) for a given type.
 * @see {@link Attribute}
 * @private
 */
function sizeInBytesOfType(type) {
    switch (type) {
        case 'BYTE':
        case 'UNSIGNED_BYTE':
            return 1;
        case 'SHORT':
        case 'UNSIGNED_SHORT':
            return 2;
        case 'FLOAT':
            return 4;
    }
}

// Geometry attributes
/**
 * Attribute layout to pack a vertex's x, y, & z as floats
 *
 * @see {@link Layout}
 */
Layout.POSITION = new Attribute('position', 3, 'FLOAT');

/**
 * Attribute layout to pack a vertex's normal's x, y, & z as floats
 *
 * @see {@link Layout}
 */
Layout.NORMAL = new Attribute('normal', 3, 'FLOAT');

/**
 * Attribute layout to pack a vertex's normal's x, y, & z as floats.
 *

 * This value will be computed on-the-fly based on the texture coordinates.
 * If no texture coordinates are available, the generated value will default to
 * 0, 0, 0.
 *
 * @see {@link Layout}
 */
Layout.TANGENT = new Attribute('tangent', 3, 'FLOAT');

/**
 * Attribute layout to pack a vertex's normal's bitangent x, y, & z as floats.
 *

 * This value will be computed on-the-fly based on the texture coordinates.
 * If no texture coordinates are available, the generated value will default to
 * 0, 0, 0.
 * @see {@link Layout}
 */
Layout.BITANGENT = new Attribute('bitangent', 3, 'FLOAT');

/**
 * Attribute layout to pack a vertex's texture coordinates' u & v as floats
 *
 * @see {@link Layout}
 */
Layout.UV = new Attribute('uv', 2, 'FLOAT');

// Material attributes

/**
 * Attribute layout to pack an unsigned short to be interpreted as a the index
 * into a {@link Mesh}'s materials list.
 *

 * The intention of this value is to send all of the {@link Mesh}'s materials
 * into multiple shader uniforms and then reference the current one by this
 * vertex attribute.
 *

 * example glsl code:
 *
 *

 *  // this is bound using MATERIAL_INDEX
 *  attribute int materialIndex;
 *
 *  struct Material {
 *    vec3 diffuse;
 *    vec3 specular;
 *    vec3 specularExponent;
 *  };
 *
 *  uniform Material materials[MAX_MATERIALS];
 *
 *  // ...
 *
 *  vec3 diffuse = materials[materialIndex];
 *
 *

 * TODO: More description & test to make sure subscripting by attributes even
 * works for webgl
 *
 * @see {@link Layout}
 */
Layout.MATERIAL_INDEX = new Attribute('materialIndex', 1, 'UNSIGNED_SHORT');
Layout.MATERIAL_ENABLED = new Attribute('materialEnabled', 1, 'UNSIGNED_SHORT');
Layout.AMBIENT = new Attribute('ambient', 3, 'FLOAT');
Layout.DIFFUSE = new Attribute('diffuse', 3, 'FLOAT');
Layout.SPECULAR = new Attribute('specular', 3, 'FLOAT');
Layout.SPECULAR_EXPONENT = new Attribute('specularExponent', 3, 'FLOAT');
Layout.EMISSIVE = new Attribute('emissive', 3, 'FLOAT');
Layout.TRANSMISSION_FILTER = new Attribute('transmissionFilter', 3, 'FLOAT');
Layout.DISSOLVE = new Attribute('dissolve', 1, 'FLOAT');
Layout.ILLUMINATION = new Attribute('illumination', 1, 'UNSIGNED_SHORT');
Layout.REFRACTION_INDEX = new Attribute('refractionIndex', 1, 'FLOAT');
Layout.SHARPNESS = new Attribute('sharpness', 1, 'FLOAT');
Layout.MAP_DIFFUSE = new Attribute('mapDiffuse', 1, 'SHORT');
Layout.MAP_AMBIENT = new Attribute('mapAmbient', 1, 'SHORT');
Layout.MAP_SPECULAR = new Attribute('mapSpecular', 1, 'SHORT');
Layout.MAP_SPECULAR_EXPONENT = new Attribute('mapSpecularExponent', 1, 'SHORT');
Layout.MAP_DISSOLVE = new Attribute('mapDissolve', 1, 'SHORT');
Layout.ANTI_ALIASING = new Attribute('antiAliasing', 1, 'UNSIGNED_SHORT');
Layout.MAP_BUMP = new Attribute('mapBump', 1, 'SHORT');
Layout.MAP_DISPLACEMENT = new Attribute('mapDisplacement', 1, 'SHORT');
Layout.MAP_DECAL = new Attribute('mapDecal', 1, 'SHORT');
Layout.MAP_EMISSIVE = new Attribute('mapEmissive', 1, 'SHORT');
<commit_msg>Layout: Use const instead of let when able<commit_after>/**
 * A class to represent the memory layout for a vertex attribute array. Used by
 * {@link Mesh}'s TBD(...) method to generate a packed array from mesh data.
 *

 * Layout can sort of be thought of as a C-style struct declaration.
 * {@link Mesh}'s TBD(...) method will use the {@link Layout} instance to
 * pack an array in the given attribute order.
 *

 * Layout also is very helpful when calling a WebGL context's
 * vertexAttribPointer method. If you've created a buffer using
 * a Layout instance, then the same Layout instance can be used to determine
 * the size, type, normalized, stride, and offset parameters for
 * vertexAttribPointer.
 *

 * For example:
 *

 *
 * const index = glctx.getAttribLocation(shaderProgram, "pos");
 * glctx.vertexAttribPointer(
 *   layout.position.size,
 *   glctx[layout.position.type],
 *   layout.position.normalized,
 *   layout.position.stride,
 *   layout.position.offset);
 *

 * @see {@link Mesh}
 */
export class Layout {
    /**
     * Create a Layout object. This constructor will throw if any duplicate
     * attributes are given.
     * @param {Array} ...attributes - An ordered list of attributes that
     *        describe the desired memory layout for each vertex attribute.
     *

     *
     * @see {@link Mesh}
     */
    constructor(...attributes) {
        this.attributes = {};
        let offset = 0;
        for (const attribute of attributes) {
            if (this[attribute.key]) {
                throw new DuplicateAttributeException(attribute);
            }
            this[attribute.key] = {
                'attribute': attribute,
                'size': attribute.size,
                'type': attribute.type,
                'normalized': attribute.normalized,
                'offset': offset,
            };
            offset += attribute.sizeInBytes;
        }
        this.stride = offset;
        for (const attribute of attributes) {
            this[attribute.key].stride = this.stride;
        }
    }
}

/**
 * An exception for when two or more of the same attributes are found in the
 * same layout.
 * @private
 */
class DuplicateAttributeException {
    /**
     * Create a DuplicateAttributeException
     * @param {Attribute} attribute - The attribute that was found more than
     *        once in the {@link Layout}
     */
    constructor(attribute) {
        this.message = 'found duplicate attribute: ' + attribute.key;
    }
}

/**
 * Represents how a vertex attribute should be packed into an buffer.
 * @private
 */
class Attribute {
    /**
     * Create an attribute. Do not call this directly, use the predefined
     * constants.
     * @param {string} key - The name of this attribute as if it were a key in
     *        an Object. Use the camel case version of the upper snake case
     *        const name.
     * @param {number} size - The number of components per vertex attribute.
     *        Must be 1, 2, 3, or 4.
     * @param {string} type - The data type of each component for this
     *        attribute. Possible values:

     *        "BYTE": signed 8-bit integer, with values in [-128, 127]

     *        "SHORT": signed 16-bit integer, with values in
     *            [-32768, 32767]

     *        "UNSIGNED_BYTE": unsigned 8-bit integer, with values in
     *            [0, 255]

     *        "UNSIGNED_SHORT": unsigned 16-bit integer, with values in
     *            [0, 65535]

     *        "FLOAT": 32-bit floating point number
     * @param {boolean} normalized - Whether integer data values should be
     *        normalized when being casted to a float.

     *        If true, signed integers are normalized to [-1, 1].

     *        If true, unsigned integers are normalized to [0, 1].

     *        For type "FLOAT", this parameter has no effect.
     */
    constructor(key, size, type, normalized=false) {
        this.key = key;
        this.size = size;
        this.type = type;
        this.normalized = false;
        this.sizeInBytes = sizeInBytesOfType(type) * size;
    }
}

/**
 * @param {string} type - A type accepted by {@link Attribute}.
 * @return The size (in bytes) for a given type.
 * @see {@link Attribute}
 * @private
 */
function sizeInBytesOfType(type) {
    switch (type) {
        case 'BYTE':
        case 'UNSIGNED_BYTE':
            return 1;
        case 'SHORT':
        case 'UNSIGNED_SHORT':
            return 2;
        case 'FLOAT':
            return 4;
    }
}

// Geometry attributes
/**
 * Attribute layout to pack a vertex's x, y, & z as floats
 *
 * @see {@link Layout}
 */
Layout.POSITION = new Attribute('position', 3, 'FLOAT');

/**
 * Attribute layout to pack a vertex's normal's x, y, & z as floats
 *
 * @see {@link Layout}
 */
Layout.NORMAL = new Attribute('normal', 3, 'FLOAT');

/**
 * Attribute layout to pack a vertex's normal's x, y, & z as floats.
 *

 * This value will be computed on-the-fly based on the texture coordinates.
 * If no texture coordinates are available, the generated value will default to
 * 0, 0, 0.
 *
 * @see {@link Layout}
 */
Layout.TANGENT = new Attribute('tangent', 3, 'FLOAT');

/**
 * Attribute layout to pack a vertex's normal's bitangent x, y, & z as floats.
 *

 * This value will be computed on-the-fly based on the texture coordinates.
 * If no texture coordinates are available, the generated value will default to
 * 0, 0, 0.
 * @see {@link Layout}
 */
Layout.BITANGENT = new Attribute('bitangent', 3, 'FLOAT');

/**
 * Attribute layout to pack a vertex's texture coordinates' u & v as floats
 *
 * @see {@link Layout}
 */
Layout.UV = new Attribute('uv', 2, 'FLOAT');

// Material attributes

/**
 * Attribute layout to pack an unsigned short to be interpreted as a the index
 * into a {@link Mesh}'s materials list.
 *

 * The intention of this value is to send all of the {@link Mesh}'s materials
 * into multiple shader uniforms and then reference the current one by this
 * vertex attribute.
 *

 * example glsl code:
 *
 *

 *  // this is bound using MATERIAL_INDEX
 *  attribute int materialIndex;
 *
 *  struct Material {
 *    vec3 diffuse;
 *    vec3 specular;
 *    vec3 specularExponent;
 *  };
 *
 *  uniform Material materials[MAX_MATERIALS];
 *
 *  // ...
 *
 *  vec3 diffuse = materials[materialIndex];
 *
 *

 * TODO: More description & test to make sure subscripting by attributes even
 * works for webgl
 *
 * @see {@link Layout}
 */
Layout.MATERIAL_INDEX = new Attribute('materialIndex', 1, 'UNSIGNED_SHORT');
Layout.MATERIAL_ENABLED = new Attribute('materialEnabled', 1, 'UNSIGNED_SHORT');
Layout.AMBIENT = new Attribute('ambient', 3, 'FLOAT');
Layout.DIFFUSE = new Attribute('diffuse', 3, 'FLOAT');
Layout.SPECULAR = new Attribute('specular', 3, 'FLOAT');
Layout.SPECULAR_EXPONENT = new Attribute('specularExponent', 3, 'FLOAT');
Layout.EMISSIVE = new Attribute('emissive', 3, 'FLOAT');
Layout.TRANSMISSION_FILTER = new Attribute('transmissionFilter', 3, 'FLOAT');
Layout.DISSOLVE = new Attribute('dissolve', 1, 'FLOAT');
Layout.ILLUMINATION = new Attribute('illumination', 1, 'UNSIGNED_SHORT');
Layout.REFRACTION_INDEX = new Attribute('refractionIndex', 1, 'FLOAT');
Layout.SHARPNESS = new Attribute('sharpness', 1, 'FLOAT');
Layout.MAP_DIFFUSE = new Attribute('mapDiffuse', 1, 'SHORT');
Layout.MAP_AMBIENT = new Attribute('mapAmbient', 1, 'SHORT');
Layout.MAP_SPECULAR = new Attribute('mapSpecular', 1, 'SHORT');
Layout.MAP_SPECULAR_EXPONENT = new Attribute('mapSpecularExponent', 1, 'SHORT');
Layout.MAP_DISSOLVE = new Attribute('mapDissolve', 1, 'SHORT');
Layout.ANTI_ALIASING = new Attribute('antiAliasing', 1, 'UNSIGNED_SHORT');
Layout.MAP_BUMP = new Attribute('mapBump', 1, 'SHORT');
Layout.MAP_DISPLACEMENT = new Attribute('mapDisplacement', 1, 'SHORT');
Layout.MAP_DECAL = new Attribute('mapDecal', 1, 'SHORT');
Layout.MAP_EMISSIVE = new Attribute('mapEmissive', 1, 'SHORT');
<|endoftext|>


<commit_before>export default db => ({
    get: (key, defaultValue) => db.ref(key).once('value')
        .then(snapshot => snapshot.val() || defaultValue),
    set: (key, value = true) => db.ref(key).set(value),
    delete: (keys) => {
        const updates = {};
        keys.forEach(key => updates[key] = null);
        return db.ref().update(updates);
    },
});
<commit_msg>Removed a line in the database lib using a default value in the call.<commit_after>export default db => ({
    get: (key, defaultValue) => db.ref(key).once('value')
        .then(snapshot => snapshot.val() || defaultValue),
    set: (key, value = true) => db.ref(key).set(value),
    delete: (keys, updates = {}) => {
        keys.forEach(key => updates[key] = null);
        return db.ref().update(updates);
    },
});
<|endoftext|>


<commit_before>/**
 * Mailvelope - secure email with OpenPGP encryption for Webmail
 * Copyright (C) 2015 Mailvelope Authors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

'use strict';

var mvelo = mvelo || {};

mvelo.OptionsContainer = function(selector, keyringId) {
  this.selector = selector;
  this.keyringId = keyringId;
  this.id = mvelo.util.getHash();
  //this.name = 'decryptCont-' + this.id;
  //this.port = mvelo.extension.connect({name: this.name});
  //this.registerEventListener();
  this.parent = null;
  this.container = null;
  this.done = null;
};

mvelo.OptionsContainer.prototype.create = function(done) {
  this.done = done;
  this.parent = document.querySelector(this.selector);
  this.container = document.createElement('iframe');
  var url;
  if (mvelo.crx) {
    url = mvelo.extension.getURL('common/ui/options.html?krid=' + this.keyringId);
  } else if (mvelo.ffa) {
    url = 'about:blank?mvelo=options&krid=' + this.keyringId;
  }
  this.container.setAttribute('src', url);
  this.container.setAttribute('frameBorder', 0);
  this.container.setAttribute('style', 'width: 100%; height: 100%; overflow-x: none; overflow-y: auto');
  this.container.addEventListener('load', this.done.bind(this, null, this.id));
  this.parent.appendChild(this.container);
};
<commit_msg>encoding the keyring id<commit_after>/**
 * Mailvelope - secure email with OpenPGP encryption for Webmail
 * Copyright (C) 2015 Mailvelope Authors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

'use strict';

var mvelo = mvelo || {};

mvelo.OptionsContainer = function(selector, keyringId) {
  this.selector = selector;
  this.keyringId = keyringId;
  this.id = mvelo.util.getHash();
  //this.name = 'decryptCont-' + this.id;
  //this.port = mvelo.extension.connect({name: this.name});
  //this.registerEventListener();
  this.parent = null;
  this.container = null;
  this.done = null;
};

mvelo.OptionsContainer.prototype.create = function(done) {
  this.done = done;
  this.parent = document.querySelector(this.selector);
  this.container = document.createElement('iframe');
  var url;
  if (mvelo.crx) {
    url = mvelo.extension.getURL('common/ui/options.html?krid=' + encodeURIComponent(this.keyringId));
  } else if (mvelo.ffa) {
    url = 'about:blank?mvelo=options&krid=' + encodeURIComponent(this.keyringId);
  }
  this.container.setAttribute('src', url);
  this.container.setAttribute('frameBorder', 0);
  this.container.setAttribute('style', 'width: 100%; height: 100%; overflow-x: none; overflow-y: auto');
  this.container.addEventListener('load', this.done.bind(this, null, this.id));
  this.parent.appendChild(this.container);
};
<|endoftext|>


<commit_before>/**
 * Views to show a description and access to the role of the player.
 */
(function () {

  var Dom = require('dom');
  var Plugin = require('plugin');
  var Constants = require('Constants')();
  var Db = require('db');

  var GameTime = require('GameTime');
  var VotingViews = require('VotingViews');

  /**
   * Gives a description of a role.
   * @param name the name of the role
   * @param icon the name of the uri
   * @param content the content to display in the description as function using dom.
   */
  function description(name, icon, content) {
    // the main color theme to use
    var color = '#ba1a6e';

    Dom.div(function () {
      Dom.cls('role-description');
      Dom.style({
        border: '3px solid ' + color,
        display: 'block',
        padding: '1em',
        margin: '1em'
      });

      // the header
      Dom.div(function () {
        Dom.h3(function () {
          Dom.style({
            color: color
          });
          Dom.span(function () {
            Dom.img(function () {
              Dom.prop('src', Plugin.resourceUri(icon));
            });
          });
          Dom.text(name);
        });
      });

      // the content
      Dom.div(function () {
        content();
      });
    });
  }

  function werewolf() {
    var time = GameTime.startingOn(Db.shared.get('time', 'start'));

    description('Werewolf', 'wolf.png', function () {
      Dom.div(function () {
        Dom.p(
          'You are a werewolf. ' +
          'Together with the other werewolves you gather ' +
          'each night to kill one of the citizens.'
        );
        Dom.p(
          'You win when there are only werewolves left in the village.'
        );
      });

      // show the voting for werewolves
      VotingViews.werewolves(time);
    });
  }

  function citizen() {
    description('Citizen', 'citizen.png', function () {
      Dom.div(function () {
        Dom.p(
          'You are an innocent citizen.' +
          'You try to protect the village by revealing ' +
          'the werewolves and lynching them.'
        );
        Dom.p(
          'You win when all the werewolves are dead.'
        );
      });
    });
  }

  /**
   * Gives a description view of the given role.
   */
  function descriptionOf(role) {
    // get a description based on the role
    switch(role) {
      case Constants.roles.CITIZEN:
        citizen();
        break;
      case Constants.roles.WEREWOLF:
        werewolf();
        break;
    }
  }

  /**
   * A view giving a description and access to the given role.
   */
  exports.description = descriptionOf;

}());
<commit_msg>Rewrite RoleViews to no longer use GameTime<commit_after>/**
 * Views to show a description and access to the role of the player.
 */
(function () {

  var Dom = require('dom');
  var Plugin = require('plugin');
  var Constants = require('Constants')();
  var Db = require('db');

  var VotingViews = require('VotingViews');

  /**
   * Gives a description of a role.
   * @param name the name of the role
   * @param icon the name of the uri
   * @param content the content to display in the description as function using dom.
   */
  function description(name, icon, content) {
    // the main color theme to use
    var color = '#ba1a6e';

    Dom.div(function () {
      Dom.cls('role-description');
      Dom.style({
        border: '3px solid ' + color,
        display: 'block',
        padding: '1em',
        margin: '1em'
      });

      // the header
      Dom.div(function () {
        Dom.h3(function () {
          Dom.style({
            color: color
          });
          Dom.span(function () {
            Dom.img(function () {
              Dom.prop('src', Plugin.resourceUri(icon));
            });
          });
          Dom.text(name);
        });
      });

      // the content
      Dom.div(function () {
        content();
      });
    });
  }

  function werewolf(time) {

    description('Werewolf', 'wolf.png', function () {
      Dom.div(function () {
        Dom.p(
          'You are a werewolf. ' +
          'Together with the other werewolves you gather ' +
          'each night to kill one of the citizens.'
        );
        Dom.p(
          'You win when there are only werewolves left in the village.'
        );
      });

      // show the voting for werewolves
      VotingViews.werewolves(time);
    });
  }

  function citizen(time) {
    description('Citizen', 'citizen.png', function () {
      Dom.div(function () {
        Dom.p(
          'You are an innocent citizen.' +
          'You try to protect the village by revealing ' +
          'the werewolves and lynching them.'
        );
        Dom.p(
          'You win when all the werewolves are dead.'
        );
      });
    });
  }

  /**
   * Gives a description view of the given role.
   * @param time the current game time
   */
  function descriptionOf(role, time) {
    // get a description based on the role
    switch(role) {
      case Constants.roles.CITIZEN:
        citizen(time);
        break;
      case Constants.roles.WEREWOLF:
        werewolf(time);
        break;
    }
  }

  /**
   * A view giving a description and access to the given role.
   */
  exports.description = descriptionOf;

}());
<|endoftext|>


<commit_before>"use strict";

(function (window, $) {
  $('document').ready(function () {
    var main = $('#main');
    var magicLinks = $('.magic-links a, .widget_recent_entries');
    var milkyWay = $('.milky-way');
    var loader = $('.milky-way--holder');
    var isLoading = false;
    var stateObj = {};
    var pushState = window && window.history && window.history.pushState;

    main.first().fadeIn();

    function centerElement(el) {
      var $window = $(window);
      var top = $window.scrollTop() * 2;
      var left = $window.width() / 2;
      el.css({
        top: (top > 256 ? top : 256) + 'px',
        left: (left > 0 ? left : 0) + 'px'
      });
    }

    function reloadThings() {
      // Bind click
      if (pushState) {
        magicLinks.each(function () {
          var item = $(this),
            doc = $(document);
          item.off('click');
          item.on('click', function (event) {
            milkyWay.width(doc.width()).height(doc.height());
            var href = this.href;
            event.preventDefault();
            if (!isLoading) {
              var splitHref = href.split('/'),
                isTheLinkBeautiful = splitHref[splitHref.length - 1] === '',
                lastHrefPart = !isTheLinkBeautiful ? splitHref[splitHref.length - 1] : splitHref[splitHref.length - 2];
              if (lastHrefPart.search('#') === -1) {
                isLoading = true;
                loader.fadeIn();
                centerElement($('.loader'));
                window.history.pushState(stateObj, "", window.location.host !== lastHrefPart ? isTheLinkBeautiful ? '../' + lastHrefPart + '/' : lastHrefPart : '/');
                main.load(href + " #main", function () {
                  loader.fadeOut();
                  isLoading = false;
                  magicLinks = $('.magic-links a, .widget_recent_entries a');
                  main = $('#main');
                  reloadThings();
                });
              }
            }
          });
        });
      }
    }
    reloadThings();
  });

})(window, jQuery);<commit_msg>Fixes magic-loader problems.<commit_after>"use strict";

(function (document, window, $) {
  $(document).ready(function () {
    var main = $('#main');
    var magicLinks = $('.magic-links a, .widget_recent_entries');
    var milkyWay = $('.milky-way');
    var loader = $('.milky-way--holder');
    var isLoading = false;
    var stateObj = {};
    var pushState = window && window.history && window.history.pushState;

    main.first().fadeIn();

    function centerElement(el) {
      var $window = $(window);
      var top = $window.scrollTop() * 2;
      var left = $window.width() / 2;
      el.css({
        top: (top > 256 ? top : 256) + 'px',
        left: (left > 0 ? left : 0) + 'px'
      });
    }

    function getPushStateURL(splittedHref) {
      var link = document.location.toString().split('/');
      if (splittedHref[splittedHref.length - 1] === '') splittedHref.pop();
      if (link[link.length - 1] === '') link.pop();
      var generatedLink = '';
      for (var i = 0; i < link.length; i++) {
        if (splittedHref[i] !== link[i]) {
          generatedLink = generatedLink + '../';
        }
      }
      return generatedLink + (splittedHref[splittedHref.length - 1] === window.location.host ? '' : splittedHref[splittedHref.length - 1]);
    }

    function colorMenu() {
      var classes = 'current-menu-item current_page_item';
      $('.magic-links li').removeClass(classes);
      $('a[href="' + document.location + '/"]').addClass(classes);
    }

    function reloadThings() {
      // Bind click
      if (pushState) {
        magicLinks.each(function () {
          var item = $(this),
            doc = $(document);
          item.off('click');
          item.on('click', function (event) {
            milkyWay.width(doc.width()).height(doc.height());
            var href = this.href;
            event.preventDefault();
            if (!isLoading) {
              isLoading = true;
              loader.fadeIn();
              centerElement($('.loader'));
              window.history.pushState(stateObj, "", getPushStateURL(href.split('/')));
              main.load(href + " #main", function () {
                loader.fadeOut();
                isLoading = false;
                magicLinks = $('.magic-links a, .widget_recent_entries a');
                main = $('#main');
                reloadThings();
                colorMenu();
              });
            }
          });
        });
      }
    }
    reloadThings();
  });

})(document, window, jQuery);<|endoftext|>


<commit_before>var OperationManager = function(_options) {
    this.options = $.extend({
        prefix: "",
        operationKey: null,
        isLite: false,
        controllerUrl: null,
        validationControllerUrl: null,
        avoidValidation: false,
        onOk: null,
        onCancelled: null,
        onOperationSuccess: null,
        multiStep: false,
        navigateOnSuccess: false,
        closePopupOnSuccess: false,
        confirmMsg: null
    }, _options);
};

OperationManager.prototype = {

    runtimeInfo: function() {
        return RuntimeInfoFor(this.options.prefix);
    },

    pf: function(s) {
        return "#" + this.options.prefix + s;
    },

    newPrefix: function() {
        return this.options.prefix + "_New";
    },

    requestData: function(newPrefix) {
        log("OperationManager requestData");
        var formChildren = "";
        if (isFalse(this.options.isLite)) {
            if (empty(this.options.prefix)) //NormalWindow
                formChildren = $("form").serialize();
            else //PopupWindow
                formChildren = $(this.pf("panelPopup *") + ", #" + sfReactive + ", #" + sfTabId).serialize();
        }

        var info = this.runtimeInfo();

        formChildren += qp("isLite", this.options.isLite)
                     + qp("sfRuntimeType", info.runtimeType())
                     + qp("sfId", info.id())
                     + qp("sfOperationFullKey", this.options.operationKey)
                     + qp(sfPrefix, newPrefix)
                     + qp("sfOldPrefix", this.options.prefix)
                     + qp("sfOnOk", singleQuote(this.options.onOk));

        return formChildren;
    },

    entityIsValid: function() {
        log("OperationManager entityIsValid");
        var info = this.runtimeInfo();
        var isValid = null;
        if (empty(this.options.prefix))
            isValid = new Validator({ controllerUrl: this.options.validationControllerUrl }).validate();
        else
            isValid = new PartialValidator({ controllerUrl: this.options.validationControllerUrl, prefix: this.options.prefix, type: info.runtimeType(), id: info.id() }).validate().isValid;
        if (!isValid) {
            window.alert(lang['popupErrorsStop']);
            return false;
        }
        return true;
    },

    executedSuccessfully: function(operationResult) {
        log("OperationManager executedSuccessfully");
        if (operationResult.indexOf("ModelState") < 0)
            return true;

        eval('var result=' + operationResult);
        var modelState = result["ModelState"];
        if (empty(this.options.prefix))
            new Validator().showErrors(modelState);
        else {
            var info = this.runtimeInfo();
            new PartialValidator({ prefix: this.options.prefix, type: info.runtimeType(), id: info.id() }).showErrors(modelState);
        }
        return false;
    },

    post: function() {
        log("OperationManager post");
        if (!empty(this.options.confirmMsg) && !confirm(this.options.confirmMsg))
            return;

        NotifyInfo(lang['executingOperation']);

        if (!this.options.avoidValidation) {
            if (!this.entityIsValid())
                return;
        }

        var info = this.runtimeInfo();
        $("form").append(hiddenInput('sfRuntimeType', info.runtimeType()) +
            hiddenInput('sfId', info.id()) +
            hiddenInput('isLite', this.options.isLite) +
            hiddenInput('sfOperationFullKey', this.options.operationKey) +
            hiddenInput(sfPrefix, this.options.prefix));
        document.forms[0].action = this.options.controllerUrl;
        document.forms[0].submit();
    }
};

var OperationExecutor = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/OperationExecute"
    }, _options));

    this.execute = function() {
        log("OperationExecutor execute");
        if (!empty(this.options.confirmMsg) && !confirm(this.options.confirmMsg))
            return;

        NotifyInfo(lang['executingOperation']);

        if (!this.options.avoidValidation) {
            if (!this.entityIsValid()) {
                NotifyInfo(lang['error'], 2000);
                return;
            }
        }

        var newPrefix = (isFalse(this.options.multiStep)) ? this.options.prefix : this.newPrefix();
        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(newPrefix),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (!self.executedSuccessfully(operationResult)) {
                    NotifyInfo(lang['error'], 2000);
                    return;
                }

                if (self.options.navigateOnSuccess) {
                    PostServer(operationResult);
                    return;
                }

                if (self.options.multiStep) {
                    new ViewNavigator({
                        prefix: newPrefix,
                        containerDiv: newPrefix + "externalPopupDiv",
                        onOk: self.options.onOk,
                        onCancelled: self.options.onCancelled
                    }).viewSave(operationResult);
                    return;
                }

                if (empty(self.options.prefix)) //NormalWindow
                    $("#content").html(operationResult.substring(operationResult.indexOf("<form"), operationResult.indexOf("</form>") + 7));
                else { //PopupWindow
                    if (self.options.closePopupOnSuccess) {
                        $('#' + newPrefix + "externalPopupDiv").remove();
                    }
                    else {
                        new ViewNavigator({
                            prefix: newPrefix,
                            containerDiv: newPrefix + "externalPopupDiv",
                            onOk: self.options.onOk,
                            onCancelled: self.options.onCancelled
                        }).viewSave(operationResult);
                    }
                }

                if (!empty(self.options.onOperationSuccess))
                    self.options.onOperationSuccess();

                NotifyInfo(lang['operationExecuted'], 2000);
            },
            error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    };
};

OperationExecutor.prototype = new OperationManager();

function OperationExecute(executor, prefix) {
    if (!empty(prefix))
        executor.options = $.extend(executor.options, { prefix: prefix });
    executor.execute();
}

function OperationExecutePost(executor) {
    executor.post();
}

//ConstructorFrom options = OperationManager options + returnType
var ConstructorFrom = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/ConstructFromExecute",
        returnType: null
    }, _options));

    this.construct = function() {
        log("ConstructorFrom construct");

        if (!empty(this.options.confirmMsg) && !confirm(this.options.confirmMsg))
            return;

        NotifyInfo(lang['executingOperation']);

        if (!this.options.avoidValidation) {
            if (!this.entityIsValid()) {
                NotifyInfo(lang['error'], 2000);
                return;
            }
        }

        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(this.newPrefix()),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (!self.executedSuccessfully(operationResult)) {
                    NotifyInfo(lang['error'], 2000);
                    return;
                }

                if (self.options.navigateOnSuccess) {
                    PostServer(operationResult);
                    return;
                }

                var navigator = new ViewNavigator({
                    prefix: self.newPrefix(),
                    type: self.options.returnType,
                    onOk: self.options.onOk,
                    onCancelled: self.options.onCancelled
                }).showCreateSave(operationResult);
                //$(self.pf("divASustituir")).html(operationResult);
                //new popup().show(self.options.prefix + "divASustituir");
                //$('#' + self.options.prefix + sfBtnCancel).click(empty(self.options.onCancel) ? (function() { $('#' + self.options.prefix + "divASustituir").html(""); }) : self.options.onCancel);

                if (!empty(self.options.onOperationSuccess))
                    self.options.onOperationSuccess();

                NotifyInfo(lang['operationExecuted'], 2000);
            },
            error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    };
};

ConstructorFrom.prototype = new OperationManager();

function OperationConstructFrom(constructorFrom) {
    constructorFrom.construct();
}

function OperationConstructFromPost(constructorFrom) {
    constructorFrom.post();
}

var DeleteExecutor = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/DeleteExecute"
    }, _options));

    this.execute = function() {
        log("DeleteOperation delete");

        if (!empty(this.options.confirmMsg) && !confirm(this.options.confirmMsg))
            return;

        NotifyInfo(lang['executingOperation']);

        if (!this.options.avoidValidation) {
            if (!this.entityIsValid()) {
                NotifyInfo(lang['error'], 2000);
                return;
            }
        }

        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(this.newPrefix()),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (!self.executedSuccessfully(operationResult)) {
                    NotifyInfo(lang['error'], 2000);
                    return;
                }

                if (self.options.navigateOnSuccess) {
                    PostServer(operationResult);
                    return;
                }

                if (!empty(self.options.onOperationSuccess))
                    self.options.onOperationSuccess();

                NotifyInfo(lang['operationExecuted'], 2000);
            },
            error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    };
};

DeleteExecutor.prototype = new OperationManager();

function OperationDelete(deleteExecutor) {
    deleteExecutor.execute();
}

function ConstructFromManyExecute(urlController, typeName, operationKey, prefix, onOk, onCancel) {
    var ids = GetSelectedElements(prefix);
    if (ids == "") return;
    var newPrefix = prefix + "_New";
    var self = this;
    $.ajax({
        type: "POST",
        url: urlController,
        data: "sfIds=" + ids + qp("sfRuntimeType", typeName) + qp("sfOperationFullKey", operationKey) + qp(sfPrefix, newPrefix) + qp("sfOnOk", singleQuote(onOk)) + qp("sfOnCancel", singleQuote(onCancel)),
        async: false,
        dataType: "html",
        success: function(msg) {
            $('#' + prefix + "divASustituir").html(msg);
            new popup().show(prefix + "divASustituir");
            $('#' + newPrefix + sfBtnOk).click(onOk);
            $('#' + newPrefix + sfBtnCancel).click(function() { $('#' + prefix + "divASustituir").html(""); if (onCancel != null) onCancel(); });
        }
    });
}

function ReloadEntity(urlController, prefix, parentDiv) {
    $.ajax({
        type: "POST",
        url: urlController,
        data: $("form").serialize() + qp(sfPrefix, prefix),
        async: false,
        dataType: "html",
        success:
                   function(msg) {
                       if (!empty(parentDiv))
                           $('#' + parentDiv).html(msg);
                       else
                           $('#' + prefix + "divMainControl").html(msg);
                   }
    });
}

<commit_msg>(TFS CS 4673)<commit_after>var OperationManager = function(_options) {
    this.options = $.extend({
        prefix: "",
        operationKey: null,
        isLite: false,
        controllerUrl: null,
        validationControllerUrl: null,
        avoidValidation: false,
        onOk: null,
        onCancelled: null,
        onOperationSuccess: null,
        multiStep: false,
        navigateOnSuccess: false,
        closePopupOnSuccess: false,
        confirmMsg: null
    }, _options);
};

OperationManager.prototype = {

    runtimeInfo: function() {
        return RuntimeInfoFor(this.options.prefix);
    },

    pf: function(s) {
        return "#" + this.options.prefix + s;
    },

    newPrefix: function() {
        return this.options.prefix + "_New";
    },

    requestData: function(newPrefix) {
        log("OperationManager requestData");
        var formChildren = "";
        if (isFalse(this.options.isLite)) {
            if (empty(this.options.prefix)) //NormalWindow
                formChildren = $("form").serialize();
            else //PopupWindow
                formChildren = $(this.pf("panelPopup *") + ", #" + sfReactive + ", #" + sfTabId).serialize();
        }
        else {
            formChildren = qp(sfTabId, $('#' + sfTabId).val());
        }

        var info = this.runtimeInfo();

        formChildren += qp("isLite", this.options.isLite)
                     + qp("sfRuntimeType", info.runtimeType())
                     + qp("sfId", info.id())
                     + qp("sfOperationFullKey", this.options.operationKey)
                     + qp(sfPrefix, newPrefix)
                     + qp("sfOldPrefix", this.options.prefix)
                     + qp("sfOnOk", singleQuote(this.options.onOk));

        return formChildren;
    },

    entityIsValid: function() {
        log("OperationManager entityIsValid");
        var info = this.runtimeInfo();
        var isValid = null;
        if (empty(this.options.prefix))
            isValid = new Validator({ controllerUrl: this.options.validationControllerUrl }).validate();
        else
            isValid = new PartialValidator({ controllerUrl: this.options.validationControllerUrl, prefix: this.options.prefix, type: info.runtimeType(), id: info.id() }).validate().isValid;
        if (!isValid) {
            window.alert(lang['popupErrorsStop']);
            return false;
        }
        return true;
    },

    executedSuccessfully: function(operationResult) {
        log("OperationManager executedSuccessfully");
        if (operationResult.indexOf("ModelState") < 0)
            return true;

        eval('var result=' + operationResult);
        var modelState = result["ModelState"];
        if (empty(this.options.prefix))
            new Validator().showErrors(modelState);
        else {
            var info = this.runtimeInfo();
            new PartialValidator({ prefix: this.options.prefix, type: info.runtimeType(), id: info.id() }).showErrors(modelState);
        }
        return false;
    },

    post: function() {
        log("OperationManager post");
        if (!empty(this.options.confirmMsg) && !confirm(this.options.confirmMsg))
            return;

        NotifyInfo(lang['executingOperation']);

        if (!this.options.avoidValidation) {
            if (!this.entityIsValid())
                return;
        }

        var info = this.runtimeInfo();
        $("form").append(hiddenInput('sfRuntimeType', info.runtimeType()) +
            hiddenInput('sfId', info.id()) +
            hiddenInput('isLite', this.options.isLite) +
            hiddenInput('sfOperationFullKey', this.options.operationKey) +
            hiddenInput(sfPrefix, this.options.prefix));
        document.forms[0].action = this.options.controllerUrl;
        document.forms[0].submit();
    }
};

var OperationExecutor = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/OperationExecute"
    }, _options));

    this.execute = function() {
        log("OperationExecutor execute");
        if (!empty(this.options.confirmMsg) && !confirm(this.options.confirmMsg))
            return;

        NotifyInfo(lang['executingOperation']);

        if (!this.options.avoidValidation) {
            if (!this.entityIsValid()) {
                NotifyInfo(lang['error'], 2000);
                return;
            }
        }

        var newPrefix = (isFalse(this.options.multiStep)) ? this.options.prefix : this.newPrefix();
        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(newPrefix),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (!self.executedSuccessfully(operationResult)) {
                    NotifyInfo(lang['error'], 2000);
                    return;
                }

                if (self.options.navigateOnSuccess) {
                    PostServer(operationResult);
                    return;
                }

                if (self.options.multiStep) {
                    new ViewNavigator({
                        prefix: newPrefix,
                        containerDiv: newPrefix + "externalPopupDiv",
                        onOk: self.options.onOk,
                        onCancelled: self.options.onCancelled
                    }).viewSave(operationResult);
                    return;
                }

                if (empty(self.options.prefix)) //NormalWindow
                    $("#content").html(operationResult.substring(operationResult.indexOf("<form"), operationResult.indexOf("</form>") + 7));
                else { //PopupWindow
                    if (self.options.closePopupOnSuccess) {
                        $('#' + newPrefix + "externalPopupDiv").remove();
                    }
                    else {
                        new ViewNavigator({
                            prefix: newPrefix,
                            containerDiv: newPrefix + "externalPopupDiv",
                            onOk: self.options.onOk,
                            onCancelled: self.options.onCancelled
                        }).viewSave(operationResult);
                    }
                }

                if (!empty(self.options.onOperationSuccess))
                    self.options.onOperationSuccess();

                NotifyInfo(lang['operationExecuted'], 2000);
            },
            error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    };
};

OperationExecutor.prototype = new OperationManager();

function OperationExecute(executor, prefix) {
    if (!empty(prefix))
        executor.options = $.extend(executor.options, { prefix: prefix });
    executor.execute();
}

function OperationExecutePost(executor) {
    executor.post();
}

//ConstructorFrom options = OperationManager options + returnType
var ConstructorFrom = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/ConstructFromExecute",
        returnType: null
    }, _options));

    this.construct = function() {
        log("ConstructorFrom construct");

        if (!empty(this.options.confirmMsg) && !confirm(this.options.confirmMsg))
            return;

        NotifyInfo(lang['executingOperation']);

        if (!this.options.avoidValidation) {
            if (!this.entityIsValid()) {
                NotifyInfo(lang['error'], 2000);
                return;
            }
        }

        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(this.newPrefix()),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (!self.executedSuccessfully(operationResult)) {
                    NotifyInfo(lang['error'], 2000);
                    return;
                }

                if (self.options.navigateOnSuccess) {
                    PostServer(operationResult);
                    return;
                }

                var navigator = new ViewNavigator({
                    prefix: self.newPrefix(),
                    type: self.options.returnType,
                    onOk: self.options.onOk,
                    onCancelled: self.options.onCancelled
                }).showCreateSave(operationResult);
                //$(self.pf("divASustituir")).html(operationResult);
                //new popup().show(self.options.prefix + "divASustituir");
                //$('#' + self.options.prefix + sfBtnCancel).click(empty(self.options.onCancel) ? (function() { $('#' + self.options.prefix + "divASustituir").html(""); }) : self.options.onCancel);

                if (!empty(self.options.onOperationSuccess))
                    self.options.onOperationSuccess();

                NotifyInfo(lang['operationExecuted'], 2000);
            },
            error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    };
};

ConstructorFrom.prototype = new OperationManager();

function OperationConstructFrom(constructorFrom) {
    constructorFrom.construct();
}

function OperationConstructFromPost(constructorFrom) {
    constructorFrom.post();
}

var DeleteExecutor = function(_options) {
    OperationManager.call(this, $.extend({
        controllerUrl: "Operation/DeleteExecute"
    }, _options));

    this.execute = function() {
        log("DeleteOperation delete");

        if (!empty(this.options.confirmMsg) && !confirm(this.options.confirmMsg))
            return;

        NotifyInfo(lang['executingOperation']);

        if (!this.options.avoidValidation) {
            if (!this.entityIsValid()) {
                NotifyInfo(lang['error'], 2000);
                return;
            }
        }

        var self = this;
        $.ajax({
            type: "POST",
            url: this.options.controllerUrl,
            data: this.requestData(this.newPrefix()),
            async: false,
            dataType: "html",
            success: function(operationResult) {
                if (!self.executedSuccessfully(operationResult)) {
                    NotifyInfo(lang['error'], 2000);
                    return;
                }

                if (self.options.navigateOnSuccess) {
                    PostServer(operationResult);
                    return;
                }

                if (!empty(self.options.onOperationSuccess))
                    self.options.onOperationSuccess();

                NotifyInfo(lang['operationExecuted'], 2000);
            },
            error:
                function() { NotifyInfo(lang['error'], 2000); }
        });
    };
};

DeleteExecutor.prototype = new OperationManager();

function OperationDelete(deleteExecutor) {
    deleteExecutor.execute();
}

function ConstructFromManyExecute(urlController, typeName, operationKey, prefix, onOk, onCancel) {
    var ids = GetSelectedElements(prefix);
    if (ids == "") return;
    var newPrefix = prefix + "_New";
    var self = this;
    $.ajax({
        type: "POST",
        url: urlController,
        data: "sfIds=" + ids + qp("sfRuntimeType", typeName) + qp("sfOperationFullKey", operationKey) + qp(sfPrefix, newPrefix) + qp("sfOnOk", singleQuote(onOk)) + qp("sfOnCancel", singleQuote(onCancel)),
        async: false,
        dataType: "html",
        success: function(msg) {
            $('#' + prefix + "divASustituir").html(msg);
            new popup().show(prefix + "divASustituir");
            $('#' + newPrefix + sfBtnOk).click(onOk);
            $('#' + newPrefix + sfBtnCancel).click(function() { $('#' + prefix + "divASustituir").html(""); if (onCancel != null) onCancel(); });
        }
    });
}

function ReloadEntity(urlController, prefix, parentDiv) {
    $.ajax({
        type: "POST",
        url: urlController,
        data: $("form").serialize() + qp(sfPrefix, prefix),
        async: false,
        dataType: "html",
        success:
                   function(msg) {
                       if (!empty(parentDiv))
                           $('#' + parentDiv).html(msg);
                       else
                           $('#' + prefix + "divMainControl").html(msg);
                   }
    });
}

<|endoftext|>


<commit_before>/* @flow weak */

let printit = options => new Logger(options)
if (printit.console == null) { printit.console = global.console }

class Logger {
  options: Object

  constructor (options) {
    this.options = options
    if (this.options == null) { this.options = {} }
    if (this.options.date && (this.options.dateFormat == null)) {
      this.options.dateFormat = 'YYYY-MM-DD hh:mm:ss:S'
    }
  }

  colorify (text, color) {
    return `${color[0]}${text}${color[1]}`
  }

  stringify (text) {
    if (text instanceof Error && text.stack) {
      text = text.stack
    } else if (text instanceof Object) {
      text = JSON.stringify(text)
    }
    return text
  }

  getFileAndLine () {
    let stacklist = (new Error()).stack.split('\n').slice(4)
    let nodeReg = /at\s+(.*)\s+\((.*):(\d*):(\d*)\)/gi
    let browserReg = /at\s+()(.*):(\d*):(\d*)/gi

    let firstLineStack = stacklist[0]
    let fileAndLineInfos =
            nodeReg.exec(firstLineStack) || browserReg.exec(firstLineStack)

    let filePath = fileAndLineInfos[2].substr(process.cwd().length)
    let line = fileAndLineInfos[3]
    return `.${filePath}:${line} |`
  }

  format (level, texts) {
    if (process.env.DEBUG) { texts.unshift(this.getFileAndLine()) }

    var text = ((() => {
      let result = []
      for (text of Array.from(texts)) {
        result.push(this.stringify(text))
      }
      return result
    })()).join(' ')

    if (this.options.prefix != null) { text = `${this.options.prefix} | ${text}` }

    if (level) { text = `${level} - ${text}` }
    if (this.options.date) {
      const date = new Date()
      text = `[${date.toLocaleString()} ${date.getMilliseconds()}] ${text}`
    }
    return text
  }

  info (...texts) {
    if (process.env.DEBUG || (process.env.NODE_ENV !== 'test')) {
      return printit.console.info(this.format('info', texts))
    }
  }

  warn (...texts) {
    if (process.env.DEBUG || (process.env.NODE_ENV !== 'test')) {
      if (this.options.duplicateToStdout) {
        printit.console.info(this.format('warn', texts))
      }
      return printit.console.warn(this.format('warn', texts))
    }
  }

  error (...texts) {
    if (process.env.DEBUG || (process.env.NODE_ENV !== 'test')) {
      if (this.options.duplicateToStdout) {
        printit.console.info(this.format('error', texts))
      }
      return printit.console.error(this.format('error', texts))
    }
  }

  debug (...texts) {
    if (process.env.DEBUG) {
      return printit.console.info(this.format('debug', texts))
    }
  }

  raw (...texts) {
    return printit.console.log(...texts)
  }

  lineBreak (text) {
    return this.raw(Array(80).join('*'))
  }
}

export default printit
<commit_msg>logger: Add milliseconds padding<commit_after>/* @flow weak */

let printit = options => new Logger(options)
if (printit.console == null) { printit.console = global.console }

class Logger {
  options: Object

  constructor (options) {
    this.options = options
    if (this.options == null) { this.options = {} }
    if (this.options.date && (this.options.dateFormat == null)) {
      this.options.dateFormat = 'YYYY-MM-DD hh:mm:ss:S'
    }
  }

  colorify (text, color) {
    return `${color[0]}${text}${color[1]}`
  }

  stringify (text) {
    if (text instanceof Error && text.stack) {
      text = text.stack
    } else if (text instanceof Object) {
      text = JSON.stringify(text)
    }
    return text
  }

  getFileAndLine () {
    let stacklist = (new Error()).stack.split('\n').slice(4)
    let nodeReg = /at\s+(.*)\s+\((.*):(\d*):(\d*)\)/gi
    let browserReg = /at\s+()(.*):(\d*):(\d*)/gi

    let firstLineStack = stacklist[0]
    let fileAndLineInfos =
            nodeReg.exec(firstLineStack) || browserReg.exec(firstLineStack)

    let filePath = fileAndLineInfos[2].substr(process.cwd().length)
    let line = fileAndLineInfos[3]
    return `.${filePath}:${line} |`
  }

  format (level, texts) {
    if (process.env.DEBUG) { texts.unshift(this.getFileAndLine()) }

    var text = ((() => {
      let result = []
      for (text of Array.from(texts)) {
        result.push(this.stringify(text))
      }
      return result
    })()).join(' ')

    if (this.options.prefix != null) { text = `${this.options.prefix} | ${text}` }

    if (level) { text = `${level} - ${text}` }
    if (this.options.date) {
      const date = new Date()
      let ms = date.getMilliseconds().toString()
      ms = '000'.substring(0, 3 - ms.length) + ms
      text = `[${date.toLocaleString()} ${ms}] ${text}`
    }
    return text
  }

  info (...texts) {
    if (process.env.DEBUG || (process.env.NODE_ENV !== 'test')) {
      return printit.console.info(this.format('info', texts))
    }
  }

  warn (...texts) {
    if (process.env.DEBUG || (process.env.NODE_ENV !== 'test')) {
      if (this.options.duplicateToStdout) {
        printit.console.info(this.format('warn', texts))
      }
      return printit.console.warn(this.format('warn', texts))
    }
  }

  error (...texts) {
    if (process.env.DEBUG || (process.env.NODE_ENV !== 'test')) {
      if (this.options.duplicateToStdout) {
        printit.console.info(this.format('error', texts))
      }
      return printit.console.error(this.format('error', texts))
    }
  }

  debug (...texts) {
    if (process.env.DEBUG) {
      return printit.console.info(this.format('debug', texts))
    }
  }

  raw (...texts) {
    return printit.console.log(...texts)
  }

  lineBreak (text) {
    return this.raw(Array(80).join('*'))
  }
}

export default printit
<|endoftext|>


<commit_before>'use strict';

require('colors');

const LEVELS = {
  DEBUG: 0,
  INFO: 1,
  WARN: 2,
  ERROR: 3
};

class Logger {
  constructor(level, tags) {
    this.level = (level === undefined || level === null) ? LEVELS.INFO : level;
    this.tags = tags || [];
  }

  error(message) {
    this.log('error', message);
  }

  warn(message) {
    this.log('warn', message);
  }

  debug(message) {
    this.log('debug', message);
  }

  info(message) {
    this.log('info', message);
  }

  log() {
    const args = Array.prototype.slice.call(arguments);
    if (args.length === 0) {
      return;
    }
    const level = args[0];
    let message = args.slice(1).join(' ');

    if (!message) {
      return;
    }

    switch (level) {
      case 'error':
        if (LEVELS.ERROR < this.level) return;
        break;
      case 'warn':
        if (LEVELS.WARN < this.level) return;
        break;
      case 'debug':
        if (LEVELS.DEBUG < this.level) return;
        break;
      default:
        if (LEVELS.INFO < this.level) return;
        break;
    }

    if (this.tags.length > 0) {
      message = `[${this.tags.join(',')}] ${message}`;
    }
    message = `${new Date().toISOString()} [${level}] ${message}`;

    switch (level) {
      case 'error':
        console.error(message.red);
        break;
      case 'warn':
        console.error(message.yellow);
        break;
      case 'debug':
        console.log(message.cyan);
        break;
      default:
        console.log(message);
        break;
    }
  }
}

module.exports = {
  Logger: Logger,
  logLevels: LEVELS
};
<commit_msg>Remove timestamp from logs<commit_after>'use strict';

require('colors');

const LEVELS = {
  DEBUG: 0,
  INFO: 1,
  WARN: 2,
  ERROR: 3
};

class Logger {
  constructor(level, tags) {
    this.level = (level === undefined || level === null) ? LEVELS.INFO : level;
    this.tags = tags || [];
  }

  error(message) {
    this.log('error', message);
  }

  warn(message) {
    this.log('warn', message);
  }

  debug(message) {
    this.log('debug', message);
  }

  info(message) {
    this.log('info', message);
  }

  log() {
    const args = Array.prototype.slice.call(arguments);
    if (args.length === 0) {
      return;
    }
    const level = args[0];
    let message = args.slice(1).join(' ');

    if (!message) {
      return;
    }

    switch (level) {
      case 'error':
        if (LEVELS.ERROR < this.level) return;
        break;
      case 'warn':
        if (LEVELS.WARN < this.level) return;
        break;
      case 'debug':
        if (LEVELS.DEBUG < this.level) return;
        break;
      default:
        if (LEVELS.INFO < this.level) return;
        break;
    }

    if (this.tags.length > 0) {
      message = `[${this.tags.join(',')}] ${message}`;
    }
    message = `[${level}] ${message}`;

    switch (level) {
      case 'error':
        console.error(message.red);
        break;
      case 'warn':
        console.error(message.yellow);
        break;
      case 'debug':
        console.log(message.cyan);
        break;
      default:
        console.log(message);
        break;
    }
  }
}

module.exports = {
  Logger: Logger,
  logLevels: LEVELS
};
<|endoftext|>


<commit_before>
var cl = console;
function disableConsole( disabled ) {
	if ( disabled ) {
		var stub = {}, methods = [ 'log', 'warn', 'error', 'info' ];
		for ( var i = 0; i < methods.length; i++ )
			stub[ methods[ i ] ] = function() {};
		console = stub;
	} else {
		console = cl;
	}
}

var tweenConstructors 	= [ 'set', 'from', 'to', 'fromTo' ];
var tweenkeyMethods 	= [ 'autoUpdate', 'update', 'pauseAll', 'killAll', 'resumeAll' ];
var tweenMethods 		= [ 'pause', 'resume', 'kill', 'delay' ];

Tweenkey.autoUpdate( false );

describe( 'tweenkey', function() {

	describe( 'Tweenkey definition', function() {

		it( 'Should be defined', function() {
			expect( Tweenkey ).not.to.be.undefined;
			expect( Tweenkey ).not.to.be.null;
		});

		it( 'Should respond to [set, from, to, fromTo] methods', function() {
			tweenConstructors.forEach(function( name ) {
				expect( Tweenkey ).to.respondTo( name );
			});
		});

		it( 'Should respond to [update, killAll, pauseAll, resumeAll] methods', function() {
			tweenkeyMethods.forEach(function( name ) {
				expect( Tweenkey ).to.respondTo( name );
			});
		});

	});

	describe( 'Tween constructors', function() {

		it( 'Should validate empty params', function() {
			disableConsole( true );
			tweenConstructors.forEach(function( name ) {
				expect( Tweenkey[ name ]() )
				.to.have.property( '_defined' ).and.equal( false );
			});
			disableConsole( false );
		});

		it( 'Should validate wrong target types', function() {
			disableConsole( true );
			tweenConstructors.forEach(function( name ) {
				[ 1, null, true, function() {}, undefined ].forEach(function( val ) {
					expect( Tweenkey[ name ]( val ) )
					.to.have.property( '_defined' ).and.equal( false );
				});
			});
			disableConsole( false );
		});

		it( 'Should validate additional params', function() {

			disableConsole( true );

			tweenConstructors.forEach(function( name ) {
				[ [], null, true, function() {}, undefined ].forEach(function( val ) {
					expect( Tweenkey[ name ]( val ) )
					.to.have.property( '_defined' ).and.equal( false );
				});
			});
			Tweenkey.killAll();

			disableConsole( false );
		});

	});

	describe( 'Tween definitions', function() {

		var basicParams = {
			set: 	[ { x: 0 }, { x: 1 } ],
			to: 	[ { x: 0 }, 1, { x: 1 } ],
			from: 	[ { x: 1 }, 1, { x: 1 } ],
			fromTo: [ { x: 0 }, 1, { x: 1 }, { x: 2 } ]
		};

		it( 'Should respond to [pause, resume, kill, delay] methods', function() {

			tweenConstructors.forEach(function( cName ) {
				var t = Tweenkey[ cName ].apply( null, basicParams[ cName ] );
				tweenMethods.forEach(function( mName ) {
					expect( t ).to.respondTo( mName );
				});
			});

		});
	});

	//chaining

	describe( 'Tween callbacks', function() {

		var invalidCallbacks = [ true, false, 1, 0, [], {}, undefined ];

		it( 'set: should work with the wrong callback parameters', function() {
			invalidCallbacks.forEach(function( val ) {

				var tween = Tweenkey.set({ x: 0 }, {
					x : 1,
					onComplete: val,
					onUpdate: val,
					onStart: val
				});

				Tweenkey.update( 1 );
				expect( tween ).to.respondTo( '_onComplete' );
				expect( tween ).to.respondTo( '_onStart' );
				expect( tween ).to.respondTo( '_onUpdate' );
				expect( tween._target ).to.have.property( 'x' ).and.equal( 1 );
			});
		});

		it( 'set: execute the [onComplete, onUpdate] callbacks when all properties are setted', function( done ) {
			var obj = { x: 0 };
			Tweenkey.set( obj, { x: 1,
				onUpdate: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
				},
				onComplete: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
					done();
				}
			});
			Tweenkey.update();
		});

		it( 'set: execute the onStart callback with all properties untouched', function( done ) {
			var obj = { x: 0 };
			Tweenkey.set( obj, { x: 1,
				onStart: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
					done();
				}
			});
			Tweenkey.update();
		});

		it( 'to: should work with the wrong callback parameters', function() {
			invalidCallbacks.forEach(function( val ) {

				var tween = Tweenkey.to({ x: 0 }, 1, {
					x : 1,
					onComplete: val,
					onUpdate: val,
					onStart: val
				});
				Tweenkey.update( 1 );

				expect( tween ).to.respondTo( '_onComplete' );
				expect( tween ).to.respondTo( '_onStart' );
				expect( tween ).to.respondTo( '_onUpdate' );
				expect( tween._target ).to.have.property( 'x' ).and.equal( 1 );
			});
		});

		it( 'to: execute the [onComplete, onUpdate] callbacks', function( done ) {
			var obj = { x: 0 };
			Tweenkey.to( obj, 1, { x: 1,
				onUpdate: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
				},
				onComplete: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

		it( 'to: should execute onStart callback with all properties untouched', function( done ) {
			var obj = { x: 0 };
			Tweenkey.to( obj, 1, { x: 1,
				onStart: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

		it( 'from: should work with the wrong callback parameters', function() {
			invalidCallbacks.forEach(function( val ) {

				var tween = Tweenkey.from({ x: 0 }, 1, {
					x : 1,
					onComplete: val,
					onUpdate: val,
					onStart: val
				});
				Tweenkey.update( 1 );

				expect( tween ).to.respondTo( '_onComplete' );
				expect( tween ).to.respondTo( '_onStart' );
				expect( tween ).to.respondTo( '_onUpdate' );
				expect( tween._target ).to.have.property( 'x' ).and.equal( 0 );
			});
		});

		it( 'from: execute the [onComplete, onUpdate] callbacks', function( done ) {
			var obj = { x: 0 };
			Tweenkey.from( obj, 1, { x: 1,
				onUpdate: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
				},
				onComplete: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

		it( 'from: should execute onStart callback with all properties untouched', function( done ) {
			var obj = { x: 0 };
			Tweenkey.to( obj, 1, { x: 1,
				onStart: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

		it( 'fromTo: should work with the wrong callback parameters', function() {
			invalidCallbacks.forEach(function( val ) {

				var tween = Tweenkey.fromTo({ x: 0 }, 1, {
					x: 1
				}, {
					x : 2,
					onComplete: val,
					onUpdate: val,
					onStart: val
				});
				Tweenkey.update( 1 );

				expect( tween ).to.respondTo( '_onComplete' );
				expect( tween ).to.respondTo( '_onStart' );
				expect( tween ).to.respondTo( '_onUpdate' );
				expect( tween._target ).to.have.property( 'x' ).and.equal( 2 );
			});
		});

		it( 'fromTo: execute the [onComplete, onUpdate] callbacks', function( done ) {
			var obj = { x: 0 };
			Tweenkey.fromTo( obj, 1, {
				x: 2
			}, {
				x: 1,
				onUpdate: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
				},
				onComplete: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

		it( 'fromTo: should execute onStart callback with all properties untouched', function( done ) {
			var obj = { x: 0 };
			Tweenkey.fromTo( obj, 1, { x: 2 }, { x: 1,
				onStart: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

	});

	describe( 'Tween linear interpolation', function() {

		it( 'to: should interpolate linear properties by default', function() {
			var obj = { x: 0 };
			Tweenkey.to( obj, 1, { x: 1 });
			for ( var i = 0; i < 10; i++ ) {
				var expectedVal = i * 0.1;
				// add tolerance to match property decimals between a range
				expect( obj ).to.have.property( 'x' ).and.to.be.within( expectedVal - 0.0001,  expectedVal + 0.0001 );
				Tweenkey.update( 0.1 );
			}
		});

		it( 'from: should interpolate linear properties by default', function() {
			var obj = { x: 1 };
			Tweenkey.from( obj, 1, { x: 0 });

			// will trigger the update to start with the current object property x setted to 0
			// this behaviour is inteded, user can change this with inmediate render param ?
			Tweenkey.update( 0.000001 );

			for ( var i = 0; i < 10; i++ ) {
				var expectedVal = i * 0.1;
				expect( obj ).to.have.property( 'x' ).and.to.be.within( expectedVal - 0.0001,  expectedVal + 0.0001 );
				Tweenkey.update( 0.1 );
			}
		});

		it( 'fromTo: should interpolate linear properties by default', function() {
			var obj = { x: 0 };
			Tweenkey.fromTo( obj, 1, { x: 0 }, { x: 1 });
			for ( var i = 0; i < 10; i++ ) {
				var expectedVal = i * 0.1;
				expect( obj ).to.have.property( 'x' ).and.to.be.within( expectedVal - 0.0001,  expectedVal + 0.0001 );
				Tweenkey.update( 0.1 );
			}
		});
	});

	describe( 'Tween pause, resume and kill', function() {
		it( 'set: should pause and resume', function() {
			var obj = { x: 0 };

			var tween = Tweenkey.set( obj, { x:1 }).pause();
			Tweenkey.update( 1 );
			expect( obj ).to.have.property( 'x' ).and.equal( 0 );
			tween.resume();
			Tweenkey.update();
			expect( obj ).to.have.property( 'x' ).and.equal( 1 );
		});

		it( 'set: should kill its properties', function() {
			var obj = { x: 0 };

			var tween = Tweenkey.set( obj, { x:1 }).kill();
			Tweenkey.update( 1 );
			expect( obj ).to.have.property( 'x' ).and.equal( 0 );
		});

		it( 'set: should kill specific properties', function() {
			var obj = { x: 0, y: 0 };

			var tween = Tweenkey.set( obj, { x:1, y: 1 }).kill('y');
			Tweenkey.update( 1 );
			expect( obj ).to.have.property( 'x' ).and.equal( 1 );
			expect( obj ).to.have.property( 'y' ).and.equal( 0 );
		});

	});
});
<commit_msg>test(tween): 3 cases for tween overriding and working with properties of the same object.<commit_after>
var cl = console;
function disableConsole( disabled ) {
	if ( disabled ) {
		var stub = {}, methods = [ 'log', 'warn', 'error', 'info' ];
		for ( var i = 0; i < methods.length; i++ )
			stub[ methods[ i ] ] = function() {};
		console = stub;
	} else {
		console = cl;
	}
}

var tweenConstructors 	= [ 'set', 'from', 'to', 'fromTo' ];
var tweenkeyMethods 	= [ 'autoUpdate', 'update', 'pauseAll', 'killAll', 'resumeAll' ];
var tweenMethods 		= [ 'pause', 'resume', 'kill', 'delay' ];

Tweenkey.autoUpdate( false );

describe( 'tweenkey', function() {

	describe( 'Tweenkey definition', function() {

		it( 'Should be defined', function() {
			expect( Tweenkey ).not.to.be.undefined;
			expect( Tweenkey ).not.to.be.null;
		});

		it( 'Should respond to [set, from, to, fromTo] methods', function() {
			tweenConstructors.forEach(function( name ) {
				expect( Tweenkey ).to.respondTo( name );
			});
		});

		it( 'Should respond to [update, killAll, pauseAll, resumeAll] methods', function() {
			tweenkeyMethods.forEach(function( name ) {
				expect( Tweenkey ).to.respondTo( name );
			});
		});

	});

	describe( 'Tween constructors', function() {

		it( 'Should validate empty params', function() {
			disableConsole( true );
			tweenConstructors.forEach(function( name ) {
				expect( Tweenkey[ name ]() )
				.to.have.property( '_defined' ).and.equal( false );
			});
			disableConsole( false );
		});

		it( 'Should validate wrong target types', function() {
			disableConsole( true );
			tweenConstructors.forEach(function( name ) {
				[ 1, null, true, function() {}, undefined ].forEach(function( val ) {
					expect( Tweenkey[ name ]( val ) )
					.to.have.property( '_defined' ).and.equal( false );
				});
			});
			disableConsole( false );
		});

		it( 'Should validate additional params', function() {

			disableConsole( true );

			tweenConstructors.forEach(function( name ) {
				[ [], null, true, function() {}, undefined ].forEach(function( val ) {
					expect( Tweenkey[ name ]( val ) )
					.to.have.property( '_defined' ).and.equal( false );
				});
			});
			Tweenkey.killAll();

			disableConsole( false );
		});

	});

	describe( 'Tween definitions', function() {

		var basicParams = {
			set: 	[ { x: 0 }, { x: 1 } ],
			to: 	[ { x: 0 }, 1, { x: 1 } ],
			from: 	[ { x: 1 }, 1, { x: 1 } ],
			fromTo: [ { x: 0 }, 1, { x: 1 }, { x: 2 } ]
		};

		it( 'Should respond to [pause, resume, kill, delay] methods', function() {

			tweenConstructors.forEach(function( cName ) {
				var t = Tweenkey[ cName ].apply( null, basicParams[ cName ] );
				tweenMethods.forEach(function( mName ) {
					expect( t ).to.respondTo( mName );
				});
			});

		});
	});

	//chaining

	describe( 'Tween callbacks', function() {

		var invalidCallbacks = [ true, false, 1, 0, [], {}, undefined ];

		it( 'set: should work with the wrong callback parameters', function() {
			invalidCallbacks.forEach(function( val ) {

				var tween = Tweenkey.set({ x: 0 }, {
					x : 1,
					onComplete: val,
					onUpdate: val,
					onStart: val
				});

				Tweenkey.update( 1 );
				expect( tween ).to.respondTo( '_onComplete' );
				expect( tween ).to.respondTo( '_onStart' );
				expect( tween ).to.respondTo( '_onUpdate' );
				expect( tween._target ).to.have.property( 'x' ).and.equal( 1 );
			});
		});

		it( 'set: execute the [onComplete, onUpdate] callbacks when all properties are setted', function( done ) {
			var obj = { x: 0 };
			Tweenkey.set( obj, { x: 1,
				onUpdate: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
				},
				onComplete: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
					done();
				}
			});
			Tweenkey.update();
		});

		it( 'set: execute the onStart callback with all properties untouched', function( done ) {
			var obj = { x: 0 };
			Tweenkey.set( obj, { x: 1,
				onStart: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
					done();
				}
			});
			Tweenkey.update();
		});

		it( 'to: should work with the wrong callback parameters', function() {
			invalidCallbacks.forEach(function( val ) {

				var tween = Tweenkey.to({ x: 0 }, 1, {
					x : 1,
					onComplete: val,
					onUpdate: val,
					onStart: val
				});
				Tweenkey.update( 1 );

				expect( tween ).to.respondTo( '_onComplete' );
				expect( tween ).to.respondTo( '_onStart' );
				expect( tween ).to.respondTo( '_onUpdate' );
				expect( tween._target ).to.have.property( 'x' ).and.equal( 1 );
			});
		});

		it( 'to: execute the [onComplete, onUpdate] callbacks', function( done ) {
			var obj = { x: 0 };
			Tweenkey.to( obj, 1, { x: 1,
				onUpdate: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
				},
				onComplete: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

		it( 'to: should execute onStart callback with all properties untouched', function( done ) {
			var obj = { x: 0 };
			Tweenkey.to( obj, 1, { x: 1,
				onStart: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

		it( 'from: should work with the wrong callback parameters', function() {
			invalidCallbacks.forEach(function( val ) {

				var tween = Tweenkey.from({ x: 0 }, 1, {
					x : 1,
					onComplete: val,
					onUpdate: val,
					onStart: val
				});
				Tweenkey.update( 1 );

				expect( tween ).to.respondTo( '_onComplete' );
				expect( tween ).to.respondTo( '_onStart' );
				expect( tween ).to.respondTo( '_onUpdate' );
				expect( tween._target ).to.have.property( 'x' ).and.equal( 0 );
			});
		});

		it( 'from: execute the [onComplete, onUpdate] callbacks', function( done ) {
			var obj = { x: 0 };
			Tweenkey.from( obj, 1, { x: 1,
				onUpdate: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
				},
				onComplete: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

		it( 'from: should execute onStart callback with all properties untouched', function( done ) {
			var obj = { x: 0 };
			Tweenkey.to( obj, 1, { x: 1,
				onStart: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

		it( 'fromTo: should work with the wrong callback parameters', function() {
			invalidCallbacks.forEach(function( val ) {

				var tween = Tweenkey.fromTo({ x: 0 }, 1, {
					x: 1
				}, {
					x : 2,
					onComplete: val,
					onUpdate: val,
					onStart: val
				});
				Tweenkey.update( 1 );

				expect( tween ).to.respondTo( '_onComplete' );
				expect( tween ).to.respondTo( '_onStart' );
				expect( tween ).to.respondTo( '_onUpdate' );
				expect( tween._target ).to.have.property( 'x' ).and.equal( 2 );
			});
		});

		it( 'fromTo: execute the [onComplete, onUpdate] callbacks', function( done ) {
			var obj = { x: 0 };
			Tweenkey.fromTo( obj, 1, {
				x: 2
			}, {
				x: 1,
				onUpdate: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
				},
				onComplete: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 1 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

		it( 'fromTo: should execute onStart callback with all properties untouched', function( done ) {
			var obj = { x: 0 };
			Tweenkey.fromTo( obj, 1, { x: 2 }, { x: 1,
				onStart: function( target ) {
					expect( obj ).to.have.property( 'x' ).and.equal( 0 );
					done();
				}
			});
			Tweenkey.update( 1 );
		});

	});

	describe( 'Tween linear interpolation', function() {

		it( 'to: should interpolate linear properties by default', function() {
			var obj = { x: 0 };
			Tweenkey.to( obj, 1, { x: 1 });
			for ( var i = 0; i < 10; i++ ) {
				var expectedVal = i * 0.1;
				// add tolerance to match property decimals between a range
				expect( obj ).to.have.property( 'x' ).and.to.be.within( expectedVal - 0.0001,  expectedVal + 0.0001 );
				Tweenkey.update( 0.1 );
			}
		});

		it( 'from: should interpolate linear properties by default', function() {
			var obj = { x: 1 };
			Tweenkey.from( obj, 1, { x: 0 });

			// will trigger the update to start with the current object property x setted to 0
			// this behaviour is inteded, user can change this with inmediate render param ?
			Tweenkey.update( 0.000001 );

			for ( var i = 0; i < 10; i++ ) {
				var expectedVal = i * 0.1;
				expect( obj ).to.have.property( 'x' ).and.to.be.within( expectedVal - 0.0001,  expectedVal + 0.0001 );
				Tweenkey.update( 0.1 );
			}
		});

		it( 'fromTo: should interpolate linear properties by default', function() {
			var obj = { x: 0 };
			Tweenkey.fromTo( obj, 1, { x: 0 }, { x: 1 });
			for ( var i = 0; i < 10; i++ ) {
				var expectedVal = i * 0.1;
				expect( obj ).to.have.property( 'x' ).and.to.be.within( expectedVal - 0.0001,  expectedVal + 0.0001 );
				Tweenkey.update( 0.1 );
			}
		});
	});

	describe( 'Tween multiple active tweens on single object', function() {

		it( '[set, to, from, fromTo]: should be able to modify different properties on same object', function() {
			var obj = { x: 0, y: 0, z: 3, w: 0 };

			Tweenkey.set( obj, { x: 1 });
			Tweenkey.to( obj, 1, { y: 2 });
			Tweenkey.from( obj, 1, { z: 0 });
			Tweenkey.fromTo(obj, 1, { w: 0 }, { w: 4 });
			Tweenkey.update(1);

			expect( obj ).to.have.property( 'x' ).and.equal( 1 );
			expect( obj ).to.have.property( 'y' ).and.equal( 2 );
			expect( obj ).to.have.property( 'z' ).and.equal( 3 );
			expect( obj ).to.have.property( 'w' ).and.equal( 4 );
		});

		it( '[set, to, from, fromTo]: should override same properties on same object', function() {
			var obj = { x: 0, y: 2, z: 0, w: 0 };

			Tweenkey.set( obj, { x: 0.1, y: 0.2, z: 0.3, w: 0.4 });
			Tweenkey.to( obj, 1, { x: 1 });
			Tweenkey.from( obj, 1, { y: 0 });
			Tweenkey.fromTo( obj, 1, { z: 1 }, { z: 3 });
			Tweenkey.update(1);

			// w should be untouched
			expect( obj ).to.have.property( 'w' ).and.equal( 0.4 );
			// x overrided by to
			expect( obj ).to.have.property( 'x' ).and.equal( 1 );
			// y overrided by from
			expect( obj ).to.have.property( 'y' ).and.equal( 2 );
			// z overrided by fromTo
			expect( obj ).to.have.property( 'z' ).and.equal( 3 );
		});

		it( '[set, to, from, fromTo]: should no override properties on delay', function() {
			var obj = { x: 0, y: 2, z: 0, w: 0 };

			Tweenkey.set( obj, { x: 0.1, y: 0.2, z: 0.3, w: 0.4 });
			Tweenkey.to( obj, 1, { x: 1, delay: 1 });
			Tweenkey.from( obj, 1, { y: 0, delay: 1 });
			Tweenkey.fromTo( obj, 1, { z: 1 }, { z: 3, delay: 1});
			Tweenkey.update(0.5);

			// x, y and z should not override set (delay is retaining)
			chai.assert.closeTo(obj.x, 0.1, 0.0001, 'x should not override');
			chai.assert.closeTo(obj.y, 0.2, 0.0001, 'y should not override');
			chai.assert.closeTo(obj.z, 0.3, 0.0001, 'z should not override');
		});
	});

	describe( 'Tween pause, resume and kill', function() {
		it( 'set: should pause and resume', function() {
			var obj = { x: 0 };

			var tween = Tweenkey.set( obj, { x:1 }).pause();
			Tweenkey.update( 1 );
			expect( obj ).to.have.property( 'x' ).and.equal( 0 );
			tween.resume();
			Tweenkey.update();
			expect( obj ).to.have.property( 'x' ).and.equal( 1 );
		});

		it( 'set: should kill all its properties', function() {
			var obj = { x: 0 };

			var tween = Tweenkey.set( obj, { x:1 }).kill();
			Tweenkey.update( 1 );
			expect( obj ).to.have.property( 'x' ).and.equal( 0 );
		});

		it( 'set: should kill specific properties', function() {
			var obj = { x: 0, y: 0 };

			var tween = Tweenkey.set( obj, { x:1, y: 1 }).kill('y');
			Tweenkey.update( 1 );
			expect( obj ).to.have.property( 'x' ).and.equal( 1 );
			expect( obj ).to.have.property( 'y' ).and.equal( 0 );
		});
	});
});
<|endoftext|>