<commit_before>var EventEmitter = require('events').EventEmitter;
var util         = require('util');
var UInt160      = require('./uint160').UInt160;
var Currency     = require('./currency').Currency;
var Transaction  = require('./transaction').Transaction;
var Account      = require('./account').Account;
var Meta         = require('./meta').Meta;
var OrderBook    = require('./orderbook').OrderBook;
var RippleError  = require('./rippleerror').RippleError;

// Request events emitted:
//  'success' : Request successful.
//  'error'   : Request failed.
//  'remoteError'
//  'remoteUnexpected'
//  'remoteDisconnected'
function Request(remote, command) {
  EventEmitter.call(this);

  this.remote     = remote;
  this.requested  = false;
  this.message    = {
    command : command,
    id      : void(0)
  };
};

util.inherits(Request, EventEmitter);

// Send the request to a remote.
Request.prototype.request = function (remote) {
  if (!this.requested) {
    this.requested = true;
    this.remote.request(this);
    this.emit('request', remote);
  }
};

Request.prototype.callback = function(callback, successEvent, errorEvent) {
  if (callback && typeof callback === 'function') {
    function request_success(message) {
      callback.call(this, null, message);
    }

    function request_error(error) {
      if (!(error instanceof RippleError)) {
        error = new RippleError(error);
      }
      callback.call(this, error);
    }

    this.once(successEvent || 'success', request_success);
    this.once(errorEvent   || 'error'  , request_error);
    this.request();
  }

  return this;
};

Request.prototype.timeout = function(duration, callback) {
  var self = this;

  if (!this.requested) {
    function requested() {
      self.timeout(duration, callback);
    }
    this.once('request', requested);
    return;
  }

  var emit      = this.emit;
  var timed_out = false;

  var timeout = setTimeout(function() {
    timed_out = true;
    if (typeof callback === 'function') callback();
    emit.call(self, 'timeout');
  }, duration);

  this.emit = function() {
    if (!timed_out) {
      clearTimeout(timeout);
      emit.apply(self, arguments);
    }
  };

  return this;
};

Request.prototype.set_server = function(server) {
  this.server = server;
};

Request.prototype.build_path = function (build) {
  if (build) {
    this.message.build_path = true;
  }
  return this;
};

Request.prototype.ledger_choose = function (current) {
  if (current) {
    this.message.ledger_index = this.remote._ledger_current_index;
  } else {
    this.message.ledger_hash  = this.remote._ledger_hash;
  }
  return this;
};

// Set the ledger for a request.
// - ledger_entry
// - transaction_entry
Request.prototype.ledger_hash = function (hash) {
  this.message.ledger_hash  = hash;
  return this;
};

// Set the ledger_index for a request.
// - ledger_entry
Request.prototype.ledger_index = function (ledger_index) {
  this.message.ledger_index  = ledger_index;
  return this;
};

Request.prototype.ledger_select = function (ledger_spec) {
  switch (ledger_spec) {
    case 'current':
    case 'closed':
    case 'verified':
      this.message.ledger_index = ledger_spec;
      break;

    default:
      // XXX Better test needed
      if (Number(ledger_spec)) {
        this.message.ledger_index = ledger_spec;
      } else {
        this.message.ledger_hash  = ledger_spec;
      }
      break;
  }

  return this;
};

Request.prototype.account_root = function (account) {
  this.message.account_root  = UInt160.json_rewrite(account);
  return this;
};

Request.prototype.index = function (hash) {
  this.message.index  = hash;
  return this;
};

// Provide the information id an offer.
// --> account
// --> seq : sequence number of transaction creating offer (integer)
Request.prototype.offer_id = function (account, seq) {
  this.message.offer = {
    account:  UInt160.json_rewrite(account),
    seq:      seq
  };
  return this;
};

// --> index : ledger entry index.
Request.prototype.offer_index = function (index) {
  this.message.offer  = index;
  return this;
};

Request.prototype.secret = function (secret) {
  if (secret) {
    this.message.secret  = secret;
  }
  return this;
};

Request.prototype.tx_hash = function (hash) {
  this.message.tx_hash  = hash;
  return this;
};

Request.prototype.tx_json = function (json) {
  this.message.tx_json  = json;
  return this;
};

Request.prototype.tx_blob = function (json) {
  this.message.tx_blob  = json;
  return this;
};

Request.prototype.ripple_state = function (account, issuer, currency) {
  this.message.ripple_state  = {
    currency : currency,
    accounts : [
      UInt160.json_rewrite(account),
      UInt160.json_rewrite(issuer)
    ]
  };
  return this;
};

Request.prototype.accounts = function (accounts, realtime) {
  if (!Array.isArray(accounts)) {
    accounts = [ accounts ];
  }

  // Process accounts parameters
  var processedAccounts = accounts.map(function(account) {
    return UInt160.json_rewrite(account);
  });

  if (realtime) {
    this.message.rt_accounts = processedAccounts;
  } else {
    this.message.accounts = processedAccounts;
  }

  return this;
};

Request.prototype.rt_accounts = function (accounts) {
  return this.accounts(accounts, true);
};

Request.prototype.books = function (books, snapshot) {
  var processedBooks = [ ];

  for (var i = 0, l = books.length; i < l; i++) {
    var book = books[i];
    var json = { };

    function processSide(side) {
      if (!book[side]) {
        throw new Error('Missing ' + side);
      }

      var obj = json[side] = {
        currency: Currency.json_rewrite(book[side].currency)
      };

      if (obj.currency !== 'XRP') {
        obj.issuer = UInt160.json_rewrite(book[side].issuer);
      }
    }

    processSide('taker_gets');
    processSide('taker_pays');

    if (snapshot) {
      json.snapshot = true;
    }

    if (book.both) {
      json.both = true;
    }

    processedBooks.push(json);
  }

  this.message.books = processedBooks;

  return this;
};

exports.Request = Request;
<commit_msg>Apply the scope of request to request callbacks<commit_after>var EventEmitter = require('events').EventEmitter;
var util         = require('util');
var UInt160      = require('./uint160').UInt160;
var Currency     = require('./currency').Currency;
var Transaction  = require('./transaction').Transaction;
var Account      = require('./account').Account;
var Meta         = require('./meta').Meta;
var OrderBook    = require('./orderbook').OrderBook;
var RippleError  = require('./rippleerror').RippleError;

// Request events emitted:
//  'success' : Request successful.
//  'error'   : Request failed.
//  'remoteError'
//  'remoteUnexpected'
//  'remoteDisconnected'
function Request(remote, command) {
  EventEmitter.call(this);

  this.remote     = remote;
  this.requested  = false;
  this.message    = {
    command : command,
    id      : void(0)
  };
};

util.inherits(Request, EventEmitter);

// Send the request to a remote.
Request.prototype.request = function (remote) {
  if (!this.requested) {
    this.requested = true;
    this.remote.request(this);
    this.emit('request', remote);
  }
};

Request.prototype.callback = function(callback, successEvent, errorEvent) {
  if (callback && typeof callback === 'function') {
    var self = this;

    function request_success(message) {
      callback.call(self, null, message);
    }

    function request_error(error) {
      if (!(error instanceof RippleError)) {
        error = new RippleError(error);
      }
      callback.call(self, error);
    }

    this.once(successEvent || 'success', request_success);
    this.once(errorEvent   || 'error'  , request_error);
    this.request();
  }

  return this;
};

Request.prototype.timeout = function(duration, callback) {
  var self = this;

  if (!this.requested) {
    function requested() {
      self.timeout(duration, callback);
    }
    this.once('request', requested);
    return;
  }

  var emit      = this.emit;
  var timed_out = false;

  var timeout = setTimeout(function() {
    timed_out = true;
    if (typeof callback === 'function') callback();
    emit.call(self, 'timeout');
  }, duration);

  this.emit = function() {
    if (!timed_out) {
      clearTimeout(timeout);
      emit.apply(self, arguments);
    }
  };

  return this;
};

Request.prototype.set_server = function(server) {
  this.server = server;
};

Request.prototype.build_path = function (build) {
  if (build) {
    this.message.build_path = true;
  }
  return this;
};

Request.prototype.ledger_choose = function (current) {
  if (current) {
    this.message.ledger_index = this.remote._ledger_current_index;
  } else {
    this.message.ledger_hash  = this.remote._ledger_hash;
  }
  return this;
};

// Set the ledger for a request.
// - ledger_entry
// - transaction_entry
Request.prototype.ledger_hash = function (hash) {
  this.message.ledger_hash  = hash;
  return this;
};

// Set the ledger_index for a request.
// - ledger_entry
Request.prototype.ledger_index = function (ledger_index) {
  this.message.ledger_index  = ledger_index;
  return this;
};

Request.prototype.ledger_select = function (ledger_spec) {
  switch (ledger_spec) {
    case 'current':
    case 'closed':
    case 'verified':
      this.message.ledger_index = ledger_spec;
      break;

    default:
      // XXX Better test needed
      if (Number(ledger_spec)) {
        this.message.ledger_index = ledger_spec;
      } else {
        this.message.ledger_hash  = ledger_spec;
      }
      break;
  }

  return this;
};

Request.prototype.account_root = function (account) {
  this.message.account_root  = UInt160.json_rewrite(account);
  return this;
};

Request.prototype.index = function (hash) {
  this.message.index  = hash;
  return this;
};

// Provide the information id an offer.
// --> account
// --> seq : sequence number of transaction creating offer (integer)
Request.prototype.offer_id = function (account, seq) {
  this.message.offer = {
    account:  UInt160.json_rewrite(account),
    seq:      seq
  };
  return this;
};

// --> index : ledger entry index.
Request.prototype.offer_index = function (index) {
  this.message.offer  = index;
  return this;
};

Request.prototype.secret = function (secret) {
  if (secret) {
    this.message.secret  = secret;
  }
  return this;
};

Request.prototype.tx_hash = function (hash) {
  this.message.tx_hash  = hash;
  return this;
};

Request.prototype.tx_json = function (json) {
  this.message.tx_json  = json;
  return this;
};

