<commit_before>bbop.core.require('bbop', 'core');
bbop.core.require('bbop', 'model');
bbop.core.require('bbop', 'model', 'tree');
bbop.core.namespace('bbop', 'render', 'phylo');

var graph_pnode = function(context, label, px, py, height, internal){
    this.context = context;
    this.label = label;
    this.px = px;
    this.py = py;
    this.height = height;
    this.internal = internal;

    var node_elem = document.createElement("div");
    if( internal ){
        node_elem.title = label;
        node_elem.style.cssText =
            context.node_style + ";"
            + "left: " + px + "%;"
            + "top: " + py + "px;";
    }else{
        $(node_elem).append(document.createTextNode(label));
        node_elem.style.cssText =
            context.leaf_style + ";"
            + "left: " + px + "%;"
            + "top: " + (py - (height / 2)) + "px;";
    }
    this.node_elem = node_elem;
    context.container.appendChild(node_elem);
};

graph_pnode.prototype.set_parent = function(parent) {
    this.parent = parent;
    if ( this.conn_elem ) this.context.container.removeChild(this.conn_elem);
    var conn_elem = document.createElement("div");
    var this_style;
    if ( this.py < parent.py ) {
        // upward connection
        this_style = [
            "border-bottom: none",
            "top: " + this.py + "px",
            "left: " + parent.px + "%",
            "width: " + (this.px - parent.px) + "%",
            "height: " + (parent.py - this.py) + "px"
        ].join(";");
    }else{
        // downward connection
        this_style = [
            "border-top: none",
            "top: " + parent.py + "px",
            "left: " + parent.px + "%",
            "width: " + (this.px - parent.px) + "%",
            "height: " + (this.py - parent.py) + "px"
        ].join(";");
    }
    conn_elem.style.cssText = this.context.connection_style + ";" + this_style;
    this.context.container.appendChild(conn_elem);
};

bbop.render.phylo.renderer = function (element_id){
    var elt_id = element_id;
    this.parentElem = document.getElementById(elt_id);

    var renderer_context = this;

    this.box_height = 20;

    // these are in pixels
    this.font_height = 15;
    this.leaf_border = 2;
    this.leaf_padding = 5;

    this.node_style = [
        "position: absolute",
        "background: white",
        "z-index: 2",
        "width: 8px",
        "height: 8px",
        "margin-top: -4px",
        "margin-left: -4px",
        "border: 1px solid black"
    ].join(";");

    this.leaf_style = [
        "position: absolute",
        "background: #f1f1ff",
        "padding: " + this.leaf_padding + "px",
        "border: " + this.leaf_border + "px solid blue",
        "font: " + this.font_height + "px sans-serif",
        "height: " + this.box_height + "px",
        "border-radius: 5px"
    ].join(";");

    this.connection_style = [
        "position: absolute",
        "border-left: 2px solid black",
        "border-top: 2px solid black",
        "border-bottom: 2px solid black",
        "border-right: none"
    ].join(";");

    ///
    /// Functions to handle internal graph management.
    ///

    var node_cache_hash = {};
    this._graph = new bbop.model.tree.graph();

    //
    this.add_node = function(unique_id){
	var new_node = new bbop.model.tree.node(unique_id, unique_id);
	node_cache_hash[unique_id] = new_node;
	this._graph.add_node(new_node);
    };

    //
    this.add_edge = function(nid1, nid2, dist){

	var retval = false;

	var n1 = node_cache_hash[nid1];
	var n2 = node_cache_hash[nid2];
	if( n1 && n2 ){
	    var new_edge = new bbop.model.tree.edge(n1, n2, dist);
	    this._graph.add_edge(new_edge);
	    retval = true;
	}

	return retval;
    };

    this.display = function () {
	var layout = this._graph.layout();
        if (this.container) {
            this.parentElem.removeChild(this.container);
        }
        this.container = document.createElement("div");
        this.container.style.cssText = [
            "position: absolute",
            "top: 0px",
            "left: 0px",
            "margin: 0px",
            "padding: 0px"
        ].join(";");

	this._render_frame_width = this.parentElem.offsetWidth;

        // x_scale will be percentage units
	var x_scale = 100 / layout.max_distance;
	var y_scale = renderer_context.box_height * 2.0; // fixed y-scale

        var top_margin = (this.box_height / 2) + this.leaf_border;
        var total_box_height = this.box_height + (this.leaf_border * 2);

        this._render_frame_height = (layout.max_width * y_scale);

	// Add phynodes and create lookup (hash) for use with connections.
	var phynodes = new Array();
	var phynode_hash = {};
        var leaves = new Array();
	for( var nidi = 0; nidi < layout.node_list.length; nidi++ ){

	    // Calculate position.
	    var node_id = layout.node_list[nidi];
	    var lpx = (layout.position_x[node_id] * x_scale);
	    var lpy = (layout.position_y[node_id] * y_scale) + top_margin;

	    // Create node at place.
	    var phynode = null;
	    if( ! this._graph.is_leaf_node(node_id) ){
                phynode = new graph_pnode(this, node_id, lpx, lpy,
                                          total_box_height, true);
	    }else{
                phynode = new graph_pnode(this, node_id, lpx, lpy,
                                          total_box_height, false);
                leaves.push(phynode);
	    }

            phynodes.push(phynode);

	    // Indexing for later (edge) use.
	    phynode_hash[node_id] = nidi;
	}

	for( var ei = 0; ei < layout.edge_list.length; ei++ ){
	    var edge = layout.edge_list[ei];
	    var e0 = edge[0];
	    var e1 = edge[1];
            phynodes[phynode_hash[e1]].set_parent(
                phynodes[phynode_hash[e0]]
            );
        }

        this.parentElem.style.cssText =
            "height: " + this._render_frame_height + "px;";
        this.parentElem.appendChild(this.container);

        var max_leaf_width = 0;
        for ( var li = 0; li < leaves.length; li++ ){
            max_leaf_width = Math.max(
                leaves[li].node_elem.offsetWidth,
                max_leaf_width
            );
        }
        max_leaf_width += (2 * this.leaf_border) + (2 * this.leaf_padding) + 1;
        console.log("max leaf width " + max_leaf_width);
        console.log("frame width " + this._render_frame_width);

        this.container.style.height = this._render_frame_height + "px",
        this.container.style.width =
            (this._render_frame_width - max_leaf_width) + "px"
    }
};
<commit_msg>clean up<commit_after>bbop.core.require('bbop', 'core');
bbop.core.require('bbop', 'model');
bbop.core.require('bbop', 'model', 'tree');
bbop.core.namespace('bbop', 'render', 'phylo');

