<commit_before>import actions from '../actions';
import * as tabs from 'background/tabs';
import * as parsers from 'shared/commands/parsers';
import * as properties from 'shared/settings/properties';

const openCommand = (url) => {
  return browser.tabs.query({
    active: true, currentWindow: true
  }).then((gotTabs) => {
    if (gotTabs.length > 0) {
      return browser.tabs.update(gotTabs[0].id, { url: url });
    }
  });
};

const tabopenCommand = (url) => {
  return browser.tabs.create({ url: url });
};

const winopenCommand = (url) => {
  return browser.windows.create({ url });
};

const bufferCommand = (keywords) => {
  if (keywords.length === 0) {
    return Promise.resolve([]);
  }
  let keywordsStr = keywords.join(' ');
  return browser.tabs.query({
    active: true, currentWindow: true
  }).then((gotTabs) => {
    if (gotTabs.length > 0) {
      if (isNaN(keywordsStr)) {
        return tabs.selectByKeyword(gotTabs[0], keywordsStr);
      }
      let index = parseInt(keywordsStr, 10) - 1;
      return tabs.selectAt(index);
    }
  });
};

const setCommand = (args) => {
  if (!args[0]) {
    return Promise.resolve();
  }

  let [name, value] = parsers.parseSetOption(args[0], properties.types);
  return {
    type: actions.SETTING_SET_PROPERTY,
    name,
    value
  };
};

const exec = (line, settings) => {
  let [name, args] = parsers.parseCommandLine(line);

  switch (name) {
  case 'o':
  case 'open':
    return openCommand(parsers.normalizeUrl(args, settings.search));
  case 't':
  case 'tabopen':
    return tabopenCommand(parsers.normalizeUrl(args, settings.search));
  case 'w':
  case 'winopen':
    return winopenCommand(parsers.normalizeUrl(args, settings.search));
  case 'b':
  case 'buffer':
    return bufferCommand(args);
  case 'set':
    return setCommand(args);
  case '':
    return Promise.resolve();
  }
  throw new Error(name + ' command is not defined');
};

export { exec };
<commit_msg>implement :q to close tab<commit_after>import actions from '../actions';
import * as tabs from 'background/tabs';
import * as parsers from 'shared/commands/parsers';
import * as properties from 'shared/settings/properties';

const openCommand = (url) => {
  return browser.tabs.query({
    active: true, currentWindow: true
  }).then((gotTabs) => {
    if (gotTabs.length > 0) {
      return browser.tabs.update(gotTabs[0].id, { url: url });
    }
  });
};

const tabopenCommand = (url) => {
  return browser.tabs.create({ url: url });
};

const tabcloseCommand = () => {
  return browser.tabs.query({ active: true }).then((tabList) => {
    return browser.tabs.remove(tabList.map(tab => tab.id));
  });
};

const winopenCommand = (url) => {
  return browser.windows.create({ url });
};

const bufferCommand = (keywords) => {
  if (keywords.length === 0) {
    return Promise.resolve([]);
  }
  let keywordsStr = keywords.join(' ');
  return browser.tabs.query({
    active: true, currentWindow: true
  }).then((gotTabs) => {
    if (gotTabs.length > 0) {
      if (isNaN(keywordsStr)) {
        return tabs.selectByKeyword(gotTabs[0], keywordsStr);
      }
      let index = parseInt(keywordsStr, 10) - 1;
      return tabs.selectAt(index);
    }
  });
};

const setCommand = (args) => {
  if (!args[0]) {
    return Promise.resolve();
  }

  let [name, value] = parsers.parseSetOption(args[0], properties.types);
  return {
    type: actions.SETTING_SET_PROPERTY,
    name,
    value
  };
};

const exec = (line, settings) => {
  let [name, args] = parsers.parseCommandLine(line);

  switch (name) {
  case 'o':
  case 'open':
    return openCommand(parsers.normalizeUrl(args, settings.search));
  case 't':
  case 'tabopen':
    return tabopenCommand(parsers.normalizeUrl(args, settings.search));
  case 'w':
  case 'winopen':
    return winopenCommand(parsers.normalizeUrl(args, settings.search));
  case 'b':
  case 'buffer':
    return bufferCommand(args);
  case 'set':
    return setCommand(args);
  case 'q':
  case 'quit':
    return tabcloseCommand();
  case '':
    return Promise.resolve();
  }
  throw new Error(name + ' command is not defined');
};

export { exec };
<|endoftext|>


<commit_before>/**
 * Copyright 2014 Solinea, Inc.
 *
 * Licensed under the Solinea Software License Agreement (goldstone),
 * Version 1.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *     http://www.solinea.com/goldstone/LICENSE.pdf
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Alex Jacobs
 */

