<commit_before>module.exports = (function($)
{
    var $form;

    return {
        validate         : _validate,
        getInvalidFields : _getInvalidFields,
        markInvalidFields: _markInvalidFields,
        unmarkAllFields  : _unmarkAllFields
    };

    function _validate(form)
    {
        var deferred      = $.Deferred();
        var invalidFields = _getInvalidFields(form);

        if (invalidFields.length > 0)
        {
            deferred.rejectWith(form, [invalidFields]);
        }
        else
        {
            deferred.resolveWith(form);
        }

        return deferred;
    }

    function _getInvalidFields(form)
    {
        $form = $(form);
        var invalidFormControls = [];

        $form.find("[data-validate]").each(function(i, elem)
        {

            if (!_validateElement($(elem)))
            {
                invalidFormControls.push(elem);
            }
        });

        return invalidFormControls;
    }

    function _markInvalidFields(fields, errorClass)
    {
        errorClass = errorClass || "has-error";

        $(fields).each(function(i, elem)
        {
            var $elem = $(elem);

            $elem.addClass(errorClass);
            _findFormControls($elem).on("click.removeErrorClass keyup.removeErrorClass change.removeErrorClass", function()
            {
                if (_validateElement($elem))
                {
                    $elem.removeClass(errorClass);
                    if ($elem.is("[type=\"radio\"], [type=\"checkbox\"]"))
                    {
                        var groupName = $elem.attr("name");

                        $("." + errorClass + "[name=\"" + groupName + "\"]").removeClass(errorClass);
                    }
                    _findFormControls($elem).off("click.removeErrorClass keyup.removeErrorClass change.removeErrorClass");
                }
            });
        });
    }

    function _unmarkAllFields(form)
    {
        $form = $(form);

        $form.find("[data-validate]").each(function(i, elem)
        {
            var $elem = $(elem);

            $elem.removeClass("error");
        });
    }

    function _validateElement(elem)
    {
        var $elem          = $(elem);
        var validationKeys = $elem.attr("data-validate").split("|").map(function(i)
            {
            return i.trim();
        }) || ["text"];
        var hasError       = false;

        _findFormControls($elem).each(function(i, formControl)
        {
            var $formControl  = $(formControl);
            var validationKey = validationKeys[i] || validationKeys[0];

            if (!_isActive($formControl))
            {
                // continue loop
                return true;
            }

            if ($formControl.is("[type=\"checkbox\"], [type=\"radio\"]"))
            {

                if (!_validateGroup($formControl, validationKey))
                {
                    hasError = true;
                }

                return true;
            }

            if ($formControl.is("select"))
            {
                if (!_validateSelect($formControl, validationKey))
                {
                    hasError = true;
                }

                return true;
            }

            if (!_validateInput($formControl, validationKey))
            {
                hasError = true;
            }

            return false;
        });

        return !hasError;
    }

    function _validateGroup($formControl, validationKey)
    {
        var groupName = $formControl.attr("name");
        var $group    = $form.find("[name=\"" + groupName + "\"]");
        var range     = _eval(validationKey) || {min: 1, max: 1};
        var checked   = $group.filter(":checked").length;

        return checked >= range.min && checked <= range.max;

    }

    function _validateSelect($formControl, validationKey)
    {
        return $.trim($formControl.val()) !== validationKey;
    }

    function _validateInput($formControl, validationKey)
    {
        switch (validationKey)
        {
        case "text":
            return _hasValue($formControl);
        case "number":
            return _hasValue($formControl) && $.isNumeric($.trim($formControl.val()));
        case "ref":
            return _compareRef($.trim($formControl.val()), $.trim($formControl.attr("data-validate-ref")));
        case "regex":
            var ref   = $formControl.attr("data-validate-ref");
            var regex = ref.startsWith("/") ? _eval(ref) : new RegExp(ref);

            return _hasValue($formControl) && regex.test($.trim($formControl.val()));
        default:
            console.error("Form validation error: unknown validation property: \"" + validationKey + "\"");
            return true;
        }
    }

    function _hasValue($formControl)
    {
        return $.trim($formControl.val()).length > 0;
    }

    function _compareRef(value, ref)
    {
        if ($(ref).length > 0)
        {
            ref = $.trim($(ref).val());
        }

        return value === ref;
    }

    function _findFormControls($elem)
    {
        if ($elem.is("input, select, textarea"))
        {
            return $elem;
        }

        return $elem.find("input, select, textarea");
    }

    function _isActive($elem)
    {
        return $elem.is(":visible") && $elem.is(":enabled");
    }

    function _eval(input)
    {
        // eslint-disable-next-line
        return (new Function("return " + input))();
    }

})(jQuery);
<commit_msg>- rewrite ValidationService in ES6<commit_after>import $ from "jquery";

let $form;

export function validate(form)
{
    const deferred      = $.Deferred();
    const invalidFields = getInvalidFields(form);

    if (invalidFields.length > 0)
    {
        deferred.rejectWith(form, [invalidFields]);
    }
    else
    {
        deferred.resolveWith(form);
    }

    return deferred;
}

export function getInvalidFields(form)
{
    $form = $(form);
    const invalidFormControls = [];

    $form.find("[data-validate]").each(function(i, elem)
    {

        if (!_validateElement($(elem)))
        {
            invalidFormControls.push(elem);
        }
    });

    return invalidFormControls;
}

export function markInvalidFields(fields, errorClass)
{
    errorClass = errorClass || "has-error";

    $(fields).each(function(i, elem)
    {
        const $elem = $(elem);

        $elem.addClass(errorClass);
        _findFormControls($elem).on("click.removeErrorClass keyup.removeErrorClass change.removeErrorClass", function()
        {
            if (_validateElement($elem))
            {
                $elem.removeClass(errorClass);
                if ($elem.is("[type=\"radio\"], [type=\"checkbox\"]"))
                {
                    const groupName = $elem.attr("name");

                    $("." + errorClass + "[name=\"" + groupName + "\"]").removeClass(errorClass);
                }
                _findFormControls($elem).off("click.removeErrorClass keyup.removeErrorClass change.removeErrorClass");
            }
        });
    });
}

export function unmarkAllFields(form)
{
    $form = $(form);

    $form.find("[data-validate]").each(function(i, elem)
    {
        const $elem = $(elem);

        $elem.removeClass("error");
    });
}

function _validateElement(elem)
{
    const $elem          = $(elem);
    const validationKeys = $elem.attr("data-validate").split("|").map(function(i)
        {
        return i.trim();
    }) || ["text"];
    let hasError       = false;

    _findFormControls($elem).each(function(i, formControl)
    {
        const $formControl  = $(formControl);
        const validationKey = validationKeys[i] || validationKeys[0];

        if (!_isActive($formControl))
        {
            // continue loop
            return true;
        }

        if ($formControl.is("[type=\"checkbox\"], [type=\"radio\"]"))
        {

            if (!_validateGroup($formControl, validationKey))
            {
                hasError = true;
            }

            return true;
        }

        if ($formControl.is("select"))
        {
            if (!_validateSelect($formControl, validationKey))
            {
                hasError = true;
            }

            return true;
        }

        if (!_validateInput($formControl, validationKey))
        {
            hasError = true;
        }

        return false;
    });

    return !hasError;
}

function _validateGroup($formControl, validationKey)
{
    const groupName = $formControl.attr("name");
    const $group    = $form.find("[name=\"" + groupName + "\"]");
    const range     = _eval(validationKey) || {min: 1, max: 1};
    const checked   = $group.filter(":checked").length;

    return checked >= range.min && checked <= range.max;
}

function _validateSelect($formControl, validationKey)
{
    return $.trim($formControl.val()) !== validationKey;
}

function _validateInput($formControl, validationKey)
{
    switch (validationKey)
    {
    case "text":
        return _hasValue($formControl);
    case "number":
        return _hasValue($formControl) && $.isNumeric($.trim($formControl.val()));
    case "ref":
        return _compareRef($.trim($formControl.val()), $.trim($formControl.attr("data-validate-ref")));
    case "regex":
        {
            const ref = $formControl.attr("data-validate-ref");
            const regex = ref.startsWith("/") ? _eval(ref) : new RegExp(ref);

            return _hasValue($formControl) && regex.test($.trim($formControl.val()));
        }
    default:
        console.error("Form validation error: unknown validation property: \"" + validationKey + "\"");
        return true;
    }
}

function _hasValue($formControl)
{
    return $.trim($formControl.val()).length > 0;
}

function _compareRef(value, ref)
{
    if ($(ref).length > 0)
    {
        ref = $.trim($(ref).val());
    }

    return value === ref;
}

function _findFormControls($elem)
{
    if ($elem.is("input, select, textarea"))
    {
        return $elem;
    }

    return $elem.find("input, select, textarea");
}

function _isActive($elem)
{
    return $elem.is(":visible") && $elem.is(":enabled");
}

function _eval(input)
{
    // eslint-disable-next-line
    return (new Function("return " + input))();
}

export default {validate, getInvalidFields, markInvalidFields, unmarkAllFields};
<|endoftext|>


<commit_before>
  ///////////////////////////////////////////////////////////////////////////////////////////////
  //                                                                                //
  //                                                                                //
  //                              //    ) )                                                    //
  //                      ___     //    / /           ___      __                              //
  //                    ((   ) ) //    / / //   / / //___) ) //  ) ) //   / /                  //
  //                     \ \    //  \ \ / //   / / //       //      ((___/ /                   //
  //                  //   ) ) ((____\ \ ((___( ( ((____   //           / /                    //
  //                                                                                //
  //                  sQuery 0.1                                                               //
  //                                                                                //
  ///////////////////////////////////////////////////////////////////////////////////////////////

var doc = context.document;
var sQuery, $;