// see default_config for a description of possible config settings
bbop.render.phylo.renderer = function (element_id, config){
    var elt_id = element_id;
    this.parentElem = document.getElementById(elt_id);

    var default_config = {
        // these are in pixels
        // height of the leaf node box, excluding border
        box_height: 27,
        // vertical space between leaf boxes
        box_spacing: 15,
        // space between leaf box edge and leaf label
        leaf_padding: 5,
        // leaf border thickness
        leaf_border: 2,

        // leaf border color
        leaf_border_color: "blue",
        // font for leaf labels
        // if you set this, you probably also want to change
        // box_height or leaf_padding
        leaf_font: "16px sans-serif"
    };

    this.config = ("object" == typeof config
                   ? bop.core.merge(default_config, config)
                   : default_config);

    this.node_style = {
        position: "absolute",
        background: "white",
        "z-index": 2,
        width: "8px",
        height: "8px",
        "margin-top": "-4px",
        "margin-left": "-4px",
        border: "1px solid black"
    };

    this.leaf_style = {
        position: "absolute",
        background: "#f1f1ff",
        padding: this.config.leaf_padding + "px",
        font: this.config.leaf_font,
        height: this.config.box_height - (2 * this.config.leaf_padding) + "px",
        "border-radius": "5px"
    };

    if( this.config.leaf_border > 0 ){
        this.leaf_style.border =
            this.config.leaf_border + "px solid "
            + this.config.leaf_border_color;
    }

    this.connection_style = {
        position: "absolute",
        "border-left": "2px solid black",
        "border-top": "2px solid black",
        "border-bottom": "2px solid black",
        "border-right": "none"
    };

    ///
    /// Functions to handle internal graph management.
    ///

    var node_cache_hash = {};
    this._graph = new bbop.model.tree.graph();

    this.add_node = function(unique_id){
	var new_node = new bbop.model.tree.node(unique_id, unique_id);
	node_cache_hash[unique_id] = new_node;
	this._graph.add_node(new_node);
    };

    this.add_edge = function(nid1, nid2, dist){

	var retval = false;

	var n1 = node_cache_hash[nid1];
	var n2 = node_cache_hash[nid2];
	if( n1 && n2 ){
	    var new_edge = new bbop.model.tree.edge(n1, n2, dist);
	    this._graph.add_edge(new_edge);
	    retval = true;
	}

	return retval;
    };

    this.display = function () {
	var layout = this._graph.layout();
        if( this.container ){
            this.parentElem.removeChild(this.container);
        }
        this.container = document.createElement("div");
        this.container.style.cssText = [
            "position: absolute",
            "top: 0px",
            "left: 0px",
            "margin: 0px",
            "padding: 0px"
        ].join(";") + ";";

	this._render_frame_width = this.parentElem.offsetWidth;

        // x_scale will be percentage units
	var x_scale = 100 / layout.max_distance;

        // y_scale is in pixel units
	var y_scale = this.config.box_height + this.config.box_spacing;

        // the position values from the tree layout are center
        // positions, and the very top one has a y-position of 0.
        // if a leaf node box is centered at that point, then the
        // top half of the top box would get cut off.  So we move
        // all of the positions down by top_margin pixels.
        var top_margin =
            (this.config.box_height / 2) + this.config.leaf_border;

        var total_box_height =
            this.config.box_height + (this.config.leaf_border * 2);

        this._render_frame_height = (layout.max_width * y_scale);

	// Add phynodes and create lookup (hash) for use with connections.
	var phynodes = new Array();
	var phynode_hash = {};
        var leaves = new Array();

        var node_style = css_string(this.node_style);
        var leaf_style = css_string(this.leaf_style);

	for( var nidi = 0; nidi < layout.node_list.length; nidi++ ){
	    // Calculate position.
	    var node_id = layout.node_list[nidi];
	    var lpx = (layout.position_x[node_id] * x_scale);
	    var lpy = (layout.position_y[node_id] * y_scale) + top_margin;

	    // Create node at place.
	    var phynode = null;
	    if( ! this._graph.is_leaf_node(node_id) ){
                phynode = new graph_pnode(node_id, lpx, lpy,
                                          node_style, leaf_style,
                                          total_box_height, true);
                this.container.appendChild(phynode.node_elem);
	    }else{
                phynode = new graph_pnode(node_id, lpx, lpy,
                                          node_style, leaf_style,
                                          total_box_height, false);
                this.container.appendChild(phynode.node_elem);
                leaves.push(phynode);
	    }

            phynodes.push(phynode);

	    // Indexing for later (edge) use.
	    phynode_hash[node_id] = nidi;
	}

        var conn_style = css_string(this.connection_style);
	for( var ei = 0; ei < layout.edge_list.length; ei++ ){
	    var edge = layout.edge_list[ei];
            var child_phynode = phynodes[phynode_hash[edge[1]]];
            child_phynode.set_parent(
                phynodes[phynode_hash[edge[0]]],
                conn_style
            );
            this.container.appendChild(child_phynode.conn_elem);
        }

        this.parentElem.style.cssText =
            "height: " + this._render_frame_height + "px;";
        this.parentElem.appendChild(this.container);

        var max_leaf_width = 0;
        for( var li = 0; li < leaves.length; li++ ){
            max_leaf_width = Math.max(
                leaves[li].node_elem.offsetWidth,
                max_leaf_width
            );
        }
        max_leaf_width =
            max_leaf_width
            + (2 * this.config.leaf_border)
            + (2 * this.config.leaf_padding) + 1;

        this.container.style.height = this._render_frame_height + "px",
        this.container.style.width =
            (this._render_frame_width - max_leaf_width) + "px"
    }

    //
    // graphical representation of a phylo node
    //

    var graph_pnode = function(label, px, py,
                               node_style, leaf_style,
                               height, is_internal){
        this.label = label;
        this.px = px;
        this.py = py;
        this.height = height;
        this.is_internal = is_internal;

        var node_elem = document.createElement("div");
        if( is_internal ){
            node_elem.title = label;
            node_elem.style.cssText =
                node_style + ";"
                + "left: " + px + "%;"
                + "top: " + py + "px;";
        }else{
            node_elem.appendChild(document.createTextNode(label));
            node_elem.style.cssText =
                leaf_style + ";"
                + "left: " + px + "%;"
            // move the top coord of the box up by height/2;
            // this makes the box vertically centered on the given
            // (px, py) position
                + "top: " + (py - (height / 2)) + "px;";
        }
        this.node_elem = node_elem;
    };

    graph_pnode.prototype.set_parent = function(parent, conn_style) {
        this.parent = parent;
        this.conn_elem = document.createElement("div");

        var this_style =
            "top: " + Math.min(parent.py, this.py) + "px;"
            + "left: " + parent.px + "%;"
            + "width: " + (this.px - parent.px) + "%;"
            + "height: " + Math.abs(parent.py - this.py) + "px;";

        if( this.py < parent.py ){
            // upward connection
            this_style += "border-bottom: none;";
        }else{
            // downward connection
            this_style += "border-top: none;";
        }
        this.conn_elem.style.cssText = conn_style + this_style;
    };

    ///
    /// Util functions
    ///

    // takes an object like {"top": "10px", "left": "5px"}
    // and return a string like "top: 10px; left: 5px;"
    function css_string(css_object) {
        var result = "";
        if( "object" == typeof css_object ){
            for( var key in css_object ){
                result += key + ":" + css_object[key] + ";";
            }
        }
        return result;
    }
};
<|endoftext|>


<commit_before>// Many utils inlined from Underscore.js
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors

export var slice = Array.prototype.slice;
export var toString = Object.prototype.toString;

function _extend(target, extensions, undefined_only) {
  for (var i = 0, length = extensions.length; i < length; i++) {
    for (var key in extensions[i]) {
      if (!undefined_only || target[key] === void 0)
        target[key] = extensions[i][key];
    }
  }

  return target;
}

export function contains(arr, item) {
  return arr.indexOf(item) >= 0;
}

export function compact(arr) {
  return arr.filter(function(item) {
    return item;
  });
}

export function difference(a, b) {
  return a.filter(function(value) {
    return b.indexOf(value) < 0;
  });
}

export function defaults(target) {
  return _extend(target, slice.call(arguments, 1), true);
}

export function extend(target) {
  return _extend(target, slice.call(arguments, 1));
}

export function flatten(arr) {
  // Assumes all items in arr are arrays and only flattens one level
  return arr.reduce(function(memo, item) {
    return memo.concat(item);
  }, []);
}

export function find(arr, fn, context) {
  if (!arr) return;
  for (var i = 0, length = arr.length; i < length; i++) {
    if (fn.call(context, arr[i], i, arr))
      return arr[i];
  }
}

export function first(arr, n) {
  if (arr == null) return void 0;
  if (n == null) return arr[0];
  return Array.prototype.slice.call(arr, 0, n);
}

export function isBoolean(obj) {
  return obj === true || obj === false;
}
export function isObject(obj) {
  var type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
}
export function isNumber(obj) {
  return toString.call(obj) === '[object Number]';
}
export function isString(obj) {
  return toString.call(obj) === '[object String]';
}
export function isUndefined(obj) {
  return obj === void 0;
}

export var isFunction = function(obj) {
  return toString.call(obj) === '[object Function]';
};
if (typeof /./ != 'function' && typeof Int8Array != 'object') {
  isFunction = function(obj) {
    return typeof obj == 'function' || false;
  };
}

export function objectEach(obj, fn, context) {
  if (!obj) return;
  var keys = Object.keys(obj);
  for (var i = 0, length = keys.length; i < length; i++) {
    fn.call(context, obj[keys[i]], keys[i], obj);
  }
}

export function objectFind(obj, fn, context) {
  if (!obj) return;
  var keys = Object.keys(obj);
  for (var i = 0, length = keys.length; i < length; i++) {
    if (fn.call(context, obj[keys[i]], keys[i], obj))
      return obj[keys[i]];
  }
}

export function pluck(objs, key) {
  if (!objs) return [];
  return objs.map(function(obj) {
    return obj[key];
  });
}

export function uniq(arr) {
  var result = [];
  for (var i = 0, length = arr.length; i < length; i++) {
    if (result.indexOf(arr[i]) < 0)
      result.push(arr[i]);
  }
  return result;
}

export function inherits(Child, Parent) {
  Child.prototype = Object.create(Parent.prototype, {
    constructor: {
      value: Child,
      enumerable: false,
      writeable: true,
      configurable: true
    }
  });

  if (Object.setPrototypeOf)
    Object.setPrototypeOf(Child, Parent);
  else
    Child.__proto__ = Parent; //eslint-disable-line no-proto
}

// If value isn't `undefined`, return `value`, otherwise use `default_value`
//
// @method valueOrDefault
// @param {Any} [value]
// @param {Any} default_value
// @return {Any}
export function valueOrDefault(value, default_value) {
  return !isUndefined(value) ? value : default_value;
}

var utils = {
  slice: slice,
  toString: toString,
  contains: contains,
  compact: compact,
  difference: difference,
  defaults: defaults,
  extend: extend,
  flatten: flatten,
  find: find,
  first: first,
  isBoolean: isBoolean,
  isFunction: isFunction,
  isObject: isObject,
  isNumber: isNumber,
  isString: isString,
  isUndefined: isUndefined,
  objectEach: objectEach,
  objectFind: objectFind,
  pluck: pluck,
  uniq: uniq,
  inherits: inherits,
  valueOrDefault: valueOrDefault
};
export default utils;
<commit_msg>Add fix for __proto__ for IE<commit_after>// Many utils inlined from Underscore.js
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors

export var slice = Array.prototype.slice;
export var toString = Object.prototype.toString;

function _extend(target, extensions, undefined_only) {
  for (var i = 0, length = extensions.length; i < length; i++) {
    for (var key in extensions[i]) {
      if (!undefined_only || target[key] === void 0)
        target[key] = extensions[i][key];
    }
  }

  return target;
}

export function contains(arr, item) {
  return arr.indexOf(item) >= 0;
}

export function compact(arr) {
  return arr.filter(function(item) {
    return item;
  });
}

export function difference(a, b) {
  return a.filter(function(value) {
    return b.indexOf(value) < 0;
  });
}

export function defaults(target) {
  return _extend(target, slice.call(arguments, 1), true);
}

export function extend(target) {
  return _extend(target, slice.call(arguments, 1));
}

export function flatten(arr) {
  // Assumes all items in arr are arrays and only flattens one level
  return arr.reduce(function(memo, item) {
    return memo.concat(item);
  }, []);
}

export function find(arr, fn, context) {
  if (!arr) return;
  for (var i = 0, length = arr.length; i < length; i++) {
    if (fn.call(context, arr[i], i, arr))
      return arr[i];
  }
}

export function first(arr, n) {
  if (arr == null) return void 0;
  if (n == null) return arr[0];
  return Array.prototype.slice.call(arr, 0, n);
}

export function isBoolean(obj) {
  return obj === true || obj === false;
}
export function isObject(obj) {
  var type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
}
export function isNumber(obj) {
  return toString.call(obj) === '[object Number]';
}
export function isString(obj) {
  return toString.call(obj) === '[object String]';
}
export function isUndefined(obj) {
  return obj === void 0;
}

export var isFunction = function(obj) {
  return toString.call(obj) === '[object Function]';
};
if (typeof /./ != 'function' && typeof Int8Array != 'object') {
  isFunction = function(obj) {
    return typeof obj == 'function' || false;
  };
}