Request.prototype.tx_blob = function (json) {
  this.message.tx_blob  = json;
  return this;
};

Request.prototype.ripple_state = function (account, issuer, currency) {
  this.message.ripple_state  = {
    currency : currency,
    accounts : [
      UInt160.json_rewrite(account),
      UInt160.json_rewrite(issuer)
    ]
  };
  return this;
};

Request.prototype.accounts = function (accounts, realtime) {
  if (!Array.isArray(accounts)) {
    accounts = [ accounts ];
  }

  // Process accounts parameters
  var processedAccounts = accounts.map(function(account) {
    return UInt160.json_rewrite(account);
  });

  if (realtime) {
    this.message.rt_accounts = processedAccounts;
  } else {
    this.message.accounts = processedAccounts;
  }

  return this;
};

Request.prototype.rt_accounts = function (accounts) {
  return this.accounts(accounts, true);
};

Request.prototype.books = function (books, snapshot) {
  var processedBooks = [ ];

  for (var i = 0, l = books.length; i < l; i++) {
    var book = books[i];
    var json = { };

    function processSide(side) {
      if (!book[side]) {
        throw new Error('Missing ' + side);
      }

      var obj = json[side] = {
        currency: Currency.json_rewrite(book[side].currency)
      };

      if (obj.currency !== 'XRP') {
        obj.issuer = UInt160.json_rewrite(book[side].issuer);
      }
    }

    processSide('taker_gets');
    processSide('taker_pays');

    if (snapshot) {
      json.snapshot = true;
    }

    if (book.both) {
      json.both = true;
    }

    processedBooks.push(json);
  }

  this.message.books = processedBooks;

  return this;
};

exports.Request = Request;
<|endoftext|>


<commit_before>import $ from 'jquery';
import * as Backbone from 'backbone';
import * as _ from 'underscore';
import splitUp from '../utils/array-splitUp';
import Events from '../utils/backbone-events.js';
import AppRouter from '../routers/app-router.js';
import Projects from '../data/coll-projects.js';
import ProjectsView from '../views/projects-view.js';
import Topics from '../data/coll-topics.js';
import TopicsView from '../views/topics-view.js';
import Types from '../data/coll-types.js';
import TypesView from '../views/types-view.js';
import Sponsors from '../data/coll-sponsors.js';
import SponsorsView from '../views/sponsors-view.js';
import Years from '../data/coll-years.js';
import YearsView from '../views/years-view.js';
import ActiveProjects from '../data/coll-activeProjects.js';
import ActiveProjectsView from '../views/activeProjects-view.js';

class MRE extends Backbone.View {

    events() {
        return {
            'change #select_yr' : 'sortProjects',
            'click #reset_filters' : 'showAllProjects'
        };
    }

    sortProjects(e) {
        e.preventDefault();
        this.projsView.trigger("projects:sort", $(e.target).find(":selected").val());
    }

    initialize(options) {
        // Start router
        new AppRouter();

        // Keep track of active categories
        this.activeCategories = {};

        this.listenTo(Events, "app:updateCats", this.updateActiveCats);

        // Load projects and start subview
        var projs = new Projects();
        var projsView = new ProjectsView({collection: projs, el: '#mre_items div:first'});
        // Make projects view available to class:
        this.projsView = projsView;
        projs.url = options.projectsData;
        projs.deferred = projs.fetch();

        // Load all categories
        this.categories = {};

        // Load topics (subview is instatiated when all data is loaded)
        var topics = new Topics();
        this.categories["Topic"] = topics;
        topics.url = projs.url = options.topicsData;
        topics.deferred = topics.fetch();

        // Load types (subview is instatiated when all data is loaded)
        var types = new Types();
        this.categories["Type"] = types;
        types.url = projs.url = options.typesData;
        types.deferred = types.fetch();

        // Create sponsor and date collections
        var sponsorsTable = {};
        var sponsors = new Sponsors();
        this.categories["Sponsor"] = sponsors;

        var yearsTable = {};
        var years = new Years();
        this.categories["YearRange"] = years;

        var activeProjects = new ActiveProjects();
        this.categories["ActiveProject"] = activeProjects;
        // this is kind of a hack, but simplifies treating the active switch as a regular category:
        activeProjects.add({name:"true", slug:"active-true", narrower:[], broader:[]});

        // When projects and topics are loaded, assign projects to each topic
        // Maybe we could use ES6 promises here
        projs.deferred.done( function () {

            projsView.render();

            // Build table of projects by research type and topic
            var projsByType = {}
            var projsByTopic = {}
            projs.each(function(proj){
                let allTypes = proj.get("research_type");
                if (!allTypes) {
                    proj.set("research_type", ["Other"]);
                    allTypes = ["Other"];
                }
                for (let rType of allTypes) {
                    if (projsByType[rType]) {
                        projsByType[rType].push(proj);
                    }
                    else projsByType[rType] = [proj];
                }

                let allTopics = proj.get("topic");
                if (!allTopics) {
                    proj.set("topic", ["Other"]);
                    allTopics = ["Other"];
                }
                else {
                    for (let topic of allTopics) {
                        if (projsByTopic[topic]) {
                            projsByTopic[topic].push(proj);
                        }
                        else projsByTopic[topic] = [proj];
                    }
                }

                // While we're looping on projects, also populate collections for sponsors, dates, and activeprojects
                if (proj.get("research_sponsor")){
                    for (let sponsor of proj.get("research_sponsor")) {
                        if (Object.keys(sponsorsTable).indexOf(sponsor) == -1){
                            // Create sponsor and add to reference table
                            let spModel = sponsors.add({"name": sponsor});
                            spModel.get("projects").add(proj);
                            sponsorsTable[sponsor] = spModel.cid;
                        }
                        else {
                            // Add this project to existing sponsor
                            sponsors.get(sponsorsTable[sponsor]).get("projects").add(proj);
                        }
                    }
                }

                if (proj.get("start")){
                    let year = proj.get("start").substring(0,4);
                    if (Object.keys(yearsTable).indexOf(year) == -1){
                        // Add to reference table
                        yearsTable[year] = [proj];
                    }
                    else {
                        // Add this project to existing year
                        yearsTable[year].push(proj);
                    }
                }

                if (proj.get("active") == "true"){
                    activeProjects.first().get("projects").add(proj);
                }

            });

            // Group years
            let groupedYears = {}
            let sortedYears = Object.keys(yearsTable).sort();
            let yearRanges = splitUp(
                _.range(parseInt(sortedYears[0]), parseInt(sortedYears.slice(-1)[0])+1), 4
                );

            for (let yRange of yearRanges) {
                let projectsInRange = [];
                for (let y of yRange){
                    if (yearsTable[y]){
                        projectsInRange = projectsInRange.concat(yearsTable[y]);
                    }
                }
                let rangeString = yRange[0].toString() + " – " + yRange.slice(-1)[0].toString();
                let yrModel = years.add({"name": rangeString});
                yrModel.get("projects").add(projectsInRange);
            }

            topics.deferred.done( function () {

                topics.each(function(topic){
                    let name = topic.get("name");
                    topic.get("projects").add(projsByTopic[name]);

                    // Create nested collections
                    if (topic.get("narrower") ? topic.get("narrower").length : false){
                        let subset = new Topics;
                        topic.set("subset", subset);
                        for (let narrower of topic.get("narrower")) {
                            subset.add(topics.where({"name":narrower}));
                        }
                    }
                });
                // Now instantiate topics subview, but only for top level topics
                // (the other topics will be contained by the top level ones)
                let organizedTopics = new Backbone.Collection(topics.filter(function(topic){
                    return !topic.get("broader").length
                }));
                new TopicsView({el: '#topics', collection: organizedTopics}).render();
            });

            types.deferred.done( function () {

                types.each(function(type){
                    let name = type.get("name");
                    type.get("projects").add(projsByType[name]);

                    // Create nested collections
                    if (type.get("narrower") ? type.get("narrower").length : false){
                        let subset = new Types;
                        type.set("subset", subset);
                        for (let narrower of type.get("narrower")) {
                            subset.add(types.where({"name":narrower}));
                        }
                    }
                });
                // Now instantiate types subview, but only for top level types
                // (the other types will be contained by the top level ones)
                let organizedTypes = new Backbone.Collection(types.filter(function(type){
                    return !type.get("broader").length
                }));
                new TypesView({el: '#types', collection: organizedTypes}).render();
            });

            // Now instantiate sponsor and date views
            new SponsorsView({el: '#sponsors', collection: sponsors}).render();
            new YearsView({el: '#years', collection: years}).render();

            // Now instantiate active topic view
            new ActiveProjectsView({el: "#activeProjects", collection: activeProjects}).render();
        });
    }

    updateActiveCats(type){

        if (type) {
            let cat = this.categories[type];
            this.activeCategories[type] = cat.getActive();
        }
        else {
            this.activeCategories = {};
        }

        // Propagate to ProjectsView and CategoriesView
        Events.trigger("projects:intersect", this.activeCategories);
        Events.trigger("categories:updateProjectCounts");
    }

    showAllProjects(e) {
        e. preventDefault();
        Events.trigger("categories:uncheck:others", []);
    }

}

export default MRE;<commit_msg>removed silly code that checked for a boolean value as string<commit_after>import $ from 'jquery';
import * as Backbone from 'backbone';
import * as _ from 'underscore';
import splitUp from '../utils/array-splitUp';
import Events from '../utils/backbone-events.js';
import AppRouter from '../routers/app-router.js';
import Projects from '../data/coll-projects.js';
import ProjectsView from '../views/projects-view.js';
import Topics from '../data/coll-topics.js';
import TopicsView from '../views/topics-view.js';
import Types from '../data/coll-types.js';
import TypesView from '../views/types-view.js';
import Sponsors from '../data/coll-sponsors.js';
import SponsorsView from '../views/sponsors-view.js';
import Years from '../data/coll-years.js';
import YearsView from '../views/years-view.js';
import ActiveProjects from '../data/coll-activeProjects.js';
import ActiveProjectsView from '../views/activeProjects-view.js';

