<commit_before>// Substance.Document 0.4.0
// (c) 2010-2013 Michael Aufreiter
// Substance.Document may be freely distributed under the MIT license.
// For all details and documentation:
// http://interior.substance.io/modules/document.html

(function(root) {

// Import
// ========

var _,
    ot,
    util,
    errors,
    Chronicle,
    ArrayOperation,
    TextOperation,
    Data;

if (typeof exports !== 'undefined') {
  _    = require('underscore');
  ot   = require('./lib/operation');
  util   = require('./lib/util/util');
  errors   = require('./lib/util/errors');
  Chronicle = require('./lib/chronicle/chronicle');
  ArrayOperation = require('./lib/chronicle/lib/ot/array_operation');
  TextOperation = require('./lib/chronicle/lib/ot/text_operation');
  Data = require('./lib/data/data');
} else {
  _ = root._;
  ot = root.ot;
  util = root.Substance.util;
  errors   = root.Substance.errors;
  Chronicle = root.Substance.Chronicle;
  ArrayOperation = Chronicle.OT.ArrayOperation;
  TextOperation = Chronicle.OT.TextOperation;
  Data = root.Substance.Data;
}

// Implementation
// ========

// Default Document Schema
// --------

var SCHEMA = {
  // Static indexes
  "indexes": {
    // all comments are now indexed by node association
    "comments": {
      "type": "comment",
      "properties": ["node"]
    },
    // All comments are now indexed by node
    "annotations": {
      "type": "annotation",
      "properties": ["node"]
    }
  },

  "types": {
    // Specific type for substance documents, holding all content elements
    "content": {
      "properties": {
      }
    },

    "text": {
      "parent": "content",
      "properties": {
        "content": "string"
      }
    },

    "document": {
      "properties": {
        "views": ["array", "views"]
      }
    },

    "view": {
      "properties": {
        "nodes": ["array", "content"]
      }
    },

    "codeblock": {
      "parent": "content",
      "properties": {
        "content": "string"
      }
    },

    "image": {
      "parent": "content",
      "properties": {
        "large": "string",
        "medium": "string",
        "caption": "string"
      }
    },

    "heading": {
      "parent": "content",
      "properties": {
        "content": "string",
        "level": "number"
      }
    },

    // Annotations
    "annotation": {
      "properties": {
        "node": "content",
        "property": "string",
        "range": "object"
      }
    },

    "strong": {
      "parent": "annotation",
      "properties": {
      }
    },

    "emphasis": {
      "properties": {
      },
      "parent": "annotation"
    },

    "code": {
      "parent": "annotation",
      "properties": {
      }
    },

    "link": {
      "parent": "annotation",
      "properties": {
        "url": "string"
      }
    },

    "idea": {
      "parent": "annotation",
      "properties": {
      }
    },

    "error": {
      "parent": "annotation",
      "properties": {
      }
    },

    "question": {
      "parent": "annotation",
      "properties": {
      }
    },

    // Comments
    "comment": {
      "properties": {
        "content": "string",
        "node": "node"
      }
    }
  }
};

// Seed Data
// ========
//
// Some pre-defined nodes that are required for each document
// `document` stores all meta-information about the document
// `content` is the main view

var SEED = [
  ["create", {
      "id": "document",
      "type": "document",
      "views": ["content", "figures", "publications"]
    }
  ],
  ["create", {
      "id": "content",
      "type": "view",
      "nodes": []
    }
  ],
  ["create", {
      "id": "figures",
      "type": "view",
      "nodes": []
    }
  ],
  ["create", {
      "id": "publications",
      "type": "view",
      "nodes": []
    }
  ]
];

// Command Converter
// ========
//
// Turns document command into Data.Graph commands

var Converter = function() {

  // Delete nodes from document
  // --------
  //
  // ["delete", {nodes: ["h1", "t1"]}]

  this.delete = function(graph, command) {
    return _.map(command.args.nodes, function(n) {
      return Data.Graph.Delete({id: n});
    });
  };

  // Position nodes in document
  // --------
  //
  // ["position", {"nodes": ["t1", "t2"], "target": -1}]
  //

  this.position = function(graph, command) {
    var path = command.path.concat(["nodes"]);
    var view = graph.resolve(path).slice(0);
    var nodes = command.args.nodes;
    var ops = [];
    var idx;

    // Create a sequence of atomic array operations that
    // are bundled into a Compound operation
    // 1. Remove elements (from right to left)
    // 2. Insert at the very position

    // the sequence contains selected nodes in the order they
    // occurr in the view
    var seq = _.intersection(view, nodes);
    var l = view.length;

    while(seq.length > 0) {
      var id = seq.pop();
      idx = view.indexOf(id);
      if (idx >= 0) {
        ops.push(ArrayOperation.Delete(idx, id));
        l--;
      }
    }

    // target index can be given as negative number (as known from python/ruby)
    var target = (l === 0) ? 0 : (l + command.args.target) % l;
    for (idx = 0; idx < nodes.length; idx++) {
      ops.push(ArrayOperation.Insert(target + idx, nodes[idx]));
    }

    var compound = ArrayOperation.Compound(ops);

    return Data.Graph.Update(path, compound);
  };

  // Update incrementally
  // --------
  //

  this.update = function(graph, command) {
    var propertyBaseType = graph.propertyBaseType(graph.get(command.path[0]), command.path[1]);
    var val = graph.resolve(command.path);

    var update;

    // String
    if (propertyBaseType === 'string') {
      update = TextOperation.fromOT(command.args, val);
    }

    // Array
    else if (propertyBaseType === 'array') {
      throw new Error("Not yet implemented for arrays");
    }

    // Object
    else if (propertyBaseType === 'object') {
      // TODO: needs ObjectOperation to be finished
      throw new Error("Not yet implemented for objects");
    }

    // Other
    else {
      throw new Error("Unsupported type for update: " + propertyBaseType);
    }

    return Data.Graph.Update(command.path, update);
  };

  // Set property values
  // --------
  //
  // Unlike update you can set values directly
  // ["set", "h1", "content", "Hello Welt"] // string update
  // ["set", "a1", "pos", ["a", "b", "c"]] // array update (not yet implemented)

  this.set = function(graph, command) {

    if (!command.args) { // for string updates
      command.args = command.path.pop();
    }

    var propertyBaseType = graph.propertyBaseType(graph.get(command.path[0]), command.path[1]);
    var result;

    // String
    if (propertyBaseType === 'string') {
      var val = graph.resolve(command.path);
      var newVal = command.args;
      var update = TextOperation.fromOT([-val.length, newVal], val);
      result = Data.Graph.Update(command.path, update);
    }

    // Array
    else if (propertyBaseType === 'array') {
      throw new Error("Not yet implemented for arrays");
    }

    // Object
    else if (propertyBaseType === 'object') {
      // TODO: needs ObjectOperation to be finished
      throw new Error("Not yet implemented for objects");
    }

    // Other
    // Note: treating any other type via string operation
    else {
      var val = graph.resolve(command.path).toString();
      var newVal = command.args.toString();

      var update = TextOperation.fromOT([-val.length, newVal], val);
      result = Data.Graph.Update(command.path, update);
    }

    return result;
  };

  // Annotate document
  // --------
  //
  // `command.path` defines the referenced content node and property
  // ["annotate", "t1", "content", {"id": "a1",  type": "idea"}]

  this.annotate = function(graph, command) {
    // TODO: check if source exists, otherwise reject annotation
    if (command.path.length !== 2) throw new Error("Invalid target: " + command.path);

    var annotation = _.extend({}, command.args, {
      node: command.path[0],
      property: command.path[1]
    });

    return Data.Graph.Create(annotation);
  };

  // Comment
  // --------
  //
  // `command.path` holds the node id, where the comment should stick on

  this.comment = function(graph, command) {
    // Delegates to graph.create method
    // TODO: check if source exists, otherwise reject annotation

    // keep track of annotation
    if (command.path.length !== 1) throw new Error("Invalid target: " + command.path);

    var comment = _.extend({}, command.args);
    comment.node = command.path[0];
    comment.type = comment.type || 'comment';

    return Data.Graph.Create(comment);
  };
};

// Document
// --------
//
// A generic model for representing and transforming digital documents

var Document = function(doc, schema) {
  Data.Graph.call(this, schema || SCHEMA);
  // Set public properties
  this.id = doc.id;

  this.reset();
};

Document.__prototype__ = function() {

  var __super__ = util.prototype(this);
  var converter = new Converter();

  // Resets the versioned object to a clean state.
  // --------
  //

  this.reset = function() {
    // Seed graph
    _.each(SEED, function(cmd) {
      this.exec(cmd);
    }, this);
  };

  var updateAnnotations = function(node, property, change) {
    // We need to update the range of affected annotations.

    var annotations = this.find("annotations", node.id);
    annotations = _.filter(annotations, function(a) {
      return a.property === property;
    });
    for (var idx = 0; idx < annotations.length; idx++) {
      TextOperation.Range.transform(annotations[idx].range, change);
    }
  };

  // Executes a document manipulation command.
  // --------
  // The command is converted into a sequence of graph commands

  this.exec = function(command) {
    console.log("Executing command: ", command);
    var graphCommand;
    // convert the command into a Data.Graph compatible command
    command = new Data.Command(command);
    if (converter[command.op]) {
      graphCommand = converter[command.op](this, command);
    } else {
      graphCommand = command;
    }

    // console.log('converted cmd', command);
    var commands = _.isArray(graphCommand) ? graphCommand : [graphCommand];

    _.each(commands, function(c) {

      __super__.exec.call(this, c);

      if (c.op === "update") {
        var node = this.get(c.path[0]);
        var property = c.path[1];
        var change = c.args;
        updateAnnotations.call(this, node, property, change);
      }
    }, this);
  };
};

// Document.__prototype__.prototype = Chronicle.Versioned.prototype;
Document.__prototype__.prototype = Data.Graph.prototype;
Document.prototype = new Document.__prototype__();

// add event support
_.extend(Document.prototype, util.Events);

// Export
// ========

if (typeof exports !== 'undefined') {
  module.exports = Document;
} else {
  root.Substance.Document = Document;
}

})(this);
<commit_msg>Trigger event when a command has been executed successfully.<commit_after>// Substance.Document 0.4.0
// (c) 2010-2013 Michael Aufreiter
// Substance.Document may be freely distributed under the MIT license.
// For all details and documentation:
// http://interior.substance.io/modules/document.html