export function objectEach(obj, fn, context) {
  if (!obj) return;
  var keys = Object.keys(obj);
  for (var i = 0, length = keys.length; i < length; i++) {
    fn.call(context, obj[keys[i]], keys[i], obj);
  }
}

export function objectFind(obj, fn, context) {
  if (!obj) return;
  var keys = Object.keys(obj);
  for (var i = 0, length = keys.length; i < length; i++) {
    if (fn.call(context, obj[keys[i]], keys[i], obj))
      return obj[keys[i]];
  }
}

export function pluck(objs, key) {
  if (!objs) return [];
  return objs.map(function(obj) {
    return obj[key];
  });
}

export function uniq(arr) {
  var result = [];
  for (var i = 0, length = arr.length; i < length; i++) {
    if (result.indexOf(arr[i]) < 0)
      result.push(arr[i]);
  }
  return result;
}

export function inherits(Child, Parent) {
  Child.prototype = Object.create(Parent.prototype, {
    constructor: {
      value: Child,
      enumerable: false,
      writeable: true,
      configurable: true
    }
  });

  if (Object.setPrototypeOf) {
    Object.setPrototypeOf(Child, Parent);
  }
  else {
    Child.__proto__ = Parent; //eslint-disable-line no-proto

    // __proto__ isn't supported in IE,
    // use one-time copy of static properties to approximate
    defaults(Child, Parent);
  }
}

// If value isn't `undefined`, return `value`, otherwise use `default_value`
//
// @method valueOrDefault
// @param {Any} [value]
// @param {Any} default_value
// @return {Any}
export function valueOrDefault(value, default_value) {
  return !isUndefined(value) ? value : default_value;
}

var utils = {
  slice: slice,
  toString: toString,
  contains: contains,
  compact: compact,
  difference: difference,
  defaults: defaults,
  extend: extend,
  flatten: flatten,
  find: find,
  first: first,
  isBoolean: isBoolean,
  isFunction: isFunction,
  isObject: isObject,
  isNumber: isNumber,
  isString: isString,
  isUndefined: isUndefined,
  objectEach: objectEach,
  objectFind: objectFind,
  pluck: pluck,
  uniq: uniq,
  inherits: inherits,
  valueOrDefault: valueOrDefault
};
export default utils;
<|endoftext|>


<commit_before>const fs = require('fs')
const path = require('path')
const prettierx = require('prettierx')
const { getSupportInfo } = prettierx
const ignore = require('ignore')

const extensions = {}

getSupportInfo()
  .languages.reduce(
    (prev, language) => prev.concat(language.extensions || []),
    []
  )
  .forEach(e => (extensions[e] = true))

function isSupportedExtension (file) {
  return extensions[path.extname(file)] || false
}

function createIgnorer (directory, filename = '.prettierignore') {
  const file = path.join(directory, filename)
  if (fs.existsSync(file)) {
    const text = fs.readFileSync(file, 'utf8')
    return ignore()
      .add(text)
      .createFilter()
  }

  return () => true
}

const defaultOptions = {
  spaceBeforeFunctionParen: true,
  generatorStarSpacing: true,
  yieldStarSpacing: true,
  singleQuote: true,
  semi: false,
  jsxSingleQuote: true,
  alignTernaryLines: false
}

function getOptions (options) {
  const final = Object.assign({}, defaultOptions, options)

  if (!final.filepath || (final.filepath === '(stdin)' && !final.parser)) {
    final.parser = 'babel'
  }

  return final
}

module.exports = {
  isSupportedExtension,
  createIgnorer,
  getOptions
}
<commit_msg>Rollback trenary formatting<commit_after>const fs = require('fs')
const path = require('path')
const prettierx = require('prettierx')
const { getSupportInfo } = prettierx
const ignore = require('ignore')

const extensions = {}

getSupportInfo()
  .languages.reduce(
    (prev, language) => prev.concat(language.extensions || []),
    []
  )
  .forEach(e => (extensions[e] = true))

function isSupportedExtension (file) {
  return extensions[path.extname(file)] || false
}

function createIgnorer (directory, filename = '.prettierignore') {
  const file = path.join(directory, filename)
  if (fs.existsSync(file)) {
    const text = fs.readFileSync(file, 'utf8')
    return ignore()
      .add(text)
      .createFilter()
  }

  return () => true
}

const defaultOptions = {
  spaceBeforeFunctionParen: true,
  generatorStarSpacing: true,
  yieldStarSpacing: true,
  singleQuote: true,
  semi: false,
  jsxSingleQuote: true
}

function getOptions (options) {
  const final = Object.assign({}, defaultOptions, options)

  if (!final.filepath || (final.filepath === '(stdin)' && !final.parser)) {
    final.parser = 'babel'
  }

  return final
}

module.exports = {
  isSupportedExtension,
  createIgnorer,
  getOptions
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Novedia Group 2012.
 *
 *     This file is part of Hubiquitus.
 *
 *     Hubiquitus is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     Hubiquitus is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with Hubiquitus.  If not, see <http://www.gnu.org/licenses/>.
 */

var log = require('winston');

var status = require('../codes.js').hResultStatus;
var xmlElement = require('node-xmpp').Element;
var db = require('../mongo.js').db;
var xmppConnection = require('../server_connectors/xmpp_hnode.js').ServerConnection;

var hUnsubscribe = function(){
};

/**
 * Unsubscribes a publisher from a channel.
 * @param hCommand - hCommand received with cmd = 'hUnsubscribe'
 * @param context - Auxiliary functions,attrs from the controller/ db models.
 * @param cb(status, result) - function that receives args:
 *    status: //Constant from var status to indicate the result of the hCommand
 *    result: undefined if ok.
 */
hUnsubscribe.prototype.exec = function(hCommand, context, cb){
    var self = this;

    if( !hCommand.params )
        return cb(status.MISSING_ATTR, 'missing params object');

    var chid = hCommand.params.chid;

    if( !chid )
        return cb(status.MISSING_ATTR, 'missing chid');

    var channel = db.cache.hChannels[chid];

    if( !channel )
        return cb(status.NOT_AUTHORIZED, 'chid does not exist');

    if(channel.active == false)
        return cb(status.NOT_AUTHORIZED, 'inactive channel');

    //Removing resource
    var user = hCommand.sender.replace(/\/.*/,'');
    db.get('hSubscriptions').findOne({_id: user, subs: chid}, function(err, doc){
        if(!err && doc)
            db._updater(db.get('hSubscriptions'), {_id: user}, {$pull: {subs: chid}}, function(err, result){
                if(!err)
                    self.XMPPUnsubscribe(channel, user, cb);
                else
                    return cb(err, result);
            });

        else if(!doc) //Doesn't exist in collection or not found in array, so it does not have subscriptions
            return cb(status.NOT_AUTHORIZED, 'user not subscribed to channel');

        else
            return cb(err, result);
    });
};

/**
 * Unsubscribes the user from the XMPP Node.
 * @param chid - Channel to unsubscribe from
 * @param jid - JID of the user to unsubscribe
 * @param cb - Executed when finished, receives err or nothing
 */
hUnsubscribe.prototype.XMPPUnsubscribe = function(chid, jid, cb){

    var attrs = {
        type: 'set',
        to: 'pubsub.' + xmppConnection.domain
    };

    var content = new xmlElement('pubsub', {xmlns: 'http://jabber.org/protocol/pubsub#owner'})
        .c('subscriptions', {node: chid})
        .c('subscription', {jid: jid, subscription: 'none'});

    xmppConnection.sendIQ(attrs, content, function(stanza){
        cb(status.OK);
    });
};

exports.Command = hUnsubscribe;<commit_msg>Fix error when sending XMPP unsubscribe message<commit_after>/*
 * Copyright (c) Novedia Group 2012.
 *
 *     This file is part of Hubiquitus.
 *
 *     Hubiquitus is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     Hubiquitus is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with Hubiquitus.  If not, see <http://www.gnu.org/licenses/>.
 */

var log = require('winston');

var status = require('../codes.js').hResultStatus;
var xmlElement = require('node-xmpp').Element;
var db = require('../mongo.js').db;
var xmppConnection = require('../server_connectors/xmpp_hnode.js').ServerConnection;

var hUnsubscribe = function(){
};

/**
 * Unsubscribes a publisher from a channel.
 * @param hCommand - hCommand received with cmd = 'hUnsubscribe'
 * @param context - Auxiliary functions,attrs from the controller/ db models.
 * @param cb(status, result) - function that receives args:
 *    status: //Constant from var status to indicate the result of the hCommand
 *    result: undefined if ok.
 */
hUnsubscribe.prototype.exec = function(hCommand, context, cb){
    var self = this;

    if( !hCommand.params )
        return cb(status.MISSING_ATTR, 'missing params object');

    var chid = hCommand.params.chid;

    if( !chid )
        return cb(status.MISSING_ATTR, 'missing chid');

    var channel = db.cache.hChannels[chid];

    if( !channel )
        return cb(status.NOT_AUTHORIZED, 'chid does not exist');

    if(channel.active == false)
        return cb(status.NOT_AUTHORIZED, 'inactive channel');

    //Removing resource
    var user = hCommand.sender.replace(/\/.*/,'');
    db.get('hSubscriptions').findOne({_id: user, subs: chid}, function(err, doc){
        if(!err && doc)
            db._updater(db.get('hSubscriptions'), {_id: user}, {$pull: {subs: chid}}, function(err, result){
                if(!err)
                    self.XMPPUnsubscribe(chid, user, cb);
                else
                    return cb(err, result);
            });

        else if(!doc) //Doesn't exist in collection or not found in array, so it does not have subscriptions
            return cb(status.NOT_AUTHORIZED, 'user not subscribed to channel');

        else
            return cb(err, result);
    });
};

/**
 * Unsubscribes the user from the XMPP Node.
 * @param chid - Channel to unsubscribe from
 * @param jid - JID of the user to unsubscribe
 * @param cb - Executed when finished, receives err or nothing
 */
hUnsubscribe.prototype.XMPPUnsubscribe = function(chid, jid, cb){

    var attrs = {
        type: 'set',
        to: 'pubsub.' + xmppConnection.domain
    };

    var content = new xmlElement('pubsub', {xmlns: 'http://jabber.org/protocol/pubsub#owner'})
        .c('subscriptions', {node: chid})
        .c('subscription', {jid: jid, subscription: 'none'});

    xmppConnection.sendIQ(attrs, content, function(stanza){
        cb(status.OK);
    });
};

exports.Command = hUnsubscribe;<|endoftext|>


<commit_before>'use strict';

var deepEqual = require('deep-equal');

// This implementation of debounce was taken from the blog of David Walsh.
// See here: https://davidwalsh.name/javascript-debounce-function
module.exports.debounce = function debounce(func, wait, immediate) {
  var timeout;

  return function () {
    var context = this;
    var args = arguments;
    var later = function () {
      timeout = null;
      if (!immediate) {
        func.apply(context, args);
      }
    };

    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) {
      func.apply(context, args);
    }
  };
};

