<commit_before>/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */

'use strict';
const CHUNK_SIZE = 16384;
const DATA_STRING = new Array(CHUNK_SIZE).fill('X').join('');

let localConnection;
let remoteConnection;
let sendChannel;
let receiveChannel;
const megsToSend = document.querySelector('input#megsToSend');
const sendButton = document.querySelector('button#sendTheData');
const orderedCheckbox = document.querySelector('input#ordered');
const sendProgress = document.querySelector('progress#sendProgress');
const receiveProgress = document.querySelector('progress#receiveProgress');
const errorMessage = document.querySelector('div#errorMsg');

let receivedSize = 0;
let bytesToSend = 0;

sendButton.addEventListener('click', createConnection);

// Prevent data sent to be set to 0.
megsToSend.addEventListener('change', function(e) {
  const number = this.value;
  if (Number.isNaN(number)) {
    errorMessage.innerHTML = `Invalid value for MB to send: ${number}`;
  } else if (number <= 0) {
    sendButton.disabled = true;
    errorMessage.innerHTML = '
Please enter a number greater than zero.
';
  } else if (number > 64) {
    sendButton.disabled = true;
    errorMessage.innerHTML = '
Please enter a number lower or equal than 64.
';
  } else {
    errorMessage.innerHTML = '';
    sendButton.disabled = false;
  }
});

async function createConnection() {
  sendButton.disabled = true;
  megsToSend.disabled = true;
  // Safari needs to trigger the media permission for RTCDataChannel to work
  if (adapter.browserDetails.browser === 'safari') {
    try {
      console.log('Call getUserMedia() to trigger media permission request.');
      const stream = await navigator.mediaDevices.getUserMedia({'audio': true, 'video': true});
      stream.getTracks().forEach(t => t.stop());
    } catch (e) {
      console.error('Error requesting permission:', e);
      return;
    }
  }

  const servers = null;

  const number = Number.parseInt(megsToSend.value);
  bytesToSend = number * 1024 * 1024;

  localConnection = new RTCPeerConnection(servers);

  // Let's make a data channel!
  const dataChannelParams = {ordered: false};
  if (orderedCheckbox.checked) {
    dataChannelParams.ordered = true;
  }
  sendChannel = localConnection.createDataChannel('sendDataChannel', dataChannelParams);
  sendChannel.binaryType = 'arraybuffer';
  sendChannel.bufferedAmountLowThreshold = CHUNK_SIZE / 2;
  sendChannel.addEventListener('open', onSendChannelStateChange);
  sendChannel.addEventListener('close', onSendChannelStateChange);
  console.log('Created send data channel: ', sendChannel);

  console.log('Created local peer connection object localConnection: ', localConnection);

  localConnection.addEventListener('icecandidate', e => onIceCandidate(localConnection, e));

  remoteConnection = new RTCPeerConnection(servers);
  remoteConnection.addEventListener('icecandidate', e => onIceCandidate(remoteConnection, e));
  remoteConnection.addEventListener('datachannel', receiveChannelCallback);

  try {
    const localOffer = await localConnection.createOffer();
    await handleLocalDescription(localOffer);
  } catch (e) {
    console.error('Failed to create session description: ', e);
  }
}

function sendData(e) {
  if (sendProgress.value < sendProgress.max) {
    // console.log('sendChannel.bufferedAmountLowThreshold:', sendChannel.bufferedAmountLowThreshold);
    // console.log('Buffered amount before sending:', sendChannel.bufferedAmount);
    sendChannel.send(DATA_STRING);
    sendProgress.value += CHUNK_SIZE;
    // console.log('Buffered amount after sending:', sendChannel.bufferedAmount);
    // console.log(`Sent another ${CHUNK_SIZE} bytes!`);

    // We need to use setTimeout() at the moment due to a bug with bufferedamountlow event.
    // See https://bugs.chromium.org/p/chromium/issues/detail?id=878682 for details
    // sendChannel.addEventListener('bufferedamountlow', sendData, {'once': true});
    setTimeout(sendData, 0);
  }
}

function startSendingData() {
  sendProgress.max = bytesToSend;
  receiveProgress.max = sendProgress.max;
  sendProgress.value = 0;
  receiveProgress.value = 0;
  sendData();
}

function closeDataChannels() {
  console.log('Closing data channels');
  sendChannel.close();
  console.log(`Closed data channel with label: ${sendChannel.label}`);
  receiveChannel.close();
  console.log(`Closed data channel with label: ${receiveChannel.label}`);
  localConnection.close();
  remoteConnection.close();
  localConnection = null;
  remoteConnection = null;
  console.log('Closed peer connections');
}

async function handleLocalDescription(desc) {
  localConnection.setLocalDescription(desc);
  console.log('Offer from localConnection:\n', desc.sdp);
  remoteConnection.setRemoteDescription(desc);
  try {
    const remoteAnswer = await remoteConnection.createAnswer();
    handleRemoteAnswer(remoteAnswer);
  } catch (e) {
    console.error('Error when creating remote answer: ', e);
  }
}

function handleRemoteAnswer(desc) {
  remoteConnection.setLocalDescription(desc);
  console.log('Answer from remoteConnection:\n', desc.sdp);
  localConnection.setRemoteDescription(desc);
}

function getOtherPc(pc) {
  return (pc === localConnection) ? remoteConnection : localConnection;
}

async function onIceCandidate(pc, event) {
  const candidate = event.candidate;
  if (candidate === null) {
    return;
  } // Ignore null candidates
  try {
    await getOtherPc(pc).addIceCandidate(candidate);
    console.log('AddIceCandidate successful: ', candidate);
  } catch (e) {
    console.error('Failed to add Ice Candidate: ', e);
  }
}

function receiveChannelCallback(event) {
  console.log('Receive Channel Callback');
  receiveChannel = event.channel;
  receiveChannel.binaryType = 'arraybuffer';
  receiveChannel.addEventListener('message', onReceiveMessageCallback);
  receivedSize = 0;
}

function onReceiveMessageCallback(event) {
  console.log('Received message!');
  receivedSize += event.data.length;
  receiveProgress.value = receivedSize;

  if (receivedSize === bytesToSend) {
    closeDataChannels();
    sendButton.disabled = false;
    megsToSend.disabled = false;
  }
}

function onSendChannelStateChange() {
  console.log('Send channel state is: ', sendChannel.readyState);
  if (sendChannel.readyState === 'open') {
    startSendingData();
  }
}
<commit_msg>Changed the workaround to use a while() loop the will, evevntually, fill up the buffered and cause the event to be fired.<commit_after>/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */

'use strict';
const CHUNK_SIZE = 16384;
const DATA_STRING = new Array(CHUNK_SIZE).fill('X').join('');

let localConnection;
let remoteConnection;
let sendChannel;
let receiveChannel;
const megsToSend = document.querySelector('input#megsToSend');
const sendButton = document.querySelector('button#sendTheData');
const orderedCheckbox = document.querySelector('input#ordered');
const sendProgress = document.querySelector('progress#sendProgress');
const receiveProgress = document.querySelector('progress#receiveProgress');
const errorMessage = document.querySelector('div#errorMsg');

let receivedSize = 0;
let bytesToSend = 0;

sendButton.addEventListener('click', createConnection);

// Prevent data sent to be set to 0.
megsToSend.addEventListener('change', function(e) {
  const number = this.value;
  if (Number.isNaN(number)) {
    errorMessage.innerHTML = `Invalid value for MB to send: ${number}`;
  } else if (number <= 0) {
    sendButton.disabled = true;
    errorMessage.innerHTML = '
Please enter a number greater than zero.
';
  } else if (number > 64) {
    sendButton.disabled = true;
    errorMessage.innerHTML = '
Please enter a number lower or equal than 64.
';
  } else {
    errorMessage.innerHTML = '';
    sendButton.disabled = false;
  }
});

async function createConnection() {
  sendButton.disabled = true;
  megsToSend.disabled = true;
  // Safari needs to trigger the media permission for RTCDataChannel to work
  if (adapter.browserDetails.browser === 'safari') {
    try {
      console.log('Call getUserMedia() to trigger media permission request.');
      const stream = await navigator.mediaDevices.getUserMedia({'audio': true, 'video': true});
      stream.getTracks().forEach(t => t.stop());
    } catch (e) {
      console.error('Error requesting permission:', e);
      return;
    }
  }

  const servers = null;

  const number = Number.parseInt(megsToSend.value);
  bytesToSend = number * 1024 * 1024;

  localConnection = new RTCPeerConnection(servers);

  // Let's make a data channel!
  const dataChannelParams = {ordered: false};
  if (orderedCheckbox.checked) {
    dataChannelParams.ordered = true;
  }
  sendChannel = localConnection.createDataChannel('sendDataChannel', dataChannelParams);
  sendChannel.binaryType = 'arraybuffer';
  sendChannel.bufferedAmountLowThreshold = CHUNK_SIZE / 2;
  sendChannel.addEventListener('open', onSendChannelStateChange);
  sendChannel.addEventListener('close', onSendChannelStateChange);
  console.log('Created send data channel: ', sendChannel);

  console.log('Created local peer connection object localConnection: ', localConnection);

  localConnection.addEventListener('icecandidate', e => onIceCandidate(localConnection, e));

  remoteConnection = new RTCPeerConnection(servers);
  remoteConnection.addEventListener('icecandidate', e => onIceCandidate(remoteConnection, e));
  remoteConnection.addEventListener('datachannel', receiveChannelCallback);

  try {
    const localOffer = await localConnection.createOffer();
    await handleLocalDescription(localOffer);
  } catch (e) {
    console.error('Failed to create session description: ', e);
  }
}

