<commit_before>// type testing utility functions

;(function($$, window){ 'use strict';

  $$.is = {
    defined: function(obj){
      return obj != null; // not undefined or null
    },

    string: function(obj){
      return obj != null && typeof obj == typeof '';
    },

    fn: function(obj){
      return obj != null && typeof obj === typeof function(){};
    },

    array: function(obj){
      return Array.isArray ? Array.isArray(obj) : obj != null && obj instanceof Array;
    },

    plainObject: function(obj){
      return obj != null && typeof obj === typeof {} && !$$.is.array(obj) && obj.constructor === Object;
    },

    number: function(obj){
      return obj != null && typeof obj === typeof 1 && !isNaN(obj);
    },

    integer: function( obj ){
      return $$.is.number(obj) && Math.floor(obj) === obj;
    },

    color: function(obj){
      return obj != null && typeof obj === typeof '' && $.Color(obj).toString() !== '';
    },

    bool: function(obj){
      return obj != null && typeof obj === typeof true;
    },

    elementOrCollection: function(obj){
      return $$.is.element(obj) || $$.is.collection(obj);
    },

    element: function(obj){
      return obj instanceof $$.Element && obj._private.single;
    },

    collection: function(obj){
      return obj instanceof $$.Collection && !obj._private.single;
    },

    core: function(obj){
      return obj instanceof $$.Core;
    },

    style: function(obj){
      return obj instanceof $$.Style;
    },

    stylesheet: function(obj){
      return obj instanceof $$.Stylesheet;
    },

    event: function(obj){
      return obj instanceof $$.Event;
    },

    emptyString: function(obj){
      if( !obj ){ // null is empty
        return true;
      } else if( $$.is.string(obj) ){
        if( obj === '' || obj.match(/^\s+$/) ){
          return true; // empty string is empty
        }
      }

      return false; // otherwise, we don't know what we've got
    },

    nonemptyString: function(obj){
      if( obj && $$.is.string(obj) && obj !== '' && !obj.match(/^\s+$/) ){
        return true;
      }

      return false;
    },

    domElement: function(obj){
      if( typeof HTMLElement === 'undefined' ){
        return false; // we're not in a browser so it doesn't matter
      } else {
        return obj instanceof HTMLElement;
      }
    },

    boundingBox: function(obj){
      return $$.is.plainObject(obj) &&
        $$.is.number(obj.x1) && $$.is.number(obj.x2) &&
        $$.is.number(obj.y1) && $$.is.number(obj.y2)
      ;
    },

    touch: function(){
      return window && ( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch );
    },

    gecko: function(){
      return typeof InstallTrigger !== 'undefined' || ('MozAppearance' in document.documentElement.style);
    },

    webkit: function(){
      return typeof webkitURL !== 'undefined' || ('WebkitAppearance' in document.documentElement.style);
    },

    chromium: function(){
      return typeof chrome !== 'undefined';
    },

    khtml: function(){
      return navigator.vendor.match(/kde/i); // TODO probably a better way to detect this...
    },

    khtmlEtc: function(){
      return $$.is.khtml() || $$.is.webkit() || $$.is.blink();
    },

    trident: function(){
       return typeof ActiveXObject !== 'undefined' || /*@cc_on!@*/false;
    },

    windows: function(){
      return typeof navigator !== 'undefined' && navigator.appVersion.match(/Win/i);
    },

    mac: function(){
      return typeof navigator !== 'undefined' && navigator.appVersion.match(/Mac/i);
    },

    linux: function(){
      typeof navigator !== 'undefined' && navigator.appVersion.match(/Linux/i);
    },

    unix: function(){
      typeof navigator !== 'undefined' && navigator.appVersion.match(/X11/i);
    }
  };

})( cytoscape, typeof window === 'undefined' ? null : window );
<commit_msg>fix missing return<commit_after>// type testing utility functions

;(function($$, window){ 'use strict';

  $$.is = {
    defined: function(obj){
      return obj != null; // not undefined or null
    },

    string: function(obj){
      return obj != null && typeof obj == typeof '';
    },

    fn: function(obj){
      return obj != null && typeof obj === typeof function(){};
    },

    array: function(obj){
      return Array.isArray ? Array.isArray(obj) : obj != null && obj instanceof Array;
    },

    plainObject: function(obj){
      return obj != null && typeof obj === typeof {} && !$$.is.array(obj) && obj.constructor === Object;
    },

    number: function(obj){
      return obj != null && typeof obj === typeof 1 && !isNaN(obj);
    },

    integer: function( obj ){
      return $$.is.number(obj) && Math.floor(obj) === obj;
    },

    color: function(obj){
      return obj != null && typeof obj === typeof '' && $.Color(obj).toString() !== '';
    },

    bool: function(obj){
      return obj != null && typeof obj === typeof true;
    },

    elementOrCollection: function(obj){
      return $$.is.element(obj) || $$.is.collection(obj);
    },

    element: function(obj){
      return obj instanceof $$.Element && obj._private.single;
    },

    collection: function(obj){
      return obj instanceof $$.Collection && !obj._private.single;
    },

    core: function(obj){
      return obj instanceof $$.Core;
    },

    style: function(obj){
      return obj instanceof $$.Style;
    },

    stylesheet: function(obj){
      return obj instanceof $$.Stylesheet;
    },

    event: function(obj){
      return obj instanceof $$.Event;
    },

    emptyString: function(obj){
      if( !obj ){ // null is empty
        return true;
      } else if( $$.is.string(obj) ){
        if( obj === '' || obj.match(/^\s+$/) ){
          return true; // empty string is empty
        }
      }

      return false; // otherwise, we don't know what we've got
    },

    nonemptyString: function(obj){
      if( obj && $$.is.string(obj) && obj !== '' && !obj.match(/^\s+$/) ){
        return true;
      }

      return false;
    },

    domElement: function(obj){
      if( typeof HTMLElement === 'undefined' ){
        return false; // we're not in a browser so it doesn't matter
      } else {
        return obj instanceof HTMLElement;
      }
    },

    boundingBox: function(obj){
      return $$.is.plainObject(obj) &&
        $$.is.number(obj.x1) && $$.is.number(obj.x2) &&
        $$.is.number(obj.y1) && $$.is.number(obj.y2)
      ;
    },

    touch: function(){
      return window && ( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch );
    },

    gecko: function(){
      return typeof InstallTrigger !== 'undefined' || ('MozAppearance' in document.documentElement.style);
    },

    webkit: function(){
      return typeof webkitURL !== 'undefined' || ('WebkitAppearance' in document.documentElement.style);
    },

    chromium: function(){
      return typeof chrome !== 'undefined';
    },

    khtml: function(){
      return navigator.vendor.match(/kde/i); // TODO probably a better way to detect this...
    },

    khtmlEtc: function(){
      return $$.is.khtml() || $$.is.webkit() || $$.is.blink();
    },

    trident: function(){
       return typeof ActiveXObject !== 'undefined' || /*@cc_on!@*/false;
    },

    windows: function(){
      return typeof navigator !== 'undefined' && navigator.appVersion.match(/Win/i);
    },

    mac: function(){
      return typeof navigator !== 'undefined' && navigator.appVersion.match(/Mac/i);
    },

    linux: function(){
      return typeof navigator !== 'undefined' && navigator.appVersion.match(/Linux/i);
    },

    unix: function(){
      return typeof navigator !== 'undefined' && navigator.appVersion.match(/X11/i);
    }
  };

})( cytoscape, typeof window === 'undefined' ? null : window );
<|endoftext|>


<commit_before>var seaport = require('seaport-bridge');
var $ = require('zepto');
var fastclick = require('fastclick');
var common = require('../lib/common');
var spinner = common.spinner;
function showSpinner() {
  spinner.spin(document.body);
  $('.spinner').css({
    position: 'fixed'
  });
}

function hideSpinner() {
  spinner.stop()
}

function showError() {
  $('.error').removeClass('hide');
}

function hideError() {
  $('.error').addClass('hide');
}

function showCategory(){
  $('.category-list').addClass('spread');
}

function hideCategory(){
  $('.category-list').removeClass('spread');
}

function toggleCategory(){
  $('.category-list').toggleClass('spread');
}

seaport.connect(function dataHandler(data) {
  toggleCategory();
}, init);

function init(bridge) {
  var screenWidth = $(document).width();
  var loading = false;
  var designList = $('.design-list');
  var designTemplate = $('.design-template');
  var categoryList = $('.category-list');
  var categoryTemplate = $('.category-template');
  var more = $('.more');
  var pageToLoad = 1;
  var categoryToLoad = '';

  more.on('click', function() {
    loadData();
  })

  loadCategory();
  loadData();

  function loadCategory() {

    showSpinner()
    bridge.http.get({
      domain: common.domain,
      path: '/api/category'
    }, function(data) {
      if (!data) {
        hideSpinner();
        showError();
        return;
      }
      addCategoryToList('最新');
      data.forEach(function(data) {
        addCategoryToList(data);
      });
    })
  }

  function addCategoryToList(data) {
    var category = $(categoryTemplate.html());
    category.text(data);
    category.appendTo(categoryList);
    fastclick(category[0]);
    category.on('click', function() {
      $('.category').removeClass('active');
      $(this).addClass('active');
      categoryToLoad = $(this).text().trim();
      bridge.data.send({
        title:$(this).text().trim()
      });
      if (categoryToLoad == '最新') {
        categoryToLoad = '';
      }
      pageToLoad=1;
      loadData();
      hideCategory();

    });
  }

  function loadData() {
    if (loading) {
      return;
    }
    hideError();
    showSpinner();
    loading = true;
    bridge.http.get({
      domain: common.domain,
      path: '/api/design',
      params: {
        page: pageToLoad,
        category: categoryToLoad
      }
    }, function(data) {
      hideSpinner();
      loading = false;
      if (!data) {
        common.alert('网络连接错误');
        showError();
        return;
      }
      if(data.length==0){
        common.alert('没有更多咯');
        return;
      }
      if(pageToLoad==1){
        designList.empty();
        $(window).scrollTop(0);
      }
      data.forEach(function(data) {
        addDesignToList(data);
      });
      more.removeClass('hide');
      pageToLoad++;
    })
  }

  function addDesignToList(data) {
    var design = $(designTemplate.html());
    design.find('.title').text(data.title);
    design.find('.description').text(data.description);
    design.find('.likes .txt').text(data.favs||0);
    design.on('click', function() {
      hideCategory();
      bridge.data.send({
        segue: 'detail',
        data: data
      })
    });
    design.appendTo(designList);
    fastclick(design[0]);
    design.find('.thumb img')[0].onload = function() {
      this.style.opacity = 1;
      design.find('.loading').addClass('hide');
      setTimeout(function() {
        design.find('.likes').css('opacity', 1);
      }, 1300);
    }
    design.find('.thumb img').attr('src', data.thumb)
    return design;
  }

}<commit_msg>add most hot<commit_after>var seaport = require('seaport-bridge');
var $ = require('zepto');
var fastclick = require('fastclick');
var common = require('../lib/common');
var spinner = common.spinner;

function showSpinner() {
  spinner.spin(document.body);
  $('.spinner').css({
    position: 'fixed'
  });
}

function hideSpinner() {
  spinner.stop()
}

function showError() {
  $('.error').removeClass('hide');
}

function hideError() {
  $('.error').addClass('hide');
}

