<commit_before>'use strict';
import { $ } from 'meteor/jquery';
import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { dbSeason } from '../../db/dbSeason';
import { dbResourceLock } from '../../db/dbResourceLock';
import { pageNameHash } from '../../routes';
import { rShowLoginDialog } from './validateDialog';

const rNavLinkListCollapsed = new ReactiveVar(true);
Template.nav.onCreated(function() {
  this.autorun(() => {
    if (dbResourceLock.find('season').count()) {
      return false;
    }
    this.subscribe('currentSeason');
  });
});
Template.nav.helpers({
  getNavLinkListClassList() {
    if (rNavLinkListCollapsed.get()) {
      return 'collapse navbar-collapse';
    }
    else {
      return 'collapse navbar-collapse show';
    }
  },
  seasonParams() {
    const seasonList = dbSeason
      .find({}, {
        sort: {
          beginDate: -1
        },
        limit: 2
      })
      .fetch();
    const previousSeasonData = seasonList[1] || seasonList[0];

    if (previousSeasonData) {
      return {
        seasonId: previousSeasonData._id
      };
    }
    else {
      return {};
    }
  }
});
Template.nav.events({
  'click [data-action="login"]'(event) {
    event.preventDefault();
    rShowLoginDialog.set(true);
  },
  'click .dropdown .dropdown-toggle'(event) {
    event.preventDefault();
    const $dropdownMenu = $(event.currentTarget).siblings('.dropdown-menu');
    const slideUp = () => {
      $dropdownMenu.slideUp('fast', () => {
        $(document).off('click', slideUp);
        $dropdownMenu.removeClass('show');
      });
    };
    $dropdownMenu.slideDown('fast', () => {
      $dropdownMenu.addClass('show');
      $(document).on('click', slideUp);
    });
  },
  'click button'() {
    rNavLinkListCollapsed.set(! rNavLinkListCollapsed.get());
  },
  'click [data-action="logout"]'(event) {
    event.preventDefault();
    Meteor.logout();
  }
});

Template.navLink.helpers({
  getClassList() {
    return 'nav-item' + (FlowRouter.getRouteName() === this.page ? ' active' : '');
  },
  getHref() {
    return FlowRouter.path(this.page, this.params);
  },
  getLinkText() {
    return pageNameHash[this.page];
  }
});
<commit_msg>Update nav.js<commit_after>'use strict';
import { $ } from 'meteor/jquery';
import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { dbSeason } from '../../db/dbSeason';
import { dbResourceLock } from '../../db/dbResourceLock';
import { pageNameHash } from '../../routes';
import { rShowLoginDialog } from './validateDialog';

const rNavLinkListCollapsed = new ReactiveVar(true);
Template.nav.onCreated(function() {
  this.autorun(() => {
    if (dbResourceLock.find('season').count()) {
      return false;
    }
    this.subscribe('currentSeason');
  });
});
Template.nav.helpers({
  getNavLinkListClassList() {
    if (rNavLinkListCollapsed.get()) {
      return 'collapse navbar-collapse';
    }
    else {
      return 'collapse navbar-collapse show';
    }
  },
  seasonParams() {
    const seasonList = dbSeason
      .find({}, {
        sort: {
          beginDate: -1
        },
        limit: 2
      })
      .fetch();
    const previousSeasonData = seasonList[1] || seasonList[0];

    if (previousSeasonData) {
      return {
        seasonId: previousSeasonData._id
      };
    }
    else {
      return {};
    }
  }
});
Template.nav.events({
  'click [data-action="login"]'(event) {
    event.preventDefault();
    rShowLoginDialog.set(true);
  },
  'click .dropdown .dropdown-toggle'(event) {
    event.preventDefault();
    const $dropdownMenu = $(event.currentTarget).siblings('.dropdown-menu');
    const slideUp = () => {
      $dropdownMenu.slideUp('fast', () => {
        $(document).off('click', slideUp);
        $dropdownMenu.removeClass('show');
      });
    };
    $dropdownMenu.slideDown('fast', () => {
      $dropdownMenu.addClass('show');
      $(document).on('click', slideUp);
    });
  },
  'click button'() {
    rNavLinkListCollapsed.set(! rNavLinkListCollapsed.get());
  },
  'click [data-action="switch-theme"]'(event) {
    event.preventDefault();
    $('#boostrap-theme').attr('href', event.target.getAttribute('rel'));
    $('nav').removeClass('navbar-light navbar-inverse').addClass(event.target.getAttribute('nav-class'));
  },
  'click [data-action="logout"]'(event) {
    event.preventDefault();
    Meteor.logout();
  }
});

Template.navLink.helpers({
  getClassList() {
    return 'nav-item' + (FlowRouter.getRouteName() === this.page ? ' active' : '');
  },
  getHref() {
    return FlowRouter.path(this.page, this.params);
  },
  getLinkText() {
    return pageNameHash[this.page];
  }
});
<|endoftext|>


<commit_before>import {
    line,
    curveBasisClosed,
    curveBasisOpen,
    curveBasis,
    curveBundle,
    curveCardinalClosed,
    curveCardinalOpen,
    curveCardinal,
    curveCatmullRomClosed,
    curveCatmullRomOpen,
    curveCatmullRom,
    curveLinearClosed,
    curveLinear,
    curveMonotoneX,
    curveMonotoneY,
    curveNatural
} from 'd3-shape';

import {isFunction} from 'd3-let';
import {extent} from 'd3-array';

import createChart from '../core/chart';
import warn from '../utils/warn';
import camelFunction from '../utils/camelfunction';
import grouper from '../transforms/groups';

export const curves = {
    curveBasisClosed,
    curveBasisOpen,
    curveBasis,
    curveBundle,
    curveCardinalClosed,
    curveCardinalOpen,
    curveCardinal,
    curveCatmullRomClosed,
    curveCatmullRomOpen,
    curveCatmullRom,
    curveLinearClosed,
    curveLinear,
    curveMonotoneX,
    curveMonotoneY,
    curveNatural
};

export const lineDrawing = {

    curve (name) {
        var obj = camelFunction(curves, 'curve', name, true);
        if (!obj) {
            warn(`Could not locate curve type "${name}"`);
            obj = curveNatural;
        }
        return obj;
    },

    range (data, x, y, agg) {
        var range = {
            x: extent(data, x),
            y: extent(data, y)
        };
        if (agg) {
            Array.prototype.push.apply(agg.x, range.x);
            Array.prototype.push.apply(agg.y, range.y);
        }
    },

    newRange () {
        return {
            x: [],
            y: []
        };
    },

    x (box, ranges) {
        var model = this.getModel(),
            scale = this.getScale(model.scaleX)
                .domain(extent(ranges))
                .range([0, box.innerWidth]);
        return function (d) {
            return scale(d[model.x]);
        };
    },

    y (box, ranges, value) {
        var model = this.getModel(),
            scale = this.getScale(model.scaleY)
                .domain(extent(ranges))
                .range([box.innerHeight, 0]);
        if (arguments.length === 2) value = d => d[model.y];
        return function (d) {
            return scale(value(d));
        };
    },

    getStack () {
        var model = this.getModel();
        if (model.stack) {
            var s = d3_shape.stack();
            if (model.stackOrder) s.order(model.stackOrder);
            return s;
        }
    }
};

//
//  Line Chart
//  =============
//
//  The barchart is one of the most flexible visuals.
//  It can be used to display label data as well as
//  timeserie data. It can display absulte values as
//  proportional data via vertical staking and normalization
export default createChart('linechart', lineDrawing, {

    options: {
        lineWidth: 1,
        curve: 'natural',
        x: 'x',
        y: 'y',
        groupby: null,  // group data by a field for grouped line charts
        scaleX: 'linear',
        scaleY: 'linear',
        //
        axisX: true,
        axisY: true
    },

    doDraw (frame) {
        var model = this.getModel(),
            x = model.x,
            y = model.y,
            box = this.boundingBox(),
            info = grouper()
                        .groupby(model.groupby)
                        .x(x)
                        .y(y)(frame),
            domainX = info.rangeX(),
            domainY = info.rangeY(),
            sx = this.getScale(model.scaleX)
                            .domain(domainX)
                            .rangeRound([0, box.innerWidth]),
            sy = this.getScale(model.scaleY)
                            .domain(domainY)
                            .rangeRound([box.innerHeight, 0]).nice(),
            group = this.group(),
            chart = this.group('chart'),
            lines = chart.selectAll('.line').data(info.data),
            colors = this.stroke(info.data).colors,
            sxshift = 0,
            //merge = paper.transition('update'),
            line_ = line()
                .x(xl)
                .y(yl)
                .curve(this.curve(model.curve));

        this.applyTransform(group, this.translate(box.padding.left, box.padding.top));
        this.applyTransform(chart, this.translate(box.margin.left, box.margin.top));

        // TODO: generalize this hack
        if (isFunction(sx.bandwidth)) {
            sx.domain(info.data[0].map(d => d.data[x]));
            sxshift = sx.bandwidth()/2;
        }

        lines
            .enter()
                .append('path')
                .attr('class', 'line')
                .attr('fill', 'none')
                .attr('stroke', stroke)
                .attr('stroke-width', model.lineWidth)
                .attr('d', line_)
            .merge(lines)
                .transition()
                .attr('stroke', stroke)
                .attr('stroke-width', model.lineWidth)
                .attr('d', line_);

        lines
            .exit()
            .transition()
            .style('opacity', 0)
            .remove();

        if (model.axisX)
            this.xAxis1(model.axisX === true ? "bottom" : model.axisX, sy, box);
        if (model.axisY)
            this.yAxis1(model.axisY === true ? "left" : model.axisY, sy, box);

        function stroke (d, i) {
            return colors[i];
        }

        function xl(d) {
            return sx(d.data[x]) + sxshift;
        }

        function yl(d) {
            return sy(d[1]);
        }
    }
});
<commit_msg>regression<commit_after>import {
    line,
    stack,
    curveBasisClosed,
    curveBasisOpen,
    curveBasis,
    curveBundle,
    curveCardinalClosed,
    curveCardinalOpen,
    curveCardinal,
    curveCatmullRomClosed,
    curveCatmullRomOpen,
    curveCatmullRom,
    curveLinearClosed,
    curveLinear,
    curveMonotoneX,
    curveMonotoneY,
    curveNatural
} from 'd3-shape';

import {isFunction} from 'd3-let';
import {extent} from 'd3-array';

import createChart from '../core/chart';
import warn from '../utils/warn';
import camelFunction from '../utils/camelfunction';
import grouper from '../transforms/groups';

export const curves = {
    curveBasisClosed,
    curveBasisOpen,
    curveBasis,
    curveBundle,
    curveCardinalClosed,
    curveCardinalOpen,
    curveCardinal,
    curveCatmullRomClosed,
    curveCatmullRomOpen,
    curveCatmullRom,
    curveLinearClosed,
    curveLinear,
    curveMonotoneX,
    curveMonotoneY,
    curveNatural
};