function sendData(e) {
  console.log('BufferedAmountLow event:', e);
  if (sendProgress.value < sendProgress.max) {
    sendChannel.addEventListener('bufferedamountlow', sendData, {once: true});

    // The following is a workaround due to the problem with bufferedamountlow event not being fired on every
    // call to send(), despite the amount of data exceeding the bufferedAmountLowThreshold.
    // If the event would be firing correctly, we could exclude the while loop below.
    let count = 0;
    while (sendProgress.value < sendProgress.max && sendChannel.bufferedAmount < CHUNK_SIZE) {
      sendChannel.send(DATA_STRING);
      sendProgress.value += CHUNK_SIZE;
      count++;
    }

    console.log(`Buffered amount after sending ${count} messages: ${sendChannel.bufferedAmount}`);
  }
}

function startSendingData() {
  sendProgress.max = bytesToSend;
  receiveProgress.max = sendProgress.max;
  sendProgress.value = 0;
  receiveProgress.value = 0;
  sendData();
}

function closeDataChannels() {
  console.log('Closing data channels');
  sendChannel.close();
  console.log(`Closed data channel with label: ${sendChannel.label}`);
  receiveChannel.close();
  console.log(`Closed data channel with label: ${receiveChannel.label}`);
  localConnection.close();
  remoteConnection.close();
  localConnection = null;
  remoteConnection = null;
  console.log('Closed peer connections');
}

async function handleLocalDescription(desc) {
  localConnection.setLocalDescription(desc);
  console.log('Offer from localConnection:\n', desc.sdp);
  remoteConnection.setRemoteDescription(desc);
  try {
    const remoteAnswer = await remoteConnection.createAnswer();
    handleRemoteAnswer(remoteAnswer);
  } catch (e) {
    console.error('Error when creating remote answer: ', e);
  }
}

function handleRemoteAnswer(desc) {
  remoteConnection.setLocalDescription(desc);
  console.log('Answer from remoteConnection:\n', desc.sdp);
  localConnection.setRemoteDescription(desc);
}

function getOtherPc(pc) {
  return (pc === localConnection) ? remoteConnection : localConnection;
}

async function onIceCandidate(pc, event) {
  const candidate = event.candidate;
  if (candidate === null) {
    return;
  } // Ignore null candidates
  try {
    await getOtherPc(pc).addIceCandidate(candidate);
    console.log('AddIceCandidate successful: ', candidate);
  } catch (e) {
    console.error('Failed to add Ice Candidate: ', e);
  }
}

function receiveChannelCallback(event) {
  console.log('Receive Channel Callback');
  receiveChannel = event.channel;
  receiveChannel.binaryType = 'arraybuffer';
  receiveChannel.addEventListener('message', onReceiveMessageCallback);
  receivedSize = 0;
}

function onReceiveMessageCallback(event) {
  console.log('Received message!');
  receivedSize += event.data.length;
  receiveProgress.value = receivedSize;

  if (receivedSize === bytesToSend) {
    closeDataChannels();
    sendButton.disabled = false;
    megsToSend.disabled = false;
  }
}

function onSendChannelStateChange() {
  console.log('Send channel state is: ', sendChannel.readyState);
  if (sendChannel.readyState === 'open') {
    startSendingData();
  }
}
<|endoftext|>


<commit_before>
//Funciones que se ejcutan en el index.html

var subastasDeTerceros = [];
var idUsuario;
var misSubastas = [];

function initialize() {
  $('#modalLogin').modal('show');
}

function renderizarSubastas(){
  $.each(subastasDeTerceros[0],function(index, unaSubasta){
    console.log(unaSubasta);
        renderizarUnaSubasta(unaSubasta);
  });
}