class MRE extends Backbone.View {

    events() {
        return {
            'change #select_yr' : 'sortProjects',
            'click #reset_filters' : 'showAllProjects'
        };
    }

    sortProjects(e) {
        e.preventDefault();
        this.projsView.trigger("projects:sort", $(e.target).find(":selected").val());
    }

    initialize(options) {
        // Start router
        new AppRouter();

        // Keep track of active categories
        this.activeCategories = {};

        this.listenTo(Events, "app:updateCats", this.updateActiveCats);

        // Load projects and start subview
        var projs = new Projects();
        var projsView = new ProjectsView({collection: projs, el: '#mre_items div:first'});
        // Make projects view available to class:
        this.projsView = projsView;
        projs.url = options.projectsData;
        projs.deferred = projs.fetch();

        // Load all categories
        this.categories = {};

        // Load topics (subview is instatiated when all data is loaded)
        var topics = new Topics();
        this.categories["Topic"] = topics;
        topics.url = projs.url = options.topicsData;
        topics.deferred = topics.fetch();

        // Load types (subview is instatiated when all data is loaded)
        var types = new Types();
        this.categories["Type"] = types;
        types.url = projs.url = options.typesData;
        types.deferred = types.fetch();

        // Create sponsor and date collections
        var sponsorsTable = {};
        var sponsors = new Sponsors();
        this.categories["Sponsor"] = sponsors;

        var yearsTable = {};
        var years = new Years();
        this.categories["YearRange"] = years;

        var activeProjects = new ActiveProjects();
        this.categories["ActiveProject"] = activeProjects;
        // this is kind of a hack, but simplifies treating the active switch as a regular category:
        activeProjects.add({name:"true", slug:"active-true", narrower:[], broader:[]});

        // When projects and topics are loaded, assign projects to each topic
        // Maybe we could use ES6 promises here
        projs.deferred.done( function () {

            projsView.render();

            // Build table of projects by research type and topic
            var projsByType = {}
            var projsByTopic = {}
            projs.each(function(proj){
                let allTypes = proj.get("research_type");
                if (!allTypes) {
                    proj.set("research_type", ["Other"]);
                    allTypes = ["Other"];
                }
                for (let rType of allTypes) {
                    if (projsByType[rType]) {
                        projsByType[rType].push(proj);
                    }
                    else projsByType[rType] = [proj];
                }

                let allTopics = proj.get("topic");
                if (!allTopics) {
                    proj.set("topic", ["Other"]);
                    allTopics = ["Other"];
                }
                else {
                    for (let topic of allTopics) {
                        if (projsByTopic[topic]) {
                            projsByTopic[topic].push(proj);
                        }
                        else projsByTopic[topic] = [proj];
                    }
                }

                // While we're looping on projects, also populate collections for sponsors, dates, and activeprojects
                if (proj.get("research_sponsor")){
                    for (let sponsor of proj.get("research_sponsor")) {
                        if (Object.keys(sponsorsTable).indexOf(sponsor) == -1){
                            // Create sponsor and add to reference table
                            let spModel = sponsors.add({"name": sponsor});
                            spModel.get("projects").add(proj);
                            sponsorsTable[sponsor] = spModel.cid;
                        }
                        else {
                            // Add this project to existing sponsor
                            sponsors.get(sponsorsTable[sponsor]).get("projects").add(proj);
                        }
                    }
                }

                if (proj.get("start")){
                    let year = proj.get("start").substring(0,4);
                    if (Object.keys(yearsTable).indexOf(year) == -1){
                        // Add to reference table
                        yearsTable[year] = [proj];
                    }
                    else {
                        // Add this project to existing year
                        yearsTable[year].push(proj);
                    }
                }

                if (proj.get("active")){
                    activeProjects.first().get("projects").add(proj);
                }

            });

            // Group years
            let groupedYears = {}
            let sortedYears = Object.keys(yearsTable).sort();
            let yearRanges = splitUp(
                _.range(parseInt(sortedYears[0]), parseInt(sortedYears.slice(-1)[0])+1), 4
                );

            for (let yRange of yearRanges) {
                let projectsInRange = [];
                for (let y of yRange){
                    if (yearsTable[y]){
                        projectsInRange = projectsInRange.concat(yearsTable[y]);
                    }
                }
                let rangeString = yRange[0].toString() + " – " + yRange.slice(-1)[0].toString();
                let yrModel = years.add({"name": rangeString});
                yrModel.get("projects").add(projectsInRange);
            }

            topics.deferred.done( function () {

                topics.each(function(topic){
                    let name = topic.get("name");
                    topic.get("projects").add(projsByTopic[name]);

                    // Create nested collections
                    if (topic.get("narrower") ? topic.get("narrower").length : false){
                        let subset = new Topics;
                        topic.set("subset", subset);
                        for (let narrower of topic.get("narrower")) {
                            subset.add(topics.where({"name":narrower}));
                        }
                    }
                });
                // Now instantiate topics subview, but only for top level topics
                // (the other topics will be contained by the top level ones)
                let organizedTopics = new Backbone.Collection(topics.filter(function(topic){
                    return !topic.get("broader").length
                }));
                new TopicsView({el: '#topics', collection: organizedTopics}).render();
            });

            types.deferred.done( function () {

                types.each(function(type){
                    let name = type.get("name");
                    type.get("projects").add(projsByType[name]);

                    // Create nested collections
                    if (type.get("narrower") ? type.get("narrower").length : false){
                        let subset = new Types;
                        type.set("subset", subset);
                        for (let narrower of type.get("narrower")) {
                            subset.add(types.where({"name":narrower}));
                        }
                    }
                });
                // Now instantiate types subview, but only for top level types
                // (the other types will be contained by the top level ones)
                let organizedTypes = new Backbone.Collection(types.filter(function(type){
                    return !type.get("broader").length
                }));
                new TypesView({el: '#types', collection: organizedTypes}).render();
            });

            // Now instantiate sponsor and date views
            new SponsorsView({el: '#sponsors', collection: sponsors}).render();
            new YearsView({el: '#years', collection: years}).render();

            // Now instantiate active topic view
            new ActiveProjectsView({el: "#activeProjects", collection: activeProjects}).render();
        });
    }

    updateActiveCats(type){

        if (type) {
            let cat = this.categories[type];
            this.activeCategories[type] = cat.getActive();
        }
        else {
            this.activeCategories = {};
        }

        // Propagate to ProjectsView and CategoriesView
        Events.trigger("projects:intersect", this.activeCategories);
        Events.trigger("categories:updateProjectCounts");
    }

    showAllProjects(e) {
        e. preventDefault();
        Events.trigger("categories:uncheck:others", []);
    }

}

export default MRE;<|endoftext|>


<commit_before>import { makeKernel } from '../utilities/kernel'
import { setStride, setPadding } from '../utilities/layer-setup'
import { Filter } from './types'
import randos2D from '../utilities/randos-2d'
import zeros2D from '../utilities/zeros-2d'
import randos from '../utilities/randos'

export function predict(inputs, filters, biases) {
  const x =
    (this.thread.x / this.output.x) *
      this.constants.inputWidth *
      this.constants.strideX -
    this.constants.paddingX
  const y =
    (this.thread.y / this.output.y) *
      this.constants.inputHeight *
      this.constants.strideY -
    this.constants.paddingY

  // convolve centered at this particular location
  let sum = 0
  for (let filterY = 0; filterY < this.constants.filterHeight; filterY++) {
    // coordinates in the original input array coordinates
    const inputY = filterY + y
    for (let filterX = 0; filterX < this.constants.filterWidth; filterX++) {
      const inputX = filterX + x
      if (
        inputY >= 0 &&
        inputY < this.constants.inputHeight &&
        inputX >= 0 &&
        inputX < this.constants.inputWidth
      ) {
        for (
          let inputIndex = 0;
          inputIndex < this.constants.inputDepth;
          inputIndex++
        ) {
          for (
            let filterIndex = 0;
            filterIndex < this.constants.filterCount;
            filterIndex++
          ) {
            sum +=
              filters[filterIndex][filterY][filterX] *
              inputs[inputIndex][inputY][inputX]
          }
        }
      }
    }
  }
  return sum + biases[this.thread.z]
}

export function compareFilters(inputs, deltas) {
  let sum = 0
  const delta =
    deltas[this.thread.z][this.thread.y * this.constants.paddingY][
      this.thread.x * this.constants.paddingX
    ]
  const inputXMax = this.constants.inputWidth + this.constants.paddingX
  const inputYMax = this.constants.inputHeight + this.constants.paddingY
  for (
    let inputY = this.thread.y - this.constants.paddingY;
    inputY < inputYMax;
    inputY += this.constants.strideY
  ) {
    for (
      let inputX = this.thread.x - this.constants.paddingX;
      inputX < inputXMax;
      inputX += this.constants.strideX
    ) {
      if (
        inputY >= 0 &&
        inputY < this.constants.inputHeight &&
        inputX >= 0 &&
        inputX < this.constants.inputWidth
      ) {
        for (
          let inputIndex = 0;
          inputIndex < this.constants.inputDepth;
          inputIndex++
        ) {
          sum += inputs[inputIndex][inputY][inputX] * delta
        }
      }
    }
  }
  return sum
}

export function compareInputs(filters, deltas) {
  let sum = 0
  for (let filterY = 0; filterY <= this.thread.y; filterY++) {
    let offsetY = this.thread.y - filterY
    for (let filterX = 0; filterX <= this.thread.x; filterX++) {
      let offsetX = this.thread.x - filterX
      for (
        let filterIndex = 0;
        filterIndex < this.constants.filterCount;
        filterIndex++
      ) {
        sum +=
          filters[filterIndex][offsetY][offsetX] *
          deltas[filterIndex][filterY][filterX]
      }
      offsetX--
    }
    offsetY--
  }
  return sum
}

export function compareBiases(biasDeltas, deltas) {
  let sum = 0
  for (let y = 0; y < this.constants.y; y++) {
    for (let x = 0; x < this.constants.x; x++) {
      sum += deltas[this.thread.z][y][x]
    }
  }
  return biasDeltas[this.thread.z] + sum
}