export const lineDrawing = {

    curve (name) {
        var obj = camelFunction(curves, 'curve', name, true);
        if (!obj) {
            warn(`Could not locate curve type "${name}"`);
            obj = curveNatural;
        }
        return obj;
    },

    range (data, x, y, agg) {
        var range = {
            x: extent(data, x),
            y: extent(data, y)
        };
        if (agg) {
            Array.prototype.push.apply(agg.x, range.x);
            Array.prototype.push.apply(agg.y, range.y);
        }
    },

    newRange () {
        return {
            x: [],
            y: []
        };
    },

    x (box, ranges) {
        var model = this.getModel(),
            scale = this.getScale(model.scaleX)
                .domain(extent(ranges))
                .range([0, box.innerWidth]);
        return function (d) {
            return scale(d[model.x]);
        };
    },

    y (box, ranges, value) {
        var model = this.getModel(),
            scale = this.getScale(model.scaleY)
                .domain(extent(ranges))
                .range([box.innerHeight, 0]);
        if (arguments.length === 2) value = d => d[model.y];
        return function (d) {
            return scale(value(d));
        };
    },

    getStack () {
        var model = this.getModel();
        if (model.stack) {
            var s = stack();
            if (model.stackOrder) s.order(model.stackOrder);
            return s;
        }
    }
};

//
//  Line Chart
//  =============
//
//  The barchart is one of the most flexible visuals.
//  It can be used to display label data as well as
//  timeserie data. It can display absulte values as
//  proportional data via vertical staking and normalization
export default createChart('linechart', lineDrawing, {

    options: {
        lineWidth: 1,
        curve: 'natural',
        x: 'x',
        y: 'y',
        groupby: null,  // group data by a field for grouped line charts
        scaleX: 'linear',
        scaleY: 'linear',
        //
        axisX: true,
        axisY: true
    },

    doDraw (frame) {
        var model = this.getModel(),
            x = model.x,
            y = model.y,
            box = this.boundingBox(),
            info = grouper()
                        .groupby(model.groupby)
                        .x(x)
                        .y(y)(frame),
            domainX = info.rangeX(),
            domainY = info.rangeY(),
            sx = this.getScale(model.scaleX)
                            .domain(domainX)
                            .rangeRound([0, box.innerWidth]),
            sy = this.getScale(model.scaleY)
                            .domain(domainY)
                            .rangeRound([box.innerHeight, 0]).nice(),
            group = this.group(),
            chart = this.group('chart'),
            lines = chart.selectAll('.line').data(info.data),
            colors = this.stroke(info.data).colors,
            sxshift = 0,
            //merge = paper.transition('update'),
            line_ = line()
                .x(xl)
                .y(yl)
                .curve(this.curve(model.curve));

        this.applyTransform(group, this.translate(box.padding.left, box.padding.top));
        this.applyTransform(chart, this.translate(box.margin.left, box.margin.top));

        // TODO: generalize this hack
        if (isFunction(sx.bandwidth)) {
            sx.domain(info.data[0].map(d => d.data[x]));
            sxshift = sx.bandwidth()/2;
        }

        lines
            .enter()
                .append('path')
                .attr('class', 'line')
                .attr('fill', 'none')
                .attr('stroke', stroke)
                .attr('stroke-width', model.lineWidth)
                .attr('d', line_)
            .merge(lines)
                .transition()
                .attr('stroke', stroke)
                .attr('stroke-width', model.lineWidth)
                .attr('d', line_);

        lines
            .exit()
            .transition()
            .style('opacity', 0)
            .remove();

        if (model.axisX)
            this.xAxis1(model.axisX === true ? "bottom" : model.axisX, sy, box);
        if (model.axisY)
            this.yAxis1(model.axisY === true ? "left" : model.axisY, sy, box);

        function stroke (d, i) {
            return colors[i];
        }

        function xl(d) {
            return sx(d.data[x]) + sxshift;
        }

        function yl(d) {
            return sy(d[1]);
        }
    }
});
<|endoftext|>


<commit_before><commit_msg>test scripts<commit_after><|endoftext|>


<commit_before>var Batch = require('batch');
var debounce = require('debounce');
var geocode = require('geocode');
var Journey = require('journey');
var Location = require('location');
var log = require('./client/log')('plan');
var defaults = require('model-defaults');
var model = require('model');
var ProfileQuery = require('profile-query');
var ProfileScorer = require('otp-profile-score');
var qs = require('querystring');

var loadPlan = require('./load');
var store = require('./store');
var updateRoutes = require('./update-routes');

/**
 * Debounce updates to once every 50ms
 */

var DEBOUNCE_UPDATES = 5;
var LIMIT = 2;

/**
 * Expose `Plan`
 */

var Plan = module.exports = model('Plan')
  .use(defaults({
    bike: true,
    bikeShare: false,
    bus: true,
    car: false,
    days: 'M—F',
    end_time: (new Date()).getHours() + 4,
    from: '',
    from_valid: false,
    loading: true,
    options: [],
    query: new ProfileQuery(),
    scorer: new ProfileScorer(),
    start_time: (new Date()).getHours() - 1,
    to: '',
    to_valid: false,
    train: true,
    tripsPerYear: 235,
    walk: true
  }))
  .attr('bike')
  .attr('bikeShare')
  .attr('bus')
  .attr('car')
  .attr('days')
  .attr('end_time')
  .attr('from')
  .attr('from_id')
  .attr('from_ll')
  .attr('from_valid')
  .attr('loading')
  .attr('journey')
  .attr('options')
  .attr('query')
  .attr('scorer')
  .attr('start_time')
  .attr('to')
  .attr('to_id')
  .attr('to_ll')
  .attr('to_valid')
  .attr('train')
  .attr('tripsPerYear')
  .attr('walk');

/**
 * Expose `load`
 */

module.exports.load = function(ctx, next) {
  loadPlan(Plan, ctx, next);
};

/**
 * Sync plans with localStorage
 */

Plan.on('change', function(plan, name, val) {
  log('plan.%s changed to %s', name, val);

  // Store in localStorage & track the change
  if (name !== 'options' && name !== 'journey' && name !== 'loading') plan.store();
});

/**
 * Keep start/end times in sync
 */

Plan.on('change start_time', function(plan, val, prev) {
  if (val >= plan.end_time()) plan.end_time(val + 1);
});

Plan.on('change end_time', function(plan, val, prev) {
  if (val <= plan.start_time()) plan.start_time(val - 1);
});

/**
 * Update routes. Restrict to once every 25ms.
 */

Plan.prototype.updateRoutes = debounce(function(opts, callback) {
  updateRoutes(this, opts, callback);
}, DEBOUNCE_UPDATES);

/**
 * Geocode
 */

Plan.prototype.geocode = function(dest, callback) {
  if (!callback) callback = function() {};

  var plan = this;
  var address = plan[dest]();
  var ll = plan[dest + '_ll']();
  if (address && address.length > 0) {
    geocode(address, function(err, ll) {
      if (err) {
        callback(err);
      } else {
        plan[dest + '_ll'](ll);
        callback(null, ll);
      }
    });
  } else {
    callback(null, ll);
  }
};

/**
 * Save Journey
 */

Plan.prototype.saveJourney = function(callback) {
  var opts = {};
  var skipKeys = ['options', 'journey', 'scorer'];
  for (var key in this.attrs) {
    if (skipKeys.indexOf(key) !== -1 || key.indexOf('to') === 0 || key.indexOf('from') === 0) {
      continue;
    }
    opts[key] = this.attrs[key];
  }

  // Create new journey
  var journey = new Journey({
    locations: [{
      _id: this.from_id()
    }, {
      _id: this.to_id()
    }],
    opts: opts
  });

  // Save
  journey.save(callback);
};

/**
 * Valid coordinates
 */

Plan.prototype.validCoordinates = function() {
  return this.coordinateIsValid(this.from_ll()) && this.coordinateIsValid(this.to_ll());
};

/**
 * Set Address
 */

Plan.prototype.setAddress = function(name, address, callback, extra) {

  console.log("name", name);
  console.log("address", address);
  console.log("callback", callback);
  console.log("extra", extra);

  callback = callback || function() {}; // noop callback
  var location = new Location();
  var plan = this;
  var c = address.split(',');
  var isCoordinate = c.length === 2 && !isNaN(parseFloat(c[0])) && !isNaN(parseFloat(c[1]));

  if (!address || address.length < 1) return callback();

  if (isCoordinate) {
    location.coordinate({
      lat: parseFloat(c[1]),
      lng: parseFloat(c[0])
    });
  } else {
    location.address(address);
  }
  console.log("location.coordenadas",  location.coordinate({lat: parseFloat(c[1]),lng: parseFloat(c[0]) }));
  console.log("location.address", location.address(address));

  location.save(function(err, res) {

    if (err) {
	if (isCoordinate) {
	    var changes = {};
	    changes[name] = extra.label;
	    changes[name + '_ll'] = location.coordinate();
	    changes[name + '_valid'] = true;

	    plan.set(changes);
	    callback(null, extra);
	} else {
	    callback(err);
	}
    } else {
      var changes = {};
      if (isCoordinate)
        changes[name] = res.body.address + ', ' + res.body.city + ', ' + res.body.state;
      else
        changes[name] = address;

      changes[name + '_ll'] = res.body.coordinate;
      changes[name + '_id'] = res.body._id;
      changes[name + '_valid'] = true;

      console.log("CHANGES PLAN SET", changes);
      plan.set(changes);
      callback(null, res.body);
    }
  });
};

/**
 * Set both addresses
 */

Plan.prototype.setAddresses = function(from, to, callback) {
  // Initialize the default locations
  var plan = this;

  Batch()
    .push(function(done) {
      plan.setAddress('from', from, done);
    })
    .push(function(done) {
      plan.setAddress('to', to, done);
    }).end(callback);
};

/**
 * Rescore Options
 */

Plan.prototype.rescoreOptions = function() {
  var scorer = this.scorer();
  var options = this.options();

  options.forEach(function(o) {
    o.rescore(scorer);
  });

  this.store();
};

/**
 * To Lower Case
 */

function toLowerCase(s) {
  return s ? s.toLowerCase() : '';
}

Plan.prototype.coordinateIsValid = function(c) {
  return !!c && !!parseFloat(c.lat) && !!parseFloat(c.lng) && parseFloat(c.lat) !== 0.0 && parseFloat(c.lng) !== 0.0;
};

/**
 * Modes as a CSV
 */

Plan.prototype.modesCSV = function() {
  var modes = [];
  if (this.bike()) modes.push('BICYCLE');
  if (this.bikeShare()) modes.push('BICYCLE_RENT');
  if (this.bus()) modes.push('BUSISH');
  if (this.train()) modes.push('TRAINISH');
  if (this.walk()) modes.push('WALK');
  if (this.car()) modes.push('CAR');

  return modes.join(',');
};

/**
 * Set modes from string
 */

Plan.prototype.setModes = function(csv) {
  if (!csv || csv.length < 1) return;
  var modes = csv.split ? csv.split(',') : csv;

  this.bike(modes.indexOf('BICYCLE') !== -1);
//  this.bikeShare(modes.indexOf('BICYCLE_RENT') !== -1);
  this.bikeShare(false);
  this.bus(true);
//  this.bus(modes.indexOf('BUSISH') !== -1);
  this.train(modes.indexOf('TRAINISH') !== -1);
  this.car(modes.indexOf('CAR') !== -1);
};

/**
 * Generate Query Parameters for this plan
 */