var EventsReportView = Backbone.View.extend({

    defaults: {},

    initialize: function(options) {
        this.options = options || {};
        this.defaults = _.clone(this.defaults);
        this.el = options.el;
        this.defaults.width = options.width;
        this.defaults.hostName = options.nodeName;

        var ns = this.defaults;
        var self = this;

        // required in case spinner loading takes
        // longer than chart loading
        ns.spinnerDisplay = 'inline';

        var spinnerLocation = this.el;
        $('').load(function() {
            $(this).appendTo(spinnerLocation).css({
                'position': 'relative',
                'margin-top': -20,
                'margin-left': (ns.width / 2),
                'display': ns.spinnerDisplay
            });
        });

        // appends display and modal html elements to this.el
        this.render();

        // bind to backbone collection
        // invoke this.update(), when the collection 'fetch' is complete
        this.collection.on('sync', this.update, this);

    },

    update: function() {

        var ns = this.defaults;
        var self = this;

        // sets css for spinner to hidden in case
        // spinner callback resolves
        // after chart data callback
        ns.spinnerDisplay = 'none';

        $(this.el).find('#spinner').hide();

        this.drawSearchTable('#events-report-table');

    },

    drawSearchTable: function(location) {

        var ns = this.defaults;
        var self = this;

        var tableData = this.collection.toJSON();

        var finalResults = [];

        _.each(tableData, function(item) {

            item.id = item.id || '';
            item.event_type = item.event_type || '';
            item.source_id = item.source_id || '';
            item.source_name = item.source_name || '';
            item.message = item.message || '';
            item.created = item.created || '';

            finalResults.push([item.id, item.event_type, item.source_id, item.source_name, item.message, item.created]);
        });

        var oTable;

        if ($.fn.dataTable.isDataTable(location)) {
            oTable = $(location).DataTable();

            // draw(false) = keep current page when adding additional rows
            oTable.rows.add(finalResults).draw(false);
        } else {
            var oTableParams = {
                "info": false,
                "processing": true,
                "lengthChange": true,
                "paging": true,
                "searching": true,
                "order": [
                    [5, 'desc']
                ],
                "ordering": true,
                "serverSide": false,
                "data": finalResults,
                "columnDefs": [{
                    "name": "id",
                    "targets": 0
                }, {
                    "name": "event_type",
                    "targets": 1
                }, {
                    "name": "source_id",
                    "targets": 2
                }, {
                    "name": "source_name",
                    "targets": 3
                }, {
                    "name": "message",
                    "targets": 4
                }, {
                    "name": "created",
                    "type": "date",
                    "targets": 5,
                    "render": function(data, type, full, meta) {
                        return moment(data).format();
                    }
                }]
            };

            oTable = $(location).DataTable(oTableParams);
        }
    },

    render: function() {
        $(this.el).append(this.template());
        return this;
    },

    template: _.template(

        '
' +
        '
' +
        '
' +
        '
' +
        '
 Events Report' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        'Id	' +
        'Event Type	' +
        'Source Id	' +
        'Source Name	' +
        'Message	' +
        'Created	' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
')
});
<commit_msg>Renders only 'created/eventType/message' for Events tab and removes 'processing'<commit_after>/**
 * Copyright 2014 Solinea, Inc.
 *
 * Licensed under the Solinea Software License Agreement (goldstone),
 * Version 1.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *     http://www.solinea.com/goldstone/LICENSE.pdf
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Alex Jacobs
 */

var EventsReportView = Backbone.View.extend({

    defaults: {},

    initialize: function(options) {
        this.options = options || {};
        this.defaults = _.clone(this.defaults);
        this.el = options.el;
        this.defaults.width = options.width;
        this.defaults.hostName = options.nodeName;

        var ns = this.defaults;
        var self = this;

        // required in case spinner loading takes
        // longer than chart loading
        ns.spinnerDisplay = 'inline';

        var spinnerLocation = this.el;
        $('').load(function() {
            $(this).appendTo(spinnerLocation).css({
                'position': 'relative',
                'margin-top': -20,
                'margin-left': (ns.width / 2),
                'display': ns.spinnerDisplay
            });
        });

        // appends display and modal html elements to this.el
        this.render();

        // bind to backbone collection
        // invoke this.update(), when the collection 'fetch' is complete
        this.collection.on('sync', this.update, this);

    },

    update: function() {

        var ns = this.defaults;
        var self = this;

        // sets css for spinner to hidden in case
        // spinner callback resolves
        // after chart data callback
        ns.spinnerDisplay = 'none';

        $(this.el).find('#spinner').hide();

        this.drawSearchTable('#events-report-table');

    },

    drawSearchTable: function(location) {

        var ns = this.defaults;
        var self = this;

        var tableData = this.collection.toJSON();

        var finalResults = [];

        _.each(tableData, function(item) {

            item.id = item.id || '';
            item.event_type = item.event_type || '';
            item.source_id = item.source_id || '';
            item.source_name = item.source_name || '';
            item.message = item.message || '';
            item.created = item.created || '';

            finalResults.push([item.created, item.event_type, item.message, item.id, item.source_id, item.source_name]);
        });

        var oTable;

        if ($.fn.dataTable.isDataTable(location)) {
            oTable = $(location).DataTable();

            // draw(false) = keep current page when adding additional rows
            oTable.rows.add(finalResults).draw(false);
        } else {
            var oTableParams = {
                "info": false,
                "processing": false,
                "lengthChange": true,
                "paging": true,
                "searching": true,
                "order": [
                    [0, 'desc']
                ],
                "ordering": true,
                "serverSide": false,
                "data": finalResults,
                "columnDefs": [{
                    "name": "created",
                    "type": "date",
                    "targets": 0,
                    "render": function(data, type, full, meta) {
                        return moment(data).format();
                    }
                }, {
                    "name": "event_type",
                    "targets": 1
                }, {
                    "name": "message",
                    "targets": 2
                }, {
                    "name": "id",
                    "targets": 3
                }, {
                    "name": "source_id",
                    "targets": 4
                }, {
                    "name": "source_name",
                    "targets": 5
                }, {
                    "visible": false,
                    "targets": [3, 4, 5]
                }]
            };

            oTable = $(location).DataTable(oTableParams);
        }
    },

    render: function() {
        $(this.el).append(this.template());
        return this;
    },

    template: _.template(

        '
' +
        '
' +
        '
' +
        '
' +
        '
 Events Report' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        'Created	' +
        'Event Type	' +
        'Message	' +
        // 'Id	' +
        // 'Source Id	' +
        // 'Source Name	' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
')
});
<|endoftext|>


<commit_before>var $ = require('interlude');

var stageAttach = function (ms, stage) {
  ms.forEach(function (m) {
    m.id.t = stage;
  });
};

// signature => Ctor usage as in ffadynamic.js
// TODO: find sensible start signatures so we can implement .sub
function Dynamic(trn) {
  this._trn = trn;
  this._ready = false;
  this._stage = 1;
  stageAttach(trn.matches, this._stage);
  this.numPlayers = trn.numPlayers; // TODO: initial always good starting point?
  this.matches = trn.matches.slice();
}

Dynamic.inherit = function (Klass, Initial) {
  Initial = Initial || Dynamic;
  Klass.prototype = Object.create(Initial.prototype);

  // TODO: defaults for _verify _progress _limbo _early and _initResult ?
  Object.defineProperty(Klass.prototype, 'rep', {
    value: Klass.idString
  });

  // TODO: configure?
  Klass.inherit = function (SubKlass) {
    return Initial.inherit(SubKlass, Klass);
  };

  // TODO: sub?
};

// TODO: getter?
Dynamic.prototype.currentStage = function () {
  return this._trn.matches;
};

Dynamic.prototype.createNextStage = function () {
  if (!this._ready) {
    throw new Error("cannot start next stage until current one is done");
  }

  // copy finished rounds matches into big list under a stage guarded ID
  this._trn.matches.forEach(function (m) {
    var copy = {
      id: $.extend({ t: this.stage }, m.id),
      p: m.p.slice()
    };
    if (m.m) {
      copy.m = m.m.slice();
    }
    this.matches.push(copy);
  }.bind(this));

  this._stage += 1;
  this._trn = this._createNext();
  stageAttach(this._trn.matches, this._stage);
  this.matches = this.matches.concat(this._trn.matches);
  this._ready = false;
};

Dynamic.prototype.stageComplete = function () {
  return this._ready;
};

Dynamic.prototype.unscorable = function (id, score, allowPast) {
  if (id.t != null && id.t !== this._stage) {
    return "cannot rescore finished stages";
  }
  // Note that classical tournaments just disregard the id.t flag
  return this._trn.unscorable(id, score, allowPast);
};

Dynamic.prototype.score = function (id, score, allowPast) {
  var invReason = this.unscorable(id, score, true);
  if (invReason !== null) {
    console.error("failed scoring match %s with %j", this.rep(id), score);
    console.error("reason:", invReason);
    return false;
  }
  // score in current tournament - we know _trn.unscorable passes at this point
  if (this._trn.score(id, score, allowPast)) {
    // copy score to global match list
    //this.findMatch($.extend({ t: this._stage }, id)).m = score;
    this._ready = this._trn.isDone();
    return true;
  }
  return false;
};

Dynamic.prototype.upcoming = function (playerId) {
  // NB: this returns id without .t - probably sensible?
  return this._trn.upcoming(playerId);
};

// TODO: isDone

var resultEntry = function (res, p) {
  return $.firstBy(function (r) {
    return r.seed === p;
  }, res);
};

Dynamic.prototype.results = function () {
  var oldRes = this._oldRes || {};
  var currRes = this._trn.results();

  oldRes.forEach(function (r) {
    if (!resultEntry(currRes, r.seed)) {
      // copy over result entries for previous stages - because we eliminate
      // between stages, difference will be the player knocked out:
      // thes, since oldRes is sorted, so is currRes after pushing
      currRes.push(r);
    }
  });

  this._oldRes = currRes;
  return currRes;
};

module.exports = Dynamic;
<commit_msg>createNextStage returns whether _createNext managed to do stuff<commit_after>var $ = require('interlude');

var stageAttach = function (ms, stage) {
  ms.forEach(function (m) {
    m.id.t = stage;
  });
};

// signature => Ctor usage as in ffadynamic.js
// TODO: find sensible start signatures so we can implement .sub
function Dynamic(trn) {
  this._trn = trn;
  this._ready = false;
  this._done = false;
  this._stage = 1;
  stageAttach(trn.matches, this._stage);
  this.numPlayers = trn.numPlayers; // TODO: initial always good starting point?
  this.matches = trn.matches.slice();
}

Dynamic.inherit = function (Klass, Initial) {
  Initial = Initial || Dynamic;
  Klass.prototype = Object.create(Initial.prototype);

  // TODO: defaults for _verify _progress _limbo _early and _initResult ?
  Object.defineProperty(Klass.prototype, 'rep', {
    value: Klass.idString
  });

  // TODO: configure?
  Klass.inherit = function (SubKlass) {
    return Initial.inherit(SubKlass, Klass);
  };

  // TODO: sub?
};

// TODO: getter?
Dynamic.prototype.currentStage = function () {
  return this._trn.matches;
};

Dynamic.prototype.createNextStage = function () {
  if (!this._ready) {
    throw new Error("cannot start next stage until current one is done");
  }

  // copy finished rounds matches into big list under a stage guarded ID
  this._trn.matches.forEach(function (m) {
    var copy = {
      id: $.extend({ t: this.stage }, m.id),
      p: m.p.slice()
    };
    if (m.m) {
      copy.m = m.m.slice();
    }
    this.matches.push(copy);
  }.bind(this));

  var trn = this._createNext(/*this._stage += 1*/);
  if (trn === null) {
    return false;
  }
  this._stage += 1;
  this._trn = trn;
  stageAttach(this._trn.matches, this._stage);
  this.matches = this.matches.concat(this._trn.matches);
  this._ready = false;
  return true;
};

Dynamic.prototype.stageComplete = function () {
  return this._ready;
};

Dynamic.prototype.unscorable = function (id, score, allowPast) {
  if (id.t != null && id.t !== this._stage) {
    return "cannot rescore finished stages";
  }
  // Note that classical tournaments just disregard the id.t flag
  return this._trn.unscorable(id, score, allowPast);
};

Dynamic.prototype.score = function (id, score, allowPast) {
  var invReason = this.unscorable(id, score, true);
  if (invReason !== null) {
    console.error("failed scoring match %s with %j", this.rep(id), score);
    console.error("reason:", invReason);
    return false;
  }
  // score in current tournament - we know _trn.unscorable passes at this point
  if (this._trn.score(id, score, allowPast)) {
    // copy score to global match list
    //this.findMatch($.extend({ t: this._stage }, id)).m = score;
    this._ready = this._trn.isDone();
    return true;
  }
  return false;
};

Dynamic.prototype.upcoming = function (playerId) {
  // NB: this returns id without .t - probably sensible?
  return this._trn.upcoming(playerId);
};

Dynamic.prototype.isDone = function () {
  return this._done;
};

var resultEntry = function (res, p) {
  return $.firstBy(function (r) {
    return r.seed === p;
  }, res);
};

Dynamic.prototype.results = function () {
  var oldRes = this._oldRes || {};
  var currRes = this._trn.results();

  oldRes.forEach(function (r) {
    if (!resultEntry(currRes, r.seed)) {
      // copy over result entries for previous stages - because we eliminate
      // between stages, difference will be the player knocked out:
      // thes, since oldRes is sorted, so is currRes after pushing
      currRes.push(r);
    }
  });

  this._oldRes = currRes;
  return currRes;
};

module.exports = Dynamic;
<|endoftext|>


<commit_before>const expect = require('expect');

const cheerio = require('cheerio');
const React = require('react');
const ReactDOM = require('react-dom/server');
const ReactRedux = require('react-redux');
const { createMemoryHistory } = require('react-router');
const { createFactory } = require('react-elementary').default;

const createStore = require('../src/scripts/store.js');
const { containerSelector } = require(
  '../src/scripts/selectors/articleSelectors.js'
);
const ArticleList = createFactory(
  require('../src/scripts/views/ArticleList.js')
);

const Provider = createFactory(ReactRedux.Provider);

describe('ArticleList', () => {
  it('renders a list of articles', () => {
    const { store } = createStore(createMemoryHistory());
    const articles = [
      {
        _id: '_id1',
        published: { utc: '2016-02-07T19:54:00Z', timezone: 'UTC' },
      },
      {
        _id: '_id2',
        published: { utc: '2016-02-07T19:55:00Z', timezone: 'UTC' },
      },
    ];
    store.dispatch({
      type: 'FETCH_ARTICLES_FULFILLED',
      payload: { docs: articles },
    });
    const props = containerSelector(store.getState());
    const component = Provider({ store }, ArticleList(props));
    const html = ReactDOM.renderToStaticMarkup(component);
    const $ = cheerio.load(html);
    const els = $('article');
    expect(els.length).toBe(2);
  })
});
<commit_msg>Fix ESLint errors<commit_after>const expect = require('expect');

const cheerio = require('cheerio');
const ReactDOM = require('react-dom/server');
const ReactRedux = require('react-redux');
const { createMemoryHistory } = require('react-router');
const { createFactory } = require('react-elementary').default;

const createStore = require('../src/scripts/store.js');
const { containerSelector } = require(
  '../src/scripts/selectors/articleSelectors.js'
);
const ArticleList = createFactory(
  require('../src/scripts/views/ArticleList.js')
);

const Provider = createFactory(ReactRedux.Provider);

describe('ArticleList', () => {
  it('renders a list of articles', () => {
    const { store } = createStore(createMemoryHistory());
    const articles = [
      {
        _id: '_id1',
        published: { utc: '2016-02-07T19:54:00Z', timezone: 'UTC' },
      },
      {
        _id: '_id2',
        published: { utc: '2016-02-07T19:55:00Z', timezone: 'UTC' },
      },
    ];
    store.dispatch({
      type: 'FETCH_ARTICLES_FULFILLED',
      payload: { docs: articles },
    });
    const props = containerSelector(store.getState());
    const component = Provider({ store }, ArticleList(props));
    const html = ReactDOM.renderToStaticMarkup(component);
    const $ = cheerio.load(html);
    const els = $('article');
    expect(els.length).toBe(2);
  });
});
<|endoftext|>


<commit_before>var express = require("express");
var db = require("./db");
var passwordless = require("passwordless");
var https = require('https');

var router = express.Router();

function setUp(req, res, next) {
  if (typeof(res.locals) == "undefined") {
    res.locals = {};
  }
  res.locals.replay = null;
  res.locals.replays = [];
  res.locals.recentReplays = [];
  res.locals.popularReplays = [];
  res.locals.errors = req.session.errors || [];
  req.session.errors = [];
  req.session.recaptchaPass = false;
  var userID = req.user;
  db.User.findById(userID, function(error, user) {
    if (error) {
      req.locals.errors.push(error.message);
    }
    res.locals.user = user;
    next();
  });
}

function populateSearch(req, res, next) {
  var search = req.session.search;
  res.locals.search = search;
  req.session.search = null;

  if (!search) {
    res.locals.search = {};
    res.locals.search.include_rated = true;
    res.locals.search.include_unrated = true;
    next();
    return;
  }

  db.Replay.search(search, function(error, replays) {
    if (error) {
      res.locals.errors.push(error.message);
      console.log(error);
    }
    if (replays.length == 0) {
      res.locals.errors.push("No results found.");
    }
    res.locals.replays = replays;
    next();
  });
}

function fetchReplay(req, res, next) {
  db.Replay.getOrFetchReplay(req.params.replayID, function(error, replay) {
    if (replay) {
      res.locals.replay = replay;
      replay.popularity += replay.popularity + 1;
      replay.save(function(err) {
        if (err) {
          res.locals.errors.push(err.message);
        }
        next();
      });
    } else {
      if (error) {
        res.locals.errors.push(error.message);
      }
      next();
    }
  });
}

function getComments(req, res, next) {
  db.Comment.find({replayCode: req.params.replayID})
    .populate("user")
    .exec(function(error, comments) {
      if (error) {
        res.locals.errors.push(error.message);
      }
      res.locals.comments = comments;
      next();
    });
}

function getPopularReplays(req, res, next) {
  var onFind = function(error, replays) {
    if (error) {
      res.locals.errors.push(error.message);
    }
    res.locals.popularReplays = replays;
    next();
  };

  db.Replay.find({})
    .sort({popularity: -1})
    .limit(5)
    .exec(onFind);
}

function getRecentReplays(req, res, next) {
  var onFind = function(error, replays) {
    if (error) {
      res.locals.errors.push(error.message);
    }
    res.locals.recentReplays = replays;
    next();
  };

  db.Replay.find({})
    .sort({dateAdded: -1})
    .limit(5)
    .exec(onFind);
}

function checkRecaptcha(req, res, next) {
  var key = req.body["g-recaptcha-response"];
  if (!key) {
    req.session.errors.push("No ReCaptcha information received.");
    next();
    return;
  }
  https.get(require("./config").recaptchaURL + key, function(recaptchaRes) {
    var data = "";
    recaptchaRes.on("data", function(chunk) {
      data += chunk.toString();
    });
    recaptchaRes.on("end", function() {
      try {
        var parsedData = JSON.parse(data);
        req.recaptchaResult = parsedData;
        if (!req.recaptchaResult.success) {
          req.session.errors.push("ReCAPTCHA verification failed.");
          console.log("Failed ReCAPTCHA: " + req.recaptchaResult);
        }
      } catch(error) {
        req.session.errors.push(error.message);
      }
      next();
    });
  });
}

function getUserId(email, delivery, callback, req) {
  db.User.getOrCreateWithEmail(email, function(error, user) {
    if (error) {
      req.session.errors.push(error.message);
    } else {
      req.session.errors.push("An email has been sent to " + email + ".");
    }
    callback(error, user._id);
  });
}

function requestTokenIfRecaptcha(req, res, next) {
  if (req.recaptchaResult.success) {
    passwordless.requestToken(getUserId)(req, res, next);
  } else {
    next();
  }
}

router.use(setUp);

router.get("/", getPopularReplays, getRecentReplays, function(req, res) {
  res.render("index", res.locals);
});

router.get("/login", function(req, res) {
  res.render("login");
});

router.get("/logout", passwordless.logout(), function(req, res) {
  res.redirect("/");
});

router.post("/sendtoken", checkRecaptcha, requestTokenIfRecaptcha, function(req, res) {
  if (req.recaptchaResult && req.recaptchaResult.success) {
    res.redirect("/");
  } else {
    res.redirect("/login");
  }
});

router.get("/search", populateSearch, function(req, res) {
  res.render("search", res.locals);
});

router.post("/search", function(req, res) {
  req.session.search = req.body;
  res.redirect(303, "/search");
});

router.get("/replay/:replayID", fetchReplay, getComments, function(req, res) {
  res.render("replay", res.locals);
});

router.post("/replay/:replayID", function(req, res) {
  var comment = {
    user: res.locals.user,
    replayCode: req.params.replayID,
    message: req.body.comment,
  };
  db.Comment.create(comment,  function(error) {
    if (error) {
      req.session.errors.push(error.message);
    }
    res.redirect(303, "/replay/" + req.params.replayID);
  });
});

router.get("/settings", function(req, res) {
  res.render("user_settings");
});

router.post("/settings", function(req, res) {
  res.locals.user.changeUsername(req.body.new_username, function(error) {
    if (error) {
      req.session.errors.push(error.message);
    }
    res.redirect(303, "/settings");
  });
});

router.get("/about", function(req, res) {
  res.render("about");
});

module.exports = router;

<commit_msg>Log every request made<commit_after>var express = require("express");
var db = require("./db");
var passwordless = require("passwordless");
var https = require('https');

var router = express.Router();

function setUp(req, res, next) {
  console.log("New Request: " + new Date().toISOString());
  console.log(req);

  if (typeof(res.locals) == "undefined") {
    res.locals = {};
  }
  res.locals.replay = null;
  res.locals.replays = [];
  res.locals.recentReplays = [];
  res.locals.popularReplays = [];
  res.locals.errors = req.session.errors || [];
  req.session.errors = [];
  req.session.recaptchaPass = false;
  var userID = req.user;
  db.User.findById(userID, function(error, user) {
    if (error) {
      req.locals.errors.push(error.message);
    }
    res.locals.user = user;
    next();
  });
}

function populateSearch(req, res, next) {
  var search = req.session.search;
  res.locals.search = search;
  req.session.search = null;

  if (!search) {
    res.locals.search = {};
    res.locals.search.include_rated = true;
    res.locals.search.include_unrated = true;
    next();
    return;
  }

  db.Replay.search(search, function(error, replays) {
    if (error) {
      res.locals.errors.push(error.message);
      console.log(error);
    }
    if (replays.length == 0) {
      res.locals.errors.push("No results found.");
    }
    res.locals.replays = replays;
    next();
  });
}

function fetchReplay(req, res, next) {
  db.Replay.getOrFetchReplay(req.params.replayID, function(error, replay) {
    if (replay) {
      res.locals.replay = replay;
      replay.popularity += replay.popularity + 1;
      replay.save(function(err) {
        if (err) {
          res.locals.errors.push(err.message);
        }
        next();
      });
    } else {
      if (error) {
        res.locals.errors.push(error.message);
      }
      next();
    }
  });
}

function getComments(req, res, next) {
  db.Comment.find({replayCode: req.params.replayID})
    .populate("user")
    .exec(function(error, comments) {
      if (error) {
        res.locals.errors.push(error.message);
      }
      res.locals.comments = comments;
      next();
    });
}

function getPopularReplays(req, res, next) {
  var onFind = function(error, replays) {
    if (error) {
      res.locals.errors.push(error.message);
    }
    res.locals.popularReplays = replays;
    next();
  };

  db.Replay.find({})
    .sort({popularity: -1})
    .limit(5)
    .exec(onFind);
}

function getRecentReplays(req, res, next) {
  var onFind = function(error, replays) {
    if (error) {
      res.locals.errors.push(error.message);
    }
    res.locals.recentReplays = replays;
    next();
  };

  db.Replay.find({})
    .sort({dateAdded: -1})
    .limit(5)
    .exec(onFind);
}

function checkRecaptcha(req, res, next) {
  var key = req.body["g-recaptcha-response"];
  if (!key) {
    req.session.errors.push("No ReCaptcha information received.");
    next();
    return;
  }
  https.get(require("./config").recaptchaURL + key, function(recaptchaRes) {
    var data = "";
    recaptchaRes.on("data", function(chunk) {
      data += chunk.toString();
    });
    recaptchaRes.on("end", function() {
      try {
        var parsedData = JSON.parse(data);
        req.recaptchaResult = parsedData;
        if (!req.recaptchaResult.success) {
          req.session.errors.push("ReCAPTCHA verification failed.");
          console.log("Failed ReCAPTCHA: " + req.recaptchaResult);
        }
      } catch(error) {
        req.session.errors.push(error.message);
      }
      next();
    });
  });
}

function getUserId(email, delivery, callback, req) {
  db.User.getOrCreateWithEmail(email, function(error, user) {
    if (error) {
      req.session.errors.push(error.message);
    } else {
      req.session.errors.push("An email has been sent to " + email + ".");
    }
    callback(error, user._id);
  });
}

function requestTokenIfRecaptcha(req, res, next) {
  if (req.recaptchaResult.success) {
    passwordless.requestToken(getUserId)(req, res, next);
  } else {
    next();
  }
}

router.use(setUp);

router.get("/", getPopularReplays, getRecentReplays, function(req, res) {
  res.render("index", res.locals);
});

router.get("/login", function(req, res) {
  res.render("login");
});

router.get("/logout", passwordless.logout(), function(req, res) {
  res.redirect("/");
});

router.post("/sendtoken", checkRecaptcha, requestTokenIfRecaptcha, function(req, res) {
  if (req.recaptchaResult && req.recaptchaResult.success) {
    res.redirect("/");
  } else {
    res.redirect("/login");
  }
});

router.get("/search", populateSearch, function(req, res) {
  res.render("search", res.locals);
});

router.post("/search", function(req, res) {
  req.session.search = req.body;
  res.redirect(303, "/search");
});

router.get("/replay/:replayID", fetchReplay, getComments, function(req, res) {
  res.render("replay", res.locals);
});

router.post("/replay/:replayID", function(req, res) {
  var comment = {
    user: res.locals.user,
    replayCode: req.params.replayID,
    message: req.body.comment,
  };
  db.Comment.create(comment,  function(error) {
    if (error) {
      req.session.errors.push(error.message);
    }
    res.redirect(303, "/replay/" + req.params.replayID);
  });
});

router.get("/settings", function(req, res) {
  res.render("user_settings");
});

router.post("/settings", function(req, res) {
  res.locals.user.changeUsername(req.body.new_username, function(error) {
    if (error) {
      req.session.errors.push(error.message);
    }
    res.redirect(303, "/settings");
  });
});

router.get("/about", function(req, res) {
  res.render("about");
});

module.exports = router;

<|endoftext|>


<commit_before>import Marty from "marty";
import OrderConstants from "../constants/orderConstants.js";

class OrderActionCreators extends Marty.ActionCreators {
  creatFlight(flight, orderId, options) {
    this.dispatch(OrderConstants.CREATE_FLIGHT, flight, orderId, options);
  }

  createCreative(creative, flightId, options) {
    this.dispatch(OrderConstants.CREATE_CREATIVE, creative, flightId, options);
  }

  createOrder(order, options) {
    this.dispatch(OrderConstants.CREATE_ORDER, order, options);
  }

  refreshOrders() {
    this.dispaych(OrderConstants.REFRESH_CREATIVES);
  }
}

export default Marty.register(OrderActionCreators);
<commit_msg>Fix typo in createFlight action<commit_after>import Marty from "marty";
import OrderConstants from "../constants/orderConstants.js";

class OrderActionCreators extends Marty.ActionCreators {
  createFlight(flight, orderId, options) {
    this.dispatch(OrderConstants.CREATE_FLIGHT, flight, orderId, options);
  }

  createCreative(creative, flightId, options) {
    this.dispatch(OrderConstants.CREATE_CREATIVE, creative, flightId, options);
  }

  createOrder(order, options) {
    this.dispatch(OrderConstants.CREATE_ORDER, order, options);
  }

  refreshOrders() {
    this.dispaych(OrderConstants.REFRESH_CREATIVES);
  }
}

export default Marty.register(OrderActionCreators);
<|endoftext|>


<commit_before>/**
 * CollectionView
 *
 * Created by GUY on 2016/1/15.
 * @class BI.CollectionView
 * @extends BI.Widget
 */
BI.CollectionView = BI.inherit(BI.Widget, {
    _defaultConfig: function () {
        return BI.extend(BI.CollectionView.superclass._defaultConfig.apply(this, arguments), {
            baseCls: "bi-collection",
            // width: 400, //必设
            // height: 300, //必设
            overflowX: true,
            overflowY: true,
            cellSizeAndPositionGetter: BI.emptyFn,
            horizontalOverscanSize: 0,
            verticalOverscanSize: 0,
            scrollLeft: 0,
            scrollTop: 0,
            items: []
        });
    },

    _init: function () {
        BI.CollectionView.superclass._init.apply(this, arguments);
        var self = this, o = this.options;
        this.renderedCells = [];
        this.renderedKeys = [];
        this.renderRange = {};
        this._scrollLock = false;
        this._debounceRelease = BI.debounce(function () {
            self._scrollLock = false;
        }, 1000 / 60);
        this.container = BI._lazyCreateWidget({
            type: "bi.absolute"
        });
        this.element.scroll(function () {
            if (self._scrollLock === true) {
                return;
            }
            o.scrollLeft = self.element.scrollLeft();
            o.scrollTop = self.element.scrollTop();
            self._calculateChildrenToRender();
            self.fireEvent(BI.CollectionView.EVENT_SCROLL, {
                scrollLeft: o.scrollLeft,
                scrollTop: o.scrollTop
            });
        });
        BI._lazyCreateWidget({
            type: "bi.vertical",
            element: this,
            scrollable: o.overflowX === true && o.overflowY === true,
            scrolly: o.overflowX === false && o.overflowY === true,
            scrollx: o.overflowX === true && o.overflowY === false,
            items: [this.container]
        });
        if (o.items.length > 0) {
            this._calculateSizeAndPositionData();
            this._populate();
        }
    },

    // mounted之后绑定事件
    mounted: function () {
        var  o = this.options;
        if (o.scrollLeft !== 0 || o.scrollTop !== 0) {
            this.element.scrollTop(o.scrollTop);
            this.element.scrollLeft(o.scrollLeft);
        }
    },

    _calculateSizeAndPositionData: function () {
        var o = this.options;
        var cellMetadata = [];
        var sectionManager = new BI.SectionManager();
        var height = 0;
        var width = 0;

        for (var index = 0, len = o.items.length; index < len; index++) {
            var cellMetadatum = o.cellSizeAndPositionGetter(index);

            if (cellMetadatum.height == null || isNaN(cellMetadatum.height) ||
                cellMetadatum.width == null || isNaN(cellMetadatum.width) ||
                cellMetadatum.x == null || isNaN(cellMetadatum.x) ||
                cellMetadatum.y == null || isNaN(cellMetadatum.y)) {
                throw Error();
            }

            height = Math.max(height, cellMetadatum.y + cellMetadatum.height);
            width = Math.max(width, cellMetadatum.x + cellMetadatum.width);

            cellMetadatum.index = index;
            cellMetadata[index] = cellMetadatum;
            sectionManager.registerCell(cellMetadatum, index);
        }

        this._cellMetadata = cellMetadata;
        this._sectionManager = sectionManager;
        this._height = height;
        this._width = width;
    },

    _cellRenderers: function (height, width, x, y) {
        this._lastRenderedCellIndices = this._sectionManager.getCellIndices(height, width, x, y);
return this._cellGroupRenderer();
    },

    _cellGroupRenderer: function () {
        var self = this, o = this.options;
        var rendered = [];
        BI.each(this._lastRenderedCellIndices, function (i, index) {
            var cellMetadata = self._sectionManager.getCellMetadata(index);
            rendered.push(cellMetadata);
        });
return rendered;
    },

    _calculateChildrenToRender: function () {
        var self = this, o = this.options;
        var scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft());
        var scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop());
        var left = Math.max(0, scrollLeft - o.horizontalOverscanSize);
        var top = Math.max(0, scrollTop - o.verticalOverscanSize);
        var right = Math.min(this._width, scrollLeft + o.width + o.horizontalOverscanSize);
        var bottom = Math.min(this._height, scrollTop + o.height + o.verticalOverscanSize);
        if (right > 0 && bottom > 0) {
            // 如果滚动的区间并没有超出渲染的范围
            if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) {
                return;
            }
            var childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top);
            var renderedCells = [], renderedKeys = {}, renderedWidgets = {};
            // 存储所有的left和top
            var lefts = {}, tops = {};
            for (var i = 0, len = childrenToDisplay.length; i < len; i++) {
                var datum = childrenToDisplay[i];
                lefts[datum.x] = datum.x;
                lefts[datum.x + datum.width] = datum.x + datum.width;
                tops[datum.y] = datum.y;
                tops[datum.y + datum.height] = datum.y + datum.height;
            }
            lefts = BI.toArray(lefts);
            tops = BI.toArray(tops);
            var leftMap = BI.invert(lefts);
            var topMap = BI.invert(tops);
            // 存储上下左右四个边界
            var leftBorder = {}, rightBorder = {}, topBorder = {}, bottomBorder = {};
            var assertMinBorder = function (border, offset) {
                if (border[offset] == null) {
                    border[offset] = Number.MAX_VALUE;
                }
            };
            var assertMaxBorder = function (border, offset) {
                if (border[offset] == null) {
                    border[offset] = 0;
                }
            };
            for (var i = 0, len = childrenToDisplay.length; i < len; i++) {
                var datum = childrenToDisplay[i];
                var index = this.renderedKeys[datum.index] && this.renderedKeys[datum.index][1];
                var child;
                var lastDatum = childrenToDisplay[len - 1];
                if (index >= 0) {
                    if (datum.width !== this.renderedCells[index]._width) {
                        this.renderedCells[index]._width = datum.width;
                        this.renderedCells[index].el.setWidth(datum.width);
                    }
                    if (datum.height !== this.renderedCells[index]._height) {
                        this.renderedCells[index]._height = datum.height;
                        this.renderedCells[index].el.setHeight(datum.height);
                    }
                    if (this.renderedCells[index]._left !== datum.x) {
                        this.renderedCells[index].el.element.css("left", datum.x / BI.pixRatio + BI.pixUnit);
                    }
                    if (this.renderedCells[index]._top !== datum.y) {
                        this.renderedCells[index].el.element.css("top", datum.y  / BI.pixRatio + BI.pixUnit);
                    }
                    renderedCells.push(child = this.renderedCells[index]);
                } else {
                    child = BI._lazyCreateWidget(BI.extend({
                        type: "bi.label",
                        width: datum.width,
                        height: datum.height
                    }, o.items[datum.index], {
                        cls: (o.items[datum.index].cls || "") + " collection-cell" + (datum.y === 0 ? " first-row" : "") + (datum.x === 0 ? " first-col" : "") + (datum.row === lastDatum.row ? " last-row" : "") + (datum.col === lastDatum.col ? " last-col" : ""),
                        _left: datum.x,
                        _top: datum.y
                    }));
                    renderedCells.push({
                        el: child,
                        left: datum.x,
                        top: datum.y,
                        _left: datum.x,
                        _top: datum.y,
                        _width: datum.width,
                        _height: datum.height
                    });
                }
                var startTopIndex = topMap[datum.y] | 0;
                var endTopIndex = topMap[datum.y + datum.height] | 0;
                for (var k = startTopIndex; k <= endTopIndex; k++) {
                    var t = tops[k];
                    assertMinBorder(leftBorder, t);
                    assertMaxBorder(rightBorder, t);
                    leftBorder[t] = Math.min(leftBorder[t], datum.x);
                    rightBorder[t] = Math.max(rightBorder[t], datum.x + datum.width);
                }
                var startLeftIndex = leftMap[datum.x] | 0;
                var endLeftIndex = leftMap[datum.x + datum.width] | 0;
                for (var k = startLeftIndex; k <= endLeftIndex; k++) {
                    var l = lefts[k];
                    assertMinBorder(topBorder, l);
                    assertMaxBorder(bottomBorder, l);
                    topBorder[l] = Math.min(topBorder[l], datum.y);
                    bottomBorder[l] = Math.max(bottomBorder[l], datum.y + datum.height);
                }

                renderedKeys[datum.index] = [datum.index, i];
                renderedWidgets[i] = child;
            }
            // 已存在的， 需要添加的和需要删除的
            var existSet = {}, addSet = {}, deleteArray = [];
            BI.each(renderedKeys, function (i, key) {
                if (self.renderedKeys[i]) {
                    existSet[i] = key;
                } else {
                    addSet[i] = key;
                }
            });
            BI.each(this.renderedKeys, function (i, key) {
                if (existSet[i]) {
                    return;
                }
                if (addSet[i]) {
                    return;
                }
                deleteArray.push(key[1]);
            });
            BI.each(deleteArray, function (i, index) {
                // 性能优化，不调用destroy方法防止触发destroy事件
                self.renderedCells[index].el._destroy();
            });
            var addedItems = [];
            BI.each(addSet, function (index, key) {
                addedItems.push(renderedCells[key[1]]);
            });
            this.container.addItems(addedItems);
            // 拦截父子级关系
            this.container._children = renderedWidgets;
            this.container.attr("items", renderedCells);
            this.renderedCells = renderedCells;
            this.renderedKeys = renderedKeys;

            // Todo 左右比较特殊
            var minX = BI.min(leftBorder);
            var maxX = BI.max(rightBorder);

            var minY = BI.max(topBorder);
            var maxY = BI.min(bottomBorder);

            this.renderRange = {minX: minX, minY: minY, maxX: maxX, maxY: maxY};
        }
    },

    _getMaxScrollLeft: function () {
        return Math.max(0, this._width - this.options.width + (this.options.overflowX ? BI.DOM.getScrollWidth() : 0));
    },

    _getMaxScrollTop: function () {
        return Math.max(0, this._height - this.options.height + (this.options.overflowY ? BI.DOM.getScrollWidth() : 0));
    },

    _populate: function (items) {
        var o = this.options;
        this._reRange();
        if (items && items !== this.options.items) {
            this.options.items = items;
            this._calculateSizeAndPositionData();
        }
        if (o.items.length > 0) {
            this.container.setWidth(this._width);
            this.container.setHeight(this._height);

            this._calculateChildrenToRender();
            // 元素未挂载时不能设置scrollTop
            try {
                this.element.scrollTop(o.scrollTop);
                this.element.scrollLeft(o.scrollLeft);
            } catch (e) {
            }
        }
    },

    setScrollLeft: function (scrollLeft) {
        if (this.options.scrollLeft === scrollLeft) {
            return;
        }
        this._scrollLock = true;
        this.options.scrollLeft = BI.clamp(scrollLeft || 0, 0, this._getMaxScrollLeft());
        this._debounceRelease();
        this._calculateChildrenToRender();
        this.element.scrollLeft(this.options.scrollLeft);
    },

    setScrollTop: function (scrollTop) {
        if (this.options.scrollTop === scrollTop) {
            return;
        }
        this._scrollLock = true;
        this.options.scrollTop = BI.clamp(scrollTop || 0, 0, this._getMaxScrollTop());
        this._debounceRelease();
        this._calculateChildrenToRender();
        this.element.scrollTop(this.options.scrollTop);
    },

    setOverflowX: function (b) {
        var self = this;
        if (this.options.overflowX !== !!b) {
            this.options.overflowX = !!b;
            BI.nextTick(function () {
                self.element.css({overflowX: b ? "auto" : "hidden"});
            });
        }
    },

    setOverflowY: function (b) {
        var self = this;
        if (this.options.overflowY !== !!b) {
            this.options.overflowY = !!b;
            BI.nextTick(function () {
                self.element.css({overflowY: b ? "auto" : "hidden"});
            });
        }
    },

    getScrollLeft: function () {
        return this.options.scrollLeft;
    },

    getScrollTop: function () {
        return this.options.scrollTop;
    },

    getMaxScrollLeft: function () {
        return this._getMaxScrollLeft();
    },

    getMaxScrollTop: function () {
        return this._getMaxScrollTop();
    },

    // 重新计算children
    _reRange: function () {
        this.renderRange = {};
    },

    _clearChildren: function () {
        this.container._children = {};
        this.container.attr("items", []);
    },

    restore: function () {
        BI.each(this.renderedCells, function (i, cell) {
            cell.el._destroy();
        });
        this._clearChildren();
        this.renderedCells = [];
        this.renderedKeys = [];
        this.renderRange = {};
        this._scrollLock = false;
    },

    populate: function (items) {
        if (items && items !== this.options.items) {
            this.restore();
        }
        this._populate(items);
    }
});
BI.CollectionView.EVENT_SCROLL = "EVENT_SCROLL";
BI.shortcut("bi.collection_view", BI.CollectionView);
<commit_msg>JSY-4371 feat: 格式<commit_after>/**
 * CollectionView
 *
 * Created by GUY on 2016/1/15.
 * @class BI.CollectionView
 * @extends BI.Widget
 */