(function(){

  sQuery = $ = function(selector) {
    return new SQUERY(selector);
  };

  allLayers = [];
  function fillArray(sel) {
    var layers = sel.layers();
    var len = layers.length();

    for (var i=0; i < len; i++) {
      var layer = layers.objectAtIndex(i);

      if ([layer class] == MSLayerGroup) {
        allLayers.push(layer);
        fillArray(layer);
      } else {
        allLayers.push(layer);
      }

    }
  };

  var SQUERY = function(selector) {

    // this
    this.typename =  "sQuery";
    this.version = "0.1";
    this.autor = "Francis Vega";
    this.layers = [];

    // vars
    var _docs = [];
    var _layers = [];
    var len;
    var i;
    var keyChar = "%";

    // this
    this.typename =  "psdQuery";
    this.version = "1.0";
    this.autor = "Francis Vega";
    this.layers = [];

    /**
     * Filtra el array de capas para dejar solo aquellas que coincidan en el tipo (klass)
     * @param {object|string} klass Determina el tipo de capa a filtrar
     * @return {[MSLayerClass]}
     * @example
     * filterLayersByClass(MSLayerGroup);
     * @example
     * filterLayersByClass("*");
     */
    function filterLayersByClass(klass) {
      allLayers = [];
      fillArray(doc.currentPage().currentArtboard());

      // Chapucilla
      if (typeof(klass) == "object") {
        var _layers = [];
        var layer;
        var len = allLayers.length;

        for(i=0; i<len; i++) {
          layer = allLayers[i];
          if(sQuery().is(layer, klass)) {
            _layers.push(layer);
          }
        }
        return _layers;
      }
      if (typeof(klass) == "string") {

        switch(klass) {
          case "*":
            return allLayers;
            break;

          case "selected":
            var _mslayers = context.selection;
            var _layers = [];
            for(var i=0; i<_mslayers.count(); i++) {
              _layers.push(_mslayers.objectAtIndex(i));
            }
            return _layers;
            break;
        }
      }

    };

    if (typeof selector === "string") {

      switch(selector) {
        case "*":
          _layers = filterLayersByClass("*");
          break;

        case "%groups%":
          _layers = filterLayersByClass(MSLayerGroup);
          break;

        case "%shapes%":
          _layers = filterLayersByClass(MSShapeGroup);
          break;

        case "%images%":
          _layers = filterLayersByClass(MSBitmapLayer);
          break;

        case "%textLayer%":
          _layers = filterLayersByClass(MSTextLayer);
          break;

        case "%selected%":
          _layers = filterLayersByClass("selected");
          break;

        default:
          break;
      }
    }

    this.layers = _layers.slice();
    this.length = _layers.length;

    // Return self object
    return this;

  };

  /* @psdQuery API */

  sQuery.fn = SQUERY.prototype = {

    is: function(layer, theClass){
      var klass = [layer class];
      return klass === theClass;
    },

    isPage: function(layer){
      return SQUERY.prototype.is(layer, MSPage);
    },

    isArtboard: function(layer){
      return SQUERY.prototype.is(layer, MSArtboardGroup);
    },

    isGroup: function(layer){
      return SQUERY.prototype.is(layer, MSLayerGroup);
    },

    isText: function(layer){
      return SQUERY.prototype.is(layer, MSTextLayer);
    },

    isShape: function(layer){
      return SQUERY.prototype.is(layer, MSShapeGroup);
    },

    isImageLayer: function(layer) {
      return SQUERY.prototype.is(layer, MSBitmapLayer);
    },

     //@LOOP METHODS

    /**
     * Itera por cada uno de los elementos previamente seleccionados y devuelve el elemento
     * @param {function} callback Una función a la que each llama por cada iteración
     * @return {this} Devuelve this
     */
    each: function(callback) {
      for(var i = 0; i < this.layers.length; ++i) {
        callback.call(this.layers[i], i);
      }

      return this;
    },

    /**
     * Itera por cada uno de los elementos filtrando los que devuelvan true
     * @param {function} callback Una función a la que filter llama por cada iteración
     * @return {this} Devuelve this
     */
    filter: function(callback) {
      var r = [];
      var k;
      for(var i = 0; i < this.layers.length; ++i) {
        k = callback.call(this.layers[i], i);
        if (k){
          r.push(this.layers[i]);
        }
      }
      this.layers = r.slice();

      return this;
    },

    rename: function(name) {
      for (var i=0; i<this.layers.length; i++) {
        this.layers[i].name = name;
      }
      return this;
    },

    isLocked: function(neg) {
      var _layers = [];

      for (var i=0; i<this.layers.length; i++) {
        if (this.layers[i].isLocked()) {
          _layers.push(this.layers[i]);
        }
      }

      this.layers = _layers.slice();

      return this;
    },

    startsWith: function(str) {
      var _layers = [];
      var strLen = str.length;
      var layerName;
      for (var i=0; i<this.layers.length; i++) {
        layerName = this.layers[i].name();

        if(layerName.substr(0, strLen) == str) {
          _layers.push(this.layers[i]);
        }
      }

      this.layers = _layers.slice();

      return this;
    },

    endsWith: function(str) {
      var _layers = [];
      var strLen = str.length;
      var layerName;
      for (var i=0; i<this.layers.length; i++) {
        layerName = this.layers[i].name();
        layerNameLen = layerName.length();

        if(layerName.substr(layerNameLen-strLen, layerNameLen) == str) {
          _layers.push(this.layers[i]);
        }
      }

      this.layers = _layers.slice();

      return this;
    },

    contains: function(str) {
      var _layers = [];
      var layerName;
      for (var i=0; i<this.layers.length; i++) {
        layerName = this.layers[i].name();

        if(layerName.split(str).length > 1) {
          _layers.push(this.layers[i]);
        }
      }

      this.layers = _layers.slice();

      return this;
    },

    UISelect: function(){
      // Primero deseleccionamos todo
      doc.currentPage().deselectAllLayers()
        for (var i=0; i<this.layers.length; i++) {
          this.layers[i].select_byExpandingSelection(true, true);
        }
      return this;
    },

    brothers: function(){
      var bigBrother = this.layers[0];
      var bigParent = bigBrother.parentGroup();
      var brothers = bigParent.layers();
      var _layers = [];
      for (var i=0; i<brothers.count(); i++) {
        _layers.push(brothers.objectAtIndex(i));
      }

      this.layers = _layers.slice();
      return this;
    },

    childs: function() {
    },

    descendants: function() {
      return this;
    },

    isEmpty: function() {
    },

    isHidden: function() {
      return this;
    },

    show: function() {
      return this;
    },

    hide: function() {
      return this;
    },

    lock: function() {
      return this;
    },

    unlock: function() {
      return this;
    },

    duplicate: function(name) {
      return this;
    },

    remove: function() {
      return this;
    },

    visible: function(val) {
      return this;
    },

    opacity: function(val) {
      return this;
    },

    addGroup: function(name) {
      return this;
    },

    addTextLayer: function(userInput) {
      return this;
    }
  };
}
)();
<commit_msg>Se han añadido algunos métodos básicos<commit_after>
  ///////////////////////////////////////////////////////////////////////////////////////////////
  //                                                                                //
  //  sQuery 0.1                                                                               //
  //                                                                                //
  ///////////////////////////////////////////////////////////////////////////////////////////////

  var doc = context.document;
  var sQuery, $;

(function(){

  sQuery = $ = function(selector) {
    return new SQUERY(selector);
  };

  allLayers = [];
  function fillArray(sel) {
    var layers = sel.layers();
    var len = layers.length();

    for (var i=0; i < len; i++) {
      var layer = layers.objectAtIndex(i);

      if ([layer class] == MSLayerGroup) {
        allLayers.push(layer);
        fillArray(layer);
      } else {
        allLayers.push(layer);
      }

    }
  };

  var SQUERY = function(selector) {

    // this
    this.typename =  "sQuery";
    this.version = "0.1";
    this.autor = "Francis Vega";
    this.layers = [];

    // vars
    var _docs = [];
    var _layers = [];
    var len;
    var i;
    var keyChar = "%";

    // this
    this.typename =  "psdQuery";
    this.version = "1.0";
    this.autor = "Francis Vega";
    this.layers = [];

    /**
     * Filtra el array de capas para dejar solo aquellas que coincidan en el tipo (klass)
     * @param {object|string} klass Determina el tipo de capa a filtrar
     * @return {[MSLayerClass]}
     * @example
     * filterLayersByClass(MSLayerGroup);
     * @example
     * filterLayersByClass("*");
     */
    function filterLayersByClass(klass) {
      allLayers = [];
      fillArray(doc.currentPage().currentArtboard());

      if (typeof(klass) == "object") {
        var _layers = [];
        var layer;
        var len = allLayers.length;

        for(i=0; i<len; i++) {
          layer = allLayers[i];
          if(sQuery().is(layer, klass)) {
            _layers.push(layer);
          }
        }
        return _layers;
      }

      if (typeof(klass) == "string") {

        switch(klass) {

          case "*":
            return allLayers;
            break;

          case "selected":
            var _mslayers = context.selection;
            var _layers = [];
            for(var i=0; i<_mslayers.count(); i++) {
              _layers.push(_mslayers.objectAtIndex(i));
            }
            return _layers;
            break;

        }

      }

    };

    if (typeof selector === "string") {

      switch(selector) {

        case "*":
          _layers = filterLayersByClass("*");
          break;

        case "%groups%":
          _layers = filterLayersByClass(MSLayerGroup);
          break;

        case "%shapes%":
          _layers = filterLayersByClass(MSShapeGroup);
          break;

        case "%images%":
          _layers = filterLayersByClass(MSBitmapLayer);
          break;

        case "%textLayer%":
          _layers = filterLayersByClass(MSTextLayer);
          break;

        case "%selected%":
          _layers = filterLayersByClass("selected");
          break;

        default:
          break;

      }

    }

    this.layers = _layers.slice();
    this.length = _layers.length;

    // Return self object
    return this;

  };

  /* @psdQuery API */

  sQuery.fn = SQUERY.prototype = {

    is: function(layer, theClass){
      var klass = [layer class];
      return klass === theClass;
    },

    isPage: function(layer){
      return SQUERY.prototype.is(layer, MSPage);
    },

    isArtboard: function(layer){
      return SQUERY.prototype.is(layer, MSArtboardGroup);
    },

    isGroup: function(layer){
      return SQUERY.prototype.is(layer, MSLayerGroup);
    },

    isText: function(layer){
      return SQUERY.prototype.is(layer, MSTextLayer);
    },

    isShape: function(layer){
      return SQUERY.prototype.is(layer, MSShapeGroup);
    },

    isImageLayer: function(layer) {
      return SQUERY.prototype.is(layer, MSBitmapLayer);
    },

     //@LOOP METHODS

    /**
     * Itera por cada uno de los elementos previamente seleccionados y devuelve el elemento
     * @param {function} callback Una función a la que each llama por cada iteración
     * @return {this} Devuelve this
     */
    each: function(callback) {
      for(var i = 0; i < this.layers.length; ++i) {
        callback.call(this.layers[i], i);
      }

      return this;
    },

    /**
     * Itera por cada uno de los elementos filtrando los que devuelvan true
     * @param {function} callback Una función a la que filter llama por cada iteración
     * @return {this} Devuelve this
     */
    filter: function(callback) {
      var r = [];
      var k;
      for(var i = 0; i < this.layers.length; ++i) {
        k = callback.call(this.layers[i], i);
        if (k){
          r.push(this.layers[i]);
        }
      }
      this.layers = r.slice();

      return this;
    },

    rename: function(name) {
      for (var i=0; i<this.layers.length; i++) {
        this.layers[i].name = name;
      }
      return this;
    },

    isLocked: function(neg) {
      var _layers = [];

      for (var i=0; i<this.layers.length; i++) {
        if (this.layers[i].isLocked()) {
          _layers.push(this.layers[i]);
        }
      }

      this.layers = _layers.slice();

      return this;
    },

    startsWith: function(str) {
      var _layers = [];
      var strLen = str.length;
      var layerName;
      for (var i=0; i<this.layers.length; i++) {
        layerName = this.layers[i].name();

        if(layerName.substr(0, strLen) == str) {
          _layers.push(this.layers[i]);
        }
      }

      this.layers = _layers.slice();

      return this;
    },

    endsWith: function(str) {
      var _layers = [];
      var strLen = str.length;
      var layerName;
      for (var i=0; i<this.layers.length; i++) {
        layerName = this.layers[i].name();
        layerNameLen = layerName.length();

        if(layerName.substr(layerNameLen-strLen, layerNameLen) == str) {
          _layers.push(this.layers[i]);
        }
      }

      this.layers = _layers.slice();

      return this;
    },

    contains: function(str) {
      var _layers = [];
      var layerName;
      for (var i=0; i<this.layers.length; i++) {
        layerName = this.layers[i].name();

        if(layerName.split(str).length > 1) {
          _layers.push(this.layers[i]);
        }
      }

      this.layers = _layers.slice();

      return this;
    },

    UISelect: function(){
      // Primero deseleccionamos todo
      doc.currentPage().deselectAllLayers()
        for (var i=0; i<this.layers.length; i++) {
          this.layers[i].select_byExpandingSelection(true, true);
        }
      return this;
    },

    brothers: function(){
      var bigBrother = this.layers[0];
      var bigParent = bigBrother.parentGroup();
      var brothers = bigParent.layers();

      var _layers = [];
      for (var i=0; i<brothers.count(); i++) {
        _layers.push(brothers.objectAtIndex(i));
      }

      this.layers = _layers.slice();
      return this;
    },

    childs: function() {
      var parent = this.layers[0];
      var childs = parent.layers();

      var _layers = [];
      for (var i=0; i<childs.count(); i++) {
        _layers.push(childs.objectAtIndex(i));
      }

      this.layers = _layers.slice();
      return this;
    },

    descendants: function() {
      var _layers = [];
      allLayers = [];

      fillArray(this.layers[0]);

      this.layers = allLayers.slice();
      return this;
    },

    isEmpty: function() {
      var _layers = [];
      for (var i=0; i<this.layers.length; i++) {
        if (this.isGroup(this.layers[i].class())) {
          if (this.layers[i].layers().length() == 0) {
            _layers.push(this.layers[i]);
          }
        }
      }
      this.layers = _layers.slice();
      return this;
    },

    isVisible: function() {
      var _layers = [];
      for (var i=0; i<this.layers.length; i++) {
        if(this.layers[i].isVisible()) {
          _layers.push(this.layers[i]);
        }
      }
      this.layers = _layers.slice();
      return this;
    },

    isHidden: function() {
      var _layers = [];
      for (var i=0; i<this.layers.length; i++) {
        if(!this.layers[i].isVisible()) {
          _layers.push(this.layers[i]);
        }
      }
      this.layers = _layers.slice();
      return this;
    },

    show: function() {
      for (var i=0; i<this.layers.length; i++) {
        this.layers[i].setIsVisible(true);
      }
      return this;
    },

    hide: function() {
      for (var i=0; i<this.layers.length; i++) {
        this.layers[i].setIsVisible(false);
      }
      return this;
    },

    lock: function() {
      for (var i=0; i<this.layers.length; i++) {
        this.layers[i].setIsLocked(true);
      }
      return this;
    },

    unlock: function() {
      for (var i=0; i<this.layers.length; i++) {
        this.layers[i].setIsLocked(false);
      }
      return this;
    },

    duplicate: function(name) {
      return this;
    },

    remove: function() {
      for (var i=0; i<this.layers.length; i++) {
        this.layers[i].parentGroup().removeLayer(this.layers[i]);
      }
      return this;
    }

  };
}
)();
<|endoftext|>


