<commit_before>// FIXME should possibly show tooltip when dragging?

goog.provide('ol.control.ZoomSlider');

goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.events.EventType');
goog.require('goog.fx.Dragger');
goog.require('goog.fx.Dragger.EventType');
goog.require('goog.math');
goog.require('goog.math.Rect');
goog.require('goog.style');
goog.require('ol');
goog.require('ol.animation');
goog.require('ol.control.Control');
goog.require('ol.css');
goog.require('ol.easing');

/**
 * @classdesc
 * A slider type of control for zooming.
 *
 * Example:
 *
 *     map.addControl(new ol.control.ZoomSlider());
 *
 * @constructor
 * @extends {ol.control.Control}
 * @param {olx.control.ZoomSliderOptions=} opt_options Zoom slider options.
 * @api stable
 */
ol.control.ZoomSlider = function(opt_options) {

  var options = goog.isDef(opt_options) ? opt_options : {};

  /**
   * Will hold the current resolution of the view.
   *
   * @type {number|undefined}
   * @private
   */
  this.currentResolution_ = undefined;

  /**
   * The direction of the slider. Will be determined from actual display of the
   * container and defaults to ol.control.ZoomSlider.direction.VERTICAL.
   *
   * @type {ol.control.ZoomSlider.direction}
   * @private
   */
  this.direction_ = ol.control.ZoomSlider.direction.VERTICAL;

  /**
   * Whether the slider is initialized.
   * @type {boolean}
   * @private
   */
  this.sliderInitialized_ = false;

  var className = goog.isDef(options.className) ?
      options.className : 'ol-zoomslider';
  var thumbElement = goog.dom.createDom(goog.dom.TagName.DIV,
      [className + '-thumb', ol.css.CLASS_UNSELECTABLE]);
  var sliderElement = goog.dom.createDom(goog.dom.TagName.DIV,
      [className, ol.css.CLASS_UNSELECTABLE], thumbElement);

  /**
   * @type {goog.fx.Dragger}
   * @private
   */
  this.dragger_ = new goog.fx.Dragger(thumbElement);
  this.registerDisposable(this.dragger_);

  goog.events.listen(this.dragger_, [
    goog.fx.Dragger.EventType.DRAG,
    goog.fx.Dragger.EventType.END
  ], this.handleSliderChange_, undefined, this);

  goog.events.listen(sliderElement, goog.events.EventType.CLICK,
      this.handleContainerClick_, false, this);
  goog.events.listen(thumbElement, goog.events.EventType.CLICK,
      goog.events.Event.stopPropagation);

  goog.base(this, {
    element: sliderElement
  });
};
goog.inherits(ol.control.ZoomSlider, ol.control.Control);

/**
 * The enum for available directions.
 *
 * @enum {number}
 */
ol.control.ZoomSlider.direction = {
  VERTICAL: 0,
  HORIZONTAL: 1
};

/**
 * @inheritDoc
 */
ol.control.ZoomSlider.prototype.setMap = function(map) {
  goog.base(this, 'setMap', map);
  if (!goog.isNull(map)) {
    map.render();
  }
};

/**
 * Initializes the slider element. This will determine and set this controls
 * direction_ and also constrain the dragging of the thumb to always be within
 * the bounds of the container.
 *
 * @private
 */
ol.control.ZoomSlider.prototype.initSlider_ = function() {
  var container = this.element,
      thumb = goog.dom.getFirstElementChild(container),
      elemSize = goog.style.getContentBoxSize(container),
      thumbBounds = goog.style.getBounds(thumb),
      thumbMargins = goog.style.getMarginBox(thumb),
      thumbBorderBox = goog.style.getBorderBox(thumb),
      w = elemSize.width -
          thumbMargins.left - thumbMargins.right -
          thumbBorderBox.left - thumbBorderBox.right -
          thumbBounds.width,
      h = elemSize.height -
          thumbMargins.top - thumbMargins.bottom -
          thumbBorderBox.top - thumbBorderBox.bottom -
          thumbBounds.height,
      limits;
  if (elemSize.width > elemSize.height) {
    this.direction_ = ol.control.ZoomSlider.direction.HORIZONTAL;
    limits = new goog.math.Rect(0, 0, w, 0);
  } else {
    this.direction_ = ol.control.ZoomSlider.direction.VERTICAL;
    limits = new goog.math.Rect(0, 0, 0, h);
  }
  this.dragger_.setLimits(limits);
  this.sliderInitialized_ = true;
};

/**
 * @inheritDoc
 */
ol.control.ZoomSlider.prototype.handleMapPostrender = function(mapEvent) {
  if (goog.isNull(mapEvent.frameState)) {
    return;
  }
  goog.asserts.assert(
      goog.isDefAndNotNull(mapEvent.frameState.viewState));
  if (!this.sliderInitialized_) {
    this.initSlider_();
  }
  var res = mapEvent.frameState.viewState.resolution;
  if (res !== this.currentResolution_) {
    this.currentResolution_ = res;
    this.positionThumbForResolution_(res);
  }
};

/**
 * @param {goog.events.BrowserEvent} browserEvent The browser event to handle.
 * @private
 */
ol.control.ZoomSlider.prototype.handleContainerClick_ = function(browserEvent) {
  var map = this.getMap();
  var view = map.getView();
  var resolution;
  var amountDragged = this.amountDragged_(browserEvent.offsetX,
      browserEvent.offsetY);
  resolution = this.resolutionForAmount_(amountDragged);
  goog.asserts.assert(goog.isDef(resolution));
  map.beforeRender(ol.animation.zoom({
    resolution: resolution,
    duration: ol.ZOOMSLIDER_ANIMATION_DURATION,
    easing: ol.easing.easeOut
  }));
  resolution = view.constrainResolution(resolution);
  view.setResolution(resolution);
};

/**
 * Positions the thumb inside its container according to the given resolution.
 *
 * @param {number} res The res.
 * @private
 */
ol.control.ZoomSlider.prototype.positionThumbForResolution_ = function(res) {
  var amount = this.amountForResolution_(res),
      dragger = this.dragger_,
      thumb = goog.dom.getFirstElementChild(this.element);

  if (this.direction_ == ol.control.ZoomSlider.direction.HORIZONTAL) {
    var left = dragger.limits.left + dragger.limits.width * amount;
    goog.style.setPosition(thumb, left);
  } else {
    var top = dragger.limits.top + dragger.limits.height * amount;
    goog.style.setPosition(thumb, dragger.limits.left, top);
  }
};

/**
 * Calculates the amount the thumb has been dragged to allow for calculation
 * of the corresponding resolution.
 *
 * @param {number} x Pixel position relative to the left of the slider.
 * @param {number} y Pixel position relative to the top of the slider.
 * @return {number} The amount the thumb has been dragged.
 * @private
 */
ol.control.ZoomSlider.prototype.amountDragged_ = function(x, y) {
  var draggerLimits = this.dragger_.limits,
      amount = 0;
  if (this.direction_ === ol.control.ZoomSlider.direction.HORIZONTAL) {
    amount = (x - draggerLimits.left) / draggerLimits.width;
  } else {
    amount = (y - draggerLimits.top) / draggerLimits.height;
  }
  return amount;
};

/**
 * Calculates the corresponding resolution of the thumb by the amount it has
 * been dragged from its minimum.
 *
 * @param {number} amount The amount the thumb has been dragged.
 * @return {number} The corresponding resolution.
 * @private
 */
ol.control.ZoomSlider.prototype.resolutionForAmount_ = function(amount) {
  // FIXME do we really need this affine transform?
  amount = (goog.math.clamp(amount, 0, 1) - 1) * -1;
  var fn = this.getMap().getView().getResolutionForValueFunction();
  return fn(amount);
};

/**
 * Determines an amount of dragging relative to this minimum position by the
 * given resolution.
 *
 * @param {number} res The resolution to get the amount for.
 * @return {number} The corresponding value (between 0 and 1).
 * @private
 */
ol.control.ZoomSlider.prototype.amountForResolution_ = function(res) {
  var fn = this.getMap().getView().getValueForResolutionFunction();
  var value = fn(res);
  // FIXME do we really need this affine transform?
  return (value - 1) * -1;
};

/**
 * Handles the user caused changes of the slider thumb and adjusts the
 * resolution of our map accordingly. Will be called both while dragging and
 * when dragging ends.
 *
 * @param {goog.fx.DragDropEvent} e The dragdropevent.
 * @private
 */
ol.control.ZoomSlider.prototype.handleSliderChange_ = function(e) {
  var map = this.getMap();
  var view = map.getView();
  var resolution;
  if (e.type === goog.fx.Dragger.EventType.DRAG) {
    var amountDragged = this.amountDragged_(e.left, e.top);
    resolution = this.resolutionForAmount_(amountDragged);
    if (resolution !== this.currentResolution_) {
      this.currentResolution_ = resolution;
      view.setResolution(resolution);
    }
  } else {
    goog.asserts.assert(goog.isDef(this.currentResolution_));
    map.beforeRender(ol.animation.zoom({
      resolution: this.currentResolution_,
      duration: ol.ZOOMSLIDER_ANIMATION_DURATION,
      easing: ol.easing.easeOut
    }));
    resolution = view.constrainResolution(this.currentResolution_);
    view.setResolution(resolution);
  }
};
<commit_msg>Add missing goog.require<commit_after>// FIXME should possibly show tooltip when dragging?