export default class Convolution extends Filter {
  static get defaults() {
    return {
      stride: 0,
      padding: 0,
      bias: 0.1,
      filterCount: 1,
      filterWidth: 0,
      filterHeight: 0,
    }
  }

  constructor(settings, inputLayer) {
    super(settings)

    this.stride = null
    this.strideX = null
    this.strideY = null
    setStride(this, settings)

    this.padding = null
    this.paddingX = null
    this.paddingY = null
    setPadding(this, settings)

    this.filterCount = settings.filterCount
    this.filterWidth = settings.filterWidth
    this.filterHeight = settings.filterHeight

    this.width = Math.floor(
      (inputLayer.width + this.paddingX * 2 - this.filterWidth) / this.strideX +
        1
    )
    this.height = Math.floor(
      (inputLayer.height + this.paddingY * 2 - this.filterHeight) /
        this.strideY +
        1
    )
    this.depth = this.filterCount

    this.biases = new Array(this.depth)
    this.biases.fill(this.bias)
    this.biasDeltas = randos(this.depth)

    this.filters = []
    this.filterDeltas = []

    for (let i = 0; i < this.filterCount; i++) {
      this.filters.push(randos2D(this.filterWidth, this.filterHeight))
      this.filterDeltas.push(zeros2D(this.filterWidth, this.filterHeight))
    }

    this.learnFilters = null
    this.learnInputs = null
    this.inputLayer = inputLayer
    this.validate()
  }

  setupKernels() {
    this.predictKernel = makeKernel(predict, {
      constants: {
        inputWidth: this.inputLayer.width,
        inputHeight: this.inputLayer.height,
        inputDepth: this.inputLayer.depth,
        strideX: this.strideX,
        strideY: this.strideY,
        paddingX: this.paddingX,
        paddingY: this.paddingY,
        filterCount: this.filterCount,
        filterWidth: this.filterWidth,
        filterHeight: this.filterHeight,
      },
      output: [this.width, this.height, this.depth],
    })

    this.compareFiltersKernel = makeKernel(compareFilters, {
      constants: {
        inputWidth: this.inputLayer.width,
        inputHeight: this.inputLayer.height,
        inputDepth: this.inputLayer.depth,
        strideX: this.strideX,
        strideY: this.strideY,
        paddingX: this.paddingX,
        paddingY: this.paddingY,
        filterCount: this.filterCount,
        filterWidth: this.filterWidth,
        filterHeight: this.filterHeight,
      },
      output: [this.width, this.height, this.depth],
    })

    this.compareInputsKernel = makeKernel(compareInputs, {
      constants: {
        filterCount: this.filterCount,
      },
      output: [
        this.inputLayer.width,
        this.inputLayer.height,
        this.inputLayer.depth,
      ],
    })

    this.compareBiasesKernel = makeKernel(compareBiases, {
      output: [1, 1, this.inputLayer.depth],
      constants: {
        x: 1,
        y: 1,
      },
    })
  }

  predict() {
    this.weights = this.predictKernel(
      this.inputLayer.weights,
      this.filters,
      this.biases
    )
  }

  compare() {
    this.filterDeltas = this.compareFiltersKernel(
      this.inputLayer.weights,
      this.deltas
    )
    this.biasDeltas = this.compareBiasesKernel(this.biasDeltas, this.deltas)
    this.deltas = this.compareInputsKernel(this.filters, this.inputLayer.deltas)
    this.inputLayer.deltas = this.deltas
  }

  learn(previousLayer, nextLayer, learningRate) {
    // TODO: handle filters
    this.weights = this.praxis.run(this, previousLayer, nextLayer, learningRate)
    this.deltas = zeros2D(this.width, this.height)
  }
}
<commit_msg>fix: add `weights` and `deltas` handling to `Convolution`<commit_after>import { makeKernel } from '../utilities/kernel'
import { setStride, setPadding } from '../utilities/layer-setup'
import { Filter } from './types'
import randos from '../utilities/randos'
import randos3D from '../utilities/randos-3d'
import zeros3D from '../utilities/zeros-3d'
import values from '../utilities/values'

export function predict(inputs, filters, biases) {
  const x =
    (this.thread.x / this.output.x) *
      this.constants.inputWidth *
      this.constants.strideX -
    this.constants.paddingX
  const y =
    (this.thread.y / this.output.y) *
      this.constants.inputHeight *
      this.constants.strideY -
    this.constants.paddingY

  // convolve centered at this particular location
  let sum = 0
  for (let filterY = 0; filterY < this.constants.filterHeight; filterY++) {
    // coordinates in the original input array coordinates
    const inputY = filterY + y
    for (let filterX = 0; filterX < this.constants.filterWidth; filterX++) {
      const inputX = filterX + x
      if (
        inputY >= 0 &&
        inputY < this.constants.inputHeight &&
        inputX >= 0 &&
        inputX < this.constants.inputWidth
      ) {
        for (
          let inputIndex = 0;
          inputIndex < this.constants.inputDepth;
          inputIndex++
        ) {
          for (
            let filterIndex = 0;
            filterIndex < this.constants.filterCount;
            filterIndex++
          ) {
            sum +=
              filters[filterIndex][filterY][filterX] *
              inputs[inputIndex][inputY][inputX]
          }
        }
      }
    }
  }
  return sum + biases[this.thread.z]
}

export function compareFilters(inputs, deltas) {
  let sum = 0
  const delta =
    deltas[this.thread.z][this.thread.y * this.constants.paddingY][
      this.thread.x * this.constants.paddingX
    ]
  const inputXMax = this.constants.inputWidth + this.constants.paddingX
  const inputYMax = this.constants.inputHeight + this.constants.paddingY
  for (
    let inputY = this.thread.y - this.constants.paddingY;
    inputY < inputYMax;
    inputY += this.constants.strideY
  ) {
    for (
      let inputX = this.thread.x - this.constants.paddingX;
      inputX < inputXMax;
      inputX += this.constants.strideX
    ) {
      if (
        inputY >= 0 &&
        inputY < this.constants.inputHeight &&
        inputX >= 0 &&
        inputX < this.constants.inputWidth
      ) {
        for (
          let inputIndex = 0;
          inputIndex < this.constants.inputDepth;
          inputIndex++
        ) {
          sum += inputs[inputIndex][inputY][inputX] * delta
        }
      }
    }
  }
  return sum
}

export function compareInputs(filters, deltas) {
  let sum = 0
  for (let filterY = 0; filterY <= this.thread.y; filterY++) {
    let offsetY = this.thread.y - filterY
    for (let filterX = 0; filterX <= this.thread.x; filterX++) {
      let offsetX = this.thread.x - filterX
      for (
        let filterIndex = 0;
        filterIndex < this.constants.filterCount;
        filterIndex++
      ) {
        sum +=
          filters[filterIndex][offsetY][offsetX] *
          deltas[filterIndex][filterY][filterX]
      }
      offsetX--
    }
    offsetY--
  }
  return sum
}

export function compareBiases(biasDeltas, deltas) {
  let sum = 0
  for (let y = 0; y < this.constants.y; y++) {
    for (let x = 0; x < this.constants.x; x++) {
      sum += deltas[this.thread.z][y][x]
    }
  }
  return biasDeltas[this.thread.z] + sum
}

export default class Convolution extends Filter {
  static get defaults() {
    return {
      stride: 0,
      padding: 0,
      bias: 0.1,
      filterCount: 1,
      filterWidth: 0,
      filterHeight: 0,
    }
  }

  constructor(settings, inputLayer) {
    super(settings)

    this.stride = null
    this.strideX = null
    this.strideY = null
    setStride(this, settings)

    this.padding = null
    this.paddingX = null
    this.paddingY = null
    setPadding(this, settings)

    this.filterCount = settings.filterCount
    this.filterWidth = settings.filterWidth
    this.filterHeight = settings.filterHeight

    this.width = Math.floor(
      (inputLayer.width + this.paddingX * 2 - this.filterWidth) / this.strideX +
        1
    )
    this.height = Math.floor(
      (inputLayer.height + this.paddingY * 2 - this.filterHeight) /
        this.strideY +
        1
    )
    this.depth = this.filterCount
    this.weights = randos3D(this.width, this.height, this.depth)
    this.deltas = zeros3D(this.width, this.height, this.depth)

    this.biases = values(this.depth, this.bias)
    this.biasDeltas = randos(this.depth)

    this.filters = randos3D(this.filterWidth, this.filterHeight, this.filterCount)
    this.filterDeltas = zeros3D(this.filterWidth, this.filterHeight, this.filterCount)

    this.learnFilters = null
    this.learnInputs = null
    this.inputLayer = inputLayer
    this.validate()
  }

  setupKernels() {
    this.predictKernel = makeKernel(predict, {
      constants: {
        inputWidth: this.inputLayer.width,
        inputHeight: this.inputLayer.height,
        inputDepth: this.inputLayer.depth,
        strideX: this.strideX,
        strideY: this.strideY,
        paddingX: this.paddingX,
        paddingY: this.paddingY,
        filterCount: this.filterCount,
        filterWidth: this.filterWidth,
        filterHeight: this.filterHeight,
      },
      output: [this.width, this.height, this.depth],
    })

    this.compareFiltersKernel = makeKernel(compareFilters, {
      constants: {
        inputWidth: this.inputLayer.width,
        inputHeight: this.inputLayer.height,
        inputDepth: this.inputLayer.depth,
        strideX: this.strideX,
        strideY: this.strideY,
        paddingX: this.paddingX,
        paddingY: this.paddingY,
        filterCount: this.filterCount,
        filterWidth: this.filterWidth,
        filterHeight: this.filterHeight,
      },
      output: [this.width, this.height, this.depth],
    })

    this.compareInputsKernel = makeKernel(compareInputs, {
      constants: {
        filterCount: this.filterCount,
      },
      output: [
        this.inputLayer.width,
        this.inputLayer.height,
        this.inputLayer.depth,
      ],
    })

    this.compareBiasesKernel = makeKernel(compareBiases, {
      output: [1, 1, this.inputLayer.depth],
      constants: {
        x: 1,
        y: 1,
      },
    })
  }