<commit_before>var expect = require("expect.js");
var parser = require("../lib/parser");
var expander = require("../lib/expander");

// load all the "private" expander names (stored in _test)
// into the global scope for cleaner testing
Object.keys(expander._test).forEach(function(val) {
    global[val] = expander._test[val];
});

// extract the token values from a token array
function tokValues (stxArray) {
    return stxArray.map(function(el) {
        return el.token.value;
    });
}

var emptyMacroMap = new Map();

describe("matchPatternClass", function() {
    it("should give null when pattern doesn't match", function() {
        var stx = parser.read("42");
        var res = matchPatternClass("ident", stx, emptyMacroMap).result;

        expect(res).to.be(null);
    });

    it("should match a single token", function() {
        var stx = parser.read("foo bar");
        var res = matchPatternClass("token", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo"]);
    });

    it("should match a single delimited token", function() {
        var stx = parser.read("(foo) bar");
        var res = matchPatternClass("token", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["()"]);
        expect(tokValues(res[0].token.inner)).to.eql(["foo"]);
    });

    it("should match a lit", function() {
        var stx = parser.read("42");
        var res = matchPatternClass("lit", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql([42]);
    });

    it("should match an ident", function() {
        var stx = parser.read("foo");
        var res = matchPatternClass("ident", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo"]);
    });

    it("should match a binary expression", function() {
        var stx = parser.read("2+2");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql([2, "+", 2]);
    });

    it("should match a complex binary expression", function() {
        var stx = parser.read("2+2*10/32");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql([2, "+", 2, "*", 10, "/", 32]);
    });

    it("should handle a broken binary expression", function() {
        var stx = parser.read("2+2 + +");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql([2, "+", 2]);
    });

    it("should match a this expression", function() {
        var stx = parser.read("this.foo");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["this"]);
    });

    it("should match a literal expression", function() {
        var stx = parser.read("42");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql([42]);
    });

    it("should match a parenthesized expression", function() {
        var stx = parser.read("(42)");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["(", 42, ")"]);
    });

    it("should match an array literal", function() {
        var stx = parser.read("[1,2,3]");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["[", 1, ",", 2, ",", 3, "]"]);
    });

    it("should match a simple object literal", function() {
        var stx = parser.read("{a: 42}");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["{", "a", ":", 42, "}"]);
    });

    it("should match an empty function call", function() {
        var stx = parser.read("foo()");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo", "(", ")"]);
    });

    it("should match a simple function call", function() {
        var stx = parser.read("foo(24)");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo", "(", 24, ")"]);
    });

    it("should match a function call with two simple arguments", function() {
        var stx = parser.read("foo(24, 42)");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo", "(", 24, ",", 42, ")"]);
    });

});

describe("expand", function() {
    it("handle a simple binary expression", function() {
        var stx = parser.read("42 + 24");
        var res = expander.flatten(expander.expand(stx));
        expect(tokValues(res)).to.eql([42, "+", 24, '']);
    });

    it("should expand a complex binary expression", function() {
        var stx = parser.read("1 + 2 * 3");
        var res = expander.flatten(expander.expand(stx));
        expect(tokValues(res)).to.eql([1, "+", 2, "*", 3, '']);
    });

    it("should handle a simple object bracket get", function() {
        var stx = parser.read("test[0]");
        var res = expander.flatten(expander.expand(stx));

        expect(tokValues(res)).to.eql(["test", "[", 0, "]", ""]);
    });

    it("should handle a object bracket get", function() {
        var stx = parser.read("test[2+3-1]");
        var res = expander.flatten(expander.expand(stx));

        expect(tokValues(res)).to.eql(["test", "[", 2, "+", 3, "-", 1, "]", ""]);
    });

    it("should handle a binop and an object bracket get", function() {
        var stx = parser.read("42 == test[0]");
        var res = expander.flatten(expander.expand(stx));

        expect(tokValues(res)).to.eql([42, "==", "test", "[", 0, "]", ""]);
    });

    it("should handle function calls", function() {
        var stx = parser.read("foo(24, 42)");
        var res = expander.flatten(expander.expand(stx));

        expect(tokValues(res)).to.eql(["foo", "(", "24", ",", "42", ")", ""]);
    });

    it("should handle complex left side function calls", function() {
        var stx = parser.read("(function(x) { return x; })(24)");
        var res = expander.flatten(expander.expand(stx));

        expect(tokValues(res)).to.eql(["(", "function", "(", "x", ")", "{",
                                        "return", "x", ";", "}", ")", "(", 24, ")", ""]);

    });
});
<commit_msg>tests<commit_after>var expect = require("expect.js");
var parser = require("../lib/parser");
var expander = require("../lib/expander");

// load all the "private" expander names (stored in _test)
// into the global scope for cleaner testing
Object.keys(expander._test).forEach(function(val) {
    global[val] = expander._test[val];
});

// extract the token values from a token array
function tokValues (stxArray) {
    return stxArray.map(function(el) {
        return el.token.value;
    });
}

var emptyMacroMap = new Map();

describe("matchPatternClass", function() {
    it("should give null when pattern doesn't match", function() {
        var stx = parser.read("42");
        var res = matchPatternClass("ident", stx, emptyMacroMap).result;

        expect(res).to.be(null);
    });

    it("should match a single token", function() {
        var stx = parser.read("foo bar");
        var res = matchPatternClass("token", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo"]);
    });

    it("should match a single delimited token", function() {
        var stx = parser.read("(foo) bar");
        var res = matchPatternClass("token", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["()"]);
        expect(tokValues(res[0].token.inner)).to.eql(["foo"]);
    });

    it("should match a lit", function() {
        var stx = parser.read("42");
        var res = matchPatternClass("lit", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql([42]);
    });

    it("should match an ident", function() {
        var stx = parser.read("foo");
        var res = matchPatternClass("ident", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo"]);
    });

    it("should match a binary expression", function() {
        var stx = parser.read("2+2");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql([2, "+", 2]);
    });

    it("should match a complex binary expression", function() {
        var stx = parser.read("2+2*10/32");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql([2, "+", 2, "*", 10, "/", 32]);
    });

    it("should handle a broken binary expression", function() {
        var stx = parser.read("2+2 + +");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql([2, "+", 2]);
    });

    it("should match a this expression", function() {
        var stx = parser.read("this.foo");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["this"]);
    });

    it("should match a literal expression", function() {
        var stx = parser.read("42");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql([42]);
    });

    it("should match a parenthesized expression", function() {
        var stx = parser.read("(42)");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["(", 42, ")"]);
    });

    it("should match an array literal", function() {
        var stx = parser.read("[1,2,3]");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["[", 1, ",", 2, ",", 3, "]"]);
    });

    it("should match a simple object literal", function() {
        var stx = parser.read("{a: 42}");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["{", "a", ":", 42, "}"]);
    });

    it("should match an empty function call", function() {
        var stx = parser.read("foo()");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo", "(", ")"]);
    });

    it("should match a simple function call", function() {
        var stx = parser.read("foo(24)");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo", "(", 24, ")"]);
    });

    it("should match a function call with two simple arguments", function() {
        var stx = parser.read("foo(24, 42)");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo", "(", 24, ",", 42, ")"]);
    });

    it("should match a function call with two complex arguments", function() {
        var stx = parser.read("foo(24 + 24, 42)");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo", "(", 24, "+", 24, ",", 42, ")"]);
    });

    it("should not match a function call with a non-expression as one of the args", function() {
        var stx = parser.read("foo(24 + 24 +, 42)");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo"]);
    });

    it("should not match a function call with a non-expression punctuator", function() {
        var stx = parser.read("foo(24 + 24, ,)");
        var res = matchPatternClass("expr", stx, emptyMacroMap).result;

        expect(tokValues(res)).to.eql(["foo"]);
    });
});