goog.provide('ol.control.ZoomSlider');

goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.events.EventType');
goog.require('goog.fx.DragDropEvent');
goog.require('goog.fx.Dragger');
goog.require('goog.fx.Dragger.EventType');
goog.require('goog.math');
goog.require('goog.math.Rect');
goog.require('goog.style');
goog.require('ol');
goog.require('ol.animation');
goog.require('ol.control.Control');
goog.require('ol.css');
goog.require('ol.easing');

/**
 * @classdesc
 * A slider type of control for zooming.
 *
 * Example:
 *
 *     map.addControl(new ol.control.ZoomSlider());
 *
 * @constructor
 * @extends {ol.control.Control}
 * @param {olx.control.ZoomSliderOptions=} opt_options Zoom slider options.
 * @api stable
 */
ol.control.ZoomSlider = function(opt_options) {

  var options = goog.isDef(opt_options) ? opt_options : {};

  /**
   * Will hold the current resolution of the view.
   *
   * @type {number|undefined}
   * @private
   */
  this.currentResolution_ = undefined;

  /**
   * The direction of the slider. Will be determined from actual display of the
   * container and defaults to ol.control.ZoomSlider.direction.VERTICAL.
   *
   * @type {ol.control.ZoomSlider.direction}
   * @private
   */
  this.direction_ = ol.control.ZoomSlider.direction.VERTICAL;

  /**
   * Whether the slider is initialized.
   * @type {boolean}
   * @private
   */
  this.sliderInitialized_ = false;

  var className = goog.isDef(options.className) ?
      options.className : 'ol-zoomslider';
  var thumbElement = goog.dom.createDom(goog.dom.TagName.DIV,
      [className + '-thumb', ol.css.CLASS_UNSELECTABLE]);
  var sliderElement = goog.dom.createDom(goog.dom.TagName.DIV,
      [className, ol.css.CLASS_UNSELECTABLE], thumbElement);

  /**
   * @type {goog.fx.Dragger}
   * @private
   */
  this.dragger_ = new goog.fx.Dragger(thumbElement);
  this.registerDisposable(this.dragger_);

  goog.events.listen(this.dragger_, [
    goog.fx.Dragger.EventType.DRAG,
    goog.fx.Dragger.EventType.END
  ], this.handleSliderChange_, undefined, this);

  goog.events.listen(sliderElement, goog.events.EventType.CLICK,
      this.handleContainerClick_, false, this);
  goog.events.listen(thumbElement, goog.events.EventType.CLICK,
      goog.events.Event.stopPropagation);

  goog.base(this, {
    element: sliderElement
  });
};
goog.inherits(ol.control.ZoomSlider, ol.control.Control);

/**
 * The enum for available directions.
 *
 * @enum {number}
 */
ol.control.ZoomSlider.direction = {
  VERTICAL: 0,
  HORIZONTAL: 1
};

/**
 * @inheritDoc
 */
ol.control.ZoomSlider.prototype.setMap = function(map) {
  goog.base(this, 'setMap', map);
  if (!goog.isNull(map)) {
    map.render();
  }
};

/**
 * Initializes the slider element. This will determine and set this controls
 * direction_ and also constrain the dragging of the thumb to always be within
 * the bounds of the container.
 *
 * @private
 */
ol.control.ZoomSlider.prototype.initSlider_ = function() {
  var container = this.element,
      thumb = goog.dom.getFirstElementChild(container),
      elemSize = goog.style.getContentBoxSize(container),
      thumbBounds = goog.style.getBounds(thumb),
      thumbMargins = goog.style.getMarginBox(thumb),
      thumbBorderBox = goog.style.getBorderBox(thumb),
      w = elemSize.width -
          thumbMargins.left - thumbMargins.right -
          thumbBorderBox.left - thumbBorderBox.right -
          thumbBounds.width,
      h = elemSize.height -
          thumbMargins.top - thumbMargins.bottom -
          thumbBorderBox.top - thumbBorderBox.bottom -
          thumbBounds.height,
      limits;
  if (elemSize.width > elemSize.height) {
    this.direction_ = ol.control.ZoomSlider.direction.HORIZONTAL;
    limits = new goog.math.Rect(0, 0, w, 0);
  } else {
    this.direction_ = ol.control.ZoomSlider.direction.VERTICAL;
    limits = new goog.math.Rect(0, 0, 0, h);
  }
  this.dragger_.setLimits(limits);
  this.sliderInitialized_ = true;
};

/**
 * @inheritDoc
 */
ol.control.ZoomSlider.prototype.handleMapPostrender = function(mapEvent) {
  if (goog.isNull(mapEvent.frameState)) {
    return;
  }
  goog.asserts.assert(
      goog.isDefAndNotNull(mapEvent.frameState.viewState));
  if (!this.sliderInitialized_) {
    this.initSlider_();
  }
  var res = mapEvent.frameState.viewState.resolution;
  if (res !== this.currentResolution_) {
    this.currentResolution_ = res;
    this.positionThumbForResolution_(res);
  }
};

/**
 * @param {goog.events.BrowserEvent} browserEvent The browser event to handle.
 * @private
 */
ol.control.ZoomSlider.prototype.handleContainerClick_ = function(browserEvent) {
  var map = this.getMap();
  var view = map.getView();
  var resolution;
  var amountDragged = this.amountDragged_(browserEvent.offsetX,
      browserEvent.offsetY);
  resolution = this.resolutionForAmount_(amountDragged);
  goog.asserts.assert(goog.isDef(resolution));
  map.beforeRender(ol.animation.zoom({
    resolution: resolution,
    duration: ol.ZOOMSLIDER_ANIMATION_DURATION,
    easing: ol.easing.easeOut
  }));
  resolution = view.constrainResolution(resolution);
  view.setResolution(resolution);
};

/**
 * Positions the thumb inside its container according to the given resolution.
 *
 * @param {number} res The res.
 * @private
 */
ol.control.ZoomSlider.prototype.positionThumbForResolution_ = function(res) {
  var amount = this.amountForResolution_(res),
      dragger = this.dragger_,
      thumb = goog.dom.getFirstElementChild(this.element);

  if (this.direction_ == ol.control.ZoomSlider.direction.HORIZONTAL) {
    var left = dragger.limits.left + dragger.limits.width * amount;
    goog.style.setPosition(thumb, left);
  } else {
    var top = dragger.limits.top + dragger.limits.height * amount;
    goog.style.setPosition(thumb, dragger.limits.left, top);
  }
};

/**
 * Calculates the amount the thumb has been dragged to allow for calculation
 * of the corresponding resolution.
 *
 * @param {number} x Pixel position relative to the left of the slider.
 * @param {number} y Pixel position relative to the top of the slider.
 * @return {number} The amount the thumb has been dragged.
 * @private
 */
ol.control.ZoomSlider.prototype.amountDragged_ = function(x, y) {
  var draggerLimits = this.dragger_.limits,
      amount = 0;
  if (this.direction_ === ol.control.ZoomSlider.direction.HORIZONTAL) {
    amount = (x - draggerLimits.left) / draggerLimits.width;
  } else {
    amount = (y - draggerLimits.top) / draggerLimits.height;
  }
  return amount;
};

/**
 * Calculates the corresponding resolution of the thumb by the amount it has
 * been dragged from its minimum.
 *
 * @param {number} amount The amount the thumb has been dragged.
 * @return {number} The corresponding resolution.
 * @private
 */
ol.control.ZoomSlider.prototype.resolutionForAmount_ = function(amount) {
  // FIXME do we really need this affine transform?
  amount = (goog.math.clamp(amount, 0, 1) - 1) * -1;
  var fn = this.getMap().getView().getResolutionForValueFunction();
  return fn(amount);
};

/**
 * Determines an amount of dragging relative to this minimum position by the
 * given resolution.
 *
 * @param {number} res The resolution to get the amount for.
 * @return {number} The corresponding value (between 0 and 1).
 * @private
 */
ol.control.ZoomSlider.prototype.amountForResolution_ = function(res) {
  var fn = this.getMap().getView().getValueForResolutionFunction();
  var value = fn(res);
  // FIXME do we really need this affine transform?
  return (value - 1) * -1;
};

/**
 * Handles the user caused changes of the slider thumb and adjusts the
 * resolution of our map accordingly. Will be called both while dragging and
 * when dragging ends.
 *
 * @param {goog.fx.DragDropEvent} e The dragdropevent.
 * @private
 */
ol.control.ZoomSlider.prototype.handleSliderChange_ = function(e) {
  var map = this.getMap();
  var view = map.getView();
  var resolution;
  if (e.type === goog.fx.Dragger.EventType.DRAG) {
    var amountDragged = this.amountDragged_(e.left, e.top);
    resolution = this.resolutionForAmount_(amountDragged);
    if (resolution !== this.currentResolution_) {
      this.currentResolution_ = resolution;
      view.setResolution(resolution);
    }
  } else {
    goog.asserts.assert(goog.isDef(this.currentResolution_));
    map.beforeRender(ol.animation.zoom({
      resolution: this.currentResolution_,
      duration: ol.ZOOMSLIDER_ANIMATION_DURATION,
      easing: ol.easing.easeOut
    }));
    resolution = view.constrainResolution(this.currentResolution_);
    view.setResolution(resolution);
  }
};
<|endoftext|>