function showCategory() {
  $('.category-list').addClass('spread');
}

function hideCategory() {
  $('.category-list').removeClass('spread');
}

function toggleCategory() {
  $('.category-list').toggleClass('spread');
}

seaport.connect(function dataHandler(data) {
  toggleCategory();
}, init);

function init(bridge) {
  var screenWidth = $(document).width();
  var loading = false;
  var designList = $('.design-list');
  var designTemplate = $('.design-template');
  var categoryList = $('.category-list');
  var categoryTemplate = $('.category-template');
  var more = $('.more');
  var pageToLoad = 1;
  var categoryToLoad = '';
  var orderToLoad = '';

  more.on('click', function() {
    loadData();
  })

  loadCategory();
  loadData();

  function loadCategory() {

    showSpinner()
    bridge.http.get({
      domain: common.domain,
      path: '/api/category'
    }, function(data) {
      if (!data) {
        hideSpinner();
        showError();
        return;
      }
      addCategoryToList('最新');
      addCategoryToList('最赞');
      data.forEach(function(data) {
        addCategoryToList(data);
      });
    })
  }

  function addCategoryToList(data) {
    var category = $(categoryTemplate.html());
    category.text(data);
    category.appendTo(categoryList);
    fastclick(category[0]);
    category.on('click', function() {
      $('.category').removeClass('active');
      $(this).addClass('active');
      categoryToLoad = $(this).text().trim();
      bridge.data.send({
        title: $(this).text().trim()
      });
      orderToLoad = '';
      if (categoryToLoad == '最新') {
        categoryToLoad = '';
      } else if (categoryToLoad == '最赞') {
        categoryToLoad = '';
        orderToLoad = 'favs';
      }
      pageToLoad = 1;
      loadData();
      hideCategory();

    });
  }

  function loadData() {
    if (loading) {
      return;
    }
    hideError();
    showSpinner();
    loading = true;
    bridge.http.get({
      domain: common.domain,
      path: '/api/design',
      params: {
        page: pageToLoad,
        category: categoryToLoad,
        order:orderToLoad
      }
    }, function(data) {
      hideSpinner();
      loading = false;
      if (!data) {
        common.alert('网络连接错误');
        showError();
        return;
      }
      if (data.length == 0) {
        common.alert('没有更多咯');
        return;
      }
      if (pageToLoad == 1) {
        designList.empty();
        $(window).scrollTop(0);
      }
      data.forEach(function(data) {
        addDesignToList(data);
      });
      more.removeClass('hide');
      pageToLoad++;
    })
  }

  function addDesignToList(data) {
    var design = $(designTemplate.html());
    design.find('.title').text(data.title);
    design.find('.description').text(data.description);
    design.find('.likes .txt').text(data.favs || 0);
    design.on('click', function() {
      hideCategory();
      bridge.data.send({
        segue: 'detail',
        data: data
      })
    });
    design.appendTo(designList);
    fastclick(design[0]);
    design.find('.thumb img')[0].onload = function() {
      this.style.opacity = 1;
      design.find('.loading').addClass('hide');
      setTimeout(function() {
        design.find('.likes').css('opacity', 1);
      }, 1300);
    }
    design.find('.thumb img').attr('src', data.thumb)
    return design;
  }

}<|endoftext|>


<commit_before>/*
* Code adapted from here: http://codepen.io/miam84/pen/aNMryw
* Original code by BY Yann L
*/
function getMouseOffset (e, id) {
    var xpos, ypos;
    if (typeof e.offsetX === 'undefined') { // ff hack
        xpos = e.pageX - $('#' + id).offset().left; //dans ce cas, jQuery nécessaire pour l'appel d'offset
        ypos = e.pageY - $('#' + id).offset().top;
    } else {
        xpos = e.offsetX;
        ypos = e.offsetY;
    }
    return { x: xpos, y: ypos };
}

/**
* Extends Canvas element to use it as a paint element
*/
var extendCanvas = function (canvas) {
  if (typeof canvas === 'string') {
    canvas = document.getElementById(canvas);
  }
  try {
    canvas.ctx = canvas.getContext('2d');
    canvas.ctx.strokeStyle = "black";
    canvas.ctx.lineWidth = 5;
    canvas.lineJoin = "round";
    canvas.ctx.scale(1, 1);
    canvas.isLocked = false;
    canvas.hasDrawn = false;

    canvas.disableSave = true;
    canvas.pixels = [];
    canvas.cpixels = [];
    canvas.xyLast = {};
    canvas.xyAddLast = {};
    canvas.calculate = false;

    //start drawing a stroke from a position
    canvas.draw = function (x, y) {
      this.ctx.lineTo(x, y);
      this.ctx.stroke();
    };
    //Get the mouse position in the canvas
    canvas.getCursorCoords = function (e) {
      return getMouseOffset(e, this.id);
    };
    //Clear the content of the canvas element
    canvas.clear = function () {
      if (!this.isLocked) {
        this.ctx.clearRect(0, 0, this.width, this.height);
        this.emptyRelatedField();
        this.isModified(false);
      }
    };
    //Lock the canvas element
    canvas.lock = function (shouldLock) {
      this.isLocked = shouldLock;
      if (shouldLock) {
        $(this).addClass('disabled');
      } else {
        $(this).removeClass('disabled');
      }
    };
    canvas.isModified = function (wasModified) {
      if (wasModified) {
        this.fillRelatedField();
        $(this).addClass('modified');
      } else {
        this.emptyRelatedField();
        $(this).removeClass('modified');
      }
    };
    //Empty the field that contains the base64 string
    canvas.emptyRelatedField = function () {
      var relatedField = document.getElementById('data-' + this.id);
      if (relatedField) {
        relatedField.value = "";
      }
    };
    //Fill the filed that contains the base64 string
    canvas.fillRelatedField = function () {
      document.getElementById('data-' + this.id).value = this.toDataURL();
    };
    //Load a passed image
    canvas.loadImage = function (base64Img) {
      //if (!canvas.isLocked) {
      var image = new Image();
      var thisCanvas = this;
      if (base64Img.indexOf("data:image/png;base64,") === -1) {
        base64Img = "data:image/png;base64," + base64Img;
      }
      image.src = base64Img;
      image.onload = function () {
        var offset = { x: 0, y: 0 };
        //center the image in the canvas
        try {
          offset.x = ((thisCanvas.width / 2) - (image.width / 2));
          offset.y = ((thisCanvas.height / 2) - (image.height / 2));
          if (offset.x < 0 || offset.y < 0) {
            throw {
              name: "Painting error",
              message: "Image has a negative offset.",
              toString: function () { return this.name + ": " + this.message; }
            };
          }
        } catch (err) {
          offset = { x: 0, y: 0 };
        }
        thisCanvas.ctx.drawImage(image, offset.x, offset.y);
      };
    };

    /**
            * This method remove the event by default, to load them only when clicking in the canvas
            */
    function remove_event_listeners() {
      canvas.removeEventListener('mousemove', on_mousemove, false);
      canvas.removeEventListener('mouseup', on_mouseup, false);
      canvas.removeEventListener('touchmove', on_mousemove, false);
      canvas.removeEventListener('touchend', on_mouseup, false);
      document.body.removeEventListener('mouseup', on_mouseup, false);
      document.body.removeEventListener('touchend', on_mouseup, false);
    };
    //Event when the mouse is clicked
    function on_mousedown(e) {
      if (!canvas.isLocked) {
        e.preventDefault();
        e.stopPropagation();

        canvas.hasDrawn = false;
        //we activate the mouse and touch events
        canvas.addEventListener('mouseup', on_mouseup, false);
        canvas.addEventListener('mousemove', on_mousemove, false);
        canvas.addEventListener('touchend', on_mouseup, false);
        canvas.addEventListener('touchmove', on_mousemove, false);
        document.body.addEventListener('mouseup', on_mouseup, false);
        document.body.addEventListener('touchend', on_mouseup, false);

        var xy = canvas.getCursorCoords(e);
        canvas.ctx.beginPath();
        canvas.pixels.push('moveStart');
        canvas.ctx.moveTo(xy.x, xy.y);
        canvas.pixels.push(xy.x, xy.y);
        canvas.xyLast = xy;
      }
    };
    //Event when the mouse is moving.
    function on_mousemove(e, finish) {
      if (!canvas.isLocked) {
        e.preventDefault();
        e.stopPropagation();

        canvas.hasDrawn = true;
        var xy = canvas.getCursorCoords(e);
        var xyAdd = {
          x: (canvas.xyLast.x + xy.x) / 2,
          y: (canvas.xyLast.y + xy.y) / 2
        };
        if (canvas.calculate) {
          var xLast = (canvas.xyAddLast.x + canvas.xyLast.x + xyAdd.x) / 3;
          var yLast = (canvas.xyAddLast.y + canvas.xyLast.y + xyAdd.y) / 3;
          canvas.pixels.push(xLast, yLast);
        } else {
          canvas.calculate = true;
        }
        canvas.ctx.quadraticCurveTo(canvas.xyLast.x, canvas.xyLast.y, xyAdd.x, xyAdd.y);
        canvas.pixels.push(xyAdd.x, xyAdd.y);
        canvas.ctx.stroke();
        canvas.ctx.beginPath();
        canvas.ctx.moveTo(xyAdd.x, xyAdd.y);
        canvas.xyAddLast = xyAdd;
        canvas.xyLast = xy;
      }
    };
    //Event when the click is released
    function on_mouseup(e) {
      if (!canvas.isLocked) {
        if (!canvas.hasDrawn) {//If there was no move, draw a single point
          var pos = canvas.getCursorCoords(e);
          canvas.ctx.rect(pos.x, pos.y, 1, 1);
        }
        remove_event_listeners();
        canvas.disableSave = false;
        canvas.ctx.stroke();
        canvas.pixels.push('e');
        canvas.calculate = false;
        canvas.isModified(true);
        canvas.hasDrawn = false;
      }
    };
    //We activate only the click or touch event.
    // ReSharper disable once Html.EventNotResolved correspond à un événement de toucher sur écran tactile
    canvas.addEventListener('touchstart', on_mousedown, false);
    canvas.addEventListener('mousedown', on_mousedown, false);

  } catch (err) {
    //If someting went wrong, notify the user.
    console.error("Canvas not initialized. Painting is not activated.");
  }

  return canvas;
};

var myC = extendCanvas('paint');
$('#clear').on('click', (e) => {
  myC.clear();
  myC.emptyRelatedField();
});<commit_msg>Changed line width<commit_after>/*
* Code adapted from here: http://codepen.io/miam84/pen/aNMryw
* Original code by BY Yann L
*/
function getMouseOffset (e, id) {
    var xpos, ypos;
    if (typeof e.offsetX === 'undefined') { // ff hack
        xpos = e.pageX - $('#' + id).offset().left; //dans ce cas, jQuery nécessaire pour l'appel d'offset
        ypos = e.pageY - $('#' + id).offset().top;
    } else {
        xpos = e.offsetX;
        ypos = e.offsetY;
    }
    return { x: xpos, y: ypos };
}