  predict() {
    this.weights = this.predictKernel(
      this.inputLayer.weights,
      this.filters,
      this.biases
    )
  }

  compare() {
    this.filterDeltas = this.compareFiltersKernel(
      this.inputLayer.weights,
      this.deltas
    )
    this.biasDeltas = this.compareBiasesKernel(this.biasDeltas, this.deltas)
    this.deltas = this.compareInputsKernel(this.filters, this.inputLayer.deltas)
    this.inputLayer.deltas = this.deltas
  }

  learn(previousLayer, nextLayer, learningRate) {
    // TODO: handle filters
    this.weights = this.praxis.run(this, previousLayer, nextLayer, learningRate)
    this.deltas = zeros3D(this.width, this.height, this.depth)
  }
}
<|endoftext|>


<commit_before>import Layer from '../Layer'
import Tensor from '../Tensor'
import _ from 'lodash'

/**
 * InputLayer layer class
 */
export default class InputLayer extends Layer {
  /**
   * Creates an InputLayer layer
   *
   * @param {Object} [attrs] - layer attributes
   */
  constructor(attrs = {}) {
    super(attrs)
    this.layerClass = 'InputLayer'

    const { shape = [] } = attrs

    this.shape = attrs.batch_input_shape && attrs.batch_input_shape.length ? attrs.batch_input_shape.slice(1) : shape
  }

  /**
   * Layer computational logic
   *
   * @param {Tensor} x
   * @returns {Tensor}
   */
  call(x) {
    if (this.gpu) {
      this._callGPU(x)
    } else {
      this._callCPU(x)
    }
    return this.output
  }

  /**
   * CPU call
   *
   * @param {Tensor} x
   */
  _callCPU(x) {
    this.inputShape = x.tensor.shape
    if (!_.isEqual(this.inputShape, this.shape)) {
      this.throwError(`input tensor shape ${x.tensor.shape} does not match specified shape ${this.shape}.`)
    }
    this.output = new Tensor(x.tensor.data, x.tensor.shape)
  }

  /**
   * GPU call
   *
   * @param {Tensor} x
   */
  _callGPU(x) {
    if (!x.glTexture) {
      this.inputShape = x.tensor.shape
    } else {
      if (x.is2DReshaped || x.is2DSquareReshaped) {
        this.inputShape = x.originalShape
      } else {
        this.inputShape = x.tensor.shape
      }
    }

    if (!_.isEqual(this.inputShape, this.shape)) {
      this.throwError(`input tensor shape ${x.tensor.shape} does not match specified shape ${this.shape}.`)
    }

    if (!x.glTexture) {
      if (x.tensor.shape.length <= 2) {
        x.createGLTexture({ type: '2d', format: 'float' })
      } else if (x.tensor.shape.length > 2) {
        x.reshapeTo2DSquare()
        x.createGLTexture({ type: '2d', format: 'float' })
      }
    }

    this.output = x
  }
}
<commit_msg>fix InputLayer gpu mode when output cannot handle is2DSquareReshaped Tensors<commit_after>import Layer from '../Layer'
import Tensor from '../Tensor'
import _ from 'lodash'

/**
 * InputLayer layer class
 */
export default class InputLayer extends Layer {
  /**
   * Creates an InputLayer layer
   *
   * @param {Object} [attrs] - layer attributes
   */
  constructor(attrs = {}) {
    super(attrs)
    this.layerClass = 'InputLayer'

    const { shape = [] } = attrs

    this.shape = attrs.batch_input_shape && attrs.batch_input_shape.length ? attrs.batch_input_shape.slice(1) : shape
  }

  /**
   * Layer computational logic
   *
   * @param {Tensor} x
   * @returns {Tensor}
   */
  call(x) {
    if (this.gpu) {
      this._callGPU(x)
    } else {
      this._callCPU(x)
    }
    return this.output
  }

  /**
   * CPU call
   *
   * @param {Tensor} x
   */
  _callCPU(x) {
    this.inputShape = x.tensor.shape
    if (!_.isEqual(this.inputShape, this.shape)) {
      this.throwError(`input tensor shape ${x.tensor.shape} does not match specified shape ${this.shape}.`)
    }
    this.output = new Tensor(x.tensor.data, x.tensor.shape)
  }

  /**
   * GPU call
   *
   * @param {Tensor} x
   */
  _callGPU(x) {
    if (!x.glTexture && !x.glTextureFragments) {
      this.inputShape = x.tensor.shape
    } else {
      if (x.is2DReshaped || x.is2DSquareReshaped) {
        this.inputShape = x.originalShape
      } else {
        this.inputShape = x.tensor.shape
      }
    }

    if (!_.isEqual(this.inputShape, this.shape)) {
      this.throwError(`input tensor shape ${x.tensor.shape} does not match specified shape ${this.shape}.`)
    }

    if (!x.glTexture) {
      if (x.tensor.shape.length <= 2) {
        x.createGLTexture({ type: '2d', format: 'float', supportsTextureFragments: true })
      } else if (x.tensor.shape.length > 2) {
        x.reshapeTo2D()
        x.createGLTexture({ type: '2d', format: 'float', supportsTextureFragments: true })
      }
    }

    this.output = x
  }
}
<|endoftext|>


<commit_before>/* globals app,window */

app.factory("api", function($rootScope, $http, reqerr) {
  window.http = $http;
  var request = function(action, data) {
    var url = "api/" + action;
    $rootScope.apiing = true;
    return $http
      .post(url, data)
      .error(reqerr)
      .finally(function() {
        $rootScope.apiing = false;
      });
  };
  var api = {};
  var actions = ["configure", "magnet", "url", "torrent", "file"];
  actions.forEach(function(action) {
    api[action] = request.bind(null, action);
  });
  return api;
});

app.factory("search", function($rootScope, $http, reqerr) {
  return {
    all: function(provider, query, page) {
      var params = {query: query};
      if (page !== undefined) params.page = page;
      $rootScope.searching = true;
      var req = $http.get("search/" + provider, {params: params});
      req.error(reqerr);
      req.finally(function() {
        $rootScope.searching = false;
      });
      return req;
    },
    one: function(provider, path) {
      var opts = {params: {item: path}};
      $rootScope.searching = true;
      var req = $http.get("search/" + provider + "/item", opts);
      req.error(reqerr);
      req.finally(function() {
        $rootScope.searching = false;
      });
      return req;
    }
  };
});

app.factory("storage", function() {
  return window.localStorage || {};
});

app.factory("reqerr", function() {
  return function(err, status) {
    alert(err.error || err);
    console.error("request error '%s' (%s)", err, status);
  };
});

app.filter("keys", function() {
  return Object.keys;
});

app.filter("addspaces", function() {
  return function(s) {
    if (typeof s !== "string") return s;
    return s
      .replace(/([A-Z]+[a-z]*)/g, function(_, word) {
        return " " + word;
      })
      .replace(/^\ /, "");
  };
});

app.filter("filename", function() {
  return function(path) {
    return /\/([^\/]+)$/.test(path) ? RegExp.$1 : path;
  };
});

app.filter("bytes", function(bytes) {
  return bytes;
});

//scale a number  and add a metric prefix
app.factory("bytes", function() {
  return function(n, d) {
    // set defaults
    if (typeof n !== "number" || isNaN(n)) n = 0;
    if (!d || typeof d !== "number") d = 1;
    // set scale index 1000,100000,... becomes 1,2,...
    var i = Math.floor(Math.floor(Math.log10(n)) / 3);
    var f = Math.pow(10, d);
    var s;
    s = n / Math.pow(10, i * 3);
    s = Math.round(s * f) / f;
    // concat (no trailing 0s) and choose scale letter
    return (
      s.toString().replace(/\.0+$/, "") +
      " " +
      ["", "K", "M", "G", "T", "P", "Z"][i] +
      "B"
    );
  };
});

app.filter("round", function() {
  return function(n) {
    if (typeof n !== "number") {
      return n;
    }
    return Math.round(n * 10) / 10;
  };
});

app.directive("ngEnter", function() {
  return function(scope, element, attrs) {
    element.bind("keydown keypress", function(event) {
      if (event.which === 13) {
        scope.$apply(function() {
          scope.$eval(attrs.ngEnter);
        });
        event.preventDefault();
      }
    });
  };
});

//TODO remove this hack
app.directive("jpSrc", function() {
  return function(scope, element, attrs) {
    scope.$watch(attrs.jpSrc, function(src) {
      element.attr("src", src);
    });
  };
});
<commit_msg>fix frontend "bytes" formatter<commit_after>/* globals app,window */

app.factory("api", function($rootScope, $http, reqerr) {
  window.http = $http;
  var request = function(action, data) {
    var url = "api/" + action;
    $rootScope.apiing = true;
    return $http
      .post(url, data)
      .error(reqerr)
      .finally(function() {
        $rootScope.apiing = false;
      });
  };
  var api = {};
  var actions = ["configure", "magnet", "url", "torrent", "file"];
  actions.forEach(function(action) {
    api[action] = request.bind(null, action);
  });
  return api;
});

app.factory("search", function($rootScope, $http, reqerr) {
  return {
    all: function(provider, query, page) {
      var params = {query: query};
      if (page !== undefined) params.page = page;
      $rootScope.searching = true;
      var req = $http.get("search/" + provider, {params: params});
      req.error(reqerr);
      req.finally(function() {
        $rootScope.searching = false;
      });
      return req;
    },
    one: function(provider, path) {
      var opts = {params: {item: path}};
      $rootScope.searching = true;
      var req = $http.get("search/" + provider + "/item", opts);
      req.error(reqerr);
      req.finally(function() {
        $rootScope.searching = false;
      });
      return req;
    }
  };
});

app.factory("storage", function() {
  return window.localStorage || {};
});