Plan.prototype.generateQuery = function() {
  var from = this.from_ll() || {};
  var to = this.to_ll() || {};

  // Transit modes
  var modes = [];//['WALK'];

  if (this.bikeShare()) modes.push('BICYCLE_RENT');

  if (this.car()) {
    modes.push('CAR');
  }
  if (this.bike()) {
    modes.push('BICYCLE');
  } else {
    modes.push('WALK');
  }
  if (this.bus()) modes.push('BUSISH');
  if (this.train()) modes.push('TRAINISH');
  if (modes.length==0) modes.push('WALK');

  var startTime = this.start_time();
  var endTime = this.end_time();
  var scorer = this.scorer();

  // Convert the hours into strings
  startTime += ':00';
  endTime = endTime === 24 ? '23:59' : endTime + ':00';

  return {
    date: this.nextDate(),
    mode: modes.join(','),
      time: startTime,
      fromPlace: (from.lat + ',' + from.lng),
      toPlace: (to.lat + ',' + to.lng),
      numItineraries: 3,
      maxWalkDistance: 20000,
      bikeSpeed: 10,
      bikeBoardCost: 15,
      walkReluctance: 10,
      clampInitialWait: 60,
//      waitAtBeginningFactor: 0.5,
      triangleSafetyFactor: 0.9,
      triangleSlopeFactor: 0.5,
      triangleTimeFactor: 0.9,
      optimize: 'QUICK'
  };
};

/**
 * Store in localStorage. Restrict this I/O to once every 25ms.
 */

Plan.prototype.store = debounce(function() {
  store(this);
}, DEBOUNCE_UPDATES);

/**
 * Clear localStorage
 */

Plan.prototype.clearStore = store.clear;

/**
 * Save URL
 */

Plan.prototype.saveURL = function() {
  window.history.replaceState(null, '', '/planner?' + this.generateQueryString());
};

/**
 * Get next date for day of the week
 */

Plan.prototype.nextDate = function() {
  var now = new Date();
  var date = now.getDate();
  var dayOfTheWeek = now.getDay();
  switch (this.days()) {
    case 'M—F':
      if (dayOfTheWeek === 0) now.setDate(date + 1);
      if (dayOfTheWeek === 6) now.setDate(date + 2);
      break;
    case 'Sat':
      now.setDate(date + (6 - dayOfTheWeek));
      break;
    case 'Sun':
      now.setDate(date + (7 - dayOfTheWeek));
      break;
  }
  return now.toISOString().split('T')[0];
};

/**
 * Generate `places` for transitive
 */

Plan.prototype.generatePlaces = function() {
  var fll = this.from_ll();
  var tll = this.to_ll();
  if (!fll || !tll) return [];

  return [{
    place_id: 'from',
    place_lat: fll.lat,
    place_lon: fll.lng,
    place_name: 'From'
  }, {
    place_id: 'to',
    place_lat: tll.lat,
    place_lon: tll.lng,
    place_name: 'To'
  }];
};

/**
 * Generate QueryString
 */

Plan.prototype.generateQueryString = function() {
  return qs.stringify({
    from: this.from(),
    to: this.to(),
    modes: this.modesCSV(),
    start_time: this.start_time(),
    end_time: this.end_time(),
    days: this.days()
  });
};
<commit_msg>adding console property<commit_after>var Batch = require('batch');
var debounce = require('debounce');
var geocode = require('geocode');
var Journey = require('journey');
var Location = require('location');
var log = require('./client/log')('plan');
var defaults = require('model-defaults');
var model = require('model');
var ProfileQuery = require('profile-query');
var ProfileScorer = require('otp-profile-score');
var qs = require('querystring');

var loadPlan = require('./load');
var store = require('./store');
var updateRoutes = require('./update-routes');

/**
 * Debounce updates to once every 50ms
 */

var DEBOUNCE_UPDATES = 5;
var LIMIT = 2;

/**
 * Expose `Plan`
 */

var Plan = module.exports = model('Plan')
  .use(defaults({
    bike: true,
    bikeShare: false,
    bus: true,
    car: false,
    days: 'M—F',
    end_time: (new Date()).getHours() + 4,
    from: '',
    from_valid: false,
    loading: true,
    options: [],
    query: new ProfileQuery(),
    scorer: new ProfileScorer(),
    start_time: (new Date()).getHours() - 1,
    to: '',
    to_valid: false,
    train: true,
    tripsPerYear: 235,
    walk: true
  }))
  .attr('bike')
  .attr('bikeShare')
  .attr('bus')
  .attr('car')
  .attr('days')
  .attr('end_time')
  .attr('from')
  .attr('from_id')
  .attr('from_ll')
  .attr('from_valid')
  .attr('loading')
  .attr('journey')
  .attr('options')
  .attr('query')
  .attr('scorer')
  .attr('start_time')
  .attr('to')
  .attr('to_id')
  .attr('to_ll')
  .attr('to_valid')
  .attr('train')
  .attr('tripsPerYear')
  .attr('walk');

/**
 * Expose `load`
 */

module.exports.load = function(ctx, next) {
  loadPlan(Plan, ctx, next);
};

/**
 * Sync plans with localStorage
 */

Plan.on('change', function(plan, name, val) {
  log('plan.%s changed to %s', name, val);

  // Store in localStorage & track the change
  if (name !== 'options' && name !== 'journey' && name !== 'loading') plan.store();
});

/**
 * Keep start/end times in sync
 */

Plan.on('change start_time', function(plan, val, prev) {
  if (val >= plan.end_time()) plan.end_time(val + 1);
});

Plan.on('change end_time', function(plan, val, prev) {
  if (val <= plan.start_time()) plan.start_time(val - 1);
});

/**
 * Update routes. Restrict to once every 25ms.
 */

Plan.prototype.updateRoutes = debounce(function(opts, callback) {
  updateRoutes(this, opts, callback);
}, DEBOUNCE_UPDATES);

/**
 * Geocode
 */

Plan.prototype.geocode = function(dest, callback) {
  if (!callback) callback = function() {};

  var plan = this;
  var address = plan[dest]();
  var ll = plan[dest + '_ll']();
  if (address && address.length > 0) {
    geocode(address, function(err, ll) {
      if (err) {
        callback(err);
      } else {
        plan[dest + '_ll'](ll);
        callback(null, ll);
      }
    });
  } else {
    callback(null, ll);
  }
};

/**
 * Save Journey
 */

Plan.prototype.saveJourney = function(callback) {
  var opts = {};
  var skipKeys = ['options', 'journey', 'scorer'];
  for (var key in this.attrs) {
    if (skipKeys.indexOf(key) !== -1 || key.indexOf('to') === 0 || key.indexOf('from') === 0) {
      continue;
    }
    opts[key] = this.attrs[key];
  }

  // Create new journey
  var journey = new Journey({
    locations: [{
      _id: this.from_id()
    }, {
      _id: this.to_id()
    }],
    opts: opts
  });

  // Save
  journey.save(callback);
};

/**
 * Valid coordinates
 */

Plan.prototype.validCoordinates = function() {
  return this.coordinateIsValid(this.from_ll()) && this.coordinateIsValid(this.to_ll());
};

/**
 * Set Address
 */

Plan.prototype.setAddress = function(name, address, callback, extra) {

  console.log("name", name);
  console.log("address", address);
  console.log("callback", callback);
  console.log("extra", extra);

  callback = callback || function() {}; // noop callback
  var location = new Location();
  var plan = this;
  var c = address.split(',');
  var isCoordinate = c.length === 2 && !isNaN(parseFloat(c[0])) && !isNaN(parseFloat(c[1]));

  if (!address || address.length < 1) return callback();

  if (isCoordinate) {
    location.coordinate({
      lat: parseFloat(c[1]),
      lng: parseFloat(c[0])
    });
  } else {
    location.address(address);
  }
  console.log("location.coordenadas",  location.coordinate({lat: parseFloat(c[1]),lng: parseFloat(c[0]) }));
  console.log("location.address", location.address(address));

  location.save(function(err, res) {

    if (err) {
	if (isCoordinate) {
        console.log("properties", extra.properties);
	    var changes = {};
	    changes[name] = extra.properties.label;
	    changes[name + '_ll'] = location.coordinate();
	    changes[name + '_valid'] = true;

	    plan.set(changes);
	    callback(null, extra);
	} else {
	    callback(err);
	}
    } else {
      var changes = {};
      if (isCoordinate)
        changes[name] = res.body.address + ', ' + res.body.city + ', ' + res.body.state;
      else
        changes[name] = address;

      changes[name + '_ll'] = res.body.coordinate;
      changes[name + '_id'] = res.body._id;
      changes[name + '_valid'] = true;

      console.log("CHANGES PLAN SET", changes);
      plan.set(changes);
      callback(null, res.body);
    }
  });
};

/**
 * Set both addresses
 */

Plan.prototype.setAddresses = function(from, to, callback) {
  // Initialize the default locations
  var plan = this;

  Batch()
    .push(function(done) {
      plan.setAddress('from', from, done);
    })
    .push(function(done) {
      plan.setAddress('to', to, done);
    }).end(callback);
};

/**
 * Rescore Options
 */

Plan.prototype.rescoreOptions = function() {
  var scorer = this.scorer();
  var options = this.options();

  options.forEach(function(o) {
    o.rescore(scorer);
  });

  this.store();
};

/**
 * To Lower Case
 */

function toLowerCase(s) {
  return s ? s.toLowerCase() : '';
}

Plan.prototype.coordinateIsValid = function(c) {
  return !!c && !!parseFloat(c.lat) && !!parseFloat(c.lng) && parseFloat(c.lat) !== 0.0 && parseFloat(c.lng) !== 0.0;
};

/**
 * Modes as a CSV
 */

Plan.prototype.modesCSV = function() {
  var modes = [];
  if (this.bike()) modes.push('BICYCLE');
  if (this.bikeShare()) modes.push('BICYCLE_RENT');
  if (this.bus()) modes.push('BUSISH');
  if (this.train()) modes.push('TRAINISH');
  if (this.walk()) modes.push('WALK');
  if (this.car()) modes.push('CAR');

  return modes.join(',');
};

/**
 * Set modes from string
 */

Plan.prototype.setModes = function(csv) {
  if (!csv || csv.length < 1) return;
  var modes = csv.split ? csv.split(',') : csv;

  this.bike(modes.indexOf('BICYCLE') !== -1);
//  this.bikeShare(modes.indexOf('BICYCLE_RENT') !== -1);
  this.bikeShare(false);
  this.bus(true);
//  this.bus(modes.indexOf('BUSISH') !== -1);
  this.train(modes.indexOf('TRAINISH') !== -1);
  this.car(modes.indexOf('CAR') !== -1);
};

/**
 * Generate Query Parameters for this plan
 */

Plan.prototype.generateQuery = function() {
  var from = this.from_ll() || {};
  var to = this.to_ll() || {};

  // Transit modes
  var modes = [];//['WALK'];

  if (this.bikeShare()) modes.push('BICYCLE_RENT');

  if (this.car()) {
    modes.push('CAR');
  }
  if (this.bike()) {
    modes.push('BICYCLE');
  } else {
    modes.push('WALK');
  }
  if (this.bus()) modes.push('BUSISH');
  if (this.train()) modes.push('TRAINISH');
  if (modes.length==0) modes.push('WALK');

  var startTime = this.start_time();
  var endTime = this.end_time();
  var scorer = this.scorer();

  // Convert the hours into strings
  startTime += ':00';
  endTime = endTime === 24 ? '23:59' : endTime + ':00';

  return {
    date: this.nextDate(),
    mode: modes.join(','),
      time: startTime,
      fromPlace: (from.lat + ',' + from.lng),
      toPlace: (to.lat + ',' + to.lng),
      numItineraries: 3,
      maxWalkDistance: 20000,
      bikeSpeed: 10,
      bikeBoardCost: 15,
      walkReluctance: 10,
      clampInitialWait: 60,
//      waitAtBeginningFactor: 0.5,
      triangleSafetyFactor: 0.9,
      triangleSlopeFactor: 0.5,
      triangleTimeFactor: 0.9,
      optimize: 'QUICK'
  };
};