describe("expand", function() {
    it("handle a simple binary expression", function() {
        var stx = parser.read("42 + 24");
        var res = expander.flatten(expander.expand(stx));
        expect(tokValues(res)).to.eql([42, "+", 24, '']);
    });

    it("should expand a complex binary expression", function() {
        var stx = parser.read("1 + 2 * 3");
        var res = expander.flatten(expander.expand(stx));
        expect(tokValues(res)).to.eql([1, "+", 2, "*", 3, '']);
    });

    it("should handle a simple object bracket get", function() {
        var stx = parser.read("test[0]");
        var res = expander.flatten(expander.expand(stx));

        expect(tokValues(res)).to.eql(["test", "[", 0, "]", ""]);
    });

    it("should handle a object bracket get", function() {
        var stx = parser.read("test[2+3-1]");
        var res = expander.flatten(expander.expand(stx));

        expect(tokValues(res)).to.eql(["test", "[", 2, "+", 3, "-", 1, "]", ""]);
    });

    it("should handle a binop and an object bracket get", function() {
        var stx = parser.read("42 == test[0]");
        var res = expander.flatten(expander.expand(stx));

        expect(tokValues(res)).to.eql([42, "==", "test", "[", 0, "]", ""]);
    });

    it("should handle function calls", function() {
        var stx = parser.read("foo(24, 42)");
        var res = expander.flatten(expander.expand(stx));

        expect(tokValues(res)).to.eql(["foo", "(", "24", ",", "42", ")", ""]);
    });

    it("should handle complex left side function calls", function() {
        var stx = parser.read("(function(x) { return x; })(24)");
        var res = expander.flatten(expander.expand(stx));

        expect(tokValues(res)).to.eql(["(", "function", "(", "x", ")", "{",
                                        "return", "x", ";", "}", ")", "(", 24, ")", ""]);

    });
});
<|endoftext|>


<commit_before>const { d } = require('../src/dice.js')

const defaultNumberRolls = 500

expect.extend({
  toBeOnAverage(received, expected, margin = 0.5) {
    const average = received.reduce(plus) / received.length
    const pass = average > expected - margin && average < expected + margin

    return {
      pass,
      message: () => (
        `expected average to${pass ? ' not ' : ' '}be around ${expected} (margin: ${margin}), got ${average}`
      )
    }
  },
  toBeBetween(received, low, high) {
    const pass = received.reduce((allOk, value) => {
      return allOk && value >= low && value <= high
    }, true)

    return {
      pass,
      message: () => (
        `expected all to${pass ? ' not ' : ' '}be between ${low} and ${high}`
      )
    }
  },
  toAllBe(received, expected) {
    const pass = received.reduce((allOk, value) => {
      return allOk && value === expected
    })

    return {
      pass,
      message: () => (
        `expected all to${pass ? ' not ' : ' '}be equal to ${expected}`
      )
    }
  }
})

const plus = (a, b) => a + b

const rollForTest = (die, numberRolls) => {
  let pools = []
  let rolls = []

  for (let i = 0; i < numberRolls; i++) {
    let rolled = die()
    pools.push(rolled)
    rolls.push(rolled.reduce(plus))
  }

  return { pools, rolls }
}

const testDie = (die, testSpecs, numberRolls = defaultNumberRolls) => {
  let { pools, rolls } = rollForTest(die, numberRolls)

  if ('diceCount' in testSpecs) {
    it(`rolls ${testSpecs.diceCount} dice`, () => {
      expect(pools.map((pool) => (pool.length))).toAllBe(testSpecs.diceCount)
    })
  }

  if ('average' in testSpecs) {
    let { average, margin } = testSpecs.average

    it(`has an expected value of ${average}`, () => {
      expect(rolls).toBeOnAverage(average, margin)
    })
  }

  if ('bounds' in testSpecs) {
    let { low, high, expectExtrema } = testSpecs.bounds

    it(`rolls between ${low} and ${high}`, () => {
      expect(rolls).toBeBetween(low, high)
    })

    if (expectExtrema) {
      it('attains its minimum', () => {
        expect(rolls).toContain(low)
      })

      it('attains its maximum', () => {
        expect(rolls).toContain(high)
      })
    }
  }
}

const basicDieTestSpecs = (number, sides) => {
  return {
    diceCount: number,
    average: {
      average: (number * (sides + 1)) / 2
    },
    variance: {
      variance: (number * (sides * sides - 1)) / 12
    },
    bounds: {
      low: number,
      high: number * sides,
      expectExtrema: true
    }
  }
}
  }
}

const describeBasicDie = (number, sides, numberRolls = defaultNumberRolls) => {
  describe(`${number}d${sides}`, () => {
    const die = d(number, sides)
    testDie(die, basicDieTestSpecs(number, sides), numberRolls)
  })
}

describe('basic dice', () => {
  describeBasicDie(1, 6)
  describeBasicDie(2, 8, 500)
  describeBasicDie(20, 1)
})
<commit_msg>Add variance tests<commit_after>const { d } = require('../src/dice.js')

const defaultNumberRolls = 500

expect.extend({
  toBeOnAverage(received, expected, margin = 0.5) {
    const average = received.reduce(plus) / received.length
    const pass = average > expected - margin && average < expected + margin

    return {
      pass,
      message: () => (
        `expected average to${pass ? ' not ' : ' '}be around ${expected} (margin: ${margin}), got ${average}`
      )
    }
  },
  toBeBetween(received, low, high) {
    const pass = received.reduce((allOk, value) => {
      return allOk && value >= low && value <= high
    }, true)

    return {
      pass,
      message: () => (
        `expected all to${pass ? ' not ' : ' '}be between ${low} and ${high}`
      )
    }
  },
  toAllBe(received, expected) {
    const pass = received.reduce((allOk, value) => {
      return allOk && value === expected
    })

    return {
      pass,
      message: () => (
        `expected all to${pass ? ' not ' : ' '}be equal to ${expected}`
      )
    }
  },
  toHaveVariance(received, expected, margin = 0.5) {
    const average = received.reduce(plus) / received.length
    const variance = received.map((value) => (Math.pow(value - average, 2)))
      .reduce(plus) / (received.length - 1)
    const pass = variance > expected - margin && variance < expected + margin

    return {
      pass,
      message: () => (
        `expected variance to${pass ? ' not ' : ' '}be around ${expected} (margin: ${margin}), got ${variance}`
      )
    }
  }
})

const plus = (a, b) => a + b

const rollForTest = (die, numberRolls) => {
  let pools = []
  let rolls = []

  for (let i = 0; i < numberRolls; i++) {
    let rolled = die()
    pools.push(rolled)
    rolls.push(rolled.reduce(plus))
  }

  return { pools, rolls }
}

const testDie = (die, testSpecs, numberRolls = defaultNumberRolls) => {
  let { pools, rolls } = rollForTest(die, numberRolls)

  if ('diceCount' in testSpecs) {
    it(`rolls ${testSpecs.diceCount} dice`, () => {
      expect(pools.map((pool) => (pool.length))).toAllBe(testSpecs.diceCount)
    })
  }

  if ('average' in testSpecs) {
    let { average, margin } = testSpecs.average

    it(`has an expected value of ${average}`, () => {
      expect(rolls).toBeOnAverage(average, margin)
    })
  }

  if ('variance' in testSpecs) {
    let { variance, margin } = testSpecs.variance

    it(`has a variance of ${variance}`, () => {
      expect(rolls).toHaveVariance(variance, margin)
    })
  }

  if ('bounds' in testSpecs) {
    let { low, high, expectExtrema } = testSpecs.bounds

    it(`rolls between ${low} and ${high}`, () => {
      expect(rolls).toBeBetween(low, high)
    })

    if (expectExtrema) {
      it('attains its minimum', () => {
        expect(rolls).toContain(low)
      })

      it('attains its maximum', () => {
        expect(rolls).toContain(high)
      })
    }
  }
}

const basicDieTestSpecs = (number, sides) => {
  return {
    diceCount: number,
    average: {
      average: (number * (sides + 1)) / 2
    },
    variance: {
      variance: (number * (sides * sides - 1)) / 12
    },
    bounds: {
      low: number,
      high: number * sides,
      expectExtrema: true
    }
  }
}
  }
}

const describeBasicDie = (number, sides, numberRolls = defaultNumberRolls) => {
  describe(`${number}d${sides}`, () => {
    const die = d(number, sides)
    testDie(die, basicDieTestSpecs(number, sides), numberRolls)
  })
}

describe('basic dice', () => {
  describeBasicDie(1, 6)
  describeBasicDie(2, 8, 500)
  describeBasicDie(20, 1)
})
<|endoftext|>