app.factory("reqerr", function() {
  return function(err, status) {
    alert(err.error || err);
    console.error("request error '%s' (%s)", err, status);
  };
});

app.filter("keys", function() {
  return Object.keys;
});

app.filter("addspaces", function() {
  return function(s) {
    if (typeof s !== "string") return s;
    return s
      .replace(/([A-Z]+[a-z]*)/g, function(_, word) {
        return " " + word;
      })
      .replace(/^\ /, "");
  };
});

app.filter("filename", function() {
  return function(path) {
    return /\/([^\/]+)$/.test(path) ? RegExp.$1 : path;
  };
});

app.filter("bytes", function(bytes) {
  return bytes;
});

//scale a number  and add a metric prefix
app.factory("bytes", function() {
  return function(n, d) {
    // set defaults
    if (typeof n !== "number" || isNaN(n) || n == 0) return "0 B";
    if (!d || typeof d !== "number") d = 1;
    // set scale index 1000,100000,... becomes 1,2,...
    var i = Math.floor(Math.floor(Math.log(n) * Math.LOG10E) / 3);
    // set rounding factor
    var f = Math.pow(10, d);
    // scale n down and round
    var s = Math.round(n / Math.pow(10, i * 3) * f) / f;
    // concat (no trailing 0s) and choose scale letter
    return (
      s.toString().replace(/\.0+$/, "") +
      " " +
      ["", "K", "M", "G", "T", "P", "Z"][i] +
      "B"
    );
  };
});

app.filter("round", function() {
  return function(n) {
    if (typeof n !== "number") {
      return n;
    }
    return Math.round(n * 10) / 10;
  };
});

app.directive("ngEnter", function() {
  return function(scope, element, attrs) {
    element.bind("keydown keypress", function(event) {
      if (event.which === 13) {
        scope.$apply(function() {
          scope.$eval(attrs.ngEnter);
        });
        event.preventDefault();
      }
    });
  };
});

//TODO remove this hack
app.directive("jpSrc", function() {
  return function(scope, element, attrs) {
    scope.$watch(attrs.jpSrc, function(src) {
      element.attr("src", src);
    });
  };
});
<|endoftext|>