BI.CollectionView = BI.inherit(BI.Widget, {
    _defaultConfig: function () {
        return BI.extend(BI.CollectionView.superclass._defaultConfig.apply(this, arguments), {
            baseCls: "bi-collection",
            // width: 400, //必设
            // height: 300, //必设
            overflowX: true,
            overflowY: true,
            cellSizeAndPositionGetter: BI.emptyFn,
            horizontalOverscanSize: 0,
            verticalOverscanSize: 0,
            scrollLeft: 0,
            scrollTop: 0,
            items: []
        });
    },

    _init: function () {
        BI.CollectionView.superclass._init.apply(this, arguments);
        var self = this, o = this.options;
        this.renderedCells = [];
        this.renderedKeys = [];
        this.renderRange = {};
        this._scrollLock = false;
        this._debounceRelease = BI.debounce(function () {
            self._scrollLock = false;
        }, 1000 / 60);
        this.container = BI._lazyCreateWidget({
            type: "bi.absolute"
        });
        this.element.scroll(function () {
            if (self._scrollLock === true) {
                return;
            }
            o.scrollLeft = self.element.scrollLeft();
            o.scrollTop = self.element.scrollTop();
            self._calculateChildrenToRender();
            self.fireEvent(BI.CollectionView.EVENT_SCROLL, {
                scrollLeft: o.scrollLeft,
                scrollTop: o.scrollTop
            });
        });
        BI._lazyCreateWidget({
            type: "bi.vertical",
            element: this,
            scrollable: o.overflowX === true && o.overflowY === true,
            scrolly: o.overflowX === false && o.overflowY === true,
            scrollx: o.overflowX === true && o.overflowY === false,
            items: [this.container]
        });
        if (o.items.length > 0) {
            this._calculateSizeAndPositionData();
            this._populate();
        }
    },

    // mounted之后绑定事件
    mounted: function () {
        var  o = this.options;
        if (o.scrollLeft !== 0 || o.scrollTop !== 0) {
            this.element.scrollTop(o.scrollTop);
            this.element.scrollLeft(o.scrollLeft);
        }
    },

    _calculateSizeAndPositionData: function () {
        var o = this.options;
        var cellMetadata = [];
        var sectionManager = new BI.SectionManager();
        var height = 0;
        var width = 0;

        for (var index = 0, len = o.items.length; index < len; index++) {
            var cellMetadatum = o.cellSizeAndPositionGetter(index);

            if (cellMetadatum.height == null || isNaN(cellMetadatum.height) ||
                cellMetadatum.width == null || isNaN(cellMetadatum.width) ||
                cellMetadatum.x == null || isNaN(cellMetadatum.x) ||
                cellMetadatum.y == null || isNaN(cellMetadatum.y)) {
                throw Error();
            }

            height = Math.max(height, cellMetadatum.y + cellMetadatum.height);
            width = Math.max(width, cellMetadatum.x + cellMetadatum.width);

            cellMetadatum.index = index;
            cellMetadata[index] = cellMetadatum;
            sectionManager.registerCell(cellMetadatum, index);
        }

        this._cellMetadata = cellMetadata;
        this._sectionManager = sectionManager;
        this._height = height;
        this._width = width;
    },

    _cellRenderers: function (height, width, x, y) {
        this._lastRenderedCellIndices = this._sectionManager.getCellIndices(height, width, x, y);
        return this._cellGroupRenderer();
    },

    _cellGroupRenderer: function () {
        var self = this, o = this.options;
        var rendered = [];
        BI.each(this._lastRenderedCellIndices, function (i, index) {
            var cellMetadata = self._sectionManager.getCellMetadata(index);
            rendered.push(cellMetadata);
        });
        return rendered;
    },

    _calculateChildrenToRender: function () {
        var self = this, o = this.options;
        var scrollLeft = BI.clamp(o.scrollLeft, 0, this._getMaxScrollLeft());
        var scrollTop = BI.clamp(o.scrollTop, 0, this._getMaxScrollTop());
        var left = Math.max(0, scrollLeft - o.horizontalOverscanSize);
        var top = Math.max(0, scrollTop - o.verticalOverscanSize);
        var right = Math.min(this._width, scrollLeft + o.width + o.horizontalOverscanSize);
        var bottom = Math.min(this._height, scrollTop + o.height + o.verticalOverscanSize);
        if (right > 0 && bottom > 0) {
            // 如果滚动的区间并没有超出渲染的范围
            if (top >= this.renderRange.minY && bottom <= this.renderRange.maxY && left >= this.renderRange.minX && right <= this.renderRange.maxX) {
                return;
            }
            var childrenToDisplay = this._cellRenderers(bottom - top, right - left, left, top);
            var renderedCells = [], renderedKeys = {}, renderedWidgets = {};
            // 存储所有的left和top
            var lefts = {}, tops = {};
            for (var i = 0, len = childrenToDisplay.length; i < len; i++) {
                var datum = childrenToDisplay[i];
                lefts[datum.x] = datum.x;
                lefts[datum.x + datum.width] = datum.x + datum.width;
                tops[datum.y] = datum.y;
                tops[datum.y + datum.height] = datum.y + datum.height;
            }
            lefts = BI.toArray(lefts);
            tops = BI.toArray(tops);
            var leftMap = BI.invert(lefts);
            var topMap = BI.invert(tops);
            // 存储上下左右四个边界
            var leftBorder = {}, rightBorder = {}, topBorder = {}, bottomBorder = {};
            var assertMinBorder = function (border, offset) {
                if (border[offset] == null) {
                    border[offset] = Number.MAX_VALUE;
                }
            };
            var assertMaxBorder = function (border, offset) {
                if (border[offset] == null) {
                    border[offset] = 0;
                }
            };
            for (var i = 0, len = childrenToDisplay.length; i < len; i++) {
                var datum = childrenToDisplay[i];
                var index = this.renderedKeys[datum.index] && this.renderedKeys[datum.index][1];
                var child;
                var lastDatum = childrenToDisplay[len - 1];
                if (index >= 0) {
                    if (datum.width !== this.renderedCells[index]._width) {
                        this.renderedCells[index]._width = datum.width;
                        this.renderedCells[index].el.setWidth(datum.width);
                    }
                    if (datum.height !== this.renderedCells[index]._height) {
                        this.renderedCells[index]._height = datum.height;
                        this.renderedCells[index].el.setHeight(datum.height);
                    }
                    if (this.renderedCells[index]._left !== datum.x) {
                        this.renderedCells[index].el.element.css("left", datum.x / BI.pixRatio + BI.pixUnit);
                    }
                    if (this.renderedCells[index]._top !== datum.y) {
                        this.renderedCells[index].el.element.css("top", datum.y  / BI.pixRatio + BI.pixUnit);
                    }
                    renderedCells.push(child = this.renderedCells[index]);
                } else {
                    child = BI._lazyCreateWidget(BI.extend({
                        type: "bi.label",
                        width: datum.width,
                        height: datum.height
                    }, o.items[datum.index], {
                        cls: (o.items[datum.index].cls || "") + " collection-cell" + (datum.y === 0 ? " first-row" : "") + (datum.x === 0 ? " first-col" : "") + (datum.row === lastDatum.row ? " last-row" : "") + (datum.col === lastDatum.col ? " last-col" : ""),
                        _left: datum.x,
                        _top: datum.y
                    }));
                    renderedCells.push({
                        el: child,
                        left: datum.x,
                        top: datum.y,
                        _left: datum.x,
                        _top: datum.y,
                        _width: datum.width,
                        _height: datum.height
                    });
                }
                var startTopIndex = topMap[datum.y] | 0;
                var endTopIndex = topMap[datum.y + datum.height] | 0;
                for (var k = startTopIndex; k <= endTopIndex; k++) {
                    var t = tops[k];
                    assertMinBorder(leftBorder, t);
                    assertMaxBorder(rightBorder, t);
                    leftBorder[t] = Math.min(leftBorder[t], datum.x);
                    rightBorder[t] = Math.max(rightBorder[t], datum.x + datum.width);
                }
                var startLeftIndex = leftMap[datum.x] | 0;
                var endLeftIndex = leftMap[datum.x + datum.width] | 0;
                for (var k = startLeftIndex; k <= endLeftIndex; k++) {
                    var l = lefts[k];
                    assertMinBorder(topBorder, l);
                    assertMaxBorder(bottomBorder, l);
                    topBorder[l] = Math.min(topBorder[l], datum.y);
                    bottomBorder[l] = Math.max(bottomBorder[l], datum.y + datum.height);
                }

                renderedKeys[datum.index] = [datum.index, i];
                renderedWidgets[i] = child;
            }
            // 已存在的， 需要添加的和需要删除的
            var existSet = {}, addSet = {}, deleteArray = [];
            BI.each(renderedKeys, function (i, key) {
                if (self.renderedKeys[i]) {
                    existSet[i] = key;
                } else {
                    addSet[i] = key;
                }
            });
            BI.each(this.renderedKeys, function (i, key) {
                if (existSet[i]) {
                    return;
                }
                if (addSet[i]) {
                    return;
                }
                deleteArray.push(key[1]);
            });
            BI.each(deleteArray, function (i, index) {
                // 性能优化，不调用destroy方法防止触发destroy事件
                self.renderedCells[index].el._destroy();
            });
            var addedItems = [];
            BI.each(addSet, function (index, key) {
                addedItems.push(renderedCells[key[1]]);
            });
            this.container.addItems(addedItems);
            // 拦截父子级关系
            this.container._children = renderedWidgets;
            this.container.attr("items", renderedCells);
            this.renderedCells = renderedCells;
            this.renderedKeys = renderedKeys;

            // Todo 左右比较特殊
            var minX = BI.min(leftBorder);
            var maxX = BI.max(rightBorder);

            var minY = BI.max(topBorder);
            var maxY = BI.min(bottomBorder);

            this.renderRange = {minX: minX, minY: minY, maxX: maxX, maxY: maxY};
        }
    },

    _getMaxScrollLeft: function () {
        return Math.max(0, this._width - this.options.width + (this.options.overflowX ? BI.DOM.getScrollWidth() : 0));
    },

    _getMaxScrollTop: function () {
        return Math.max(0, this._height - this.options.height + (this.options.overflowY ? BI.DOM.getScrollWidth() : 0));
    },

    _populate: function (items) {
        var o = this.options;
        this._reRange();
        if (items && items !== this.options.items) {
            this.options.items = items;
            this._calculateSizeAndPositionData();
        }
        if (o.items.length > 0) {
            this.container.setWidth(this._width);
            this.container.setHeight(this._height);

            this._calculateChildrenToRender();
            // 元素未挂载时不能设置scrollTop
            try {
                this.element.scrollTop(o.scrollTop);
                this.element.scrollLeft(o.scrollLeft);
            } catch (e) {
            }
        }
    },

    setScrollLeft: function (scrollLeft) {
        if (this.options.scrollLeft === scrollLeft) {
            return;
        }
        this._scrollLock = true;
        this.options.scrollLeft = BI.clamp(scrollLeft || 0, 0, this._getMaxScrollLeft());
        this._debounceRelease();
        this._calculateChildrenToRender();
        this.element.scrollLeft(this.options.scrollLeft);
    },

    setScrollTop: function (scrollTop) {
        if (this.options.scrollTop === scrollTop) {
            return;
        }
        this._scrollLock = true;
        this.options.scrollTop = BI.clamp(scrollTop || 0, 0, this._getMaxScrollTop());
        this._debounceRelease();
        this._calculateChildrenToRender();
        this.element.scrollTop(this.options.scrollTop);
    },

    setOverflowX: function (b) {
        var self = this;
        if (this.options.overflowX !== !!b) {
            this.options.overflowX = !!b;
            BI.nextTick(function () {
                self.element.css({overflowX: b ? "auto" : "hidden"});
            });
        }
    },

    setOverflowY: function (b) {
        var self = this;
        if (this.options.overflowY !== !!b) {
            this.options.overflowY = !!b;
            BI.nextTick(function () {
                self.element.css({overflowY: b ? "auto" : "hidden"});
            });
        }
    },

    getScrollLeft: function () {
        return this.options.scrollLeft;
    },

    getScrollTop: function () {
        return this.options.scrollTop;
    },

    getMaxScrollLeft: function () {
        return this._getMaxScrollLeft();
    },

    getMaxScrollTop: function () {
        return this._getMaxScrollTop();
    },

    // 重新计算children
    _reRange: function () {
        this.renderRange = {};
    },

    _clearChildren: function () {
        this.container._children = {};
        this.container.attr("items", []);
    },

    restore: function () {
        BI.each(this.renderedCells, function (i, cell) {
            cell.el._destroy();
        });
        this._clearChildren();
        this.renderedCells = [];
        this.renderedKeys = [];
        this.renderRange = {};
        this._scrollLock = false;
    },

    populate: function (items) {
        if (items && items !== this.options.items) {
            this.restore();
        }
        this._populate(items);
    }
});
BI.CollectionView.EVENT_SCROLL = "EVENT_SCROLL";
BI.shortcut("bi.collection_view", BI.CollectionView);
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');