/**
* Extends Canvas element to use it as a paint element
*/
var extendCanvas = function (canvas) {
  if (typeof canvas === 'string') {
    canvas = document.getElementById(canvas);
  }
  try {
    canvas.ctx = canvas.getContext('2d');
    canvas.ctx.strokeStyle = "black";
    canvas.ctx.lineWidth = 4;
    canvas.lineJoin = "round";
    canvas.ctx.scale(1, 1);
    canvas.isLocked = false;
    canvas.hasDrawn = false;

    canvas.disableSave = true;
    canvas.pixels = [];
    canvas.cpixels = [];
    canvas.xyLast = {};
    canvas.xyAddLast = {};
    canvas.calculate = false;

    //start drawing a stroke from a position
    canvas.draw = function (x, y) {
      this.ctx.lineTo(x, y);
      this.ctx.stroke();
    };
    //Get the mouse position in the canvas
    canvas.getCursorCoords = function (e) {
      return getMouseOffset(e, this.id);
    };
    //Clear the content of the canvas element
    canvas.clear = function () {
      if (!this.isLocked) {
        this.ctx.clearRect(0, 0, this.width, this.height);
        this.emptyRelatedField();
        this.isModified(false);
      }
    };
    //Lock the canvas element
    canvas.lock = function (shouldLock) {
      this.isLocked = shouldLock;
      if (shouldLock) {
        $(this).addClass('disabled');
      } else {
        $(this).removeClass('disabled');
      }
    };
    canvas.isModified = function (wasModified) {
      if (wasModified) {
        this.fillRelatedField();
        $(this).addClass('modified');
      } else {
        this.emptyRelatedField();
        $(this).removeClass('modified');
      }
    };
    //Empty the field that contains the base64 string
    canvas.emptyRelatedField = function () {
      var relatedField = document.getElementById('data-' + this.id);
      if (relatedField) {
        relatedField.value = "";
      }
    };
    //Fill the filed that contains the base64 string
    canvas.fillRelatedField = function () {
      document.getElementById('data-' + this.id).value = this.toDataURL();
    };
    //Load a passed image
    canvas.loadImage = function (base64Img) {
      //if (!canvas.isLocked) {
      var image = new Image();
      var thisCanvas = this;
      if (base64Img.indexOf("data:image/png;base64,") === -1) {
        base64Img = "data:image/png;base64," + base64Img;
      }
      image.src = base64Img;
      image.onload = function () {
        var offset = { x: 0, y: 0 };
        //center the image in the canvas
        try {
          offset.x = ((thisCanvas.width / 2) - (image.width / 2));
          offset.y = ((thisCanvas.height / 2) - (image.height / 2));
          if (offset.x < 0 || offset.y < 0) {
            throw {
              name: "Painting error",
              message: "Image has a negative offset.",
              toString: function () { return this.name + ": " + this.message; }
            };
          }
        } catch (err) {
          offset = { x: 0, y: 0 };
        }
        thisCanvas.ctx.drawImage(image, offset.x, offset.y);
      };
    };

    /**
            * This method remove the event by default, to load them only when clicking in the canvas
            */
    function remove_event_listeners() {
      canvas.removeEventListener('mousemove', on_mousemove, false);
      canvas.removeEventListener('mouseup', on_mouseup, false);
      canvas.removeEventListener('touchmove', on_mousemove, false);
      canvas.removeEventListener('touchend', on_mouseup, false);
      document.body.removeEventListener('mouseup', on_mouseup, false);
      document.body.removeEventListener('touchend', on_mouseup, false);
    };
    //Event when the mouse is clicked
    function on_mousedown(e) {
      if (!canvas.isLocked) {
        e.preventDefault();
        e.stopPropagation();

        canvas.hasDrawn = false;
        //we activate the mouse and touch events
        canvas.addEventListener('mouseup', on_mouseup, false);
        canvas.addEventListener('mousemove', on_mousemove, false);
        canvas.addEventListener('touchend', on_mouseup, false);
        canvas.addEventListener('touchmove', on_mousemove, false);
        document.body.addEventListener('mouseup', on_mouseup, false);
        document.body.addEventListener('touchend', on_mouseup, false);

        var xy = canvas.getCursorCoords(e);
        canvas.ctx.beginPath();
        canvas.pixels.push('moveStart');
        canvas.ctx.moveTo(xy.x, xy.y);
        canvas.pixels.push(xy.x, xy.y);
        canvas.xyLast = xy;
      }
    };
    //Event when the mouse is moving.
    function on_mousemove(e, finish) {
      if (!canvas.isLocked) {
        e.preventDefault();
        e.stopPropagation();

        canvas.hasDrawn = true;
        var xy = canvas.getCursorCoords(e);
        var xyAdd = {
          x: (canvas.xyLast.x + xy.x) / 2,
          y: (canvas.xyLast.y + xy.y) / 2
        };
        if (canvas.calculate) {
          var xLast = (canvas.xyAddLast.x + canvas.xyLast.x + xyAdd.x) / 3;
          var yLast = (canvas.xyAddLast.y + canvas.xyLast.y + xyAdd.y) / 3;
          canvas.pixels.push(xLast, yLast);
        } else {
          canvas.calculate = true;
        }
        canvas.ctx.quadraticCurveTo(canvas.xyLast.x, canvas.xyLast.y, xyAdd.x, xyAdd.y);
        canvas.pixels.push(xyAdd.x, xyAdd.y);
        canvas.ctx.stroke();
        canvas.ctx.beginPath();
        canvas.ctx.moveTo(xyAdd.x, xyAdd.y);
        canvas.xyAddLast = xyAdd;
        canvas.xyLast = xy;
      }
    };
    //Event when the click is released
    function on_mouseup(e) {
      if (!canvas.isLocked) {
        if (!canvas.hasDrawn) {//If there was no move, draw a single point
          var pos = canvas.getCursorCoords(e);
          canvas.ctx.rect(pos.x, pos.y, 1, 1);
        }
        remove_event_listeners();
        canvas.disableSave = false;
        canvas.ctx.stroke();
        canvas.pixels.push('e');
        canvas.calculate = false;
        canvas.isModified(true);
        canvas.hasDrawn = false;
      }
    };
    //We activate only the click or touch event.
    // ReSharper disable once Html.EventNotResolved correspond à un événement de toucher sur écran tactile
    canvas.addEventListener('touchstart', on_mousedown, false);
    canvas.addEventListener('mousedown', on_mousedown, false);

  } catch (err) {
    //If someting went wrong, notify the user.
    console.error("Canvas not initialized. Painting is not activated.");
  }

  return canvas;
};

var myC = extendCanvas('paint');
$('#clear').on('click', (e) => {
  myC.clear();
  myC.emptyRelatedField();
});<|endoftext|>


<commit_before>$(function () {
    $('#datetimepicker').datetimepicker({
        format: 'YYYY-MM-DD HH:mm:ss',
        locale: 'es'

    });
});

$(function () {
    $('#datetimepicker2').datetimepicker({
        format: 'YYYY-MM-DD HH:mm:ss',
        locale: 'es'
    });
});

function ConfirmDelete() {
    var x = confirm("¿Seguro que quiere cancelar la orden?");
    if (x)
        return true;
    else
        return false;
};<commit_msg>change message alert in report update<commit_after>$(function () {
    $('#datetimepicker').datetimepicker({
        format: 'YYYY-MM-DD HH:mm:ss',
        locale: 'es'

    });
});

$(function () {
    $('#datetimepicker2').datetimepicker({
        format: 'YYYY-MM-DD HH:mm:ss',
        locale: 'es'
    });
});

function ConfirmDelete() {
    var x = confirm("¿Está seguro en cancelar la orden?");
    if (x)
        return true;
    else
        return false;
};<|endoftext|>


<commit_before>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

const cp = require('child_process');
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';

function npmInstall(location) {
	const result = cp.spawnSync(npm, ['install'], {
		cwd: location ,
		stdio: 'inherit'
	});

	if (result.error || result.status !== 0) {
		process.exit(1);
	}
}

npmInstall('extensions'); // node modules shared by all extensions

const extensions = [
	'vscode-api-tests',
	'vscode-colorize-tests',
	'json',
	'configuration-editing',
	'extension-editing',
	'markdown',
	'typescript',
	'php',
	'javascript',
	'css',
	'html',
	'git',
	'gulp',
	'grunt',
	'jake'
];

extensions.forEach(extension => npmInstall(`extensions/${extension}`));

npmInstall(`build`); // node modules required for build<commit_msg>Add merge-conflict extension to postInstall<commit_after>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

const cp = require('child_process');
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';

function npmInstall(location) {
	const result = cp.spawnSync(npm, ['install'], {
		cwd: location ,
		stdio: 'inherit'
	});

	if (result.error || result.status !== 0) {
		process.exit(1);
	}
}

npmInstall('extensions'); // node modules shared by all extensions

const extensions = [
	'vscode-api-tests',
	'vscode-colorize-tests',
	'json',
	'configuration-editing',
	'extension-editing',
	'markdown',
	'typescript',
	'php',
	'javascript',
	'css',
	'html',
	'git',
	'gulp',
	'grunt',
	'jake',
	'merge-conflict'
];

extensions.forEach(extension => npmInstall(`extensions/${extension}`));

npmInstall(`build`); // node modules required for build<|endoftext|>