(function(root) {

// Import
// ========

var _,
    ot,
    util,
    errors,
    Chronicle,
    ArrayOperation,
    TextOperation,
    Data;

if (typeof exports !== 'undefined') {
  _    = require('underscore');
  ot   = require('./lib/operation');
  util   = require('./lib/util/util');
  errors   = require('./lib/util/errors');
  Chronicle = require('./lib/chronicle/chronicle');
  ArrayOperation = require('./lib/chronicle/lib/ot/array_operation');
  TextOperation = require('./lib/chronicle/lib/ot/text_operation');
  Data = require('./lib/data/data');
} else {
  _ = root._;
  ot = root.ot;
  util = root.Substance.util;
  errors   = root.Substance.errors;
  Chronicle = root.Substance.Chronicle;
  ArrayOperation = Chronicle.OT.ArrayOperation;
  TextOperation = Chronicle.OT.TextOperation;
  Data = root.Substance.Data;
}

// Implementation
// ========

// Default Document Schema
// --------

var SCHEMA = {
  // Static indexes
  "indexes": {
    // all comments are now indexed by node association
    "comments": {
      "type": "comment",
      "properties": ["node"]
    },
    // All comments are now indexed by node
    "annotations": {
      "type": "annotation",
      "properties": ["node"]
    }
  },

  "types": {
    // Specific type for substance documents, holding all content elements
    "content": {
      "properties": {
      }
    },

    "text": {
      "parent": "content",
      "properties": {
        "content": "string"
      }
    },

    "document": {
      "properties": {
        "views": ["array", "views"]
      }
    },

    "view": {
      "properties": {
        "nodes": ["array", "content"]
      }
    },

    "codeblock": {
      "parent": "content",
      "properties": {
        "content": "string"
      }
    },

    "image": {
      "parent": "content",
      "properties": {
        "large": "string",
        "medium": "string",
        "caption": "string"
      }
    },

    "heading": {
      "parent": "content",
      "properties": {
        "content": "string",
        "level": "number"
      }
    },

    // Annotations
    "annotation": {
      "properties": {
        "node": "content",
        "property": "string",
        "range": "object"
      }
    },

    "strong": {
      "parent": "annotation",
      "properties": {
      }
    },

    "emphasis": {
      "properties": {
      },
      "parent": "annotation"
    },

    "code": {
      "parent": "annotation",
      "properties": {
      }
    },

    "link": {
      "parent": "annotation",
      "properties": {
        "url": "string"
      }
    },

    "idea": {
      "parent": "annotation",
      "properties": {
      }
    },

    "error": {
      "parent": "annotation",
      "properties": {
      }
    },

    "question": {
      "parent": "annotation",
      "properties": {
      }
    },

    // Comments
    "comment": {
      "properties": {
        "content": "string",
        "node": "node"
      }
    }
  }
};

// Seed Data
// ========
//
// Some pre-defined nodes that are required for each document
// `document` stores all meta-information about the document
// `content` is the main view

var SEED = [
  ["create", {
      "id": "document",
      "type": "document",
      "views": ["content", "figures", "publications"]
    }
  ],
  ["create", {
      "id": "content",
      "type": "view",
      "nodes": []
    }
  ],
  ["create", {
      "id": "figures",
      "type": "view",
      "nodes": []
    }
  ],
  ["create", {
      "id": "publications",
      "type": "view",
      "nodes": []
    }
  ]
];

// Command Converter
// ========
//
// Turns document command into Data.Graph commands

var Converter = function() {

  // Delete nodes from document
  // --------
  //
  // ["delete", {nodes: ["h1", "t1"]}]

  this.delete = function(graph, command) {
    return _.map(command.args.nodes, function(n) {
      return Data.Graph.Delete({id: n});
    });
  };

  // Position nodes in document
  // --------
  //
  // ["position", {"nodes": ["t1", "t2"], "target": -1}]
  //

  this.position = function(graph, command) {
    var path = command.path.concat(["nodes"]);
    var view = graph.resolve(path).slice(0);
    var nodes = command.args.nodes;
    var ops = [];
    var idx;

    // Create a sequence of atomic array operations that
    // are bundled into a Compound operation
    // 1. Remove elements (from right to left)
    // 2. Insert at the very position

    // the sequence contains selected nodes in the order they
    // occurr in the view
    var seq = _.intersection(view, nodes);
    var l = view.length;

    while(seq.length > 0) {
      var id = seq.pop();
      idx = view.indexOf(id);
      if (idx >= 0) {
        ops.push(ArrayOperation.Delete(idx, id));
        l--;
      }
    }

    // target index can be given as negative number (as known from python/ruby)
    var target = (l === 0) ? 0 : (l + command.args.target) % l;
    for (idx = 0; idx < nodes.length; idx++) {
      ops.push(ArrayOperation.Insert(target + idx, nodes[idx]));
    }

    var compound = ArrayOperation.Compound(ops);

    return Data.Graph.Update(path, compound);
  };

  // Update incrementally
  // --------
  //

  this.update = function(graph, command) {
    var propertyBaseType = graph.propertyBaseType(graph.get(command.path[0]), command.path[1]);
    var val = graph.resolve(command.path);

    var update;

    // String
    if (propertyBaseType === 'string') {
      update = TextOperation.fromOT(command.args, val);
    }

    // Array
    else if (propertyBaseType === 'array') {
      throw new Error("Not yet implemented for arrays");
    }

    // Object
    else if (propertyBaseType === 'object') {
      // TODO: needs ObjectOperation to be finished
      throw new Error("Not yet implemented for objects");
    }

    // Other
    else {
      throw new Error("Unsupported type for update: " + propertyBaseType);
    }

    return Data.Graph.Update(command.path, update);
  };

  // Set property values
  // --------
  //
  // Unlike update you can set values directly
  // ["set", "h1", "content", "Hello Welt"] // string update
  // ["set", "a1", "pos", ["a", "b", "c"]] // array update (not yet implemented)

  this.set = function(graph, command) {

    if (!command.args) { // for string updates
      command.args = command.path.pop();
    }

    var propertyBaseType = graph.propertyBaseType(graph.get(command.path[0]), command.path[1]);
    var result;

    // String
    if (propertyBaseType === 'string') {
      var val = graph.resolve(command.path);
      var newVal = command.args;
      var update = TextOperation.fromOT([-val.length, newVal], val);
      result = Data.Graph.Update(command.path, update);
    }

    // Array
    else if (propertyBaseType === 'array') {
      throw new Error("Not yet implemented for arrays");
    }

    // Object
    else if (propertyBaseType === 'object') {
      // TODO: needs ObjectOperation to be finished
      throw new Error("Not yet implemented for objects");
    }

    // Other
    // Note: treating any other type via string operation
    else {
      var val = graph.resolve(command.path).toString();
      var newVal = command.args.toString();

      var update = TextOperation.fromOT([-val.length, newVal], val);
      result = Data.Graph.Update(command.path, update);
    }

    return result;
  };

  // Annotate document
  // --------
  //
  // `command.path` defines the referenced content node and property
  // ["annotate", "t1", "content", {"id": "a1",  type": "idea"}]

  this.annotate = function(graph, command) {
    // TODO: check if source exists, otherwise reject annotation
    if (command.path.length !== 2) throw new Error("Invalid target: " + command.path);

    var annotation = _.extend({}, command.args, {
      node: command.path[0],
      property: command.path[1]
    });

    return Data.Graph.Create(annotation);
  };

  // Comment
  // --------
  //
  // `command.path` holds the node id, where the comment should stick on

  this.comment = function(graph, command) {
    // Delegates to graph.create method
    // TODO: check if source exists, otherwise reject annotation

    // keep track of annotation
    if (command.path.length !== 1) throw new Error("Invalid target: " + command.path);

    var comment = _.extend({}, command.args);
    comment.node = command.path[0];
    comment.type = comment.type || 'comment';

    return Data.Graph.Create(comment);
  };
};

// Document
// --------
//
// A generic model for representing and transforming digital documents

var Document = function(doc, schema) {
  Data.Graph.call(this, schema || SCHEMA);
  // Set public properties
  this.id = doc.id;

  // TODO: shift into a dedicated facility
  this.meta = {};

  this.reset();
};

Document.__prototype__ = function() {

  var __super__ = util.prototype(this);
  var converter = new Converter();

  // Resets the versioned object to a clean state.
  // --------
  //

  this.reset = function() {
    // Seed graph
    _.each(SEED, function(cmd) {
      this.exec(cmd);
    }, this);
  };

  var updateAnnotations = function(node, property, change) {
    // We need to update the range of affected annotations.

    var annotations = this.find("annotations", node.id);
    annotations = _.filter(annotations, function(a) {
      return a.property === property;
    });
    for (var idx = 0; idx < annotations.length; idx++) {
      TextOperation.Range.transform(annotations[idx].range, change);
    }
  };

  // Executes a document manipulation command.
  // --------
  // The command is converted into a sequence of graph commands

  this.exec = function(command) {
    console.log("Executing command: ", command);
    var graphCommand;
    // convert the command into a Data.Graph compatible command
    command = new Data.Command(command);
    if (converter[command.op]) {
      graphCommand = converter[command.op](this, command);
    } else {
      graphCommand = command;
    }

    // console.log('converted cmd', command);
    var commands = _.isArray(graphCommand) ? graphCommand : [graphCommand];

    _.each(commands, function(c) {

      __super__.exec.call(this, c);

      if (c.op === "update") {
        var node = this.get(c.path[0]);
        var property = c.path[1];
        var change = c.args;
        updateAnnotations.call(this, node, property, change);
      }
    }, this);
    this.trigger('command:executed', command);
  };
};

// Document.__prototype__.prototype = Chronicle.Versioned.prototype;
Document.__prototype__.prototype = Data.Graph.prototype;
Document.prototype = new Document.__prototype__();

// add event support
_.extend(Document.prototype, util.Events);

// Export
// ========

if (typeof exports !== 'undefined') {
  module.exports = Document;
} else {
  root.Substance.Document = Document;
}

})(this);
<|endoftext|>