function renderizarUnaSubasta(subasta){
  var vistaSubasta = sprintf("
");
  //  var vistaSubasta = sprintf("
");
  if (subasta.mejor_oferta == null) subasta.mejor_oferta = {precio: subasta.precio_base};
  vistaSubasta += sprintf("
");
  vistaSubasta += sprintf("
", subasta.id);
  vistaSubasta += sprintf("
%s

$ %s.

Finalizada: %s.

" +
        "<button class=\"btn btn-primary\" onclick=\"ofertar(%s)\"> Ofertar (+ $2)! </button>
",
        subasta.titulo, subasta.mejor_oferta.precio, subasta.terminada, subasta.id);
  vistaSubasta += "

";
  $('#subastasActuales').append(vistaSubasta);

}

/*Cuando oferto,y sale todo bien, cambiar el valor del monto actual*/
function renderizarOfertaEnSubasta(idOferta){
  console.log("A punto de renderizar el cambio del monto actual de la subasta");

}

function ofertar(idSubasta){

  console.log("A punto de ofertar...");
  var oferta = armarOferta(idSubasta);
  $.ajax({
    headers: { 'id-usuario': idUsuario },
    type: "POST",
    contentType: "application/json",
    data: JSON.stringify(oferta),
    url:   location.origin + "/api/subastas/"+ idSubasta + "/ofertas",
    success: function (data) {
      console.log("Se Oferto Correctamente.");
      renderizarOfertaEnSubasta(oferta.id);
    },
    error: function(jqXHR, textStatus, errorThrown){
      console.log("Ofertar - Hubo un error en el servidor");
      console.log(JSON.stringify(jqXHR) + ". " + JSON.stringify(textStatus) + ". " + JSON.stringify(errorThrown));
    }
  });

}

function armarOferta(idSubasta){
  var subasta = $.grep(subastasDeTerceros[0], function(elem){ return elem.id === idSubasta; })[0];
  return {oferta:  {precio: subasta.mejor_oferta.precio+2, comprador: idUsuario} };
}

function crearNuevaSubasta(){
  console.log("A punto de crear nueva subasta...");
  var subasta = armarSubasta();
  console.log("contenido del json subasta:" + JSON.stringify(subasta));
  $.ajax({
    headers: { 'id-usuario': idUsuario },
    type: "POST",
    contentType: "application/json",
    data: JSON.stringify(subasta),
    url: location.origin + "/api/subastas",
    success: function (data) {
      console.log("Se Creo al Subasta Correctamente.");
      vaciarForm();
      agregarAlDivMisSubastas(subasta);
      misSubastas.push(subasta);
    },
    error: function(jqXHR, textStatus, errorThrown){
      console.log("Crear Subasta - Hubo un error en el servidor");
      console.log(JSON.stringify(jqXHR) + ". " + JSON.stringify(textStatus) + ". " + JSON.stringify(errorThrown));
    }
  });
}

function armarSubasta(){
  /*Armar algo del estilo:
  {"data":{"vendedor":"Juan",
  "titulo":"venta heladera",
  "terminada":false,
  "precio_base":200.0,
  "mejor_oferta":null,
  "id":9,"duracion":10}}
  */
  return {
      subasta:{
         vendedor: idUsuario,
         titulo: $("#tituloNuevaSubasta").val(),
         duracion: $("#duracionNuevaSubasta").val(),
         /*O si queres poner el tiempo final
         var xMinutesLater = new Date();
         xMinutesLater.setMinutes(xMinutesLater.getMinutes() + $("#duracionNuevaSubasta").val());*/
         precio_base: $("#precioNuevaSubasta").val(),
         terminada: false
       }
     };
}

function vaciarForm(){
  titulo: $("#tituloNuevaSubasta").val("");
  duracion: $("#duracionNuevaSubasta").val("");
  precioBase: $("#precioNuevaSubasta").val("");

}

function agregarAlDivMisSubastas(unaSubasta){
  var vistaSubasta = sprintf("
", unaSubasta.titulo);
  vistaSubasta += sprintf("%s", unaSubasta.titulo);
  vistaSubasta += sprintf("
");
  vistaSubasta += sprintf("<button class=\"btn btn-default\" onclick=\"cancelarSubasta('%s')\">Cancelar Subasta</button>",unaSubasta.titulo);
  vistaSubasta += "

";
  $('#misSubastas').append(vistaSubasta);

}

function login(){
  var nombreUsuario = $("#nombreUsuario").val();
  $("#nombreUsuarioLogueado").text($("#nombreUsuario").val());
  idUsuario = $("#nombreUsuarioLogueado").text();
  $('#modalLogin').modal('toggle');

  mostrarContenido();
}

function mostrarContenido(){
 /* subastasDeTerceros.push({id: 1, titulo:"pelota futbol", montoActual: 20.00});
  subastasDeTerceros.push({id: 2, titulo:"remera", montoActual: 50.00});
  /*Cambiar esas subastas de arriba por una peticion ajax al servidor despues de haberse logueado*/
  $.ajax({
    headers: { 'id-usuario': idUsuario },
    type: "GET",
    contentType: "application/json",
    url: "/api/subastas",
    success: function (data) {
      console.log("Se obtuvieron correctamente las subastas.");
      $.each(data,function(index, unaSubasta){
          subastasDeTerceros.push(unaSubasta);
          renderizarSubastas(); //Descomentar este y borrar el otro renderizar que esta de prueba
      });

    },
    error: function(jqXHR, textStatus, errorThrown){
      console.log("Get de subastas - Hubo un error en el servidor");
      console.log(JSON.stringify(jqXHR) + ". " + JSON.stringify(textStatus) + ". " + JSON.stringify(errorThrown));
    }
  })
}

function cancelarSubasta(titulo){

  $.ajax({
    headers: { 'id-usuario': idUsuario },
    type: "POST",
    url: location.origin + "/api/subastas/" + titulo + "/cancelar",
    success: function (data) {
      console.log("Se Cancelo la Subasta Correctamente.");
      eliminarMiSubasta(titulo);
    },
    error: function(jqXHR, textStatus, errorThrown){
      console.log("Crear Subasta - Hubo un error en el servidor");
      console.log(JSON.stringify(jqXHR) + ". " + JSON.stringify(textStatus) + ". " + JSON.stringify(errorThrown));
    }
  });

}

function eliminarMiSubasta(titulo){
  $("#div"+titulo).remove();
  misSubastas = $.grep(misSubastas, function(elem, index) {
   return elem.titulo != titulo;
  });

}

/* Un comprador A se registra.
    un nombre
    una forma de contacto

Un vendedor crea una subasta, con la siguiente información
Un título
Un precio base (que puede ser cero)
La duración máxima de la subasta
*/

function sprintf( format ){
  for( var i=1; i < arguments.length; i++ ) {
    format = format.replace( /%s/, arguments[i] );
  }
  return format;
}
<commit_msg> persiste el nombre de usuario en una cookie así no lo pregunta cada vez<commit_after>
//Funciones que se ejcutan en el index.html

var subastasDeTerceros = [];
var idUsuario;
var misSubastas = [];

function initialize() {
  if (readCookie("usuario")== null)
     $('#modalLogin').modal('show');
  else {
    idUsuario = readCookie("usuario")
    $("#nombreUsuarioLogueado").text(idUsuario);
  };
}

function renderizarSubastas(){
  $.each(subastasDeTerceros[0],function(index, unaSubasta){
    console.log(unaSubasta);
        renderizarUnaSubasta(unaSubasta);
  });
}

function renderizarUnaSubasta(subasta){
  var vistaSubasta = sprintf("
");
  //  var vistaSubasta = sprintf("
");
  if (subasta.mejor_oferta == null) subasta.mejor_oferta = {precio: subasta.precio_base};
  vistaSubasta += sprintf("
");
  vistaSubasta += sprintf("
", subasta.id);
  vistaSubasta += sprintf("
%s

$ %s.

Finalizada: %s.

" +
        "<button class=\"btn btn-primary\" onclick=\"ofertar(%s)\"> Ofertar (+ $2)! </button>
",
        subasta.titulo, subasta.mejor_oferta.precio, subasta.terminada, subasta.id);
  vistaSubasta += "

";
  $('#subastasActuales').append(vistaSubasta);

}

/*Cuando oferto,y sale todo bien, cambiar el valor del monto actual*/
function renderizarOfertaEnSubasta(idOferta){
  console.log("A punto de renderizar el cambio del monto actual de la subasta");

}

function ofertar(idSubasta){

  console.log("A punto de ofertar...");
  var oferta = armarOferta(idSubasta);
  $.ajax({
    headers: { 'id-usuario': idUsuario },
    type: "POST",
    contentType: "application/json",
    data: JSON.stringify(oferta),
    url:   location.origin + "/api/subastas/"+ idSubasta + "/ofertas",
    success: function (data) {
      console.log("Se Oferto Correctamente.");
      renderizarOfertaEnSubasta(oferta.id);
    },
    error: function(jqXHR, textStatus, errorThrown){
      console.log("Ofertar - Hubo un error en el servidor");
      console.log(JSON.stringify(jqXHR) + ". " + JSON.stringify(textStatus) + ". " + JSON.stringify(errorThrown));
    }
  });

}

function armarOferta(idSubasta){
  var subasta = $.grep(subastasDeTerceros[0], function(elem){ return elem.id === idSubasta; })[0];
  return {oferta:  {precio: subasta.mejor_oferta.precio+2, comprador: idUsuario} };
}

function crearNuevaSubasta(){
  console.log("A punto de crear nueva subasta...");
  var subasta = armarSubasta();
  console.log("contenido del json subasta:" + JSON.stringify(subasta));
  $.ajax({
    headers: { 'id-usuario': idUsuario },
    type: "POST",
    contentType: "application/json",
    data: JSON.stringify(subasta),
    url: location.origin + "/api/subastas",
    success: function (data) {
      console.log("Se Creo al Subasta Correctamente.");
      vaciarForm();
      agregarAlDivMisSubastas(subasta);
      misSubastas.push(subasta);
    },
    error: function(jqXHR, textStatus, errorThrown){
      console.log("Crear Subasta - Hubo un error en el servidor");
      console.log(JSON.stringify(jqXHR) + ". " + JSON.stringify(textStatus) + ". " + JSON.stringify(errorThrown));
    }
  });
}

function armarSubasta(){
  /*Armar algo del estilo:
  {"data":{"vendedor":"Juan",
  "titulo":"venta heladera",
  "terminada":false,
  "precio_base":200.0,
  "mejor_oferta":null,
  "id":9,"duracion":10}}
  */
  return {
      subasta:{
         vendedor: idUsuario,
         titulo: $("#tituloNuevaSubasta").val(),
         duracion: $("#duracionNuevaSubasta").val(),
         /*O si queres poner el tiempo final
         var xMinutesLater = new Date();
         xMinutesLater.setMinutes(xMinutesLater.getMinutes() + $("#duracionNuevaSubasta").val());*/
         precio_base: $("#precioNuevaSubasta").val(),
         terminada: false
       }
     };
}

function vaciarForm(){
  titulo: $("#tituloNuevaSubasta").val("");
  duracion: $("#duracionNuevaSubasta").val("");
  precioBase: $("#precioNuevaSubasta").val("");

}

function agregarAlDivMisSubastas(unaSubasta){
  var vistaSubasta = sprintf("
", unaSubasta.titulo);
  vistaSubasta += sprintf("%s", unaSubasta.titulo);
  vistaSubasta += sprintf("
");
  vistaSubasta += sprintf("<button class=\"btn btn-default\" onclick=\"cancelarSubasta('%s')\">Cancelar Subasta</button>",unaSubasta.titulo);
  vistaSubasta += "

";
  $('#misSubastas').append(vistaSubasta);

}

function login(){
  if (readCookie("usuario")== null)
  {
      var nombreUsuario = $("#nombreUsuario").val();
      $("#nombreUsuarioLogueado").text($("#nombreUsuario").val());
      idUsuario = $("#nombreUsuarioLogueado").text();
      $('#modalLogin').modal('toggle');
      createCookie("usuario",nombreUsuario, 7);
  }
  else
    nombreUsuario = readCookie("usuario");
  mostrarContenido();

}

function mostrarContenido(){
 /* subastasDeTerceros.push({id: 1, titulo:"pelota futbol", montoActual: 20.00});
  subastasDeTerceros.push({id: 2, titulo:"remera", montoActual: 50.00});
  /*Cambiar esas subastas de arriba por una peticion ajax al servidor despues de haberse logueado*/
  $.ajax({
    headers: { 'id-usuario': idUsuario },
    type: "GET",
    contentType: "application/json",
    url: "/api/subastas",
    success: function (data) {
      console.log("Se obtuvieron correctamente las subastas.");
      $.each(data,function(index, unaSubasta){
          subastasDeTerceros.push(unaSubasta);
          renderizarSubastas(); //Descomentar este y borrar el otro renderizar que esta de prueba
      });

    },
    error: function(jqXHR, textStatus, errorThrown){
      console.log("Get de subastas - Hubo un error en el servidor");
      console.log(JSON.stringify(jqXHR) + ". " + JSON.stringify(textStatus) + ". " + JSON.stringify(errorThrown));
    }
  })
}

function cancelarSubasta(titulo){

  $.ajax({
    headers: { 'id-usuario': idUsuario },
    type: "POST",
    url: location.origin + "/api/subastas/" + titulo + "/cancelar",
    success: function (data) {
      console.log("Se Cancelo la Subasta Correctamente.");
      eliminarMiSubasta(titulo);
    },
    error: function(jqXHR, textStatus, errorThrown){
      console.log("Crear Subasta - Hubo un error en el servidor");
      console.log(JSON.stringify(jqXHR) + ". " + JSON.stringify(textStatus) + ". " + JSON.stringify(errorThrown));
    }
  });

}

function eliminarMiSubasta(titulo){
  $("#div"+titulo).remove();
  misSubastas = $.grep(misSubastas, function(elem, index) {
   return elem.titulo != titulo;
  });

}

/* Un comprador A se registra.
    un nombre
    una forma de contacto

Un vendedor crea una subasta, con la siguiente información
Un título
Un precio base (que puede ser cero)
La duración máxima de la subasta
*/

function sprintf( format ){
  for( var i=1; i < arguments.length; i++ ) {
    format = format.replace( /%s/, arguments[i] );
  }
  return format;
}

function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  }
  return null;
}
function createCookie(name,value,days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  else var expires = "";
  document.cookie = name+"="+value+expires+"; path=/";
}<|endoftext|>


<commit_before>$('#panels').change(function(){
	  var request = $.ajax({
	    url: "/workers/filter_workers",
	    type: "GET",
	    data: {panels : document.getElementById("panels").value },
	    dataType: "html"
	    }); //end var request

	    request.done(function( msg ) {
	     $("#panel_results").html( msg );
	    }); //end request.done
 });

$('#panels_right').change(function(){
	  var request = $.ajax({
	    url: "/workers/filter_workers_rightsidebar",
	    type: "GET",
	    data: {panels : document.getElementById("panels_right").value },
	    dataType: "html"
	    }); //end var request

	    request.done(function( msg ) {
	     $("#filter_results").html( msg );
	     copyEmailsToForm();
	    }); //end request.done
 });

var selWorkers = [];

$('input[type=checkbox]').change(function(e){

   if($(this).is(':checked')) {
   		selWorkers.push(this.value);
    } else {
      var removeItem = this.value;
	  selWorkers = jQuery.grep(selWorkers, function(value) {
		  return value != removeItem;
	  });
    }
    console.log(selWorkers);

	var request = $.ajax({
	   url: "/workers/filter_workers_emails",
	   type: "GET",
	   data: {workers : selWorkers },
	   dataType: "html"
	}); //end var request

	request.done(function( msg ) {
		$("#worker_results").html( msg );
		//$("#recipient_email").val( msg );
	}); //end request.done

	//for sidebar view
	var req2 = $.ajax({
	   url: "/workers/right_sidebar_filt",
	   type: "GET",
	   data: {workers : selWorkers },
	   //dataType: "html"
	}); //end var request

	req2.done(function( res ) {
		//$("#worker_results").html( msg );
		res_trim = res.trim();
		$("#recipient_email").val(res_trim);
	}); //end request.done

 });

/*The code below updates the content of the edit modal each time you click on the edit button next to a worker in the panel
(fixes the issue that was causing the same worker information to appear in the edit modal unless you refreshed the page)
found via: http://stackoverflow.com/questions/13104919/twitter-bootstrap-modal-loads-wrong-remote-data
copied from: http://jsfiddle.net/Sherbrow/ThLYb/ */

$('[data-load-remote]').on('click',function(e) {
    e.preventDefault();
    var $this = $(this);
    var remote = $this.data('load-remote');
    if(remote) {
        $($this.data('remote-target')).load(remote);
    }
});

function copyEmailsToForm() {
	console.log("in copy emails");
	emails = document.getElementById("copy-emails-button").getAttribute("data-clipboard-text");
	console.log("emails: " + emails);
 	$("#recipient_email").val(emails);
 }

/*Zero Clipboard All Emails Copy Button */

var client = new ZeroClipboard( document.getElementById("copy-button") );

client.on( "ready", function( readyEvent ) {
  // alert( "ZeroClipboard SWF is ready!" );

  client.on( "aftercopy", function( event ) {
    // `this` === `client`
    // `event.target` === the element that was clicked
    //event.target.style.display = "none";
    alert("Copied emails to clipboard: " + event.data["text/plain"] );
  } );
} );

function insertFoundryLink(sel){
	link = sel.value.split(',');
	foundry_member_url = link[1].substring(2, link[1].length-2);
	console.log("link: " + link[1].substring(2, link[1].length-2));

	$("#foundry_member_url").val(foundry_member_url);
}

function showMemberTasks(sel){
	link = sel.value.split(',');
	console.log('sel: ' + sel.value);
	console.log('link: ' + link[1].substring(2, link[1].length-2));
	// foundry_member_url = link[1].substring(2, link[1].length-2);
	// console.log("link: " + link[1].substring(2, link[1].length-2));

	// $("#foundry_member_url").val(foundry_member_url);
}

function hideRightPanels(){
	$("#hidePanelsLink").html('View Panels');
	$("#right-sidebar-wrapper").css('display', 'none');
	$("#hidePanelsLink").attr('onclick', 'viewRightPanels()');
	$("#email-form-div").removeClass("span8");
	$("#email-form-div").addClass("span12");
}

function viewRightPanels(){
	$("#hidePanelsLink").html('Hide Panels');
	$("#right-sidebar-wrapper").css('display', '');
	$("#hidePanelsLink").attr('onclick', 'hideRightPanels()');
	$("#email-form-div").removeClass("span12");
	$("#email-form-div").addClass("span8");
}

/*---LEFT BAR ACCORDION----*/
/*
$(function() {
    $('#nav-accordion').dcAccordion({
        eventType: 'click',
        autoClose: true,
        saveState: true,
        disableLink: true,
        speed: 'slow',
        showCount: false,
        autoExpand: true,
//        cookie: 'dcjq-accordion-1',
        classExpand: 'dcjq-current-parent'
    });
});
*/<commit_msg>removed old code<commit_after>$('#panels').change(function(){
	  var request = $.ajax({
	    url: "/workers/filter_workers",
	    type: "GET",
	    data: {panels : document.getElementById("panels").value },
	    dataType: "html"
	    }); //end var request

	    request.done(function( msg ) {
	     $("#panel_results").html( msg );
	    }); //end request.done
 });

$('#panels_right').change(function(){
	  var request = $.ajax({
	    url: "/workers/filter_workers_rightsidebar",
	    type: "GET",
	    data: {panels : document.getElementById("panels_right").value },
	    dataType: "html"
	    }); //end var request

	    request.done(function( msg ) {
	     $("#filter_results").html( msg );
	     copyEmailsToForm();
	    }); //end request.done
 });

var selWorkers = [];

$('input[type=checkbox]').change(function(e){

   if($(this).is(':checked')) {
   		selWorkers.push(this.value);
    } else {
      var removeItem = this.value;
	  selWorkers = jQuery.grep(selWorkers, function(value) {
		  return value != removeItem;
	  });
    }
    console.log(selWorkers);

	var request = $.ajax({
	   url: "/workers/filter_workers_emails",
	   type: "GET",
	   data: {workers : selWorkers },
	   dataType: "html"
	}); //end var request

	request.done(function( msg ) {
		$("#worker_results").html( msg );
		//$("#recipient_email").val( msg );
	}); //end request.done

	//for sidebar view
	var req2 = $.ajax({
	   url: "/workers/right_sidebar_filt",
	   type: "GET",
	   data: {workers : selWorkers },
	   //dataType: "html"
	}); //end var request

	req2.done(function( res ) {
		//$("#worker_results").html( msg );
		res_trim = res.trim();
		$("#recipient_email").val(res_trim);
	}); //end request.done

 });

/*The code below updates the content of the edit modal each time you click on the edit button next to a worker in the panel
(fixes the issue that was causing the same worker information to appear in the edit modal unless you refreshed the page)
found via: http://stackoverflow.com/questions/13104919/twitter-bootstrap-modal-loads-wrong-remote-data
copied from: http://jsfiddle.net/Sherbrow/ThLYb/ */

$('[data-load-remote]').on('click',function(e) {
    e.preventDefault();
    var $this = $(this);
    var remote = $this.data('load-remote');
    if(remote) {
        $($this.data('remote-target')).load(remote);
    }
});

function copyEmailsToForm() {
	console.log("in copy emails");
	emails = document.getElementById("copy-emails-button").getAttribute("data-clipboard-text");
	console.log("emails: " + emails);
 	$("#recipient_email").val(emails);
 }

/*Zero Clipboard All Emails Copy Button */

var client = new ZeroClipboard( document.getElementById("copy-button") );

client.on( "ready", function( readyEvent ) {
  // alert( "ZeroClipboard SWF is ready!" );

  client.on( "aftercopy", function( event ) {
    // `this` === `client`
    // `event.target` === the element that was clicked
    //event.target.style.display = "none";
    alert("Copied emails to clipboard: " + event.data["text/plain"] );
  } );
} );

function insertFoundryLink(sel){
	link = sel.value.split(',');
	foundry_member_url = link[1].substring(2, link[1].length-2);
	console.log("link: " + link[1].substring(2, link[1].length-2));

	$("#foundry_member_url").val(foundry_member_url);
}

function hideRightPanels(){
	$("#hidePanelsLink").html('View Panels');
	$("#right-sidebar-wrapper").css('display', 'none');
	$("#hidePanelsLink").attr('onclick', 'viewRightPanels()');
	$("#email-form-div").removeClass("span8");
	$("#email-form-div").addClass("span12");
}

function viewRightPanels(){
	$("#hidePanelsLink").html('Hide Panels');
	$("#right-sidebar-wrapper").css('display', '');
	$("#hidePanelsLink").attr('onclick', 'hideRightPanels()');
	$("#email-form-div").removeClass("span12");
	$("#email-form-div").addClass("span8");
}

/*---LEFT BAR ACCORDION----*/
/*
$(function() {
    $('#nav-accordion').dcAccordion({
        eventType: 'click',
        autoClose: true,
        saveState: true,
        disableLink: true,
        speed: 'slow',
        showCount: false,
        autoExpand: true,
//        cookie: 'dcjq-accordion-1',
        classExpand: 'dcjq-current-parent'
    });
});
*/<|endoftext|>


<commit_before>const httpError = require('http-errors');
const models = {
  task: require('../models/task'),
  discussion: require('../models/discussion'),
  project: require('../models/project'),
  office: require('../models/office'),
  folder: require('../models/folder'),
  document: require('../models/document'),
  templateDoc: require('../models/templateDoc')
};

module.exports = {
  update,
  recycle,
  remove
}

function update(req, res, next) {
  let entity = req.params.entity;
  let Model = models[entity];
  let ids = req.body.ids;
  let update = req.body.update;

  let {
    watchers,
    tags
  } = update;

  let changeWholeParameter = {
      status: update.status,
      due: update.due,
      assign: update.assign,
  };

  watchers = watchers || [];
  tags = tags || [];

  Model.find({ _id: { $in: ids } })
  .then(function(docs) {
    if(!docs.length) throw new httpError(404);

    let set = clean(Object.assign({}, changeWholeParameter));
    return Model.update({
      _id: { $in: ids }
    }, {
      $addToSet: {
        watchers: { $each: watchers },
        tags: { $each: tags }
      },
      $set: set,
    }, {
      multi: true
    })
  })
  .then(function(results) {
    return Model.find({ _id: { $in: ids } })
  })
  .then(function(docs) {
    if(!docs.length) throw new httpError(404);
    res.json(docs)
  })
  .catch(function(err) {
    next(err)
  })
}

function recycle(req, res, next) {
  let entity = req.params.entity;
  let Model = models[entity];
  let ids = req.body.ids;

  Model.find({ _id: { $in: ids } })
  .then(function(docs) {
    if(!docs.length) throw new httpError(404);
    return Model.update({
      _id: { $in: ids }
    }, {
      $set: {
        recycled: new Date
      }
    }, {
      multi: true
    })
  })
  .then(function(results) {
      return Model.find({ _id: { $in: ids } })
  })
  .then(updatedItems=>{
      if(!updatedItems.length) throw new httpError(404);
      res.json(updatedItems)
  })
  .catch(function(err) {
      next(err)
  })
}

function clean(obj) {
    for (let propName in obj) {
        if (obj[propName] === null || obj[propName] === undefined) {
            delete obj[propName];
        }
    }
    return obj;
}

function remove(req, res, next) {
  //delete method cannot transfer any data in req.body, Avraham you need to remove this maybe
  let entity = req.params.entity;
  let Model = models[entity];
  let ids = req.body.ids;

  Model.find({ _id: { $in: ids } })
  .then(function(docs) {
    if(!docs.length) throw new httpError(404);
    return Model.remove({ _id: { $in: ids } })
  })
  .then(function(results) {
    res.end()
  })
  .catch(function(err) {
    next(err)
  })
}
<commit_msg>"disables multiple-watchers, replaced removed duplicate of statuses map, fixed bug in backend when entities are saving with empty attributes"<commit_after>const httpError = require('http-errors');
const models = {
  task: require('../models/task'),
  discussion: require('../models/discussion'),
  project: require('../models/project'),
  office: require('../models/office'),
  folder: require('../models/folder'),
  document: require('../models/document'),
  templateDoc: require('../models/templateDoc')
};

module.exports = {
  update,
  recycle,
  remove
}

function update(req, res, next) {
  let entity = req.params.entity;
  let Model = models[entity];
  let ids = req.body.ids;
  let update = req.body.update;

  let {
    watchers,
    tags
  } = update;

  let changeWholeParameter = {
      status: update.status,
      due: update.due,
      assign: update.assign,
  };

  watchers = watchers || [];
  tags = tags || [];

  Model.find({ _id: { $in: ids } })
  .then(function(docs) {
    if(!docs.length) throw new httpError(404);

    let set = clean(Object.assign({}, changeWholeParameter));
    return Model.update({
      _id: { $in: ids }
    }, {
      $addToSet: {
        watchers: { $each: watchers },
        tags: { $each: tags }
      },
      $set: set,
    }, {
      multi: true
    })
  })
  .then(function(results) {
    return Model.find({ _id: { $in: ids } })
  })
  .then(function(docs) {
    if(!docs.length) throw new httpError(404);
    res.json(docs)
  })
  .catch(function(err) {
    next(err)
  })
}

function recycle(req, res, next) {
  let entity = req.params.entity;
  let Model = models[entity];
  let ids = req.body.ids;

  Model.find({ _id: { $in: ids } })
  .then(function(docs) {
    if(!docs.length) throw new httpError(404);
    return Model.update({
      _id: { $in: ids }
    }, {
      $set: {
        recycled: new Date
      }
    }, {
      multi: true
    })
  })
  .then(function(results) {
      return Model.find({ _id: { $in: ids } })
  })
  .then(updatedItems=>{
      if(!updatedItems.length) throw new httpError(404);
      res.json(updatedItems)
  })
  .catch(function(err) {
      next(err)
  })
}

function clean(obj) {
    for (let propName in obj) {
        if (obj[propName] === null || obj[propName] === undefined) {
            delete obj[propName];
        }
    }
    return obj;
}

function remove(req, res, next) {
  //usused - remove this maybe
  let entity = req.params.entity;
  let Model = models[entity];
  let ids = req.body.ids;

  Model.find({ _id: { $in: ids } })
  .then(function(docs) {
    if(!docs.length) throw new httpError(404);
    return Model.remove({ _id: { $in: ids } })
  })
  .then(function(results) {
    res.end()
  })
  .catch(function(err) {
    next(err)
  })
}
<|endoftext|>


<commit_before>enyo.kind({
	name: "FindPopup",
	kind: "onyx.Popup",
	events: {
		onFindNext:"",
		onFindPrevious:"",
		//onReplace:"",
		onReplaceAll:"",
		onReplaceFind: "",
		onClose: ""
	},
	published: {
		findValue:"",
		replaceValue: ""
	},
	handlers: {
		onShow: "shown"
	},
	components: [
		{kind: "FittableRows", classes:"ares_phobos_findpop", components: [
			{kind: "FittableColumns", components: [
				{fit: true, content: "Find:", classes: "phobos-find-label"},
				{kind: "onyx.InputDecorator", components: [
					{name: "find", kind: "onyx.Input", classes: "phobos-find-field", placeholder: "", onchange: "findChanged"}
				]},
			]},
			{tag: "br"},
			{kind: "FittableColumns", components:[
				{fit: true, content: "Replace:", classes: "phobos-find-label"},
				{kind: "onyx.InputDecorator", components: [
					{name: "replace", kind: "onyx.Input", classes: "phobos-find-field", placeholder: "", onchange: "replaceChanged"}
				]},
			]},
			{tag: "br"},
			{kind: "FittableColumns", components: [
				//{name: "replaceOne", kind: "onyx.Button", content: "Replace", ontap: "doReplace"},

				{style: "width: 97px"},
				{name: "replaceAll", kind: "onyx.Button", disabled: true, content: "Replace All", ontap: "doReplaceAll"},
				{style: "width: 10px"},
				{name: "replaceFind", kind: "onyx.Button", disabled: true, content: "Replace & Find", ontap: "doReplaceFind"},
				{tag: "br"},
				{tag: "br"},
				{style: "width: 177px"},
				{name: "findprevious", kind: "onyx.Button", content: "Previous", ontap: "doFindPrevious"},
				{style: "width: 10px"},
				{name: "findnext", kind: "onyx.Button", content: "Next", ontap: "doFindNext"},
				{tag: "br"},
				{name: "close", kind: "onyx.Button", content: "Close", ontap: "doClose"},
			]}
		]}
	],
	findChanged: function(inSender, inEvent) {
		this.findValue = this.$.find.getValue();
	},
	replaceChanged: function(inSender, inEvent) {
		this.replaceValue = this.$.replace.getValue();
		this.$.replaceFind.setDisabled(false);
		this.$.replaceAll.setDisabled(false);
	},
	shown: function(inSender, inEvent) {
		this.$.find.focus();
	}
});
<commit_msg>replaced control dedicated to layout adjustments with style attributes<commit_after>enyo.kind({
	name: "FindPopup",
	kind: "onyx.Popup",
	events: {
		onFindNext:"",
		onFindPrevious:"",
		//onReplace:"",
		onReplaceAll:"",
		onReplaceFind: "",
		onClose: ""
	},
	published: {
		findValue:"",
		replaceValue: ""
	},
	handlers: {
		onShow: "shown"
	},
	components: [
		{kind: "FittableRows", classes:"ares_phobos_findpop", components: [
			{kind: "FittableColumns", style: "margin-bottom: 10px", components: [
				{fit: true, content: "Find:", classes: "phobos-find-label"},
				{kind: "onyx.InputDecorator", components: [
					{name: "find", kind: "onyx.Input", classes: "phobos-find-field", placeholder: "", onchange: "findChanged"}
				]}
			]},
			{kind: "FittableColumns", style: "margin-bottom: 10px", components:[
				{fit: true, content: "Replace:", classes: "phobos-find-label"},
				{kind: "onyx.InputDecorator", components: [
					{name: "replace", kind: "onyx.Input", classes: "phobos-find-field", placeholder: "", onchange: "replaceChanged"}
				]}
			]},
			{kind: "FittableColumns", style: "margin-bottom: 10px", components: [
				//{name: "replaceOne", kind: "onyx.Button", content: "Replace", ontap: "doReplace"},

				{fit: true},
				{name: "replaceAll", kind: "onyx.Button", disabled: true, style: "margin-right: 10px",
				 content: "Replace All", ontap: "doReplaceAll"},
				{name: "replaceFind", kind: "onyx.Button", disabled: true, content: "Replace & Find", ontap: "doReplaceFind"}
			]},
			{kind: "FittableColumns", style: "margin-bottom: 10px", components: [
				{fit: true},
				{name: "findprevious", kind: "onyx.Button", content: "Previous", style: "margin-right: 10px", ontap: "doFindPrevious"},
				{name: "findnext", kind: "onyx.Button", content: "Next", ontap: "doFindNext"}
			]},
			{kind: "FittableColumns", components: [
				{name: "close", kind: "onyx.Button", content: "Close", ontap: "doClose"},
				{fit: true}
			]}
		]}
	],
	findChanged: function(inSender, inEvent) {
		this.findValue = this.$.find.getValue();
	},
	replaceChanged: function(inSender, inEvent) {
		this.replaceValue = this.$.replace.getValue();
		this.$.replaceFind.setDisabled(false);
		this.$.replaceAll.setDisabled(false);
	},
	shown: function(inSender, inEvent) {
		this.$.find.focus();
	}
});
<|endoftext|>


<commit_before>var radiusSupported = false;
var nextCount = 0;
var touchMap = {};
var pointMode = (window.location.hash == "#points");
var enableForce = false;
var drawTouchMajor = true;
var foundRotationAngle = false;
var scale = 1;
var mousePressed = false;

function InitializeApp() {
    InitializeCanvas();

    var elem = document.getElementById("canvas");
    if (window.PointerEvent) {
        console.log("Adding PointerEvent listeners");
        ["pointerdown", "pointermove", "pointerup"].forEach(function(e) {
            elem.addEventListener(e, PointerHandler);
        });
    } else {
        console.log("Adding MouseEvent & TouchEvent listeners");
        ["mousedown", "mousemove", "mouseup"].forEach(function(e) {
            elem.addEventListener(e, MouseHandler);
        });
        ["touchstart", "touchmove", "touchend"].forEach(function(e) {
            elem.addEventListener(e, TouchHandler);
        });
    }

    window.addEventListener("resize", function(e) {
        InitializeCanvas();
    });

    document.addEventListener("keyup", function(e) {
        switch(e.which) {
        // ESC
        case 27:
            var canvas = document.getElementById("canvas");
            canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
            break;

        // p
        case 80:
            pointMode = !pointMode;
            window.location.hash = pointMode ? "#points" : "";
            break;

        // f
        case 70:
            enableForce = !enableForce;
            break;

        // a
        case 65:
            drawTouchMajor = !drawTouchMajor;
            break;

        // enter
        case 13:
            if (document.documentElement.webkitRequestFullscreen) {
                if (document.webkitFullscreenElement)
                    document.webkitCancelFullScreen();
                else
                    document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
            }
        }
    });
}

function InitializeCanvas() {
    var elem = document.getElementById("canvas");

    var newscale = window.devicePixelRatio ? window.devicePixelRatio : 1;
    var newwidth = window.screen.width * newscale;
    var newheight = window.screen.height * newscale;

    if (elem.width != newwidth || elem.height != newheight || scale != newscale) {
        // resizing a canvas clears it, so do it only when it's dimensions have changed.
        scale = newscale;
        elem.width = newwidth;
        elem.height = newheight;
        elem.style.width = window.screen.width + "px";
        elem.style.height = window.screen.height + "px";
    }
}

function PointerHandler(event) {
    event.preventDefault();

    if (event.type == "pointerdown" && event.button === 0)
        mousePressed = true;

    if (mousePressed || event.type == "pointerup" || (event.buttons & 1)) {
        var fakeTouch = {
            identifier: event.pointerId,
            pageX : event.pageX,
            pageY : event.pageY,
            radiusX : event.width,
            radiusY : event.height,
            force : event.pressure,
        };
        var eventType = event.type == "pointerdown" ? "touchstart" :
            event.type == "pointerup" ? "touchend" : "touchmove";
        drawTouch(fakeTouch, eventType);
        event.preventDefault();
    }

    if (event.type == "pointerup")
        mousePressed = false;
}

function MouseHandler(event) {
    if (event.type == "mousedown" && event.button === 0)
        mousePressed = true;

    if (mousePressed && event.button === 0) {
        var fakeTouch = {
            identifier : 10,
            pageX : event.pageX,
            pageY : event.pageY
        };
        var eventType = event.type == "mousedown" ? "touchstart" :
            event.type == "mouseup" ? "touchend" : "touchmove";
        drawTouch(fakeTouch, eventType);
        event.preventDefault();
    }

    if (event.type == "mouseup")
        mousePressed = false;
}

function TouchHandler(event) {
    event.preventDefault();
    for (var i = 0; i < event.changedTouches.length; i++)
        drawTouch(event.changedTouches[i], event.type);
}

function drawTouch(touch, eventType) {
    var context = document.getElementById("canvas").getContext("2d");

    // Map the identifier to a small count (no-op on Chrome, but
    // important for mobile Safari).
    if (!(touch.identifier in touchMap)) {
        touchMap[touch.identifier] = nextCount;
        nextCount++;
    }

    // Polyfill non-standard properties
    if (!("radiusX" in touch) && "webkitRadiusX" in touch)
        touch.radiusX = touch.webkitRadiusX;
    if (!("radiusY" in touch) && "webkitRadiusY" in touch)
        touch.radiusY = touch.webkitRadiusY;
    if (!("rotationAngle" in touch) && "webkitRotationAngle" in touch)
        touch.rotationAngle = touch.webkitRotationAngle;
    if (!("force" in touch) && "webkitForce" in touch)
        touch.force = touch.webkitForce;

    var radiusX = getAdjustedRadius(touch.radiusX, touch.radiusY);
    var radiusY = getAdjustedRadius(touch.radiusY, touch.radiusX);
    var rotationAngle = getAdjustedRotationAngle(touch.rotationAngle);
    foundRotationAngle = foundRotationAngle || rotationAngle;

    // Try to avoid start/end ellipses overlapping exactly
    if (eventType == "touchend") {
        radiusX++;
        radiusY++;
    }

    context.save();
    context.translate(touch.pageX * scale, touch.pageY * scale);
    context.rotate(rotationAngle);
    context.scale(1, radiusY/radiusX);
    context.beginPath();
    context.arc(0, 0, radiusX, 0, 2.0 * Math.PI, false);
    context.closePath();

    // Fill the ellipse on start/move
    if (eventType != "touchend") {
        var opacity = pointMode ? 1 : 0.1;

        var hue = (touchMap[touch.identifier] * 30) % 256;
        var lum = 40;
        if (enableForce && touch.force)
            lum = Math.round(touch.force / 0.4 * 50 + 20);
        context.fillStyle = "hsla(" + hue + ",100%," + lum + "%, " + opacity + ")";
        context.fill();
    }

    // Outline ellipse on start/end
    if (eventType != "touchmove") {
        context.strokeStyle = eventType == "touchstart" ? "black" : "grey";
        context.lineWidth = 2;
        context.stroke();
    }

    if (drawTouchMajor && foundRotationAngle) {
        context.strokeStyle = "#fff";
        context.lineWidth = 1;
        context.beginPath();
        if (radiusX >= radiusY) {
            context.moveTo(-radiusX, 0);
            context.lineTo(radiusX, 0);
        } else {
            // Note that this is also radiusX, because of the scaling above
            context.moveTo(0, -radiusX);
            context.lineTo(0, radiusX);
        }
        context.stroke();
    }

    context.restore();
}

function getAdjustedRadius(radius, otherRadius) {
    if (pointMode)
        return 1;

    // Spec says to use 1 for unknown radius, can't differentiate between that
    // and real 1 pixel radius.
    var radiusUndefined = !radius || radius <= 1;
    var otherRadiusUndefined = !otherRadius || otherRadius <= 1;

    if (radiusUndefined) {
        radius = otherRadiusUndefined? 15 : otherRadius;
    }

    if (radius > 100) {
        console.error("Got large radius: " + radius);
        radius = 100;
    }

    return radius * scale;
}

function getAdjustedRotationAngle(angle) {
    return angle * Math.PI / 180;
}

// Google analytics
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-69196529-2', 'auto');
ga('send', 'pageview');
<commit_msg>Added a "no pointer event" mode.<commit_after>var radiusSupported = false;
var nextCount = 0;
var touchMap = {};
var pointMode = (window.location.hash == "#points");
var pointerEventDisabledMode = (window.location.hash == "#nopointer");
var enableForce = false;
var drawTouchMajor = true;
var foundRotationAngle = false;
var scale = 1;
var mousePressed = false;

function InitializeApp() {
    InitializeCanvas();

    var elem = document.getElementById("canvas");
    if (window.PointerEvent && !pointerEventDisabledMode) {
        console.log("Adding PointerEvent listeners");
        ["pointerdown", "pointermove", "pointerup"].forEach(function(e) {
            elem.addEventListener(e, PointerHandler);
        });
    } else {
        console.log("Adding MouseEvent & TouchEvent listeners");
        ["mousedown", "mousemove", "mouseup"].forEach(function(e) {
            elem.addEventListener(e, MouseHandler);
        });
        ["touchstart", "touchmove", "touchend"].forEach(function(e) {
            elem.addEventListener(e, TouchHandler);
        });
    }

    window.addEventListener("resize", function(e) {
        InitializeCanvas();
    });

    document.addEventListener("keyup", function(e) {
        switch(e.which) {
        // ESC
        case 27:
            var canvas = document.getElementById("canvas");
            canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
            break;

        // p
        case 80:
            pointMode = !pointMode;
            window.location.hash = pointMode ? "#points" : "";
            break;

        // f
        case 70:
            enableForce = !enableForce;
            break;

        // a
        case 65:
            drawTouchMajor = !drawTouchMajor;
            break;

        // enter
        case 13:
            if (document.documentElement.webkitRequestFullscreen) {
                if (document.webkitFullscreenElement)
                    document.webkitCancelFullScreen();
                else
                    document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
            }
        }
    });
}

function InitializeCanvas() {
    var elem = document.getElementById("canvas");

    var newscale = window.devicePixelRatio ? window.devicePixelRatio : 1;
    var newwidth = window.screen.width * newscale;
    var newheight = window.screen.height * newscale;

    if (elem.width != newwidth || elem.height != newheight || scale != newscale) {
        // resizing a canvas clears it, so do it only when it's dimensions have changed.
        scale = newscale;
        elem.width = newwidth;
        elem.height = newheight;
        elem.style.width = window.screen.width + "px";
        elem.style.height = window.screen.height + "px";
    }
}

function PointerHandler(event) {
    event.preventDefault();

    if (event.type == "pointerdown" && event.button === 0)
        mousePressed = true;

    if (mousePressed || event.type == "pointerup" || (event.buttons & 1)) {
        var fakeTouch = {
            identifier: event.pointerId,
            pageX : event.pageX,
            pageY : event.pageY,
            radiusX : event.width,
            radiusY : event.height,
            force : event.pressure,
        };
        var eventType = event.type == "pointerdown" ? "touchstart" :
            event.type == "pointerup" ? "touchend" : "touchmove";
        drawTouch(fakeTouch, eventType);
        event.preventDefault();
    }

    if (event.type == "pointerup")
        mousePressed = false;
}

function MouseHandler(event) {
    if (event.type == "mousedown" && event.button === 0)
        mousePressed = true;

    if (mousePressed && event.button === 0) {
        var fakeTouch = {
            identifier : 10,
            pageX : event.pageX,
            pageY : event.pageY
        };
        var eventType = event.type == "mousedown" ? "touchstart" :
            event.type == "mouseup" ? "touchend" : "touchmove";
        drawTouch(fakeTouch, eventType);
        event.preventDefault();
    }

    if (event.type == "mouseup")
        mousePressed = false;
}

function TouchHandler(event) {
    event.preventDefault();
    for (var i = 0; i < event.changedTouches.length; i++)
        drawTouch(event.changedTouches[i], event.type);
}

function drawTouch(touch, eventType) {
    var context = document.getElementById("canvas").getContext("2d");

    // Map the identifier to a small count (no-op on Chrome, but
    // important for mobile Safari).
    if (!(touch.identifier in touchMap)) {
        touchMap[touch.identifier] = nextCount;
        nextCount++;
    }

    // Polyfill non-standard properties
    if (!("radiusX" in touch) && "webkitRadiusX" in touch)
        touch.radiusX = touch.webkitRadiusX;
    if (!("radiusY" in touch) && "webkitRadiusY" in touch)
        touch.radiusY = touch.webkitRadiusY;
    if (!("rotationAngle" in touch) && "webkitRotationAngle" in touch)
        touch.rotationAngle = touch.webkitRotationAngle;
    if (!("force" in touch) && "webkitForce" in touch)
        touch.force = touch.webkitForce;

    var radiusX = getAdjustedRadius(touch.radiusX, touch.radiusY);
    var radiusY = getAdjustedRadius(touch.radiusY, touch.radiusX);
    var rotationAngle = getAdjustedRotationAngle(touch.rotationAngle);
    foundRotationAngle = foundRotationAngle || rotationAngle;

    // Try to avoid start/end ellipses overlapping exactly
    if (eventType == "touchend") {
        radiusX++;
        radiusY++;
    }

    context.save();
    context.translate(touch.pageX * scale, touch.pageY * scale);
    context.rotate(rotationAngle);
    context.scale(1, radiusY/radiusX);
    context.beginPath();
    context.arc(0, 0, radiusX, 0, 2.0 * Math.PI, false);
    context.closePath();

    // Fill the ellipse on start/move
    if (eventType != "touchend") {
        var opacity = pointMode ? 1 : 0.1;

        var hue = (touchMap[touch.identifier] * 30) % 256;
        var lum = 40;
        if (enableForce && touch.force)
            lum = Math.round(touch.force / 0.4 * 50 + 20);
        context.fillStyle = "hsla(" + hue + ",100%," + lum + "%, " + opacity + ")";
        context.fill();
    }

    // Outline ellipse on start/end
    if (eventType != "touchmove") {
        context.strokeStyle = eventType == "touchstart" ? "black" : "grey";
        context.lineWidth = 2;
        context.stroke();
    }

    if (drawTouchMajor && foundRotationAngle) {
        context.strokeStyle = "#fff";
        context.lineWidth = 1;
        context.beginPath();
        if (radiusX >= radiusY) {
            context.moveTo(-radiusX, 0);
            context.lineTo(radiusX, 0);
        } else {
            // Note that this is also radiusX, because of the scaling above
            context.moveTo(0, -radiusX);
            context.lineTo(0, radiusX);
        }
        context.stroke();
    }

    context.restore();
}

function getAdjustedRadius(radius, otherRadius) {
    if (pointMode)
        return 1;

    // Spec says to use 1 for unknown radius, can't differentiate between that
    // and real 1 pixel radius.
    var radiusUndefined = !radius || radius <= 1;
    var otherRadiusUndefined = !otherRadius || otherRadius <= 1;

    if (radiusUndefined) {
        radius = otherRadiusUndefined? 15 : otherRadius;
    }

    if (radius > 100) {
        console.error("Got large radius: " + radius);
        radius = 100;
    }

    return radius * scale;
}

function getAdjustedRotationAngle(angle) {
    return angle * Math.PI / 180;
}

// Google analytics
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-69196529-2', 'auto');
ga('send', 'pageview');
<|endoftext|>


<commit_before>/* eslint-disable react/jsx-no-bind */
import React, { PropTypes } from 'react';
import StackedNotification from './stackedNotification';

function defaultStyleFactory(index, style) {
  return Object.assign(
    {},
    style,
    { bottom: `${2 + (index * 4)}rem` }
  );
}

/**
* The notification list does not have any state, so use a
* pure function here. It just needs to return the stacked array
* of notification components.
*/
const NotificationStack = props => (

    {props.notifications.map((notification, index) => {
      const isLast = index === 0 && props.notifications.length === 1;
      const dismissNow = isLast || !props.dismissInOrder;

      // Allow onClick from notification stack or individual notifications
      const onClick = notification.onClick || props.onClick;
      const onDismiss = props.onDismiss;

      let { dismissAfter } = notification;
      if (dismissAfter !== false) {
        if (dismissAfter == null) dismissAfter = props.dismissAfter;
        if (!dismissNow) dismissAfter += index * 1000;
      }
      const barStyle = props.barStyleFactory(index, notification.barStyle);
      const activeBarStyle = props.activeBarStyleFactory(index, notification.activeBarStyle);

      return (
        <StackedNotification
          {...notification}
          key={notification.key}
          isLast={isLast}
          action={notification.action || props.action}
          dismissAfter={dismissAfter}
          onDismiss={onDismiss.bind(this, notification)}
          onClick={onClick.bind(this, notification)}
          activeBarStyle={activeBarStyle}
          barStyle={barStyle}
        />
      );
    })}

);

/* eslint-disable react/no-unused-prop-types, react/forbid-prop-types */

NotificationStack.propTypes = {
  activeBarStyleFactory: PropTypes.func,
  barStyleFactory: PropTypes.func,
  dismissInOrder: PropTypes.bool.isRequired,
  notifications: PropTypes.array.isRequired,
  onDismiss: PropTypes.func.isRequired,
  onClick: PropTypes.func,
};

NotificationStack.defaultProps = {
  activeBarStyleFactory: defaultStyleFactory,
  barStyleFactory: defaultStyleFactory,
  dismissInOrder: true,
  dismissAfter: 1000,
  onClick: () => {}
};

/* eslint-enable no-alert, no-console */

export default NotificationStack;
<commit_msg>Improve spacing of constants<commit_after>/* eslint-disable react/jsx-no-bind */
import React, { PropTypes } from 'react';
import StackedNotification from './stackedNotification';

function defaultStyleFactory(index, style) {
  return Object.assign(
    {},
    style,
    { bottom: `${2 + (index * 4)}rem` }
  );
}

/**
* The notification list does not have any state, so use a
* pure function here. It just needs to return the stacked array
* of notification components.
*/
const NotificationStack = props => (

    {props.notifications.map((notification, index) => {
      const isLast = index === 0 && props.notifications.length === 1;
      const dismissNow = isLast || !props.dismissInOrder;

      // Handle styles
      const barStyle = props.barStyleFactory(index, notification.barStyle);
      const activeBarStyle = props.activeBarStyleFactory(index, notification.activeBarStyle);

      // Allow onClick from notification stack or individual notifications
      const onClick = notification.onClick || props.onClick;
      const onDismiss = props.onDismiss;

      let { dismissAfter } = notification;

      if (dismissAfter !== false) {
        if (dismissAfter == null) dismissAfter = props.dismissAfter;
        if (!dismissNow) dismissAfter += index * 1000;
      }

      return (
        <StackedNotification
          {...notification}
          key={notification.key}
          isLast={isLast}
          action={notification.action || props.action}
          dismissAfter={dismissAfter}
          onDismiss={onDismiss.bind(this, notification)}
          onClick={onClick.bind(this, notification)}
          activeBarStyle={activeBarStyle}
          barStyle={barStyle}
        />
      );
    })}

);

/* eslint-disable react/no-unused-prop-types, react/forbid-prop-types */

NotificationStack.propTypes = {
  activeBarStyleFactory: PropTypes.func,
  barStyleFactory: PropTypes.func,
  dismissInOrder: PropTypes.bool,
  notifications: PropTypes.array.isRequired,
  onDismiss: PropTypes.func.isRequired,
  onClick: PropTypes.func,
  action: PropTypes.string
};

NotificationStack.defaultProps = {
  activeBarStyleFactory: defaultStyleFactory,
  barStyleFactory: defaultStyleFactory,
  dismissInOrder: true,
  dismissAfter: 1000,
  onClick: () => {}
};

/* eslint-enable no-alert, no-console */

export default NotificationStack;
<|endoftext|>


<commit_before>
var dc2rtf = {};

var config;

dc2rtf.map = function(metadata, conf) {
    config = conf || require('../config.json');
    result = {};
    for(var i = 0; i < metadata.length; i++){
        var qual = metadata[i]['$'].qualifier;
        var elm = metadata[i]['$'].element;
        var lang = metadata[i]['$'].language;
        var value = metadata[i]['$'].value.replace(/\r?\n|\r/g, "");

        // Get the type and add it to the result array
        if(elm === "type" && lang === "en"){
            if(value.includes("thesis") || value.includes("Bachelor's")){
                result['RT'] = "Dissertation/Thesis";
            }else if(value.indexOf("abstract") > -1){
                result['RT'] = "Abstract";
            }else{
                result['RT'] = "Generic";
            }
        }

        // Some Edge Cases
        if(elm === "title" && qual !== "alternative"){
            result['T1'] = value;
            continue;
        }

        if((elm === "publisher" || elm === "organization") && qual === undefined){
            var cleanedpub = cleanpublisher(value);
            //Check if the same publisher is in already
            if(result['PB'] != undefined ){
                if(result['PB'] === value || result['PB'].includes(value))
                {
                    continue;
                }
            }

            //Check if we have a string or an object
            if(typeof cleanedpub == "string"){
                result['PB'] == undefined ? result['PB'] = cleanedpub : result['PB'].push(cleanedpub);
                continue;
            }

            //Check the language and if there's more than one publisher we add it in to an array
            if(result['LA'] === 'English') {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['en']] : result['PB'].push(cleanedpub['en']);
            }
            else if(result['LA'] === 'Finnish') {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['fi']] : result['PB'].push(cleanedpub['sv']);
            }
            else if(result['LA'] === 'Swedish') {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['sv']] : result['PB'].push(cleanedpub['sv']);
            }
            continue;
        }

        //Add Keywords
        if (elm === "subject"){
            var keytag = config.mapping[elm];
            result[keytag] == undefined ? result[keytag] = [value] : result[keytag].push(value);
            continue;
        }

        //Add LUT Publisher
        if(elm === "contributor" && (value.indexOf("Lappeenrannan") > -1)){
            result['PB'] = [value.split("/")[0]];
            continue;
        }

        // Pagerange
        if(elm === "format" && qual === "pagerange"){
            var pages = value.split("-");
            result['SP'] = pages[0];
            result['OP'] = pages[1];
            continue;
        }

        // Add urn link
        if(qual === "uri" && value.includes("URN")){
            result['LK'] = "http://urn.fi/"+value;
            continue;
        }

        if(qual === "urn"){
            value = "http://urn.fi/"+value;
        }

        //If tag is undefined, ignore it
        var tag = config.mapping[qual];
        if(tag === undefined){
            continue;
        }

        if(elm === "language" && qual === "iso"){
            value = typeof config.lang[value] == 'undefined' ? "Finnish(32)" : config.lang[value];
        }

        //Add primary authors to a array
        if(tag === "A1"){
            result[tag] == undefined ? result[tag] = [value] : result[tag].push(value);
            continue;
        }

        //Clean the issued date
        if(tag === "YR"){
            var yearArr = /^[12][0-9]{3}/.exec(value);
            result[tag] = yearArr[0];
            continue;
       }

        //If the tag is not empty, append the value to it
        if(result[tag] !== undefined){
            result[tag].push(value);
        }else {
            result[tag] = [value];
        }
    }

    return result;
};

dc2rtf.maketext = function(data){
    var text = "";

    for(var key in data){
        if (data[key].constructor === Array){
            for(var i = 0; i < data[key].length; i++){
                text += key + " " + data[key][i] + "\n"
            }
        }else{
            text += key + " " + data[key]+"\n";
        }
    }

    return text;

};

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

function cleanpublisher(publisherstring){
    if(!isLocalizedString(publisherstring)){
        return publisherstring;
    }
    var pubarray = publisherstring.split("|");
    pubarray.pop();
    var publishers = {};
    for (var pub in pubarray){
        if(pubarray[pub].includes('fi')){
            publishers['fi'] = pubarray[pub].replaceAll("fi=", "");
        } else if(pubarray[pub].includes('en')){
            publishers['en'] = pubarray[pub].replaceAll("en=", "")
        } else if(pubarray[pub].includes('sv')){
            publishers['sv'] = pubarray[pub].replaceAll("sv=", "")
        }
    }
    return publishers;
};

function isLocalizedString(s){
    return !!(s.includes("fi=") || s.includes("en=") || s.includes("sv="));

}

module.exports = dc2rtf;
<commit_msg>fixes to publisher strings<commit_after>
var dc2rtf = {};

var config;

dc2rtf.map = function(metadata, conf) {
    config = conf || require('../config.json');
    result = {};
    for(var i = 0; i < metadata.length; i++){
        var qual = metadata[i]['$'].qualifier;
        var elm = metadata[i]['$'].element;
        var lang = metadata[i]['$'].language;
        var value = metadata[i]['$'].value.replace(/\r?\n|\r/g, "");

        // Get the type and add it to the result array
        if(elm === "type" && lang === "en"){
            if(value.includes("thesis") || value.includes("Bachelor's")){
                result['RT'] = "Dissertation/Thesis";
            }else if(value.indexOf("abstract") > -1){
                result['RT'] = "Abstract";
            }else{
                result['RT'] = "Generic";
            }
        }

        // Some Edge Cases
        if(elm === "title" && qual !== "alternative"){
            result['T1'] = value;
            continue;
        }

        if((elm === "publisher" || elm === "organization") && qual === undefined){
            var cleanedpub = cleanpublisher(value);
            //Check if the same publisher is in already
            if(result['PB'] != undefined ){
                if(result['PB'] === value || result['PB'].includes(value))
                {
                    continue;
                }
            }

            //Check if we have a string or an object
            if(typeof cleanedpub == "string"){
                result['PB'] == undefined ? result['PB'] = cleanedpub : result['PB'].push(cleanedpub);
                continue;
            }

            //Check the language and if there's more than one publisher we add it in to an array
            if(result['LA'] === 'English') {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['en']] : result['PB'].push(cleanedpub['en']);
            }
            else if(result['LA'] === 'Finnish') {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['fi']] : result['PB'].push(cleanedpub['sv']);
            }
            else if(result['LA'] === 'Swedish') {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['sv']] : result['PB'].push(cleanedpub['sv']);
            } else {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['fi']] : result['PB'].push(cleanedpub['sv']);
            }
            continue;
        }

        //Add Keywords
        if (elm === "subject"){
            var keytag = config.mapping[elm];
            result[keytag] == undefined ? result[keytag] = [value] : result[keytag].push(value);
            continue;
        }

        //Add LUT Publisher
        if(elm === "contributor" && (value.indexOf("Lappeenrannan") > -1)){
            result['PB'] = [value.split("/")[0]];
            continue;
        }

        //Add Theseus Publisher
        if (elm === "contributor" && value.indexOf("fi=") > -1){
            var cleanedpub = cleanpublisher(value);
            if(result['LA'] === 'English') {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['en']] : result['PB'].push(cleanedpub['en']);
            }
            else if(result['LA'] === 'Finnish') {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['fi']] : result['PB'].push(cleanedpub['sv']);
            }
            else if(result['LA'] === 'Swedish') {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['sv']] : result['PB'].push(cleanedpub['sv']);
            } else {
                result['PB'] == undefined ? result['PB'] = [cleanedpub['fi']] : result['PB'].push(cleanedpub['sv']);
            }
            continue;
        }

        // Pagerange
        if(elm === "format" && qual === "pagerange"){
            var pages = value.split("-");
            result['SP'] = pages[0];
            result['OP'] = pages[1];
            continue;
        }

        // Add urn link
        if(qual === "uri" && value.includes("URN")){
            result['LK'] = "http://urn.fi/"+value;
            continue;
        }

        if(qual === "urn"){
            value = "http://urn.fi/"+value;
        }

        //If tag is undefined, ignore it
        var tag = config.mapping[qual];
        if(tag === undefined){
            continue;
        }

        if(elm === "language" && qual === "iso"){
            value = typeof config.lang[value] == 'undefined' ? "Finnish(32)" : config.lang[value];
        }

        //Add primary authors to a array
        if(tag === "A1"){
            result[tag] == undefined ? result[tag] = [value] : result[tag].push(value);
            continue;
        }

        //Clean the issued date
        if(tag === "YR"){
            var yearArr = /^[12][0-9]{3}/.exec(value);
            result[tag] = yearArr[0];
            continue;
       }

        //If the tag is not empty, append the value to it
        if(result[tag] !== undefined){
            result[tag].push(value);
        }else {
            result[tag] = [value];
        }
    }

    return result;
};

dc2rtf.maketext = function(data){
    var text = "";

    for(var key in data){
        if (data[key].constructor === Array){
            for(var i = 0; i < data[key].length; i++){
                text += key + " " + data[key][i] + "\n"
            }
        }else{
            text += key + " " + data[key]+"\n";
        }
    }

    return text;

};

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

function cleanpublisher(publisherstring){
    if(!isLocalizedString(publisherstring)){
        return publisherstring;
    }
    var firegex = /fi=[^|]+/gm;
    var svregex = /sv=[^|]+/gm;
    var enregex = /en=[^|]+/gm;

    var publishers = {};
    publishers["fi"] = publisherstring.match(firegex)[0].replaceAll("fi=", "");
    publishers["sv"] = publisherstring.match(svregex)[0].replaceAll("sv=", "");
    publishers["en"] = publisherstring.match(enregex)[0].replaceAll("en=", "");
    return publishers;
};

function isLocalizedString(s){
    return !!(s.includes("fi=") || s.includes("en=") || s.includes("sv="));

}

module.exports = dc2rtf;
<|endoftext|>