var template = fs.readFileSync(__dirname + '/input-variable-table.html', 'utf8');

module.exports = [ 'ViewsProvider', function(ViewsProvider) {

  ViewsProvider.registerDefaultView('cockpit.decisionInstance.tab', {
    id: 'decision-input-table',
    label: 'Inputs',
    template: template,
    controller: [
      '$scope',
      function($scope) {
        $scope.loadingState = $scope.decisionInstance.inputs > 0 ? 'LOADED' : 'EMPTY';

        $scope.variables = $scope.decisionInstance.inputs.map(function(variable) {
          return {
            variable: {
              type: variable.type,
              value: variable.value,
              name: variable.clauseName || variable.clauseId,
              valueInfo: variable.valueInfo
            }
          };
        });
      }],
    priority: 20
  });
}];

<commit_msg>fix: add missing length to expression<commit_after>'use strict';

var fs = require('fs');

var template = fs.readFileSync(__dirname + '/input-variable-table.html', 'utf8');

module.exports = [ 'ViewsProvider', function(ViewsProvider) {

  ViewsProvider.registerDefaultView('cockpit.decisionInstance.tab', {
    id: 'decision-input-table',
    label: 'Inputs',
    template: template,
    controller: [
      '$scope',
      function($scope) {
        $scope.loadingState = $scope.decisionInstance.inputs.length > 0 ? 'LOADED' : 'EMPTY';

        $scope.variables = $scope.decisionInstance.inputs.map(function(variable) {
          return {
            variable: {
              type: variable.type,
              value: variable.value,
              name: variable.clauseName || variable.clauseId,
              valueInfo: variable.valueInfo
            }
          };
        });
      }],
    priority: 20
  });
}];