<commit_before>module.exports = function( grunt ) {

"use strict";

var versions = {
		"git": "git",
		"1.10": "1.10.0 1.10.1 1.10.2",
		"1.9": "1.9.0 1.9.1",
		"1.8": "1.8.0 1.8.1 1.8.2 1.8.3",
		"1.7": "1.7 1.7.1 1.7.2",
		"1.6": "1.6 1.6.1 1.6.2 1.6.3 1.6.4"
	},
	tests = {
		"Accordion": "accordion/accordion.html",
		"Autocomplete": "autocomplete/autocomplete.html",
		"Button": "button/button.html",
		"Core": "core/core.html",
		"Core_deprecated": "core/core_deprecated.html",
		"Datepicker": "datepicker/datepicker.html",
		"Dialog": "dialog/dialog.html",
		"Draggable": "draggable/draggable.html",
		"Droppable": "droppable/droppable.html",
		"Effects": "effects/effects.html",
		"Menu": "menu/menu.html",
		"Position": "position/position.html",
		"Progressbar": "progressbar/progressbar.html",
		"Resizable": "resizable/resizable.html",
		"Selectable": "selectable/selectable.html",
		"Slider": "slider/slider.html",
		"Sortable": "sortable/sortable.html",
		"Spinner": "spinner/spinner.html",
		"Tabs": "tabs/tabs.html",
		"Tooltip": "tooltip/tooltip.html",
		"Widget": "widget/widget.html"
	};

function submit( commit, runs, configFile, extra, done ) {
	var testName,
		testswarm = require( "testswarm" ),
		config = grunt.file.readJSON( configFile ).jqueryui,
		commitUrl = "https://github.com/jquery/jquery-ui/commit/" + commit;

	if ( extra ) {
		extra = " (" + extra + ")";
	}

	for ( testName in runs ) {
		runs[ testName ] = config.testUrl + commit + "/tests/unit/" + runs[ testName ];
	}

	testswarm.createClient({
		url: config.swarmUrl,
		pollInterval: 10000,
		timeout: 1000 * 60 * 45
	})
	.addReporter( testswarm.reporters.cli )
	.auth({
		id: config.authUsername,
		token: config.authToken
	})
	.addjob({
		name: "Commit " + commit.substr( 0, 10 ) + "" + extra,
		runs: runs,
		runMax: config.runMax,
		browserSets: config.browserSets
	}, function( error, passed ) {
		if ( error ) {
			grunt.log.error( error );
		}
		done( passed );
	});
}

grunt.registerTask( "testswarm", function( commit, configFile ) {
	var test,
		latestTests = {};
	for ( test in tests ) {
		latestTests[ test ] = tests[ test ] + "?nojshint=true";
	}
	submit( commit, latestTests, configFile, false, this.async() );
});

grunt.registerTask( "testswarm-multi-jquery", function( commit, configFile, minor ) {
	var allTests = {};
	versions[ minor ].split(" ").forEach(function( version ) {
		for ( var test in tests ) {
			allTests[ test + "-" + version ] = tests[ test ] + "?nojshint=true&jquery=" + version;
		}
	});
	submit( commit, allTests, configFile, "core " + minor, this.async() );
});

};
<commit_msg>Build: Fixed TestSwarm submission.<commit_after>module.exports = function( grunt ) {

"use strict";

var versions = {
		"git": "git",
		"1.10": "1.10.0 1.10.1 1.10.2",
		"1.9": "1.9.0 1.9.1",
		"1.8": "1.8.0 1.8.1 1.8.2 1.8.3",
		"1.7": "1.7 1.7.1 1.7.2",
		"1.6": "1.6 1.6.1 1.6.2 1.6.3 1.6.4"
	},
	tests = {
		"Accordion": "accordion/accordion.html",
		"Autocomplete": "autocomplete/autocomplete.html",
		"Button": "button/button.html",
		"Core": "core/core.html",
		"Core_deprecated": "core/core_deprecated.html",
		"Datepicker": "datepicker/datepicker.html",
		"Dialog": "dialog/dialog.html",
		"Draggable": "draggable/draggable.html",
		"Droppable": "droppable/droppable.html",
		"Effects": "effects/effects.html",
		"Menu": "menu/menu.html",
		"Position": "position/position.html",
		"Progressbar": "progressbar/progressbar.html",
		"Resizable": "resizable/resizable.html",
		"Selectable": "selectable/selectable.html",
		"Slider": "slider/slider.html",
		"Sortable": "sortable/sortable.html",
		"Spinner": "spinner/spinner.html",
		"Tabs": "tabs/tabs.html",
		"Tooltip": "tooltip/tooltip.html",
		"Widget": "widget/widget.html"
	};

function submit( commit, runs, configFile, extra, done ) {
	var testName,
		testswarm = require( "testswarm" ),
		config = grunt.file.readJSON( configFile ).jqueryui,
		commitUrl = "https://github.com/jquery/jquery-ui/commit/" + commit;

	if ( extra ) {
		extra = " (" + extra + ")";
	}

	for ( testName in runs ) {
		runs[ testName ] = config.testUrl + commit + "/tests/unit/" + runs[ testName ];
	}

	testswarm.createClient({
		url: config.swarmUrl,
		pollInterval: 10000,
		timeout: 1000 * 60 * 45
	})
	.addReporter( testswarm.reporters.cli )
	.auth({
		id: config.authUsername,
		token: config.authToken
	})
	.addjob({
		name: "Commit " + commit.substr( 0, 10 ) + "" + extra,
		runs: runs,
		runMax: config.runMax,
		browserSets: config.browserSets
	}, function( error, passed ) {
		if ( error ) {
			grunt.log.error( error );
		}
		done( passed );
	});
}

grunt.registerTask( "testswarm", function( commit, configFile ) {
	var test,
		latestTests = {};
	for ( test in tests ) {
		latestTests[ test ] = tests[ test ] + "?nojshint=true";
	}
	submit( commit, latestTests, configFile, "", this.async() );
});

grunt.registerTask( "testswarm-multi-jquery", function( commit, configFile, minor ) {
	var allTests = {};
	versions[ minor ].split(" ").forEach(function( version ) {
		for ( var test in tests ) {
			allTests[ test + "-" + version ] = tests[ test ] + "?nojshint=true&jquery=" + version;
		}
	});
	submit( commit, allTests, configFile, "core " + minor, this.async() );
});

};
<|endoftext|>


<commit_before>'use strict';

var React = require('react-native');
var {Component, PropTypes, TouchableOpacity, StyleSheet, View, Text} = React;
var UIManager = require('NativeModules').UIManager;

var noop = () => {};

class SectionList extends Component {

  constructor(props, context) {
    super(props, context);

    this.onSectionSelect = this.onSectionSelect.bind(this);
    this.lastSelectedIndex = null;
  }

  onSectionSelect(sectionId, fromTouch) {
    this.props.onPress && this.props.onPress(sectionId);

    if (!fromTouch) {
      this.lastSelectedIndex = null;
    }
  }

  render() {
    var SectionComponent = this.props.component;
    var sections = this.props.sections.map((section, index) => {
      var title = this.props.getSectionListTitle ?
        this.props.getSectionListTitle(section) :
        section;

      return SectionComponent ?
        <SectionComponent
          key={index}
          sectionId={section}
          title={title}
          onPress={this.onSectionSelect}
        /> :
        <TouchableOpacity
          key={index}
          onPress={() => this.onSectionSelect(section)}>
          <View style={styles.item}><Text style={styles.text}>{title}</Text></View>
        </TouchableOpacity>;
    });

    return (
      <View style={[styles.container, this.props.style]} onMoveShouldSetResponder={(e) => {
          var ev = e.nativeEvent;
          var rect = {width:1, height:1, x: ev.locationX, y: ev.locationY};
          UIManager.measureViewsInRect(rect, e.target, noop, (frames) => {
            if (frames.length) {
              var index = frames[0].index;
              if (this.lastSelectedIndex !== index) {
                this.lastSelectedIndex = index;
                this.onSectionSelect(this.props.sections[index], true);
              }
            }
          });
        }} >
        {sections}
      </View>
    );
  }
}

SectionList.propTypes = {

  /**
   * A component to render for each section item
   */
  component: PropTypes.func,

  /**
   * Function to provide a title the section list items.
   */
  getSectionListTitle: PropTypes.func,

  /**
   * Function to be called upon pressing a sction list item
   */
  onPress: PropTypes.func,

  /**
   * The sections to render
   */
  sections: PropTypes.array.isRequired,

  /**
   * A style to apply to the section list container
   */
  style: PropTypes.oneOfType([
    PropTypes.number,
    PropTypes.object,
  ])
};

var styles = StyleSheet.create({
  container: {
    position: 'absolute',
    backgroundColor: 'transparent',
    alignItems:'center',
    justifyContent:'center',
    right: 0,
    top: 0,
    bottom: 0,
    width: 15
  },

  item: {
    padding: 0
  },

  text: {
    fontWeight: '700',
    color: '#008fff'
  }
});

module.exports = SectionList;
<commit_msg>Moved view detection into own method and using correct prop to respond now<commit_after>'use strict';

var React = require('react-native');
var {Component, PropTypes, TouchableOpacity, StyleSheet, View, Text} = React;
var UIManager = require('NativeModules').UIManager;

var noop = () => {};
var returnTrue = () => true;

class SectionList extends Component {

  constructor(props, context) {
    super(props, context);

    this.onSectionSelect = this.onSectionSelect.bind(this);
    this.detectAndScrollToSection = this.detectAndScrollToSection.bind(this);
    this.lastSelectedIndex = null;
  }

  onSectionSelect(sectionId, fromTouch) {
    this.props.onPress && this.props.onPress(sectionId);

    if (!fromTouch) {
      this.lastSelectedIndex = null;
    }
  }

  detectAndScrollToSection(e) {
    var ev = e.nativeEvent;
    var rect = {width:1, height:1, x: ev.locationX, y: ev.locationY};
    UIManager.measureViewsInRect(rect, e.target, noop, (frames) => {
      if (frames.length) {
        var index = frames[0].index;
        if (this.lastSelectedIndex !== index) {
          this.lastSelectedIndex = index;
          this.onSectionSelect(this.props.sections[index], true);
        }
      }
    });
  }

  render() {
    var SectionComponent = this.props.component;
    var sections = this.props.sections.map((section, index) => {
      var title = this.props.getSectionListTitle ?
        this.props.getSectionListTitle(section) :
        section;

      return SectionComponent ?
        <SectionComponent
          key={index}
          sectionId={section}
          title={title}
          onPress={this.onSectionSelect}
        /> :
        <TouchableOpacity
          key={index}
          onPress={() => this.onSectionSelect(section)}>
          <View style={styles.item}><Text style={styles.text}>{title}</Text></View>
        </TouchableOpacity>;
    });

    return (
      <View style={[styles.container, this.props.style]}
        onMoveShouldSetResponder={returnTrue}
        onResponderMove={this.detectAndScrollToSection}>
        {sections}
      </View>
    );
  }
}

SectionList.propTypes = {

  /**
   * A component to render for each section item
   */
  component: PropTypes.func,

  /**
   * Function to provide a title the section list items.
   */
  getSectionListTitle: PropTypes.func,

  /**
   * Function to be called upon pressing a sction list item
   */
  onPress: PropTypes.func,

  /**
   * The sections to render
   */
  sections: PropTypes.array.isRequired,

  /**
   * A style to apply to the section list container
   */
  style: PropTypes.oneOfType([
    PropTypes.number,
    PropTypes.object,
  ])
};

var styles = StyleSheet.create({
  container: {
    position: 'absolute',
    backgroundColor: 'transparent',
    alignItems:'center',
    justifyContent:'center',
    right: 0,
    top: 0,
    bottom: 0,
    width: 15
  },

  item: {
    padding: 0
  },

  text: {
    fontWeight: '700',
    color: '#008fff'
  }
});

module.exports = SectionList;
<|endoftext|>