<commit_before>/***
 * This file will contain all the scripts required for display entries to judges.
***/
$(function() {
	/* If it doesn't look like there's a contest ID in the URL, show an alert, and go back one page. */
	if (window.location.search.indexOf("?contest") === -1) {
		alert("Contest ID not found!");

		window.history.back();
	}

	/* Locate the contest ID in the URL, and store it for later use. */
	var contestId = window.location.href.split("?contest=")[1];

	/* Go ahead and find the div that we'll store all the entries in. */
	var entriesDiv = document.querySelector("#entries");

	console.log("Contest found!");
	console.log("Contest ID: " + contestId);

	/* Hide elements that we've marked with the class "hideWhileLoad". */
	$(".hideWhileLoad").css("display", "none");

	/* Attempt to load a contest, based on the ID we found in the URL. */
	Contest_Judging_System.loadContest(contestId, function(contest) {
		Contest_Judging_System.get_N_Entries(10, contest.id, function(entries) {

			/* Setup the page */
			$("title").text(contest.name);
			$("#contestName").text(contest.name);
			$("#contestDescription").html("Description coming soon!");

			/* Add all entries to the page */
			for (var i in entries) {
				/* Instead of having to write entries[i] all the time, let's declare a variable that's a bit shorter. */
				var curr = entries[i];

				/* Create a div and give it Bootstrap's "row" class */
				var rowDiv = document.createElement("row");
				rowDiv.className = "row";

				/* Create a paragraph element that'll eventually hold a link to this entry */
				var paragraphElem = document.createElement("p");

				/* Create a link element and set it's text to the name of this entry */
				var aElem = document.createElement("a");
				aElem.textContent = curr.name;
				aElem.href = "https://www.khanacademy.org/computer-programming/entry/" + curr.id;

				/* Add the link element to our paragraph element */
				paragraphElem.appendChild(aElem);

				/* Add our paragraph element to our row div */
				rowDiv.appendChild(paragraphElem);

				/* Add our row div to the entries div */
				entriesDiv.appendChild(rowDiv);
			}

			/* Hide the loading div and show items that were hidden during loading. */
			$("#loading").css("display", "none");
			$(".hideWhileLoad").css("display", "block");
		});
	});
}); <commit_msg>Added a comment<commit_after>/***
 * This file will contain all the scripts required for display entries to judges.
***/
$(function() {
	/* If it doesn't look like there's a contest ID in the URL, show an alert, and go back one page. */
	if (window.location.search.indexOf("?contest") === -1) {
		alert("Contest ID not found!");

		window.history.back();
	}

	/* Locate the contest ID in the URL, and store it for later use. */
	var contestId = window.location.href.split("?contest=")[1];

	/* Go ahead and find the div that we'll store all the entries in. */
	var entriesDiv = document.querySelector("#entries");

	console.log("Contest found!");
	console.log("Contest ID: " + contestId);

	/* Hide elements that we've marked with the class "hideWhileLoad". */
	$(".hideWhileLoad").css("display", "none");

	/* Attempt to load a contest, based on the ID we found in the URL. */
	Contest_Judging_System.loadContest(contestId, function(contest) {

		/* Randomly pick n entries, and then display them on the page. */
		Contest_Judging_System.get_N_Entries(10, contest.id, function(entries) {

			/* Setup the page */
			$("title").text(contest.name);
			$("#contestName").text(contest.name);
			$("#contestDescription").html("Description coming soon!");

			/* Add all entries to the page */
			for (var i in entries) {
				/* Instead of having to write entries[i] all the time, let's declare a variable that's a bit shorter. */
				var curr = entries[i];

				/* Create a div and give it Bootstrap's "row" class */
				var rowDiv = document.createElement("row");
				rowDiv.className = "row";

				/* Create a paragraph element that'll eventually hold a link to this entry */
				var paragraphElem = document.createElement("p");

				/* Create a link element and set it's text to the name of this entry */
				var aElem = document.createElement("a");
				aElem.textContent = curr.name;
				aElem.href = "https://www.khanacademy.org/computer-programming/entry/" + curr.id;

				/* Add the link element to our paragraph element */
				paragraphElem.appendChild(aElem);

				/* Add our paragraph element to our row div */
				rowDiv.appendChild(paragraphElem);

				/* Add our row div to the entries div */
				entriesDiv.appendChild(rowDiv);
			}

			/* Hide the loading div and show items that were hidden during loading. */
			$("#loading").css("display", "none");
			$(".hideWhileLoad").css("display", "block");
		});
	});
}); <|endoftext|>


<commit_before>var assert = require('assert');

var dateFormat = require('./../lib/dateformat');

describe('isoUtcDateTime', function() {
  it('should correctly format the timezone part', function(done) {
    var actual = dateFormat('2014-06-02T13:23:21-08:00', 'isoUtcDateTime');
    assert.strictEqual(actual, '2014-06-02T21:23:21Z');
    done();
  });
});
<commit_msg>Minor Formatting Changes for Is OUTC Datetime Test<commit_after>var assert = require("assert");

var dateFormat = require("./../lib/dateformat");

describe("isoUtcDateTime", function () {
  it("should correctly format the timezone part", function (done) {
    var actual = dateFormat("2014-06-02T13:23:21-08:00", "isoUtcDateTime");
    assert.strictEqual(actual, "2014-06-02T21:23:21Z");
    done();
  });
});
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2006-2009 Sun Microsystems, Inc.
 * Copyright (c) 2008-2011 Hasso Plattner Institute
 *
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * Data.js.  Data manipulation (mostly XML).
 */

module('lively.Data').requires('lively.OldModel').toRun(function(thisModule) {

// FIX for IE9+
if (typeof XPathResult == 'undefined') {
    JSLoader.loadJs(Config.codeBase + 'lib/wgxpath.install.js', undefined, true);
    XPathEvaluator = (function () { return document; });
    wgxpath.install();
}

if (!Global.View) Object.subclass("View");

View.subclass('Query',  {
    documentation: "Wrapper around XPath evaluation",

    xpe: Global.XPathEvaluator ? new XPathEvaluator()
         : (console.log('XPath not available') || {}),

    formals: ["+Results", // Node[]
        "-ContextNode", // where to evaluate
    ],

      initialize: function(expression, optPlug) {
            this.contextNode = null;
            this.expression = expression;
            if (optPlug) this.connectModel(optPlug);
      },

      establishContext: function(node) {
            if (this.nsResolver) return;
            var ctx = node.ownerDocument ? node.ownerDocument.documentElement : node.documentElement;
            if (ctx !== this.contextNode) {
                  this.contextNode = ctx;
                  this.nsResolver = this.xpe.createNSResolver(ctx);
            }
      },

      manualNSLookup: function() {
            this.nsResolver = function(prefix) {
                  return Namespace[prefix.toUpperCase()] || null;
            }
            return this;
      },

      updateView: function(aspect, controller) {
            var p = this.modelPlug;
            if (!p) return;
            switch (aspect) {
                  case p.getContextNode:
                  this.onContextNodeUpdate(this.getContextNode());
                  break;
            }
      },

      onContextNodeUpdate: function(node) {
            if (node instanceof Document) node = node.documentElement;
            var result = this.findAll(node, null);
            this.setResults(result);
      },

      findAll: function(node, defaultValue) {
            this.establishContext(node);
            var result = this.xpe.evaluate(this.expression, node, this.nsResolver, XPathResult.ANY_TYPE, null),
            accumulator = [],
            res = null;
            while (res = result.iterateNext()) accumulator.push(res);
            return accumulator.length > 0 || defaultValue === undefined ? accumulator : defaultValue;
      },

      findFirst: function(node) {
            this.establishContext(node);
            var result = this.xpe.evaluate(this.expression, node, this.nsResolver, XPathResult.ANY_TYPE, null);
            return result.iterateNext();
      }

});

Object.extend(Query, {
    find: function(expr, doc) {
        return new Query(expr).manualNSLookup().findFirst(doc);
    },

    findAll: function(expr, doc) {
        return new Query(expr).manualNSLookup().findAll(doc);
    }
});

Object.extend(module("lively.Data"), {
    XPathQuery: Query
});

}); // end of module
<commit_msg>XPathEvaluator fix<commit_after>/*
 * Copyright (c) 2006-2009 Sun Microsystems, Inc.
 * Copyright (c) 2008-2011 Hasso Plattner Institute
 *
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * Data.js.  Data manipulation (mostly XML).
 */

module('lively.Data').requires('lively.OldModel').toRun(function(thisModule) {

// FIX for IE9+
if (typeof XPathResult == 'undefined') {
    JSLoader.loadJs(Config.codeBase + 'lib/wgxpath.install.js', undefined, true);
    XPathEvaluator = (function () {
        return {
            createNSResolver: function(ctx) {
                if (ctx.ownerDocument) {
                    if (!ctx.ownerDocument.createNSResolver) {
                        wgxpath.install({document: ctx.ownerDocument});
                    }
                    var result = ctx.ownerDocument.createNSResolver(ctx);
                    result.__doc = ctx.ownerDocument;
                    return result;
                } else {
                    console.warn("Got a ctx without ownerDocument. Shouldn't happen!")
                    return document.createNSResolver(ctx);
                }
            },
            evaluate: function(expression, node, nsResolver, type, arg) {
                if (nsResolver.__doc) {
                    nsResolver.__doc.evaluate(expression, node, nsResolver, type, arg);
                } else {
                    console.warn("Got a nsResolver without __doc. Shouldn't happen!")
                    return document.evaluate(expression, node, nsResolver, type, arg);
                }
            }
        }
    });
    wgxpath.install();
}

if (!Global.View) Object.subclass("View");

View.subclass('Query',  {
    documentation: "Wrapper around XPath evaluation",

    xpe: Global.XPathEvaluator ? new XPathEvaluator()
         : (console.log('XPath not available') || {}),

    formals: ["+Results", // Node[]
        "-ContextNode", // where to evaluate
    ],

      initialize: function(expression, optPlug) {
            this.contextNode = null;
            this.expression = expression;
            if (optPlug) this.connectModel(optPlug);
      },

      establishContext: function(node) {
            if (this.nsResolver) return;
            var ctx = node.ownerDocument ? node.ownerDocument.documentElement : node.documentElement;
            if (ctx !== this.contextNode) {
                  this.contextNode = ctx;
                  this.nsResolver = this.xpe.createNSResolver(ctx);
            }
      },

      manualNSLookup: function() {
            this.nsResolver = function(prefix) {
                  return Namespace[prefix.toUpperCase()] || null;
            }
            return this;
      },

      updateView: function(aspect, controller) {
            var p = this.modelPlug;
            if (!p) return;
            switch (aspect) {
                  case p.getContextNode:
                  this.onContextNodeUpdate(this.getContextNode());
                  break;
            }
      },

      onContextNodeUpdate: function(node) {
            if (node instanceof Document) node = node.documentElement;
            var result = this.findAll(node, null);
            this.setResults(result);
      },

      findAll: function(node, defaultValue) {
            this.establishContext(node);
            var result = this.xpe.evaluate(this.expression, node, this.nsResolver, XPathResult.ANY_TYPE, null),
            accumulator = [],
            res = null;
            while (res = result.iterateNext()) accumulator.push(res);
            return accumulator.length > 0 || defaultValue === undefined ? accumulator : defaultValue;
      },

      findFirst: function(node) {
            this.establishContext(node);
            var result = this.xpe.evaluate(this.expression, node, this.nsResolver, XPathResult.ANY_TYPE, null);
            return result.iterateNext();
      }

});

Object.extend(Query, {
    find: function(expr, doc) {
        return new Query(expr).manualNSLookup().findFirst(doc);
    },

    findAll: function(expr, doc) {
        return new Query(expr).manualNSLookup().findAll(doc);
    }
});

Object.extend(module("lively.Data"), {
    XPathQuery: Query
});

}); // end of module
<|endoftext|>