<commit_before>function Panel(args) {
    this.id = Utils.genId("Panel");
    this.name = "";
    this.diseases = [];
    this.genes = [];
    this.mutations = [];
    this.name = "";
    this.author = "";
    this.description = "";
    this.date = "";
    this.disease = "";
    this.version = 1;
    this.archived = false;
    this.used = false;
    this.polymer;

    _.extend(this, args);

    this.modCount = 0;

    this.hashMutations = {};
};
Panel.prototype = {
    _incModCount: function () {
        this.modCount++;
    },
    addDiseases: function (diseases) {
        var me = this;
        var genes = [];

        for (var i = 0; i < diseases.length; i++) {
            var disease = diseases[i];
            if (!this.containsDisease(disease)) {
                delete disease._filtered;
                this.polymer.push('formData.diseases', disease);
                // this._emit("add-disease", disease);

                if (disease.associatedGenes && disease.associatedGenes.length > 0) {
                    for (var j = 0; j < disease.associatedGenes.length; j++) {
                        var assocGene = disease.associatedGenes[j];
                        if (!this._checkGenes(assocGene, this.genes)) {
                            genes.push(assocGene);
                        }
                    }
                }

                if (disease.source == "clinvar") {

                    CellBaseManager.get({
                        species: 'hsapiens',
                        category: 'feature',
                        subCategory: 'clinical',
                        resource: 'search',
                        async: false,
                        params: {
                            source: 'clinvar',
                            phenotype: disease.phenotype,
                            exclude: "annot,clinvarSet"
                        },
                        success: function (data) {
                            if (data.response && data.response.length > 0) {
                                var result = data.response[0].result;
                                for (var i = 0; i < result.length; i++) {
                                    var row = result[i];
                                    var mut = {

                                        chr: row.chromosome,
                                        pos: row.start,
                                        ref: row.reference,
                                        alt: row.alternate,
                                        phe: disease.phenotype,
                                        src: disease.source
                                    }
                                    me.addMutation(mut);

                                }
                            }
                        }
                    });
                }

            }

        }

        Utils.applyFunctionBatch(genes, 5, function (genes) {
            CellBaseManager.get({
                species: 'hsapiens',
                category: 'feature',
                subCategory: 'gene',
                resource: 'info',
                async: false,
                query: genes.join(","),
                params: {
                    include: "name,chromosome,start,end"
                },
                success: function (data) {

                    if (data.response && data.response.length > 0) {

                        for (var i = 0; i < data.response.length; i++) {
                            var geneElem = data.response[i];

                            if (geneElem.result.length > 0) {
                                var row = data.response[i].result[0];
                                var gene = {
                                    name: row.name,
                                    chr: row.chromosome,
                                    start: row.start,
                                    end: row.end
                                };
                                me.addGene(gene);

                            } else {
                                me.addGene({
                                    name: geneElem.id
                                });
                            }

                        }
                    }
                }
            });
        });
        this._incModCount();

    },
    addDisease: function (disease) {
        var me = this;
        if (!this.containsDisease(disease)) {
            delete disease._filtered
            this.polymer.push('formData.diseases', disease);

            if (disease.associatedGenes && disease.associatedGenes.length > 0) {
                var genes = [];
                for (var j = 0; j < disease.associatedGenes.length; j++) {
                    var assocGene = disease.associatedGenes[j];
                    if (!this._checkGenes(assocGene, this.genes)) {
                        genes.push(assocGene);
                    }
                }
                if (genes.length > 0) {

                    CellBaseManager.get({
                        species: 'hsapiens',
                        category: 'feature',
                        subCategory: 'gene',
                        resource: 'info',
                        async: false,
                        query: genes.join(","),
                        params: {
                            include: "name,chromosome,start,end"
                        },
                        success: function (data) {

                            if (data.response && data.response.length > 0) {

                                for (var i = 0; i < data.response.length; i++) {
                                    var geneElem = data.response[i];
                                    if (geneElem.result.length > 0) {
                                        var row = data.response[i].result[0];
                                        var gene = {
                                            name: row.name,
                                            chr: row.chromosome,
                                            start: row.start,
                                            end: row.end
                                        };
                                        me.addGene(gene);

                                    } else {
                                        me.addGene({
                                            name: geneElem.id
                                        });
                                    }

                                }
                            }
                        }
                    });

                }
            }

            if (disease.source == "clinvar") {
                CellBaseManager.get({
                    species: 'hsapiens',
                    category: 'feature',
                    subCategory: 'clinical',
                    resource: 'search',
                    async: false,
                    params: {
                        source: 'clinvar',
                        phenotype: disease.phenotype,
                        exclude: "annot,clinvarSet"
                    },
                    success: function (data) {
                        if (data.response && data.response.length > 0) {
                            var result = data.response[0].result;
                            for (var i = 0; i < result.length; i++) {
                                var row = result[i];
                                var mut = {

                                    chr: row.chromosome,
                                    pos: row.start,
                                    ref: row.reference,
                                    alt: row.alternate,
                                    phe: disease.phenotype,
                                    src: disease.source
                                }
                                me.addMutation(mut);

                            }
                        }
                    }
                });
            }

            this._incModCount();
        }
    },
    _checkGenes: function (assocGen, genes) {
        for (var j = 0; j < genes.length; j++) {
            if (assocGen == genes[j].name) {
                return true;
            }
        }
        return false;
    },
    addAllDiseases: function (diseases) {
        for (var i = 0; i < diseases.length; i++) {
            var disease = diseases[i];
            this.addDisease(disease);
        }
    },
    containsDisease: function (disease) {
        for (var i = 0; i < this.diseases.length; i++) {
            var elem = this.diseases[i];
            if (elem === disease) {
                return true;
            }
        }
        return false;
    },
    clearDiseases: function () {
        for (var i = 0; i < this.diseases.length; i++) {
            var disease = this.diseases[i];
            this.removeGenesFromDisease(disease);
            this.removeMutationsFromDisease(disease);
        }
        this.diseases = [];
        this.polymer.notifyPath('formData.diseases', this.diseases);
        this._incModCount();
    },
    clearGenes: function () {
        this.genes = [];
        this.polymer.notifyPath('formData.genes', this.genes);
        this._incModCount();
    },
    clearMutations: function () {
        this.mutations = [];
        this.polymer.notifyPath('formData.mutations', this.mutations);
        this._incModCount();
    },
    addGene: function (gene) {

        var panelGenes = [];

        for (var i = 0; i < this.genes.length; i++) {
            panelGenes.push(this.genes[i]);
        }
        var auxGene = this.containsGene(gene);

        // console.log("add gene:" + JSON.stringify(gene));

        if (auxGene) {
            auxGene.count++;
        } else {
            gene.count = 1;
            panelGenes.push(gene);
        }
        this._incModCount();
        this.polymer.set('formData.genes', panelGenes);
        this.polymer.$.geneTable.set("data", this.polymer.formData.genes);

    },
    addAllGenes: function (genes) {
        var panelGenes = [];

        for (var i = 0; i < this.genes.length; i++) {
            panelGenes.push(this.genes[i]);
        }

        for (var i = 0; i < genes.length; i++) {
            var elem = genes[i];
            var auxGene = this.containsGene(elem);

            if (auxGene) {
                auxGene.count++;
            } else {
                elem.count = 1;
                panelGenes.push(elem);
            }
            this._incModCount();
        }
        return panelGenes;
    },
    containsGene: function (gene) {
        for (var i = 0; i < this.genes.length; i++) {
            var elem = this.genes[i];
            if (elem.name === gene.name) {
                return elem;
            }
        }
        return null;
    },
    addMutation: function (mutation) {
      var panelMutations = [];

      for (var i = 0; i < this.mutations.length; i++) {
          panelMutations.push(this.mutations[i]);
      }
      var auxMutation = this.containsMutation(mutation);

      if (auxMutation) {
          auxMutation.count++;
      } else {
          mutation.count = 1;
          panelMutations.push(mutation);
      }
      this._incModCount();
      this.polymer.push('formData.mutations', mutation);
      this.polymer.$.mutationTable.set("data", this.polymer.formData.mutations);
    },
    containsMutation: function (mutation) {
        // var mutName = mutation.chr + "_" + mutation.pos + "_" + mutation.ref + "_" + mutation.alt + "_" + mutation.phe + "_" + mutation.src;
        // if (this.hashMutations[mutName]) { // mutName in hashMutations
        //     return true;
        // } else {
        //   this.hashMutations[mutName]=true;
        //
        for (var i = 0; i < this.mutations.length; i++) {
            var elem = this.mutations[i];
            if (elem.chr == mutation.chr &&
                elem.pos == mutation.pos &&
                elem.ref == mutation.ref &&
                elem.alt == mutation.alt &&
                elem.phe == mutation.phe &&
                elem.src == mutation.src) {
                return true;
            }
        }
        return false;
        // }
    },
    removeGenesFromDisease: function (disease) {
        if (disease.associatedGenes && disease.associatedGenes.length > 0) {
            for (var j = 0; j < disease.associatedGenes.length; j++) {
                var elem = disease.associatedGenes[j];
                if (elem.indexOf(",") >= 0) {
                    var splits = elem.split(",");
                    for (var k = 0; k < splits.length; k++) {
                        var gene = splits[k];
                        this.removeGene({
                            name: gene
                        });
                    }
                } else {
                    this.removeGene({
                        name: elem
                    });
                }
            }
        }

    },
    removeMutationsFromDisease: function (disease) {
        var mutations = [];
        for (var i = 0; i < this.mutations.length; i++) {
            var mutation = this.mutations[i];
            if (mutation.phe !== disease.phenotype) {
                mutations.push(mutation);

            }
        }
        this.polymer.set('formData.mutations', mutations);

    },
    removeGene: function (gene) {
        var index = -1;
        var g = null;
        for (var i = 0; g == null && i < this.genes.length; i++) {
            var elem = this.genes[i];
            if (elem.name === gene.name) {
                index = i;
                g = elem;
            }
        }

        if (g != null && index >= 0) {
            if (g.count > 1) {
                g.count--;
            } else {
                this.polymer.splice('formData.genes', index, 1);
            }
            this._incModCount();
        }
    },
    toJSON: function () {
        return {
            id: this.id,
            name: this.name,
            author: this.author,
            description: this.description,
            date: this.date,
            disease: this.disease,
            version: this.version,
            archived: this.archived,
            used: this.used,
            diseases: this.diseases,
            genes: this.genes,
            mutations: this.mutations
        }
    }
};