/**
 * Store in localStorage. Restrict this I/O to once every 25ms.
 */

Plan.prototype.store = debounce(function() {
  store(this);
}, DEBOUNCE_UPDATES);

/**
 * Clear localStorage
 */

Plan.prototype.clearStore = store.clear;

/**
 * Save URL
 */

Plan.prototype.saveURL = function() {
  window.history.replaceState(null, '', '/planner?' + this.generateQueryString());
};

/**
 * Get next date for day of the week
 */

Plan.prototype.nextDate = function() {
  var now = new Date();
  var date = now.getDate();
  var dayOfTheWeek = now.getDay();
  switch (this.days()) {
    case 'M—F':
      if (dayOfTheWeek === 0) now.setDate(date + 1);
      if (dayOfTheWeek === 6) now.setDate(date + 2);
      break;
    case 'Sat':
      now.setDate(date + (6 - dayOfTheWeek));
      break;
    case 'Sun':
      now.setDate(date + (7 - dayOfTheWeek));
      break;
  }
  return now.toISOString().split('T')[0];
};

/**
 * Generate `places` for transitive
 */

Plan.prototype.generatePlaces = function() {
  var fll = this.from_ll();
  var tll = this.to_ll();
  if (!fll || !tll) return [];

  return [{
    place_id: 'from',
    place_lat: fll.lat,
    place_lon: fll.lng,
    place_name: 'From'
  }, {
    place_id: 'to',
    place_lat: tll.lat,
    place_lon: tll.lng,
    place_name: 'To'
  }];
};

/**
 * Generate QueryString
 */

Plan.prototype.generateQueryString = function() {
  return qs.stringify({
    from: this.from(),
    to: this.to(),
    modes: this.modesCSV(),
    start_time: this.start_time(),
    end_time: this.end_time(),
    days: this.days()
  });
};
<|endoftext|>


<commit_before>var localStorageSupported = require('localstorage-supported')();
var log = require('./client/log')('plan:store');
var session = require('session');
var store = require('store');

/**
 * Expose `storePlan`
 */

module.exports = storePlan;

/**
 * Store a plan
 */

function storePlan(plan) {
  log('--> storing plan');
  if (!localStorageSupported) return;

  // convert to "JSON", remove routes & patterns
  var json = {};
  for (var key in plan.attrs) {
    if (key === 'journey' || key === 'options' || key === 'scorer') continue;
    json[key] = plan.attrs[key];
  }

  // if we've created a commuter object, save to the commuter
  var commuter = session.commuter();
  if (commuter) {
    json._commuter = commuter._id();
    commuter.opts(json);
    //commuter.save();
  }

  // save in local storage
  try {
    store('plan', json);
    log('<-- stored plan');
  } catch (e) {
    log.error('<-- failed to store plan %e', e);
  }

  return json;
}

/**
 * Clear storage
 */

module.exports.clear = function() {
  if (localStorageSupported)
    store('plan', null);
};
<commit_msg>Disables local storage<commit_after>var localStorageSupported = require('localstorage-supported')();
var log = require('./client/log')('plan:store');
var session = require('session');
var store = require('store');

/**
 * Expose `storePlan`
 */

module.exports = storePlan;

/**
 * Store a plan
 */

function storePlan(plan) {
  log('--> storing plan');
  // FIXME: temporary solution, disabling localstorage!
  return;
  if (!localStorageSupported) return;

  // convert to "JSON", remove routes & patterns
  var json = {};
  for (var key in plan.attrs) {
    if (key === 'journey' || key === 'options' || key === 'scorer') continue;
    json[key] = plan.attrs[key];
  }

  // if we've created a commuter object, save to the commuter
  var commuter = session.commuter();
  if (commuter) {
    json._commuter = commuter._id();
    commuter.opts(json);
    //commuter.save();
  }

  // save in local storage
  try {
    store('plan', json);
    log('<-- stored plan');
  } catch (e) {
    log.error('<-- failed to store plan %e', e);
  }

  return json;
}

/**
 * Clear storage
 */

module.exports.clear = function() {
  if (localStorageSupported)
    store('plan', null);
};
<|endoftext|>


<commit_before><commit_msg>switch to es6 syntax<commit_after><|endoftext|>


<commit_before>/*!
 * ${copyright}
 */

// Provides control sap.m.ObjectStatus.
sap.ui.define(['jquery.sap.global', './library', 'sap/ui/core/Control', 'sap/ui/core/IconPool'],
	function(jQuery, library, Control, IconPool) {
	"use strict";

	/**
	 * Constructor for a new ObjectStatus.
	 *
	 * @param {string} [sId] id for the new control, generated automatically if no id is given
	 * @param {object} [mSettings] initial settings for the new control
	 *
	 * @class
	 * Status information that may be either text with a value state, or an icon.
	 * @extends sap.ui.core.Control
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @alias sap.m.ObjectStatus
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var ObjectStatus = Control.extend("sap.m.ObjectStatus", /** @lends sap.m.ObjectStatus.prototype */ { metadata : {

		library : "sap.m",
		properties : {

			/**
			 * The object status title.
			 */
			title : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * The object status text.
			 */
			text : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Text value state.
			 */
			state : {type : "sap.ui.core.ValueState", group : "Misc", defaultValue : sap.ui.core.ValueState.None},

			/**
			 * Icon URI. This may be either an icon font or image path.
			 */
			icon : {type : "sap.ui.core.URI", group : "Misc", defaultValue : null},

			/**
			 * By default, this is set to true but then one or more requests are sent trying to get the density perfect version of image if this version of image doesn't exist on the server.
			 *
			 * If bandwidth is the key for the application, set this value to false.
			 */
			iconDensityAware : {type : "boolean", group : "Appearance", defaultValue : true},

			/**
			 * Determines the direction of the text, not including the title.
			 * Available options for the text direction are LTR (left-to-right) and RTL (right-to-left). By default the control inherits the text direction from its parent control.
			 */
			textDirection : {type : "sap.ui.core.TextDirection", group : "Appearance", defaultValue : sap.ui.core.TextDirection.Inherit}
		},
		associations : {

			/**
			 * Association to controls / ids which describe this control (see WAI-ARIA attribute aria-describedby).
			 */
			ariaDescribedBy : {type : "sap.ui.core.Control", multiple : true, singularName : "ariaDescribedBy"}
		}
	}});

	///**
	// * This file defines behavior for the control
	// */

	/**
	 * Called when the control is destroyed.
	 *
	 * @private
	 */
	ObjectStatus.prototype.exit = function() {
		if (this._oImageControl) {
			this._oImageControl.destroy();
			this._oImageControl = null;
		}
	};

	/**
	 * Lazy load feed icon image.
	 *
	 * @private
	 */
	ObjectStatus.prototype._getImageControl = function() {
		var sImgId = this.getId() + '-icon';
		var mProperties = {
			src : this.getIcon(),
			densityAware : this.getIconDensityAware()
		};

		this._oImageControl = sap.m.ImageHelper.getImageControl(sImgId, this._oImageControl, this, mProperties);

		return this._oImageControl;
	};

	/**
	 * Setter for property title.
	 * Default value is empty/undefined
	 * @public
	 * @param {string} sTitle new value for property title
	 * @returns {sap.m.ObjectStatus} this to allow method chaining
	 */
	ObjectStatus.prototype.setTitle = function (sTitle) {
		var $Title = this.$().children(".sapMObjStatusTitle"),
			bShouldSuppressInvalidate = !!$Title.length && !!this.validateProperty("title", sTitle).trim();

		this.setProperty("title", sTitle, bShouldSuppressInvalidate);

		if (bShouldSuppressInvalidate) {
			$Title.text(this.getTitle() + ":");
		}

		return this;
	};

	/**
	 * Setter for property text.
	 * Default value is empty/undefined
	 * @public
	 * @param {string} sText new value for property text
	 * @returns {sap.m.ObjectStatus} this to allow method chaining
	 */
	ObjectStatus.prototype.setText = function (sText) {
		var $Text = this.$().children(".sapMObjStatusText"),
			bShouldSuppressInvalidate = !!$Text.length && !!this.validateProperty("text", sText).trim();

		this.setProperty("text", sText, bShouldSuppressInvalidate);

		if (bShouldSuppressInvalidate) {
			$Text.text(this.getText());
		}

		return this;
	};

	/**
	 * @private
	 * @returns {boolean}
	 */
	ObjectStatus.prototype._isEmpty = function() {

		return !(this.getText().trim() || this.getIcon().trim() || this.getTitle().trim());
	};

	return ObjectStatus;

}, /* bExport= */ true);
<commit_msg>[FIX] sap.m.ObjectStatus: prevent default icon tooltip<commit_after>/*!
 * ${copyright}
 */

// Provides control sap.m.ObjectStatus.
sap.ui.define(['jquery.sap.global', './library', 'sap/ui/core/Control', 'sap/ui/core/IconPool'],
	function(jQuery, library, Control, IconPool) {
	"use strict";

	/**
	 * Constructor for a new ObjectStatus.
	 *
	 * @param {string} [sId] id for the new control, generated automatically if no id is given
	 * @param {object} [mSettings] initial settings for the new control
	 *
	 * @class
	 * Status information that may be either text with a value state, or an icon.
	 * @extends sap.ui.core.Control
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @alias sap.m.ObjectStatus
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var ObjectStatus = Control.extend("sap.m.ObjectStatus", /** @lends sap.m.ObjectStatus.prototype */ { metadata : {

		library : "sap.m",
		properties : {

			/**
			 * The object status title.
			 */
			title : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * The object status text.
			 */
			text : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Text value state.
			 */
			state : {type : "sap.ui.core.ValueState", group : "Misc", defaultValue : sap.ui.core.ValueState.None},

			/**
			 * Icon URI. This may be either an icon font or image path.
			 */
			icon : {type : "sap.ui.core.URI", group : "Misc", defaultValue : null},

			/**
			 * By default, this is set to true but then one or more requests are sent trying to get the density perfect version of image if this version of image doesn't exist on the server.
			 *
			 * If bandwidth is the key for the application, set this value to false.
			 */
			iconDensityAware : {type : "boolean", group : "Appearance", defaultValue : true},

			/**
			 * Determines the direction of the text, not including the title.
			 * Available options for the text direction are LTR (left-to-right) and RTL (right-to-left). By default the control inherits the text direction from its parent control.
			 */
			textDirection : {type : "sap.ui.core.TextDirection", group : "Appearance", defaultValue : sap.ui.core.TextDirection.Inherit}
		},
		associations : {

			/**
			 * Association to controls / ids which describe this control (see WAI-ARIA attribute aria-describedby).
			 */
			ariaDescribedBy : {type : "sap.ui.core.Control", multiple : true, singularName : "ariaDescribedBy"}
		}
	}});

	///**
	// * This file defines behavior for the control
	// */

	/**
	 * Called when the control is destroyed.
	 *
	 * @private
	 */
	ObjectStatus.prototype.exit = function() {
		if (this._oImageControl) {
			this._oImageControl.destroy();
			this._oImageControl = null;
		}
	};

	/**
	 * Lazy load feed icon image.
	 *
	 * @private
	 */
	ObjectStatus.prototype._getImageControl = function() {
		var sImgId = this.getId() + '-icon';
		var mProperties = {
			src : this.getIcon(),
			densityAware : this.getIconDensityAware(),
			useIconTooltip : false
		};

		this._oImageControl = sap.m.ImageHelper.getImageControl(sImgId, this._oImageControl, this, mProperties);

		return this._oImageControl;
	};

	/**
	 * Setter for property title.
	 * Default value is empty/undefined
	 * @public
	 * @param {string} sTitle new value for property title
	 * @returns {sap.m.ObjectStatus} this to allow method chaining
	 */
	ObjectStatus.prototype.setTitle = function (sTitle) {
		var $Title = this.$().children(".sapMObjStatusTitle"),
			bShouldSuppressInvalidate = !!$Title.length && !!this.validateProperty("title", sTitle).trim();

		this.setProperty("title", sTitle, bShouldSuppressInvalidate);

		if (bShouldSuppressInvalidate) {
			$Title.text(this.getTitle() + ":");
		}

		return this;
	};

	/**
	 * Setter for property text.
	 * Default value is empty/undefined
	 * @public
	 * @param {string} sText new value for property text
	 * @returns {sap.m.ObjectStatus} this to allow method chaining
	 */
	ObjectStatus.prototype.setText = function (sText) {
		var $Text = this.$().children(".sapMObjStatusText"),
			bShouldSuppressInvalidate = !!$Text.length && !!this.validateProperty("text", sText).trim();

		this.setProperty("text", sText, bShouldSuppressInvalidate);

		if (bShouldSuppressInvalidate) {
			$Text.text(this.getText());
		}

		return this;
	};

	/**
	 * @private
	 * @returns {boolean}
	 */
	ObjectStatus.prototype._isEmpty = function() {

		return !(this.getText().trim() || this.getIcon().trim() || this.getTitle().trim());
	};

	return ObjectStatus;

}, /* bExport= */ true);
<|endoftext|>