module.exports.format = function (template) {
  var args = Array.prototype.slice.call(arguments, 1);
  return template.replace(/{(\d+)}/g, function (match, number) {
    return typeof args[number] != 'undefined' ? args[number] : match;
  });
};

module.exports.isArray = function isArray(arg) {
  if (typeof Array.isArray === 'function') {
    return Array.isArray(arg);
  }

  return Object.prototype.toString.call(arg) === '[object Array]';
};

module.exports.isEmpty = function (value) {
  if (module.exports.isArray(value)) {
    return !value.length;
  } else if (value === undefined || value === null) {
    return true;
  } else {
    return !String(value).trim().length;
  }
};

module.exports.isEqual = function isEqual(o1, o2) {
  return deepEqual(o1, o2);
};

module.exports.isFunction = function isFunction(arg) {
  return typeof arg === 'function';
};

module.exports.isNaN = function isNaN(arg) {
  return arg !== arg;
};

module.exports.isNull = function isNull(arg) {
  return arg === null;
};

module.exports.isString = function isString(arg) {
  return typeof arg === 'string' || arg instanceof String;
};

module.exports.isUndefined = function isUndefined(arg) {
  return typeof arg === 'undefined';
};

module.exports.omit = function omit(obj, key) {
  var result = {};

  for (var name in obj) {
    if (name !== key) {
      result[name] = obj[name];
    }
  }

  return result;
};

module.exports.templates = require('./templates');

module.exports.mode = 'interactive'; // other values: conservative and manual

<commit_msg>float fix<commit_after>'use strict';

var deepEqual = require('deep-equal');

// This implementation of debounce was taken from the blog of David Walsh.
// See here: https://davidwalsh.name/javascript-debounce-function
module.exports.debounce = function (func, wait, immediate) {
  var timeout;

  return function () {
    var context = this;
    var args = arguments;
    var later = function () {
      timeout = null;
      if (!immediate) {
        func.apply(context, args);
      }
    };

    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) {
      func.apply(context, args);
    }
  };
};

module.exports.format = function (template) {
  var args = Array.prototype.slice.call(arguments, 1);
  return template.replace(/{(\d+)}/g, function (match, number) {
    return typeof args[number] != 'undefined' ? args[number] : match;
  });
};

module.exports.isArray = function (arg) {
  if (typeof Array.isArray === 'function') {
    return Array.isArray(arg);
  }

  return Object.prototype.toString.call(arg) === '[object Array]';
};

module.exports.isEmpty = function (value) {
  if (module.exports.isArray(value)) {
    return !value.length;
  } else if (value === undefined || value === null) {
    return true;
  } else {
    return !String(value).trim().length;
  }
};

module.exports.isEqual = function (o1, o2) {
  return deepEqual(o1, o2);
};

module.exports.isFunction = function (arg) {
  return typeof arg === 'function';
};

module.exports.isNaN = function (arg) {
  return /^\s*$/.test(arg) || isNaN(arg);
};

module.exports.isNull = function (arg) {
  return arg === null;
};

module.exports.isString = function (arg) {
  return typeof arg === 'string' || arg instanceof String;
};

module.exports.isUndefined = function (arg) {
  return typeof arg === 'undefined';
};

module.exports.omit = function omit(obj, key) {
  var result = {};

  for (var name in obj) {
    if (name !== key) {
      result[name] = obj[name];
    }
  }

  return result;
};

module.exports.templates = require('./templates');

module.exports.mode = 'interactive'; // other values: conservative and manual

<|endoftext|>


<commit_before>/*
MagJS v0.23.5
http://github.com/magnumjs/mag.js
(c) Michael Glazer
License: MIT
*/

(function(mag) {

  'use strict';

  var utils = {};

  utils.callHook = function(hookins, key, name, i, data, before) {
    data.change = false
    if (hookins[name][i].key == key) {
      before = JSON.stringify({
        v: data.value,
        k: data.key
      })
      hookins[name][i].handler.call(hookins[name][i].context, data)
        //if any change
      if (before !== JSON.stringify({
          v: data.value,
          k: data.key
        })) {
        data.change = true
      }
    }
  }

  utils.unloaders = []
  var handlers = []
  utils.onLCEvent = function(eventName, index, handler) {
    handlers[eventName + '-' + index] = handler
  }
  utils.callLCEvent = function(eventName, controller, node, index, once, extra) {
    var isPrevented = false,
      event = {
        preventDefault: function() {
          isPrevented = true
        }
      }

    if (controller && controller[eventName]) {
      controller[eventName].call(controller, event, node, mag.mod.getProps(index), index, extra)
      if (once) controller[eventName] = 0
    }

    // on Handlers
    handlers[eventName + '-' + index] && handlers[eventName + '-' + index](mag.mod.getState(index), mag.mod.getProps(index));

    return isPrevented
  }

  //UTILITY
  utils.copy = function(o) {
    return Object.assign({}, o);
  }

  utils.merge = function() {
    return Object.assign.apply({}, arguments);
  }

  var a = {
    i: [],
    isItem: function(id) {
      return a.i.indexOf(id) > -1
    },
    setItem: function(id) {
      a.i[a.i.length] = id
    },
    getItem: function(id) {
      return a.i.indexOf(id)
    },
    getItemVal: function(index) {
      return a.i[index]
    },
    removeItem: function(id) {
      a.i.splice(a.i.indexOf(id), 1)
    }
  }

  utils.items = a

  utils.getItemInstanceIdAll = function() {
    return a.i
  }

  utils.getItemInstanceId = function(id) {
    if (a.isItem(id)) {
      return a.getItem(id)
    } else {
      a.setItem(id)
      return a.getItem(id)
    }
  }

  mag.utils = utils

}(window.mag || {}));
<commit_msg>Update utils.js<commit_after>/*
MagJS v0.23.5
http://github.com/magnumjs/mag.js
(c) Michael Glazer
License: MIT
*/

(function(mag) {

  'use strict';

  var utils = {};

  utils.callHook = function(hookins, key, name, i, data, before) {
    data.change = false
    if (hookins[name][i].key == key) {
      before = JSON.stringify({
        v: data.value,
        k: data.key
      })
      hookins[name][i].handler.call(hookins[name][i].context, data)
        //if any change
      if (before !== JSON.stringify({
          v: data.value,
          k: data.key
        })) {
        data.change = true
      }
    }
  }

  var handlers = []
  utils.onLCEvent = function(eventName, index, handler) {
    handlers[eventName + '-' + index] = handler
  }
  utils.callLCEvent = function(eventName, controller, node, index, once, extra) {
    var isPrevented = false,
      event = {
        preventDefault: function() {
          isPrevented = true
        }
      }

    if (controller && controller[eventName]) {
      controller[eventName].call(controller, event, node, mag.mod.getProps(index), index, extra)
      if (once) controller[eventName] = 0
    }

    // on Handlers
    handlers[eventName + '-' + index] && handlers[eventName + '-' + index](mag.mod.getState(index), mag.mod.getProps(index));

    return isPrevented
  }

  //UTILITY
  utils.copy = function(o) {
    return Object.assign({}, o);
  }

  utils.merge = function() {
    return Object.assign.apply({}, arguments);
  }

  var a = {
    i: [],
    isItem: function(id) {
      return a.i.indexOf(id) > -1
    },
    setItem: function(id) {
      a.i[a.i.length] = id
    },
    getItem: function(id) {
      return a.i.indexOf(id)
    },
    getItemVal: function(index) {
      return a.i[index]
    },
    removeItem: function(id) {
      a.i.splice(a.i.indexOf(id), 1)
    }
  }

  utils.items = a

  utils.getItemInstanceIdAll = function() {
    return a.i
  }

  utils.getItemInstanceId = function(id) {
    if (a.isItem(id)) {
      return a.getItem(id)
    } else {
      a.setItem(id)
      return a.getItem(id)
    }
  }

  mag.utils = utils

}(window.mag || {}));
<|endoftext|>