function PanelConfig(args) {
    this.id = Utils.genId("Panel");
    this.panels = [];
    this.panelHash = {};
    this.userInfo = args;
    this.polymer;

    var attrs = this.userInfo.attributes;

    if (!("team" in attrs)) {
        attrs.team = {};
    }

    if (!("panels" in attrs.team)) {
        attrs.team.panels = [];
    }

    this.panels = attrs.team.panels;

    for (var i = 0; i < this.panels.length; i++) {
        var panel = this.panels[i];
        this.panelHash[panel.fileId] = panel;
    }

    this._modCount = 0;
};
PanelConfig.prototype = {

    addPanelConfig: function (newPanelConfig) {
        if (newPanelConfig) {
            //this.panels.push(newPanelConfig);
            this.polymer.push("panelConfig.panels", newPanelConfig);
            this.panelHash[newPanelConfig.fileId] = newPanelConfig;
            this.savePanelConfig();

        }
    },
    savePanelConfig: function () {

        var url = OpencgaManager.users.update({
            id: this.userInfo.id,
            query: {
                sid: Cookies('bioinfo_sid'),
            },
            request: {
                method: "POST",
                url: true
            }
        });

        console.log(url);
        var data = {
            'attributes': {
                "team": this.userInfo.attributes.team
            }
        };

        //function createCORSRequest(method, url) {
        //    var xhr = new XMLHttpRequest();
        //    if ("withCredentials" in xhr) {
        //        xhr.open(method, url, true);
        //    } else if (typeof XDomainRequest != "undefined") {
        //        xhr = new XDomainRequest();
        //        xhr.open(method, url);
        //    } else {
        //        xhr = null;
        //    }
        //    return xhr;
        //}
        //
        //var request = createCORSRequest("POST", url);
        //if (request) {
        //    request.setRequestHeader("Content-Type", "application/json");
        //
        //    request.onload = function (e) {
        //        var response = JSON.parse(e.srcElement.response);
        //        //do something with request.responseText
        //    };
        //    request.onerror = function () {
        //        console.log("Error")
        //        debugger
        //    }
        //    request.send(JSON.stringify(data));
        //
        //}

        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);
        // xhr.setRequestHeader("Content-Type", "text/plain");
        // xhr.setRequestHeader("Content-Type", "application/json");

        xhr.onload = function (e) {
            console.log(JSON.parse(this.response));
        };
        xhr.send(JSON.stringify(data));

    },
    archivePanel: function (fileId) {
        this.panelHash[fileId].archived = !this.panelHash[fileId].archived;
        this.polymer.notifyPath('panelConfig.panels', this.panels);

        this._updatePanels();
        this.savePanelConfig();
    },
    _updatePanels: function () {
        var panels = [];
        for (var i = 0; i < this.panels.length; i++) {
            var panel = this.panels[i];
            panels.push(panel);
        }
        this.polymer.set('configPanel.panels', panels);

    }
}
<commit_msg>Solved bug in update panels<commit_after>function Panel(args) {
    this.id = Utils.genId("Panel");
    this.name = "";
    this.diseases = [];
    this.genes = [];
    this.mutations = [];
    this.name = "";
    this.author = "";
    this.description = "";
    this.date = "";
    this.disease = "";
    this.version = 1;
    this.archived = false;
    this.used = false;
    this.polymer;

    _.extend(this, args);

    this.modCount = 0;

    this.hashMutations = {};
};
Panel.prototype = {
    _incModCount: function () {
        this.modCount++;
    },
    addDiseases: function (diseases) {
        var me = this;
        var genes = [];

        for (var i = 0; i < diseases.length; i++) {
            var disease = diseases[i];
            if (!this.containsDisease(disease)) {
                delete disease._filtered;
                this.polymer.push('formData.diseases', disease);
                // this._emit("add-disease", disease);

                if (disease.associatedGenes && disease.associatedGenes.length > 0) {
                    for (var j = 0; j < disease.associatedGenes.length; j++) {
                        var assocGene = disease.associatedGenes[j];
                        if (!this._checkGenes(assocGene, this.genes)) {
                            genes.push(assocGene);
                        }
                    }
                }

                if (disease.source == "clinvar") {

                    CellBaseManager.get({
                        species: 'hsapiens',
                        category: 'feature',
                        subCategory: 'clinical',
                        resource: 'search',
                        async: false,
                        params: {
                            source: 'clinvar',
                            phenotype: disease.phenotype,
                            exclude: "annot,clinvarSet"
                        },
                        success: function (data) {
                            if (data.response && data.response.length > 0) {
                                var result = data.response[0].result;
                                for (var i = 0; i < result.length; i++) {
                                    var row = result[i];
                                    var mut = {

                                        chr: row.chromosome,
                                        pos: row.start,
                                        ref: row.reference,
                                        alt: row.alternate,
                                        phe: disease.phenotype,
                                        src: disease.source
                                    }
                                    me.addMutation(mut);

                                }
                            }
                        }
                    });
                }

            }

        }

        Utils.applyFunctionBatch(genes, 5, function (genes) {
            CellBaseManager.get({
                species: 'hsapiens',
                category: 'feature',
                subCategory: 'gene',
                resource: 'info',
                async: false,
                query: genes.join(","),
                params: {
                    include: "name,chromosome,start,end"
                },
                success: function (data) {

                    if (data.response && data.response.length > 0) {

                        for (var i = 0; i < data.response.length; i++) {
                            var geneElem = data.response[i];

                            if (geneElem.result.length > 0) {
                                var row = data.response[i].result[0];
                                var gene = {
                                    name: row.name,
                                    chr: row.chromosome,
                                    start: row.start,
                                    end: row.end
                                };
                                me.addGene(gene);

                            } else {
                                me.addGene({
                                    name: geneElem.id
                                });
                            }

                        }
                    }
                }
            });
        });
        this._incModCount();

    },
    addDisease: function (disease) {
        var me = this;
        if (!this.containsDisease(disease)) {
            delete disease._filtered
            this.polymer.push('formData.diseases', disease);

            if (disease.associatedGenes && disease.associatedGenes.length > 0) {
                var genes = [];
                for (var j = 0; j < disease.associatedGenes.length; j++) {
                    var assocGene = disease.associatedGenes[j];
                    if (!this._checkGenes(assocGene, this.genes)) {
                        genes.push(assocGene);
                    }
                }
                if (genes.length > 0) {

                    CellBaseManager.get({
                        species: 'hsapiens',
                        category: 'feature',
                        subCategory: 'gene',
                        resource: 'info',
                        async: false,
                        query: genes.join(","),
                        params: {
                            include: "name,chromosome,start,end"
                        },
                        success: function (data) {

                            if (data.response && data.response.length > 0) {

                                for (var i = 0; i < data.response.length; i++) {
                                    var geneElem = data.response[i];
                                    if (geneElem.result.length > 0) {
                                        var row = data.response[i].result[0];
                                        var gene = {
                                            name: row.name,
                                            chr: row.chromosome,
                                            start: row.start,
                                            end: row.end
                                        };
                                        me.addGene(gene);

                                    } else {
                                        me.addGene({
                                            name: geneElem.id
                                        });
                                    }

                                }
                            }
                        }
                    });

                }
            }

            if (disease.source == "clinvar") {
                CellBaseManager.get({
                    species: 'hsapiens',
                    category: 'feature',
                    subCategory: 'clinical',
                    resource: 'search',
                    async: false,
                    params: {
                        source: 'clinvar',
                        phenotype: disease.phenotype,
                        exclude: "annot,clinvarSet"
                    },
                    success: function (data) {
                        if (data.response && data.response.length > 0) {
                            var result = data.response[0].result;
                            for (var i = 0; i < result.length; i++) {
                                var row = result[i];
                                var mut = {

                                    chr: row.chromosome,
                                    pos: row.start,
                                    ref: row.reference,
                                    alt: row.alternate,
                                    phe: disease.phenotype,
                                    src: disease.source
                                }
                                me.addMutation(mut);

                            }
                        }
                    }
                });
            }

            this._incModCount();
        }
    },
    _checkGenes: function (assocGen, genes) {
        for (var j = 0; j < genes.length; j++) {
            if (assocGen == genes[j].name) {
                return true;
            }
        }
        return false;
    },
    addAllDiseases: function (diseases) {
        for (var i = 0; i < diseases.length; i++) {
            var disease = diseases[i];
            this.addDisease(disease);
        }
    },
    containsDisease: function (disease) {
        for (var i = 0; i < this.diseases.length; i++) {
            var elem = this.diseases[i];
            if (elem === disease) {
                return true;
            }
        }
        return false;
    },
    clearDiseases: function () {
        for (var i = 0; i < this.diseases.length; i++) {
            var disease = this.diseases[i];
            this.removeGenesFromDisease(disease);
            this.removeMutationsFromDisease(disease);
        }
        this.diseases = [];
        this.polymer.notifyPath('formData.diseases', this.diseases);
        this._incModCount();
    },
    clearGenes: function () {
        this.genes = [];
        this.polymer.notifyPath('formData.genes', this.genes);
        this._incModCount();
    },
    clearMutations: function () {
        this.mutations = [];
        this.polymer.notifyPath('formData.mutations', this.mutations);
        this._incModCount();
    },
    addGene: function (gene) {

        var panelGenes = [];

        for (var i = 0; i < this.genes.length; i++) {
            panelGenes.push(this.genes[i]);
        }
        var auxGene = this.containsGene(gene);

        // console.log("add gene:" + JSON.stringify(gene));

        if (auxGene) {
            auxGene.count++;
        } else {
            gene.count = 1;
            panelGenes.push(gene);
        }
        this._incModCount();
        this.polymer.set('formData.genes', panelGenes);
        this.polymer.$.geneTable.set("data", this.polymer.formData.genes);

    },
    addAllGenes: function (genes) {
        var panelGenes = [];

        for (var i = 0; i < this.genes.length; i++) {
            panelGenes.push(this.genes[i]);
        }

        for (var i = 0; i < genes.length; i++) {
            var elem = genes[i];
            var auxGene = this.containsGene(elem);

            if (auxGene) {
                auxGene.count++;
            } else {
                elem.count = 1;
                panelGenes.push(elem);
            }
            this._incModCount();
        }
        return panelGenes;
    },
    containsGene: function (gene) {
        for (var i = 0; i < this.genes.length; i++) {
            var elem = this.genes[i];
            if (elem.name === gene.name) {
                return elem;
            }
        }
        return null;
    },
    addMutation: function (mutation) {
      var panelMutations = [];

      for (var i = 0; i < this.mutations.length; i++) {
          panelMutations.push(this.mutations[i]);
      }
      var auxMutation = this.containsMutation(mutation);

      if (auxMutation) {
          auxMutation.count++;
      } else {
          mutation.count = 1;
          panelMutations.push(mutation);
      }
      this._incModCount();
      this.polymer.push('formData.mutations', mutation);
      this.polymer.$.mutationTable.set("data", this.polymer.formData.mutations);
    },
    containsMutation: function (mutation) {
        // var mutName = mutation.chr + "_" + mutation.pos + "_" + mutation.ref + "_" + mutation.alt + "_" + mutation.phe + "_" + mutation.src;
        // if (this.hashMutations[mutName]) { // mutName in hashMutations
        //     return true;
        // } else {
        //   this.hashMutations[mutName]=true;
        //
        for (var i = 0; i < this.mutations.length; i++) {
            var elem = this.mutations[i];
            if (elem.chr == mutation.chr &&
                elem.pos == mutation.pos &&
                elem.ref == mutation.ref &&
                elem.alt == mutation.alt &&
                elem.phe == mutation.phe &&
                elem.src == mutation.src) {
                return true;
            }
        }
        return false;
        // }
    },
    removeGenesFromDisease: function (disease) {
        if (disease.associatedGenes && disease.associatedGenes.length > 0) {
            for (var j = 0; j < disease.associatedGenes.length; j++) {
                var elem = disease.associatedGenes[j];
                if (elem.indexOf(",") >= 0) {
                    var splits = elem.split(",");
                    for (var k = 0; k < splits.length; k++) {
                        var gene = splits[k];
                        this.removeGene({
                            name: gene
                        });
                    }
                } else {
                    this.removeGene({
                        name: elem
                    });
                }
            }
        }

    },
    removeMutationsFromDisease: function (disease) {
        var mutations = [];
        for (var i = 0; i < this.mutations.length; i++) {
            var mutation = this.mutations[i];
            if (mutation.phe !== disease.phenotype) {
                mutations.push(mutation);

            }
        }
        this.polymer.set('formData.mutations', mutations);

    },
    removeGene: function (gene) {
        var index = -1;
        var g = null;
        for (var i = 0; g == null && i < this.genes.length; i++) {
            var elem = this.genes[i];
            if (elem.name === gene.name) {
                index = i;
                g = elem;
            }
        }

        if (g != null && index >= 0) {
            if (g.count > 1) {
                g.count--;
            } else {
                this.polymer.splice('formData.genes', index, 1);
            }
            this._incModCount();
        }
    },
    toJSON: function () {
        return {
            id: this.id,
            name: this.name,
            author: this.author,
            description: this.description,
            date: this.date,
            disease: this.disease,
            version: this.version,
            archived: this.archived,
            used: this.used,
            diseases: this.diseases,
            genes: this.genes,
            mutations: this.mutations
        }
    }
};