<|endoftext|>


<commit_before>function Solution(posX, posY, id, raphael) {
    this.posX = posX;
    this.posY = posY;
    this.id = id;
    this.data = $.parseJSON(window.data).solutions[id];
    this.raphael = raphael;
    this.sprite = raphael.circle(posX, posY, 40).attr({fill: '#6DA2FF', stroke: "none"});
    this.sprite.node.id = id;
    this.textSprite = undefined;
    this.createText();
}

Solution.prototype.createText = function () {

    this.textSprite = this.raphael.text(this.posX, this.posY).attr({opacity: 0});
    var textSprite = this.textSprite;

    console.log("LIKELY ERROR HERE")
    var text = $.parseJSON(window.data).solutions[this.id].title || "Failure";
    var words = text.split(" ");
    var tempText = "";
    for (var i = 0; i < words.length; i++) {
        textSprite.attr("text", tempText + " " + words[i]);
        if (textSprite.getBBox().width > 50) {
            tempText += "\n" + words[i];
        } else {
            tempText += " " + words[i];
        }
    }

    textSprite.attr("text", tempText);
    textSprite.attr({ "font-size": 14, "font-family": "Opificio", "fill": "#FFFFFF"});
    textSprite.node.setAttribute("pointer-events", "none");
};

Solution.prototype.animate = function (direction) {
    var scale = direction == "in" ? "s1.3" : "s1.0";
    var opacity = direction == "in" ? 1 : 0;
    this.sprite.animate({transform: scale}, 400);
    this.textSprite.animate({transform: scale}, 400);
    this.textSprite.animate({opacity: opacity}, 300).toFront();
};