<commit_before>// Importing Angular
import angular from "angular";
import "./services.js";
import "./config.js";
import "./country.services.js";
import "./filters.js";
import "./controllers/index.js";
import "./directives/index.js";
// Style and JS deps
import "./external_dependencies";
import "./style";

/*
 * Declare app level module which depends on filters, and services
 */
angular
  .module("ricardo", [
    "ngRoute",
    "ngAnimate",
    "ngSanitize",
    "ui.bootstrap",
    "ui.grid",
    "ui.grid.pagination",
    "ui.select",
    "angular-loading-bar",
    "pascalprecht.translate",
    "angulartics",
    "angulartics.google.analytics",
    "ricardo.config",
    "ricardo.filters",
    "ricardo.controllers",
    "ricardo.services",
    "ricardo.services.country",
    "ricardo.directives",
  ])
  .run(function ($rootScope, $location, $anchorScroll, $timeout, cfpLoadingBar) {
    $rootScope.$on("$routeChangeStart", function () {
      cfpLoadingBar.start();
      // $rootScope.routeLoading=true;
    });
    $rootScope.$on("$routeChangeSuccess", function (event, toState, toParams, fromState, fromParams) {
      cfpLoadingBar.complete();
      // $rootScope.routeLoading=false;
      $timeout(function () {
        if ($location.hash()) {
          $anchorScroll();
        }
      });
    });
  })
  .config([
    "$routeProvider",
    "$locationProvider",
    "DEFAULT_REPORTING",
    "DEFAULT_PARTNER",
    "DEFAULT_CONTINENT",
    function ($routeProvider, $locationProvider, DEFAULT_REPORTING, DEFAULT_PARTNER, DEFAULT_CONTINENT) {
      $routeProvider.when("/", {
        templateUrl: "partials/home.html",
        controller: "home",
        resolve: {
          blogRSS: function (apiService) {
            return apiService.getBlogRSS();
          },
        },
      });
      $routeProvider.when("/bilateral", {
        templateUrl: "partials/bilateral.html",
        controller: "bilateral",
        resolve: {
          reportingEntities: function (apiService) {
            return apiService.getBilateralEntities();
          },
        },
      });
      $routeProvider.when("/country/:country", {
        templateUrl: "partials/country.html",
        controller: "country",
        resolve: {
          reportingEntities: function (apiService) {
            return apiService.getReportingEntities({
              type_filter: "country,group,city",
            });
          },
        },
      });
      $routeProvider.when("/country", {
        redirectTo: function () {
          let country = DEFAULT_REPORTING;
          if (localStorage.getItem("sourceEntitySelected")) {
            country = JSON.parse(localStorage.getItem("sourceEntitySelected")).RICid;
          }
          return `/country/${country}`;
        },
      });
      $routeProvider.when("/world", {
        templateUrl: "partials/world.html",
        controller: "world",
        resolve: {
          // reportingEntities : function (apiService) {
          //   return apiService.getReportingEntities({'partners_ids': 'Worldbestguess'})
          // },
          reportingWorldFlows: function (apiService) {
            return apiService.getWorldFlows();
            // return apiService.getWorldAvailable()
          },
          reportingWorldPartner: function (apiService) {
            return apiService.getWorldAvailable();
          },
        },
      });
      $routeProvider.when("/network", {
        templateUrl: "partials/network.html",
        controller: "network",
        resolve: {
          reportingYears: function (apiService) {
            return apiService.getReportingYears();
          },
        },
      });
      $routeProvider.when("/metadata", {
        templateUrl: "partials/matrix.html",
        controller: "matrix",
        // resolve:{
        //   reportingByYear: function(apiService){
        //     return apiService.getReportingsAvailableByYear()
        //   },
        //   flowsByYear: function(apiService){
        //     return apiService.getNumberFlows()
        //   }
        // }
      });
      $routeProvider.when("/glossary", {
        templateUrl: "partials/glossary.html",
      });
      $routeProvider.when("/corpus", {
        templateUrl: "partials/corpus.html",
      });
      $routeProvider.when("/about", {
        templateUrl: "partials/about.html",
      });
      $routeProvider.when("/legalNotice", {
        templateUrl: "partials/legalNotice.html",
      });
      $routeProvider.otherwise({ redirectTo: "/" });
    },
  ])
  .config([
    "cfpLoadingBarProvider",
    function (cfpLoadingBarProvider) {
      cfpLoadingBarProvider.includeSpinner = true;
      cfpLoadingBarProvider.includeBar = false;
    },
  ])
  .config(function ($translateProvider) {
    $translateProvider.useStaticFilesLoader({
      prefix: "i18n/locale-",
      suffix: ".json",
    });
    var language = navigator.languages ? navigator.languages[0] : navigator.language || navigator.userLanguage;

    if (language.indexOf("fr") > -1) language = "fr-FR";
    else language = "en-EN";
    $translateProvider.use(language);
  });
<commit_msg>[client]: Remove dead code<commit_after>// Importing Angular
import angular from "angular";
import "./services.js";
import "./config.js";
import "./country.services.js";
import "./filters.js";
import "./controllers/index.js";
import "./directives/index.js";
// Style and JS deps
import "./external_dependencies";
import "./style";

/*
 * Declare app level module which depends on filters, and services
 */
angular
  .module("ricardo", [
    "ngRoute",
    "ngAnimate",
    "ngSanitize",
    "ui.bootstrap",
    "ui.grid",
    "ui.grid.pagination",
    "ui.select",
    "angular-loading-bar",
    "pascalprecht.translate",
    "angulartics",
    "angulartics.google.analytics",
    "ricardo.config",
    "ricardo.filters",
    "ricardo.controllers",
    "ricardo.services",
    "ricardo.services.country",
    "ricardo.directives",
  ])
  .run(function ($rootScope, $location, $anchorScroll, $timeout, cfpLoadingBar) {
    $rootScope.$on("$routeChangeStart", function () {
      cfpLoadingBar.start();
      // $rootScope.routeLoading=true;
    });
    $rootScope.$on("$routeChangeSuccess", function (event, toState, toParams, fromState, fromParams) {
      cfpLoadingBar.complete();
      // $rootScope.routeLoading=false;
      $timeout(function () {
        if ($location.hash()) {
          $anchorScroll();
        }
      });
    });
  })
  .config([
    "$routeProvider",
    "$locationProvider",
    "DEFAULT_REPORTING",
    "DEFAULT_PARTNER",
    "DEFAULT_CONTINENT",
    function ($routeProvider, $locationProvider, DEFAULT_REPORTING, DEFAULT_PARTNER, DEFAULT_CONTINENT) {
      $routeProvider.when("/", {
        templateUrl: "partials/home.html",
        controller: "home",
        resolve: {
          blogRSS: function (apiService) {
            return apiService.getBlogRSS();
          },
        },
      });
      $routeProvider.when("/bilateral", {
        templateUrl: "partials/bilateral.html",
        controller: "bilateral",
        resolve: {
          reportingEntities: function (apiService) {
            return apiService.getBilateralEntities();
          },
        },
      });
      $routeProvider.when("/country/:country", {
        templateUrl: "partials/country.html",
        controller: "country",
        resolve: {
          reportingEntities: function (apiService) {
            return apiService.getReportingEntities({
              type_filter: "country,group,city",
            });
          },
        },
      });
      $routeProvider.when("/country", {
        redirectTo: function () {
          let country = DEFAULT_REPORTING;
          if (localStorage.getItem("sourceEntitySelected")) {
            country = JSON.parse(localStorage.getItem("sourceEntitySelected")).RICid;
          }
          return `/country/${country}`;
        },
      });
      $routeProvider.when("/world", {
        templateUrl: "partials/world.html",
        controller: "world",
        resolve: {
          // reportingEntities : function (apiService) {
          //   return apiService.getReportingEntities({'partners_ids': 'Worldbestguess'})
          // },
          reportingWorldFlows: function (apiService) {
            return apiService.getWorldFlows();
            // return apiService.getWorldAvailable()
          },
          reportingWorldPartner: function (apiService) {
            return apiService.getWorldAvailable();
          },
        },
      });
      $routeProvider.when("/network", {
        templateUrl: "partials/network.html",
        controller: "network",
        resolve: {
          reportingYears: function (apiService) {
            return apiService.getReportingYears();
          },
        },
      });
      $routeProvider.when("/metadata", {
        templateUrl: "partials/matrix.html",
        controller: "matrix",
      });
      $routeProvider.when("/glossary", {
        templateUrl: "partials/glossary.html",
      });
      $routeProvider.when("/corpus", {
        templateUrl: "partials/corpus.html",
      });
      $routeProvider.when("/about", {
        templateUrl: "partials/about.html",
      });
      $routeProvider.when("/legalNotice", {
        templateUrl: "partials/legalNotice.html",
      });
      $routeProvider.otherwise({ redirectTo: "/" });
    },
  ])
  .config([
    "cfpLoadingBarProvider",
    function (cfpLoadingBarProvider) {
      cfpLoadingBarProvider.includeSpinner = true;
      cfpLoadingBarProvider.includeBar = false;
    },
  ])
  .config(function ($translateProvider) {
    $translateProvider.useStaticFilesLoader({
      prefix: "i18n/locale-",
      suffix: ".json",
    });
    var language = navigator.languages ? navigator.languages[0] : navigator.language || navigator.userLanguage;

    if (language.indexOf("fr") > -1) language = "fr-FR";
    else language = "en-EN";
    $translateProvider.use(language);
  });