<commit_before>/**
* Copyright 2012-2017, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var mapboxgl = require('mapbox-gl');

var Fx = require('../cartesian/graph_interact');
var Lib = require('../../lib');
var constants = require('./constants');
var layoutAttributes = require('./layout_attributes');
var createMapboxLayer = require('./layers');

function Mapbox(opts) {
    this.id = opts.id;
    this.gd = opts.gd;
    this.container = opts.container;
    this.isStatic = opts.staticPlot;

    var fullLayout = opts.fullLayout;

    // unique id for this Mapbox instance
    this.uid = fullLayout._uid + '-' + this.id;

    // full mapbox options (N.B. needs to be updated on every updates)
    this.opts = fullLayout[this.id];

    // create framework on instantiation for a smoother first plot call
    this.div = null;
    this.xaxis = null;
    this.yaxis = null;
    this.createFramework(fullLayout);

    // state variables used to infer how and what to update
    this.map = null;
    this.accessToken = null;
    this.styleObj = null;
    this.traceHash = {};
    this.layerList = [];
}

var proto = Mapbox.prototype;

module.exports = function createMapbox(opts) {
    var mapbox = new Mapbox(opts);

    return mapbox;
};

proto.plot = function(calcData, fullLayout, promises) {
    var self = this;

    // feed in new mapbox options
    var opts = self.opts = fullLayout[this.id];

    // remove map and create a new map if access token has change
    if(self.map && (opts.accesstoken !== self.accessToken)) {
        self.map.remove();
        self.map = null;
        self.styleObj = null;
        self.traceHash = [];
        self.layerList = {};
    }

    var promise;

    if(!self.map) {
        promise = new Promise(function(resolve, reject) {
            self.createMap(calcData, fullLayout, resolve, reject);
        });
    }
    else {
        promise = new Promise(function(resolve, reject) {
            self.updateMap(calcData, fullLayout, resolve, reject);
        });
    }

    promises.push(promise);
};

proto.createMap = function(calcData, fullLayout, resolve, reject) {
    var self = this,
        gd = self.gd,
        opts = self.opts;

    // store style id and URL or object
    var styleObj = self.styleObj = getStyleObj(opts.style);

    // store access token associated with this map
    self.accessToken = opts.accesstoken;

    // create the map!
    var map = self.map = new mapboxgl.Map({
        container: self.div,

        style: styleObj.style,
        center: convertCenter(opts.center),
        zoom: opts.zoom,
        bearing: opts.bearing,
        pitch: opts.pitch,

        interactive: !self.isStatic,
        preserveDrawingBuffer: self.isStatic
    });

    // clear navigation container
    var className = constants.controlContainerClassName,
        controlContainer = self.div.getElementsByClassName(className)[0];
    self.div.removeChild(controlContainer);

    self.rejectOnError(reject);

    map.once('load', function() {
        self.updateData(calcData);
        self.updateLayout(fullLayout);

        self.resolveOnRender(resolve);
    });

    // keep track of pan / zoom in user layout and emit relayout event
    map.on('moveend', function(eventData) {
        if(!self.map) return;

        var view = self.getView();

        opts._input.center = opts.center = view.center;
        opts._input.zoom = opts.zoom = view.zoom;
        opts._input.bearing = opts.bearing = view.bearing;
        opts._input.pitch = opts.pitch = view.pitch;

        // 'moveend' gets triggered by map.setCenter, map.setZoom,
        // map.setBearing and map.setPitch.
        //
        // Here, we make sure that 'plotly_relayout' is
        // triggered here only when the 'moveend' originates from a
        // mouse target (filtering out API calls) to not
        // duplicate 'plotly_relayout' events.

        if(eventData.originalEvent) {
            var update = {};
            update[self.id] = Lib.extendFlat({}, view);
            gd.emit('plotly_relayout', update);
        }
    });

    map.on('mousemove', function(evt) {
        var bb = self.div.getBoundingClientRect();

        // some hackery to get Fx.hover to work

        evt.clientX = evt.point.x + bb.left;
        evt.clientY = evt.point.y + bb.top;

        evt.target.getBoundingClientRect = function() { return bb; };

        self.xaxis.p2c = function() { return evt.lngLat.lng; };
        self.yaxis.p2c = function() { return evt.lngLat.lat; };

        Fx.hover(gd, evt, self.id);
    });

    map.on('click', function() {
        Fx.click(gd, { target: true });
    });

    function unhover() {
        Fx.loneUnhover(fullLayout._toppaper);
    }

    map.on('dragstart', unhover);
    map.on('zoomstart', unhover);

};

proto.updateMap = function(calcData, fullLayout, resolve, reject) {
    var self = this,
        map = self.map;

    self.rejectOnError(reject);

    var styleObj = getStyleObj(self.opts.style);

    if(self.styleObj.id !== styleObj.id) {
        self.styleObj = styleObj;
        map.setStyle(styleObj.style);

        map.style.once('load', function() {

            // need to rebuild trace layers on reload
            // to avoid 'lost event' errors
            self.traceHash = {};

            self.updateData(calcData);
            self.updateLayout(fullLayout);

            self.resolveOnRender(resolve);
        });
    }
    else {
        self.updateData(calcData);
        self.updateLayout(fullLayout);

        self.resolveOnRender(resolve);
    }
};

proto.updateData = function(calcData) {
    var traceHash = this.traceHash;

    var traceObj, trace, i, j;

    // update or create trace objects
    for(i = 0; i < calcData.length; i++) {
        var calcTrace = calcData[i];

        trace = calcTrace[0].trace;
        traceObj = traceHash[trace.uid];

        if(traceObj) traceObj.update(calcTrace);
        else if(trace._module) {
            traceHash[trace.uid] = trace._module.plot(this, calcTrace);
        }
    }

    // remove empty trace objects
    var ids = Object.keys(traceHash);
    id_loop:
    for(i = 0; i < ids.length; i++) {
        var id = ids[i];

        for(j = 0; j < calcData.length; j++) {
            trace = calcData[j][0].trace;

            if(id === trace.uid) continue id_loop;
        }

        traceObj = traceHash[id];
        traceObj.dispose();
        delete traceHash[id];
    }
};

proto.updateLayout = function(fullLayout) {
    var map = this.map,
        opts = this.opts;

    map.setCenter(convertCenter(opts.center));
    map.setZoom(opts.zoom);
    map.setBearing(opts.bearing);
    map.setPitch(opts.pitch);

    this.updateLayers();
    this.updateFramework(fullLayout);
    this.map.resize();
};

proto.resolveOnRender = function(resolve) {
    var map = this.map;

    map.on('render', function onRender() {
        if(map.loaded()) {
            map.off('render', onRender);
            resolve();
        }
    });
};

proto.rejectOnError = function(reject) {
    var map = this.map;

    function handler() {
        reject(new Error(constants.mapOnErrorMsg));
    }

    map.once('error', handler);
    map.once('style.error', handler);
    map.once('source.error', handler);
    map.once('tile.error', handler);
    map.once('layer.error', handler);
};

proto.createFramework = function(fullLayout) {
    var self = this;

    var div = self.div = document.createElement('div');

    div.id = self.uid;
    div.style.position = 'absolute';

    self.container.appendChild(div);

    // create mock x/y axes for hover routine

    self.xaxis = {
        _id: 'x',
        c2p: function(v) { return self.project(v).x; }
    };

    self.yaxis = {
        _id: 'y',
        c2p: function(v) { return self.project(v).y; }
    };

    self.updateFramework(fullLayout);
};

proto.updateFramework = function(fullLayout) {
    var domain = fullLayout[this.id].domain,
        size = fullLayout._size;

    var style = this.div.style;

    // TODO Is this correct? It seems to get the map zoom level wrong?

    style.width = size.w * (domain.x[1] - domain.x[0]) + 'px';
    style.height = size.h * (domain.y[1] - domain.y[0]) + 'px';
    style.left = size.l + domain.x[0] * size.w + 'px';
    style.top = size.t + (1 - domain.y[1]) * size.h + 'px';

    this.xaxis._offset = size.l + domain.x[0] * size.w;
    this.xaxis._length = size.w * (domain.x[1] - domain.x[0]);

    this.yaxis._offset = size.t + (1 - domain.y[1]) * size.h;
    this.yaxis._length = size.h * (domain.y[1] - domain.y[0]);
};

proto.updateLayers = function() {
    var opts = this.opts,
        layers = opts.layers,
        layerList = this.layerList,
        i;

    // if the layer arrays don't match,
    // don't try to be smart,
    // delete them all, and start all over.

    if(layers.length !== layerList.length) {
        for(i = 0; i < layerList.length; i++) {
            layerList[i].dispose();
        }

        layerList = this.layerList = [];

        for(i = 0; i < layers.length; i++) {
            layerList.push(createMapboxLayer(this, i, layers[i]));
        }
    }
    else {
        for(i = 0; i < layers.length; i++) {
            layerList[i].update(layers[i]);
        }
    }
};

proto.destroy = function() {
    if(this.map) {
        this.map.remove();
        this.map = null;
    }
    this.container.removeChild(this.div);
};

proto.toImage = function() {
    return this.map.getCanvas().toDataURL();
};

// convenience wrapper to create blank GeoJSON sources
// and avoid 'invalid GeoJSON' errors
proto.initSource = function(idSource) {
    var blank = {
        type: 'geojson',
        data: {
            type: 'Feature',
            geometry: {
                type: 'Point',
                coordinates: []
            }
        }
    };

    return this.map.addSource(idSource, blank);
};

// convenience wrapper to set data of GeoJSON sources
proto.setSourceData = function(idSource, data) {
    this.map.getSource(idSource).setData(data);
};

// convenience wrapper to create set multiple layer
// 'layout' or 'paint options at once.
proto.setOptions = function(id, methodName, opts) {
    var map = this.map,
        keys = Object.keys(opts);

    for(var i = 0; i < keys.length; i++) {
        var key = keys[i];

        map[methodName](id, key, opts[key]);
    }
};

// convenience method to project a [lon, lat] array to pixel coords
proto.project = function(v) {
    return this.map.project(new mapboxgl.LngLat(v[0], v[1]));
};

// get map's current view values in plotly.js notation
proto.getView = function() {
    var map = this.map;

    var mapCenter = map.getCenter(),
        center = { lon: mapCenter.lng, lat: mapCenter.lat };

    return {
        center: center,
        zoom: map.getZoom(),
        bearing: map.getBearing(),
        pitch: map.getPitch()
    };
};

function getStyleObj(val) {
    var styleValues = layoutAttributes.style.values,
        styleDflt = layoutAttributes.style.dflt,
        styleObj = {};

    if(Lib.isPlainObject(val)) {
        styleObj.id = val.id;
        styleObj.style = val;
    }
    else if(typeof val === 'string') {
        styleObj.id = val;
        styleObj.style = (styleValues.indexOf(val) !== -1) ?
             convertStyleVal(val) :
             val;
    }
    else {
        styleObj.id = styleDflt;
        styleObj.style = convertStyleVal(styleDflt);
    }

    return styleObj;
}

// if style is part of the 'official' mapbox values, add URL prefix and suffix
function convertStyleVal(val) {
    return constants.styleUrlPrefix + val + '-' + constants.styleUrlSuffix;
}

function convertCenter(center) {
    return [center.lon, center.lat];
}
<commit_msg>events: fix plotly events in mapbox plots<commit_after>/**
* Copyright 2012-2017, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

var mapboxgl = require('mapbox-gl');

var Fx = require('../cartesian/graph_interact');
var Lib = require('../../lib');
var constants = require('./constants');
var layoutAttributes = require('./layout_attributes');
var createMapboxLayer = require('./layers');

function Mapbox(opts) {
    this.id = opts.id;
    this.gd = opts.gd;
    this.container = opts.container;
    this.isStatic = opts.staticPlot;

    var fullLayout = opts.fullLayout;

    // unique id for this Mapbox instance
    this.uid = fullLayout._uid + '-' + this.id;

    // full mapbox options (N.B. needs to be updated on every updates)
    this.opts = fullLayout[this.id];

    // create framework on instantiation for a smoother first plot call
    this.div = null;
    this.xaxis = null;
    this.yaxis = null;
    this.createFramework(fullLayout);

    // state variables used to infer how and what to update
    this.map = null;
    this.accessToken = null;
    this.styleObj = null;
    this.traceHash = {};
    this.layerList = [];
}

var proto = Mapbox.prototype;

module.exports = function createMapbox(opts) {
    var mapbox = new Mapbox(opts);

    return mapbox;
};

proto.plot = function(calcData, fullLayout, promises) {
    var self = this;

    // feed in new mapbox options
    var opts = self.opts = fullLayout[this.id];

    // remove map and create a new map if access token has change
    if(self.map && (opts.accesstoken !== self.accessToken)) {
        self.map.remove();
        self.map = null;
        self.styleObj = null;
        self.traceHash = [];
        self.layerList = {};
    }

    var promise;

    if(!self.map) {
        promise = new Promise(function(resolve, reject) {
            self.createMap(calcData, fullLayout, resolve, reject);
        });
    }
    else {
        promise = new Promise(function(resolve, reject) {
            self.updateMap(calcData, fullLayout, resolve, reject);
        });
    }

    promises.push(promise);
};

proto.createMap = function(calcData, fullLayout, resolve, reject) {
    var self = this,
        gd = self.gd,
        opts = self.opts;

    // store style id and URL or object
    var styleObj = self.styleObj = getStyleObj(opts.style);

    // store access token associated with this map
    self.accessToken = opts.accesstoken;

    // create the map!
    var map = self.map = new mapboxgl.Map({
        container: self.div,

        style: styleObj.style,
        center: convertCenter(opts.center),
        zoom: opts.zoom,
        bearing: opts.bearing,
        pitch: opts.pitch,

        interactive: !self.isStatic,
        preserveDrawingBuffer: self.isStatic
    });

    // clear navigation container
    var className = constants.controlContainerClassName,
        controlContainer = self.div.getElementsByClassName(className)[0];
    self.div.removeChild(controlContainer);

    self.rejectOnError(reject);

    map.once('load', function() {
        self.updateData(calcData);
        self.updateLayout(fullLayout);

        self.resolveOnRender(resolve);
    });

    // keep track of pan / zoom in user layout and emit relayout event
    map.on('moveend', function(eventData) {
        if(!self.map) return;

        var view = self.getView();

        opts._input.center = opts.center = view.center;
        opts._input.zoom = opts.zoom = view.zoom;
        opts._input.bearing = opts.bearing = view.bearing;
        opts._input.pitch = opts.pitch = view.pitch;

        // 'moveend' gets triggered by map.setCenter, map.setZoom,
        // map.setBearing and map.setPitch.
        //
        // Here, we make sure that 'plotly_relayout' is
        // triggered here only when the 'moveend' originates from a
        // mouse target (filtering out API calls) to not
        // duplicate 'plotly_relayout' events.

        if(eventData.originalEvent) {
            var update = {};
            update[self.id] = Lib.extendFlat({}, view);
            gd.emit('plotly_relayout', update);
        }
    });

    map.on('mousemove', function(evt) {
        var bb = self.div.getBoundingClientRect();

        // some hackery to get Fx.hover to work

        evt.clientX = evt.point.x + bb.left;
        evt.clientY = evt.point.y + bb.top;

        evt.target.getBoundingClientRect = function() { return bb; };

        self.xaxis.p2c = function() { return evt.lngLat.lng; };
        self.yaxis.p2c = function() { return evt.lngLat.lat; };

        Fx.hover(gd, evt, self.id);
    });

    map.on('click', function(evt) {
        Fx.click(gd, evt.originalEvent);
    });

    function unhover() {
        Fx.loneUnhover(fullLayout._toppaper);
    }

    map.on('dragstart', unhover);
    map.on('zoomstart', unhover);

};

proto.updateMap = function(calcData, fullLayout, resolve, reject) {
    var self = this,
        map = self.map;

    self.rejectOnError(reject);

    var styleObj = getStyleObj(self.opts.style);

    if(self.styleObj.id !== styleObj.id) {
        self.styleObj = styleObj;
        map.setStyle(styleObj.style);

        map.style.once('load', function() {

            // need to rebuild trace layers on reload
            // to avoid 'lost event' errors
            self.traceHash = {};

            self.updateData(calcData);
            self.updateLayout(fullLayout);

            self.resolveOnRender(resolve);
        });
    }
    else {
        self.updateData(calcData);
        self.updateLayout(fullLayout);

        self.resolveOnRender(resolve);
    }
};

proto.updateData = function(calcData) {
    var traceHash = this.traceHash;

    var traceObj, trace, i, j;

    // update or create trace objects
    for(i = 0; i < calcData.length; i++) {
        var calcTrace = calcData[i];

        trace = calcTrace[0].trace;
        traceObj = traceHash[trace.uid];

        if(traceObj) traceObj.update(calcTrace);
        else if(trace._module) {
            traceHash[trace.uid] = trace._module.plot(this, calcTrace);
        }
    }

    // remove empty trace objects
    var ids = Object.keys(traceHash);
    id_loop:
    for(i = 0; i < ids.length; i++) {
        var id = ids[i];

        for(j = 0; j < calcData.length; j++) {
            trace = calcData[j][0].trace;

            if(id === trace.uid) continue id_loop;
        }

        traceObj = traceHash[id];
        traceObj.dispose();
        delete traceHash[id];
    }
};

proto.updateLayout = function(fullLayout) {
    var map = this.map,
        opts = this.opts;

    map.setCenter(convertCenter(opts.center));
    map.setZoom(opts.zoom);
    map.setBearing(opts.bearing);
    map.setPitch(opts.pitch);

    this.updateLayers();
    this.updateFramework(fullLayout);
    this.map.resize();
};

proto.resolveOnRender = function(resolve) {
    var map = this.map;

    map.on('render', function onRender() {
        if(map.loaded()) {
            map.off('render', onRender);
            resolve();
        }
    });
};

proto.rejectOnError = function(reject) {
    var map = this.map;

    function handler() {
        reject(new Error(constants.mapOnErrorMsg));
    }

    map.once('error', handler);
    map.once('style.error', handler);
    map.once('source.error', handler);
    map.once('tile.error', handler);
    map.once('layer.error', handler);
};

proto.createFramework = function(fullLayout) {
    var self = this;

    var div = self.div = document.createElement('div');

    div.id = self.uid;
    div.style.position = 'absolute';

    self.container.appendChild(div);

    // create mock x/y axes for hover routine

    self.xaxis = {
        _id: 'x',
        c2p: function(v) { return self.project(v).x; }
    };

    self.yaxis = {
        _id: 'y',
        c2p: function(v) { return self.project(v).y; }
    };

    self.updateFramework(fullLayout);
};

proto.updateFramework = function(fullLayout) {
    var domain = fullLayout[this.id].domain,
        size = fullLayout._size;

    var style = this.div.style;

    // TODO Is this correct? It seems to get the map zoom level wrong?

    style.width = size.w * (domain.x[1] - domain.x[0]) + 'px';
    style.height = size.h * (domain.y[1] - domain.y[0]) + 'px';
    style.left = size.l + domain.x[0] * size.w + 'px';
    style.top = size.t + (1 - domain.y[1]) * size.h + 'px';

    this.xaxis._offset = size.l + domain.x[0] * size.w;
    this.xaxis._length = size.w * (domain.x[1] - domain.x[0]);

    this.yaxis._offset = size.t + (1 - domain.y[1]) * size.h;
    this.yaxis._length = size.h * (domain.y[1] - domain.y[0]);
};

proto.updateLayers = function() {
    var opts = this.opts,
        layers = opts.layers,
        layerList = this.layerList,
        i;

    // if the layer arrays don't match,
    // don't try to be smart,
    // delete them all, and start all over.

    if(layers.length !== layerList.length) {
        for(i = 0; i < layerList.length; i++) {
            layerList[i].dispose();
        }

        layerList = this.layerList = [];

        for(i = 0; i < layers.length; i++) {
            layerList.push(createMapboxLayer(this, i, layers[i]));
        }
    }
    else {
        for(i = 0; i < layers.length; i++) {
            layerList[i].update(layers[i]);
        }
    }
};

proto.destroy = function() {
    if(this.map) {
        this.map.remove();
        this.map = null;
    }
    this.container.removeChild(this.div);
};

proto.toImage = function() {
    return this.map.getCanvas().toDataURL();
};

// convenience wrapper to create blank GeoJSON sources
// and avoid 'invalid GeoJSON' errors
proto.initSource = function(idSource) {
    var blank = {
        type: 'geojson',
        data: {
            type: 'Feature',
            geometry: {
                type: 'Point',
                coordinates: []
            }
        }
    };

    return this.map.addSource(idSource, blank);
};

// convenience wrapper to set data of GeoJSON sources
proto.setSourceData = function(idSource, data) {
    this.map.getSource(idSource).setData(data);
};

// convenience wrapper to create set multiple layer
// 'layout' or 'paint options at once.
proto.setOptions = function(id, methodName, opts) {
    var map = this.map,
        keys = Object.keys(opts);

    for(var i = 0; i < keys.length; i++) {
        var key = keys[i];

        map[methodName](id, key, opts[key]);
    }
};

// convenience method to project a [lon, lat] array to pixel coords
proto.project = function(v) {
    return this.map.project(new mapboxgl.LngLat(v[0], v[1]));
};

// get map's current view values in plotly.js notation
proto.getView = function() {
    var map = this.map;

    var mapCenter = map.getCenter(),
        center = { lon: mapCenter.lng, lat: mapCenter.lat };

    return {
        center: center,
        zoom: map.getZoom(),
        bearing: map.getBearing(),
        pitch: map.getPitch()
    };
};

function getStyleObj(val) {
    var styleValues = layoutAttributes.style.values,
        styleDflt = layoutAttributes.style.dflt,
        styleObj = {};

    if(Lib.isPlainObject(val)) {
        styleObj.id = val.id;
        styleObj.style = val;
    }
    else if(typeof val === 'string') {
        styleObj.id = val;
        styleObj.style = (styleValues.indexOf(val) !== -1) ?
             convertStyleVal(val) :
             val;
    }
    else {
        styleObj.id = styleDflt;
        styleObj.style = convertStyleVal(styleDflt);
    }

    return styleObj;
}

// if style is part of the 'official' mapbox values, add URL prefix and suffix
function convertStyleVal(val) {
    return constants.styleUrlPrefix + val + '-' + constants.styleUrlSuffix;
}

function convertCenter(center) {
    return [center.lon, center.lat];
}
<|endoftext|>


<commit_before>$(document).ready(function(){
  $(".rating").hide();
  handleWordSubmission();
  $(".update-form").on("submit", function(event){
    event.preventDefault();
    $(".no-word").remove();
    var update1 = $(".update1:checked").val();
    var update2 = $(".update2:checked").val();
    var update3 = $(".update3:checked").val();
    var line1 = $(".line1").text();
    var line2 = $(".line2").text();
    var line3 = $(".line3").text();
    console.log(line1);
    var request = {train1: update1, train2: update2, train3: update3, lineOne: line1, lineTwo: line2, lineThree: line3};
    $.ajax({
      url: '/train',
      type: 'POST',
      dataType: 'json',
      data: JSON.stringify(request),
      contentType: 'application/json'
    })
    .done(function(response) {
      $('input[name="update1"]').prop('checked', false);
      $('input[name="update2"]').prop('checked', false);
      $('input[name="update3"]').prop('checked', false);
      $(".rating").hide();
      $("#newHaikuForm").trigger('reset');
      $("#newHaikuForm").show();

    })
    .fail(function() {
      console.log("error");
    })
    .always(function() {
      console.log("complete");
    });

  })
})

function handleWordSubmission() {
  $('#newHaikuForm').on("submit", function(event) {
      event.preventDefault();
      var $form = $(this);
      var introHaiku = $(".haiku");
      var newHaiku = $(".resultHaiku");
      var url = $form.attr("action");
      var word = $(this).serialize();
      var wordText = word.split("=");
      wordText = wordText.pop();
      var request = $.ajax({
        url: url,
        type: "POST",
        data: word,
      });
      request.done(function(response){
        function isWordInHaiku(wordText, response){
          var returnBool = false;
          if (findWord(wordText, response.lineOne)){
            returnBool = true;
          } else if (findWord(wordText, response.lineTwo)){
            returnBool = true;
          } else if (findWord(wordText, response.lineThree)){
            returnBool = true;
          } else {
            returnBool = false;
          }
          return returnBool;
        }
        function findWord(word, str) {
          return RegExp('\\b'+ word +'\\b').test(str)
        }
        if (isWordInHaiku(wordText, response)) {
        } else {
          insertString = "
Sorry, I don't know that word, so I chose a new one
";
        }
        $(".line1").text(response.lineOne);
        $(".line2").text(response.lineTwo);
        $(".line3").text(response.lineThree);
        if (typeof insertString != 'undefined'){
          $(".line1").closest("b").prepend(insertString);
        }
        $form.hide();
        $(".rating").show();
      })
  })
}
<commit_msg>fix bug for form submittal that is null (#80)<commit_after>$(document).ready(function(){
  $(".rating").hide();
  handleWordSubmission();
  $(".update-form").on("submit", function(event){
    event.preventDefault();
    $(".no-word").remove();
    var update1 = $(".update1:checked").val() || "indifferent1";
    var update2 = $(".update2:checked").val() || "indifferent2";
    var update3 = $(".update3:checked").val() || "indifferent3";
    var line1 = $(".line1").text();
    var line2 = $(".line2").text();
    var line3 = $(".line3").text();
    console.log(line1);
    var request = {train1: update1, train2: update2, train3: update3, lineOne: line1, lineTwo: line2, lineThree: line3};
    $.ajax({
      url: '/train',
      type: 'POST',
      dataType: 'json',
      data: JSON.stringify(request),
      contentType: 'application/json'
    })
    .done(function(response) {
      $('input[name="update1"]').prop('checked', false);
      $('input[name="update2"]').prop('checked', false);
      $('input[name="update3"]').prop('checked', false);
      $(".rating").hide();
      $("#newHaikuForm").trigger('reset');
      $("#newHaikuForm").show();

    })
    .fail(function() {
      console.log("error");
    })
    .always(function() {
      console.log("complete");
    });

  })
})

function handleWordSubmission() {
  $('#newHaikuForm').on("submit", function(event) {
      event.preventDefault();
      var $form = $(this);
      var introHaiku = $(".haiku");
      var newHaiku = $(".resultHaiku");
      var url = $form.attr("action");
      var word = $(this).serialize();
      var wordText = word.split("=");
      wordText = wordText.pop();
      var request = $.ajax({
        url: url,
        type: "POST",
        data: word,
      });
      request.done(function(response){
        function isWordInHaiku(wordText, response){
          var returnBool = false;
          if (findWord(wordText, response.lineOne)){
            returnBool = true;
          } else if (findWord(wordText, response.lineTwo)){
            returnBool = true;
          } else if (findWord(wordText, response.lineThree)){
            returnBool = true;
          } else {
            returnBool = false;
          }
          return returnBool;
        }
        function findWord(word, str) {
          return RegExp('\\b'+ word +'\\b').test(str)
        }
        if (isWordInHaiku(wordText, response)) {
        } else {
          insertString = "
Sorry, I don't know that word, so I chose a new one
";
        }
        $(".line1").text(response.lineOne);
        $(".line2").text(response.lineTwo);
        $(".line3").text(response.lineThree);
        if (typeof insertString != 'undefined'){
          $(".line1").closest("b").prepend(insertString);
        }
        $form.hide();
        $(".rating").show();
      })
  })
}
<|endoftext|>