<commit_before>angular.module('opal.controllers').controller(
    'EpisodeListCtrl', function($scope, $q, $http, $cookieStore,
                                $location, $routeParams,
                                $modal, $rootScope,
                                Flow, Item,
                                Episode, schema, episodes, options,
                                profile,
                                episodeVisibility){

        var version = window.version;
        $scope.state = 'normal';
        $scope.url = $location.url()

	    $scope.rix = 0; // row index
	    $scope.cix = 0; // column index
	    $scope.iix = 0; // item index

	    $scope.mouseRix = -1; // index of row mouse is currently over
	    $scope.mouseCix = -1; // index of column mouse is currently over
        $scope._ =  _;

	    $scope.query = {hospital_number: '', name: '', ward: '', bed: ''};
        $scope.$location = $location;

        $scope.path_base = '/list/';

        if(!$routeParams.tag){
            var tag =  $cookieStore.get('opal.currentTag') || _.keys(options.tag_hierarchy)[0];
            $location.path($scope.path_base + tag);
            return
        }
        $scope.currentTag = $routeParams.tag;

        if(!$routeParams.subtag){
            // We now force redirect to the first subtag if there is one
            if($scope.currentTag in options.tag_hierarchy &&
               options.tag_hierarchy[$scope.currentTag].length > 0){
                var subtag = options.tag_hierarchy[$scope.currentTag][0];
                var target = $scope.path_base + $scope.currentTag + '/' + subtag;
                $location.path(target);
                return
            }else{
                $scope.currentSubTag = 'all';
            }
        }else{
            $scope.currentSubTag = $routeParams.subtag;
        }
        $scope.columns = schema.columns;

        $scope.profile = profile;
        $scope.tag_display = options.tag_display;

	    function getVisibleEpisodes() {
		    var visibleEpisodes = [];
            var episode_list = [];

            visibleEpisodes = _.filter(episodes, function(episode){
                return episodeVisibility(episode, $scope)
            });
		    visibleEpisodes.sort(compareEpisodes);
		    return visibleEpisodes;
	    };

	    $scope.rows = getVisibleEpisodes();

	    function compareEpisodes(p1, p2) {
		    return p1.compare(p2);
	    };

        $scope.jumpToTag = function(tag){
            if(_.contains(_.keys(options.tag_hierarchy), tag)){
                $location.path($scope.path_base + tag)
            }else{

                for(var prop in options.tag_hierarchy){
                    if(options.tag_hierarchy.hasOwnProperty(prop)){
                        if(_.contains(_.values(options.tag_hierarchy[prop]), tag)){
                            $location.path($scope.path_base + prop + '/' + tag)
                        }
                    }
                }

            };
        }

        $scope.otherTags = function(episode){
            tags = episode.getTags();
            return _.filter(tags, function(t){
                if(t in options.tag_hierarchy &&
                   options.tag_hierarchy[t].length > 0){ return false };
                if(t == $scope.currentTag){ return false };
                if(t == $scope.currentSubTag){ return false };
                return true
            });
        }

	    $scope.$watch('currentTag', function() {
		    $cookieStore.put('opal.currentTag', $scope.currentTag);
            if($scope.currentTag != $routeParams.tag){
                $scope.state = 'reloading'
            }
            var target = $scope.path_base +  $scope.currentTag;

            $location.path(target);
	    });

	    $scope.$watch('currentSubTag', function(){
		    $cookieStore.put('opal.currentSubTag', $scope.currentSubTag);
            if($scope.currentSubTag == 'all'){
                if($routeParams.subtag && $scope.currentSubTag != $routeParams.subtag){
                    $scope.state = 'reloading'
                }
                $location.path($scope.path_base +  $scope.currentTag);
            }else{
                if($scope.currentSubTag != $routeParams.subtag){
                    $scope.state = 'reloading'
                }
                $location.path($scope.path_base +  $scope.currentTag + '/' +  $scope.currentSubTag);
            }
	    });

        $scope.showSubtags = function(withsubtags){
            var show =  _.contains(withsubtags, $scope.currentTag);
            return show
        };

	    $scope.$watch('query.hospital_number', function() {
		    $scope.rows = getVisibleEpisodes();
	    });

	    $scope.$watch('query.ward', function() {
		    $scope.rows = getVisibleEpisodes();
	    });

	    $scope.$watch('query.bed', function() {
		    $scope.rows = getVisibleEpisodes();
	    });

	    $scope.$watch('query.name', function() {
		    $scope.rows = getVisibleEpisodes();
	    });

	    $scope.$on('keydown', function(event, e) {
		    if ($scope.state == 'normal') {
			    switch (e.keyCode) {
			    case 37: // left
				    goLeft();
				    break;
			    case 39: // right
				    goRight();
				    break;
			    case 38: // up
				    goUp();
				    break;
			    case 40: // down
				    goDown();
				    break;
			    case 13: // enter
			    case 113: // F2
				    $scope.editItem($scope.rix, $scope.cix, $scope.iix);
                    e.preventDefault();
				    break;
			    case 8: // backspace
				    e.preventDefault();
			    case 46: // delete
				    $scope.deleteItem($scope.rix, $scope.cix, $scope.iix);
				    break;
			    case 191: // question mark
				    if(e.shiftKey){
					    showKeyboardShortcuts();
				    }
				    break;
                case 78: // n
                    $scope.addEpisode();
                    e.preventDefault();
                    break;
			    };
		    };
	    });

	    function getColumnName(cix) {
		    return $scope.columns[cix].name;
	    };

	    function getRowIxFromEpisodeId(episodeId) {
		    for (var rix = 0; rix < $scope.rows.length; rix++) {
			    if ($scope.rows[rix].id == episodeId) {
				    return rix;
			    }
		    };
		    return -1;
	    };

	    function getEpisode(rix) {
		    return $scope.rows[rix];
	    };

	    $scope.print = function() {
		    window.print();
	    };

	    $scope.selectItem = function(rix, cix, iix) {
		    $scope.rix = rix;
		    $scope.cix = cix;
		    $scope.iix = iix;
	    };

	    $scope.focusOnQuery = function() {
		    $scope.selectItem(-1, -1, -1);
		    $scope.state = 'search';
	    };

	    $scope.blurOnQuery = function() {
		    if ($scope.rix == -1) {
			    $scope.selectItem(0, 0, 0);
		    };
		    $scope.state = 'normal';
	    };

	    $scope.addEpisode = function() {
            if(profile.readonly){ return null; };

            var enter = Flow(
                'enter', schema, options,
                {
                    current_tags: {
                        tag: $scope.currentTag,
                        subtag: $scope.currentSubTag
                    }
                }
            );

		    $scope.state = 'modal';

            enter.then(
                function(episode) {
		            // User has either retrieved an existing episode or created a new one,
		            // or has cancelled the process at some point.
		            //
		            // This ensures that the relevant episode is added to the table and
		            // selected.
		            var rowIx;
		            $scope.state = 'normal';
		            if (episode && episode != 'cancel') {
			            episodes[episode.id] = episode;
			            $scope.rows = getVisibleEpisodes();
			            rowIx = getRowIxFromEpisodeId(episode.id);
			            $scope.selectItem(rowIx, 0, 0);
		            };
	            },
                function(reason){
                    // The modal has been dismissed. Practically speaking this means
                    // that the Angular UI called dismiss rather than our cancel()
                    // method on the OPAL controller. We just need to re-set in order
                    // to re-enable keybard listeners.
                    $scope.state = 'normal';
                });
	    };

	    $scope.dischargeEpisode = function(rix, event) {
		    var episode = getEpisode(rix);

            if(profile.readonly){ return null; };

		    event.preventDefault();// Required to prevent the page reloading
		    $scope.state = 'modal';

            var exit = Flow(
                'exit', schema, options,
                {
                    current_tags: {
                        tag   : $scope.currentTag,
                        subtag: $scope.currentSubTag
                    },
                    episode: episode
                }
            );

            exit.then(function(result) {
			    $scope.state = 'normal';

			    if (result == 'discharged' | result == 'moved') {
				    $scope.rows = getVisibleEpisodes();
				    $scope.selectItem(0, $scope.cix, 0);
			    };
		    });
	    };

        // TODO: Test This!
        $scope.removeFromMine = function(rix, event){
            if(profile.readonly){
                return null;
            };

            event.preventDefault();

            var modal;
            var episode = getEpisode(rix);
            var tagging = episode.tagging[0];
            editing = tagging.makeCopy();
            editing.mine = false;
            tagging.save(editing).then(function(result){
                $scope.rows = getVisibleEpisodes();
            })

        };

        _openEditItemModal = function(item, columnName, episode) {
            if(profile.readonly){
                return null;
            };
            $scope.state = 'modal';
            var template_url = '/templates/modals/' + columnName + '.html/';
            template_url += $scope.currentTag + '/' + $scope.currentSubTag;

            modal = $modal.open({
                templateUrl: template_url,
                controller: 'EditItemCtrl',
                resolve: {
                    item: function() { return item; },
                    options: function() { return options; },
                    profile: function() { return profile; },
                    episode: function() { return episode; }
                }
            });

            modal.result.then(function(result) {
                $scope.state = 'normal';

                if (columnName == 'tagging') {
                    // User may have removed current tag
                    $scope.rows = getVisibleEpisodes();
                    $scope.selectItem(getRowIxFromEpisodeId(episode.id), $scope.cix, 0);
                }

                if (result == 'save-and-add-another') {
                    $scope.newNamedItem(episode, columnName);
                    return
                };
                if (item.sort){
                    episode.sortColumn(item.columnName, item.sort);
                };
            }, function(){
                $scope.state = 'normal';
            });
        }

        $scope.newNamedItem = function(episode, name) {
            var item = episode.newItem(name, {column: $rootScope.fields[name]});
            if (!episode[name]) {
                episode[name] = [];
            }
            episode[name].push(item);
            return _openEditItemModal(item, name, episode);
        }

        $scope.editNamedItem = function(episode, name, iix) {
            var item;
            if (episode[name][iix] && episode[name][iix].columnName) {
                item = episode[name][iix];
            } else {
                item = new Item(episode[name][iix], episode, $rootScope.fields[name]);
                episode[name][iix] = item;
            }

            return _openEditItemModal(item, name, episode);
        }

	    $scope.editItem = function(rix, cix, iix) {
		    var columnName = getColumnName(cix);
		    var episode = getEpisode(rix);
		    var item;

            if(columnName == 'demographics' && !profile.can_see_pid()){
                return false;
            }

		    if (iix == episode.getNumberOfItems(columnName)) {
			    item = episode.newItem(columnName, {schema: schema,
                                                    column: $rootScope.fields[columnName]});
		    } else {
			    item = episode.getItem(columnName, iix);
		    };

		    $scope.selectItem(rix, cix, iix);
            return _openEditItemModal(item, columnName, episode);
	    };

	    $scope.deleteItem = function(rix, cix, iix) {
		    var modal;
		    var columnName = getColumnName(cix);
		    var episode = getEpisode(rix);
		    var item = episode.getItem(columnName, iix);

            if(profile.readonly){
                return null;
            };

            if (schema.isReadOnly(columnName)) {
                // Cannont delete readonly columns
                return;
            }

		    if (schema.isSingleton(columnName)) {
			    // Cannot delete singleton
			    return;
		    }

		    if (!angular.isDefined(item)) {
			    // Cannot delete 'Add'
			    return;
		    }

		    $scope.state = 'modal'
		    modal = $modal.open({
			    templateUrl: '/templates/modals/delete_item_confirmation.html/',
			    controller: 'DeleteItemConfirmationCtrl',
			    resolve: {
				    item: function() { return item; }
			    }
		    });

		    modal.result.then(function(result) {
			    $scope.state = 'normal';
		    });
	    };

	    $scope.mouseEnter = function(rix, cix) {
		    $scope.mouseRix = rix;
		    $scope.mouseCix = cix;
	    }

	    $scope.mouseLeave = function() {
		    $scope.mouseRix = -1;
		    $scope.mouseCix = -1;
	    }

        function showKeyboardShortcuts(){
		    // TODO fix this
            $('#keyboard-shortcuts').modal();
        };

	    function goLeft() {
		    if ($scope.cix > 0) {
			    $scope.cix--;
			    $scope.iix = 0;
		    };
	    };

	    function goRight() {
		    if ($scope.cix < $scope.columns.length - 1) {
			    $scope.cix++;
			    $scope.iix = 0;
		    };
	    };

	    function goUp() {
		    var episode;
		    var columnName = getColumnName($scope.cix);

		    if ($scope.iix > 0) {
			    $scope.iix--;
		    } else if ($scope.rix > 0) {
			    $scope.rix--;
			    if (schema.isSingleton(columnName)) {
				    $scope.iix = 0;
			    } else {
				    episode = getEpisode($scope.rix);
				    $scope.iix = episode.getNumberOfItems(columnName);
			    };
		    };
	    };

	    function goDown() {
		    var episode = getEpisode($scope.rix);
		    var columnName = getColumnName($scope.cix);

		    if (!schema.isSingleton(columnName) &&
		        ($scope.iix < episode.getNumberOfItems(columnName))) {
			    $scope.iix++;
		    } else if ($scope.rix < $scope.rows.length - 1) {
			    $scope.rix++;
			    $scope.iix = 0;
		    };
	    };

        $scope.controller_for_episode = function(controller, template, size, episode){
            $modal.open({
                controller : controller,
                templateUrl: template,
                size       : size,
                resolve    : {
                    episode: function(){ return episode }
                }
            });
        }
    });