<|endoftext|>


<commit_before><commit_msg>Tag count should be based on user's permissions.<commit_after><|endoftext|>


<commit_before>const path = require("path");
const webpack = require('webpack');
const BundleTracker = require('webpack4-bundle-tracker');
const CompressionPlugin = require('compression-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const devMode = process.env.NODE_ENV == 'development'
console.log('devMode = ' + devMode)

module.exports = {
    context: __dirname,
    entry: {
        'main': [
            path.resolve(__dirname, 'mpcontribs/portal/assets/js/analytics'),
            path.resolve(__dirname, 'mpcontribs/portal/assets/js/main'),
            path.resolve(__dirname, 'mpcontribs/portal/assets/js/render_json'),
            path.resolve(__dirname, 'mpcontribs/portal/assets/js/render_table'),
            path.resolve(__dirname, 'mpcontribs/portal/assets/js/render_plot'),
            path.resolve(__dirname, 'mpcontribs/portal/assets/js/render_overview'),
        ]
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "[name].[chunkhash].js",
        chunkFilename: '[name].[chunkhash].js',
        crossOriginLoading: "anonymous",
        publicPath: '/static/'
    },
    plugins: [
        //new BundleAnalyzerPlugin(),
        new BundleTracker({filename: './webpack-stats.json'}),
        new webpack.ProvidePlugin({
            _: "underscore", $: "jquery", jquery: "jquery",
            "window.jQuery": "jquery", jQuery: "jquery"
        }),
        new webpack.HashedModuleIdsPlugin(),
        new CompressionPlugin({minRatio: 1}),
        new webpack.EnvironmentPlugin(['NODE_ENV', 'API_CNAME']),
        new MiniCssExtractPlugin({
            filename: "[name].[chunkhash].css",
            chunkFilename: '[name].[chunkhash].css'
        })
    ],
    optimization: {
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
        minimize: true
    },
    resolve: {
        modules: [
            path.resolve(__dirname, 'mpcontribs/portal/assets'),
            path.resolve(__dirname, 'mpcontribs/users'),
            path.resolve(__dirname, 'node_modules')
        ],
        extensions: ['.js'],
        alias: {
            "jquery": 'jquery/src/jquery',
            "jquery-validation": 'jquery-validation/dist/jquery.validate',
            "jquery-form": 'jquery-form/src/jquery.form',
            "czmore": 'js/jquery.czMore-latest',
            "typy": 'typy/lib/index',
            "backbone": 'backbone/backbone',
            "underscore": 'underscore/underscore',
            "lunr": 'lunr.js/lunr',
            "clipboard": "clipboard-polyfill/dist/clipboard-polyfill",
            "plotly": 'plotly.js/lib/core',
            "backgrid-select-all": 'backgrid-select-all/backgrid-select-all',
            "backbone.paginator": 'backbone.paginator/lib/backbone.paginator',
            "js-cookie": 'js-cookie/src/js.cookie',
            "linkify": 'linkifyjs/lib/linkify',
            "linkify-element": 'linkifyjs/lib/linkify-element',
            "mathjs": 'mathjs/dist/math',
        }
    },
    module: {
        rules: [
            {
                test: /\.(gif|png|jpe?g)$/i,
                use: [
                    {loader: 'url-loader', options: {limit: 8192, name:'[name].[ext]', outputPath: 'assets'}},
                    {loader: 'image-webpack-loader'}
                ],
            },
            {
                test: /\.(woff(2)?|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader',
                options: { limit: 8192, name:'[name].[ext]', outputPath: 'assets' }
            },
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader, {loader: 'css-loader'},
                    {loader: 'sass-loader', options: {sourceMap: true}}
                ]
            },
            { test: /\.css$/, loaders: [MiniCssExtractPlugin.loader, "css-loader"] },
            { test: /backbone/, loader: 'exports-loader?Backbone!imports-loader?underscore,jquery' },
            { test: /backgrid/, loader: 'imports-loader?jquery,backbone' },
            { test: /jquery-form/, loader: 'imports-loader?jquery' },
            { test: /jquery-validation/, loader: 'imports-loader?jquery' },
            { test: /jquery-simulate/, loader: 'imports-loader?jquery' },
            { test: /select2/, loader: 'imports-loader?jquery' },
            { test: /czmore/, loader: 'imports-loader?jquery' },
            { test: /backgrid-select-all/, loader: 'imports-loader?backgrid' },
            { test: /backgrid-filter/, loader: 'imports-loader?backgrid' },
            { test: /backbone.paginator/, loader: 'imports-loader?backbone' },
            { test: /backgrid-paginator/, loader: 'imports-loader?backgrid,backbone.paginator' },
            { test: /backgrid-grouped-columns/, loader: 'imports-loader?backgrid' },
            { test: /backgrid-columnmanager/, loader: 'imports-loader?backgrid' },
            { test: /linkify-element/, loader: 'imports-loader?linkify' }
        ]
    },
    mode : devMode ? 'development' : 'production'
}
<commit_msg>portal: disable render_* for now<commit_after>const path = require("path");
const webpack = require('webpack');
const BundleTracker = require('webpack4-bundle-tracker');
const CompressionPlugin = require('compression-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const devMode = process.env.NODE_ENV == 'development'
console.log('devMode = ' + devMode)

module.exports = {
    context: __dirname,
    entry: {
        'main': [
            path.resolve(__dirname, 'mpcontribs/portal/assets/js/analytics'),
            path.resolve(__dirname, 'mpcontribs/portal/assets/js/main'),
            //path.resolve(__dirname, 'mpcontribs/portal/assets/js/render_json'),
            //path.resolve(__dirname, 'mpcontribs/portal/assets/js/render_table'),
            //path.resolve(__dirname, 'mpcontribs/portal/assets/js/render_plot'),
            //path.resolve(__dirname, 'mpcontribs/portal/assets/js/render_overview'),
        ]
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "[name].[chunkhash].js",
        chunkFilename: '[name].[chunkhash].js',
        crossOriginLoading: "anonymous",
        publicPath: '/static/'
    },
    plugins: [
        //new BundleAnalyzerPlugin(),
        new BundleTracker({filename: './webpack-stats.json'}),
        new webpack.ProvidePlugin({
            _: "underscore", $: "jquery", jquery: "jquery",
            "window.jQuery": "jquery", jQuery: "jquery"
        }),
        new webpack.HashedModuleIdsPlugin(),
        new CompressionPlugin({minRatio: 1}),
        new webpack.EnvironmentPlugin(['NODE_ENV', 'API_CNAME']),
        new MiniCssExtractPlugin({
            filename: "[name].[chunkhash].css",
            chunkFilename: '[name].[chunkhash].css'
        })
    ],
    optimization: {
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
        minimize: true
    },
    resolve: {
        modules: [
            path.resolve(__dirname, 'mpcontribs/portal/assets'),
            path.resolve(__dirname, 'mpcontribs/users'),
            path.resolve(__dirname, 'node_modules')
        ],
        extensions: ['.js'],
        alias: {
            "jquery": 'jquery/src/jquery',
            "jquery-validation": 'jquery-validation/dist/jquery.validate',
            "jquery-form": 'jquery-form/src/jquery.form',
            "czmore": 'js/jquery.czMore-latest',
            "typy": 'typy/lib/index',
            "backbone": 'backbone/backbone',
            "underscore": 'underscore/underscore',
            "lunr": 'lunr.js/lunr',
            "clipboard": "clipboard-polyfill/dist/clipboard-polyfill",
            "plotly": 'plotly.js/lib/core',
            "backgrid-select-all": 'backgrid-select-all/backgrid-select-all',
            "backbone.paginator": 'backbone.paginator/lib/backbone.paginator',
            "js-cookie": 'js-cookie/src/js.cookie',
            "linkify": 'linkifyjs/lib/linkify',
            "linkify-element": 'linkifyjs/lib/linkify-element',
            "mathjs": 'mathjs/dist/math',
        }
    },
    module: {
        rules: [
            {
                test: /\.(gif|png|jpe?g)$/i,
                use: [
                    {loader: 'url-loader', options: {limit: 8192, name:'[name].[ext]', outputPath: 'assets'}},
                    {loader: 'image-webpack-loader'}
                ],
            },
            {
                test: /\.(woff(2)?|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader',
                options: { limit: 8192, name:'[name].[ext]', outputPath: 'assets' }
            },
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader, {loader: 'css-loader'},
                    {loader: 'sass-loader', options: {sourceMap: true}}
                ]
            },
            { test: /\.css$/, loaders: [MiniCssExtractPlugin.loader, "css-loader"] },
            { test: /backbone/, loader: 'exports-loader?Backbone!imports-loader?underscore,jquery' },
            { test: /backgrid/, loader: 'imports-loader?jquery,backbone' },
            { test: /jquery-form/, loader: 'imports-loader?jquery' },
            { test: /jquery-validation/, loader: 'imports-loader?jquery' },
            { test: /jquery-simulate/, loader: 'imports-loader?jquery' },
            { test: /select2/, loader: 'imports-loader?jquery' },
            { test: /czmore/, loader: 'imports-loader?jquery' },
            { test: /backgrid-select-all/, loader: 'imports-loader?backgrid' },
            { test: /backgrid-filter/, loader: 'imports-loader?backgrid' },
            { test: /backbone.paginator/, loader: 'imports-loader?backbone' },
            { test: /backgrid-paginator/, loader: 'imports-loader?backgrid,backbone.paginator' },
            { test: /backgrid-grouped-columns/, loader: 'imports-loader?backgrid' },
            { test: /backgrid-columnmanager/, loader: 'imports-loader?backgrid' },
            { test: /linkify-element/, loader: 'imports-loader?linkify' }
        ]
    },
    mode : devMode ? 'development' : 'production'
}
<|endoftext|>