<commit_before>'use strict';

function cdAgreementsService(cdApi){
  function topfail(err){
    console.log(err);
  }

  return {
    save: function(agreement, win, fail){
      debugger
      agreement = angular.copy(agreement);
      if (agreement.id) {
        cdApi.post('agreements/' + agreement.id, { agreement: agreement }, win, fail);
      }
      else {
        cdApi.post('agreements', { agreement: agreement }, win, fail || topfail);
      }
    },
    getAgreementsByIds: function(ids, win, fail){
      cdApi.post('agreements/list-by-ids', {usersIds: ids}, win, fail || topfail);
    },
    count: function(query, win, fail){
      cdApi.post('agreements/count', {query: query}, win, fail || topfail);
    }
  };
}

angular.module('cpZenPlatform')
  .service('cdAgreementsService', ['cdApi', cdAgreementsService]);
<commit_msg>cleanup<commit_after>'use strict';

function cdAgreementsService(cdApi){
  function topfail(err){
    console.log(err);
  }

  return {
    save: function(agreement, win, fail){
      agreement = angular.copy(agreement);
      cdApi.post('agreements', { agreement: agreement }, win, fail || topfail);
    },
    getAgreementsByIds: function(ids, win, fail){
      cdApi.post('agreements/list-by-ids', {usersIds: ids}, win, fail || topfail);
    },
    count: function(query, win, fail){
      cdApi.post('agreements/count', {query: query}, win, fail || topfail);
    }
  };
}

angular.module('cpZenPlatform')
  .service('cdAgreementsService', ['cdApi', cdAgreementsService]);
<|endoftext|>


<commit_before>Array.prototype.compare = function(arr) {
  if (this.length != arr.length) {
    return false;
  }
  var success = true, l = this.length, i = 0;
  for(i; i<l; i++) {
    if(arr.indexOf(this[i]) == -1) {
      success = false;
      break;
    }
  }
  return success;
};
Array.prototype.keyify = function(converted) {
  converted = typeof converted == 'boolean' ? converted : false;
  var r = [], i = 0, l = this.length;
  for(i; i<l; i++) {
    if (converted) {
      r.push(this[i].toString());
    } else {
      r.push($.keys.reverse(this[i]).toString());
    }
  }
  return r.sort().join('_');
};
a.keyify(true);
c.keyify(false);
a.compare(b);<commit_msg>[master] accidental addition of file<commit_after><|endoftext|>


<commit_before>'use strict';
var exports = module.exports = {};

var log = require('nodelog')();
var config = require('../config.json').services.employees;
var Job = require('../models/job');
var Employee = require('../models/employee');
var faker = require('faker');

log.info('initialize fakeDB module');

if (config.persistence.fakeDB.locale !== undefined) {
    faker.locale = config.persistence.fakeDB.locale;
}

var employeeDB;

//todo extract persistence to separate file for faker, mock and dynamo/couch
function provisionCreateAddress() {
    var street2;

    //randomize the street2 attribute
    if (Math.floor(Math.random() * 10) + 1 > 5) {
        street2 = faker.address.secondaryAddress();
    }

    return {
        country: faker.address.country(),
        city: faker.address.city(),
        zipcode: faker.address.zipCode(),
        street: faker.address.streetAddress(),
        street2: street2,
        geo: {
            latitude: faker.address.latitude(),
            longitude: faker.address.longitude()
        }
    };
}

function provisionCreateJobHistory(dateOfBirth) {
    var jh = [];
    //TODO: create maximum age-18 / 2 jobs
    //use a randomized count between 0 and 7
    var companycount = Math.floor(Math.random() * 7) /*+ 1 activate if we want at least one*/ ;
    for (var i = 0; i < companycount; i++) {
        //TODO date start should be min last year
        var ds = faker.date.past(40, new Date());
        //TODO date end can be maximum today - 4 weeks
        var de = faker.date.future(20, new Date(ds));
        jh.push({
            id: (i + 1) + '',
            companyName: faker.company.companyName() + ' ' + faker.company.companySuffix(),
            department: faker.name.jobArea(),
            jobTitle: faker.name.title(),
            dateStart: ds,
            dateEnd: de,
            address: provisionCreateAddress()
        });
    }
    return jh;
}

function provisionCreateEmployee() {
    var dob = faker.date.past(40, new Date('Sat Apr 01 1998 21:35:02 GMT+0200 (CEST)'));
    return {
        firstName: faker.name.firstName(),
        lastName: faker.name.lastName(),
        phone: faker.phone.phoneNumber(),

        imageUrl: faker.image.avatar(),
        jobTitle: faker.name.title(),
        department: faker.name.jobArea(),
        dateOfBirth: dob,

        address: provisionCreateAddress(),
        jobHistory: provisionCreateJobHistory(dob)
    };
}

function createFakeData() {
    log.info('fakeDB.createFakeData');
    if (employeeDB === undefined) {
        employeeDB = [];
        for (var i = 0; i < config.persistence.fakeDB.employeeCount; i++) {
            var e = new Employee(provisionCreateEmployee());
            employeeDB.push(e);
        }
    }
    //define one fixed username for testing and developing purposes
    employeeDB[employeeDB.length - 1].userName = 'testuser';
    return employeeDB;
}

createFakeData();

// **************************************************************************
// Data Manipulation
// **************************************************************************

function getAllEmployees() {
    return employeeDB;
}

//returnUndefined not set or false --> function will throw an error if user was not found
function getEmployeeByUserName(userName, returnUndefined) {
    log.info('database.getEmployeeByUserName');

    var retVal;
    for (let emp of employeeDB) {
        //db.getAllEmployees().foreach(function(emp) {
        if (emp.userName === userName) {
            retVal = emp;
            break;
        }
    }
    if (retVal === undefined && !returnUndefined) {
        throw new Error(userName + ' not found');
    }
    return retVal;
}

function getJobByUserNameAndId(userName, jobId) {
    log.info('database.getJobByUserNameAndId');

    var retVal;
    var jh = getEmployeeByUserName(userName).jobHistory;
    for (let job of jh) {
        log.debug('check ', JSON.stringify(job));
        jobId = jobId + ''; //convert to string
        if (job.id === jobId) {
            log.debug('found job');
            retVal = job;
            break;
        }
    }
    if (retVal === undefined) {
        throw new Error('user ' + userName + ' has no job ' + jobId + '');
    }
    return retVal;
}

function createEmployee(employee) {
    log.info('database.createEmployee');
    if (employee instanceof Employee) {
        if (getEmployeeByUserName(employee.userName, true) !== undefined) {
            throw new Error('a user with the specified username already exists');
        }
        employeeDB.push(employee);
    } else {
        throw new Error('expected Employee object');
    }

}

function deleteEmployee(userName) {
    log.info('database.deleteEmployee');

    for (var i = 0; i < employeeDB.length; i++) {
        //db.getAllEmployees().foreach(function(emp) {
        if (employeeDB[i].userName === userName) {
            employeeDB.splice(i, 1);
            break;
        }
    }
}

function createJob(userName, job) {
    log.info('database.createEmployee');
    if (job instanceof Job) {
        var jh = getEmployeeByUserName(userName).jobHistory;
        jh.push(job);
    } else {
        throw new Error('expected Employee object');
    }

}

function deleteJob(userName, jobId) {
    log.info('database.deleteJob');

    var jh = getEmployeeByUserName(userName).jobHistory;
    for (var i = 0; i < jh.length; i++) {
        if (jh[i].id === jobId) {
            jh.splice(i, 1);
            break;
        }
    }
}

//TODO: create a object for database instead of module
exports.getEmployeeByUserName = getEmployeeByUserName;
exports.getAllEmployees = getAllEmployees;
exports.createEmployee = createEmployee;
exports.deleteEmployee = deleteEmployee;

exports.getJobByUserNameAndId = getJobByUserNameAndId;
exports.createJob = createJob;
exports.deleteJob = deleteJob;
<commit_msg>Integrate reset function for database which may become an endpoint for cron based resets<commit_after>'use strict';
var exports = module.exports = {};

var log = require('nodelog')();
var config = require('../config.json').services.employees;
var Job = require('../models/job');
var Employee = require('../models/employee');
var faker = require('faker');

log.info('initialize fakeDB module');

if (config.persistence.fakeDB.locale !== undefined) {
    faker.locale = config.persistence.fakeDB.locale;
}

var employeeDB;

//todo extract persistence to separate file for faker, mock and dynamo/couch
function provisionCreateAddress() {
    var street2;

    //randomize the street2 attribute
    if (Math.floor(Math.random() * 10) + 1 > 5) {
        street2 = faker.address.secondaryAddress();
    }

    return {
        country: faker.address.country(),
        city: faker.address.city(),
        zipcode: faker.address.zipCode(),
        street: faker.address.streetAddress(),
        street2: street2,
        geo: {
            latitude: faker.address.latitude(),
            longitude: faker.address.longitude()
        }
    };
}