<commit_before>/** Singleton util class, with jquery and underscore like features. */
define([], function() {

    'use strict';

    function Utils() {
    }

    //Returns true if it is a DOM node
    //taken from: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
    Utils.prototype.isNode = function(o) {
        return (
            typeof Node === "object" ? o instanceof Node :
            o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
        );
    };

    //Returns true if it is a DOM element
    //taken from: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
    Utils.prototype.isElement = function(o) {
        return (
            typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
            o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName==="string"
        );
    };

    //adds all type of change listeners to an element, intended to be a text field
    Utils.prototype.addChangeListener = function(element, listener) {
        element.addEventListener("changed", listener);
        element.addEventListener("paste", listener);
        element.addEventListener("input", listener);
    };

    //if value is undefined, null or blank, returns null, othrewise returns the value
    Utils.prototype.makeNull = function(value) {
        if (value===null || value===undefined || value==="") {
            return null;
        } else {
            return value;
        }
    };

    Utils.prototype.uniqueValues = function(list, key) {
        var uniqueCheck = {};
        var result = [];
        for(var i = 0, l = list.length; i < l; i++){
            var value = list[i][key];
            if (value==="" || value===undefined) {
                value = null;
            }
            if(!uniqueCheck.hasOwnProperty(value)) {
                result.push(value);
                uniqueCheck[value] = 1;
            }
        }
        return result;
    };

    Utils.prototype.removeAllChildren = function(node) {
        if (node) {
            while (node.hasChildNodes()) {
                node.removeChild(node.lastChild);
            }
        }
    };

    //adds an element to a div, but also adds a background checking for clicks,
    //so that when the background is clicked, the child is removed again, giving
    //a model look to popups.
    Utils.prototype.addAsModalPopup = function(eParent, eChild) {
        var eBackdrop = document.createElement("div");
        eBackdrop.className = "ag-popup-backdrop";

        eBackdrop.onclick = function() {
            eParent.removeChild(eChild);
            eParent.removeChild(eBackdrop);
        };

        eParent.appendChild(eBackdrop);
        eParent.appendChild(eChild);
    };

    //loads the template and returns it as an element. makes up for no simple way in
    //the dom api to load html directly, eg we cannot do this: document.createElement(template)
    Utils.prototype.loadTemplate = function(template) {
        var tempDiv = document.createElement("div");
        tempDiv.innerHTML = template;
        return tempDiv.firstChild;
    };

    //if passed '42px' then returns the number 42
    Utils.prototype.pixelStringToNumber = function(val) {
        if (typeof val === "string") {
            if (val.indexOf("px")>=0) {
                val.replace("px","");
            }
            return parseInt(val);
        } else {
            return val;
        }
    };

    Utils.prototype.addCssClass = function(element, className) {
        var oldClasses = element.className;
        if (oldClasses.indexOf(className)>=0) {
            return;
        }
        element.className = oldClasses + " " + className;;
    };

    Utils.prototype.removeCssClass = function(element, className) {
        var oldClasses = element.className;
        if (oldClasses.indexOf(className)<0) {
            return;
        }
        var newClasses = oldClasses.replace(" " + className, "");
        newClasses = newClasses.replace(className + " ", "");
        if (newClasses==className) {
            newClasses = "";
        }
        element.className = newClasses;
    };

    Utils.prototype.removeFromArray = function(array, object) {
        array.splice(array.indexOf(object), 1);
    };

    Utils.prototype.defaultComparator = function(valueA, valueB) {
        var valueAMissing = valueA===null || valueA===undefined;
        var valueBMissing = valueB===null || valueB===undefined;
        if (valueAMissing && valueBMissing) {return 0;}
        if (valueAMissing) {return -1;}
        if (valueBMissing) {return 1;}

        if (valueA < valueB) {
            return -1;
        } else if (valueA > valueB) {
            return 1;
        } else {
            return 0;
        }
    };

    Utils.prototype.formatWidth = function(width) {
        if (typeof width === "number") {
            return width + "px";
        } else {
            return width;
        }
    };

    return new Utils();

});<commit_msg>notes<commit_after>/** Singleton util class, with jquery and underscore like features. */
define([], function() {

    'use strict';

    function Utils() {
    }

    //Returns true if it is a DOM node
    //taken from: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
    Utils.prototype.isNode = function(o) {
        return (
            typeof Node === "object" ? o instanceof Node :
            o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
        );
    };

    //Returns true if it is a DOM element
    //taken from: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
    Utils.prototype.isElement = function(o) {
        return (
            typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
            o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName==="string"
        );
    };

    //adds all type of change listeners to an element, intended to be a text field
    Utils.prototype.addChangeListener = function(element, listener) {
        element.addEventListener("changed", listener);
        element.addEventListener("paste", listener);
        element.addEventListener("input", listener);
    };

    //if value is undefined, null or blank, returns null, othrewise returns the value
    Utils.prototype.makeNull = function(value) {
        if (value===null || value===undefined || value==="") {
            return null;
        } else {
            return value;
        }
    };

    Utils.prototype.uniqueValues = function(list, key) {
        var uniqueCheck = {};
        var result = [];
        for(var i = 0, l = list.length; i < l; i++){
            var value = list[i][key];
            if (value==="" || value===undefined) {
                value = null;
            }
            if(!uniqueCheck.hasOwnProperty(value)) {
                result.push(value);
                uniqueCheck[value] = 1;
            }
        }
        return result;
    };

    Utils.prototype.removeAllChildren = function(node) {
        if (node) {
            while (node.hasChildNodes()) {
                node.removeChild(node.lastChild);
            }
        }
    };

    //adds an element to a div, but also adds a background checking for clicks,
    //so that when the background is clicked, the child is removed again, giving
    //a model look to popups.
    Utils.prototype.addAsModalPopup = function(eParent, eChild) {
        var eBackdrop = document.createElement("div");
        eBackdrop.className = "ag-popup-backdrop";

        eBackdrop.onclick = function() {
            eParent.removeChild(eChild);
            eParent.removeChild(eBackdrop);
        };

        eParent.appendChild(eBackdrop);
        eParent.appendChild(eChild);
    };

    //loads the template and returns it as an element. makes up for no simple way in
    //the dom api to load html directly, eg we cannot do this: document.createElement(template)
    Utils.prototype.loadTemplate = function(template) {
        var tempDiv = document.createElement("div");
        tempDiv.innerHTML = template;
        return tempDiv.firstChild;
    };

    //if passed '42px' then returns the number 42
    Utils.prototype.pixelStringToNumber = function(val) {
        if (typeof val === "string") {
            if (val.indexOf("px")>=0) {
                val.replace("px","");
            }
            return parseInt(val);
        } else {
            return val;
        }
    };

    Utils.prototype.addCssClass = function(element, className) {
        var oldClasses = element.className;
        if (oldClasses.indexOf(className)>=0) {
            return;
        }
        element.className = oldClasses + " " + className;;
    };

    Utils.prototype.removeCssClass = function(element, className) {
        var oldClasses = element.className;
        if (oldClasses.indexOf(className)<0) {
            return;
        }
        var newClasses = oldClasses.replace(" " + className, "");
        newClasses = newClasses.replace(className + " ", "");
        if (newClasses==className) {
            newClasses = "";
        }
        element.className = newClasses;
    };

    Utils.prototype.removeFromArray = function(array, object) {
        array.splice(array.indexOf(object), 1);
    };

    Utils.prototype.defaultComparator = function(valueA, valueB) {
        var valueAMissing = valueA===null || valueA===undefined;
        var valueBMissing = valueB===null || valueB===undefined;
        if (valueAMissing && valueBMissing) {return 0;}
        if (valueAMissing) {return -1;}
        if (valueBMissing) {return 1;}

        if (valueA < valueB) {
            return -1;
        } else if (valueA > valueB) {
            return 1;
        } else {
            return 0;
        }
    };

    Utils.prototype.formatWidth = function(width) {
        if (typeof width === "number") {
            return width + "px";
        } else {
            return width;
        }
    };

    return new Utils();

});

//13:44CAMPO, Alberto, M&IBthe day you get to the fronty page
//from then on, on your post, a recurennt 5 visits
//you need to accumulate posts
//just make a post entry
//and put it in dzone
//disclose yourself as the author of the plattform and encourage disccussion
//this is the worst site, but the easiest to score
//second best
//news.ycombinator.com
//if you get published here... 1000-1500 visits on the day, and if you are lucky quite a lot recurrent
//and the gold pot
//reddit.com/programming if you get in the top spot there... well, that's massive
//this is the most difficult and you are likely to get some abuse, but is worth it<|endoftext|>


<commit_before>'use strict';

const crc = require('crc');

const verifyCrc = (raw, checksum) => {
  let crcData;
  const idx = raw.lastIndexOf('|');
  const data = raw.slice(0, idx + 1);
  crcData = crc.crc16modbus(data);
  return crcData === checksum;
};

const verifyLen = (raw, len) => {
  return raw.replace('\r\n', '').length === len;
};

const isValid = (raw, len, checksum) =>{
  return verifyCrc(raw, checksum) && verifyLen(raw, len);
};

const getAlarm = alarm => {
  const alarmTypes = {
    '01': {type: 'SOS_Button'},
    '49': {type: 'DI', number: 5, status: false},
    '09': {type: 'Auto_Shutdown'},
    '10': {type: 'Low_Battery'},
    '11': {type: 'Over_Speed', status: true},
    '13': {type: 'Over_Speed', status: false},
    '14': {type: 'Aceleration', status: true},
    '15': {type: 'Aceleration', status: false},
    '30': {type: 'Parking'},
    '42': {type: 'Geo_Fence', status: true},
    '43': {type: 'Geo_Fence', status: false},
    '50': {type: 'DI', number: 1, status: false},
    '51': {type: 'DI', number: 1, status: true},
    '52': {type: 'DI', number: 2, status: false},
    '53': {type: 'DI', number: 2, status: true},
    '54': {type: 'DI', number: 3, status: false},
    '55': {type: 'DI', number: 3, status: true},
    '56': {type: 'DI', number: 4, status: false},
    '57': {type: 'DI', number: 4, status: true},
    '60': {type: 'Charge', status: true},
    '61': {type: 'Charge', status: false},
    '66': {type: 'Rfid'},
    '77': {type: 'Angle'},
    '88': {type: 'Heartbeat'},
    '91': {type: 'Sleep', status: true},
    '92': {type: 'Sleep', status: false},
    'AA': {type: 'Gps'}
  };
  return alarmTypes[alarm];
};

module.exports = {
  isValid: isValid,
  getAlarm: getAlarm
};
<commit_msg>feat(utils): Add message to getAlarm<commit_after>'use strict';

const crc = require('crc');
const langEs = require('./messages/es.json');
const langs = {'es': langEs};

const verifyCrc = (raw, checksum) => {
  let crcData;
  const idx = raw.lastIndexOf('|');
  const data = raw.slice(0, idx + 1);
  crcData = crc.crc16modbus(data);
  return crcData === checksum;
};

const verifyLen = (raw, len) => {
  return raw.replace('\r\n', '').length === len;
};

const isValid = (raw, len, checksum) =>{
  return verifyCrc(raw, checksum) && verifyLen(raw, len);
};