Solution.prototype.addEventListeners = function () {
    var target = $('#' + this.id)
    target.bind({
        click: function () {
            if (!Percolator.isZooming) {
                Percolator.zoomIn(this);
                if ($("#used_and_abused")) {
                    Comments.appendDiv("solutions", solutionNumber)
                } else {
                    Comments.appendDiv("solutions", solutionNumber)
                }
            }
        },
        mouseenter: function () {
            if (!Percolator.isZooming) {
                BubbleGraph.solutions[this.id].animate("in")
            }
        },
        mouseleave: function () {
            if (!Percolator.isZooming) {
                BubbleGraph.solutions[this.id].animate("out")
            }
        }
    });
};
<commit_msg>solution title now concatenates and displays better<commit_after>function Solution(posX, posY, id, raphael) {
    this.posX = posX;
    this.posY = posY;
    this.id = id;
    this.data = $.parseJSON(window.data).solutions[id];
    this.raphael = raphael;
    this.sprite = raphael.circle(posX, posY, 40).attr({fill: '#6DA2FF', stroke: "none"});
    this.sprite.node.id = id;
    this.textSprite = undefined;
    this.createText();
}

Solution.prototype.createText = function () {

    this.textSprite = this.raphael.text(this.posX, this.posY).attr({opacity: 0});
    var textSprite = this.textSprite;

    console.log("LIKELY ERROR HERE")
    var text = $.parseJSON(window.data).solutions[this.id].title || "Failure";
    if (text.length > 55) {
        text = text.substring(0, 45) + "...";
    };
    var words = text.split(" ");
    var tempText = "";
    for (var i = 0; i < words.length; i++) {
        textSprite.attr("text", tempText + " " + words[i]);
        if (textSprite.getBBox().width > 60) {
            tempText += "\n" + words[i];
        } else {
            tempText += " " + words[i];
        }
    }

    textSprite.attr("text", tempText);
    textSprite.attr({ "font-size": 10, "font-family": "Opificio", "fill": "#FFFFFF"});
    textSprite.node.setAttribute("pointer-events", "none");
};

Solution.prototype.animate = function (direction) {
    var scale = direction == "in" ? "s1.3" : "s1.0";
    var opacity = direction == "in" ? 1 : 0;
    this.sprite.animate({transform: scale}, 400);
    this.textSprite.animate({transform: scale}, 400);
    this.textSprite.animate({opacity: opacity}, 300).toFront();
};