<commit_before>/*
    Copyright 2015 Diamond Light Source <stuart.fisher@diamond.ac.uk>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

define(['backbone', 'marionette', 'underscore', 'jquery',

    'views/header',
    'views/sidebar',
    'views/dialogregion',
    'views/login',

    'models/proposal',
    'models/options',

    'utils',
    'config.json',
    'jquery.cookie', 'jquery-ui',
        ],
function(Backbone, Marionette, _, $, HeaderView, SideBarView, DialogRegion, LoginView, Proposal, Options, utils, config) {

  window.app = new Marionette.Application()

  console.log('CONFIG', config)

  // Moved to here so its available on app start
  app.options = new Options()

  // Base url for the api
  app.apiurl = config.apiurl

  // Base url for the app
  app.appurl = config.appurl

  // reference to config
  app.config = config

  // Restore token if its in sessionStorage
  app.token = sessionStorage.getItem('token')

  // Allow the app to load a proposal on bootstrap
  app.parseQuery = function() {
      var str = location.search.replace(/\?/, '').split(/&/)
      var pairs = {}
      _.each(str, function(v) {
          var kv = v.split(/=/)
          pairs[kv[0]] = kv[1]
      })

      console.log('pairs', pairs)

      if ('prop' in pairs) sessionStorage.setItem('prop', pairs.prop)
  }

  app.parseQuery()

  // Allow the app to autoupdate itself when running
  app.checkForUpdate = function() {
      Backbone.ajax({
          url: app.appurl+'/assets/js/config.json?t='+(new Date().getTime()),
          success: function(config) {
              console.log('old', app.config.build, 'new', config.build)
              if (config.build != app.config.build) {
                  app.alert({ message: 'An update to SynchWeb is available. This page will automatically refresh in 5 seconds' })
                  setTimeout(function() {
                      window.location.reload()
                  }, 5000)
              }

              setTimeout(app.checkForUpdate, 1000 * 60 * 30)
          },
      })
  }
  app.checkForUpdate()

  // Allow us to set a global base url for the API
  var oldSync = Backbone.sync;
  Backbone.sync = function(method, model, options) {
    var url = _.isFunction(model.url) ? model.url() : model.url;

    options = options || {};
    if (url) options.url = app.apiurl+url

    return oldSync.call(this, method, model, options);
  }

  // Pass prop to Backbone.ajax
  var oldAjax = Backbone.ajax
  Backbone.ajax = function(options) {
      var prop = app.prop

      // FormData
      if (options.data instanceof FormData) {
          options.data.append('prop', prop)

      // JSON content
      } else if (options.contentType == 'application/json' || options.type == 'DELETE') {
          if (options.data) var tmp = JSON.parse(options.data)
          else var tmp = {}

          if (Array.isArray(tmp)) tmp[0].prop = prop
          else {
            if (!tmp.prop) tmp.prop = prop
          }
          options.data = JSON.stringify(tmp)

      // Append to object for anything else
      } else {
          if (!options.data) options.data = {}
          if (!options.data.prop) options.data.prop = prop
      }

      // Send token with requst
      if (app.token) {
          options.beforeSend = function(request){
              request.setRequestHeader('Authorization', 'Bearer ' + app.token);
          }
      }

      return oldAjax.call(this, options)
  }

  // Override so we can redirect to login when theres no token present
  Backbone.Router.prototype.execute = function(callback, args, name) {
      if (!app.token) {
        app.login()
        return false
      }

      if (callback) callback.apply(this, args)
  }

  app.addRegions({
    content: '#container',
    header: '#header',
    sidebar: '#sidebar',
    dialog: DialogRegion,
    motd: '#motd',
  })

  /*
   Monitor all ajax requests to detect when user needs to login and/or
   is disconnected from the interwebs
  */
  $(document).ajaxError(_.debounce(function(event, xhr, settings, error) {
    console.log('ajax error', 'status', xhr.status, 'code', settings, error)

    var json;
    if (xhr.responseText) {
        try {
            json = $.parseJSON(xhr.responseText)
        } catch(err) {

        }
    }
    var msg = json && (json.error || json.msg) ? (json.error ? json.error : json.msg) : error

    if (xhr.readyState == 0) {
        app.alert({ message: 'A network request failed', persist: 'network' })

    }

    if (xhr.status == 401) app.login(xhr)
    if (xhr.status == 500) app.alert({ message: 'An application error has occurred
'+msg+'
', persist: 'e500' })
    if (xhr.status == 503) {
        if (json) app.alert({ message: 'A database error has occurred
'+msg+'
', persist: 'e503' })
        else  app.alert({ message: 'A server error has occurred
'+msg+'
', persist: 'e503' })
    }
  }, 300))

  app.login = function(xhr) {
      app.bc.reset([{ title: 'Login' }])
      app.content.show(new LoginView())
  }

  /*
    Load module routers and startup application
  */
  app.addInitializer(function(options){
    require([
        'modules/dc/router',
        'modules/proposal/router',
        'modules/shipment/router',
        'modules/samples/router',
        'modules/projects/router',
        'modules/calendar/router',
        'modules/contact/router',
        'modules/cell/router',
        'modules/assign/router',
        'modules/fault/router',
        'modules/stats/router',
        'modules/blstats/router',
        'modules/status/router',
        'modules/docs/router',
        'modules/feedback/router',
        'modules/mc/router',
        'modules/admin/router',
        'modules/imaging/router',
        'modules/types/em/relion/router',
        'modules/types/em/scipion/router',
    ], function() {

        this.sidebarview = new SideBarView()
        app.sidebar.show(this.sidebarview)

        // Breadcrumbs collection
        if (!app.bc) {
          app.bc = new Backbone.Collection()
          if (!this.headerview) this.headerview = new HeaderView({ bc: app.bc })
          app.header.show(this.headerview)
        }

        $.when(app.loadopts()).done(function() {
          if (app.token) app.getuser({
            callback: function() {
                if (!Backbone.History.started) app.starthistory()
            }
          })
          else {
            if (!Backbone.History.started) app.starthistory()
          }
        })
    })
  })

  /*
   Get the fedid for the logged in user to read cookie
  */
  app.getuser = function(options) {
    Backbone.ajax({
      url: app.apiurl+'/users/current',
      success: function(resp) {
          app.user = resp.user
          app.personid = resp.personid
          app.givenname = resp.givenname
          app.staff = resp.is_staff
          // Saving the default type for this user.
          // Needed for resetting the home view
          app.defaultType = resp.ty
          if (!app.type) app.type = resp.ty

          // Should put this somewhere else...
          app.user_can = function(perm) {
            return resp.permissions.indexOf(perm) > -1
          }

          app.cookie(null, function() {
            if (options && options.callback) options.callback()
          })
      },

      error: function() {
          if (options && options.callback) options.callback()
      }

    })
  }

  /*
   Shortcut to navigate
  */
  app.navigate = function(route,  options){
    options || (options = {});
    Backbone.history.navigate(route, options);
    log()
  }

  /*
   Cookie the selected proposal
      rename me app.get_proposal()
  */
  app.cookie = function(prop, callback) {
    if (prop) sessionStorage.setItem('prop', prop)
    else prop = sessionStorage.getItem('prop')

    app.prop = prop

    if (prop) {
        var proposal = new Proposal({ PROPOSAL: prop })
        proposal.fetch({
            success: function() {
                app.type = proposal.get('TYPE'),
                require(['modules/types/'+proposal.get('TYPE')+'/menu'], function(menus) {
                    proposal.set('MENUS', menus)
                    app.prop = prop
                    app.proposal = proposal
                    app.trigger('proposal:change', proposal)
                    if (callback) callback()
                })
            },

            error: function() {
                app.message({ title: 'No such proposal', message: 'The selected proposal does not exist' })
                app.prop = null
                sessionStorage.removeItem('prop')
            },

        })
    } else if (callback) callback()
  },

  /*
   Deselect the selected proposal.
   Used when navigating back to home page.
  */
  app.clearProposal = function() {
      // Clear the proposal cookie/object
    sessionStorage.removeItem('prop')

    delete app.prop
    app.clearVisit()
    // Reset type to the default for this user
    app.type = app.defaultType
    if (!app.type) {
      console.log('Error clearing proposal, no default type for this user')
    }

    // Recall the user info so we can set the default type for this person
    // app.getuser()
    // Now we need to tell any listening views that the proposal has changed...
    app.triggerMethod('proposal:change', null)
  },

  /*
   Set current visit number
  */
 app.setVisit = function(visit){
  if(visit) sessionStorage.setItem('visit', visit)
  else visit = sessionStorage.getItem('visit')
  app.visit = visit
  app.trigger('visit:change', visit)
}

/*
 Deselect selected visit.
 Called by clearProposal() when navigating back to home page.
*/
app.clearVisit = function(){
    sessionStorage.removeItem('visit')
    delete app.visit
    app.triggerMethod('visit:change', null)
}

  /*
   Load client side options and show MOTD
  */
  app.loadopts = function() {
    //   app.options = new Options()
      return app.options.fetch({
          data: { t: new Date().getTime() },
          success: function() {
              if (app.options.get('motd')) {
                  var options = {
                      persist: 'motd',
                      dismissible: true,
                      notify: true,
                      message: app.options.get('motd')
                  }
                  app.motd.show(new utils.alert(options))
              }
          }
      })
  }

  /*
   Log message to console
  */
  app.log = function() {
    console.log.apply(console, arguments)
  },

  /*
    Show an alert message at the top of the page and highlight
  */
  app.alert = function(options) {
      if (options && options.persist) {
          app.content.$el.find('.content .'+options.persist).remove()
      }

      app.content.$el.find('.content').prepend(new utils.alert(options).render().$el)
  }

  /*
   Show the generic message page (for errors, etc)
  */
  app.message = function(options) {
    app.content.show(new utils.generic_msg(options))
  }

  /*
   Check screen width
  */
  app.mobile = function() {
    return $(window).width() <= 600
  }

  /*
   Show blank loading view
  */
  app.loading = function() {
    var LoadingView = Marionette.ItemView.extend({ className: 'loading-container', template: '

' })
    app.content.show(new LoadingView())
  }

  /*
   Single Event for window scrolling
  */
  $(window).scroll(_.debounce(function() {
    app.trigger('window:scroll')
  }, 10))

  app.starthistory = function() {
      if(Backbone.history){
          Backbone.history.start({ pushState: true, root: app.appurl });

          // Only need this for pushState enabled browsers
          if (Backbone.history && Backbone.history._hasPushState) {
              var $document = $(window.document);
              var openLinkInTab = false;

              var is_relative_to_page = function(href) {
                  return href.match(/^\/|(http:|https:|ftp:|mailto:|javascript:)/) === null;
              };

              var is_routable = function(href) {
                  console.log('routable', href.indexOf('/'))
                  return href.indexOf("#") === -1 && (is_relative_to_page(href) || href.indexOf(Backbone.history.root) == 0 || href.indexOf('/') == 0) && (href.indexOf(app.apiurl) != 0);
              };

              $document.keydown(function(e) {
                  if (e.ctrlKey || e.keyCode === 91) {
                      openLinkInTab = true;
                  }
              });

              $document.keyup(function(e) {
                  openLinkInTab = false;
              });

              $document.on("click", "a", function(e) {
                  var href =  $(this).attr("href");
                  if (!href) return
                  if (is_routable(href)) {
                      e.preventDefault();
                      Backbone.history.navigate(href, true);
                  }
              });
          }

          Backbone.history.on('route', function(route, params) {
              console.log('routing', arguments)
              log()
          })
      }
  }

  function log() {
      var data = { location: window.location.pathname }
      Backbone.ajax({
          url: app.apiurl+'/users/log/',
          type: 'POST',
          data: data
      })
  }

  // log()

  return app

})
<commit_msg>Ensured global visit parameter survives page reload<commit_after>/*
    Copyright 2015 Diamond Light Source <stuart.fisher@diamond.ac.uk>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

define(['backbone', 'marionette', 'underscore', 'jquery',

    'views/header',
    'views/sidebar',
    'views/dialogregion',
    'views/login',

    'models/proposal',
    'models/options',

    'utils',
    'config.json',
    'jquery.cookie', 'jquery-ui',
        ],
function(Backbone, Marionette, _, $, HeaderView, SideBarView, DialogRegion, LoginView, Proposal, Options, utils, config) {

  window.app = new Marionette.Application()

  console.log('CONFIG', config)

  // Moved to here so its available on app start
  app.options = new Options()

  // Base url for the api
  app.apiurl = config.apiurl

  // Base url for the app
  app.appurl = config.appurl

  // reference to config
  app.config = config

  // Restore token if its in sessionStorage
  app.token = sessionStorage.getItem('token')

  // Allow the app to load a proposal on bootstrap
  app.parseQuery = function() {
      var str = location.search.replace(/\?/, '').split(/&/)
      var pairs = {}
      _.each(str, function(v) {
          var kv = v.split(/=/)
          pairs[kv[0]] = kv[1]
      })

      console.log('pairs', pairs)

      if ('prop' in pairs) sessionStorage.setItem('prop', pairs.prop)
  }

  app.parseQuery()

  // Allow the app to autoupdate itself when running
  app.checkForUpdate = function() {
      Backbone.ajax({
          url: app.appurl+'/assets/js/config.json?t='+(new Date().getTime()),
          success: function(config) {
              console.log('old', app.config.build, 'new', config.build)
              if (config.build != app.config.build) {
                  app.alert({ message: 'An update to SynchWeb is available. This page will automatically refresh in 5 seconds' })
                  setTimeout(function() {
                      window.location.reload()
                  }, 5000)
              }

              setTimeout(app.checkForUpdate, 1000 * 60 * 30)
          },
      })
  }
  app.checkForUpdate()

  // Allow us to set a global base url for the API
  var oldSync = Backbone.sync;
  Backbone.sync = function(method, model, options) {
    var url = _.isFunction(model.url) ? model.url() : model.url;

    options = options || {};
    if (url) options.url = app.apiurl+url

    return oldSync.call(this, method, model, options);
  }

  // Pass prop to Backbone.ajax
  var oldAjax = Backbone.ajax
  Backbone.ajax = function(options) {
      var prop = app.prop

      // FormData
      if (options.data instanceof FormData) {
          options.data.append('prop', prop)

      // JSON content
      } else if (options.contentType == 'application/json' || options.type == 'DELETE') {
          if (options.data) var tmp = JSON.parse(options.data)
          else var tmp = {}

          if (Array.isArray(tmp)) tmp[0].prop = prop
          else {
            if (!tmp.prop) tmp.prop = prop
          }
          options.data = JSON.stringify(tmp)

      // Append to object for anything else
      } else {
          if (!options.data) options.data = {}
          if (!options.data.prop) options.data.prop = prop
      }

      // Send token with requst
      if (app.token) {
          options.beforeSend = function(request){
              request.setRequestHeader('Authorization', 'Bearer ' + app.token);
          }
      }

      return oldAjax.call(this, options)
  }

  // Override so we can redirect to login when theres no token present
  Backbone.Router.prototype.execute = function(callback, args, name) {
      if (!app.token) {
        app.login()
        return false
      }

      if (callback) callback.apply(this, args)
  }

  app.addRegions({
    content: '#container',
    header: '#header',
    sidebar: '#sidebar',
    dialog: DialogRegion,
    motd: '#motd',
  })

  /*
   Monitor all ajax requests to detect when user needs to login and/or
   is disconnected from the interwebs
  */
  $(document).ajaxError(_.debounce(function(event, xhr, settings, error) {
    console.log('ajax error', 'status', xhr.status, 'code', settings, error)

    var json;
    if (xhr.responseText) {
        try {
            json = $.parseJSON(xhr.responseText)
        } catch(err) {

        }
    }
    var msg = json && (json.error || json.msg) ? (json.error ? json.error : json.msg) : error

    if (xhr.readyState == 0) {
        app.alert({ message: 'A network request failed', persist: 'network' })

    }

    if (xhr.status == 401) app.login(xhr)
    if (xhr.status == 500) app.alert({ message: 'An application error has occurred
'+msg+'
', persist: 'e500' })
    if (xhr.status == 503) {
        if (json) app.alert({ message: 'A database error has occurred
'+msg+'
', persist: 'e503' })
        else  app.alert({ message: 'A server error has occurred
'+msg+'
', persist: 'e503' })
    }
  }, 300))

  app.login = function(xhr) {
      app.bc.reset([{ title: 'Login' }])
      app.content.show(new LoginView())
  }

  /*
    Load module routers and startup application
  */
  app.addInitializer(function(options){
    require([
        'modules/dc/router',
        'modules/proposal/router',
        'modules/shipment/router',
        'modules/samples/router',
        'modules/projects/router',
        'modules/calendar/router',
        'modules/contact/router',
        'modules/cell/router',
        'modules/assign/router',
        'modules/fault/router',
        'modules/stats/router',
        'modules/blstats/router',
        'modules/status/router',
        'modules/docs/router',
        'modules/feedback/router',
        'modules/mc/router',
        'modules/admin/router',
        'modules/imaging/router',
        'modules/types/em/relion/router',
        'modules/types/em/scipion/router',
    ], function() {

        this.sidebarview = new SideBarView()
        app.sidebar.show(this.sidebarview)

        // Breadcrumbs collection
        if (!app.bc) {
          app.bc = new Backbone.Collection()
          if (!this.headerview) this.headerview = new HeaderView({ bc: app.bc })
          app.header.show(this.headerview)
        }

        $.when(app.loadopts()).done(function() {
          if (app.token) app.getuser({
            callback: function() {
                if (!Backbone.History.started) app.starthistory()
            }
          })
          else {
            if (!Backbone.History.started) app.starthistory()
          }
        })
    })
  })

  /*
   Get the fedid for the logged in user to read cookie
  */
  app.getuser = function(options) {
    Backbone.ajax({
      url: app.apiurl+'/users/current',
      success: function(resp) {
          app.user = resp.user
          app.personid = resp.personid
          app.givenname = resp.givenname
          app.staff = resp.is_staff
          // Saving the default type for this user.
          // Needed for resetting the home view
          app.defaultType = resp.ty
          if (!app.type) app.type = resp.ty

          // Should put this somewhere else...
          app.user_can = function(perm) {
            return resp.permissions.indexOf(perm) > -1
          }

          app.cookie(null, function() {
            if (options && options.callback) options.callback()
          })

          app.setVisit()
      },

      error: function() {
          if (options && options.callback) options.callback()
      }

    })
  }

  /*
   Shortcut to navigate
  */
  app.navigate = function(route,  options){
    options || (options = {});
    Backbone.history.navigate(route, options);
    log()
  }

  /*
   Cookie the selected proposal
      rename me app.get_proposal()
  */
  app.cookie = function(prop, callback) {
    if (prop) sessionStorage.setItem('prop', prop)
    else prop = sessionStorage.getItem('prop')

    app.prop = prop

    if (prop) {
        var proposal = new Proposal({ PROPOSAL: prop })
        proposal.fetch({
            success: function() {
                app.type = proposal.get('TYPE'),
                require(['modules/types/'+proposal.get('TYPE')+'/menu'], function(menus) {
                    proposal.set('MENUS', menus)
                    app.prop = prop
                    app.proposal = proposal
                    app.trigger('proposal:change', proposal)
                    if (callback) callback()
                })
            },

            error: function() {
                app.message({ title: 'No such proposal', message: 'The selected proposal does not exist' })
                app.prop = null
                sessionStorage.removeItem('prop')
            },

        })
    } else if (callback) callback()
  },

  /*
   Deselect the selected proposal.
   Used when navigating back to home page.
  */
  app.clearProposal = function() {
      // Clear the proposal cookie/object
    sessionStorage.removeItem('prop')

    delete app.prop
    app.clearVisit()
    // Reset type to the default for this user
    app.type = app.defaultType
    if (!app.type) {
      console.log('Error clearing proposal, no default type for this user')
    }

    // Recall the user info so we can set the default type for this person
    // app.getuser()
    // Now we need to tell any listening views that the proposal has changed...
    app.triggerMethod('proposal:change', null)
  },

  /*
   Set current visit number
  */
 app.setVisit = function(visit){
  if(visit) sessionStorage.setItem('visit', visit)
  else visit = sessionStorage.getItem('visit')
  app.visit = visit
  app.trigger('visit:change', visit)
}

/*
 Deselect selected visit.
 Called by clearProposal() when navigating back to home page.
*/
app.clearVisit = function(){
    sessionStorage.removeItem('visit')
    delete app.visit
    app.triggerMethod('visit:change', null)
}

  /*
   Load client side options and show MOTD
  */
  app.loadopts = function() {
    //   app.options = new Options()
      return app.options.fetch({
          data: { t: new Date().getTime() },
          success: function() {
              if (app.options.get('motd')) {
                  var options = {
                      persist: 'motd',
                      dismissible: true,
                      notify: true,
                      message: app.options.get('motd')
                  }
                  app.motd.show(new utils.alert(options))
              }
          }
      })
  }

  /*
   Log message to console
  */
  app.log = function() {
    console.log.apply(console, arguments)
  },

  /*
    Show an alert message at the top of the page and highlight
  */
  app.alert = function(options) {
      if (options && options.persist) {
          app.content.$el.find('.content .'+options.persist).remove()
      }

      app.content.$el.find('.content').prepend(new utils.alert(options).render().$el)
  }

  /*
   Show the generic message page (for errors, etc)
  */
  app.message = function(options) {
    app.content.show(new utils.generic_msg(options))
  }

  /*
   Check screen width
  */
  app.mobile = function() {
    return $(window).width() <= 600
  }

  /*
   Show blank loading view
  */
  app.loading = function() {
    var LoadingView = Marionette.ItemView.extend({ className: 'loading-container', template: '

' })
    app.content.show(new LoadingView())
  }

  /*
   Single Event for window scrolling
  */
  $(window).scroll(_.debounce(function() {
    app.trigger('window:scroll')
  }, 10))

  app.starthistory = function() {
      if(Backbone.history){
          Backbone.history.start({ pushState: true, root: app.appurl });

          // Only need this for pushState enabled browsers
          if (Backbone.history && Backbone.history._hasPushState) {
              var $document = $(window.document);
              var openLinkInTab = false;

              var is_relative_to_page = function(href) {
                  return href.match(/^\/|(http:|https:|ftp:|mailto:|javascript:)/) === null;
              };

              var is_routable = function(href) {
                  console.log('routable', href.indexOf('/'))
                  return href.indexOf("#") === -1 && (is_relative_to_page(href) || href.indexOf(Backbone.history.root) == 0 || href.indexOf('/') == 0) && (href.indexOf(app.apiurl) != 0);
              };

              $document.keydown(function(e) {
                  if (e.ctrlKey || e.keyCode === 91) {
                      openLinkInTab = true;
                  }
              });

              $document.keyup(function(e) {
                  openLinkInTab = false;
              });

              $document.on("click", "a", function(e) {
                  var href =  $(this).attr("href");
                  if (!href) return
                  if (is_routable(href)) {
                      e.preventDefault();
                      Backbone.history.navigate(href, true);
                  }
              });
          }

          Backbone.history.on('route', function(route, params) {
              console.log('routing', arguments)
              log()
          })
      }
  }

  function log() {
      var data = { location: window.location.pathname }
      Backbone.ajax({
          url: app.apiurl+'/users/log/',
          type: 'POST',
          data: data
      })
  }

  // log()

  return app

})
<|endoftext|>


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

// This config file is used to create a webpack bundle that we use on
// spec/performance-test.html to profile the performance footprint of the
// component.
module.exports = {
  entry: path.join(__dirname, 'spec/performance-test.jsx'),
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'performance-test.js'
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json']
  },
  module: {
    rules: [
      {
        test: /\.jsx?/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
    ],
  },
};
<commit_msg>Add source-map to perf-test webpack bundle<commit_after>const path = require('path');

// This config file is used to create a webpack bundle that we use on
// spec/performance-test.html to profile the performance footprint of the
// component.
module.exports = {
  entry: path.join(__dirname, 'spec/performance-test.jsx'),
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'performance-test.js'
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json']
  },
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.jsx?/,
        exclude: /node_modules/,
        loader: 'babel-loader',
      },
    ],
  },
};
<|endoftext|>