<commit_msg>Deal with deferreds coming back from modals - wait for them if they're promises.<commit_after>angular.module('opal.controllers').controller(
    'EpisodeListCtrl', function($scope, $q, $http, $cookieStore,
                                $location, $routeParams,
                                $modal, $rootScope,
                                growl,
                                Flow, Item,
                                Episode, schema, episodes, options,
                                profile,
                                episodeVisibility){

        var version = window.version;
        $scope.state = 'normal';
        $scope.url = $location.url()

	    $scope.rix = 0; // row index
	    $scope.cix = 0; // column index
	    $scope.iix = 0; // item index

	    $scope.mouseRix = -1; // index of row mouse is currently over
	    $scope.mouseCix = -1; // index of column mouse is currently over
        $scope._ =  _;

	    $scope.query = {hospital_number: '', name: '', ward: '', bed: ''};
        $scope.$location = $location;

        $scope.path_base = '/list/';

        if(!$routeParams.tag){
            var tag =  $cookieStore.get('opal.currentTag') || _.keys(options.tag_hierarchy)[0];
            $location.path($scope.path_base + tag);
            return
        }
        $scope.currentTag = $routeParams.tag;

        if(!$routeParams.subtag){
            // We now force redirect to the first subtag if there is one
            if($scope.currentTag in options.tag_hierarchy &&
               options.tag_hierarchy[$scope.currentTag].length > 0){
                var subtag = options.tag_hierarchy[$scope.currentTag][0];
                var target = $scope.path_base + $scope.currentTag + '/' + subtag;
                $location.path(target);
                return
            }else{
                $scope.currentSubTag = 'all';
            }
        }else{
            $scope.currentSubTag = $routeParams.subtag;
        }
        $scope.columns = schema.columns;

        $scope.profile = profile;
        $scope.tag_display = options.tag_display;

	    function getVisibleEpisodes() {
		    var visibleEpisodes = [];
            var episode_list = [];

            visibleEpisodes = _.filter(episodes, function(episode){
                return episodeVisibility(episode, $scope)
            });
		    visibleEpisodes.sort(compareEpisodes);
		    return visibleEpisodes;
	    };

	    $scope.rows = getVisibleEpisodes();

	    function compareEpisodes(p1, p2) {
		    return p1.compare(p2);
	    };

        $scope.jumpToTag = function(tag){
            if(_.contains(_.keys(options.tag_hierarchy), tag)){
                $location.path($scope.path_base + tag)
            }else{

                for(var prop in options.tag_hierarchy){
                    if(options.tag_hierarchy.hasOwnProperty(prop)){
                        if(_.contains(_.values(options.tag_hierarchy[prop]), tag)){
                            $location.path($scope.path_base + prop + '/' + tag)
                        }
                    }
                }

            };
        }

        $scope.otherTags = function(episode){
            tags = episode.getTags();
            return _.filter(tags, function(t){
                if(t in options.tag_hierarchy &&
                   options.tag_hierarchy[t].length > 0){ return false };
                if(t == $scope.currentTag){ return false };
                if(t == $scope.currentSubTag){ return false };
                return true
            });
        }

	    $scope.$watch('currentTag', function() {
		    $cookieStore.put('opal.currentTag', $scope.currentTag);
            if($scope.currentTag != $routeParams.tag){
                $scope.state = 'reloading'
            }
            var target = $scope.path_base +  $scope.currentTag;

            $location.path(target);
	    });

	    $scope.$watch('currentSubTag', function(){
		    $cookieStore.put('opal.currentSubTag', $scope.currentSubTag);
            if($scope.currentSubTag == 'all'){
                if($routeParams.subtag && $scope.currentSubTag != $routeParams.subtag){
                    $scope.state = 'reloading'
                }
                $location.path($scope.path_base +  $scope.currentTag);
            }else{
                if($scope.currentSubTag != $routeParams.subtag){
                    $scope.state = 'reloading'
                }
                $location.path($scope.path_base +  $scope.currentTag + '/' +  $scope.currentSubTag);
            }
	    });

        $scope.showSubtags = function(withsubtags){
            var show =  _.contains(withsubtags, $scope.currentTag);
            return show
        };

	    $scope.$watch('query.hospital_number', function() {
		    $scope.rows = getVisibleEpisodes();
	    });

	    $scope.$watch('query.ward', function() {
		    $scope.rows = getVisibleEpisodes();
	    });

	    $scope.$watch('query.bed', function() {
		    $scope.rows = getVisibleEpisodes();
	    });

	    $scope.$watch('query.name', function() {
		    $scope.rows = getVisibleEpisodes();
	    });

	    $scope.$on('keydown', function(event, e) {
		    if ($scope.state == 'normal') {
			    switch (e.keyCode) {
			    case 37: // left
				    goLeft();
				    break;
			    case 39: // right
				    goRight();
				    break;
			    case 38: // up
				    goUp();
				    break;
			    case 40: // down
				    goDown();
				    break;
			    case 13: // enter
			    case 113: // F2
				    $scope.editItem($scope.rix, $scope.cix, $scope.iix);
                    e.preventDefault();
				    break;
			    case 8: // backspace
				    e.preventDefault();
			    case 46: // delete
				    $scope.deleteItem($scope.rix, $scope.cix, $scope.iix);
				    break;
			    case 191: // question mark
				    if(e.shiftKey){
					    showKeyboardShortcuts();
				    }
				    break;
                case 78: // n
                    $scope.addEpisode();
                    e.preventDefault();
                    break;
			    };
		    };
	    });

	    function getColumnName(cix) {
		    return $scope.columns[cix].name;
	    };

	    function getRowIxFromEpisodeId(episodeId) {
		    for (var rix = 0; rix < $scope.rows.length; rix++) {
			    if ($scope.rows[rix].id == episodeId) {
				    return rix;
			    }
		    };
		    return -1;
	    };

	    function getEpisode(rix) {
		    return $scope.rows[rix];
	    };

	    $scope.print = function() {
		    window.print();
	    };

	    $scope.selectItem = function(rix, cix, iix) {
		    $scope.rix = rix;
		    $scope.cix = cix;
		    $scope.iix = iix;
	    };

	    $scope.focusOnQuery = function() {
		    $scope.selectItem(-1, -1, -1);
		    $scope.state = 'search';
	    };

	    $scope.blurOnQuery = function() {
		    if ($scope.rix == -1) {
			    $scope.selectItem(0, 0, 0);
		    };
		    $scope.state = 'normal';
	    };

	    $scope.addEpisode = function() {
            if(profile.readonly){ return null; };

            var enter = Flow(
                'enter', schema, options,
                {
                    current_tags: {
                        tag: $scope.currentTag,
                        subtag: $scope.currentSubTag
                    }
                }
            );

		    $scope.state = 'modal';

            enter.then(
                function(resolved) {
		            // We have either retrieved an existing episode or created a new one,
                    // rendered a new modal for which we are waiting,
		            // or has cancelled the process at some point.

                    var return_to_normal = function(episode){
                    	// This ensures that the relevant episode is added to the table and
		                // selected.
		                var rowIx;
		                $scope.state = 'normal';
		                if (episode && episode != 'cancel') {
			                episodes[episode.id] = episode;
			                $scope.rows = getVisibleEpisodes();
			                rowIx = getRowIxFromEpisodeId(episode.id);
			                $scope.selectItem(rowIx, 0, 0);
                            growl.success("Added a new episode for " + episode.demographics[0].name);
		                };
                    }

                    if(resolved.then){ // OMG - it's a promise!
                        resolved.then(
                            function(r){ return_to_normal(r) },
                            function(r){ return_to_normal(r) }
                        );
                    }else{
                        return_to_normal(resolved);
                    }
	            },
                function(reason){
                    // The modal has been dismissed. Practically speaking this means
                    // that the Angular UI called dismiss rather than our cancel()
                    // method on the OPAL controller. We just need to re-set in order
                    // to re-enable keybard listeners.
                    $scope.state = 'normal';
                });
	    };

	    $scope.dischargeEpisode = function(rix, event) {
		    var episode = getEpisode(rix);

            if(profile.readonly){ return null; };

		    event.preventDefault();// Required to prevent the page reloading
		    $scope.state = 'modal';

            var exit = Flow(
                'exit', schema, options,
                {
                    current_tags: {
                        tag   : $scope.currentTag,
                        subtag: $scope.currentSubTag
                    },
                    episode: episode
                }
            );

            exit.then(function(result) {
			    $scope.state = 'normal';

			    if (result == 'discharged' | result == 'moved') {
				    $scope.rows = getVisibleEpisodes();
				    $scope.selectItem(0, $scope.cix, 0);
			    };
		    });
	    };

        // TODO: Test This!
        $scope.removeFromMine = function(rix, event){
            if(profile.readonly){
                return null;
            };

            event.preventDefault();

            var modal;
            var episode = getEpisode(rix);
            var tagging = episode.tagging[0];
            editing = tagging.makeCopy();
            editing.mine = false;
            tagging.save(editing).then(function(result){
                $scope.rows = getVisibleEpisodes();
            })
        };

        //
        // Do the work of editing an item - open the modal and
        // resolve it.
        //
        _openEditItemModal = function(item, columnName, episode) {
            if(profile.readonly){
                return null;
            };
            $scope.state = 'modal';
            var template_url = '/templates/modals/' + columnName + '.html/';
            template_url += $scope.currentTag + '/' + $scope.currentSubTag;

            modal = $modal.open({
                templateUrl: template_url,
                controller: 'EditItemCtrl',
                resolve: {
                    item: function() { return item; },
                    options: function() { return options; },
                    profile: function() { return profile; },
                    episode: function() { return episode; }
                }
            });

            //
            // The state resetting logic is fairly simple, but we may have to
            // wait for an intermediary modal to close...
            //
            // TODO: Figure out & document how to actually take advantage of this hook :/
            //
            var reset_state = function(result){
                $scope.state = 'normal';

                if (columnName == 'tagging') {

                    // User may have removed current tag
                    $scope.rows = getVisibleEpisodes();
                    $scope.selectItem(getRowIxFromEpisodeId(episode.id), $scope.cix, 0);
                }

                if (result == 'save-and-add-another') {
                    $scope.newNamedItem(episode, columnName);
                    return
                };
                if (item.sort){
                    episode.sortColumn(item.columnName, item.sort);
                };
            };

            modal.result.then(function(result) {
                if(result.then){
                    result.then(function(r){ reset_state(r) });
                }else{
                    reset_state(result);
                }
            }, function(){
                $scope.state = 'normal';
            });
        }

        $scope.newNamedItem = function(episode, name) {
            var item = episode.newItem(name, {column: $rootScope.fields[name]});
            if (!episode[name]) {
                episode[name] = [];
            }
            episode[name].push(item);
            return _openEditItemModal(item, name, episode);
        }

        $scope.editNamedItem = function(episode, name, iix) {
            var item;
            if (episode[name][iix] && episode[name][iix].columnName) {
                item = episode[name][iix];
            } else {
                item = new Item(episode[name][iix], episode, $rootScope.fields[name]);
                episode[name][iix] = item;
            }

            return _openEditItemModal(item, name, episode);
        }

	    $scope.editItem = function(rix, cix, iix) {
		    var columnName = getColumnName(cix);
		    var episode = getEpisode(rix);
		    var item;

            if(columnName == 'demographics' && !profile.can_see_pid()){
                return false;
            }

		    if (iix == episode.getNumberOfItems(columnName)) {
			    item = episode.newItem(columnName, {schema: schema,
                                                    column: $rootScope.fields[columnName]});
		    } else {
			    item = episode.getItem(columnName, iix);
		    };

		    $scope.selectItem(rix, cix, iix);
            return _openEditItemModal(item, columnName, episode);
	    };

	    $scope.deleteItem = function(rix, cix, iix) {
		    var modal;
		    var columnName = getColumnName(cix);
		    var episode = getEpisode(rix);
		    var item = episode.getItem(columnName, iix);

            if(profile.readonly){
                return null;
            };

            if (schema.isReadOnly(columnName)) {
                // Cannont delete readonly columns
                return;
            }

		    if (schema.isSingleton(columnName)) {
			    // Cannot delete singleton
			    return;
		    }

		    if (!angular.isDefined(item)) {
			    // Cannot delete 'Add'
			    return;
		    }

		    $scope.state = 'modal'
		    modal = $modal.open({
			    templateUrl: '/templates/modals/delete_item_confirmation.html/',
			    controller: 'DeleteItemConfirmationCtrl',
			    resolve: {
				    item: function() { return item; }
			    }
		    });

		    modal.result.then(function(result) {
			    $scope.state = 'normal';
		    });
	    };

	    $scope.mouseEnter = function(rix, cix) {
		    $scope.mouseRix = rix;
		    $scope.mouseCix = cix;
	    }

	    $scope.mouseLeave = function() {
		    $scope.mouseRix = -1;
		    $scope.mouseCix = -1;
	    }

        function showKeyboardShortcuts(){
		    // TODO fix this
            $('#keyboard-shortcuts').modal();
        };

	    function goLeft() {
		    if ($scope.cix > 0) {
			    $scope.cix--;
			    $scope.iix = 0;
		    };
	    };

	    function goRight() {
		    if ($scope.cix < $scope.columns.length - 1) {
			    $scope.cix++;
			    $scope.iix = 0;
		    };
	    };

	    function goUp() {
		    var episode;
		    var columnName = getColumnName($scope.cix);

		    if ($scope.iix > 0) {
			    $scope.iix--;
		    } else if ($scope.rix > 0) {
			    $scope.rix--;
			    if (schema.isSingleton(columnName)) {
				    $scope.iix = 0;
			    } else {
				    episode = getEpisode($scope.rix);
				    $scope.iix = episode.getNumberOfItems(columnName);
			    };
		    };
	    };

	    function goDown() {
		    var episode = getEpisode($scope.rix);
		    var columnName = getColumnName($scope.cix);

		    if (!schema.isSingleton(columnName) &&
		        ($scope.iix < episode.getNumberOfItems(columnName))) {
			    $scope.iix++;
		    } else if ($scope.rix < $scope.rows.length - 1) {
			    $scope.rix++;
			    $scope.iix = 0;
		    };
	    };

        $scope.controller_for_episode = function(controller, template, size, episode){
            $modal.open({
                controller : controller,
                templateUrl: template,
                size       : size,
                resolve    : {
                    episode: function(){ return episode }
                }
            });
        }
    });