function provisionCreateJobHistory(dateOfBirth) {
    var jh = [];
    //TODO: create maximum age-18 / 2 jobs
    //use a randomized count between 0 and 7
    var companycount = Math.floor(Math.random() * 7) /*+ 1 activate if we want at least one*/ ;
    for (var i = 0; i < companycount; i++) {
        //TODO date start should be min last year
        var ds = faker.date.past(40, new Date());
        //TODO date end can be maximum today - 4 weeks
        var de = faker.date.future(20, new Date(ds));
        jh.push({
            id: (i + 1) + '',
            companyName: faker.company.companyName() + ' ' + faker.company.companySuffix(),
            department: faker.name.jobArea(),
            jobTitle: faker.name.title(),
            dateStart: ds,
            dateEnd: de,
            address: provisionCreateAddress()
        });
    }
    return jh;
}

function provisionCreateEmployee() {
    var dob = faker.date.past(40, new Date('Sat Apr 01 1998 21:35:02 GMT+0200 (CEST)'));
    return {
        firstName: faker.name.firstName(),
        lastName: faker.name.lastName(),
        phone: faker.phone.phoneNumber(),

        imageUrl: faker.image.avatar(),
        jobTitle: faker.name.title(),
        department: faker.name.jobArea(),
        dateOfBirth: dob,

        address: provisionCreateAddress(),
        jobHistory: provisionCreateJobHistory(dob)
    };
}

function createFakeData(count) {
    log.info('fakeDB.createFakeData');
    if (employeeDB === undefined) {
        employeeDB = [];
    }
    if (employeeDB.length === 0) {
        for (var i = 0; i < count; i++) {
            var e = new Employee(provisionCreateEmployee());
            employeeDB.push(e);
        }
    }
    //define one fixed username for testing and developing purposes
    employeeDB[employeeDB.length - 1].userName = 'testuser';
    return employeeDB;
}

createFakeData(config.persistence.fakeDB.employeeCount);

// **************************************************************************
// Data Manipulation
// **************************************************************************

function getAllEmployees() {
    return employeeDB;
}

//returnUndefined not set or false --> function will throw an error if user was not found
function getEmployeeByUserName(userName, returnUndefined) {
    log.info('database.getEmployeeByUserName');

    var retVal;
    for (let emp of employeeDB) {
        //db.getAllEmployees().foreach(function(emp) {
        if (emp.userName === userName) {
            retVal = emp;
            break;
        }
    }
    if (retVal === undefined && !returnUndefined) {
        throw new Error(userName + ' not found');
    }
    return retVal;
}

function getJobByUserNameAndId(userName, jobId) {
    log.info('database.getJobByUserNameAndId');

    var retVal;
    var jh = getEmployeeByUserName(userName).jobHistory;
    for (let job of jh) {
        log.debug('check ', JSON.stringify(job));
        jobId = jobId + ''; //convert to string
        if (job.id === jobId) {
            log.debug('found job');
            retVal = job;
            break;
        }
    }
    if (retVal === undefined) {
        throw new Error('user ' + userName + ' has no job ' + jobId + '');
    }
    return retVal;
}

function createEmployee(employee) {
    log.info('database.createEmployee');
    if (employee instanceof Employee) {
        if (getEmployeeByUserName(employee.userName, true) !== undefined) {
            throw new Error('a user with the specified username already exists');
        }
        employeeDB.push(employee);
    } else {
        throw new Error('expected Employee object');
    }

}

function deleteEmployee(userName) {
    log.info('database.deleteEmployee');

    for (var i = 0; i < employeeDB.length; i++) {
        //db.getAllEmployees().foreach(function(emp) {
        if (employeeDB[i].userName === userName) {
            employeeDB.splice(i, 1);
            break;
        }
    }
}

function createJob(userName, job) {
    log.info('database.createEmployee');
    if (job instanceof Job) {
        var jh = getEmployeeByUserName(userName).jobHistory;
        jh.push(job);
    } else {
        throw new Error('expected Employee object');
    }

}

function deleteJob(userName, jobId) {
    log.info('database.deleteJob');

    var jh = getEmployeeByUserName(userName).jobHistory;
    for (var i = 0; i < jh.length; i++) {
        if (jh[i].id === jobId) {
            jh.splice(i, 1);
            break;
        }
    }
}

exports.resetData = function (count) {
    employeeDB = [];
    createFakeData(count);
};

//TODO: create a object for database instead of module
exports.getEmployeeByUserName = getEmployeeByUserName;
exports.getAllEmployees = getAllEmployees;
exports.createEmployee = createEmployee;
exports.deleteEmployee = deleteEmployee;

exports.getJobByUserNameAndId = getJobByUserNameAndId;
exports.createJob = createJob;
exports.deleteJob = deleteJob;
<|endoftext|>