Solution.prototype.addEventListeners = function () {
    var target = $('#' + this.id)
    target.bind({
        click: function () {
            if (!Percolator.isZooming) {
                Percolator.zoomIn(this);
                if ($("#used_and_abused")) {
                    Comments.appendDiv("solutions", solutionNumber)
                } else {
                    Comments.appendDiv("solutions", solutionNumber)
                }
            }
        },
        mouseenter: function () {
            if (!Percolator.isZooming) {
                BubbleGraph.solutions[this.id].animate("in")
            }
        },
        mouseleave: function () {
            if (!Percolator.isZooming) {
                BubbleGraph.solutions[this.id].animate("out")
            }
        }
    });
};
<|endoftext|>


<commit_before>import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import ProfilePic from 'components/ProfilePic';
import Button from 'components/Button';
import ErrorBoundary from 'components/Wrappers/ErrorBoundary';
import { openSigninModal } from 'redux/actions/UserActions';
import { connect } from 'react-redux';
import { container } from './Styles';
import { Color } from 'constants/css';

ProfileWidget.propTypes = {
  history: PropTypes.object,
  loadImage: PropTypes.func,
  openSigninModal: PropTypes.func,
  profilePicId: PropTypes.number,
  profileTheme: PropTypes.string,
  realName: PropTypes.string,
  showAlert: PropTypes.func,
  userId: PropTypes.number,
  username: PropTypes.string
};

function ProfileWidget({
  history,
  loadImage,
  openSigninModal,
  profilePicId,
  profileTheme,
  realName,
  showAlert,
  userId,
  username
}) {
  const FileInputRef = useRef(null);
  const themeColor = profileTheme || 'logoBlue';

  return (
    <ErrorBoundary>

 (username ? history.push(`/users/${username}`) : null)}
        className={container({
          username: Color[themeColor](0.6),
          usernameHovered: Color[themeColor]()
        })}
      >
        {username && (

            <ProfilePic
              className="widget__profile-pic"
              style={{
                cursor: userId ? 'pointer' : 'default'
              }}
              userId={userId}
              profilePicId={profilePicId}
              onClick={() => {
                if (userId) history.push(`/users/${username}`);
              }}
            />

              {username}
              {realName && (

                  ({realName})

              )}

        )}

          {userId && (

              <Button
                style={{ width: '100%' }}
                transparent
                onClick={() => history.push(`/users/${username}`)}
              >
                View Profile
              </Button>
              <Button
                style={{ width: '100%' }}
                transparent
                onClick={() => FileInputRef.current.click()}
              >
                Change Picture
              </Button>

          )}

            {!userId && (
              <>

Log in

to access all features

              </>
            )}
            {!userId && (
              <Button
                filled
                color="green"
                style={{ marginTop: '1rem' }}
                onClick={openSigninModal}
              >
                Tap here!
              </Button>
            )}

          <input
            ref={FileInputRef}
            style={{ display: 'none' }}
            type="file"
            onChange={handlePicture}
            accept="image/*"
          />

    </ErrorBoundary>
  );

  function handlePicture(event) {
    const reader = new FileReader();
    const maxSize = 5000;
    const file = event.target.files[0];
    if (file.size / 1000 > maxSize) {
      return showAlert();
    }
    reader.onload = loadImage;
    reader.readAsDataURL(file);
    event.target.value = null;
  }
}

export default connect(
  state => ({
    realName: state.UserReducer.realName,
    twinkleXP: state.UserReducer.twinkleXP,
    username: state.UserReducer.username,
    userId: state.UserReducer.userId,
    profilePicId: state.UserReducer.profilePicId,
    profileTheme: state.UserReducer.profileTheme
  }),
  { openSigninModal }
)(ProfileWidget);
<commit_msg>minor fix<commit_after>import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import ProfilePic from 'components/ProfilePic';
import Button from 'components/Button';
import ErrorBoundary from 'components/Wrappers/ErrorBoundary';
import { openSigninModal } from 'redux/actions/UserActions';
import { connect } from 'react-redux';
import { container } from './Styles';
import { Color } from 'constants/css';

ProfileWidget.propTypes = {
  history: PropTypes.object,
  loadImage: PropTypes.func,
  openSigninModal: PropTypes.func,
  profilePicId: PropTypes.number,
  profileTheme: PropTypes.string,
  realName: PropTypes.string,
  showAlert: PropTypes.func,
  userId: PropTypes.number,
  username: PropTypes.string
};

function ProfileWidget({
  history,
  loadImage,
  openSigninModal,
  profilePicId,
  profileTheme,
  realName,
  showAlert,
  userId,
  username
}) {
  const FileInputRef = useRef(null);
  const themeColor = profileTheme || 'logoBlue';

  return (
    <ErrorBoundary>

 (username ? history.push(`/users/${username}`) : null)}
        className={container({
          username: Color[themeColor](0.6),
          usernameHovered: Color[themeColor]()
        })}
      >
        {username && (

            <ProfilePic
              className="widget__profile-pic"
              style={{
                cursor: userId ? 'pointer' : 'default'
              }}
              userId={userId}
              profilePicId={profilePicId}
              onClick={() => {
                if (userId) history.push(`/users/${username}`);
              }}
            />

              {username}
              {realName && (

                  ({realName})

              )}

        )}

          {userId && (

              <Button
                style={{ width: '100%' }}
                transparent
                onClick={() => history.push(`/users/${username}`)}
              >
                View Profile
              </Button>
              <Button
                style={{ width: '100%' }}
                transparent
                onClick={() => FileInputRef.current.click()}
              >
                Change Picture
              </Button>

          )}

            {!userId && (
              <>

Log in

to access all features

              </>
            )}
            {!userId && (
              <Button
                filled
                color="green"
                style={{ marginTop: '1rem' }}
                onClick={openSigninModal}
              >
                Tap here!
              </Button>
            )}

          <input
            ref={FileInputRef}
            style={{ display: 'none' }}
            type="file"
            onChange={handlePicture}
            accept="image/*"
          />

    </ErrorBoundary>
  );

  function handlePicture(event) {
    const reader = new FileReader();
    const maxSize = 5000;
    const file = event.target.files[0];
    if (file.size / 1000 > maxSize) {
      return showAlert();
    }
    reader.onload = loadImage;
    reader.readAsDataURL(file);
    event.target.value = null;
  }
}

export default connect(
  state => ({
    realName: state.UserReducer.realName,
    twinkleXP: state.UserReducer.twinkleXP,
    username: state.UserReducer.username,
    userId: state.UserReducer.userId,
    profilePicId: state.UserReducer.profilePicId,
    profileTheme: state.UserReducer.profileTheme
  }),
  { openSigninModal }
)(ProfileWidget);
<|endoftext|>


<commit_before>let getBase = (route) => {
  return '/' + route.path;
};