<commit_before>/*
 * JBoss, Home of Professional Open Source
 * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

goog.require('goog.events');
goog.require('goog.testing.ContinuationTestCase');
goog.require('goog.testing.jsunit');
goog.require('org.jboss.core.service.query.SimpleTimeCache');

// ---- taken from continuationtestcase_test.html
var original_timeout = goog.testing.ContinuationTestCase.MAX_TIMEOUT;
goog.testing.ContinuationTestCase.MAX_TIMEOUT = 2 * 1000; // prolong default timeout

var testCase = new goog.testing.ContinuationTestCase('Test for org.jboss.core.service.query.SimpleTimeCache');
testCase.autoDiscoverTests();

// Standalone Closure Test Runner.
if (typeof G_testRunner != 'undefined') {
  G_testRunner.initialize(testCase);
}

function shouldRunTests() {
  // workaround for ContinuationTestCase, see https://github.com/jlgrock/ClosureJavascriptFramework/issues/41
  testCase.saveMessage('Start');
  return true;
}

/**
 * Test the cache. First we set two objects and test they expire after specified interval.
 * We set another object into the cache in the meantime and test it expires later as well.
 * In the end we test that the cache can be disposed.
 */
function testSimpleCache() {

  var firstExpiration = false;
  var secondExpiration = false;
  setTimeout(function() { firstExpiration = true; }, 300);
  setTimeout(function() { secondExpiration = true; }, 500);

  var cache = new org.jboss.core.service.query.SimpleTimeCache(0.2); // 200ms
  assertNotNull(cache);

  {
    assertTrue(cache.getCacheSize() == 0);
    assertFalse(cache.containsForKey('1'));
    assertFalse(cache.containsForKey('2'));
    assertFalse(cache.containsForKey('3'));

    cache.put('1', 'One');
    cache.put('2', 'Two');

    assertTrue(cache.getCacheSize() == 2);
    assertTrue(cache.containsForKey('1'));
    assertTrue(cache.containsForKey('2'));
    assertFalse(cache.containsForKey('3'));
  }

  setTimeout(function() { cache.put('3', 'Three'); }, 100);

  waitForCondition(
      function() {
        return firstExpiration;
      },
      function() {
        assertTrue(cache.getCacheSize() == 1);
        assertFalse(cache.containsForKey('1'));
        assertFalse(cache.containsForKey('2'));
        assertTrue(cache.containsForKey('3'));
      }
  );

  waitForCondition(
      function() {
        return secondExpiration;
      },
      function() {
        assertTrue(cache.getCacheSize() == 0);
        assertFalse(cache.containsForKey('1'));
        assertFalse(cache.containsForKey('2'));
        assertFalse(cache.containsForKey('3'));
      }
  );

  setTimeout(function() {goog.dispose(cache)}, 700);

  waitForCondition(
      function() {
        return cache.isDisposed();
      },
      function() {
        // if this is not executed the test will timeout (which should be considered an error!)
        try {
          // this should fire an error because cache has been disposed
          cache.get('1');
        } catch (e) {
          assertTrue(e instanceof TypeError);
        }
      }
  );
}

/**
 * This test that expired cache records are removed when internal cache check is executed.
 * Frequency of this check is driven by the 'validation' value passed into constructor (usually
 * the 'validation' value should be much smaller then the 'expiration' value).
 * In this test we use a small trick to test the effect of internal validation check by setting
 * the 'validation' value to greater value then the 'expiration' value.
 */
function testSimpleCacheExpirationCheckInterval() {

  var firstExpiration = false;
  var secondExpiration = false;
  setTimeout(function() { firstExpiration = true; }, 300);
  setTimeout(function() { secondExpiration = true; }, 500);

  var cache = new org.jboss.core.service.query.SimpleTimeCache(0.2, 0.4); // 200ms
  assertNotNull(cache);

  cache.put('1', 'One');
  cache.put('2', 'Two');

  // no records from cache are removed despite records are already expired
  waitForCondition(
      function() {
        return firstExpiration;
      },
      function() {
        assertEquals(2, cache.getCacheSize());
      }
  );

  // but now they are removed
  waitForCondition(
    function() {
      return secondExpiration;
    },
    function() {
      assertEquals(0, cache.getCacheSize());
    }
  );
}

/**
 * Test the cache correctly clone objects on both the 'put' and 'get' operations.
 */
function testSimpleCacheCloneObject() {

  var cache = new org.jboss.core.service.query.SimpleTimeCache(1);

  var model = { value: 'original' };
  cache.put('1', model);

  // change value in model object and test that the cached version
  // is intact and still keeps the original value
  {
    model.value = 'changed';
    var clone = cache.get('1');

    // references not equal
    assertTrue(model != clone);
    assertEquals('original', clone.value);
  }

  // change value of clone after it has been retrieved from the cache
  // and verify this does not affect future clones
  {
    clone.value = 'overridden';
    var nextClone = cache.get('1');

    // references not equal
    assertTrue(model != clone);
    assertEquals('original', nextClone.value);
  }

  goog.dispose(cache);
}
<commit_msg>Extends timeouts in test to help it make it through under pressure on Jenkins<commit_after>/*
 * JBoss, Home of Professional Open Source
 * Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

goog.require('goog.events');
goog.require('goog.testing.ContinuationTestCase');
goog.require('goog.testing.jsunit');
goog.require('org.jboss.core.service.query.SimpleTimeCache');

// ---- taken from continuationtestcase_test.html
var original_timeout = goog.testing.ContinuationTestCase.MAX_TIMEOUT;
goog.testing.ContinuationTestCase.MAX_TIMEOUT = 2 * 1000; // prolong default timeout

var testCase = new goog.testing.ContinuationTestCase('Test for org.jboss.core.service.query.SimpleTimeCache');
testCase.autoDiscoverTests();

// Standalone Closure Test Runner.
if (typeof G_testRunner != 'undefined') {
  G_testRunner.initialize(testCase);
}

function shouldRunTests() {
  // workaround for ContinuationTestCase, see https://github.com/jlgrock/ClosureJavascriptFramework/issues/41
  testCase.saveMessage('Start');
  return true;
}

/**
 * Test the cache. First we set two objects and test they expire after specified interval.
 * We set another object into the cache in the meantime and test it expires later as well.
 * In the end we test that the cache can be disposed.
 */
function testSimpleCache() {

  var firstExpiration = false;
  var secondExpiration = false;
  setTimeout(function() { firstExpiration = true; }, 500);
  setTimeout(function() { secondExpiration = true; }, 700);

  var cache = new org.jboss.core.service.query.SimpleTimeCache(0.3); // 300ms
  assertNotNull(cache);

  setTimeout(function() { cache.put('3', 'Three'); }, 200);

  {
    assertTrue(cache.getCacheSize() == 0);
    assertFalse(cache.containsForKey('1'));
    assertFalse(cache.containsForKey('2'));
    assertFalse(cache.containsForKey('3'));

    cache.put('1', 'One');
    cache.put('2', 'Two');

    assertTrue(cache.getCacheSize() == 2);
    assertTrue(cache.containsForKey('1'));
    assertTrue(cache.containsForKey('2'));
    assertFalse(cache.containsForKey('3'));
  }

  waitForCondition(
      function() {
        return firstExpiration;
      },
      function() {
        assertTrue(cache.getCacheSize() == 1);
        assertFalse(cache.containsForKey('1'));
        assertFalse(cache.containsForKey('2'));
        assertTrue(cache.containsForKey('3'));
      }
  );

  waitForCondition(
      function() {
        return secondExpiration;
      },
      function() {
        assertTrue(cache.getCacheSize() == 0);
        assertFalse(cache.containsForKey('1'));
        assertFalse(cache.containsForKey('2'));
        assertFalse(cache.containsForKey('3'));
      }
  );

  setTimeout(function() {goog.dispose(cache)}, 1000);

  waitForCondition(
      function() {
        return cache.isDisposed();
      },
      function() {
        // if this is not executed the test will timeout (which should be considered an error!)
        try {
          // this should fire an error because cache has been disposed
          cache.get('1');
        } catch (e) {
          assertTrue(e instanceof TypeError);
        }
      }
  );
}

/**
 * This test that expired cache records are removed when internal cache check is executed.
 * Frequency of this check is driven by the 'validation' value passed into constructor (usually
 * the 'validation' value should be much smaller then the 'expiration' value).
 * In this test we use a small trick to test the effect of internal validation check by setting
 * the 'validation' value to greater value then the 'expiration' value.
 */
function testSimpleCacheExpirationCheckInterval() {

  var firstExpiration = false;
  var secondExpiration = false;
  setTimeout(function() { firstExpiration = true; }, 300);
  setTimeout(function() { secondExpiration = true; }, 500);

  var cache = new org.jboss.core.service.query.SimpleTimeCache(0.2, 0.4); // 200ms
  assertNotNull(cache);

  cache.put('1', 'One');
  cache.put('2', 'Two');

  // no records from cache are removed despite records are already expired
  waitForCondition(
      function() {
        return firstExpiration;
      },
      function() {
        assertEquals(2, cache.getCacheSize());
      }
  );

  // but now they are removed
  waitForCondition(
    function() {
      return secondExpiration;
    },
    function() {
      assertEquals(0, cache.getCacheSize());
    }
  );
}

/**
 * Test the cache correctly clone objects on both the 'put' and 'get' operations.
 */
function testSimpleCacheCloneObject() {

  var cache = new org.jboss.core.service.query.SimpleTimeCache(1);

  var model = { value: 'original' };
  cache.put('1', model);

  // change value in model object and test that the cached version
  // is intact and still keeps the original value
  {
    model.value = 'changed';
    var clone = cache.get('1');

    // references not equal
    assertTrue(model != clone);
    assertEquals('original', clone.value);
  }

  // change value of clone after it has been retrieved from the cache
  // and verify this does not affect future clones
  {
    clone.value = 'overridden';
    var nextClone = cache.get('1');

    // references not equal
    assertTrue(model != clone);
    assertEquals('original', nextClone.value);
  }

  goog.dispose(cache);
}
<|endoftext|>