<|endoftext|>


<commit_before>import React from 'react';

const About = () => {
  return (

        Gå til hovedsiden

        Velkommen til Online, linjeforeningen for informatikkstudenter ved NTNU.

        Det er vi som sørger for at studietiden blir den beste tiden i ditt liv! Vi i Online arrangerer utflukter,
        turer, fester, holder kurs og bedriftspresentasjoner gjennom hele året.

        Vi har samlet litt info for nye informatikere med spørsmål, ta en titt på{' '}
        wikien for å sjekke den ut!

        Ny på master? Se her for viktig info om
        IT-ekskursjonen, OBS kort frist!{' '}

        Hopp til program

  );
};

export default About;
<commit_msg>Update index.js<commit_after>import React from 'react';

const About = () => {
  return (

        Gå til hovedsiden

        Velkommen til Online, linjeforeningen for informatikkstudenter ved NTNU.

        Det er vi som sørger for at studietiden blir den beste tiden i ditt liv! Vi i Online arrangerer utflukter,
        turer, fester, holder kurs og bedriftspresentasjoner gjennom hele året.

        Vi har samlet litt info for nye informatikere med spørsmål, ta en titt på{' '}
        wikien for å sjekke den ut!

        Ny på master? Se her for viktig info om
        IT-ekskursjonen, OBS kort frist!{' '}

        Hopp til program

  );
};

export default About;
<|endoftext|>


<commit_before>import cookie from 'cookie';

module.exports = function userStoragePlugin(options) {
    /**
     * @class userStorage
     */
    return {
        name: 'UserStoragePlugin',
        // Called after context creation to dynamically create a context plugin
        plugContext: function plugContext(contextOptions) {
            // `options` is the same as what is passed into `Fluxible.createContext(options)`
            let user = null;
            if (contextOptions.req) {
                user = contextOptions.req.user;
            }
            const user_cookieName = 'user_json_storage';

            //original from fluxible-plugin-cookie
            let req = contextOptions.req;
            let res = contextOptions.res;

            //get cookies from cookie-parser plugin
            let cookies = req ? req.cookies : cookie.parse(document.cookie);

            // Returns a context plugin
            return {
                /**
                 * Provides full access to the user in the action context
                 * @param {Object} actionContext
                 */
                plugActionContext: function plugActionContext(actionContext) {
                    actionContext.getUser = function () {
                        let result = user;

                        if (result === undefined || result === null || result === {}) {
                            result = actionContext.getCookie(user_cookieName);
                        }

                        return result;
                    };
                    actionContext.setUser = function (newUser) {
                        user = newUser;

                        actionContext.setCookie(user_cookieName, JSON.stringify(newUser), {});
                    };
                    actionContext.setCookie = function (name, value, options) {
                        const cookieStr = cookie.serialize(name, value, options);
                        if (res) {
                            res.setHeader('Set-Cookie', cookieStr);
                        } else {
                            document.cookie = cookieStr;
                        }
                        cookies[name] = value;
                    };
                    actionContext.getCookie = function (name) {
                        return cookies[name];
                    };
                },
                /**
                 * Provides access to user
                 * @param {Object} componentContext
                 */
                plugComponentContext: function plugComponentContext(componentContext) {
                    componentContext.getUser = function () {
                        return user;
                    };
                },
                /**
                 * Provides access to user
                 * @param {Object} storeContext
                 */
                plugStoreContext: function plugStoreContext(storeContext) {
                    storeContext.getUser = function () {
                        return user;
                    };
                },
                dehydrate: function () {
                    return {
                        user: user
                    };
                },
                // Called on client to rehydrate the context plugin settings
                rehydrate: function (state) {
                    user = state.user;
                }
            };
        },

    };
};
<commit_msg>[SWIK-455_save_user_data] Added deleteUser to action context<commit_after>import cookie from 'cookie';

module.exports = function userStoragePlugin(options) {
    /**
     * @class userStorage
     */
    return {
        name: 'UserStoragePlugin',
        // Called after context creation to dynamically create a context plugin
        plugContext: function plugContext(contextOptions) {
            // `options` is the same as what is passed into `Fluxible.createContext(options)`
            let user = null;
            if (contextOptions.req) {
                user = contextOptions.req.user;
            }
            const user_cookieName = 'user_json_storage';

            //original from fluxible-plugin-cookie
            let req = contextOptions.req;
            let res = contextOptions.res;

            //get cookies from cookie-parser plugin
            let cookies = req ? req.cookies : cookie.parse(document.cookie);

            // Returns a context plugin
            return {
                /**
                 * Provides full access to the user in the action context
                 * @param {Object} actionContext
                 */
                plugActionContext: function plugActionContext(actionContext) {
                    actionContext.getUser = function () {
                        let result = user;

                        if (result === undefined || result === null || result === {}) {
                            result = actionContext.getCookie(user_cookieName);
                        }

                        return result;
                    };
                    actionContext.setUser = function (newUser) {
                        user = newUser;

                        actionContext.setCookie(user_cookieName, JSON.stringify(newUser), {});
                    };
                    actionContext.deleteUser = function() {
                        actionContext.setUser({});
                    };
                    actionContext.setCookie = function (name, value, options) {
                        const cookieStr = cookie.serialize(name, value, options);
                        if (res) {
                            res.setHeader('Set-Cookie', cookieStr);
                        } else {
                            document.cookie = cookieStr;
                        }
                        cookies[name] = value;
                    };
                    actionContext.getCookie = function (name) {
                        return cookies[name];
                    };
                },
                /**
                 * Provides access to user
                 * @param {Object} componentContext
                 */
                plugComponentContext: function plugComponentContext(componentContext) {
                    componentContext.getUser = function () {
                        return user;
                    };
                },
                /**
                 * Provides access to user
                 * @param {Object} storeContext
                 */
                plugStoreContext: function plugStoreContext(storeContext) {
                    storeContext.getUser = function () {
                        return user;
                    };
                },
                dehydrate: function () {
                    return {
                        user: user
                    };
                },
                // Called on client to rehydrate the context plugin settings
                rehydrate: function (state) {
                    user = state.user;
                }
            };
        },

    };
};
<|endoftext|>


<commit_before>'use strict';

var db = require.main.require('./src/database');
var winston = require.main.require('winston');
var xxh = require('xxhash');
var async = require.main.require('async');
var PluginSocket = require.main.require('./src/socket.io/plugins');

var SmoothShorts = {};

SmoothShorts.init = function(app, cb) {
  app.router.get('/ss/:hash', SmoothShorts.resolveHash);
  PluginSocket.SmoothShorts = {};
  PluginSocket.SmoothShorts.getTopicHashs = function(socket, tids, cb) {
    async.map(tids, SmoothShorts.getHashForTid, function(err, hashs) {
      if (err) {
        return cb(err);
      }
      cb(null, hashs);
    });
  };
  PluginSocket.SmoothShorts.getPostHashs = function(socket, pids, cb) {
    async.map(pids, SmoothShorts.getHashForPid, function(err, hashs) {
      if (err) {
        return cb(err);
      }
      cb(null, hashs);
    });
  };
  return cb(null, app);
};