const getAlarm = (alarm, speed, rfid) => {
  const messages = langs['es'];
  const alarmTypes = {
    '01': {type: 'SOS_Button', message: messages[alarm]},
    '49': {type: 'DI', number: 5, status: false, message: messages[alarm]},
    '09': {type: 'Auto_Shutdown', message: messages[alarm]},
    '10': {type: 'Low_Battery', message: messages[alarm]},
    '11': {type: 'Over_Speed', status: true, message: messages[alarm].replace('${speed}', Math.round(speed))},
    '13': {type: 'Over_Speed', status: false, message: messages[alarm]},
    '14': {type: 'Aceleration', status: true, message: messages[alarm]},
    '15': {type: 'Aceleration', status: false, message: messages[alarm]},
    '30': {type: 'Parking', message: messages[alarm]},
    '42': {type: 'Geo_Fence', status: true, message: messages[alarm]},
    '43': {type: 'Geo_Fence', status: false, message: messages[alarm]},
    '50': {type: 'DI', number: 1, status: false, message: messages[alarm]},
    '51': {type: 'DI', number: 1, status: true, message: messages[alarm]},
    '52': {type: 'DI', number: 2, status: false, message: messages[alarm]},
    '53': {type: 'DI', number: 2, status: true, message: messages[alarm]},
    '54': {type: 'DI', number: 3, status: false, message: messages[alarm]},
    '55': {type: 'DI', number: 3, status: true, message: messages[alarm]},
    '56': {type: 'DI', number: 4, status: false, message: messages[alarm]},
    '57': {type: 'DI', number: 4, status: true, message: messages[alarm]},
    '60': {type: 'Charge', status: true, message: messages[alarm]},
    '61': {type: 'Charge', status: false, message: messages[alarm]},
    '66': {type: 'Rfid', message: messages[alarm].replace('${rfid}', rfid)},
    '77': {type: 'Angle', message: messages[alarm]},
    '88': {type: 'Heartbeat', message: messages[alarm]},
    '91': {type: 'Sleep', status: true, message: messages[alarm]},
    '92': {type: 'Sleep', status: false, message: messages[alarm]},
    'AA': {type: 'Gps', message: messages[alarm]},
  };
  return alarmTypes[alarm];
};

module.exports = {
  isValid: isValid,
  getAlarm: getAlarm
};
<|endoftext|>


<commit_before>export function createCallbacks(callbacks, placemark) {
    if (callbacks && typeof callbacks === 'object') {
        for (let key in callbacks) {
            placemark.events.add(key, callbacks[key]);
        }
    }
}

export function addToCart(markers, { options, callbacks, map, useObjectManager, objectManagerClusterize }) {
    const defaultLayout = `

{{ properties.balloonContentHeader }}

{{ properties.balloonContentBody }}

{{ properties.balloonContentFooter }}

    `;
    const defaultClusterLayout = 'cluster#balloonTwoColumns';

    let clusters = {};
    let unclastered = [];
    for (let marker of markers) {
        if (!marker.clusterName) {
            unclastered.push(marker);
            continue;
        };
        clusters[marker.clusterName] = clusters[marker.clusterName] ? [...clusters[marker.clusterName], marker] : [marker];
    }

    for (let clusterName in clusters) {
        const clusterOptions = options[clusterName] || {};
        const clusterCallbacks = callbacks[clusterName] || {};
        const layout = clusterOptions.layout || defaultLayout;
        clusterOptions.clusterBalloonItemContentLayout = ymaps.templateLayoutFactory.createClass(layout);

        const clusterLayout = clusterOptions.clusterLayout ? ymaps.templateLayoutFactory.createClass(clusterOptions.clusterLayout) :
            clusterOptions.clusterBalloonContentLayout || defaultClusterLayout;
        console.log(clusterLayout);
        console.log(clusterOptions.clusterLayout);
        clusterOptions.clusterBalloonContentLayout = clusterLayout;

        if (useObjectManager) {
            const ObjectManager = new ymaps.ObjectManager(Object.assign({ clusterize: objectManagerClusterize }, clusterOptions));
            for (let key in clusterCallbacks) {
                ObjectManager.clusters.events.add(key, clusterCallbacks[key]);
            }
            ObjectManager.add(clusters[clusterName]);
            map.geoObjects.add(ObjectManager);
        } else {
            const clusterer = new ymaps.Clusterer(clusterOptions);
            for (let key in clusterCallbacks) {
                clusterer.events.add(key, clusterCallbacks[key]);
            }
            clusterer.add(clusters[clusterName]);
            map.geoObjects.add(clusterer);
        }
    }
    if (unclastered.length) {
        const unclasteredMarkers = useObjectManager ? new ymaps.ObjectManager({ clusterize: false }) : new ymaps.GeoObjectCollection();
        unclastered.forEach(obj => unclasteredMarkers.add(obj))
        map.geoObjects.add(unclasteredMarkers);
    }
}

export function getIconPreset(marker) {
    let firstPart = marker.icon.color || 'blue',
        secondPart;
    if (marker.icon.glyph) {
        secondPart = setFirstLetterToUppercase(marker.icon.glyph);
    } else if (marker.icon.content) {
        secondPart = 'Stretchy'
    } else {
        secondPart = ''
    }
    return firstPart + secondPart
}