function PanelConfig(args) {
    this.id = Utils.genId("Panel");
    this.panels = [];
    this.panelHash = {};
    this.userInfo = args;
    this.polymer;

    var attrs = this.userInfo.attributes;

    if (!("team" in attrs)) {
        attrs.team = {};
    }

    if (!("panels" in attrs.team)) {
        attrs.team.panels = [];
    }

    this.panels = attrs.team.panels;

    for (var i = 0; i < this.panels.length; i++) {
        var panel = this.panels[i];
        this.panelHash[panel.fileId] = panel;
    }

    this._modCount = 0;
};
PanelConfig.prototype = {

    addPanelConfig: function (newPanelConfig) {
        if (newPanelConfig) {
            //this.panels.push(newPanelConfig);
            this.polymer.push("panelConfig.panels", newPanelConfig);
            this.panelHash[newPanelConfig.fileId] = newPanelConfig;
            this.savePanelConfig();

        }
    },
    savePanelConfig: function () {

        var url = OpencgaManager.users.update({
            id: this.userInfo.id,
            query: {
                sid: Cookies('bioinfo_sid'),
            },
            request: {
                method: "POST",
                url: true
            }
        });

        console.log(url);
        var data = {
            'attributes': {
                "team": this.userInfo.attributes.team
            }
        };

        //function createCORSRequest(method, url) {
        //    var xhr = new XMLHttpRequest();
        //    if ("withCredentials" in xhr) {
        //        xhr.open(method, url, true);
        //    } else if (typeof XDomainRequest != "undefined") {
        //        xhr = new XDomainRequest();
        //        xhr.open(method, url);
        //    } else {
        //        xhr = null;
        //    }
        //    return xhr;
        //}
        //
        //var request = createCORSRequest("POST", url);
        //if (request) {
        //    request.setRequestHeader("Content-Type", "application/json");
        //
        //    request.onload = function (e) {
        //        var response = JSON.parse(e.srcElement.response);
        //        //do something with request.responseText
        //    };
        //    request.onerror = function () {
        //        console.log("Error")
        //        debugger
        //    }
        //    request.send(JSON.stringify(data));
        //
        //}

        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);
        // xhr.setRequestHeader("Content-Type", "text/plain");
        xhr.setRequestHeader("Content-Type", "application/json");

        xhr.onload = function (e) {
            console.log(JSON.parse(this.response));
        };
        xhr.send(JSON.stringify(data));

    },
    archivePanel: function (fileId) {
        this.panelHash[fileId].archived = !this.panelHash[fileId].archived;
        this.polymer.notifyPath('panelConfig.panels', this.panels);

        this._updatePanels();
        this.savePanelConfig();
    },
    _updatePanels: function () {
        var panels = [];
        for (var i = 0; i < this.panels.length; i++) {
            var panel = this.panels[i];
            panels.push(panel);
        }
        this.polymer.set('configPanel.panels', panels);

    }
}
<|endoftext|>


<commit_before>'use strict';

require('./init');

const TransitProvider = require('../lib/providers/transit');
const STATUS_CODES = require('../lib/control/util/status-codes');
const preconditions = require('conditional');
const nock = require('nock');
const should = require('should');

/**
 * Create a mock Vault server
 *
 * @param {Object} options - Options to use when setting up a mock Vault server
 * @param {Boolean} options.global - True if the mocked Vault server should define setup API calls
 * @return {Nock} - The mock Vault server
 */
function createVaultMock(options) {
  const vaultHostname = `${(Config.get('vault:tls')) ? 'https' : 'http'}://${Config.get('vault:host')}:${Config.get('vault:port')}/`;

  if (!options.global) {
    return nock(vaultHostname);
  }

  return nock(vaultHostname).persist()
    .get('/v1/sys/init')
    .reply(STATUS_CODES.OK, {initialized: true})
    .get('/v1/sys/seal-status')
    .reply(STATUS_CODES.OK, {sealed: false, t: 1, n: 1, progress: 1})
    .get('/v1/sys/mounts')
    .reply(STATUS_CODES.OK, {'transit/': {config: {default_lease_ttl: 0, max_lease_ttl: 0}, type: 'transit'}})
    .get('/v1/sys/auth')
    .reply(STATUS_CODES.OK, {'token/': {type: 'token'}});
}

describe('Provider/Transit', function () {
  let globalVaultMock = null,
      localVaultMock = null;

  before(function () {
    globalVaultMock = createVaultMock({global: true});
  });

  beforeEach(function () {
    localVaultMock = createVaultMock({global: false});
  });

  afterEach(function () {
    nock.removeInterceptor(localVaultMock);
  });

  after(function () {
    nock.removeInterceptor(globalVaultMock);
  });

  describe('TransitProvider#constructor', function () {
    it('requires secret be provided', function () {
      [null, undefined, ''].forEach(function (value) {
        should.throws(() => {
          return new TransitProvider(value, 'TOKEN');
        }, preconditions.IllegalValueError, `invalid "secret" argument: ${value}`);
      });
    });

    it('requires token be provided', function () {
      [null, undefined, ''].forEach(function (value) {
        should.throws(() => {
          return new TransitProvider({key: 'KEY', ciphertext: 'CTEXT'}, value);
        }, preconditions.IllegalValueError, `invalid "token" argument: ${value}`);
      });
    });

    it('requires secret.key be provided', function () {
      [null, undefined, ''].forEach(function (value) {
        should.throws(() => {
          return new TransitProvider({key: value, ciphertext: 'CTEXT'}, 'TOKEN');
        }, preconditions.IllegalValueError, `invalid "secret.key" argument: ${value}`);
      });
    });

    it('requires secret.ciphertext be provided', function () {
      [null, undefined, ''].forEach(function (value) {
        should.throws(() => {
          return new TransitProvider({key: 'KEY', ciphertext: value}, 'TOKEN');
        }, preconditions.IllegalValueError, `invalid "secret.ciphertext" argument: ${value}`);
      });
    });
  });

  describe('TransitProvider#initialize', function () {
    it('calls Vault once when initializing', function (done) {
      const transit = new TransitProvider({key: 'KEY', ciphertext: 'CTEXT'}, 'TOKEN');

      localVaultMock.post('/v1/transit/decrypt/KEY', {
        ciphertext: 'CTEXT'
      })
      .reply(STATUS_CODES.OK, {
        plaintext: 'PTEXT'
      });

      transit.initialize()
      .then((retrievedPlaintext) => {
        should(retrievedPlaintext).eql({
          plaintext: 'PTEXT'
        });
      })
      .then(() => transit.initialize())
      .then((cachedPlaintext) => {
        should(cachedPlaintext).eql({
          plaintext: 'PTEXT'
        });

        localVaultMock.done();
        done();
      })
      .catch(done);
    });

    it('fails with an error if the key does not exist', function (done) {
      const transit = new TransitProvider({key: 'INVALID-KEY', ciphertext: 'CTEXT'}, 'TOKEN');

      localVaultMock.post('/v1/transit/decrypt/INVALID-KEY', {
        ciphertext: 'CTEXT'
      })
      .reply(STATUS_CODES.BAD_REQUEST, {
        errors: ['policy not found']
      });

      transit.initialize()
      .then(() => done(new Error('Invalid keys should fail!')))
      .catch((err) => {
        should(err).be.instanceOf(Error);

        localVaultMock.done();
        done();
      });
    });
  });

  describe('TransitProvider#renew', function () {
    it('calls Vault every time when renewing', function (done) {
      const transit = new TransitProvider({key: 'KEY', ciphertext: 'CTEXT'}, 'TOKEN');

      localVaultMock.post('/v1/transit/decrypt/KEY', {
        ciphertext: 'CTEXT'
      })
      .reply(STATUS_CODES.OK, {
        plaintext: 'PTEXT'
      })
      .post('/v1/transit/decrypt/KEY', {
        ciphertext: 'CTEXT'
      })
      .reply(STATUS_CODES.OK, {
        plaintext: 'PTEXT'
      });

      transit.renew()
      .then((retrievedPlaintext) => {
        should(retrievedPlaintext).eql({
          plaintext: 'PTEXT'
        });
      })
      .then(() => transit.renew())
      .then((renewedPlaintext) => {
        should(renewedPlaintext).eql({
          plaintext: 'PTEXT'
        });

        localVaultMock.done();
        done();
      })
      .catch(done);
    });

    it('fails with an error if the key does not exist', function (done) {
      const transit = new TransitProvider({key: 'INVALID-KEY', ciphertext: 'CTEXT'}, 'TOKEN');

      localVaultMock.post('/v1/transit/decrypt/INVALID-KEY', {
        ciphertext: 'CTEXT'
      })
      .reply(STATUS_CODES.BAD_REQUEST, {
        errors: ['policy not found']
      });

      transit.renew()
      .then(() => done(new Error('Invalid keys should fail!')))
      .catch((err) => {
        should(err).be.instanceOf(Error);

        localVaultMock.done();
        done();
      });
    });
  });
});
<commit_msg>Clean up from other tests that use nock. Tests are still broken!<commit_after>'use strict';

require('./init');

const TransitProvider = require('../lib/providers/transit');
const STATUS_CODES = require('../lib/control/util/status-codes');
const preconditions = require('conditional');
const nock = require('nock');
const should = require('should');

/**
 * Create a mock Vault server
 *
 * @param {Object} options - Options to use when setting up a mock Vault server
 * @param {Boolean} options.global - True if the mocked Vault server should define setup API calls
 * @return {Nock} - The mock Vault server
 */