<commit_before>/*global define */
/*jslint white: true, browser: true */
define([
    'kb/common/html',
    'kb/data/genomeAnnotation',
    'kb/data/taxon',
    'kb/data/assembly',
    '../utils',
    'bluebird',
    'jquery',
    'underscore'
],
    function (html, GenomeAnnotation, Taxon, Assembly, utils, bluebird, $, _) {
        'use strict';

        //http://localhost:8080/#dataview/1779/1006539/1
        function factory(config) {
            var parent, container, runtime = config.runtime,
                div = html.tag('div'),
                templates = {
                    overview: "
"
                            + "
"
                            + "
"
                            + "
NCBI taxonomic ID
"
                            + "
Scientific name
"
                            + "
Kingdom
"
                            + "
Genetic Code
"
                            + "
"
                            + "
"
                            + "
Aliases
"
                            + "

"
                            + "
"
                            + "
"
                            + "
"
                            + "
"
                            + "
",
                    additionalInfo: "
"
                                  + "
"
                                  + "
"
                                  + "

"
                                  + "

"
                                  + "
"
                                  + "
"
                                  + "

"
                                  + "
"
                                  + "
"
                                  + "
"
                };

            // VIEW

            function layout() {
                return div([
                    html.makePanel({
                        title: 'Summary',
                        content: div({id: 'overview'}, templates.overview)
                    }),
                    html.makePanel({
                        title: 'Children Taxons',
                        content: div({id: 'taxonChildren'}, html.loading())
                    }),
                    html.makePanel({
                        title: 'Additional Information for this Taxon',
                        content: div({id: 'moreTaxonInfo'}, templates.additionalInfo)
                    })
                ]);
            }

            function setDataElementHTML(element, value) {
                try {
                    container.querySelector("[data-element='" + element + "']").innerHTML = value;
                }
                catch (err) {
                    console.error('while setting data element "' + element + '":', err);
                    throw err;
                }
            }

            function renderLineage(name, name_lineage, ref_lineage) {
                var list_o_links = [], i, len = name_lineage.length;

                for (i = 0; i < len; i+=1) {
                    list_o_links.push("
"
                                    + ""
                                    + name_lineage[i] + "
");
                }
                list_o_links.push("
" + name + "
");

                setDataElementHTML('lineage', div([div("
Lineage
"),
                                                   div(list_o_links)]));
            }

            function renderAliases(aliases) {
                var alias_divs = [], i, len = aliases.length;

                for (i = 0; i < len; i+=1) {
                    alias_divs.push("
" + aliases[i] + "
");
                }
                setDataElementHTML('aliases', alias_divs.join(""));
            }

            function renderChildren(info) {
                var list_o_links = [],
                    i,
                    len = info.length,
                    sorted = info.sort(function (a,b) { return a[0].toLowerCase() > b[0].toLowerCase(); });

                for (i = 0; i < len; i+=1) {
                    list_o_links.push("
"
                                    + sorted[i][0] + "
");
                }

                container.querySelector('div[id="taxonChildren"]').innerHTML = div(list_o_links);
            }

            function renderNCBILink(taxid) {
                setDataElementHTML('ncbi-id',
                                   "" + taxid + "");
            }

            function renderWikipediaEntry(wikiInfo) {
                if (wikiInfo === null || wikiInfo.link === undefined) {
                    setDataElementHTML('wiki_url', "No Wikipedia entry found for this Taxon");
                }
                else {
                    setDataElementHTML('wiki_url',
                                       "Wikipedia entry for this Taxon");
                }

                if (wikiInfo === null || wikiInfo.extract === undefined) {
                    setDataElementHTML('wikipedia_text', 'No text found');
                }
                else {
                    setDataElementHTML('wikipedia_text', wikiInfo.extract);
                }
            }

            function renderWikipediaImage(imageURL) {
                if (imageURL === null) {
                    setDataElementHTML('wikipedia_image', 'No image found');
                }
                else {
                    setDataElementHTML('wikipedia_image', "");
                }
            }

            /**
             * Return copy of string with rightmost space-separated token removed.
             *
             * @param s
             */
            function removeLastToken(s) {
                if (s == '') {
                    return ''
                }
                var a = s.split(' ');
                if (a.length <= 1) {
                    return ''
                }
                return _.initial(a).join(' ');
            }

            // WIDGET API

            function attach(node) {
                parent = node;
                container = parent.appendChild(document.createElement('div'));
                container.innerHTML = layout();
            }

            function start(params) {
                /* Need to create the taxon client object here because it requires params.
                 * The params is determined by the dataview route, which makes
                 * available:
                 *   workspaceId
                 *   objectId
                 *   objectVersion
                 *   ...
                 */

                var taxon_ref = utils.getRef(params),
                    taxon,
                    scientific_name,
                    wikiInfo;

                Array.from(container.querySelectorAll("[data-element]")).forEach(function (e) {
                    e.innerHTML = html.loading();
                });

                var wiki_api_url = "https://en.wikipedia.org/w/api.php?";

                /**
                 * Get text and image from wikipedia.
                 *
                 * Calls: fetchWikipediaData, fetchWikipediaImage
                 *
                 * @param name Scientific name
                 * @returns {*}
                 */
                function fetchWikipediaEntry(name) {
                    //console.debug('fetchWikipediaEntry name="' + name + '"');
                    return fetchWikipediaData(name)
                        .then(function(data){
                            return fetchWikipediaImage(data);
                        })
                        .catch(function (err) {
                            console.error('while fetching wikipedia entry for "' + name + '":', err);
                            return false;
                        });
                }

                /**
                 * Look for the organism in wikipedia, and fetch the JSON
                 * version of the basic information.
                 *
                 * @param name
                 * @returns {*}
                 */
                function fetchWikipediaData(name) {
                    var query_params = "action=query&list=search&format=json"
                            + "&srwhat=text&srsearch=",
                        wiki_request_url = wiki_api_url + query_params + name; // "&callback=?";

                    //console.debug('Call Wikipedia url="' + wiki_request_url + '"');

                    return bluebird.resolve($.ajax({
                            url: wiki_request_url,
                            data: {format: 'json'},
                            dataType: 'jsonp'
                        }))
                        .then(function (data) {
                            // If nothing was found, try stripping the last token and
                            // re-issuing the query.
                            if (data.query.search.length == 0) {
                                var name2 = removeLastToken(name);
                                //console.debug('Stripped scientific name "' + name + '" down to "' + name2 + '"');
                                if (name2 == '') {
                                    throw new Error('No page found on Wikipedia for "' + name2 + '"');
                                }
                                data = fetchWikipediaData(name2);
                            }
                            return data;
                        });
                }

                /**
                 * Get wikipedia image info and add to the base wikipedia info.
                 *
                 * @param data Result object from fetchWikipediaData()
                 * @returns {object} Object with properties 'extract', 'image', and 'link'
                 */
                function fetchWikipediaImage(data) {
                    var query = data.query,
                        title = query.search[0].title,
                        query_params = "action=query&prop=extracts|pageimages|imageinfo|images|info|pageimages|pageprops"
                            + "&format=json&exlimit=1&exintro=&piprop=name"
                            + "&inprop=url&indexpageids=&titles=",
                        wiki_request_url = wiki_api_url + query_params + title;

                    return bluebird.resolve(
                        $.ajax({
                        url: wiki_request_url, // + "&callback=?",
                        data: {format: 'json'},
                        dataType: 'jsonp'
                        }).then(function (data) {
                            //console.debug('Images callback, data:', data);
                            var pageid = data.query.pageids[0];
                            return {
                                extract: data.query.pages[pageid].extract,
                                image: data.query.pages[pageid].pageimage,
                                link: data.query.pages[pageid].fullurl
                            };
                        })
                    ).catch (function(err) {
                        console.error('while fetching wikipedia image at "' + wiki_request_url + '":', err);
                        return {
                            extract: undefined,
                            image: undefined,
                            link: undefined
                        };
                    });
                }

                /**
                 * Get image data from Wikipedia
                 *
                 * @param name The canonical name for the page.
                 * @returns {*}
                 */
                function fetchWikipediaImageURL(name) {
                    if (name === undefined) {
                        return null;
                    }
                    var query_params = "action=query&prop=pageimages|imageinfo"
                            + "&indexpageids&iiprop=url&pithumbsize=600w&titles=Image:",
                        wiki_request_url = wiki_api_url + query_params + name + "&callback=?";

                    return bluebird.resolve($.ajax({
                            url: wiki_request_url,
                            data: { format: 'json' },
                            dataType: 'jsonp'
                        }))
                        .then(function (data) {
                            //console.debug("FetchWikipediaImage data:",data);
                            var pageid = data.query.pageids[0];
                            return data.query.pages[pageid].thumbnail.source;
                        })
                        .catch(function (err) {
                            console.error('while fetching wikipedia image at "' + wiki_request_url + '":', err);
                            return null;
                        });
                }

                function getTaxonClient(ref) {
                    return Taxon.client({
                        url: runtime.getConfig('services.taxon_api.url'),
                        token: runtime.service('session').getAuthToken(),
                        ref: ref,
                        timeout: 900000
                    });
                }

                taxon = getTaxonClient(taxon_ref);

                return taxon.scientific_name().then(function (scientificName) {
                        setDataElementHTML('scientific-name', scientificName);
                        scientific_name = scientificName;
                        return fetchWikipediaEntry(scientificName);
                    })
                    .then(function (wiki_content) {
                        wikiInfo = wiki_content;
                        if (wikiInfo === false) {
                            //console.debug('No wikiInfo');
                            renderWikipediaEntry(null);
                            return false;
                        }
                        else {
                            renderWikipediaEntry(wikiInfo);
                        }
                        return fetchWikipediaImageURL(wikiInfo.image);
                    })
                    .then(function (wikiImage) {
                        if (wikiImage === null) {
                            renderWikipediaImage(null);
                        }
                        else {
                            renderWikipediaImage(wikiImage);
                        }
                        return taxon.scientific_lineage();
                    })
                    .then(function (lineage) {
                        var refLineage = [];

                        /*
                         * Call get_parent() and collect the reference until undefined is returned from the client.
                         * At that point, remove the 'root' reference and return the name lineage and reference lineage.
                         **/
                        function recursiveGetParent(t) {
                            return t.parent().then(function (parent_ref) {
                                if (parent_ref !== undefined) {
                                    refLineage.unshift(parent_ref);
                                    return recursiveGetParent(getTaxonClient(parent_ref));
                                }
                                else {
                                    // remove the 'root' element
                                    refLineage.splice(0,1);
                                    return [lineage, refLineage];
                                }
                            });
                        }

                        return recursiveGetParent(taxon);
                    })
                    .then(function(lineages) {
                        renderLineage(scientific_name, lineages[0], lineages[1]);
                        return taxon.kingdom();
                    })
                    .then(function(kingdom) {
                        setDataElementHTML('kingdom', kingdom);
                        return taxon.taxonomic_id();
                    })
                    .then(function(taxid) {
                        renderNCBILink(taxid);
                        return taxon.genetic_code();
                    })
                    .then(function(geneticCode) {
                        setDataElementHTML('genetic-code', geneticCode);
                        return taxon.aliases();
                    })
                    .then(function(aliases) {
                        renderAliases(aliases);
                        return taxon.children();
                    })
                    .then(function(children_refs) {
                        // join together all the promises into a single array of child taxon info
                        return bluebird.all(children_refs.map(function (ref) {
                            return getTaxonClient(ref).scientific_name().then(function (name) {
                                return [name, ref];
                            });
                        }));
                    })
                    .then(function (childrenInfo) {
                        renderChildren(childrenInfo);
                    })
                    .catch(function (err) {
                        console.error(err);
                    });
            }

            function stop() {
                // nothing to do
            }

            function detach() {
                // nothing to do necessarily, since the parent dom node will
                // be removed the controller for this widget removes it,
                // but it is nice to take responsibility for undoing what we
                // changed in the parent node:
                if (parent && container) {
                    container.innerHTML = '';
                    parent.removeChild(container);
                }
            }

            return Object.freeze({
                attach: attach,
                start: start,
                stop: stop,
                detach: detach
            });
        }

        return {
            make: function (config) {
                return factory(config);
            }
        };
    });<commit_msg>update taxon page to new data api dynamic service, plus some performance improvements<commit_after>/*global define */
/*jslint white: true, browser: true */
define([
    'kb/common/html',
    'kb_sdk_clients/GenomeAnnotationAPI/dev/GenomeAnnotationAPIClient',
    'kb_sdk_clients/TaxonAPI/dev/TaxonAPIClient',
    'kb_sdk_clients/AssemblyAPI/dev/AssemblyAPIClient',
    'kb/service/client/workspace',
    '../utils',
    'bluebird',
    'jquery',
    'underscore',
    'datatables',
    'datatables_bootstrap',
],
    function (html, GenomeAnnotation, Taxon, Assembly, Workspace, utils, bluebird, $, _, DataTable) {
        'use strict';

        //http://localhost:8080/#dataview/1779/1006539/1
        function factory(config) {
            var parent, container, runtime = config.runtime,
                div = html.tag('div'),
                templates = {
                    overview: "
"
                            + "
"
                            + "
"
                            + "
NCBI taxonomic ID
"
                            + "
Scientific name
"
                            /* KINGDOM IS ALWAYS MISSING IN DATA!! + "
Kingdom
" */
                            + "
Domain
"
                            + "
Genetic Code
"
                            + "
"
                            + "
"
                            + "
Aliases
"
                            + "

"
                            + "
"
                            + "
"
                            + "
"
                            + "
"
                            + "
",
                    additionalInfo: "
"
                                  + "
"
                                  + "
"
                                  + "

"
                                  + "

"
                                  + "
"
                                  + "
"
                                  + "

"
                                  + "
"
                                  + "
"
                                  + "
"
                };

            // VIEW

            function layout() {
                return div([
                    html.makePanel({
                        title: 'Summary',
                        content: div({id: 'overview'}, templates.overview)
                    }),
                    html.makePanel({
                        title: 'Children Taxons',
                        content: div({id: 'taxonChildren'}, html.loading())
                    }),
                    html.makePanel({
                        title: 'Additional Information for this Taxon',
                        content: div({id: 'moreTaxonInfo'}, templates.additionalInfo)
                    })
                ]);
            }

            function setDataElementHTML(element, value) {
                try {
                    container.querySelector("[data-element='" + element + "']").innerHTML = value;
                }
                catch (err) {
                    console.error('while setting data element "' + element + '":', err);
                    throw err;
                }
            }

            function renderLineage(decorated_lineage, my_scientific_name) {
                var list_o_links = [], i, len = decorated_lineage.length;

                for (i = 0; i < len; i+=1) {
                    list_o_links.push("
"
                                    + ""
                                    + decorated_lineage[i]['scientific_name'] + "
");
                }
                list_o_links.push("
" + my_scientific_name + "
");

                setDataElementHTML('lineage', div([div("
Lineage
"),
                                                   div(list_o_links)]));
            }

            function renderAliases(aliases) {
                var alias_divs = [], i, len = aliases.length;

                for (i = 0; i < len; i+=1) {
                    alias_divs.push("
" + aliases[i] + "
");
                }
                if(len>0) {
                    setDataElementHTML('aliases', alias_divs.join(""));
                } else {
                    setDataElementHTML('aliases', 'None');
                }
            }

            function renderChildren(decorated_children) {
                var list_o_links = [],
                    i,
                    len = decorated_children.length,
                    sorted_children = decorated_children.sort(
                                            function (a,b) {
                                                return a['scientific_name'].toLowerCase() > b['scientific_name'].toLowerCase();
                                            });

                for (i = 0; i < len; i+=1) {
                    list_o_links.push("
"
                                    + sorted_children[i]['scientific_name'] + "
");
                }

                if(len>0) {
                    container.querySelector('div[id="taxonChildren"]').innerHTML = div(list_o_links);
                } else {
                    container.querySelector('div[id="taxonChildren"]').innerHTML = div('None');
                }
            }

            function renderNCBILink(taxid) {
                setDataElementHTML('ncbi-id',
                                   "" + taxid + "");
            }

            function renderWikipediaEntry(wikiInfo) {
                if (wikiInfo === null || wikiInfo.link === undefined) {
                    setDataElementHTML('wiki_url', "No Wikipedia entry found for this Taxon");
                }
                else {
                    setDataElementHTML('wiki_url',
                                       "Wikipedia entry for this Taxon");
                }

                if (wikiInfo === null || wikiInfo.extract === undefined) {
                    setDataElementHTML('wikipedia_text', 'No text found');
                }
                else {
                    setDataElementHTML('wikipedia_text', wikiInfo.extract);
                }
            }

            function renderWikipediaImage(imageURL) {
                if (imageURL === null) {
                    setDataElementHTML('wikipedia_image', 'No image found');
                }
                else {
                    setDataElementHTML('wikipedia_image', "");
                }
            }

            /**
             * Return copy of string with rightmost space-separated token removed.
             *
             * @param s
             */
            function removeLastToken(s) {
                if (s == '') {
                    return ''
                }
                var a = s.split(' ');
                if (a.length <= 1) {
                    return ''
                }
                return _.initial(a).join(' ');
            }

            // WIDGET API

            function attach(node) {
                parent = node;
                container = parent.appendChild(document.createElement('div'));
                container.innerHTML = layout();
            }

            function start(params) {
                /* Need to create the taxon client object here because it requires params.
                 * The params is determined by the dataview route, which makes
                 * available:
                 *   workspaceId
                 *   objectId
                 *   objectVersion
                 *   ...
                 */

                var taxon_ref = utils.getRef(params),
                    scientific_name,
                    wikiInfo;

                Array.from(container.querySelectorAll("[data-element]")).forEach(function (e) {
                    e.innerHTML = html.loading();
                });

                var wiki_api_url = "https://en.wikipedia.org/w/api.php?";

                /**
                 * Get text and image from wikipedia.
                 *
                 * Calls: fetchWikipediaData, fetchWikipediaImage
                 *
                 * @param name Scientific name
                 * @returns {*}
                 */
                function fetchWikipediaEntry(name) {
                    //console.debug('fetchWikipediaEntry name="' + name + '"');
                    return fetchWikipediaData(name)
                        .then(function(data){
                            return fetchWikipediaImage(data);
                        })
                        .catch(function (err) {
                            console.error('while fetching wikipedia entry for "' + name + '":', err);
                            return false;
                        });
                }

                /**
                 * Look for the organism in wikipedia, and fetch the JSON
                 * version of the basic information.
                 *
                 * @param name
                 * @returns {*}
                 */
                function fetchWikipediaData(name) {
                    var query_params = "action=query&list=search&format=json"
                            + "&srwhat=text&srsearch=",
                        wiki_request_url = wiki_api_url + query_params + name; // "&callback=?";

                    //console.debug('Call Wikipedia url="' + wiki_request_url + '"');

                    return bluebird.resolve($.ajax({
                            url: wiki_request_url,
                            data: {format: 'json'},
                            dataType: 'jsonp'
                        }))
                        .then(function (data) {
                            // If nothing was found, try stripping the last token and
                            // re-issuing the query.
                            if (data.query.search.length == 0) {
                                var name2 = removeLastToken(name);
                                //console.debug('Stripped scientific name "' + name + '" down to "' + name2 + '"');
                                if (name2 == '') {
                                    throw new Error('No page found on Wikipedia for "' + name2 + '"');
                                }
                                data = fetchWikipediaData(name2);
                            }
                            return data;
                        });
                }

                /**
                 * Get wikipedia image info and add to the base wikipedia info.
                 *
                 * @param data Result object from fetchWikipediaData()
                 * @returns {object} Object with properties 'extract', 'image', and 'link'
                 */
                function fetchWikipediaImage(data) {
                    var query = data.query,
                        title = query.search[0].title,
                        query_params = "action=query&prop=extracts|pageimages|imageinfo|images|info|pageimages|pageprops"
                            + "&format=json&exlimit=1&exintro=&piprop=name"
                            + "&inprop=url&indexpageids=&titles=",
                        wiki_request_url = wiki_api_url + query_params + title;

                    return bluebird.resolve(
                        $.ajax({
                        url: wiki_request_url, // + "&callback=?",
                        data: {format: 'json'},
                        dataType: 'jsonp'
                        }).then(function (data) {
                            //console.debug('Images callback, data:', data);
                            var pageid = data.query.pageids[0];
                            return {
                                extract: data.query.pages[pageid].extract,
                                image: data.query.pages[pageid].pageimage,
                                link: data.query.pages[pageid].fullurl
                            };
                        })
                    ).catch (function(err) {
                        console.error('while fetching wikipedia image at "' + wiki_request_url + '":', err);
                        return {
                            extract: undefined,
                            image: undefined,
                            link: undefined
                        };
                    });
                }

                /**
                 * Get image data from Wikipedia
                 *
                 * @param name The canonical name for the page.
                 * @returns {*}
                 */
                function fetchWikipediaImageURL(name) {
                    if (name === undefined) {
                        return null;
                    }
                    var query_params = "action=query&prop=pageimages|imageinfo"
                            + "&indexpageids&iiprop=url&pithumbsize=600w&titles=Image:",
                        wiki_request_url = wiki_api_url + query_params + name + "&callback=?";

                    return bluebird.resolve($.ajax({
                            url: wiki_request_url,
                            data: { format: 'json' },
                            dataType: 'jsonp'
                        }))
                        .then(function (data) {
                            //console.debug("FetchWikipediaImage data:",data);
                            var pageid = data.query.pageids[0];
                            return data.query.pages[pageid].thumbnail.source;
                        })
                        .catch(function (err) {
                            console.error('while fetching wikipedia image at "' + wiki_request_url + '":', err);
                            return null;
                        });
                }

                function getTaxonClient() {
                    return new Taxon({
                        url: runtime.getConfig('services.service_wizard.url'),
                        auth: {token: runtime.service('session').getAuthToken() },
                        version: 'release'
                    });
                }

                var taxon = getTaxonClient();
                var loadingCalls = [];

                var scientificName;

                // Call 1: do most the work, and kick off the scientific lineage + wikipedia fetching
                loadingCalls.push(
                    taxon.get_all_data({ ref:taxon_ref, exclude_children:1 })
                            .then(function(data) {
                                console.log('Taxonomy data', data);
                                scientificName = data['scientific_name'];

                                setDataElementHTML('scientific-name', scientificName);

                                /* KINGDOM IS ALWAYS MISSING IN DATA --setDataElementHTML('kingdom', data['kingdom']); */
                                setDataElementHTML('domain', data['domain']);
                                renderNCBILink(data['taxonomic_id']);
                                setDataElementHTML('genetic-code', data['genetic_code']);

                                renderAliases(data['aliases']);

                                return taxon.get_decorated_scientific_lineage({ ref:taxon_ref });
                            })
                            .then(function(lineage) {
                                renderLineage(lineage['decorated_scientific_lineage'], scientificName)

                                return fetchWikipediaEntry(scientificName);
                            })
                            .then(function (wiki_content) {
                                wikiInfo = wiki_content;
                                if (wikiInfo === false) {
                                    //console.debug('No wikiInfo');
                                    renderWikipediaEntry(null);
                                    return false;
                                }
                                else {
                                    renderWikipediaEntry(wikiInfo);
                                }
                                return fetchWikipediaImageURL(wikiInfo.image);
                            })
                            .then(function (wikiImage) {
                                if (wikiImage === null) {
                                    renderWikipediaImage(null);
                                }
                                else {
                                    renderWikipediaImage(wikiImage);
                                }
                            }));

                // Call 3: get the decorated children
                loadingCalls.push(
                    taxon.get_decorated_children({ ref:taxon_ref })
                            .then(function(lineage) {
                                renderChildren(lineage['decorated_children'])
                            }));

                return Promise.all(loadingCalls)
                            .catch(function(err) {
                                console.error(err);
                            });
            }

            function stop() {
                // nothing to do
            }

            function detach() {
                // nothing to do necessarily, since the parent dom node will
                // be removed the controller for this widget removes it,
                // but it is nice to take responsibility for undoing what we
                // changed in the parent node:
                if (parent && container) {
                    container.innerHTML = '';
                    parent.removeChild(container);
                }
            }

            return Object.freeze({
                attach: attach,
                start: start,
                stop: stop,
                detach: detach
            });
        }

        return {
            make: function (config) {
                return factory(config);
            }
        };
    });<|endoftext|>


<commit_before>export default function({ variants }) {
  return function({ addUtilities }) {
    addUtilities(
      {
        '.bg-fixed': { 'background-attachment': 'fixed' },
        '.bg-local': { 'background-attachment': 'local' },
        '.bg-scroll': { 'background-attachment': 'scroll' },
      },
      variants
    )
  }
}
<commit_msg>Source backgroundAttachment options from config<commit_after>export default function() {
  return function({ addUtilities, config }) {
    addUtilities(
      {
        '.bg-fixed': { 'background-attachment': 'fixed' },
        '.bg-local': { 'background-attachment': 'local' },
        '.bg-scroll': { 'background-attachment': 'scroll' },
      },
      config('variants.backgroundAttachment')
    )
  }
}
<|endoftext|>


<commit_before>/*
    TODO: Faire un concreteiamgeselector (celui-ci étant un conceptualImageSelector)..
    renommer les fichiers et faire les mod. nécessaires
    ou faire comme pour image-dialog et faire en sorte que ce widget retourne un objet du genre
    {
        conceptualImage: conceptualImage,
        concreteImage: concreteImage,
        imageForLineups: bool //
    }
*/

define(['text!./rc.component.image-picker.html', 'jquery', 'knockout-utilities', 'dialoger', 'knockout', 'configs'],
    function(template, $, knockoutUtilities, dialoger, ko, configs) {
        "use strict";

        var ViewModel = function(params, componentInfo) {
            var self = this;

            var imagesBasePath = (configs.baseUrl || '/') + 'bower_components/rc.component.image-picker/src/images/';

            //todo: should we throw instead?
            if (configs.imagePicker && configs.imagePicker.imagesBasePath) {
                imagesBasePath = configs.imagePicker.imagesBasePath;
            }

            self.focused = ko.observable(false);
            self.imageUrl = params.image;

            if (!self.imageUrl()) {
                self.imageUrl(imagesBasePath + 'choisir2.png');
            }
        };

        ViewModel.prototype.selectImage = function(model, jQueryEvent) {
            var self = this;

            if (!ko.components.isRegistered('images-dialog')) {
                dialoger.registerDialog('images', {
                    title: 'Select an image',
                    basePath: 'bower_components/rc.component.image-picker/src'
                });
            }

            dialoger.showDialog('images').then(function(imageUrl) {
                if (imageUrl) {
                    self.imageUrl(imageUrl);
                }

                self.focused(true);
            });
        };

        return {
            viewModel: {
                createViewModel: function(params, componentInfo) {
                    return new ViewModel(params, componentInfo);
                }
            },
            template: template
        };
    });
<commit_msg>show pour showdialog<commit_after>/*
    TODO: Faire un concreteiamgeselector (celui-ci étant un conceptualImageSelector)..
    renommer les fichiers et faire les mod. nécessaires
    ou faire comme pour image-dialog et faire en sorte que ce widget retourne un objet du genre
    {
        conceptualImage: conceptualImage,
        concreteImage: concreteImage,
        imageForLineups: bool //
    }
*/

define(['text!./rc.component.image-picker.html', 'jquery', 'knockout-utilities', 'dialoger', 'knockout', 'configs'],
    function(template, $, knockoutUtilities, dialoger, ko, configs) {
        "use strict";

        var ViewModel = function(params, componentInfo) {
            var self = this;

            var imagesBasePath = (configs.baseUrl || '/') + 'bower_components/rc.component.image-picker/src/images/';

            //todo: should we throw instead?
            if (configs.imagePicker && configs.imagePicker.imagesBasePath) {
                imagesBasePath = configs.imagePicker.imagesBasePath;
            }

            self.focused = ko.observable(false);
            self.imageUrl = params.image;

            if (!self.imageUrl()) {
                self.imageUrl(imagesBasePath + 'choisir2.png');
            }
        };

        ViewModel.prototype.selectImage = function(model, jQueryEvent) {
            var self = this;

            if (!ko.components.isRegistered('images-dialog')) {
                dialoger.registerDialog('images', {
                    title: 'Select an image',
                    basePath: 'bower_components/rc.component.image-picker/src'
                });
            }

            dialoger.show('images').then(function(imageUrl) {
                if (imageUrl) {
                    self.imageUrl(imageUrl);
                }

                self.focused(true);
            });
        };

        return {
            viewModel: {
                createViewModel: function(params, componentInfo) {
                    return new ViewModel(params, componentInfo);
                }
            },
            template: template
        };
    });
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

import { Group } from '../../objects/Group.js';
import { Vector4 } from '../../math/Vector4.js';
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
import { setProjectionFromUnion } from './WebVRUtils.js';

function WebXRManager( renderer ) {

	var gl = renderer.context;

	var device = null;
	var session = null;

	var framebufferScaleFactor = 1.0;

	var frameOfReference = null;
	var frameOfReferenceType = 'stage';

	var pose = null;

	var controllers = [];
	var inputSources = [];

	function isPresenting() {

		return session !== null && frameOfReference !== null;

	}

	//

	var cameraL = new PerspectiveCamera();
	cameraL.layers.enable( 1 );
	cameraL.viewport = new Vector4();

	var cameraR = new PerspectiveCamera();
	cameraR.layers.enable( 2 );
	cameraR.viewport = new Vector4();

	var cameraVR = new ArrayCamera( [ cameraL, cameraR ] );
	cameraVR.layers.enable( 1 );
	cameraVR.layers.enable( 2 );

	//

	this.enabled = false;

	this.getController = function ( id ) {

		var controller = controllers[ id ];

		if ( controller === undefined ) {

			controller = new Group();
			controller.matrixAutoUpdate = false;
			controller.visible = false;

			controllers[ id ] = controller;

		}

		return controller;

	};

	this.getDevice = function () {

		return device;

	};

	this.setDevice = function ( value ) {

		if ( value !== undefined ) device = value;
		if ( value instanceof XRDevice ) gl.setCompatibleXRDevice( value );

	};

	//

	function onSessionEvent( event ) {

		var controller = controllers[ inputSources.indexOf( event.inputSource ) ];
		if ( controller ) controller.dispatchEvent( { type: event.type } );

	}

	function onSessionEnd() {

		renderer.setFramebuffer( null );
		renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830
		animation.stop();

	}

	this.setFramebufferScaleFactor = function ( value ) {

		framebufferScaleFactor = value;

	};

	this.setFrameOfReferenceType = function ( value ) {

		frameOfReferenceType = value;

	};

	this.setSession = function ( value ) {

		session = value;

		if ( session !== null ) {

			session.addEventListener( 'select', onSessionEvent );
			session.addEventListener( 'selectstart', onSessionEvent );
			session.addEventListener( 'selectend', onSessionEvent );
			session.addEventListener( 'end', onSessionEnd );

			session.baseLayer = new XRWebGLLayer( session, gl, { framebufferScaleFactor: framebufferScaleFactor } );
			session.requestFrameOfReference( frameOfReferenceType ).then( function ( value ) {

				frameOfReference = value;

				renderer.setFramebuffer( session.baseLayer.framebuffer );

				animation.setContext( session );
				animation.start();

			} );

			//

			inputSources = session.getInputSources();

			session.addEventListener( 'inputsourceschange', function () {

				inputSources = session.getInputSources();
				console.log( inputSources );

				for ( var i = 0; i < controllers.length; i ++ ) {

					var controller = controllers[ i ];
					controller.userData.inputSource = inputSources[ i ];

				}

			} );

		}

	};

	function updateCamera( camera, parent ) {

		if ( parent === null ) {

			camera.matrixWorld.copy( camera.matrix );

		} else {

			camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix );

		}

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

	}

	this.getCamera = function ( camera ) {

		if ( isPresenting() ) {

			var parent = camera.parent;
			var cameras = cameraVR.cameras;

			updateCamera( cameraVR, parent );

			for ( var i = 0; i < cameras.length; i ++ ) {

				updateCamera( cameras[ i ], parent );

			}

			// update camera and its children

			camera.matrixWorld.copy( cameraVR.matrixWorld );

			var children = camera.children;

			for ( var i = 0, l = children.length; i < l; i ++ ) {

				children[ i ].updateMatrixWorld( true );

			}

			setProjectionFromUnion( cameraVR, cameraL, cameraR );

			return cameraVR;

		}

		return camera;

	};

	this.isPresenting = isPresenting;

	// Animation Loop

	var onAnimationFrameCallback = null;

	function onAnimationFrame( time, frame ) {

		pose = frame.getDevicePose( frameOfReference );

		if ( pose !== null ) {

			var layer = session.baseLayer;
			var views = frame.views;

			for ( var i = 0; i < views.length; i ++ ) {

				var view = views[ i ];
				var viewport = layer.getViewport( view );
				var viewMatrix = pose.getViewMatrix( view );

				var camera = cameraVR.cameras[ i ];
				camera.matrix.fromArray( viewMatrix ).getInverse( camera.matrix );
				camera.projectionMatrix.fromArray( view.projectionMatrix );
				camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );

				if ( i === 0 ) {

					cameraVR.matrix.copy( camera.matrix );

				}

			}

		}

		//

		for ( var i = 0; i < controllers.length; i ++ ) {

			var controller = controllers[ i ];

			var inputSource = inputSources[ i ];

			if ( inputSource ) {

				var inputPose = frame.getInputPose( inputSource, frameOfReference );

				if ( inputPose !== null ) {

					if ( 'targetRay' in inputPose ) {

						controller.matrix.elements = inputPose.targetRay.transformMatrix;

					} else if ( 'pointerMatrix' in inputPose ) {

						// DEPRECATED

						controller.matrix.elements = inputPose.pointerMatrix;

					}

					controller.matrix.decompose( controller.position, controller.rotation, controller.scale );
					controller.visible = true;

					continue;

				}

			}

			controller.visible = false;

		}

		if ( onAnimationFrameCallback ) onAnimationFrameCallback( time );

	}

	var animation = new WebGLAnimation();
	animation.setAnimationLoop( onAnimationFrame );

	this.setAnimationLoop = function ( callback ) {

		onAnimationFrameCallback = callback;

	};

	this.dispose = function () {};

	// DEPRECATED

	this.getStandingMatrix = function () {

		console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' );
		return new THREE.Matrix4();

	};

	this.submitFrame = function () {};

}

export { WebXRManager };
<commit_msg>WebXRManager: Remove old THREE call and add Matrix import statement<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 */

import { Group } from '../../objects/Group.js';
import { Vector4 } from '../../math/Vector4.js';
import { ArrayCamera } from '../../cameras/ArrayCamera.js';
import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
import { setProjectionFromUnion } from './WebVRUtils.js';
import { Matrix4 } from '../../math/Matrix4';

function WebXRManager( renderer ) {

	var gl = renderer.context;

	var device = null;
	var session = null;

	var framebufferScaleFactor = 1.0;

	var frameOfReference = null;
	var frameOfReferenceType = 'stage';

	var pose = null;

	var controllers = [];
	var inputSources = [];

	function isPresenting() {

		return session !== null && frameOfReference !== null;

	}

	//

	var cameraL = new PerspectiveCamera();
	cameraL.layers.enable( 1 );
	cameraL.viewport = new Vector4();

	var cameraR = new PerspectiveCamera();
	cameraR.layers.enable( 2 );
	cameraR.viewport = new Vector4();

	var cameraVR = new ArrayCamera( [ cameraL, cameraR ] );
	cameraVR.layers.enable( 1 );
	cameraVR.layers.enable( 2 );

	//

	this.enabled = false;

	this.getController = function ( id ) {

		var controller = controllers[ id ];

		if ( controller === undefined ) {

			controller = new Group();
			controller.matrixAutoUpdate = false;
			controller.visible = false;

			controllers[ id ] = controller;

		}

		return controller;

	};

	this.getDevice = function () {

		return device;

	};

	this.setDevice = function ( value ) {

		if ( value !== undefined ) device = value;
		if ( value instanceof XRDevice ) gl.setCompatibleXRDevice( value );

	};

	//

	function onSessionEvent( event ) {

		var controller = controllers[ inputSources.indexOf( event.inputSource ) ];
		if ( controller ) controller.dispatchEvent( { type: event.type } );

	}

	function onSessionEnd() {

		renderer.setFramebuffer( null );
		renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830
		animation.stop();

	}

	this.setFramebufferScaleFactor = function ( value ) {

		framebufferScaleFactor = value;

	};

	this.setFrameOfReferenceType = function ( value ) {

		frameOfReferenceType = value;

	};

	this.setSession = function ( value ) {

		session = value;

		if ( session !== null ) {

			session.addEventListener( 'select', onSessionEvent );
			session.addEventListener( 'selectstart', onSessionEvent );
			session.addEventListener( 'selectend', onSessionEvent );
			session.addEventListener( 'end', onSessionEnd );

			session.baseLayer = new XRWebGLLayer( session, gl, { framebufferScaleFactor: framebufferScaleFactor } );
			session.requestFrameOfReference( frameOfReferenceType ).then( function ( value ) {

				frameOfReference = value;

				renderer.setFramebuffer( session.baseLayer.framebuffer );

				animation.setContext( session );
				animation.start();

			} );

			//

			inputSources = session.getInputSources();

			session.addEventListener( 'inputsourceschange', function () {

				inputSources = session.getInputSources();
				console.log( inputSources );

				for ( var i = 0; i < controllers.length; i ++ ) {

					var controller = controllers[ i ];
					controller.userData.inputSource = inputSources[ i ];

				}

			} );

		}

	};

	function updateCamera( camera, parent ) {

		if ( parent === null ) {

			camera.matrixWorld.copy( camera.matrix );

		} else {

			camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix );

		}

		camera.matrixWorldInverse.getInverse( camera.matrixWorld );

	}

	this.getCamera = function ( camera ) {

		if ( isPresenting() ) {

			var parent = camera.parent;
			var cameras = cameraVR.cameras;

			updateCamera( cameraVR, parent );

			for ( var i = 0; i < cameras.length; i ++ ) {

				updateCamera( cameras[ i ], parent );

			}

			// update camera and its children

			camera.matrixWorld.copy( cameraVR.matrixWorld );

			var children = camera.children;

			for ( var i = 0, l = children.length; i < l; i ++ ) {

				children[ i ].updateMatrixWorld( true );

			}

			setProjectionFromUnion( cameraVR, cameraL, cameraR );

			return cameraVR;

		}

		return camera;

	};

	this.isPresenting = isPresenting;

	// Animation Loop

	var onAnimationFrameCallback = null;

	function onAnimationFrame( time, frame ) {

		pose = frame.getDevicePose( frameOfReference );

		if ( pose !== null ) {

			var layer = session.baseLayer;
			var views = frame.views;

			for ( var i = 0; i < views.length; i ++ ) {

				var view = views[ i ];
				var viewport = layer.getViewport( view );
				var viewMatrix = pose.getViewMatrix( view );

				var camera = cameraVR.cameras[ i ];
				camera.matrix.fromArray( viewMatrix ).getInverse( camera.matrix );
				camera.projectionMatrix.fromArray( view.projectionMatrix );
				camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );

				if ( i === 0 ) {

					cameraVR.matrix.copy( camera.matrix );

				}

			}

		}

		//

		for ( var i = 0; i < controllers.length; i ++ ) {

			var controller = controllers[ i ];

			var inputSource = inputSources[ i ];

			if ( inputSource ) {

				var inputPose = frame.getInputPose( inputSource, frameOfReference );

				if ( inputPose !== null ) {

					if ( 'targetRay' in inputPose ) {

						controller.matrix.elements = inputPose.targetRay.transformMatrix;

					} else if ( 'pointerMatrix' in inputPose ) {

						// DEPRECATED

						controller.matrix.elements = inputPose.pointerMatrix;

					}

					controller.matrix.decompose( controller.position, controller.rotation, controller.scale );
					controller.visible = true;

					continue;

				}

			}

			controller.visible = false;

		}

		if ( onAnimationFrameCallback ) onAnimationFrameCallback( time );

	}

	var animation = new WebGLAnimation();
	animation.setAnimationLoop( onAnimationFrame );

	this.setAnimationLoop = function ( callback ) {

		onAnimationFrameCallback = callback;

	};

	this.dispose = function () {};

	// DEPRECATED

	this.getStandingMatrix = function () {

		console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' );
		return new Matrix4();

	};

	this.submitFrame = function () {};

}

export { WebXRManager };
<|endoftext|>