module.exports = (app, route) => {

  app.get(getBase(route) + '/:id', (req, res) => {
    try {
      if (!route.handler.getOne) return res.sendStatus(405);

      let id = req.params.id;
      let result = route.handler.getOne(id);

      if (!result) return res.sendStatus(404);

      return res
        .status(200)
        .send(result);
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  app.get(getBase(route), (req, res) => {
    try {
      if (!route.handler.get) return res.sendStatus(405);

      return res
        .status(200)
        .send(route.handler.get());
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  app.post(getBase(route), (req, res) => {
    try {
      if (!Object.keys(req.body).length) {
        return res
          .status(400)
          .send('No body');
      }

      if (!route.handler.post) return res.sendStatus(405);
      let id = route.handler.post(req.body);

      return res
        .set({'Location': id})
        .sendStatus(200);
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  app.put(getBase(route) + '/:id', (req, res) => {
    try {
      if (!Object.keys(req.body).length) {
        return res
          .status(400)
          .send('No body');
      }

      let id = req.params.id;
      if (!route.handler.put) return res.sendStatus(405);
      let result = route.handler.put(id, req.body);

      if (!result) return res.sendStatus(404);

      debugger;
      return res
        .status(200)
        .send(result);
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  app.patch(getBase(route) + '/:id', (req, res) => {
    try {
      if (!Object.keys(req.body).length) {
        return res
          .status(400)
          .send('No body');
      }

      let id = req.params.id;
      if (!route.handler.patch) return res.sendStatus(405);
      let result = route.handler.patch(id, req.body);

      if (!result) return res.sendStatus(404);

      return res
        .status(200)
        .send(result);
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  app.delete(getBase(route) + '/:id', (req, res) => {
    try {
      let id = req.params.id;
      if (!route.handler.delete) return res.sendStatus(405);

      let result = route.handler.delete(id);
      let status = result ? 204 : 404;

      return res
        .sendStatus(status);
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  // Complain about PUT with no id.
  app.put(getBase(route), (req, res) => {
    return res
      .status(400)
      .send('Bad request');
  });

  // Complain about PATCH with no id.
  app.patch(getBase(route), (req, res) => {
    return res
      .status(400)
      .send('Bad request');
  });

  // Complain about DELETE with no id.
  app.delete(getBase(route), (req, res) => {
    return res
      .status(400)
      .send('Bad request');
  });

};
<commit_msg>local changes<commit_after>let getBase = (route) => {
  return '/' + route.path + '/';
};

module.exports = (app, route) => {

  app.get(getBase(route) + ':id', (req, res) => {
    try {
      if (!route.handler.getOne) return res.sendStatus(405);

      let id = req.params.id;
      let result = route.handler.getOne(id);

      if (!result) return res.sendStatus(404);

      return res
        .status(200)
        .send(result);
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  app.get(getBase(route), (req, res) => {
    try {
      if (!route.handler.get) return res.sendStatus(405);

      return res
        .status(200)
        .send(route.handler.get());
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  app.post(getBase(route), (req, res) => {
    try {
      if (!Object.keys(req.body).length) {
        return res
          .status(400)
          .send('No body');
      }

      if (!route.handler.post) return res.sendStatus(405);
      let id = route.handler.post(req.body);

      return res
        .set({'Location': id})
        .sendStatus(200);
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  app.put(getBase(route) + ':id', (req, res) => {
    try {
      if (!Object.keys(req.body).length) {
        return res
          .status(400)
          .send('No body');
      }

      let id = req.params.id;
      if (!route.handler.put) return res.sendStatus(405);
      let result = route.handler.put(id, req.body);

      if (!result) return res.sendStatus(404);

      debugger;
      return res
        .status(200)
        .send(result);
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  app.patch(getBase(route) + ':id', (req, res) => {
    try {
      if (!Object.keys(req.body).length) {
        return res
          .status(400)
          .send('No body');
      }

      let id = req.params.id;
      if (!route.handler.patch) return res.sendStatus(405);
      let result = route.handler.patch(id, req.body);

      if (!result) return res.sendStatus(404);

      return res
        .status(200)
        .send(result);
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  app.delete(getBase(route) + ':id', (req, res) => {
    try {
      let id = req.params.id;
      if (!route.handler.delete) return res.sendStatus(405);

      let result = route.handler.delete(id);
      let status = result ? 204 : 404;

      return res
        .sendStatus(status);
    }
    catch (ex) {
      console.error(ex);
      return res
        .sendStatus(500);
    }
  });

  // Complain about PUT with no id.
  app.put(getBase(route), (req, res) => {
    return res
      .status(400)
      .send('Bad request');
  });

  // Complain about PATCH with no id.
  app.patch(getBase(route), (req, res) => {
    return res
      .status(400)
      .send('Bad request');
  });

  // Complain about DELETE with no id.
  app.delete(getBase(route), (req, res) => {
    return res
      .status(400)
      .send('Bad request');
  });

};
<|endoftext|>


<commit_before>function Solution(posX, posY, id, raphael) {
    this.posX = posX;
    this.posY = posY;
    this.id = id;
    this.data = $.parseJSON(window.data).solutions[id];
    this.raphael = raphael;
    this.upvotes = $.parseJSON(window.data).solutions[this.id].upvotes;
    this.downvotes = $.parseJSON(window.data).solutions[this.id].downvotes;
    this.radius = 10 + (this.upvotes + this.downvotes)
    this.frameSprite = raphael.circle(posX, posY, this.radius + (this.radius * .1)).attr({fill: this.createVoteFrame(), stroke: 'none'});
    this.sprite = raphael.circle(posX, posY, this.radius).attr({fill: '#6DA2FF', stroke: "none"});
    this.sprite.node.id = id;
    this.textSprite = undefined;
    this.createText();
    this.frameColor = this.createVoteFrame();
}

Solution.prototype.createText = function () {

    this.textSprite = this.raphael.text(this.posX, (this.posY - 5)).attr({opacity: 0});
    var textSprite = this.textSprite;

    //TODO
    console.log("LIKELY ERROR HERE")
    if (Percolator.currentState == "problem"){
        $('#render-solution-form').show();
        $("#improvement-button").hide();
    } else {
        $('#render-solution-form').hide();
        $("#improvement-button").show();
    };

    var text = $.parseJSON(window.data).solutions[this.id].title || "Failure";
    if (text.length > 55) {
        text = text.substring(0, 45) + "...";
    };

    var words = text.split(" ");
    var tempText = "";
    for (var i = 0; i < words.length; i++) {
        textSprite.attr("text", tempText + " " + words[i]);
        if (textSprite.getBBox().width > (1.3*this.radius)) {
            tempText += "\n" + words[i];
        } else {
            tempText += " " + words[i];
        }
    }

    textSprite.attr("text", tempText);
    textSprite.attr({ "font-size": ((this.radius * .15)+3), "font-family": "Opificio", "fill": "#FFFFFF"});
    textSprite.node.setAttribute("pointer-events", "none");
};

Solution.prototype.animate = function (direction) {
    var scale = direction == "in" ? "s1.3" : "s1.0";
    var opacity = direction == "in" ? 1 : 0;
    this.sprite.animate({transform: scale}, 400);
    this.textSprite.animate({transform: scale}, 400);
    this.textSprite.animate({opacity: opacity}, 300);//.toFront();
    this.frameSprite.animate({transform: scale}, 400);
};

Solution.prototype.addEventListeners = function () {
    var target = $('#' + this.id)
    target.bind({
        click: function () {
            if (!Percolator.isZooming) {
                Percolator.solutionNumber = this.id;
                Percolator.zoomIn(this);
                Percolator.currentState = "solution";
                if ($("#used_and_abused")) {
                    Comments.appendDiv("solutions", solutionNumber)
                } else {
                    Comments.appendDiv("solutions", solutionNumber)
                }
            }
        },
        mouseenter: function () {
            if (!Percolator.isZooming) {
                BubbleGraph.solutions[this.id].animate("in")
            }
        },
        mouseleave: function () {
            if (!Percolator.isZooming) {
                BubbleGraph.solutions[this.id].animate("out")
            }
        }
    });
};

Solution.prototype.createVoteFrame = function() {
    var upvoteRatio = this.upvotes / (this.upvotes + this.downvotes)
    var downvoteRatio = this.downvotes / (this.upvotes + this.downvotes)
    var r = 255*downvoteRatio;
    var g = 255*upvoteRatio;
    var b = 0;
    return rgbToHex(r,g,b);
    function rgbToHex(r,g,b) {return "#"+toHex(r)+toHex(g)+toHex(b)}
    function toHex(n) {
       n = parseInt(n,10);
       if (isNaN(n)) return "00";
       n = Math.max(0,Math.min(n,255));
       return "0123456789ABCDEF".charAt((n-n%16)/16)
       + "0123456789ABCDEF".charAt(n%16);
   }
};
<commit_msg>-insert logic to differentiate between initial and later waves of solution creates(solution here being used interchangeably with improvements--next iteration coming soon) -bind newly created canvas divs accordingly -restrict animation logic to original solution create<commit_after>function Solution(posX, posY, id, raphael) {
    if (typeof id === "number") {
        this.id = id;
    } else {
        var numId = id.replace(/_/g, '')
        this.id = numId
        this.lifeSaver = id
    }
    this.posX = posX;
    this.posY = posY;
    this.data = $.parseJSON(window.data).solutions[id];
    this.raphael = raphael;
    this.upvotes = $.parseJSON(window.data).solutions[this.id].upvotes;
    this.downvotes = $.parseJSON(window.data).solutions[this.id].downvotes;
    this.radius = 10 + (this.upvotes + this.downvotes)
    this.frameSprite = raphael.circle(posX, posY, this.radius + (this.radius * .1)).attr({fill: this.createVoteFrame(), stroke: 'none'});
    this.sprite = raphael.circle(posX, posY, this.radius).attr({fill: '#6DA2FF', stroke: "none", XXX: "SIGNIFIER"});
    this.sprite.node.id = id;
    this.textSprite = undefined;
    this.createText();
    this.frameColor = this.createVoteFrame();
}

Solution.prototype.createText = function () {

    this.textSprite = this.raphael.text(this.posX, (this.posY - 5)).attr({opacity: 0});
    var textSprite = this.textSprite;

    if (Percolator.currentState == "problem"){
        $('#render-solution-form').show();
        $("#improvement-button").hide();
    } else {
        $('#render-solution-form').hide();
        $("#improvement-button").show();
    };

    var text = $.parseJSON(window.data).solutions[this.id].title || "Failure";
    if (text.length > 55) {
        text = text.substring(0, 45) + "...";
    };

    var words = text.split(" ");
    var tempText = "";
    for (var i = 0; i < words.length; i++) {
        textSprite.attr("text", tempText + " " + words[i]);
        if (textSprite.getBBox().width > (1.3*this.radius)) {
            tempText += "\n" + words[i];
        } else {
            tempText += " " + words[i];
        }
    }

    textSprite.attr("text", tempText);
    textSprite.attr({ "font-size": ((this.radius * .15)+3), "font-family": "Opificio", "fill": "#FFFFFF"});
    textSprite.node.setAttribute("pointer-events", "none");
};

Solution.prototype.animate = function (direction) { // only called during the initial wave of creates
    var scale = direction == "in" ? "s1.3" : "s1.0";
    var opacity = direction == "in" ? 1 : 0;
    this.sprite.animate({transform: scale}, 400);
    this.textSprite.animate({transform: scale}, 400);
    this.textSprite.animate({opacity: opacity}, 300);//.toFront();
    this.frameSprite.animate({transform: scale}, 400);
};

Solution.prototype.addEventListeners = function () {
    var saveLifer = this.lifeSaver

    if (saveLifer) {
        var target = $("#" + this.lifeSaver)
    } else {
        var target = $('#' + this.id)
    }
    target.bind({
        click: function () {
            if (!Percolator.isZooming) {
                if (saveLifer) {
                    Percolator.zoomIn($("#" + saveLifer)[0])
                } else {
                    Percolator.zoomIn(this)
                }
                // This needs to be made dynamic to allow for parsing of improvements from server side
                Percolator.currentState = "solution";
                // This needs to be made dynamic to allow for parsing of improvements from server side
                if ($("#used_and_abused")) {
                    Comments.appendDiv("solutions", solutionNumber)
                } else {
                    Comments.appendDiv("solutions", solutionNumber)
                }
            }
        },
        mouseenter: function () {
            if (!Percolator.isZooming) {
                if (!saveLifer) {
                    BubbleGraph.solutions[this.id].animate("in")
                }
            }
        },
        mouseleave: function () {
            if (!Percolator.isZooming) {
                if (!saveLifer) {
                    BubbleGraph.solutions[this.id].animate("out")
                }
            }
        }
    });
};

Solution.prototype.createVoteFrame = function() {
    var upvoteRatio = this.upvotes / (this.upvotes + this.downvotes)
    var downvoteRatio = this.downvotes / (this.upvotes + this.downvotes)
    var r = 255*downvoteRatio;
    var g = 255*upvoteRatio;
    var b = 0;
    return rgbToHex(r,g,b);
    function rgbToHex(r,g,b) {return "#"+toHex(r)+toHex(g)+toHex(b)}
    function toHex(n) {
       n = parseInt(n,10);
       if (isNaN(n)) return "00";
       n = Math.max(0,Math.min(n,255));
       return "0123456789ABCDEF".charAt((n-n%16)/16)
       + "0123456789ABCDEF".charAt(n%16);
   }
};
<|endoftext|>


<commit_before>/*
Here is where you create all the functions that will do the routing for your app, and the logic of each route.
*/
var express = require('express');
var router = express.Router();
var path = require('path');
var passport = require('passport');

// Controllers
var isLoggedIn = require('./controllers/isLoggedIn');
var signup = require('./controllers/signup');
var login = require('./controllers/login');
var coinInput = require('./controllers/coinInput');

// =====================================
// HOME PAGE (with login links) ========
// =====================================
router.get('/', function(req, res) {
	res.sendFile(path.join(__dirname, './public', 'index.html'));
});

// =====================================
// LOGIN PAGE ==========================
// =====================================
router.get('/login', function(req, res) {
  res.sendFile(path.join(__dirname, './public', 'login.html'));
});

// =====================================
// LOGIN ===============================
// =====================================
// process the login form
router.post('/login', login);

// =====================================
// SIGNUP ==============================
// =====================================
// process the signup form
router.post('/signup', signup);

// =====================================
// SUCCESS =============================
// =====================================
// process the signup form
router.get('/success', isLoggedIn, function(req, res) {
	res.sendFile(path.join(__dirname, 'success.html'))
});

// =====================================
// LOGOUT ==============================
// =====================================
router.get('/logout', function(req, res) {
	req.logout();
	res.redirect('/');
});

// ===============================================
// ===== coin input from Raspberry Pi server =====
// ===============================================
router.post('/coin', coinInput);

module.exports = router;
<commit_msg>Delete router.js<commit_after><|endoftext|>