function createVaultMock(options) {
  const vaultHostname = `${(Config.get('vault:tls')) ? 'https' : 'http'}://${Config.get('vault:host')}:${Config.get('vault:port')}/`;

  if (!options.global) {
    return nock(vaultHostname);
  }

  return nock(vaultHostname).persist()
    .get('/v1/sys/init')
    .reply(STATUS_CODES.OK, {initialized: true})
    .get('/v1/sys/seal-status')
    .reply(STATUS_CODES.OK, {sealed: false, t: 1, n: 1, progress: 1})
    .get('/v1/sys/mounts')
    .reply(STATUS_CODES.OK, {'transit/': {config: {default_lease_ttl: 0, max_lease_ttl: 0}, type: 'transit'}})
    .get('/v1/sys/auth')
    .reply(STATUS_CODES.OK, {'token/': {type: 'token'}});
}

describe('Provider/Transit', function () {
  let globalVaultMock = null,
      localVaultMock = null;

  before(function () {
    nock.cleanAll();
    globalVaultMock = createVaultMock({global: true});
  });

  beforeEach(function () {
    localVaultMock = createVaultMock({global: false});
  });

  afterEach(function () {
    nock.removeInterceptor(localVaultMock);
  });

  after(function () {
    nock.removeInterceptor(globalVaultMock);
    nock.cleanAll();
  });

  describe('TransitProvider#constructor', function () {
    it('requires secret be provided', function () {
      [null, undefined, ''].forEach(function (value) {
        should.throws(() => {
          return new TransitProvider(value, 'TOKEN');
        }, preconditions.IllegalValueError, `invalid "secret" argument: ${value}`);
      });
    });

    it('requires token be provided', function () {
      [null, undefined, ''].forEach(function (value) {
        should.throws(() => {
          return new TransitProvider({key: 'KEY', ciphertext: 'CTEXT'}, value);
        }, preconditions.IllegalValueError, `invalid "token" argument: ${value}`);
      });
    });

    it('requires secret.key be provided', function () {
      [null, undefined, ''].forEach(function (value) {
        should.throws(() => {
          return new TransitProvider({key: value, ciphertext: 'CTEXT'}, 'TOKEN');
        }, preconditions.IllegalValueError, `invalid "secret.key" argument: ${value}`);
      });
    });

    it('requires secret.ciphertext be provided', function () {
      [null, undefined, ''].forEach(function (value) {
        should.throws(() => {
          return new TransitProvider({key: 'KEY', ciphertext: value}, 'TOKEN');
        }, preconditions.IllegalValueError, `invalid "secret.ciphertext" argument: ${value}`);
      });
    });
  });

  describe('TransitProvider#initialize', function () {
    it('calls Vault once when initializing', function (done) {
      const transit = new TransitProvider({key: 'KEY', ciphertext: 'CTEXT'}, 'TOKEN');

      localVaultMock.post('/v1/transit/decrypt/KEY', {
        ciphertext: 'CTEXT'
      })
      .reply(STATUS_CODES.OK, {
        plaintext: 'PTEXT'
      });

      transit.initialize()
      .then((retrievedPlaintext) => {
        should(retrievedPlaintext).eql({
          plaintext: 'PTEXT'
        });
      })
      .then(() => transit.initialize())
      .then((cachedPlaintext) => {
        should(cachedPlaintext).eql({
          plaintext: 'PTEXT'
        });

        localVaultMock.done();
        done();
      })
      .catch(done);
    });

    it('fails with an error if the key does not exist', function (done) {
      const transit = new TransitProvider({key: 'INVALID-KEY', ciphertext: 'CTEXT'}, 'TOKEN');

      localVaultMock.post('/v1/transit/decrypt/INVALID-KEY', {
        ciphertext: 'CTEXT'
      })
      .reply(STATUS_CODES.BAD_REQUEST, {
        errors: ['policy not found']
      });

      transit.initialize()
      .then(() => done(new Error('Invalid keys should fail!')))
      .catch((err) => {
        should(err).be.instanceOf(Error);

        localVaultMock.done();
        done();
      });
    });
  });

  describe('TransitProvider#renew', function () {
    it('calls Vault every time when renewing', function (done) {
      const transit = new TransitProvider({key: 'KEY', ciphertext: 'CTEXT'}, 'TOKEN');

      localVaultMock.post('/v1/transit/decrypt/KEY', {
        ciphertext: 'CTEXT'
      })
      .reply(STATUS_CODES.OK, {
        plaintext: 'PTEXT'
      })
      .post('/v1/transit/decrypt/KEY', {
        ciphertext: 'CTEXT'
      })
      .reply(STATUS_CODES.OK, {
        plaintext: 'PTEXT'
      });

      transit.renew()
      .then((retrievedPlaintext) => {
        should(retrievedPlaintext).eql({
          plaintext: 'PTEXT'
        });
      })
      .then(() => transit.renew())
      .then((renewedPlaintext) => {
        should(renewedPlaintext).eql({
          plaintext: 'PTEXT'
        });

        localVaultMock.done();
        done();
      })
      .catch(done);
    });

    it('fails with an error if the key does not exist', function (done) {
      const transit = new TransitProvider({key: 'INVALID-KEY', ciphertext: 'CTEXT'}, 'TOKEN');

      localVaultMock.post('/v1/transit/decrypt/INVALID-KEY', {
        ciphertext: 'CTEXT'
      })
      .reply(STATUS_CODES.BAD_REQUEST, {
        errors: ['policy not found']
      });

      transit.renew()
      .then(() => done(new Error('Invalid keys should fail!')))
      .catch((err) => {
        should(err).be.instanceOf(Error);

        localVaultMock.done();
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>//value tips: hover over a name to see a pop-up with its current value
D.vt=function(w){'use strict' //.init(w) gets called for every window w (session or editor)
  var i,p,rf //i:timeout id, p:position as {line,ch}, rf:function that processes the reply
  var mrk //marker from https://codemirror.net/doc/manual.html#markText
  //╭─────────────╮
  //│             │ I.vt_bln   balloon
  //╰────.  .─────╯
  //      ╲╱        I.vt_tri   triangle, centred horizontally on the token
  // ┌ ─ ─ ─ ─ ┐
  //  t o k e n                rectangle around the token
  // └ ─ ─ ─ ─ ┘
  var MW=64,MH=32 //maxWidth and maxHeight for the character matrix displayed in the tooltip
  var cl=function(){ //clear all
    mrk&&mrk.clear();mrk=null;i&&clearTimeout(i);I.vt_bln.hidden=I.vt_tri.hidden=1;i=p=null
  }
  w.cm.on('cursorActivity',cl)
  var show=function(p0,force){ //p0:{line,ch}
    cl();p0.outside||(i=setTimeout(function(){ //send a request (but not too often)
      i=0;p=p0;var s=w.cm.getLine(p.line),c=s[p.ch]||' ',lbt=D.lb.tips[c]
      if((force||D.prf.squiggleTips())&&lbt&&!(c==='⎕'&&/[áa-z]/i.test(s[p.ch+1]||''))){
        rf({tip:lbt.join('\n\n').split('\n'),startCol:p.ch,endCol:p.ch+1}) //show tooltip from language bar
      }else if((force||D.prf.valueTips())&&/[^ \(\)\[\]\{\}':;]/.test(c)){
        D.send('GetValueTip',{win:w.id,line:s,pos:p.ch,token:w.id,maxWidth:MW,maxHeight:MH}) //ask interpreter
      }
    },500))
  }
  var oldX=0,oldY=0 //ignore "mousemove" when it's the result of the user pressing <ER> at the end of session
                    //without moving the mouse
  w.cm.display.wrapper.onmouseout=cl
  w.cm.display.wrapper.onmousemove=function(e){var x=e.clientX,y=e.clientY;if(x===oldX&&y===oldY)return
                                               show(w.cm.coordsChar({left:oldX=x,top:oldY=y}))}
  return{clear:cl,show:show,processReply:rf=function(x){
    if(!p)return
    var d=w.getDocument(),ce=w.cm.display.wrapper                 //ce:CodeMirror element
    ,cw=ce.clientWidth,cx=ce.clientLeft,cy=ce.clientTop           //CodeMirror's dimensions and coordinates
    ,de=d.documentElement,ww=de.clientWidth,wh=de.clientHeight    //window dimensions
    ,p0={line:p.line,ch:x.startCol} ,r0=w.cm.charCoords(p0)       //r0:bounding rectangle for start of token
    ,p1={line:p.line,ch:x.endCol}   ,r1=w.cm.charCoords(p1)       //r1:                   for end   of token
    ,rx=r0.left,ry=r0.top,rw=r1.right-r0.left,rh=r1.bottom-r0.top //bounding rectangle for whole token
    ,s=(x.tip.length<MH?x.tip:x.tip.slice(0,MH-1).concat('…'))
            .map(function(s){return s.length<MW?s:s.slice(0,MW-1)+'…'}).join('\n')
    ,be=I.vt_bln,te=I.vt_tri
    cl();be.hidden=te.hidden=0;be.textContent=s
    mrk=w.cm.markText(p0,p1,{className:'vt_marker'})
    var th=6,tw=2*th,inv=ry<wh-ry-rh                              //tw,th:triangle dimensions, inv:is upside-down?
    ,bp=0,bw=be.clientWidth,bh=be.clientHeight                    //balloon padding and dimensions
    ,bx=Math.max(0,Math.min(ww-bw,rx+(rw-bw)/2-bp))               //balloon coordinates
    ,by=inv?ry+rh+th:ry-bh-2*bp-th
    ,tx=rx+(rw-tw)/2,ty=inv?ry+rh:ry-th                           //triangle coordinates
    var bs=be.style;bs.left=bx+'px';bs.top=by<0?0:by+'px';bs.height=by<0?(ry-th-2*bp)+'px':'auto'
    var ts=te.style;ts.left=tx+'px';ts.top=ty+'px';te.className=inv?'inv':''
  }}
}
<commit_msg>re-centre value tip on token<commit_after>//value tips: hover over a name to see a pop-up with its current value
D.vt=function(w){'use strict' //.init(w) gets called for every window w (session or editor)
  var i,p,rf //i:timeout id, p:position as {line,ch}, rf:function that processes the reply
  var mrk //marker from https://codemirror.net/doc/manual.html#markText
  //╭─────────────╮
  //│             │ I.vt_bln   balloon
  //╰────.  .─────╯
  //      ╲╱        I.vt_tri   triangle, centred horizontally on the token
  // ┌ ─ ─ ─ ─ ┐
  //  t o k e n                rectangle around the token
  // └ ─ ─ ─ ─ ┘
  var MW=64,MH=32 //maxWidth and maxHeight for the character matrix displayed in the tooltip
  var cl=function(){ //clear all
    mrk&&mrk.clear();mrk=null;i&&clearTimeout(i);I.vt_bln.hidden=I.vt_tri.hidden=1;i=p=null
  }
  w.cm.on('cursorActivity',cl)
  var show=function(p0,force){ //p0:{line,ch}
    cl();p0.outside||(i=setTimeout(function(){ //send a request (but not too often)
      i=0;p=p0;var s=w.cm.getLine(p.line),c=s[p.ch]||' ',lbt=D.lb.tips[c]
      if((force||D.prf.squiggleTips())&&lbt&&!(c==='⎕'&&/[áa-z]/i.test(s[p.ch+1]||''))){
        rf({tip:lbt.join('\n\n').split('\n'),startCol:p.ch,endCol:p.ch+1}) //show tooltip from language bar
      }else if((force||D.prf.valueTips())&&/[^ \(\)\[\]\{\}':;]/.test(c)){
        D.send('GetValueTip',{win:w.id,line:s,pos:p.ch,token:w.id,maxWidth:MW,maxHeight:MH}) //ask interpreter
      }
    },500))
  }
  var oldX=0,oldY=0 //ignore "mousemove" when it's the result of the user pressing <ER> at the end of session
                    //without moving the mouse
  w.cm.display.wrapper.onmouseout=cl
  w.cm.display.wrapper.onmousemove=function(e){var x=e.clientX,y=e.clientY;if(x===oldX&&y===oldY)return
                                               show(w.cm.coordsChar({left:oldX=x,top:oldY=y}))}
  return{clear:cl,show:show,processReply:rf=function(x){
    if(!p)return
    var d=w.getDocument(),ce=w.cm.display.wrapper                 //ce:CodeMirror element
    ,cw=ce.clientWidth,cx=ce.clientLeft,cy=ce.clientTop           //CodeMirror's dimensions and coordinates
    ,de=d.documentElement,ww=de.clientWidth,wh=de.clientHeight    //window dimensions
    ,p0={line:p.line,ch:x.startCol}
    ,p1={line:p.line,ch:x.endCol}
    ,r0=w.cm.charCoords(p0)                                       //r0:bounding rectangle for start of token
    ,r1=w.cm.charCoords({line:p.line,ch:x.endCol-1})              //r1:                   for end   of token
    ,rx=r0.left,ry=r0.top,rw=r1.right-r0.left,rh=r1.bottom-r0.top //bounding rectangle for whole token
    ,s=(x.tip.length<MH?x.tip:x.tip.slice(0,MH-1).concat('…'))
            .map(function(s){return s.length<MW?s:s.slice(0,MW-1)+'…'}).join('\n')
    ,be=I.vt_bln,te=I.vt_tri
    cl();be.hidden=te.hidden=0;be.textContent=s
    mrk=w.cm.markText(p0,p1,{className:'vt_marker',inclusiveRight:0})
    var th=6,tw=2*th,inv=ry<wh-ry-rh                              //tw,th:triangle dimensions, inv:is upside-down?
    ,bp=0,bw=be.clientWidth,bh=be.clientHeight                    //balloon padding and dimensions
    ,bx=Math.max(0,Math.min(ww-bw,rx+(rw-bw)/2-bp))               //balloon coordinates
    ,by=inv?ry+rh+th:ry-bh-2*bp-th
    ,tx=rx+(rw-tw)/2,ty=inv?ry+rh:ry-th                           //triangle coordinates
    var bs=be.style;bs.left=bx+'px';bs.top=by<0?0:by+'px';bs.height=by<0?(ry-th-2*bp)+'px':'auto'
    var ts=te.style;ts.left=tx+'px';ts.top=ty+'px';te.className=inv?'inv':''
  }}
}
<|endoftext|>


<commit_before>/**
 * Execute a given function once the document has finished loading
 * @param  {Function} cb - Function to execute once the document has finished loading
 */
export default function domReady(once) {
  return (cb) => {
    if(typeof cb !== 'function') { return; }
    if(document.readyState === 'complete') { return cb(); }
    once(document, 'DOMContentLoaded', () => cb());
  };
}
<commit_msg>domReady: Create a 'domReadyBuilder' and imporve algorithm<commit_after>import _once from './once';
import isFunction from './isFunction';

/**
 * Build a method that executes a given function once the document has finished loading
 * @param  {Function} once - The 'once' (single trigger event) method to use
 * @return {Function} - The 'domready' method using the given once method
 */
export function domReadyBuilder(once = _once) {
  if(!isFunction(once)) { return null; }

  return (cb) => {
    if(!isFunction(cb)) { return; }
    if(document.readyState === 'complete') { return cb(); }
    once(document, 'DOMContentLoaded', () => cb());
  }
}

/**
 * Execute a given function once the document has finished loading
 * @param  {Function} cb - Function to execute once the document has finished loading
 */
const domReady = domReadyBuilder();
export default domReady;
<|endoftext|>


<commit_before>import superagentPromise from 'superagent-promise';
import _superagent from 'superagent';
import { authStore } from './stores/authStore';

const superagent = superagentPromise(_superagent, global.Promise);

const API_ROOT = process.env.REACT_APP_API_URL || 'http://localhost:5000/api';

const handleErrors = error => {
  if (error && error.response && error.response.status === 401) {
    authStore.logout();
  }
  return error;
};

const responseBody = res => res.body;

const tokenPlugin = req => {
  const token = window.localStorage.getItem('jwt');
  if (token) {
    req.set('authorization', `Token ${token}`);
  }
};

const requests = {
  del: url =>
    superagent
      .del(`${API_ROOT}${url}`)
      .use(tokenPlugin)
      .end(handleErrors)
      .then(responseBody),
  get: url =>
    superagent
      .get(`${API_ROOT}${url}`)
      .use(tokenPlugin)
      .end(handleErrors)
      .then(responseBody),
  put: (url, body) =>
    superagent
      .put(`${API_ROOT}${url}`, body)
      .use(tokenPlugin)
      .end(handleErrors)
      .then(responseBody),
  post: (url, body) =>
    superagent
      .post(`${API_ROOT}${url}`, body)
      .use(tokenPlugin)
      .end(handleErrors)
      .then(responseBody)
};

// prettier-ignore
const Auth = {
  current: () =>
    requests.get('/user'),
  login: (userid, password) =>
    requests.post('/users/login', { userid, password }),
  register: (username, email, password) =>
    requests.post('/users', { username, email, password }),
  save: user =>
    requests.put('/user', { user })
};

// prettier-ignore
const limit = (count, page) => `limit=${count}&offset=${page ? page * count : 0}`;

// prettier-ignore
const Profile = {
  follow: username =>
    requests.post(`/profiles/${username}/follow`),
  unfollow: username =>
    requests.del(`/profiles/${username}/follow`),
  get: username =>
    requests.get(`/profiles/${username}`)
};

// prettier-ignore
const Project = {
  all: (page, lim = 20) =>
    requests.get(`/projects?${limit(lim, page)}`),
  byAuthor: (username, page, lim=20) =>
    requests.get(`/projects?${limit(lim, page)}&author=${username}`),
  byFavorited: (username, page, lim=20) =>
    requests.get(`/projects?${limit(lim,page)}&favorited=${username}`),
  byTag: (tag, page, lim=20) =>
    requests.get(`/projects?${limit(lim, page)}$tag=${tag}`),
  get: slug =>
    requests.get(`/projects/${slug}`),
  edit: (slug, data) =>
    requests.put(`/projects/${slug}`, data),
  delete: slug =>
    requests.delete(`/projects/${slug}`),
  create: data =>
    requests.post('/projects', data),
  feed: (page, lim=20) =>
    requests.get(`/projects/feed?${limit(lim, page)}`),
  favorite: slug =>
    requests.post(`/projects/${slug}/favorite`),
  unfavorite: slug =>
    requests.delete(`/projects/${slug}/favorite`),
  getTheme: slug =>
    requests.get(`/projects/${slug}/theme`)
}

// prettier-ignore
const Field = {
  create: (label, spaceId, type, ...rest) =>
    requests.post('/fields', {
      label,
      spaceId,
      type,
      ...rest
    }),
  edit: (fieldId, ...items) =>
    requests.put(`/fields/${fieldId}`, {
      ...items
    })
}

// prettier-ignore
const Space = {
  allSpaces: slug =>
     requests.get(`/projects/${slug}/spaces`),
  create: slug =>
    requests.post(`/spaces`, { project_slug: slug }),
  delete: spaceId =>
    requests.del(`/spaces/${spaceId}`)
}

export default {
  Auth,
  Profile,
  Project,
  Space,
  Field
};
<commit_msg>added themes endpoint<commit_after>import superagentPromise from 'superagent-promise';
import _superagent from 'superagent';
import { authStore } from './stores/authStore';

const superagent = superagentPromise(_superagent, global.Promise);

const API_ROOT = process.env.REACT_APP_API_URL || 'http://localhost:5000/api';

const handleErrors = error => {
  if (error && error.response && error.response.status === 401) {
    authStore.logout();
  }
  return error;
};

const responseBody = res => res.body;

const tokenPlugin = req => {
  const token = window.localStorage.getItem('jwt');
  if (token) {
    req.set('authorization', `Token ${token}`);
  }
};

const requests = {
  del: url =>
    superagent
      .del(`${API_ROOT}${url}`)
      .use(tokenPlugin)
      .end(handleErrors)
      .then(responseBody),
  get: url =>
    superagent
      .get(`${API_ROOT}${url}`)
      .use(tokenPlugin)
      .end(handleErrors)
      .then(responseBody),
  put: (url, body) =>
    superagent
      .put(`${API_ROOT}${url}`, body)
      .use(tokenPlugin)
      .end(handleErrors)
      .then(responseBody),
  post: (url, body) =>
    superagent
      .post(`${API_ROOT}${url}`, body)
      .use(tokenPlugin)
      .end(handleErrors)
      .then(responseBody)
};

// prettier-ignore
const Auth = {
  current: () =>
    requests.get('/user'),
  login: (userid, password) =>
    requests.post('/users/login', { userid, password }),
  register: (username, email, password) =>
    requests.post('/users', { username, email, password }),
  save: user =>
    requests.put('/user', { user })
};

// prettier-ignore
const limit = (count, page) => `limit=${count}&offset=${page ? page * count : 0}`;

// prettier-ignore
const Profile = {
  follow: username =>
    requests.post(`/profiles/${username}/follow`),
  unfollow: username =>
    requests.del(`/profiles/${username}/follow`),
  get: username =>
    requests.get(`/profiles/${username}`)
};

// prettier-ignore
const Project = {
  all: (page, lim = 20) =>
    requests.get(`/projects?${limit(lim, page)}`),
  byAuthor: (username, page, lim=20) =>
    requests.get(`/projects?${limit(lim, page)}&author=${username}`),
  byFavorited: (username, page, lim=20) =>
    requests.get(`/projects?${limit(lim,page)}&favorited=${username}`),
  byTag: (tag, page, lim=20) =>
    requests.get(`/projects?${limit(lim, page)}$tag=${tag}`),
  get: slug =>
    requests.get(`/projects/${slug}`),
  edit: (slug, data) =>
    requests.put(`/projects/${slug}`, data),
  delete: slug =>
    requests.delete(`/projects/${slug}`),
  create: data =>
    requests.post('/projects', data),
  feed: (page, lim=20) =>
    requests.get(`/projects/feed?${limit(lim, page)}`),
  favorite: slug =>
    requests.post(`/projects/${slug}/favorite`),
  unfavorite: slug =>
    requests.delete(`/projects/${slug}/favorite`),
  getTheme: slug =>
    requests.get(`/projects/${slug}/theme`)
}

// prettier-ignore
const Field = {
  create: (label, spaceId, type, ...rest) =>
    requests.post('/fields', {
      label,
      spaceId,
      type,
      ...rest
    }),
  edit: (fieldId, ...items) =>
    requests.put(`/fields/${fieldId}`, {
      ...items
    })
}

// prettier-ignore
const Space = {
  allSpaces: slug =>
     requests.get(`/projects/${slug}/spaces`),
  create: slug =>
    requests.post(`/spaces`, { project_slug: slug }),
  delete: spaceId =>
    requests.del(`/spaces/${spaceId}`)
}

// prettier-ignore
const Theme = {
  all: () =>
    requests.get('/themes')
}

export default {
  Auth,
  Profile,
  Project,
  Space,
  Field,
  Theme
};
<|endoftext|>


<commit_before>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

function vote(current_blockchain, author, permlink, weight){

current_blockchain = current_blockchain.toLowerCase();
current_blockchain = current_blockchain + 'sig';

var wif = get_wif(current_blockchain);

if (wif.status  ==  'success'){
try{
    $('#icon_' + permlink).addClass('vote-process');
    pub_key = convert_to_pub_key_steem(wif.plaintext);

    check_pub_key_steem(pub_key, function steem_callback(err, result){
    if (!err){
        var voter = result[0][0];
        steem.broadcast.vote(wif.plaintext, voter, author, permlink, weight, function(err, result) {
            if (err) {
                $('#icon_' + permlink).removeClass('vote-process');
                alert (err);

            } else {
                 $('#icon_' + permlink).removeClass('vote-process');
                 $("#" + permlink).css('z-index', 10);

            };

        console.log(err, result);
        });

    }
    else {
        alert(err);
        $('#icon_' + permlink).removeClass('vote-process');

    }

   });

} catch(err){ alert('Key Error. Check your keys');}
} else alert('Key Error. Check your keys');

}

function down_vote(current_blockchain, author, permlink, weight){

current_blockchain = current_blockchain.toLowerCase();
current_blockchain = current_blockchain + 'sig';

var wif = get_wif(current_blockchain);

if (wif.status  ==  'success'){
try{
    $('#icon_' + permlink).addClass('vote-process');
    pub_key = convert_to_pub_key_steem(wif.plaintext);

 check_pub_key_steem(pub_key, function steem_callback(err, result){
    if (!err){
        var voter = result[0][0];
        steem.broadcast.downvote(wif.plaintext, voter, author, permlink, weight, function(err, result) {
            if (err) {
                alert (err);
                $('#icon_' + permlink).removeClass('vote-process');

            } else {
                 $('#icon_' + permlink).removeClass('vote-process');
                 $("#" + permlink).css('z-index', -1);

            };

        console.log(err, result);
        });

    }
    else {alert(err);
        $('#icon_' + permlink).removeClass('vote-process');

    }

   });

} catch(err){ alert('Key Error. Check your keys');}
} else alert('Key Error. Check your keys');

}

function comment (data, callback){
    var trx = new Array();
    data = JSON.parse(data);
    var blockchain = data.blockchain.toLowerCase() + 'sig';

    var wif = get_wif(blockchain);

    if (wif.status  ==  'success')
    try{
        pub_key = convert_to_pub_key_steem(wif.plaintext);

        check_pub_key_steem(pub_key, function steem_callback(err, result){

        if (!err){
            trx['parentAuthor'] = data.parentAuthor;
            trx['parentPermlink'] = data.parentPermlink;
            trx['author'] = result[0][0];
            trx['permlink'] = data.permlink;
            trx['title'] = data.title;
            trx['body'] = data.body;
            trx['metadata'] = data.metadata;

            //jsonMetadata = JSON.parse(trx['metadata']);

                console.log(trx);

                steem.broadcast.comment(wif.plaintext,
                trx['parentAuthor'],
                trx['parentPermlink'],
                trx['author'],
                trx['permlink'],
                trx['title'],
                trx['body'],
                trx['metadata'],
                function(err, result) {
                    console.log(err, result);

                    if (err == null){
                        setTimeout(redirect, 6000);
                    }
            });

        } else alert(err);

        });

    } catch(err){ alert('Key Error. Check your keys');}

}

function redirect(){
    document.location.href = '/site/show_single_blog';
}

function reply (data, callback){

    var trx = new Array();
    data = JSON.parse(data);
    var blockchain = data.blockchain.toLowerCase() + 'sig';

    var wif = get_wif(blockchain);

    if (wif.status  ==  'success')
    try{
        pub_key = convert_to_pub_key_steem(wif.plaintext);

        check_pub_key_steem(pub_key, function steem_callback(err, result){

        if (!err){
            trx['parentAuthor'] = data.parentAuthor;
            trx['parentPermlink'] = data.parentPermlink;
            trx['author'] = result[0][0];
            trx['permlink'] = 're-' + trx['author'] + '-' + data.permlink;
            trx['title'] = data.title;
            trx['body'] = data.body;
            trx['metadata'] = data.metadata;

            //jsonMetadata = JSON.parse(trx['metadata']);
            console.log(trx);

              steem.broadcast.comment(wif.plaintext,
                trx['parentAuthor'],
                trx['parentPermlink'],
                trx['author'],
                trx['permlink'],
                trx['title'],
                trx['body'],
                trx['metadata'],
                function(err, result) {
                    callback(result);
                    console.log(err, result);
            });

        } else alert(err);

        });

    } catch(err){ alert('Key Error. Check your keys');}

}
    <commit_msg>tr fix<commit_after>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

function vote(current_blockchain, author, permlink, weight){

current_blockchain = current_blockchain.toLowerCase();
current_blockchain = current_blockchain + 'sig';

var wif = get_wif(current_blockchain);

if (wif.status  ==  'success'){
try{
    $('#icon_' + permlink).addClass('vote-process');
    pub_key = convert_to_pub_key_steem(wif.plaintext);

    check_pub_key_steem(pub_key, function steem_callback(err, result){
    if (!err){
        var voter = result[0][0];
        steem.broadcast.vote(wif.plaintext, voter, author, permlink, weight, function(err, result) {
            if (err) {
                $('#icon_' + permlink).removeClass('vote-process');
                alert (err);

            } else {
                 $('#icon_' + permlink).removeClass('vote-process');
                 $("#" + permlink).css('z-index', 10);

            };

        console.log(err, result);
        });

    }
    else {
        alert(err);
        $('#icon_' + permlink).removeClass('vote-process');

    }

   });

} catch(err){ alert('Key Error. Check your keys');}
} else alert('Key Error. Check your keys');

}

function down_vote(current_blockchain, author, permlink, weight){

current_blockchain = current_blockchain.toLowerCase();
current_blockchain = current_blockchain + 'sig';

var wif = get_wif(current_blockchain);

if (wif.status  ==  'success'){
try{
    $('#icon_' + permlink).addClass('vote-process');
    pub_key = convert_to_pub_key_steem(wif.plaintext);

 check_pub_key_steem(pub_key, function steem_callback(err, result){
    if (!err){
        var voter = result[0][0];
        steem.broadcast.downvote(wif.plaintext, voter, author, permlink, weight, function(err, result) {
            if (err) {
                alert (err);
                $('#icon_' + permlink).removeClass('vote-process');

            } else {
                 $('#icon_' + permlink).removeClass('vote-process');
                 $("#" + permlink).css('z-index', -1);

            };

        console.log(err, result);
        });

    }
    else {alert(err);
        $('#icon_' + permlink).removeClass('vote-process');

    }

   });

} catch(err){ alert('Key Error. Check your keys');}
} else alert('Key Error. Check your keys');

}

function comment (data, callback){
    var trx = new Array();
    data = JSON.parse(data);
    var blockchain = data.blockchain.toLowerCase() + 'sig';

    var wif = get_wif(blockchain);

    if (wif.status  ==  'success')
    try{
        pub_key = convert_to_pub_key_steem(wif.plaintext);

        check_pub_key_steem(pub_key, function steem_callback(err, result){

        if (!err){
            trx['parentAuthor'] = data.parentAuthor;
            trx['parentPermlink'] = data.parentPermlink;
            trx['author'] = result[0][0];
            trx['permlink'] = data.permlink;
            trx['title'] = data.title;
            trx['body'] = data.body;
            trx['metadata'] = data.metadata;

            //jsonMetadata = JSON.parse(trx['metadata']);

                console.log(trx);

                steem.broadcast.comment(wif.plaintext,
                trx['parentAuthor'],
                trx['parentPermlink'],
                trx['author'],
                trx['permlink'],
                trx['title'],
                trx['body'],
                trx['metadata'],
                function(err, result) {
                    console.log(err, result);

                    if (err == null){
                        setTimeout(redirect, 7000);
                    }
            });

        } else alert(err);

        });

    } catch(err){ alert('Key Error. Check your keys');}

}

function redirect(){
    document.location.href = '/site/show_single_blog';
}

function reply (data, callback){

    var trx = new Array();
    data = JSON.parse(data);
    var blockchain = data.blockchain.toLowerCase() + 'sig';

    var wif = get_wif(blockchain);

    if (wif.status  ==  'success')
    try{
        pub_key = convert_to_pub_key_steem(wif.plaintext);

        check_pub_key_steem(pub_key, function steem_callback(err, result){

        if (!err){
            trx['parentAuthor'] = data.parentAuthor;
            trx['parentPermlink'] = data.parentPermlink;
            trx['author'] = result[0][0];
            trx['permlink'] = 're-' + trx['author'] + '-' + data.permlink;
            trx['title'] = data.title;
            trx['body'] = data.body;
            trx['metadata'] = data.metadata;

            //jsonMetadata = JSON.parse(trx['metadata']);
            console.log(trx);

              steem.broadcast.comment(wif.plaintext,
                trx['parentAuthor'],
                trx['parentPermlink'],
                trx['author'],
                trx['permlink'],
                trx['title'],
                trx['body'],
                trx['metadata'],
                function(err, result) {
                    callback(result);
                    console.log(err, result);
            });

        } else alert(err);

        });

    } catch(err){ alert('Key Error. Check your keys');}

}
    <|endoftext|>