export function setFirstLetterToUppercase(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

export function setCoordsToNumeric(arr) {
    return arr.map(item => {
        return Array.isArray(item) ? setCoordsToNumeric(item) : +item;
    })
}

export function objectComparison( first, second ){

	let cache = []; //кеш обьектов, для избежания рекурсии

	function inCache( first, second ){
		var i = cache.length;
		while(i--) if(
			( cache[i][0] === first || cache[i][0] === second) && (cache[i][1] === second  || cache[i][1] === first )
		) return true;
		return false
	}

	return function eq(f, s){
		if ( f === s ) return true; //сравниваем обычным образом
		if ( f instanceof Date && s instanceof Date ) return +f === +s; //время
		if ( typeof f !== 'object' || typeof s !== 'object' ) return false; //если хотябы один из аргументов не объект (положительный случай для необъектов рассмотрен выше)
		if( inCache(f, s) ) return true; //есть в кеше
		cache.push( [f , s] ); //кешируем

		var keys = Object.keys(f), i = keys.length; //получаем ключи
		if (Object.keys(s).length !== i ) return false; //если количество ключей не совпадает
		while(i--) if( !eq(f[keys[i]], s[keys[i]]) ) return false; //рекурсивный вызов

		return true
	}(first, second)
}

export function compareValues (newVal, oldVal, bus) {
    if (objectComparison(newVal, oldVal)) { return; }
    if (bus.rerender) { clearTimeout(bus.rerender); }
    bus.rerender = setTimeout(() => bus.updateMap && bus.updateMap(), 10);
}

class EventEmitter {
    constructor() {
        this.events = {};
        this.ymapReady = false;
        this.scriptIsNotAttached = true;
    }

    $on(eventName, fn) {
        if (!this.events[eventName]) {
            this.events[eventName] = [];
        }

        this.events[eventName].push(fn);

        return () => {
            this.events[eventName] = this.events[eventName].filter(eventFn => fn !== eventFn);
        };
    }

    $emit(eventName, data) {
        const event = this.events[eventName];
        if (event) {
            event.forEach(fn => fn(data));
        }
    }
}

export const emitter = new EventEmitter();

const CONTROL_TYPES = [
    'fullscreenControl',
    'geolocationControl',
    'routeEditor',
    'rulerControl',
    'searchControl',
    'trafficControl',
    'typeSelector',
    'zoomControl',
    'routePanelControl'
];

export function controlsTypeValidator(val) {
    return val.filter(control => ![...CONTROL_TYPES, 'default'].includes(control)).length === 0
}

export function createMarkerType(val, useObjectManager) {
    const type = setFirstLetterToUppercase(val);
    if (!useObjectManager) return type;
    switch(type) {
        case 'Placemark':
            return 'Point';
        case 'Polyline':
            return 'LineString';
        default:
            return type;
    }
}

export function createMarker(object, useObjectManager) {
    let marker = useObjectManager ? {
        type: 'Feature',
        id: object.properties.markerId,
        geometry: {
            type: object.markerType,
            coordinates: object.coords
        },
        properties: object.properties,
        options: object.options
    } : new ymaps[object.markerType](object.coords, object.properties, object.options);

    marker.clusterName = object.clusterName;

    if (!useObjectManager) createCallbacks(object.callbacks, marker);

    return marker;
}
<commit_msg>Remove logs<commit_after>export function createCallbacks(callbacks, placemark) {
    if (callbacks && typeof callbacks === 'object') {
        for (let key in callbacks) {
            placemark.events.add(key, callbacks[key]);
        }
    }
}

export function addToCart(markers, { options, callbacks, map, useObjectManager, objectManagerClusterize }) {
    const defaultLayout = `

{{ properties.balloonContentHeader }}

{{ properties.balloonContentBody }}

{{ properties.balloonContentFooter }}

    `;
    const defaultClusterLayout = 'cluster#balloonTwoColumns';

    let clusters = {};
    let unclastered = [];
    for (let marker of markers) {
        if (!marker.clusterName) {
            unclastered.push(marker);
            continue;
        };
        clusters[marker.clusterName] = clusters[marker.clusterName] ? [...clusters[marker.clusterName], marker] : [marker];
    }

    for (let clusterName in clusters) {
        const clusterOptions = options[clusterName] || {};
        const clusterCallbacks = callbacks[clusterName] || {};
        const layout = clusterOptions.layout || defaultLayout;
        clusterOptions.clusterBalloonItemContentLayout = ymaps.templateLayoutFactory.createClass(layout);

        const clusterLayout = clusterOptions.clusterLayout ? ymaps.templateLayoutFactory.createClass(clusterOptions.clusterLayout) :
            clusterOptions.clusterBalloonContentLayout || defaultClusterLayout;
        clusterOptions.clusterBalloonContentLayout = clusterLayout;

        if (useObjectManager) {
            const ObjectManager = new ymaps.ObjectManager(Object.assign({ clusterize: objectManagerClusterize }, clusterOptions));
            for (let key in clusterCallbacks) {
                ObjectManager.clusters.events.add(key, clusterCallbacks[key]);
            }
            ObjectManager.add(clusters[clusterName]);
            map.geoObjects.add(ObjectManager);
        } else {
            const clusterer = new ymaps.Clusterer(clusterOptions);
            for (let key in clusterCallbacks) {
                clusterer.events.add(key, clusterCallbacks[key]);
            }
            clusterer.add(clusters[clusterName]);
            map.geoObjects.add(clusterer);
        }
    }
    if (unclastered.length) {
        const unclasteredMarkers = useObjectManager ? new ymaps.ObjectManager({ clusterize: false }) : new ymaps.GeoObjectCollection();
        unclastered.forEach(obj => unclasteredMarkers.add(obj))
        map.geoObjects.add(unclasteredMarkers);
    }
}

export function getIconPreset(marker) {
    let firstPart = marker.icon.color || 'blue',
        secondPart;
    if (marker.icon.glyph) {
        secondPart = setFirstLetterToUppercase(marker.icon.glyph);
    } else if (marker.icon.content) {
        secondPart = 'Stretchy'
    } else {
        secondPart = ''
    }
    return firstPart + secondPart
}

export function setFirstLetterToUppercase(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

export function setCoordsToNumeric(arr) {
    return arr.map(item => {
        return Array.isArray(item) ? setCoordsToNumeric(item) : +item;
    })
}

export function objectComparison( first, second ){

	let cache = []; //кеш обьектов, для избежания рекурсии

	function inCache( first, second ){
		var i = cache.length;
		while(i--) if(
			( cache[i][0] === first || cache[i][0] === second) && (cache[i][1] === second  || cache[i][1] === first )
		) return true;
		return false
	}

	return function eq(f, s){
		if ( f === s ) return true; //сравниваем обычным образом
		if ( f instanceof Date && s instanceof Date ) return +f === +s; //время
		if ( typeof f !== 'object' || typeof s !== 'object' ) return false; //если хотябы один из аргументов не объект (положительный случай для необъектов рассмотрен выше)
		if( inCache(f, s) ) return true; //есть в кеше
		cache.push( [f , s] ); //кешируем

		var keys = Object.keys(f), i = keys.length; //получаем ключи
		if (Object.keys(s).length !== i ) return false; //если количество ключей не совпадает
		while(i--) if( !eq(f[keys[i]], s[keys[i]]) ) return false; //рекурсивный вызов

		return true
	}(first, second)
}

export function compareValues (newVal, oldVal, bus) {
    if (objectComparison(newVal, oldVal)) { return; }
    if (bus.rerender) { clearTimeout(bus.rerender); }
    bus.rerender = setTimeout(() => bus.updateMap && bus.updateMap(), 10);
}

class EventEmitter {
    constructor() {
        this.events = {};
        this.ymapReady = false;
        this.scriptIsNotAttached = true;
    }

    $on(eventName, fn) {
        if (!this.events[eventName]) {
            this.events[eventName] = [];
        }

        this.events[eventName].push(fn);

        return () => {
            this.events[eventName] = this.events[eventName].filter(eventFn => fn !== eventFn);
        };
    }

    $emit(eventName, data) {
        const event = this.events[eventName];
        if (event) {
            event.forEach(fn => fn(data));
        }
    }
}

export const emitter = new EventEmitter();

const CONTROL_TYPES = [
    'fullscreenControl',
    'geolocationControl',
    'routeEditor',
    'rulerControl',
    'searchControl',
    'trafficControl',
    'typeSelector',
    'zoomControl',
    'routePanelControl'
];

export function controlsTypeValidator(val) {
    return val.filter(control => ![...CONTROL_TYPES, 'default'].includes(control)).length === 0
}

export function createMarkerType(val, useObjectManager) {
    const type = setFirstLetterToUppercase(val);
    if (!useObjectManager) return type;
    switch(type) {
        case 'Placemark':
            return 'Point';
        case 'Polyline':
            return 'LineString';
        default:
            return type;
    }
}

export function createMarker(object, useObjectManager) {
    let marker = useObjectManager ? {
        type: 'Feature',
        id: object.properties.markerId,
        geometry: {
            type: object.markerType,
            coordinates: object.coords
        },
        properties: object.properties,
        options: object.options
    } : new ymaps[object.markerType](object.coords, object.properties, object.options);

    marker.clusterName = object.clusterName;

    if (!useObjectManager) createCallbacks(object.callbacks, marker);

    return marker;
}
<|endoftext|>


<commit_before>define([
    'require',
    "jquery",
    './core/init'
], function(require, $, mapal) {
    var extractParameters = function(params, sources) {
        var tmp,
            j,
            paramObjs = {};
        if (params.length > 0) {
            var p = params.slice(1).split('!');
            for (var i = p.length-1; i >= 0; i--) {
                // support injection parameters in other patterns
                if (p[i][0] == '#') {
                    var param, effect;

                    if (p[i].indexOf('.') > 0) {
                        tmp = p[i].split('.');
                        param = tmp[0];
                        effect = tmp[1];
                    } else {
                        param = p[i];
                        effect = undefined;
                    }
                    var source = [sources.pop()];
                    // XXX: $a and url were also not defined in the old context
                    // We need automated tests
                    mapal.injection.load($a, url, param.slice(1), source);
                } else if (p[i].indexOf('=') > 0) {
                    j = p[i].indexOf('=');
                    paramObjs[p[i].slice(0, j)] = p[i].slice(j+1);
                } else {
                    paramObjs[p[i]] = true;
                }
            }
        }
        return paramObjs;
    };

    // input = "a!b=1 2!c=x"
    // --> options = {a: true, b: '1 2', c: 'x'}
    var parseOptions = function(input) {
        var params = input.split("!"),
            options = {}, name, value, index;

        for (var i=0; i<params.length; i++) {
            index = params[i].indexOf("=");
            if (index === -1) {
                name = params[i];
                value = true;
            } else {
                name = params[i].slice(0, index);
                value = params[i].slice(index+1);
            }
            options[name] = value;
        }
        return options;
    };

    var jquery_plugin = function(pattern) {
        var plugin = function(method) {
            if (!method || typeof method === "object") {
                pattern.init.apply(this, [this].concat(arguments));
            } else if (pattern[method]) {
                pattern[method].apply(
                    this,
                    [this].concat(Array.prototype.slice.call(arguments, 1))
                );
            } else {
                $.error('Method ' + method +
                        ' does not exist on jQuery.' + pattern.name);
            }
            return this;
        };
        return plugin;
    };

    // XXX: need to understand require magic to make this work here
    // require paths are local to where it is called, we would need to
    // pass the path of the module that called load_modules
    var load_modules = function(prefix, names, suffix) {
        prefix = prefix || '';
        suffix = suffix || '';
        var modules = names.reduce(function(acc, name) {
            acc[name] = require(prefix + name + suffix);
            return acc;
        }, {});
        return modules;
    };

    function _renumberAttribute(el, attr, i) {
        var $el = $(el),
            buf = $el.attr(attr);
        if (buf) {
            $el.attr(attr, buf.replace(/[0-9]+/, i));
        }
    }

    function _renumberEl() {
	_renumberAttribute(this, "for", i);
	_renumberAttribute(this, "id", i);
	_renumberAttribute(this, "name", i);
    }

    function renumber($container, selector) {
        var $entries = $container.find(selector ? selector : "fieldset,tr,dd"),
            entry, i;

        for (i=0; i<$entries.length; i++) {
            entry = $entries.get(i);
            _renumberAttribute(entry, "id", i);
            $("label, :input", entry).each(_renumberEl);
        }
    }

    function hasContent($el) {
        if ($el.is(":input")) {
            return $el.val();
        } else {
            return $el.text().replace(/\s*/g, "") || $el.find("img,object,video,audio").length;
        }
    }

    //     Underscore.js 1.3.1
    //     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
    //     Underscore is freely distributable under the MIT license.
    //     Portions of Underscore are inspired or borrowed from Prototype,
    //     Oliver Steele's Functional, and John Resig's Micro-Templating.
    //     For all details and documentation:
    //     http://documentcloud.github.com/underscore
    //
    // Returns a function, that, as long as it continues to be invoked, will not
    // be triggered. The function will be called after it stops being called for
    // N milliseconds.
    var debounce = function(func, wait) {
        var timeout;
        return function() {
            var context = this, args = arguments;
            var later = function() {
                timeout = null;
                func.apply(context, args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    };

    var utils = {
        extractParameters: extractParameters,
        parseOptions: parseOptions,
        //load_modules: load_modules,
        // pattern pimping - own module?
        jquery_plugin: jquery_plugin,
        debounce: debounce,
	renumber: renumber,
	hasContent: hasContent
    };

    return utils;
});
<commit_msg>utils cleanup<commit_after>define([
    "jquery"
], function($) {
    var extractParameters = function(params, sources) {
        var tmp,
            j,
            paramObjs = {};
        if (params.length > 0) {
            var p = params.slice(1).split('!');
            for (var i = p.length-1; i >= 0; i--) {
                // support injection parameters in other patterns
                if (p[i][0] == '#') {
                    var param, effect;

                    if (p[i].indexOf('.') > 0) {
                        tmp = p[i].split('.');
                        param = tmp[0];
                        effect = tmp[1];
                    } else {
                        param = p[i];
                        effect = undefined;
                    }
                    var source = [sources.pop()];
                    // XXX: $a and url were also not defined in the old context
                    // We need automated tests
                    mapal.injection.load($a, url, param.slice(1), source);
                } else if (p[i].indexOf('=') > 0) {
                    j = p[i].indexOf('=');
                    paramObjs[p[i].slice(0, j)] = p[i].slice(j+1);
                } else {
                    paramObjs[p[i]] = true;
                }
            }
        }
        return paramObjs;
    };

    // input = "a!b=1 2!c=x"
    // --> options = {a: true, b: '1 2', c: 'x'}
    var parseOptions = function(input) {
        var params = input.split("!"),
            options = {}, name, value, index;

        for (var i=0; i<params.length; i++) {
            index = params[i].indexOf("=");
            if (index === -1) {
                name = params[i];
                value = true;
            } else {
                name = params[i].slice(0, index);
                value = params[i].slice(index+1);
            }
            options[name] = value;
        }
        return options;
    };

    var jquery_plugin = function(pattern) {
        var plugin = function(method) {
            if (!method || typeof method === "object") {
                pattern.init.apply(this, [this].concat(arguments));
            } else if (pattern[method]) {
                pattern[method].apply(
                    this,
                    [this].concat(Array.prototype.slice.call(arguments, 1))
                );
            } else {
                $.error('Method ' + method +
                        ' does not exist on jQuery.' + pattern.name);
            }
            return this;
        };
        return plugin;
    };

    function _renumberAttribute(el, attr, i) {
        var $el = $(el),
            buf = $el.attr(attr);
        if (buf) {
            $el.attr(attr, buf.replace(/[0-9]+/, i));
        }
    }

    function _renumberEl() {
	_renumberAttribute(this, "for", i);
	_renumberAttribute(this, "id", i);
	_renumberAttribute(this, "name", i);
    }

    function renumber($container, selector) {
        var $entries = $container.find(selector ? selector : "fieldset,tr,dd"),
            entry, i;

        for (i=0; i<$entries.length; i++) {
            entry = $entries.get(i);
            _renumberAttribute(entry, "id", i);
            $("label, :input", entry).each(_renumberEl);
        }
    }

    function hasContent($el) {
        if ($el.is(":input")) {
            return $el.val();
        } else {
            return $el.text().replace(/\s*/g, "") || $el.find("img,object,video,audio").length;
        }
    }

    //     Underscore.js 1.3.1
    //     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
    //     Underscore is freely distributable under the MIT license.
    //     Portions of Underscore are inspired or borrowed from Prototype,
    //     Oliver Steele's Functional, and John Resig's Micro-Templating.
    //     For all details and documentation:
    //     http://documentcloud.github.com/underscore
    //
    // Returns a function, that, as long as it continues to be invoked, will not
    // be triggered. The function will be called after it stops being called for
    // N milliseconds.
    var debounce = function(func, wait) {
        var timeout;
        return function() {
            var context = this, args = arguments;
            var later = function() {
                timeout = null;
                func.apply(context, args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    };

    var utils = {
        extractParameters: extractParameters,
        parseOptions: parseOptions,
        //load_modules: load_modules,
        // pattern pimping - own module?
        jquery_plugin: jquery_plugin,
        debounce: debounce,
	renumber: renumber,
	hasContent: hasContent
    };

    return utils;
});
<|endoftext|>


<commit_before>import React from 'react';

class Utils {
  nopElement = <span />;

  forEachChild(children, handler) {
    React.Children.forEach(children, (child) => {
      handler(child);

      if (child.props && child.props.children) {
        this.forEachChild(child.props.children, handler);
      }
    });
  }

  buildElementTree(element, optionsFactory, elementFactory, parent) {
    var newChildren = undefined;

    var newElement = elementFactory && elementFactory(element, parent) || element;
    var newOptions = optionsFactory && optionsFactory(element, parent) || {};

    if (newElement !== this.nopElement && newElement.props && newElement.props.children ) {
      newChildren = React.Children.map(
        newElement.props.children,
        (childElement) => {
          if (!React.isValidElement(childElement)) {
            return elementFactory(childElement, parent);
          }
          return this.buildElementTree(childElement, optionsFactory, elementFactory, newElement);
        }
      );
    }

    return React.cloneElement(newElement, newOptions, newChildren);
  }

  getFormFieldMap(root, handler) {
    var fields = {};

    var tryMapField = (field, name) => {
      if (field.props.ignore) {
        return;
      }

      if (field.props.fieldName) {
        name = elements.props.fieldName;
      }

      if (!('name' in fields)) {
        fields[name] = field;
      }
    };

    this.forEachChild(root, (child) => {
      if (!child.props) {
        return;
      }

      handler(child, tryMapField.bind(null, child));
    });

    var inverseMap = {};
    var defaultValues = {};

    for (var key in fields) {
      var field = fields[key];

      if (!(field.type in inverseMap)) {
        inverseMap[field.type] = {};
      }

      var defaultValue = field.props.value || '';
      defaultValues[key] = defaultValue;

      inverseMap[field.type][field.props.name] = {
        fieldName: key,
        field: field
      };
    }

    return {
      defaultValues: defaultValues,
      inverse: inverseMap
    };
  }

  makeForm(source, fieldMapFn, spIf, spBindFn) {
    var root = React.cloneElement(<div />, {}, source.props.children);

    var fieldMap = this.getFormFieldMap(root, fieldMapFn);

    source.state.fields = source.state.fields || {};
    for (var key in fieldMap.defaultValues) {
      if (!(key in source.state.fields)) {
        source.state.fields[key] = fieldMap.defaultValues[key];
      }
    }

    var elementFactory = (element, parent) => {
      if (element.props) {
        var spIf = element.props.spIf;

        if (spIf) {
          var test = null;
          var inverted = false;

          if (spIf[0] === '!') {
            inverted = true;
            spIf = spIf.substr(1);
          }

          test = spIf(spIf, element);

          if (test !== null) {
            if (inverted) {
              test = !test;
            }

            if (!test) {
              return this.nopElement;
            }
          }
        }

        var spBind = element.props.spBind;

        if (spBind) {
          var newElement = spBindFn(spBind, element);
          if (newElement !== false) {
            element = newElement;
          }
        }
      }
      return element;
    };

    var optionsFactory = (element, parent) => {
      var options = {};

      if (element.props) {
        var elementType = element.type;
        var elementAttributeName = element.props.name;

        if (elementType in fieldMap.inverse && elementAttributeName in fieldMap.inverse[elementType]) {
          var mappedField = fieldMap.inverse[elementType][elementAttributeName];
          options.onChange = (e) => {
            disabled: source.state.isFormProcessing
            source.state.fields[mappedField.fieldName] = e.target.value;
          };
        }

        var elementAttributeType = element.props.type;

        if ((elementType === 'input' || elementType === 'button') && elementAttributeType === 'submit') {
          options.disabled = source.state.isFormProcessing;
        }
      }

      return options;
    };

    return this.buildElementTree(root, optionsFactory, elementFactory);
  }
}

export default new Utils()
<commit_msg>fix invalid naming (spIf function should be spIfFn)<commit_after>import React from 'react';

class Utils {
  nopElement = <span />;

  forEachChild(children, handler) {
    React.Children.forEach(children, (child) => {
      handler(child);

      if (child.props && child.props.children) {
        this.forEachChild(child.props.children, handler);
      }
    });
  }

  buildElementTree(element, optionsFactory, elementFactory, parent) {
    var newChildren = undefined;

    var newElement = elementFactory && elementFactory(element, parent) || element;
    var newOptions = optionsFactory && optionsFactory(element, parent) || {};

    if (newElement !== this.nopElement && newElement.props && newElement.props.children ) {
      newChildren = React.Children.map(
        newElement.props.children,
        (childElement) => {
          if (!React.isValidElement(childElement)) {
            return elementFactory(childElement, parent);
          }
          return this.buildElementTree(childElement, optionsFactory, elementFactory, newElement);
        }
      );
    }

    return React.cloneElement(newElement, newOptions, newChildren);
  }

  getFormFieldMap(root, handler) {
    var fields = {};

    var tryMapField = (field, name) => {
      if (field.props.ignore) {
        return;
      }

      if (field.props.fieldName) {
        name = elements.props.fieldName;
      }

      if (!('name' in fields)) {
        fields[name] = field;
      }
    };

    this.forEachChild(root, (child) => {
      if (!child.props) {
        return;
      }

      handler(child, tryMapField.bind(null, child));
    });

    var inverseMap = {};
    var defaultValues = {};

    for (var key in fields) {
      var field = fields[key];

      if (!(field.type in inverseMap)) {
        inverseMap[field.type] = {};
      }

      var defaultValue = field.props.value || '';
      defaultValues[key] = defaultValue;

      inverseMap[field.type][field.props.name] = {
        fieldName: key,
        field: field
      };
    }

    return {
      defaultValues: defaultValues,
      inverse: inverseMap
    };
  }

  makeForm(source, fieldMapFn, spIfFn, spBindFn) {
    var root = React.cloneElement(<div />, {}, source.props.children);

    var fieldMap = this.getFormFieldMap(root, fieldMapFn);

    source.state.fields = source.state.fields || {};
    for (var key in fieldMap.defaultValues) {
      if (!(key in source.state.fields)) {
        source.state.fields[key] = fieldMap.defaultValues[key];
      }
    }

    var elementFactory = (element, parent) => {
      if (element.props) {
        var spIf = element.props.spIf;

        if (spIf) {
          var test = null;
          var inverted = false;

          if (spIf[0] === '!') {
            inverted = true;
            spIf = spIf.substr(1);
          }

          test = spIfFn(spIf, element);

          if (test !== null) {
            if (inverted) {
              test = !test;
            }

            if (!test) {
              return this.nopElement;
            }
          }
        }

        var spBind = element.props.spBind;

        if (spBind) {
          var newElement = spBindFn(spBind, element);
          if (newElement !== false) {
            element = newElement;
          }
        }
      }
      return element;
    };

    var optionsFactory = (element, parent) => {
      var options = {};

      if (element.props) {
        var elementType = element.type;
        var elementAttributeName = element.props.name;

        if (elementType in fieldMap.inverse && elementAttributeName in fieldMap.inverse[elementType]) {
          var mappedField = fieldMap.inverse[elementType][elementAttributeName];
          options.onChange = (e) => {
            disabled: source.state.isFormProcessing
            source.state.fields[mappedField.fieldName] = e.target.value;
          };
        }

        var elementAttributeType = element.props.type;

        if ((elementType === 'input' || elementType === 'button') && elementAttributeType === 'submit') {
          options.disabled = source.state.isFormProcessing;
        }
      }

      return options;
    };

    return this.buildElementTree(root, optionsFactory, elementFactory);
  }
}

export default new Utils()
<|endoftext|>