<commit_before>(function () {
    var utils = {
        getIcon: function (question) {
            if (question.tag === 'upload') {
                return ' ';
            }
            return '';
        },
        getDisplay: function (question, MAXLEN) {
            return utils.getIcon(question) + utils.getLabel(question, MAXLEN)
                    + " (" + (question.hashtagValue || question.value) + ")";
        },
        getTruncatedDisplay: function (question, MAXLEN) {
            return utils.getIcon(question) + utils.getLabel(question, MAXLEN)
                    + " (" + utils.truncateValue(question.hashtagValue || question.value, MAXLEN) + ")";
        },
        getLabel: function (question, MAXLEN) {
            return utils.truncateLabel((question.repeat ? '- ' : '')
                    + question.label, question.tag === 'hidden' ? ' (Hidden)' : '', MAXLEN);
        },
        truncateLabel: function (label, suffix, MAXLEN) {
            suffix = suffix || "";
            var MAXLEN = MAXLEN || 40,
                maxlen = MAXLEN - suffix.length;
            return ((label.length <= maxlen) ? (label) : (label.slice(0, maxlen) + "...")) + suffix;
        },
        truncateValue: function (value, MAXLEN) {
            MAXLEN = MAXLEN || 40;
            return (value.length <= MAXLEN) ? (value) : (value.slice(0, MAXLEN / 2) + "..." + value.slice(value.length - MAXLEN / 2));
        },
    };

    ko.bindingHandlers.questionsSelect = {
        /*
            The value used with this binding should be in the form:
            [
                {value: "someValue", label: "someLabel"},
                ...
            ]
         */
        init: function (element, valueAccessor) {
            $(element).after('

');
        },
        update: function (element, valueAccessor, allBindingsAccessor) {
            var optionObjects = ko.utils.unwrapObservable(valueAccessor());
            var allBindings = ko.utils.unwrapObservable(allBindingsAccessor());
            var value = ko.utils.unwrapObservable(allBindings.value);
            var $warning = $(element).next();
            if (value && !_.some(optionObjects, function (option) {
                return option.value === value;
            })) {
                var option = {
                    label: 'Unidentified Question (' + value + ')',
                    value: value,
                };
                optionObjects = [option].concat(optionObjects);
                $warning.show().text('We cannot find this question in the allowed questions for this field. ' +
                    'It is likely that you deleted or renamed the question. ' +
                    'Please choose a valid question from the dropdown.');
            } else {
                $warning.hide();
            }
            _.delay(function () {
                $(element).select2({
                    placeholder: 'Select a Question',
                    data: {
                        results: _(optionObjects).map(function (o) {
                            return {id: o.value, text: utils.getDisplay(o), question: o};
                        }),
                    },
                    formatSelection: function (o) {
                        return utils.getTruncatedDisplay(o.question);
                    },
                    formatResult: function (o) {
                        return utils.getTruncatedDisplay(o.question, 90);
                    },
                    dropdownCssClass: 'bigdrop',
                });
            });
            allBindings.optstrText = utils.getLabel;
        },
    };
}());

ko.bindingHandlers.casePropertyAutocomplete = {
    /*
     * Strip "attachment:" prefix and show icon for attachment properties.
     * Replace any spaces in free text with underscores.
     */
    init: function (element, valueAccessor) {
        $(element).on('textchange', function () {
            var $el = $(this);
            if ($el.val().match(/\s/)) {
                var pos = $el.caret('pos');
                $el.val($el.val().replace(/\s/g, '_'));
                $el.caret('pos', pos);
            }
        });
        ko.bindingHandlers.autocompleteAtwho.init(element, valueAccessor);
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        function wrappedValueAccessor() {
            return _.map(ko.unwrap(valueAccessor()), function (value) {
                if (value.indexOf("attachment:") === 0) {
                    var text = value.substring(11),
                        html = ' ' + text;
                    return {name: text, content: html};
                }
                return {name: value, content: value};
            });
        }
        ko.bindingHandlers.autocompleteAtwho.update(element, wrappedValueAccessor, allBindingsAccessor);
    },
};

// Originally from http://stackoverflow.com/a/17998880
ko.extenders.withPrevious = function (target) {
    // Define new properties for previous value and whether it's changed
    target.previous = ko.observable();

    // Subscribe to observable to update previous, before change.
    target.subscribe(function (v) {
        target.previous(v);
    }, null, 'beforeChange');

    // Return modified observable
    return target;
};

ko.bindingHandlers.numericValue = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var underlyingObservable = valueAccessor();
        var interceptor = ko.dependentObservable({
            read: underlyingObservable,
            write: function (value) {
                if ($.isNumeric(value)) {
                    underlyingObservable(parseFloat(value));
                } else if (value === '') {
                    underlyingObservable(null);
                }
            },
        });
        ko.bindingHandlers.value.init(element, function () { return interceptor; }, allBindingsAccessor);
    },
    update: ko.bindingHandlers.value.update,
};
<commit_msg>Added translations<commit_after>(function () {
    var utils = {
        getIcon: function (question) {
            if (question.tag === 'upload') {
                return ' ';
            }
            return '';
        },
        getDisplay: function (question, MAXLEN) {
            return utils.getIcon(question) + utils.getLabel(question, MAXLEN)
                    + " (" + (question.hashtagValue || question.value) + ")";
        },
        getTruncatedDisplay: function (question, MAXLEN) {
            return utils.getIcon(question) + utils.getLabel(question, MAXLEN)
                    + " (" + utils.truncateValue(question.hashtagValue || question.value, MAXLEN) + ")";
        },
        getLabel: function (question, MAXLEN) {
            return utils.truncateLabel((question.repeat ? '- ' : '')
                    + question.label, question.tag === 'hidden' ? ' (Hidden)' : '', MAXLEN);
        },
        truncateLabel: function (label, suffix, MAXLEN) {
            suffix = suffix || "";
            var MAXLEN = MAXLEN || 40,
                maxlen = MAXLEN - suffix.length;
            return ((label.length <= maxlen) ? (label) : (label.slice(0, maxlen) + "...")) + suffix;
        },
        truncateValue: function (value, MAXLEN) {
            MAXLEN = MAXLEN || 40;
            return (value.length <= MAXLEN) ? (value) : (value.slice(0, MAXLEN / 2) + "..." + value.slice(value.length - MAXLEN / 2));
        },
    };

    ko.bindingHandlers.questionsSelect = {
        /*
            The value used with this binding should be in the form:
            [
                {value: "someValue", label: "someLabel"},
                ...
            ]
         */
        init: function (element, valueAccessor) {
            $(element).after('

');
        },
        update: function (element, valueAccessor, allBindingsAccessor) {
            var optionObjects = ko.utils.unwrapObservable(valueAccessor());
            var allBindings = ko.utils.unwrapObservable(allBindingsAccessor());
            var value = ko.utils.unwrapObservable(allBindings.value);
            var $warning = $(element).next();
            if (value && !_.some(optionObjects, function (option) {
                return option.value === value;
            })) {
                var option = {
                    label: gettext('Unidentified Question') + ' (' + value + ')',
                    value: value,
                };
                optionObjects = [option].concat(optionObjects);
                $warning.show().text(gettext('We cannot find this question in the allowed questions for this field. ' +
                    'It is likely that you deleted or renamed the question. ' +
                    'Please choose a valid question from the dropdown.'));
            } else {
                $warning.hide();
            }
            _.delay(function () {
                $(element).select2({
                    placeholder: gettext('Select a Question'),
                    data: {
                        results: _(optionObjects).map(function (o) {
                            return {id: o.value, text: utils.getDisplay(o), question: o};
                        }),
                    },
                    formatSelection: function (o) {
                        return utils.getTruncatedDisplay(o.question);
                    },
                    formatResult: function (o) {
                        return utils.getTruncatedDisplay(o.question, 90);
                    },
                    dropdownCssClass: 'bigdrop',
                });
            });
            allBindings.optstrText = utils.getLabel;
        },
    };
}());

ko.bindingHandlers.casePropertyAutocomplete = {
    /*
     * Strip "attachment:" prefix and show icon for attachment properties.
     * Replace any spaces in free text with underscores.
     */
    init: function (element, valueAccessor) {
        $(element).on('textchange', function () {
            var $el = $(this);
            if ($el.val().match(/\s/)) {
                var pos = $el.caret('pos');
                $el.val($el.val().replace(/\s/g, '_'));
                $el.caret('pos', pos);
            }
        });
        ko.bindingHandlers.autocompleteAtwho.init(element, valueAccessor);
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        function wrappedValueAccessor() {
            return _.map(ko.unwrap(valueAccessor()), function (value) {
                if (value.indexOf("attachment:") === 0) {
                    var text = value.substring(11),
                        html = ' ' + text;
                    return {name: text, content: html};
                }
                return {name: value, content: value};
            });
        }
        ko.bindingHandlers.autocompleteAtwho.update(element, wrappedValueAccessor, allBindingsAccessor);
    },
};

// Originally from http://stackoverflow.com/a/17998880
ko.extenders.withPrevious = function (target) {
    // Define new properties for previous value and whether it's changed
    target.previous = ko.observable();

    // Subscribe to observable to update previous, before change.
    target.subscribe(function (v) {
        target.previous(v);
    }, null, 'beforeChange');

    // Return modified observable
    return target;
};

ko.bindingHandlers.numericValue = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var underlyingObservable = valueAccessor();
        var interceptor = ko.dependentObservable({
            read: underlyingObservable,
            write: function (value) {
                if ($.isNumeric(value)) {
                    underlyingObservable(parseFloat(value));
                } else if (value === '') {
                    underlyingObservable(null);
                }
            },
        });
        ko.bindingHandlers.value.init(element, function () { return interceptor; }, allBindingsAccessor);
    },
    update: ko.bindingHandlers.value.update,
};
<|endoftext|>


<commit_before>//Mobile
var Mobile = datum.define({
    //Meta data of the class
    __meta: {
        name: 'Mobile'
    },

    //properties
    manufacturer: '',
    operatingSystem: '',
    model: '',
    cost: '',

    //Constructor
    constructor: function (manufacturer, operatingSystem, model, cost) {
        this.manufacturer = manufacturer;
        this.operatingSystem = operatingSystem;
        this.model = model;
        this.cost = cost;
    },

    //Methods
    getModel: function () {
        return this.model;
    },
    sendText: function(receiver, text){
        console.log('Text sent to ' + receiver);
    }
});

//Android
var Android = datum.define({
    //Meta data of the class
    __meta: {
        name: 'Android',
        extends: Mobile
    },

    //Constructor
    constructor: function (manufacturer, operatingSystem, model, cost) {
        this.base(manufacturer, operatingSystem, model, cost);
    },

    //Methods
    getModel: function () {
        return "This is Android Mobile - " + this.model;
    }
});

//Blackberry
var Blackberry = datum.define({
    //Meta data of the class
    __meta: {
        name: 'Blackberry',
        extends: Mobile
    },

    //Constructor
    constructor: function (manufacturer, operatingSystem, model, cost) {
        this.base(manufacturer, operatingSystem, model, cost);
    },

    //Methods
    getModel: function () {
        return "This is Android Blackberry - " + this.model;
    }
});

//Creating Object
var mobile = datum.create(Mobile, "Nokia", "Win8", "Lumia", 10000);

//Creating Object of Sublcass
var android = datum.create(Android, "Samsung", "Android", "Grand", 30000);
var blackberry = datum.create(Blackberry, "BlackB", "RIM", "Curve", 20000);

//Calling methods
console.log(mobile.getModel());
console.log(android.getModel());
console.log(blackberry.getModel());

mobile.sendText('Chloe', "Hello Chloe, How are you?");
android.sendText('Smith', "Hello Smith, How are you?");
blackberry.sendText('Brayan', "Hello Brayan, How are you?");<commit_msg>Modifying sample.js<commit_after>//Mobile
var Mobile = datum.define({
    //Meta data of the class
    __meta: {
        name: 'Mobile'
    },

    //properties
    manufacturer: '',
    operatingSystem: '',
    model: '',
    cost: '',

    //Constructor
    constructor: function (manufacturer, operatingSystem, model, cost) {
        this.manufacturer = manufacturer;
        this.operatingSystem = operatingSystem;
        this.model = model;
        this.cost = cost;
    },

    //Methods
    getModel: function () {
        return this.model;
    },
    sendText: function(receiver, text){
        console.log('Text sent to ' + receiver);
    }
});