SmoothShorts.resolveHash = function(req, res, next) {
  var hash = req.params.hash;

  // async this mess!
  // better yet, take the time to get familiar with db.*
  // and sort it out!
  // holy crap ^_^ - use db.sortedSetScore!
  db.isSortedSetMember('posts:smoothshorts', hash, function(err, isPostHash) {
    if (isPostHash) {
      /* if this hash points to a post */
      // get data row (rank) of hash/postid
      db.sortedSetRank('posts:smoothshorts', hash, function(err, rank) {
        // get postid from that row (rank)
        db.getSortedSetRangeWithScores('posts:smoothshorts', rank, rank, function(err, range) {
          // postid for hash
          var pid = range[0].score;
          // get topicid this pid belongs to
          db.getObjectField('post:' + pid, 'tid', function(err, tid) {
            /* is this a non-initial post? (i.e. not the first post in topic) */
            db.isSortedSetMember('tid:' + tid + ':posts', pid, function(err, isNotInitial) {
              if (isNotInitial) {
                /* yes, it is */
                // get position in topic listing (i.e. data-index in DOM)
                db.sortedSetRank('tid:' + tid + ':posts', pid, function(err, postInTopic) {
                  // get topic slug; needed for URI
                  db.getObjectField('topic:' + tid, 'slug', function(err, slug) {
                    // build URI
                    var uri = '/topic/' + slug + '/' + (parseInt(postInTopic, 10) + 2).toString();
                    winston.verbose('[plugins:SmoothShorts] Redirecting ' +
                                    hash + ' to post(' + pid + ') ' + uri);
                    // redirect user to URI
                    res.redirect(uri);
                  });
                });
              } else {
                /* no, it's not; simply redirect to topic */
                // get topic slug (i.e. 'tid/title'); needed for URI
                db.getObjectField('topic:' + tid, 'slug', function(err, slug) {
                  // build URI
                  var uri = '/topic/' + slug + '/1';
                  winston.verbose('[plugins:SmoothShorts] Redirecting ' + hash +
                                  ' to post(' + pid + ') ' + uri);
                  // redirect user to URI
                  res.redirect(uri);
                }); // Did you ever
              }     // wonder where
            });     // the term
          });       // callback hell
        });         // comes from?
      });           // Well, here you go. :]
    } else {
      // if this hash points to a topic
      db.isSortedSetMember('topics:smoothshorts', hash, function(err, isTopicHash) {
        if (isTopicHash) {
          // get data row (rank) of hash/topicid
          db.sortedSetRank('topics:smoothshorts', hash, function(err, rank) {
            // get topicid from that row (rank)
            db.getSortedSetRangeWithScores('topics:smoothshorts', rank, rank, function(err, range) {
              var tid = range[0].score;
              db.getObjectField('topic:' + tid, 'slug', function(err, slug) {
                // build URI
                var uri = '/topic/' + slug + '/';
                winston.verbose('[plugins:SmoothShorts] Redirecting ' + hash +
                                ' to topic(' + tid + ') ' + uri);
                // redirect user to URI
                res.redirect(uri);
              });
            });
          });
        } else {
          // at this point it's clear that
          // this is neither a post- nor topic-hash
          // show some error message
          winston.warn('[plugins:smoothshorts] Couldn\'t resolve ' + hash);
          next(null);
        }
      });
    }
  });
};

SmoothShorts.shortenTopic = function(topicData) {
  winston.verbose('[plugin:smoothshorts] Shortening Topic:');
  /** topics:smoothshorts sortedSet **/
  // hash topic object
  var hash = xxh.hash(new Buffer(JSON.stringify(topicData)),
                      0xCAFEBABE).toString(16);
  db.sortedSetAdd('topics:smoothshorts', topicData.tid, hash, function(err) {
    if (!err) {
      winston.verbose('[plugin:smoothshorts] ' + topicData);
    } else {
      winston.error('[plugin:smoothshorts] Writing hash to DB failed.' +
                    '(tid=' + topicData.tid + ')');
    }
  });
  // next(null, topicData);
};
SmoothShorts.purgeTopic = function(tid) {
  winston.verbose('[plugin:smoothshorts] Purging Topic: ' + tid);
  db.sortedSetsRemoveRangeByScore(['topics:smoothshorts'], tid, tid, function(err) {
    if (err) {
      winston.error('[plugin:smoothshorts] Deleting hash from DB failed.' +
                    '(tid=' + tid + ')');
    };
  });
};
SmoothShorts.shortenPost = function(postData) {
  winston.verbose('[plugin:smoothshorts] Shortening Post:');
  /** posts:smoothshorts sortedSet **/
  // hash post object
  var hash = xxh.hash(new Buffer(JSON.stringify(postData)), 0xCAFEBABE).toString(16);
  db.sortedSetAdd('posts:smoothshorts', postData.pid, hash, function(err) {
    if (!err) {
      winston.verbose('[plugin:smoothshorts] ' + postData);
    } else {
      winston.error('[plugin:smoothshorts] Writing hash to DB failed.' +
                    '(pid=' + postData.pid + ')');
      winston.error(err);
    }
  });
};
SmoothShorts.purgePost = function(pid) {
  winston.verbose('[plugin:smoothshorts] Purging Post: ' + pid);
  db.sortedSetsRemoveRangeByScore(['posts:smoothshorts'], pid, pid, function(err) {
    if (err) {
      winston.error('[plugin:smoothshorts] Deleting hash from DB failed.' +
                    '(pid=' + pid + ')');
    };
  });
};

SmoothShorts.getHashForTid = function(tid, cb) {
  db.getSortedSetRangeByScore('topics:smoothshorts', 0, -1, tid, tid, function(err, hash) {
    if (err) {
      return cb(err);
    }
    cb(null, {tid: tid, hash: hash[0]});
  });
};

SmoothShorts.getHashForPid = function(pid, cb) {
  db.getSortedSetRangeByScore('posts:smoothshorts', 0, -1, pid, pid, function(err, hash) {
    if (err) {
      cb(err);
    }
    cb(null, {pid: pid, hash: hash[0]});
  });
};

module.exports = SmoothShorts;
<commit_msg>cleaning up db calls mess/async<commit_after>'use strict';

var db = require.main.require('./src/database');
var winston = require.main.require('winston');
var xxh = require('xxhash');
var async = require.main.require('async');
var PluginSocket = require.main.require('./src/socket.io/plugins');

var SmoothShorts = {};

SmoothShorts.init = function(app, cb) {
  app.router.get('/ss/:hash', SmoothShorts.resolveHash);
  PluginSocket.SmoothShorts = {};
  PluginSocket.SmoothShorts.getTopicHashs = function(socket, tids, cb) {
    async.map(tids, SmoothShorts.getHashForTid, function(err, hashs) {
      if (err) {
        return cb(err);
      }
      cb(null, hashs);
    });
  };
  PluginSocket.SmoothShorts.getPostHashs = function(socket, pids, cb) {
    async.map(pids, SmoothShorts.getHashForPid, function(err, hashs) {
      if (err) {
        return cb(err);
      }
      cb(null, hashs);
    });
  };
  return cb(null, app);
};

SmoothShorts.resolveHash = function(req, res, cb) {
  var hash = req.params.hash;
  console.log(hash);

  async.parallel({
    isPost: function(next) {
      db.isSortedSetMember('posts:smoothshorts', hash, next);
    },
    isTopic: function(next) {
      db.isSortedSetMember('topics:smoothshorts', hash, next);
    }
  }, function(err, result) {
    if (err) {
      return cb(err);
    } else if (result.isPost) {
      async.waterfall([
        function(next) {
          db.sortedSetScore('posts:smoothshorts', hash, next);
        },
        function(pid, next) {
          db.getObjectField('post:' + pid, 'tid', function(err, tid) {
            return next(null, {pid: pid, tid: tid});
          });
        },
        function(data, next) {
          async.parallel({
            rank: function(next) {
              db.sortedSetRank('tid:' + data.tid + ':posts', data.pid, next);
            },
            slug: function(next) {
              db.getObjectField('topic:' + data.tid, 'slug', next);
            }
          }, function(err, result) {
            if (err) {
              return cb(err);
            }
            var pIndex = (result.rank !== null) ?
                         (parseInt(result.rank, 10) + 2).toString() : '1';
            var uri = '/topic/' + result.slug + '/' + pIndex;
            next(null, uri);
          });
        }
      ], function(err, uri) {
        if (err) {
          return cb(err);
        }
        winston.verbose('[plugins:SmoothShorts] Redirecting ' + hash +
                        ' to ' + uri);
        res.redirect(uri);
      });
    } else if (result.isTopic) {
      /* if this hash points to a topic */
      async.waterfall([
        function(next) {
          db.sortedSetScore('topics:smoothshorts', hash, next);
        },
        function(tid, next) {
          db.getObjectField('topic:' + tid, 'slug', next);
        }
      ], function(err, slug) {
        if (err) {
          return cb(err);
        }
        // build URI
        var uri = '/topic/' + slug + '/';
        winston.verbose('[plugins:SmoothShorts] Redirecting ' + hash +
                        ' to ' + uri);
        // redirect user to URI
        res.redirect(uri);
      });
    } else {
      winston.warn('[plugins:SmoothShorts] Couldn\'t resolve ' + hash);
      cb(null);
    }
  });
};

SmoothShorts.shortenTopic = function(topicData) {
  winston.verbose('[plugin:smoothshorts] Shortening Topic:');
  /** topics:smoothshorts sortedSet **/
  // hash topic object
  var hash = xxh.hash(new Buffer(JSON.stringify(topicData)),
                      0xCAFEBABE).toString(16);
  db.sortedSetAdd('topics:smoothshorts', topicData.tid, hash, function(err) {
    if (!err) {
      winston.verbose('[plugin:smoothshorts] ' + topicData);
    } else {
      winston.error('[plugin:smoothshorts] Writing hash to DB failed.' +
                    '(tid=' + topicData.tid + ')');
    }
  });
  // next(null, topicData);
};
SmoothShorts.purgeTopic = function(tid) {
  winston.verbose('[plugin:smoothshorts] Purging Topic: ' + tid);
  db.sortedSetsRemoveRangeByScore(['topics:smoothshorts'], tid, tid, function(err) {
    if (err) {
      winston.error('[plugin:smoothshorts] Deleting hash from DB failed.' +
                    '(tid=' + tid + ')');
    };
  });
};
SmoothShorts.shortenPost = function(postData) {
  winston.verbose('[plugin:smoothshorts] Shortening Post:');
  /** posts:smoothshorts sortedSet **/
  // hash post object
  var hash = xxh.hash(new Buffer(JSON.stringify(postData)), 0xCAFEBABE).toString(16);
  db.sortedSetAdd('posts:smoothshorts', postData.pid, hash, function(err) {
    if (!err) {
      winston.verbose('[plugin:smoothshorts] ' + postData);
    } else {
      winston.error('[plugin:smoothshorts] Writing hash to DB failed.' +
                    '(pid=' + postData.pid + ')');
      winston.error(err);
    }
  });
};
SmoothShorts.purgePost = function(pid) {
  winston.verbose('[plugin:smoothshorts] Purging Post: ' + pid);
  db.sortedSetsRemoveRangeByScore(['posts:smoothshorts'], pid, pid, function(err) {
    if (err) {
      winston.error('[plugin:smoothshorts] Deleting hash from DB failed.' +
                    '(pid=' + pid + ')');
    };
  });
};

SmoothShorts.getHashForTid = function(tid, cb) {
  db.getSortedSetRangeByScore('topics:smoothshorts', 0, -1, tid, tid, function(err, hash) {
    if (err) {
      return cb(err);
    }
    cb(null, {tid: tid, hash: hash[0]});
  });
};

SmoothShorts.getHashForPid = function(pid, cb) {
  db.getSortedSetRangeByScore('posts:smoothshorts', 0, -1, pid, pid, function(err, hash) {
    if (err) {
      cb(err);
    }
    cb(null, {pid: pid, hash: hash[0]});
  });
};

module.exports = SmoothShorts;
<|endoftext|>