//Android
var Android = datum.define({
    //Meta data of the class
    __meta: {
        name: 'Android',
        extends: Mobile
    },

    //Constructor
    constructor: function (manufacturer, operatingSystem, model, cost) {
        this.base(manufacturer, operatingSystem, model, cost);
    },

    //Methods
    getModel: function () {
        return "This is Android Mobile - " + this.model;
    }
});

//Blackberry
var Blackberry = datum.define({
    //Meta data of the class
    __meta: {
        name: 'Blackberry',
        extends: Mobile
    },

    //Constructor
    constructor: function (manufacturer, operatingSystem, model, cost) {
        this.base(manufacturer, operatingSystem, model, cost);
    },

    //Methods
    getModel: function () {
        return "This is Android Blackberry - " + this.base.getModel();
    }
});

//Creating Object
var mobile = datum.create(Mobile, "Nokia", "Win8", "Lumia", 10000);

//Creating Object of Sublcass
var android = datum.create(Android, "Samsung", "Android", "Grand", 30000);
var blackberry = datum.create(Blackberry, "BlackB", "RIM", "Curve", 20000);

//Calling methods
console.log(mobile.getModel());
console.log(android.getModel());
console.log(blackberry.getModel());

mobile.sendText('Chloe', "Hello Chloe, How are you?");
android.sendText('Smith', "Hello Smith, How are you?");
blackberry.sendText('Brayan', "Hello Brayan, How are you?");<|endoftext|>


<commit_before>const pogobuf = require('pogobuf'),
      POGOProts = require('node-pogo-protos'),
      bluebird = require('bluebird'),
      Long = require('long');

const lat = 45.510798,
      lon = 12.234108;

const pokemonList = require('./data/pokemon.json');

function alphabetic(a, b){
	var na = pokemonList[a.pokemon_id].name;
	var nb = pokemonList[b.pokemon_id].name;
	if(na < nb) return -1;
	if(na > nb) return 1;
	return 0;
}

function cp(a, b){
	if(a.cp > b.cp) return -1;
	if(a.cp < b.cp) return 1;
	return 0;
}

function iv(a, b){
	var tota = a.individual_attack + a.individual_defense + a.individual_stamina;
	var totb = b.individual_attack + b.individual_defense + b.individual_stamina;

	if(tota > totb) return -1;
	if(tota < totb) return 1;
	return 0;
}

function number(a, b){
	if(a.pokemon_id < b.pokemon_id) return -1;
	if(a.pokemon_id > b.pokemon_id) return 1;
	return 0;
}

function printData(data){
	var atk = data.individual_attack;
	var dfs = data.individual_defense;
	var stm = data.individual_stamina;

	console.log('+--------------------------');
	console.log('POKEMON: ' + pokemonList[data.pokemon_id].name);
	console.log('CP: ' + data.cp);
	console.log('Attack: ' + atk);
	console.log('Defense: ' + dfs);
	console.log('Stamina: ' + stm);

	var IV = (atk + dfs + stm)/0.45;
	console.log('IV: ' + IV + '%');
	console.log('');
}

var argv = require('minimist')(process.argv.slice(2));

if(!argv.u){
	console.log('You should specify a username using: -u <yourUsername>');
	process.exit(1);
}
if(!argv.p){
	console.log('You should specify a password using: -p <yourPassword>');
	process.exit(1);
}
var login, loginMethod;
if(argv.a){
	if(argv.a === 'ptc'){
		login = new pogobuf.PTCLogin();
		loginMethod = 'ptc';
	} else if(argv.a === 'google'){
		login = new pogobuf.GoogleLogin();
		loginMethod = 'google';
	} else {
		console.log('ERROR, you specified an invalid login method. Current valid method are ptc or google');
	}
} else {
	console.log('No login method specified, using PTC as default');
	login = new pogobuf.PTCLogin();
	loginMethod = 'ptc';
}

var order = cp;
var o = argv.o;
if(o){
	if(o === 'ab' || o === 'alphabetic'){
		order = alphabetic;
	} else if(o === 'cp'){
		order = cp;
	} else if(o === 'iv' || o === 'IV'){
		order = iv;
	} else if(o === 'n' || o === 'number'){
		order = number;
	} else {
		console.log('Order method not supported');
		process.exit(2);
	}

}
var pkmns = [];

var client = new pogobuf.Client();
login.login(argv.u, argv.p)
.then(token => {
    client.setAuthInfo(loginMethod, token);
    client.setPosition(lat, lon);
    return client.init();
}).then(() => {
    console.log('login successful');
    // Make some API calls!
    return client.getInventory(0);
}, (err)=>{console.log(err);}).then(inventory => {
	inventory.inventory_delta.inventory_items.forEach((item) =>{
	var data = item.inventory_item_data.pokemon_data;
		if(data!==null && !data.is_egg){
			pkmns.push(data);
		}
	});
	pkmns.sort(order);
	pkmns.forEach((pk)=>{
		printData(pk);
	});
/*try{
	setInterval(()=>{
		var cellIDs = pogobuf.Utils.getCellIDs(lat,lon);
		return bluebird.resolve(client.getMapObjects(cellIDs, Array(cellIDs.length).fill(0))).then(mapObjects => {return mapObjects.map_cells;
}).each(cell => {
	console.log(cell.s2_cell_id.toString());
	console.log('Has ' + cell.catchable_pokemons.length + ' catchable Pokemon');
	return bluebird.resolve(cell.catchable_pokemons).each(catchablePokemon=>{
		console.log(' - A ' + pogobuf.Utils.getEnumKeyByValue(POGOProtos.Enums.PokemonId, catchablePokemon.pokemon_id));
	});
	});
	}, 10*1000);
} catch(e){
	console.log(e);
}*/
    // Use the returned data
});
<commit_msg>Removed fixed location, added parameter -l<commit_after>const pogobuf = require('pogobuf'),
      POGOProts = require('node-pogo-protos'),
      bluebird = require('bluebird'),
      Long = require('long');

/*const lat = 45.510798,
      lon = 12.234108;*/

const pokemonList = require('./data/pokemon.json');

function alphabetic(a, b){
	var na = pokemonList[a.pokemon_id].name;
	var nb = pokemonList[b.pokemon_id].name;
	if(na < nb) return -1;
	if(na > nb) return 1;
	return 0;
}

function cp(a, b){
	if(a.cp > b.cp) return -1;
	if(a.cp < b.cp) return 1;
	return 0;
}

function iv(a, b){
	var tota = a.individual_attack + a.individual_defense + a.individual_stamina;
	var totb = b.individual_attack + b.individual_defense + b.individual_stamina;

	if(tota > totb) return -1;
	if(tota < totb) return 1;
	return 0;
}

function number(a, b){
	if(a.pokemon_id < b.pokemon_id) return -1;
	if(a.pokemon_id > b.pokemon_id) return 1;
	return 0;
}

function printData(data){
	var atk = data.individual_attack;
	var dfs = data.individual_defense;
	var stm = data.individual_stamina;

	console.log('+--------------------------');
	console.log('POKEMON: ' + pokemonList[data.pokemon_id].name);
	console.log('CP: ' + data.cp);
	console.log('Attack: ' + atk);
	console.log('Defense: ' + dfs);
	console.log('Stamina: ' + stm);

	var IV = (atk + dfs + stm)/0.45;
	console.log('IV: ' + IV + '%');
	console.log('');
}

var argv = require('minimist')(process.argv.slice(2));

if(!argv.u){
	console.log('You should specify a username using: -u <yourUsername>');
	process.exit(1);
}
if(!argv.p){
	console.log('You should specify a password using: -p <yourPassword>');
	process.exit(1);
}
var login, loginMethod;
if(argv.a){
	if(argv.a === 'ptc'){
		login = new pogobuf.PTCLogin();
		loginMethod = 'ptc';
	} else if(argv.a === 'google'){
		login = new pogobuf.GoogleLogin();
		loginMethod = 'google';
	} else {
		console.log('ERROR, you specified an invalid login method. Current valid method are ptc or google');
	}
} else {
	console.log('No login method specified, using PTC as default');
	login = new pogobuf.PTCLogin();
	loginMethod = 'ptc';
}

var order = cp;
var o = argv.o;
if(o){
	if(o === 'ab' || o === 'alphabetic'){
		order = alphabetic;
	} else if(o === 'cp'){
		order = cp;
	} else if(o === 'iv' || o === 'IV'){
		order = iv;
	} else if(o === 'n' || o === 'number'){
		order = number;
	} else {
		console.log('Order method not supported');
		process.exit(2);
	}

}

var loc = null;
var lat,lon;
if(argv.l){
	var split = argv.l.split(', ');
	if(split.length !== 2){
		split = argv.l.split(' ');
	}
	if(split.length !== 2){
		console.log('ERROR, coord format not valid. A valid format is: "45.000, 12.0000" or "45.0000 12.0000"');
		process.exit(3);
	}
	lat = parseFloat(split[0]);
	lon = parseFloat(split[1]);
}
var pkmns = [];

var client = new pogobuf.Client();
login.login(argv.u, argv.p)
.then(token => {
	client.setAuthInfo(loginMethod, token);
	if(lat && lon){
		client.setPosition(lat, lon);
	}
    return client.init();
}).then(() => {
    console.log('login successful');
    // Make some API calls!
    return client.getInventory(0);
}, (err)=>{console.log(err);}).then(inventory => {
	inventory.inventory_delta.inventory_items.forEach((item) =>{
	var data = item.inventory_item_data.pokemon_data;
		if(data!==null && !data.is_egg){
			pkmns.push(data);
		}
	});
	pkmns.sort(order);
	pkmns.forEach((pk)=>{
		printData(pk);
	});
/*try{
	setInterval(()=>{
		var cellIDs = pogobuf.Utils.getCellIDs(lat,lon);
		return bluebird.resolve(client.getMapObjects(cellIDs, Array(cellIDs.length).fill(0))).then(mapObjects => {return mapObjects.map_cells;
}).each(cell => {
	console.log(cell.s2_cell_id.toString());
	console.log('Has ' + cell.catchable_pokemons.length + ' catchable Pokemon');
	return bluebird.resolve(cell.catchable_pokemons).each(catchablePokemon=>{
		console.log(' - A ' + pogobuf.Utils.getEnumKeyByValue(POGOProtos.Enums.PokemonId, catchablePokemon.pokemon_id));
	});
	});
	}, 10*1000);
} catch(e){
	console.log(e);
}*/
    // Use the returned data
});
<|endoftext|>