<commit_before>/**
 * fullPage 1.0
 * https://github.com/alvarotrigo/fullPage.js
 * MIT licensed
 *
 * Copyright (C) 2013 alvarotrigo.com - A project by Alvaro Trigo
 */
(function(b){b.fn.fullpage=function(c){function m(){return function(a){if(c.autoScrolling){a=window.event||a;a=Math.max(-1,Math.min(1,a.wheelDelta||-a.detail));if(!h){var e=b(".section.active").find(".scrollable");if(0>a)if(0<e.length)if(l("bottom",e))b.fn.fullpage.moveSlideDown();else return!0;else b.fn.fullpage.moveSlideDown();else if(0<e.length)if(l("top",e))b.fn.fullpage.moveSlideUp();else return!0;else b.fn.fullpage.moveSlideUp()}return!1}}}function k(a){var e={},d;d=a.position();d=null!==d?
d.top:null;h=!0;"undefined"!==typeof a.data("anchor")?location.hash=a.data("anchor"):location.hash="";c.autoScrolling?(e.top=-d,d="#superContainer"):(e.scrollTop=d,d="html, body");b(d).animate(e,c.scrollingSpeed,c.easing,function(){b.isFunction(c.afterLoad)&&c.afterLoad.call(this,f,a.index(".section")+1);setTimeout(function(){h=!1},700)});var f=a.attr("data-anchor");r=f;s(f);x(f)}function y(){var a=window.location.hash.replace("#","");a&&(a=b('[data-anchor="'+a+'"]'),a.addClass("active").siblings().removeClass("active"),
k(a))}function t(){var a=b(window).width(),e=b(window).height();c.scrollOverflow&&b(".section").each(function(){b(this).find(".scrollable").css("height",e+"px").parent().css("height",e+"px")});c.resize&&z(e,a);b(".section").each(function(){b(this).css("height",e+"px");var a=b(this).find(".slides");if(0a||900>c?(900>c&&(f=c,d=900),d=(100*f/d).toFixed(2),b("body").css("font-size",d+"%")):b("body").css("font-size","100%")}function x(a){c.navigation&&(b("#fullPage-nav").find(".active").removeClass("active"),b("#fullPage-nav").find('a[href="#'+a+'"]').addClass("active"))}function s(a){c.menu&&(b(c.menu).find(".active").removeClass("active"),b(c.menu).find('[data-menuanchor="'+a+'"]').addClass("active"))}function l(a,b){if("top"===a)return!b.scrollTop();if("bottom"===
a)return b.scrollTop()+b.innerHeight()>=b[0].scrollHeight}c=b.extend({verticalCentered:!0,resize:!0,slidesColor:[],anchors:[],scrollingSpeed:700,easing:"easeInQuart",menu:!1,navigation:!1,navigationPosition:"right",navigationColor:"#000",controlArrowColor:"#fff",loopBottom:!1,loopTop:!1,autoScrolling:!0,scrollOverflow:!1,afterLoad:null,afterRender:null},c);b.fn.fullpage.setAutoScrolling=function(a){c.autoScrolling=a;c.autoScrolling?b("html, body").css({overflow:"hidden",height:"100%"}):(b("html, body").css({overflow:"auto",
height:"auto"}),b("#superContainer").css("top","0px"))};var n=!0,p=navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|Windows Phone)/),q=b(window).height(),h=!1,r;b.fn.fullpage.setAutoScrolling(c.autoScrolling);c.verticalCentered&&b(".section").addClass("table").wrapInner('
');b("body").wrapInner('
');if(c.navigation){b("body").append('

');var g=b("#fullPage-nav");g.css("color",c.navigationColor);"right"===
c.navigationPosition?g.css("right","17px"):g.css("left","17px")}b(".section").each(function(a){var e=b(this).find(".slide"),d=e.length;a||b(this).addClass("active");b(this).css("height",q+"px");"undefined"!==typeof c.slidesColor[a]&&b(this).css("background-color",c.slidesColor[a]);"undefined"!==typeof c.anchors[a]&&b(this).attr("data-anchor",c.anchors[a]);c.navigation&&b("#fullPage-nav").find("ul").append('

');if(0<d){a=100*d;var f=100/d;e.wrapAll('
');
e.parent().wrap('
');b(this).find(".slidesContainer").css("width",a+"%");b(this).find(".slides").after('

');b(".controlArrow.next").css("border-color","transparent transparent transparent "+c.controlArrowColor);b(".controlArrow.prev").css("border-color","transparent "+c.controlArrowColor+" transparent transparent");e.each(function(a){a||b(this).addClass("active");b(this).css("width",f+"%")})}}).promise().done(function(){b.isFunction(c.afterRender)&&
c.afterRender.call(this);c.scrollOverflow&&b(".section").each(function(){b(this).height()>q&&(c.verticalCentered?b(this).find(".tableCell").wrapInner('
'):b(this).wrapInner('
'),b(this).find(".scrollable").slimScroll({height:q+"px",size:"10px",alwaysVisible:!0}))});y()});b(window).scroll(function(a){if(c.menu&&!c.autoScrolling){var e=b(window).scrollTop();a=b(".section").map(function(){if(b(this).offset().top<e+100)return b(this)});a=a[a.length-1];
b(".section.active").removeClass("active");a.addClass("active");var d=a.attr("data-anchor");b.isFunction(c.afterLoad)&&c.afterLoad.call(this,d,a.index(".section")+1);s(d)}});var u=0,v=0;b(document).on("touchmove",function(a){if(c.autoScrolling&&p&&(a.preventDefault(),a=a.originalEvent,!h)){var e=b(".section.active").find(".scrollable");v=a.touches[0].pageY;if(u>v)if(0<e.length)if(l("bottom",e))b.fn.fullpage.moveSlideDown();else return!0;else b.fn.fullpage.moveSlideDown();else if(0<e.length)if(l("top",
e))b.fn.fullpage.moveSlideUp();else return!0;else b.fn.fullpage.moveSlideUp()}});b(document).on("touchstart",function(a){c.autoScrolling&&p&&(u=a.originalEvent.touches[0].pageY)});g={};g=document;g.addEventListener?(g.addEventListener("mousewheel",m(),!1),g.addEventListener("DOMMouseScroll",m(),!1)):g.attachEvent("onmousewheel",m());b.fn.fullpage.moveSlideUp=function(){var a=b(".section.active").prev(".section");c.loopTop&&!a.length&&(a=b(".section").last());if(0<a.length||!a.length&&c.loopTop)a.addClass("active").siblings().removeClass("active"),
k(a)};b.fn.fullpage.moveSlideDown=function(){var a=b(".section.active").next(".section");c.loopBottom&&!a.length&&(a=b(".section").first());if(0<a.length||!a.length&&c.loopBottom)a.addClass("active").siblings().removeClass("active"),k(a)};b.fn.fullpage.moveToSlide=function(a){var c="",c=isNaN(a)?b('[data-anchor="'+a+'"]'):b(".section").eq(a-1);0<c.length&&(c.addClass("active").siblings().removeClass("active"),k(c))};b(window).on("hashchange",function(){var a=window.location.hash.replace("#","");a!==
r&&(a=b('[data-anchor="'+a+'"]'),a.addClass("active").siblings().removeClass("active"),k(a))});b(document).keydown(function(a){if(!h)switch(a.which){case 38:case 33:b.fn.fullpage.moveSlideUp();break;case 40:case 34:b.fn.fullpage.moveSlideDown();break;case 37:b(".section.active").find(".controlArrow.prev").trigger("click");break;case 39:b(".section.active").find(".controlArrow.next").trigger("click")}});b(".section").on("click",".controlArrow",function(){if(n){n=!1;var a=b(this).closest(".section").find(".slides"),
c=a.find(".slidesContainer").parent(),a=a.find(".slide.active"),d=null,f=0;a.removeClass("active");d=b(this).hasClass("prev")?a.prev(".slide"):a.next(".slide");0<d.length||(d=b(this).hasClass("prev")?a.siblings(":last"):a.siblings(":first"));f=d.position();c.animate({scrollLeft:f.left},500,function(){n=!0});d.addClass("active")}});if(!p){var w;b(window).resize(function(){clearTimeout(w);w=setTimeout(t,500)})}b(window).bind("orientationchange",function(){t()})}})(jQuery);<commit_msg>- Updated minified version.<commit_after>/**
 * fullPage 1.0
 * https://github.com/alvarotrigo/fullPage.js
 * MIT licensed
 *
 * Copyright (C) 2013 alvarotrigo.com - A project by Alvaro Trigo
 */
(function(b){b.fn.fullpage=function(c){function m(){return function(a){if(c.autoScrolling){a=window.event||a;a=Math.max(-1,Math.min(1,a.wheelDelta||-a.detail));if(!h){var e=b(".section.active").find(".scrollable");if(0>a)if(0<e.length)if(l("bottom",e))b.fn.fullpage.moveSlideDown();else return!0;else b.fn.fullpage.moveSlideDown();else if(0<e.length)if(l("top",e))b.fn.fullpage.moveSlideUp();else return!0;else b.fn.fullpage.moveSlideUp()}return!1}}}function k(a){var e={},d;d=a.position();d=null!==d?
d.top:null;h=!0;"undefined"!==typeof a.data("anchor")?location.hash=a.data("anchor"):location.hash="";c.autoScrolling?(e.top=-d,d="#superContainer"):(e.scrollTop=d,d="html, body");b(d).animate(e,c.scrollingSpeed,c.easing,function(){b.isFunction(c.afterLoad)&&c.afterLoad.call(this,f,a.index(".section")+1);setTimeout(function(){h=!1},700)});var f=a.attr("data-anchor");r=f;s(f);x(f)}function y(){var a=window.location.hash.replace("#","");a&&(a=b('[data-anchor="'+a+'"]'),a.addClass("active").siblings().removeClass("active"),
k(a))}function t(){var a=b(window).width(),e=b(window).height();c.scrollOverflow&&b(".section").each(function(){b(this).find(".scrollable").css("height",e+"px").parent().css("height",e+"px")});c.resize&&z(e,a);b(".section").each(function(){b(this).css("height",e+"px");var a=b(this).find(".slides");if(0a||900>c?(900>c&&(f=c,d=900),d=(100*f/d).toFixed(2),b("body").css("font-size",d+"%")):b("body").css("font-size","100%")}function x(a){c.navigation&&(b("#fullPage-nav").find(".active").removeClass("active"),b("#fullPage-nav").find('a[href="#'+a+'"]').addClass("active"))}function s(a){c.menu&&(b(c.menu).find(".active").removeClass("active"),b(c.menu).find('[data-menuanchor="'+a+'"]').addClass("active"))}function l(a,b){if("top"===a)return!b.scrollTop();if("bottom"===
a)return b.scrollTop()+b.innerHeight()>=b[0].scrollHeight}c=b.extend({verticalCentered:!0,resize:!0,slidesColor:[],anchors:[],scrollingSpeed:700,easing:"easeInQuart",menu:!1,navigation:!1,navigationPosition:"right",navigationColor:"#000",controlArrowColor:"#fff",loopBottom:!1,loopTop:!1,autoScrolling:!0,scrollOverflow:!1,afterLoad:null,afterRender:null},c);b.fn.fullpage.setAutoScrolling=function(a){c.autoScrolling=a;c.autoScrolling?b("html, body").css({overflow:"hidden",height:"100%"}):(b("html, body").css({overflow:"auto",
height:"auto"}),b("#superContainer").css("top","0px"))};var n=!0,p=navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|Windows Phone)/),q=b(window).height(),h=!1,r;b.fn.fullpage.setAutoScrolling(c.autoScrolling);c.verticalCentered&&b(".section").addClass("table").wrapInner('
');b("body").wrapInner('
');if(c.navigation){b("body").append('

');var g=b("#fullPage-nav");g.css("color",c.navigationColor);"right"===
c.navigationPosition?g.css("right","17px"):g.css("left","17px")}b(".section").each(function(a){var e=b(this).find(".slide"),d=e.length;a||b(this).addClass("active");b(this).css("height",q+"px");"undefined"!==typeof c.slidesColor[a]&&b(this).css("background-color",c.slidesColor[a]);"undefined"!==typeof c.anchors[a]&&b(this).attr("data-anchor",c.anchors[a]);c.navigation&&b("#fullPage-nav").find("ul").append('

');if(0<d){a=100*d;var f=100/d;e.wrapAll('
');
e.parent().wrap('
');b(this).find(".slidesContainer").css("width",a+"%");b(this).find(".slides").after('

');b(".controlArrow.next").css("border-color","transparent transparent transparent "+c.controlArrowColor);b(".controlArrow.prev").css("border-color","transparent "+c.controlArrowColor+" transparent transparent");e.each(function(a){a||b(this).addClass("active");b(this).css("width",f+"%")})}}).promise().done(function(){b.isFunction(c.afterRender)&&
c.afterRender.call(this);if(c.scrollOverflow)b(window).on("load",function(){b(".section").each(function(){b(this).height()>q&&(c.verticalCentered?b(this).find(".tableCell").wrapInner('
'):b(this).wrapInner('
'),b(this).find(".scrollable").slimScroll({height:q+"px",size:"10px",alwaysVisible:!0}))})});y()});b(window).scroll(function(a){if(c.menu&&!c.autoScrolling){var e=b(window).scrollTop();a=b(".section").map(function(){if(b(this).offset().top<e+100)return b(this)});
a=a[a.length-1];b(".section.active").removeClass("active");a.addClass("active");var d=a.attr("data-anchor");b.isFunction(c.afterLoad)&&c.afterLoad.call(this,d,a.index(".section")+1);s(d)}});var u=0,v=0;b(document).on("touchmove",function(a){if(c.autoScrolling&&p&&(a.preventDefault(),a=a.originalEvent,!h)){var e=b(".section.active").find(".scrollable");v=a.touches[0].pageY;if(u>v)if(0<e.length)if(l("bottom",e))b.fn.fullpage.moveSlideDown();else return!0;else b.fn.fullpage.moveSlideDown();else if(0<
e.length)if(l("top",e))b.fn.fullpage.moveSlideUp();else return!0;else b.fn.fullpage.moveSlideUp()}});b(document).on("touchstart",function(a){c.autoScrolling&&p&&(u=a.originalEvent.touches[0].pageY)});g={};g=document;g.addEventListener?(g.addEventListener("mousewheel",m(),!1),g.addEventListener("DOMMouseScroll",m(),!1)):g.attachEvent("onmousewheel",m());b.fn.fullpage.moveSlideUp=function(){var a=b(".section.active").prev(".section");c.loopTop&&!a.length&&(a=b(".section").last());if(0<a.length||!a.length&&
c.loopTop)a.addClass("active").siblings().removeClass("active"),k(a)};b.fn.fullpage.moveSlideDown=function(){var a=b(".section.active").next(".section");c.loopBottom&&!a.length&&(a=b(".section").first());if(0<a.length||!a.length&&c.loopBottom)a.addClass("active").siblings().removeClass("active"),k(a)};b.fn.fullpage.moveToSlide=function(a){var c="",c=isNaN(a)?b('[data-anchor="'+a+'"]'):b(".section").eq(a-1);0<c.length&&(c.addClass("active").siblings().removeClass("active"),k(c))};b(window).on("hashchange",
function(){var a=window.location.hash.replace("#","");a!==r&&(a=b('[data-anchor="'+a+'"]'),a.addClass("active").siblings().removeClass("active"),k(a))});b(document).keydown(function(a){if(!h)switch(a.which){case 38:case 33:b.fn.fullpage.moveSlideUp();break;case 40:case 34:b.fn.fullpage.moveSlideDown();break;case 37:b(".section.active").find(".controlArrow.prev").trigger("click");break;case 39:b(".section.active").find(".controlArrow.next").trigger("click")}});b(".section").on("click",".controlArrow",
function(){if(n){n=!1;var a=b(this).closest(".section").find(".slides"),c=a.find(".slidesContainer").parent(),a=a.find(".slide.active"),d=null,f=0;a.removeClass("active");d=b(this).hasClass("prev")?a.prev(".slide"):a.next(".slide");0<d.length||(d=b(this).hasClass("prev")?a.siblings(":last"):a.siblings(":first"));f=d.position();c.animate({scrollLeft:f.left},500,function(){n=!0});d.addClass("active")}});b(".section").on("click",".toSlide",function(a){a.preventDefault();a=b(this).closest(".section").find(".slides");
var c=a.find(".slidesContainer").parent(),d=a.find(".slide.active"),f=null,g=0,f=a.find(".slide").eq(b(this).attr("data-index")-1);0<f.length&&(d.removeClass("active"),g=f.position(),c.animate({scrollLeft:g.left},500),f.addClass("active"))});if(!p){var w;b(window).resize(function(){clearTimeout(w);w=setTimeout(t,500)})}b(window).bind("orientationchange",function(){t()})}})(jQuery);<|endoftext|>


<commit_before>var QRCodeScanner = {
  canvas: document.getElementById("qr-canvas"),
  video: document.getElementById('v'),
  // photo: document.getElementById('p'),
  width: 320,
  height: 240,
  streaming: false,

  read: function scanner_read(txt) {
    // alert(txt);
    var msg = document.getElementById('message');
    msg.innerHTML = this.formatContent(txt);
  },

  formatContent: function scanner_format(txt) {
    if (txt.indexOf('http') === 0) {
      return '' + txt + '';
    } else {
      return txt;
    }
  },

  // imageData: null,
  context: null,
  init: function scanner_init() {
  	navigator.getMedia = ( navigator.getUserMedia ||
                         navigator.webkitGetUserMedia ||
                         navigator.mozGetUserMedia ||
                         navigator.msGetUserMedia);
  	var self = this;
  	navigator.getMedia(
      {
        video: true,
        audio: false
      },
      function(stream) {
        // if (navigator.mozGetUserMedia) {
        //   self.video.mozSrcObject = stream;
        // } else {
        var vendorURL = window.URL || window.webkitURL;
        self.video.src = vendorURL.createObjectURL(stream);
        // }
        self.video.play();
      },
        function(err) {
        console.log("An error occured! " + err);
      }
    );

    this.canvas.addEventListener("dragenter", this.dragenter, false);
    this.canvas.addEventListener("dragover", this.dragover, false);
    this.canvas.addEventListener("drop", this.drop.bind(this), false);

    qrcode.callback = this.read.bind(this);

    this.video.addEventListener('canplay', function(ev){
      if (!self.streaming) {
        // self.height = self.video.videoHeight / (self.video.videoWidth/self.width);
        self.video.setAttribute('width', self.width);
        self.video.setAttribute('height', self.height);
        self.canvas.setAttribute('width', self.width);
        self.canvas.setAttribute('height', self.height);
        self.streaming = true;
        // console.log('w:'+self.video.videoWidth+'/h:'+self.video.videoHeight);
        self.canvas.style.width = self.width + "px";
        self.canvas.style.height = self.height + "px";
        self.canvas.width = self.width;
        self.canvas.height = self.height;
        self.context = self.canvas.getContext("2d");
        self.context.clearRect(0, 0, self.width, self.height);
        // self.imageData = self.context.getImageData(0,0,
        //   self.video.videoWidth,self.video.videoHeight);
      }
    }, false);

    var capture = document.getElementById('capture');
    capture.addEventListener('click', function(ev){
      self.scanQRCode();
      ev.preventDefault();
    });
  },

  dragenter: function scanner_dragenter(e) {
    e.stopPropagation();
    e.preventDefault();
  },

  dragover: function scanner_dragover(e) {
    e.stopPropagation();
    e.preventDefault();
  },

  drop: function scanner_drop(e) {
    e.stopPropagation();
    e.preventDefault();

    var dt = e.dataTransfer;
    var files = dt.files;

    this.handleFiles(files);
  },

  handleFiles: function scanner_handleFiles(f) {
    var o=[];
    for(var i =0;i<f.length;i++)
    {
      var reader = new FileReader();

      reader.onload = (function(theFile) {
        return function(e) {
          qrcode.decode(e.target.result);
        };
      })(f[i]);

      // Read in the image file as a data URL.
      reader.readAsDataURL(f[i]);
    }
  },

  scanQRCode: function scanner_scanQRCode() {
    this.context.drawImage(this.video, 0, 0, this.width, this.height);
    var data = this.canvas.toDataURL('image/png');
    // this.photo.setAttribute('src', data);
  	qrcode.decode();
  },
}

window.addEventListener('load', function onload_scanner() {
  window.removeEventListener('load', onload_scanner);
  QRCodeScanner.init();
});<commit_msg>add jsdoc<commit_after>var QRCodeScanner = {
  canvas: document.getElementById("qr-canvas"),
  video: document.getElementById('v'),
  // photo: document.getElementById('p'),
  width: 320,
  height: 240,
  streaming: false,

  /**
   * Present content on screen
   */
  read: function scanner_read(txt) {
    // alert(txt);
    if (txt) {
      // this.video.pause();
      var msg = document.getElementById('message');
      msg.innerHTML = this.formatContent(txt);
    }
  },

  formatContent: function scanner_format(txt) {
    if (txt.indexOf('http') === 0) {
      return '' + txt + '';
    } else {
      return txt;
    }
  },

  // imageData: null,
  context: null,

  init: function scanner_init() {
  	navigator.getMedia = ( navigator.getUserMedia ||
                         navigator.webkitGetUserMedia ||
                         navigator.mozGetUserMedia ||
                         navigator.msGetUserMedia);
  	var self = this;
  	navigator.getMedia(
      {
        video: true,
        audio: false
      },
      function(stream) {
        // if (navigator.mozGetUserMedia) {
        //   self.video.mozSrcObject = stream;
        // } else {
        var vendorURL = window.URL || window.webkitURL;
        self.video.src = vendorURL.createObjectURL(stream);
        // }
        self.video.play();
      },
        function(err) {
        console.log("An error occured! " + err);
      }
    );

    this.canvas.addEventListener("dragenter", this.dragenter, false);
    this.canvas.addEventListener("dragover", this.dragover, false);
    this.canvas.addEventListener("drop", this.drop.bind(this), false);

    qrcode.callback = this.read.bind(this);

    this.video.addEventListener('canplay', function(ev){
      if (!self.streaming) {
        // self.height = self.video.videoHeight / (self.video.videoWidth/self.width);
        self.video.setAttribute('width', self.width);
        self.video.setAttribute('height', self.height);
        self.canvas.setAttribute('width', self.width);
        self.canvas.setAttribute('height', self.height);
        self.streaming = true;
        // console.log('w:'+self.video.videoWidth+'/h:'+self.video.videoHeight);
        self.canvas.style.width = self.width + "px";
        self.canvas.style.height = self.height + "px";
        self.canvas.width = self.width;
        self.canvas.height = self.height;
        self.context = self.canvas.getContext("2d");
        self.context.clearRect(0, 0, self.width, self.height);
        // self.imageData = self.context.getImageData(0,0,
        //   self.video.videoWidth,self.video.videoHeight);
      }
    }, false);

    var capture = document.getElementById('capture');
    capture.addEventListener('click', function(ev){
      self.scanQRCode();
      ev.preventDefault();
    });
  },

  dragenter: function scanner_dragenter(e) {
    e.stopPropagation();
    e.preventDefault();
  },

  dragover: function scanner_dragover(e) {
    e.stopPropagation();
    e.preventDefault();
  },

  drop: function scanner_drop(e) {
    e.stopPropagation();
    e.preventDefault();

    var dt = e.dataTransfer;
    var files = dt.files;

    this.handleFiles(files);
  },

  handleFiles: function scanner_handleFiles(f) {
    var o=[];
    for(var i =0;i<f.length;i++)
    {
      var reader = new FileReader();

      reader.onload = (function(theFile) {
        return function(e) {
          qrcode.decode(e.target.result);
        };
      })(f[i]);

      // Read in the image file as a data URL.
      reader.readAsDataURL(f[i]);
    }
  },

  /**
   * Decode the QRCode
   */
  scanQRCode: function scanner_scanQRCode() {
    // this.video.play();
    this.context.drawImage(this.video, 0, 0, this.width, this.height);
    var data = this.canvas.toDataURL('image/png');
    // this.photo.setAttribute('src', data);
  	qrcode.decode();
  },
}

window.addEventListener('load', function onload_scanner() {
  window.removeEventListener('load', onload_scanner);
  QRCodeScanner.init();
});<|endoftext|>


<commit_before>var _ = require("lodash");

var wrapInOr = function(states){
  if(_.size(states) === 1){
    return _.head(states);
  }
  return ["or", _.head(states), wrapInOr(_.tail(states))];
};

var toLispArgs = function(ast, traverse){
  return _.map(ast.args, traverse);
};

var event_ops = {
  "or": {
    toLispArgs: toLispArgs,
    mkStateMachine: function(start, end, args, newState, evalEELisp){
      var stm = {};
      stm[start] = [];

      var loop_backers = [];

      var a = evalEELisp(args[0], "aaa-START", "aaa-END");
      var b = evalEELisp(args[1], "aaa-START", "aaa-END");

      _.each([a, b], function(asdf){
        _.each(asdf["aaa-START"], function(transition){
          var condition = transition[0];
          var next_state = transition[1];
          if(next_state === "aaa-END"){
            stm[start].push([condition, end]);
          }else if(next_state === "aaa-START"){
            loop_backers.push(condition);
          }
        });
      });
      stm[start].push([["and"].concat(loop_backers), start]);
      return stm;
    }
  },
  "and": {
    toLispArgs: toLispArgs,
    mkStateMachine: function(start, end, args, newState){
      var a = args[0];
      var b = args[1];
      var s1 = newState();
      var s2 = newState();

      var stm = {};
      stm[start] = [
        [a, s1],
        [b, s2],
        [["not", ["or", a, b]], start]
      ];
      stm[s1] = [
        [b, end],
        [["not", b], s1]
      ];
      stm[s2] = [
        [a, end],
        [["not", a], s2]
      ];
      return stm;
    }
  }
};

module.exports = function(ast, comp, e){
  if(ast.kind !== "when"){
    throw new Error("RuleSelect.kind not supported: " + ast.kind);
  }
  var ee_id = 0;
  var graph = {};
  var eventexprs = {};

  var onEE = function(ast){
    var domain = ast.event_domain.value;
    var type = ast.event_type.value;
    var id = "expr_" + (ee_id++);

    _.set(graph, [domain, type, id], true);

    eventexprs[id] = comp(ast);
    return id;
  };

  var traverse = function(ast){
    if(ast.type === "EventExpression"){
      return onEE(ast);
    }else if(ast.type === "EventOperator"){
      if(_.has(event_ops, ast.op)){
        return [ast.op].concat(event_ops[ast.op].toLispArgs(ast, traverse));
      }
      throw new Error("EventOperator.op not supported: " + ast.op);
    }
    throw new Error("invalid event ast node: " + ast.type);
  };

  var newState = (function(){
    var i = 0;
    return function(){
      var id = "state_" + i;
      i++;
      return id;
    };
  }());

  var evalEELisp = function(lisp, start, end){
    if(_.isString(lisp)){
      var stm = {};
      stm[start] = [
        [lisp, end],
        [["not", lisp], start]
      ];
      return stm;
    }
    if(_.has(event_ops, lisp[0])){
      return event_ops[lisp[0]].mkStateMachine(start, end, lisp.slice(1), newState, evalEELisp);
    }else{
      throw new Error("EventOperator.op not supported: " + ast.op);
    }
  };

  var lisp = traverse(ast.event);
  var state_machine = evalEELisp(lisp, "start", "end");

  return e("obj", {
    graph: e("json", graph),
    eventexprs: e("obj", eventexprs),
    state_machine: e("json", state_machine)
  });
};
<commit_msg>new way of merging 'and' state machines<commit_after>var _ = require("lodash");

var wrapInOr = function(states){
  if(_.size(states) === 1){
    return _.head(states);
  }
  return ["or", _.head(states), wrapInOr(_.tail(states))];
};

var toLispArgs = function(ast, traverse){
  return _.map(ast.args, traverse);
};

var event_ops = {
  "or": {
    toLispArgs: toLispArgs,
    mkStateMachine: function(start, end, args, newState, evalEELisp){
      var stm = {};
      stm[start] = [];

      var loop_backers = [];

      var a = evalEELisp(args[0], "aaa-START", "aaa-END");
      var b = evalEELisp(args[1], "aaa-START", "aaa-END");

      _.each([a, b], function(asdf){
        _.each(asdf["aaa-START"], function(transition){
          var condition = transition[0];
          var next_state = transition[1];
          if(next_state === "aaa-END"){
            stm[start].push([condition, end]);
          }else if(next_state === "aaa-START"){
            loop_backers.push(condition);
          }
        });
      });
      stm[start].push([["and"].concat(loop_backers), start]);
      return stm;
    }
  },
  "and": {
    toLispArgs: toLispArgs,
    mkStateMachine: function(start, end, args, newState, evalEELisp){
      var a = evalEELisp(args[0], "aaa-START", "aaa-END");
      var b = evalEELisp(args[1], "bbb-START", "bbb-END");

      var s1 = newState();
      var s2 = newState();

      var loop_backers = [];

      var stm = {};
      stm[start] = [];
      stm[s1] = [];
      stm[s2] = [];

      _.each(a["aaa-START"], function(transition){
        var condition = transition[0];
        var next_state = transition[1];
        if(next_state === "aaa-END"){
          stm[start].push([condition, s1]);
          stm[s2].push([condition, end]);
        }else if(next_state === "aaa-START"){
          loop_backers.push(condition);
          stm[s2].push([condition, s2]);
        }
      });

      _.each(b["bbb-START"], function(transition){
        var condition = transition[0];
        var next_state = transition[1];
        if(next_state === "bbb-END"){
          stm[start].push([condition, s2]);
          stm[s1].push([condition, end]);
        }else if(next_state === "bbb-START"){
          loop_backers.push(condition);
          stm[s1].push([condition, s1]);
        }
      });

      stm[start].push([["and"].concat(loop_backers), start]);
      return stm;
    }
  }
};

module.exports = function(ast, comp, e){
  if(ast.kind !== "when"){
    throw new Error("RuleSelect.kind not supported: " + ast.kind);
  }
  var ee_id = 0;
  var graph = {};
  var eventexprs = {};

  var onEE = function(ast){
    var domain = ast.event_domain.value;
    var type = ast.event_type.value;
    var id = "expr_" + (ee_id++);

    _.set(graph, [domain, type, id], true);

    eventexprs[id] = comp(ast);
    return id;
  };

  var traverse = function(ast){
    if(ast.type === "EventExpression"){
      return onEE(ast);
    }else if(ast.type === "EventOperator"){
      if(_.has(event_ops, ast.op)){
        return [ast.op].concat(event_ops[ast.op].toLispArgs(ast, traverse));
      }
      throw new Error("EventOperator.op not supported: " + ast.op);
    }
    throw new Error("invalid event ast node: " + ast.type);
  };

  var newState = (function(){
    var i = 0;
    return function(){
      var id = "state_" + i;
      i++;
      return id;
    };
  }());

  var evalEELisp = function(lisp, start, end){
    if(_.isString(lisp)){
      var stm = {};
      stm[start] = [
        [lisp, end],
        [["not", lisp], start]
      ];
      return stm;
    }
    if(_.has(event_ops, lisp[0])){
      return event_ops[lisp[0]].mkStateMachine(start, end, lisp.slice(1), newState, evalEELisp);
    }else{
      throw new Error("EventOperator.op not supported: " + ast.op);
    }
  };

  var lisp = traverse(ast.event);
  var state_machine = evalEELisp(lisp, "start", "end");

  return e("obj", {
    graph: e("json", graph),
    eventexprs: e("obj", eventexprs),
    state_machine: e("json", state_machine)
  });
};
<|endoftext|>


<commit_before>var assert = require("assert");
var path = require("path");
var promisify = require("promisify-node");
var fse = promisify(require("fs-extra"));
var Diff = require("../../lib/diff");
var normalizeOptions = require("../../lib/util/normalize_options");
var NodeGit = require("../../");

describe("Diff", function() {
  var Repository = require("../../lib/repository");
  var reposPath = path.resolve("test/repos/workdir/.git");
  var oid = "fce88902e66c72b5b93e75bdb5ae717038b221f6";
  var diffFilename = "wddiff.txt";
  var diffFilepath = path.join(
    path.resolve("test/repos/workdir"),
    diffFilename
  );

  before(function() {
    var test = this;

    return Repository.open(reposPath).then(function(repository) {
      test.repository = repository;

      return repository.getBranchCommit("master");
    })
    .then(function(masterCommit) {
      return masterCommit.getTree();
    })
    .then(function(tree) {
      test.masterCommitTree = tree;

      return test.repository.getCommit(oid);
    })
    .then(function(commit) {
      test.commit = commit;

      return commit.getDiff();
    }).then(function(diff) {
      test.diff = diff;

      return fse.writeFile(diffFilepath, "1 line\n2 line\n3 line\n\n4");
    })
    .then(function() {
      return Diff.treeToWorkdirWithIndex(
        test.repository,
        test.masterCommitTree,
        normalizeOptions({
          flags: Diff.OPTION.INCLUDE_UNTRACKED
        }, NodeGit.DiffOptions)
      );
    })
    .then(function(workdirDiff) {
      test.workdirDiff = workdirDiff;
    });
  });

  it("can walk a DiffList", function() {
    var patch = this.diff[0].patches()[0];

    assert.equal(patch.oldFile().path(), "README.md");
    assert.equal(patch.newFile().path(), "README.md");
    assert.equal(patch.size(), 1);
    assert.ok(patch.isModified());

    var hunk = patch.hunks()[0];
    assert.equal(hunk.size(), 5);

    var lines = hunk.lines();
    assert.equal(lines[0].origin(), Diff.LINE.CONTEXT);
    assert.equal(lines[1].origin(), Diff.LINE.CONTEXT);
    assert.equal(lines[2].origin(), Diff.LINE.CONTEXT);

    var oldContent = "__Before submitting a pull request, please ensure " +
      "both unit tests and lint checks pass.__\n";
    assert.equal(lines[3].content(), oldContent);
    assert.equal(lines[3].origin(), Diff.LINE.DELETION);
    assert.equal(lines[3].contentLen(), 90);

    var newContent = "__Before submitting a pull request, please ensure " +
      "both that you've added unit tests to cover your shiny new code, " +
      "and that all unit tests and lint checks pass.__\n";
    assert.equal(lines[4].content(), newContent);
    assert.equal(lines[4].origin(), Diff.LINE.ADDITION);
    assert.equal(lines[4].contentLen(), 162);
  });

  it("can diff the workdir with index", function() {
    var patches = this.workdirDiff.patches();
    assert.equal(patches.length, 1);
    assert(patches[0].isUntracked());

    var oldFile = patches[0].delta.oldFile();
    assert.equal(oldFile.path(), "wddiff.txt");
    assert.equal(oldFile.size(), 0);

    var newFile = patches[0].delta.newFile();
    assert.equal(newFile.path(), "wddiff.txt");
    assert.equal(newFile.size(), 23);
  });

  it("can diff with a null tree", function() {
    var repo = this.repository;
    var tree = this.masterCommitTree;
    return Diff.treeToTree(repo, null, tree, null).then(function(diff) {
      assert.equal(diff.patches().length, 85);
    });
  });

  it("can diff the initial commit of a repository", function() {
    var repo = this.repository;
    var oid = "99c88fd2ac9c5e385bd1fe119d89c83dce326219"; // First commit
    return repo.getCommit(oid).then(function(commit) {
      return commit.getDiff().then(function(diffs) {
        assert.equal(diffs[0].patches().length, 8);
      });
    });
  });
});
<commit_msg>Cleanup added file that was making status tests fail.<commit_after>var assert = require("assert");
var path = require("path");
var promisify = require("promisify-node");
var fse = promisify(require("fs-extra"));
var Diff = require("../../lib/diff");
var normalizeOptions = require("../../lib/util/normalize_options");
var NodeGit = require("../../");

describe("Diff", function() {
  var Repository = require("../../lib/repository");
  var reposPath = path.resolve("test/repos/workdir/.git");
  var oid = "fce88902e66c72b5b93e75bdb5ae717038b221f6";
  var diffFilename = "wddiff.txt";
  var diffFilepath = path.join(
    path.resolve("test/repos/workdir"),
    diffFilename
  );

  before(function() {
    var test = this;

    return Repository.open(reposPath).then(function(repository) {
      test.repository = repository;

      return repository.getBranchCommit("master");
    })
    .then(function(masterCommit) {
      return masterCommit.getTree();
    })
    .then(function(tree) {
      test.masterCommitTree = tree;

      return test.repository.getCommit(oid);
    })
    .then(function(commit) {
      test.commit = commit;

      return commit.getDiff();
    }).then(function(diff) {
      test.diff = diff;

      return fse.writeFile(diffFilepath, "1 line\n2 line\n3 line\n\n4");
    })
    .then(function() {
      return Diff.treeToWorkdirWithIndex(
        test.repository,
        test.masterCommitTree,
        normalizeOptions({
          flags: Diff.OPTION.INCLUDE_UNTRACKED
        }, NodeGit.DiffOptions)
      );
    })
    .then(function(workdirDiff) {
      test.workdirDiff = workdirDiff;
    });
  });

  after(function(done) {
    return fse.unlink(diffFilepath).then(function() {
      done();
    });
  });

  it("can walk a DiffList", function() {
    var patch = this.diff[0].patches()[0];

    assert.equal(patch.oldFile().path(), "README.md");
    assert.equal(patch.newFile().path(), "README.md");
    assert.equal(patch.size(), 1);
    assert.ok(patch.isModified());

    var hunk = patch.hunks()[0];
    assert.equal(hunk.size(), 5);

    var lines = hunk.lines();
    assert.equal(lines[0].origin(), Diff.LINE.CONTEXT);
    assert.equal(lines[1].origin(), Diff.LINE.CONTEXT);
    assert.equal(lines[2].origin(), Diff.LINE.CONTEXT);

    var oldContent = "__Before submitting a pull request, please ensure " +
      "both unit tests and lint checks pass.__\n";
    assert.equal(lines[3].content(), oldContent);
    assert.equal(lines[3].origin(), Diff.LINE.DELETION);
    assert.equal(lines[3].contentLen(), 90);

    var newContent = "__Before submitting a pull request, please ensure " +
      "both that you've added unit tests to cover your shiny new code, " +
      "and that all unit tests and lint checks pass.__\n";
    assert.equal(lines[4].content(), newContent);
    assert.equal(lines[4].origin(), Diff.LINE.ADDITION);
    assert.equal(lines[4].contentLen(), 162);
  });

  it("can diff the workdir with index", function() {
    var patches = this.workdirDiff.patches();
    assert.equal(patches.length, 1);
    assert(patches[0].isUntracked());

    var oldFile = patches[0].delta.oldFile();
    assert.equal(oldFile.path(), "wddiff.txt");
    assert.equal(oldFile.size(), 0);

    var newFile = patches[0].delta.newFile();
    assert.equal(newFile.path(), "wddiff.txt");
    assert.equal(newFile.size(), 23);
  });

  it("can diff with a null tree", function() {
    var repo = this.repository;
    var tree = this.masterCommitTree;
    return Diff.treeToTree(repo, null, tree, null).then(function(diff) {
      assert.equal(diff.patches().length, 85);
    });
  });

  it("can diff the initial commit of a repository", function() {
    var repo = this.repository;
    var oid = "99c88fd2ac9c5e385bd1fe119d89c83dce326219"; // First commit
    return repo.getCommit(oid).then(function(commit) {
      return commit.getDiff().then(function(diffs) {
        assert.equal(diffs[0].patches().length, 8);
      });
    });
  });
});
<|endoftext|>


<commit_before>
module.exports = readJson
readJson.processJson = processJson

var fs = require("fs")
  , semver = require("./semver")
  , log = require("../utils/log")

function readJson (jsonFile, tag, cb) {
  log(jsonFile, "readJson")
  fs.readFile(jsonFile, processJson(tag, cb))
}
function processJson (tag, cb) {
  if (!cb) cb = tag, tag = null
  if (typeof cb !== "function") {
    var thing = cb, cb = null
    return P(null, thing)
  } else return P

  function P (er, thing) {
    if (er) {
      if (cb) return cb(er, thing)
      throw er
    }
    if (Object.prototype.toString.call(thing) === "[object Object]") {
      return processObject(tag, cb)(er, thing)
    } else {
      return processJsonString(tag, cb)(er, thing)
    }
  }
}
function processJsonString (tag, cb) { return function (er, jsonString) {
  jsonString += ""
  if (er) return cb(er, jsonString)
  var json
  try {
    json = JSON.parse(jsonString)
  } catch (ex) {
    var e = new Error(
      "Failed to parse json\n"+ex.message+"\n"+jsonString)
    if (cb) return cb(e)
    throw e
  }
  return processObject(tag, cb)(er, json)
}}
function processObject (tag, cb) { return function (er, json) {
  ;[ "overlay", "env", "context", "ctx", "vnd", "vendor" ]
  .forEach(function (vnd) {
    if (!json[vnd]) return undefined
    ;["node", "npm"].forEach(function (k) {
      if (!json[vnd][k]) return undefined
      for (var i in json[vnd][k]) json[i] = json[vnd][k][i]
    })
  })

  // slashes would be a security risk.
  // anything else will just fail harmlessly.
  json.name = json.name.replace(/\//g, '-')
  if (tag) json.version += tag
  if (!(semver.valid(json.version))) {
    var e = new Error("Invalid version: "+json.version)
    if (cb) return cb(e)
    throw e
  }

  json._id = json.name+"-"+json.version
  json = testEngine(json)
  if (cb) cb(null,json)
  return json
}}

function testEngine (json) {
  if (!json.engines) json.engines = { "node" : "*" }

  var nodeVer = process.version
    , ok = false
  if (Array.isArray(json.engines)) {
    // Packages/1.0 commonjs style, with an array.
    // hack it to just hang a "node" member with the version range,
    // then do the npm-style check below.
    for (var i = 0, l = json.engines.length; i < l; i ++) {
      var e = json.engines[i].trim()
      if (e.substr(0, 4) === "node") {
        json.engines.node = e.substr(4)
        break
      }
    }
  }
  json._nodeSupported = semver.satisfies(nodeVer, json.engines.node || "undefined")
  return json
}
<commit_msg>Accept filenames on main, and only use "overlay" for overlay<commit_after>
module.exports = readJson
readJson.processJson = processJson

var fs = require("fs")
  , semver = require("./semver")
  , log = require("../utils/log")

function readJson (jsonFile, tag, cb) {
  log(jsonFile, "readJson")
  fs.readFile(jsonFile, processJson(tag, cb))
}
function processJson (tag, cb) {
  if (!cb) cb = tag, tag = null
  if (typeof cb !== "function") {
    var thing = cb, cb = null
    return P(null, thing)
  } else return P

  function P (er, thing) {
    if (er) {
      if (cb) return cb(er, thing)
      throw er
    }
    if (Object.prototype.toString.call(thing) === "[object Object]") {
      return processObject(tag, cb)(er, thing)
    } else {
      return processJsonString(tag, cb)(er, thing)
    }
  }
}
function processJsonString (tag, cb) { return function (er, jsonString) {
  jsonString += ""
  if (er) return cb(er, jsonString)
  var json
  try {
    json = JSON.parse(jsonString)
  } catch (ex) {
    var e = new Error(
      "Failed to parse json\n"+ex.message+"\n"+jsonString)
    if (cb) return cb(e)
    throw e
  }
  return processObject(tag, cb)(er, json)
}}
function processObject (tag, cb) { return function (er, json) {
  if (json.overlay) {
    ;["node", "npm"].forEach(function (k) {
      if (!json.overlay[k]) return undefined
      for (var i in json.overlay[k]) json[i] = json.overlay[k][i]
    })
  }

  // slashes would be a security risk.
  // anything else will just fail harmlessly.
  json.name = json.name.replace(/\//g, '-')
  if (tag) json.version += tag
  if (!(semver.valid(json.version))) {
    var e = new Error("Invalid version: "+json.version)
    if (cb) return cb(e)
    throw e
  }

  if (json.main) json.main = json.main.replace(/(\.js|\.node)$/, '')

  json._id = json.name+"-"+json.version
  json = testEngine(json)
  if (cb) cb(null,json)
  return json
}}

function testEngine (json) {
  if (!json.engines) json.engines = { "node" : "*" }

  var nodeVer = process.version
    , ok = false
  if (Array.isArray(json.engines)) {
    // Packages/1.0 commonjs style, with an array.
    // hack it to just hang a "node" member with the version range,
    // then do the npm-style check below.
    for (var i = 0, l = json.engines.length; i < l; i ++) {
      var e = json.engines[i].trim()
      if (e.substr(0, 4) === "node") {
        json.engines.node = e.substr(4)
        break
      }
    }
  }
  json._nodeSupported = semver.satisfies(nodeVer, json.engines.node || "undefined")
  return json
}
<|endoftext|>


<commit_before>var treeData = {};
var selectedNode = null;
var clickedNode = null;
var draggingNode = null;
var colors = d3.scale.category10();

// ------------- moving -------------------------------
var overCircle = function(d) {
    selectedNode = d;
    updateTempConnector();
};

var outCircle = function(d) {
    selectedNode = null;
    updateTempConnector();
};

var clickCircle = function(d) {
    clickedNode = d.node;
    console.log("You just clicked a node");
    console.log(clickedNode);
    updateTempConnector();
};

var addNewNode = function() {
    // Ignore the click event if it was suppressed
    if (d3.event.defaultPrevented) return;

    // Extract the click location\
    var point = d3.mouse(this)
        , p = {x: point[0], y: point[1]};

    var newNodes = [{x: p.x -50 , y: p.y -20, name: Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5)}];
    vis.selectAll("lonely")
        .data(newNodes).enter().append("circle")
        .attr("class", "lonely")
        .attr('r', 12)
        .attr("cx", p.x -50)
        .attr("cy", p.y -20)
        .style('fill', function (d) {
            return (d === selectedNode) ? d3.rgb(colors(d.id)).brighter().toString() : colors(d.id);
        })
        .style('stroke', function (d) {
            return d3.rgb(colors(d.id)).darker().toString();
        })
        .on('click', function(d){
            d3.event.stopPropagation();
            clickCircle(d);
            updateMenu();
            d3.select("#tableInformations").style("display","none");
            d3.select("#svgShape").style("display", "none");
            d3.select("#svgMenu").style("display", "block");
            if (d3.event.defaultPrevented) return; // click suppressed
        })
        .call(circleDragger);
};

var circleDragger = d3.behavior.drag()
    .on("drag", function(d) {
        draggingNode = d;
        d3.select(this).attr( 'pointer-events', 'none' );
        d.x += d3.event.dx;
        d.y += d3.event.dy;
        var node = d3.select(this);
        node.attr( { cx: d.x, cy: d.y } );
        updateTempConnector();
    })
    .on("dragend", function(d){
        var tempLinks = vis.selectAll(".templink");
        console.log(tempLinks[0]);
        draggingNode = null;
        // now restore the mouseover event or we won't be able to drag a 2nd time
        d3.select(this).attr( 'pointer-events', '' );
    });

var updateTempConnector = function() {
    var data = [];
    if ( draggingNode != null && selectedNode != null) {
        // have to flip the source coordinates since we did this for the existing connectors on the original tree
        data = [ {source: {x: selectedNode.y, y: selectedNode.x},
            target: {x: draggingNode.x, y: draggingNode.y} } ];
    }
    var link = vis.selectAll(".templink").data(data);

    link.enter().append("path")
        .attr("class", "templink")
        .attr("d", d3.svg.diagonal() )
        .attr('pointer-events', 'none');

    link.attr("d", d3.svg.diagonal());

    link.exit().remove();
};

// ------------- normal tree drawing code --------
var width  = 1000,
    height = 500;

var vis = d3.select('#viz')
    .append('svg')
    .attr('id', 'svgTree')
    .attr('width', width)
    .attr('height', height)
    .on("click", addNewNode)
    .append("svg:g").attr("transform", "translate(50, 20)");
/*
var div = d3.select("body")
    .append("div")     // declare the tooltip div
    .attr("id","toolTip")
    .attr("class", "tooltip")              // apply the 'tooltip' class
    .style("opacity", 0);
*/

var width = 460,
    height = 300,
    radius = Math.min(width, height) / 2;

var color = d3.scale.category20();

var arc = d3.svg.arc()
    .innerRadius(radius - 100)
    .outerRadius(radius - 50);

var tree = d3.layout.tree().size([150,150]);

/**
 * Display the tree with new data
 */
function displayTree() {
    var nodes = tree.nodes(treeData);
    var links = tree.links(nodes);

    var treeSvg = d3.select("#svgTree");
    treeSvg.selectAll('.node').remove();
    treeSvg.selectAll('.nodelink').remove();

    var diagonalHorizontal = d3.svg.diagonal().projection(function (d) {
        return [d.y, d.x];
    });
    var link = vis.selectAll(".nodelink")
        .data(links)
        .enter().append("path")
        .attr("class", "nodelink")
        .attr("d", diagonalHorizontal)
        .attr('pointer-events', 'none');

    var node = vis.selectAll("g.node")
        .data(nodes)
        .enter().append("g")
        .attr("transform", function (d) {
            return "translate(" + d.y + "," + d.x + ")";
        })
        .on('click', function (d) {
            d3.event.stopPropagation();
            updateMenu();
            d3.select("#tableInformations").style("display", "none");
            d3.select("#svgShape").style("display", "none");
            d3.select("#svgMenu").style("display", "block");
            if (d3.event.defaultPrevented) return; // click suppressed
        });

    node.append("path")
        //.attr('pointer-events', 'none')
        .attr('class', 'node')
        .attr("d", d3.superformula()
            .size(400)
            .type(function(d) {
                return d.node.monosaccharideType.shape;
            }))
        .style('fill', function(d) { return d.node.monosaccharideType.color;});

    // ------------- trickery to avoid collision detection

    // phantom node to give us mouseover in a radius around it
        node.append("circle")
            .attr("r", 60)
            .attr("opacity", 0.0) // change this to non-zero to see the target area
            .attr('pointer-events', 'mouseover')
            .on("mouseover", overCircle)
            .on("mouseout", outCircle)
            .on("click", clickCircle);

    // a new, unconnected node that can be dragged near others to connect it
}

<commit_msg>Modification star and triangle shape rotations<commit_after>var treeData = {};
var selectedNode = null;
var clickedNode = null;
var draggingNode = null;
var colors = d3.scale.category10();

// ------------- moving -------------------------------
var overCircle = function(d) {
    selectedNode = d;
    updateTempConnector();
};

var outCircle = function(d) {
    selectedNode = null;
    updateTempConnector();
};

var clickCircle = function(d) {
    clickedNode = d.node;
    console.log("You just clicked a node");
    console.log(clickedNode);
    updateTempConnector();
};

var addNewNode = function() {
    // Ignore the click event if it was suppressed
    if (d3.event.defaultPrevented) return;

    // Extract the click location\
    var point = d3.mouse(this)
        , p = {x: point[0], y: point[1]};

    var newNodes = [{x: p.x -50 , y: p.y -20, name: Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5)}];
    vis.selectAll("lonely")
        .data(newNodes).enter().append("circle")
        .attr("class", "lonely")
        .attr('r', 12)
        .attr("cx", p.x -50)
        .attr("cy", p.y -20)
        .style('fill', function (d) {
            return (d === selectedNode) ? d3.rgb(colors(d.id)).brighter().toString() : colors(d.id);
        })
        .style('stroke', function (d) {
            return d3.rgb(colors(d.id)).darker().toString();
        })
        .on('click', function(d){
            d3.event.stopPropagation();
            clickCircle(d);
            updateMenu();
            d3.select("#tableInformations").style("display","none");
            d3.select("#svgShape").style("display", "none");
            d3.select("#svgMenu").style("display", "block");
            if (d3.event.defaultPrevented) return; // click suppressed
        })
        .call(circleDragger);
};

var circleDragger = d3.behavior.drag()
    .on("drag", function(d) {
        draggingNode = d;
        d3.select(this).attr( 'pointer-events', 'none' );
        d.x += d3.event.dx;
        d.y += d3.event.dy;
        var node = d3.select(this);
        node.attr( { cx: d.x, cy: d.y } );
        updateTempConnector();
    })
    .on("dragend", function(d){
        var tempLinks = vis.selectAll(".templink");
        console.log(tempLinks[0]);
        draggingNode = null;
        // now restore the mouseover event or we won't be able to drag a 2nd time
        d3.select(this).attr( 'pointer-events', '' );
    });

var updateTempConnector = function() {
    var data = [];
    if ( draggingNode != null && selectedNode != null) {
        // have to flip the source coordinates since we did this for the existing connectors on the original tree
        data = [ {source: {x: selectedNode.y, y: selectedNode.x},
            target: {x: draggingNode.x, y: draggingNode.y} } ];
    }
    var link = vis.selectAll(".templink").data(data);

    link.enter().append("path")
        .attr("class", "templink")
        .attr("d", d3.svg.diagonal() )
        .attr('pointer-events', 'none');

    link.attr("d", d3.svg.diagonal());

    link.exit().remove();
};

// ------------- normal tree drawing code --------
var width  = 1000,
    height = 500;

var vis = d3.select('#viz')
    .append('svg')
    .attr('id', 'svgTree')
    .attr('width', width)
    .attr('height', height)
    .on("click", addNewNode)
    .append("svg:g").attr("transform", "translate(50, 20)");
/*
var div = d3.select("body")
    .append("div")     // declare the tooltip div
    .attr("id","toolTip")
    .attr("class", "tooltip")              // apply the 'tooltip' class
    .style("opacity", 0);
*/

var width = 460,
    height = 300,
    radius = Math.min(width, height) / 2;

var color = d3.scale.category20();

var arc = d3.svg.arc()
    .innerRadius(radius - 100)
    .outerRadius(radius - 50);

var tree = d3.layout.tree().size([150,150]);

/**
 * Display the tree with new data
 */
function displayTree() {
    var nodes = tree.nodes(treeData);
    var links = tree.links(nodes);

    var treeSvg = d3.select("#svgTree");
    treeSvg.selectAll('.node').remove();
    treeSvg.selectAll('.nodelink').remove();

    var diagonalHorizontal = d3.svg.diagonal().projection(function (d) {
        return [d.y, d.x];
    });
    var link = vis.selectAll(".nodelink")
        .data(links)
        .enter().append("path")
        .attr("class", "nodelink")
        .attr("d", diagonalHorizontal)
        .attr('pointer-events', 'none');

    var node = vis.selectAll("g.node")
        .data(nodes)
        .enter().append("g")
        .attr("transform", function (d) {
            return "translate(" + d.y + "," + d.x + ")";
        })
        .on('click', function (d) {
            d3.event.stopPropagation();
            updateMenu();
            d3.select("#tableInformations").style("display", "none");
            d3.select("#svgShape").style("display", "none");
            d3.select("#svgMenu").style("display", "block");
            if (d3.event.defaultPrevented) return; // click suppressed
        });

    node.append("path")
        //.attr('pointer-events', 'none')
        .attr('class', 'node')
        .attr("d", d3.superformula()
            .size(400)
            .type(function(d) {
                return d.node.monosaccharideType.shape;
            }))
        .attr("transform", function(d) {
            var shape = d.node.monosaccharideType.shape;
            if (shape == "star") {
                return "rotate(-20)";
            } else if (shape == "triangle") {
                return "rotate(30)";
            }
        })
        .style('fill', function(d) { return d.node.monosaccharideType.color;});

    // ------------- trickery to avoid collision detection

    // phantom node to give us mouseover in a radius around it
        node.append("circle")
            .attr("r", 60)
            .attr("opacity", 0.0) // change this to non-zero to see the target area
            .attr('pointer-events', 'mouseover')
            .on("mouseover", overCircle)
            .on("mouseout", outCircle)
            .on("click", clickCircle);

    // a new, unconnected node that can be dragged near others to connect it
}

<|endoftext|>


<commit_before>window.c.AdminUser = (function(m, h) {
    return {
        view: function(ctrl, args) {
            var user = args.item;
            return m('.w-row.admin-user', [
                m('.w-col.w-col-3.w-col-small-3.u-marginbottom-10', [
                    m('img.user-avatar[src="' + h.useAvatarOrDefault(user.profile_img_thumbnail) + '"]')
                ]),
                m('.w-col.w-col-9.w-col-small-9', [
                    m('.fontweight-semibold.fontsize-smaller.lineheight-tighter.u-marginbottom-10', [
                        m('a.alt-link[target="_blank"][href="/users/' + user.id + '/edit"]', user.name)
                    ]),
                    m('.fontsize-smallest', 'Usuário: ' + user.id),
                    m('.fontsize-smallest.fontcolor-secondary', 'Email: ' + user.email),
                    args.additional_data || m('')
                ])
            ]);
        }
    };
}(window.m, window.c.h));
<commit_msg>Show email in Admin Users if profile name is null [fix #108253852]<commit_after>window.c.AdminUser = (function(m, h) {
    return {
        view: function(ctrl, args) {
            var user = args.item;
            return m('.w-row.admin-user', [
                m('.w-col.w-col-3.w-col-small-3.u-marginbottom-10', [
                    m('img.user-avatar[src="' + h.useAvatarOrDefault(user.profile_img_thumbnail) + '"]')
                ]),
                m('.w-col.w-col-9.w-col-small-9', [
                    m('.fontweight-semibold.fontsize-smaller.lineheight-tighter.u-marginbottom-10', [
                        m('a.alt-link[target="_blank"][href="/users/' + user.id + '/edit"]', user.name || user.email)
                    ]),
                    m('.fontsize-smallest', 'Usuário: ' + user.id),
                    m('.fontsize-smallest.fontcolor-secondary', 'Email: ' + user.email),
                    args.additional_data || m('')
                ])
            ]);
        }
    };
}(window.m, window.c.h));
<|endoftext|>


<commit_before>'use strict';

// Module dependencies
const assert = require('assert');
const Promise = require('any-promise');

// Automatically or manually handle `next` according to fn's arguments length
module.exports = function wrapperFn(fn) {
  assert(typeof fn === 'function', 'Method fn must be a valid function');

  // Manually handle next
  if (fn.length > 1) return fn;

  // Automatically handle next
  return function(ctx, next) {
    return Promise.resolve(fn.call(this, ctx)).then(next);
  };
};
<commit_msg>optimize fn wrapper<commit_after>'use strict';

// Module dependencies
const assert = require('assert');
const Promise = require('any-promise');

// Automatically or manually handle `next` according to fn's arguments length
module.exports = function wrapperFn(fn) {
  assert(typeof fn === 'function', 'Method fn must be a valid function');

  // Manually handle next
  if (fn.length > 1) return fn;

  // Automatically handle next
  return (new Function('fn', 'Promise', `
    return function ${fn.name || ''}(ctx, next) {
      return Promise.resolve(fn.call(this, ctx)).then(next);
    }`
  ))(fn, Promise);
};
<|endoftext|>


<commit_before>(function(){
  'use strict';

  angular.module('topFive', ['topFive.home', 'topFive.searchFactory']);

})();
<commit_msg>fix syntax error with search submodule dependency injection<commit_after>(function(){
  'use strict';

  angular.module('topFive', ['topFive.home', 'topFive.search']);

})();
<|endoftext|>


<commit_before>/*global _, Kinetic*/
/*jslint nomen: true*/
(function () {
	'use strict';
	Kinetic.Link = function (config) {
		this.shapeFrom = config.shapeFrom;
		this.shapeTo = config.shapeTo;
		this.shapeType = 'Link';
		Kinetic.Shape.call(this, config);
		this._setDrawFuncs();
	};
	var calculateConnectorInner = _.memoize(
		function (parentX, parentY, parentWidth, parentHeight, childX, childY, childWidth, childHeight) {
			var parent = [
				{
					x: parentX + 0.5 * parentWidth,
					y: parentY
				},
				{
					x: parentX + parentWidth,
					y: parentY + 0.5 * parentHeight
				},
				{
					x: parentX + 0.5 * parentWidth,
					y: parentY + parentHeight
				},
				{
					x: parentX,
					y: parentY + 0.5 * parentHeight
				}
			], child = [
				{
					x: childX + 0.5 * childWidth,
					y: childY
				},
				{
					x: childX + childWidth,
					y: childY + 0.5 * childHeight
				},
				{
					x: childX + 0.5 * childWidth,
					y: childY + childHeight
				},
				{
					x: childX,
					y: childY + 0.5 * childHeight
				}
			], i, j, min = Infinity, bestParent, bestChild, dx, dy, current;
			for (i = 0; i < parent.length; i += 1) {
				for (j = 0; j < child.length; j += 1) {
					dx = parent[i].x - child[j].x;
					dy = parent[i].y - child[j].y;
					current = dx * dx + dy * dy;
					if (current < min) {
						bestParent = i;
						bestChild = j;
						min = current;
					}
				}
			}
			return {
				from: parent[bestParent],
				to: child[bestChild]
			};
		},
		function () {
			return Array.prototype.join.call(arguments, ',');
		}
	),
		calculateConnector = function (parent, child) {
			return calculateConnectorInner(parent.getX(), parent.getY(), parent.getWidth(), parent.getHeight(),
				child.getX(), child.getY(), child.getWidth(), child.getHeight());
		};
	Kinetic.Link.prototype = {
		drawHitFunc: function (context) {
			var shapeFrom = this.shapeFrom,
				shapeTo = this.shapeTo,
				conn,
				strokeWidth = this.getStrokeWidth();
			this.setStrokeWidth(strokeWidth * 9);
			conn = calculateConnector(shapeFrom, shapeTo);
			context.fillStyle = this.getStroke();
			context.beginPath();
			context.moveTo(conn.from.x, conn.from.y);
			context.lineTo(conn.to.x, conn.to.y);
			context.fillStrokeShape(this);
			this.setStrokeWidth(strokeWidth);
		},
		drawFunc: function (context) {
			var shapeFrom = this.shapeFrom,
				shapeTo = this.shapeTo,
				conn,
				n = Math.tan(Math.PI / 9);
			conn = calculateConnector(shapeFrom, shapeTo);
			context.fillStyle = this.getStroke();
			context.beginPath();
			context.moveTo(conn.from.x, conn.from.y);
			context.lineTo(conn.to.x, conn.to.y);
			context.fillStrokeShape(this);
			if (this.attrs.arrow) {
				var a1x, a1y, a2x, a2y, len = 14, iy, m,
					dx = conn.to.x - conn.from.x,
					dy = conn.to.y - conn.from.y;
				if (dx === 0) {
					iy = dy < 0 ? -1 : 1;
					a1x = conn.to.x + len * Math.sin(n) * iy;
					a2x = conn.to.x - len * Math.sin(n) * iy;
					a1y = conn.to.y - len * Math.cos(n) * iy;
					a2y = conn.to.y - len * Math.cos(n) * iy;
				} else {
					m = dy / dx;
					if (conn.from.x < conn.to.x) {
						len = -len;
					}
					a1x = conn.to.x + (1 - m * n) * len / Math.sqrt((1 + m * m) * (1 + n * n));
					a1y = conn.to.y + (m + n) * len / Math.sqrt((1 + m * m) * (1 + n * n));
					a2x = conn.to.x + (1 + m * n) * len / Math.sqrt((1 + m * m) * (1 + n * n));
					a2y = conn.to.y + (m - n) * len / Math.sqrt((1 + m * m) * (1 + n * n));
				}
				context.moveTo(a1x, a1y);
				context.lineTo(conn.to.x, conn.to.y);
				context.lineTo(a2x, a2y);
				context.lineTo(a1x, a1y);
				context.fillStrokeShape(this);
			}
		}
	};
	Kinetic.Util.extend(Kinetic.Link, Kinetic.Shape);
}());
Kinetic.Link.prototype.setMMAttr = function (newMMAttr) {
	'use strict';
	var style = newMMAttr && newMMAttr.style,
		dashTypes = {
			solid: [],
			dashed: [8, 8]
		};
	this.setStroke(style && style.color || 'red');
	this.setFill(style.color || 'red');
	this.setDashArray(dashTypes[style && style.lineStyle || 'dashed']);
	this.attrs.arrow = style && style.arrow || false;
};
<commit_msg>Revert "Links work in Kinetic 4.7.1"<commit_after>/*global _, Kinetic*/
/*jslint nomen: true*/
(function () {
	'use strict';
	Kinetic.Link = function (config) {
		this.shapeFrom = config.shapeFrom;
		this.shapeTo = config.shapeTo;
		this.shapeType = 'Link';
		Kinetic.Shape.call(this, config);
		this._setDrawFuncs();
	};
	var calculateConnectorInner = _.memoize(
		function (parentX, parentY, parentWidth, parentHeight, childX, childY, childWidth, childHeight) {
			var parent = [
				{
					x: parentX + 0.5 * parentWidth,
					y: parentY
				},
				{
					x: parentX + parentWidth,
					y: parentY + 0.5 * parentHeight
				},
				{
					x: parentX + 0.5 * parentWidth,
					y: parentY + parentHeight
				},
				{
					x: parentX,
					y: parentY + 0.5 * parentHeight
				}
			], child = [
				{
					x: childX + 0.5 * childWidth,
					y: childY
				},
				{
					x: childX + childWidth,
					y: childY + 0.5 * childHeight
				},
				{
					x: childX + 0.5 * childWidth,
					y: childY + childHeight
				},
				{
					x: childX,
					y: childY + 0.5 * childHeight
				}
			], i, j, min = Infinity, bestParent, bestChild, dx, dy, current;
			for (i = 0; i < parent.length; i += 1) {
				for (j = 0; j < child.length; j += 1) {
					dx = parent[i].x - child[j].x;
					dy = parent[i].y - child[j].y;
					current = dx * dx + dy * dy;
					if (current < min) {
						bestParent = i;
						bestChild = j;
						min = current;
					}
				}
			}
			return {
				from: parent[bestParent],
				to: child[bestChild]
			};
		},
		function () {
			return Array.prototype.join.call(arguments, ',');
		}
	),
		calculateConnector = function (parent, child) {
			return calculateConnectorInner(parent.getX(), parent.getY(), parent.getWidth(), parent.getHeight(),
				child.getX(), child.getY(), child.getWidth(), child.getHeight());
		};
	Kinetic.Link.prototype = {
		drawHitFunc: function (canvas) {
			var shapeFrom = this.shapeFrom,
				shapeTo = this.shapeTo,
				conn,
				strokeWidth = this.getStrokeWidth();
			this.setStrokeWidth(strokeWidth * 9);
			conn = calculateConnector(shapeFrom, shapeTo);
			canvas.fillStyle = this.getStroke();
			canvas.beginPath();
			canvas.moveTo(conn.from.x, conn.from.y);
			canvas.lineTo(conn.to.x, conn.to.y);
			canvas.stroke(this);
			this.setStrokeWidth(strokeWidth);
		},
		drawFunc: function (canvas) {
			var shapeFrom = this.shapeFrom,
				shapeTo = this.shapeTo,
				conn,
				n = Math.tan(Math.PI / 9);
			conn = calculateConnector(shapeFrom, shapeTo);
			canvas.fillStyle = this.getStroke();
			canvas.beginPath();
			canvas.moveTo(conn.from.x, conn.from.y);
			canvas.lineTo(conn.to.x, conn.to.y);
			canvas.stroke(this);
			if (this.attrs.arrow) {
				var a1x, a1y, a2x, a2y, len = 14, iy, m,
					dx = conn.to.x - conn.from.x,
					dy = conn.to.y - conn.from.y;
				if (dx === 0) {
					iy = dy < 0 ? -1 : 1;
					a1x = conn.to.x + len * Math.sin(n) * iy;
					a2x = conn.to.x - len * Math.sin(n) * iy;
					a1y = conn.to.y - len * Math.cos(n) * iy;
					a2y = conn.to.y - len * Math.cos(n) * iy;
				} else {
					m = dy / dx;
					if (conn.from.x < conn.to.x) {
						len = -len;
					}
					a1x = conn.to.x + (1 - m * n) * len / Math.sqrt((1 + m * m) * (1 + n * n));
					a1y = conn.to.y + (m + n) * len / Math.sqrt((1 + m * m) * (1 + n * n));
					a2x = conn.to.x + (1 + m * n) * len / Math.sqrt((1 + m * m) * (1 + n * n));
					a2y = conn.to.y + (m - n) * len / Math.sqrt((1 + m * m) * (1 + n * n));
				}
				canvas.moveTo(a1x, a1y);
				canvas.lineTo(conn.to.x, conn.to.y);
				canvas.lineTo(a2x, a2y);
				canvas.lineTo(a1x, a1y);
				canvas.fill();
			}
		}
	};
	Kinetic.Util.extend(Kinetic.Link, Kinetic.Shape);
}());
Kinetic.Link.prototype.setMMAttr = function (newMMAttr) {
	'use strict';
	var style = newMMAttr && newMMAttr.style,
		dashTypes = {
			solid: [],
			dashed: [8, 8]
		};
	this.setStroke(style && style.color || 'red');
	this.setDashArray(dashTypes[style && style.lineStyle || 'dashed']);
	this.attrs.arrow = style && style.arrow || false;
};
<|endoftext|>


<commit_before>"use strict";

var _ = require('lodash');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var sira = require('sira');
var express = require('express');
var debug = require('debug')('sira:rest');

var bodyParser = require('body-parser');
var cors = require('cors');
var async = require('async');

var json = bodyParser.json;
var urlencoded = bodyParser.urlencoded;

var SUPPORTED_TYPES = ['json', 'application/javascript', 'text/javascript'];

exports = module.exports = function (remotes, handler) {
    var rest = new Rest(remotes, handler);
    return rest.createHandler();
};

exports.Rest = Rest;
exports.RestClass = RestClass;
exports.RestMethod = RestMethod;
exports.sortRoutes = sortRoutes;

function Rest(remotes, handler) {
    EventEmitter.call(this);

    this.remotes = remotes;
    this.handler = handler && (typeof handler === 'function' ? handler : _.bind(handler.handle, handler));
}

util.inherits(Rest, EventEmitter);

Rest.prototype.createHandler = function () {
    var root = express.Router();
    var rest = this;
    var classes = this.buildClasses();

    // Add a handler to tolerate empty json as connect's json middleware throws an error
    root.use(function(req, res, next) {
        if(req.is('application/json')) {
            if(req.get('Content-Length') === '0') { // This doesn't cover the transfer-encoding: chunked
                req._body = true; // Mark it as parsed
                req.body = {};
            }
        }
        next();
    });

    // Set strict to be `false` so that anything `JSON.parse()` accepts will be parsed
    debug("remoting options: %j", this.remotes.options);
    var urlencodedOptions = this.remotes.options.urlencoded || {extended: true};
    if (urlencodedOptions.extended === undefined) {
        urlencodedOptions.extended = true;
    }
    var jsonOptions = this.remotes.options.json || {strict: false};
    var corsOptions = this.remotes.options.cors || {};
    root.use(urlencoded(urlencodedOptions));
    root.use(json(jsonOptions));
    root.use(cors(corsOptions));

    classes.forEach(function (restClass) {
        var router = express.Router();
        var className = restClass.sharedClass.name;

        debug('registering REST handler for class %j', className);

        var methods = [];
        // Register handlers for all shared methods of this class sharedClass
        restClass
            .methods
            .forEach(function(restMethod) {
                var sharedMethod = restMethod.sharedMethod;
                debug('    method %s', sharedMethod.stringName);
                restMethod.routes.forEach(function(route) {
                    methods.push({route: route, method: sharedMethod});
                });
            });

        // Sort all methods based on the route path
        methods.sort(sortRoutes);

        methods.forEach(function(m) {
            rest._registerMethodRouteHandlers(router, m.method, m.route);
        });

        // Convert requests for unknown methods of this sharedClass into 404.
        // Do not allow other middleware to invade our URL space.
        router.use(Rest.remoteMethodNotFoundHandler(className));

        // Mount the remoteClass router on all class routes.
        restClass
            .routes
            .forEach(function (route) {
                debug('    at %s', route.path);
                root.use(route.path, router);
            });

    });

    // Convert requests for unknown URLs into 404.
    // Do not allow other middleware to invade our URL space.
    root.use(Rest.urlNotFoundHandler());

    // Use our own error handler to make sure the error response has
    // always the format expected by remoting clients.
    root.use(Rest.errorHandler());

    return root;
};

Rest.prototype.buildClasses = function() {
    return this.remotes.classes().map(function(c) {
        return new RestClass(c);
    });
};

Rest.prototype._registerMethodRouteHandlers = function(router, sharedMethod, route) {
    debug('        %s %s %s', route.verb, route.path, sharedMethod.stringName);
    var verb = route.verb;
    if(verb === 'del') {
        // Express 4.x only supports delete
        verb = 'delete';
    }
    var self = this;
    router[verb](route.path, function (req, res, next) {
        var context = new RestContext(req, res, self.handler);
        self._handleRequest(context, sharedMethod, next);
    });
};

Rest.prototype._handleRequest = function(context, method, next) {
    context.handle(method, function (err) {
        if (err) return next(err);
    })
};

Rest.remoteMethodNotFoundHandler = function(className) {
    className = className || '(unknown)';
    return function restRemoteMethodNotFound(req, res, next) {
        var message = 'Shared class "' + className + '"' +
            ' has no method handling ' + req.method + ' ' + req.url;
        var error = new Error(message);
        error.status = error.statusCode = 404;
        next(error);
    };
};

Rest.urlNotFoundHandler = function() {
    return function restUrlNotFound(req, res, next) {
        var message = 'There is no method to handle ' + req.method + ' ' + req.url;
        var error = new Error(message);
        error.status = error.statusCode = 404;
        next(error);
    };
};

Rest.errorHandler = function() {
    return function restErrorHandler(err, req, res, next) {
        if(typeof err === 'string') {
            err = new Error(err);
            err.status = err.statusCode = 500;
        }

        res.statusCode = err.statusCode || err.status || 500;

        debug('Error in %s %s: %s', req.method, req.url, err.stack);
        var data = {
            name: err.name,
            status: res.statusCode,
            message: err.message || 'An unknown error occurred'
        };

        for (var prop in err)
            data[prop] = err[prop];

        // TODO(bajtos) Remove stack info when running in production
        data.stack = err.stack;

        res.send({ error: data });
    };
};

Rest.prototype.allRoutes = function () {
    var routes = [];
    var adapter = this;
    var classes = this.remotes.classes();
    var currentRoot = '';

    classes.forEach(function (sc) {
        adapter
            .getRoutes(sc)
            .forEach(function (classRoute) {
                currentRoot = classRoute.path;
                var methods = sc.methods();

                methods.forEach(function (method) {
                    adapter.getRoutes(method).forEach(function (route) {
                        if(method.isStatic) {
                            addRoute(route.verb, route.path, method);
                        } else {
                            adapter
                                .getRoutes(method.sharedCtor)
                                .forEach(function (sharedCtorRoute) {
                                    addRoute(route.verb, sharedCtorRoute.path + route.path, method);
                                });
                        }
                    });
                });
            });
    });

    return routes;

    function addRoute(verb, path, method) {
        if(path === '/' || path === '//') {
            path = currentRoot;
        } else {
            path = currentRoot + path;
        }

        if(path[path.length - 1] === '/') {
            path = path.substr(0, path.length - 1);
        }

        // TODO this could be cleaner
        path = path.replace(/\/\//g, '/');

        routes.push({
            verb: verb,
            path: path,
            description: method.description,
            method: method.stringName,
            accepts: (method.accepts && method.accepts.length) ? method.accepts : undefined,
            returns: (method.returns && method.returns.length) ? method.returns : undefined
        });
    }
};

/*!
 * Compare two routes
 * @param {Object} r1 The first route {route: {verb: 'get', path: '/:id'}, method: ...}
 * @param [Object} r2 The second route route: {verb: 'get', path: '/findOne'}, method: ...}
 * @returns {number} 1: r1 comes after 2, -1: r1 comes before r2, 0: equal
 */
function sortRoutes(r1, r2) {
    var a = r1.route;
    var b = r2.route;

    // Normalize the verbs
    var verb1 = a.verb.toLowerCase();
    var verb2 = b.verb.toLowerCase();

    if (verb1 === 'del') {
        verb1 = 'delete';
    }
    if (verb2 === 'del') {
        verb2 = 'delete';
    }
    // First sort by verb
    if (verb1 > verb2) {
        return -1;
    } else if (verb1 < verb2) {
        return 1;
    }

    // Sort by path part by part using the / delimiter
    // For example '/:id' will become ['', ':id'], '/findOne' will become
    // ['', 'findOne']
    var p1 = a.path.split('/');
    var p2 = b.path.split('/');
    var len = Math.min(p1.length, p2.length);

    // Loop through the parts and decide which path should come first
    for (var i = 0; i < len; i++) {
        // Empty part has lower weight
        if (p1[i] === '' && p2[i] !== '') {
            return 1;
        } else if (p1[i] !== '' && p2[i] === '') {
            return -1;
        }
        // Wildcard has lower weight
        if (p1[i][0] === ':' && p2[i][0] !== ':') {
            return 1;
        } else if (p1[i][0] !== ':' && p2[i][0] === ':') {
            return -1;
        }
        // Now the regular string comparision
        if (p1[i] > p2[i]) {
            return 1;
        } else if (p1[i] < p2[i]) {
            return -1;
        }
    }
    // Both paths have the common parts. The longer one should come before the
    // shorter one
    return p2.length - p1.length;
}

/**
 * Get the path for the given method.
 */

//Rest.prototype.buildRoutes = buildRoutes;
function buildRoutes(obj) {
    var routes = obj.http;

    if(routes && !Array.isArray(routes)) {
        routes = [routes];
    }

    // overidden
    if(routes) {
        // patch missing verbs / routes
        routes.forEach(function (r) {
            r.verb = String(r.verb || 'all').toLowerCase();
            r.path = r.path || ('/' + obj.name);
        });
    } else {
        if(obj.name === 'sharedCtor') {
            routes = [{
                verb: 'all',
                path: '/prototype'
            }];
        } else {
            // build default route
            routes = [{
                verb: 'all',
                path: obj.name ? ('/' + obj.name) : ''
            }];
        }
    }

    return routes;
}

function RestClass(sharedClass) {
    hiddenConstProperty(this, 'sharedClass', sharedClass);

    var self = this;
    this.name = sharedClass.name;
    this.routes = buildRoutes(sharedClass);

    this.ctor = sharedClass.sharedCtor && new RestMethod(this, sharedClass.sharedCtor);

    this.methods = sharedClass.methods()
        .filter(function(sm) {
            return !sm.isSharedCtor;
        })
        .map(function(sm) {
            return new RestMethod(self, sm);
        });
}

RestClass.prototype.getPath = function() {
    return this.routes[0].path;
};

function RestMethod(restClass, sharedMethod) {
    hiddenConstProperty(this, 'restClass', restClass);
    hiddenConstProperty(this, 'sharedMethod', sharedMethod);

    // The full name is ClassName.methodName or ClassName.prototype.methodName
    this.fullName = sharedMethod.stringName;
    this.name = this.fullName.split('.').slice(1).join('.');

    this.accepts = sharedMethod.accepts;
    this.returns = sharedMethod.returns;
    this.description = sharedMethod.description;

    var methodRoutes = buildRoutes(sharedMethod);
    if (sharedMethod.isStatic || !restClass.ctor) {
        this.routes = methodRoutes;
    } else {
        var routes = this.routes = [];
        methodRoutes.forEach(function(route) {
            restClass.ctor.routes.forEach(function(ctorRoute) {
                var fullRoute = util._extend({}, route);
                fullRoute.path = joinPaths(ctorRoute.path, route.path);
                routes.push(fullRoute);
            });
        });
    }
}

RestMethod.prototype.isReturningArray = function() {
    return this.returns.length == 1 &&
        this.returns[0].root &&
        getTypeString(this.returns[0].type) === 'array' || false;
};

RestMethod.prototype.acceptsSingleBodyArgument = function() {
    if (this.accepts.length != 1) return false;
    var accepts = this.accepts[0];

    return accepts.http &&
        accepts.http.source == 'body' &&
        getTypeString(accepts.type) == 'object' || false;
};

RestMethod.prototype.getHttpMethod = function() {
    var verb = this.routes[0].verb;
    if (verb == 'all') return 'POST';
    if (verb == 'del') return 'DELETE';
    return verb.toUpperCase();
};

RestMethod.prototype.getPath = function() {
    return this.routes[0].path;
};

RestMethod.prototype.getFullPath = function() {
    return joinPaths(this.restClass.getPath(), this.getPath());
};

function RestContext(req, res, handler) {
    this.req = req;
    this.res = res;
    this.handler = handler;
}

RestContext.prototype._buildRequest = function (method) {
    return sira.rekuest(method, this.req.query, this.req.params, this.req.body)
        .prop('body', this.req.body)
        .prop('query', this.req.query)
        .prop('path', this.req.params)
        .prop('accessToken', this.req.accessToken)
        .req;
};

RestContext.prototype.handle = function (method, cb) {
    var self = this;
    this.handler(this._buildRequest(method), function (err, ctx) { // sira context
        if (err) return cb(err);
        self.done(ctx.result);
        cb();
    });
};

RestContext.prototype.done = function (data) {
    // send the result back as
    // the requested content type
    var res = this.res;
    var accepts = this.req.accepts(SUPPORTED_TYPES);
    var dataExists = typeof data !== 'undefined';

    if(dataExists) {
        switch(accepts) {
            case 'json':
                res.json(data);
                break;
            case 'application/javascript':
            case 'text/javascript':
                res.jsonp(data);
                break;
            default:
                // not acceptable
                res.send(406);
                break;
        }
    } else {
        res.header('Content-Type', 'application/json');
        res.statusCode = 204;
        res.end();
    }
};

function hiddenConstProperty(where, property, value) {
    Object.defineProperty(where, property, {
        writable: false,
        enumerable: false,
        configurable: false,
        value: value
    });
}

function getTypeString(ctorOrName) {
    if (typeof ctorOrName === 'function')
        ctorOrName = ctorOrName.name;
    if (typeof ctorOrName === 'string') {
        return ctorOrName.toLowerCase();
    } else {
        debug('WARNING: unknown ctorOrName of type %s: %j',  typeof ctorOrName, ctorOrName);
        return typeof undefined;
    }
}

function joinPaths(left, right) {
    if (!left) return right;
    if (!right || right == '/') return left;

    var glue = left[left.length-1] + right[0];
    if (glue == '//')
        return left + right.slice(1);
    else if (glue[0] == '/' || glue[1] == '/')
        return left + right;
    else
        return left + '/' + right;
}

<commit_msg>support rest(sapp)<commit_after>"use strict";

var _ = require('lodash');
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var sira = require('sira');
var express = require('express');
var debug = require('debug')('sira:rest');

var bodyParser = require('body-parser');
var cors = require('cors');
var async = require('async');

var json = bodyParser.json;
var urlencoded = bodyParser.urlencoded;

var SUPPORTED_TYPES = ['json', 'application/javascript', 'text/javascript'];

exports = module.exports = function (remotes, handler) {
    if (remotes.remotes && remotes.handle) {
        handler = handler || remotes;
        remotes = remotes.remotes;
    }
    var rest = new Rest(remotes, handler);
    return rest.createHandler();
};

exports.Rest = Rest;
exports.RestClass = RestClass;
exports.RestMethod = RestMethod;
exports.sortRoutes = sortRoutes;

function Rest(remotes, handler) {
    EventEmitter.call(this);

    this.remotes = remotes;
    this.handler = handler && (typeof handler === 'function' ? handler : _.bind(handler.handle, handler));
}

util.inherits(Rest, EventEmitter);

Rest.prototype.createHandler = function () {
    var root = express.Router();
    var rest = this;
    var classes = this.buildClasses();

    // Add a handler to tolerate empty json as connect's json middleware throws an error
    root.use(function(req, res, next) {
        if(req.is('application/json')) {
            if(req.get('Content-Length') === '0') { // This doesn't cover the transfer-encoding: chunked
                req._body = true; // Mark it as parsed
                req.body = {};
            }
        }
        next();
    });

    // Set strict to be `false` so that anything `JSON.parse()` accepts will be parsed
    debug("remoting options: %j", this.remotes.options);
    var urlencodedOptions = this.remotes.options.urlencoded || {extended: true};
    if (urlencodedOptions.extended === undefined) {
        urlencodedOptions.extended = true;
    }
    var jsonOptions = this.remotes.options.json || {strict: false};
    var corsOptions = this.remotes.options.cors || {};
    root.use(urlencoded(urlencodedOptions));
    root.use(json(jsonOptions));
    root.use(cors(corsOptions));

    classes.forEach(function (restClass) {
        var router = express.Router();
        var className = restClass.sharedClass.name;

        debug('registering REST handler for class %j', className);

        var methods = [];
        // Register handlers for all shared methods of this class sharedClass
        restClass
            .methods
            .forEach(function(restMethod) {
                var sharedMethod = restMethod.sharedMethod;
                debug('    method %s', sharedMethod.stringName);
                restMethod.routes.forEach(function(route) {
                    methods.push({route: route, method: sharedMethod});
                });
            });

        // Sort all methods based on the route path
        methods.sort(sortRoutes);

        methods.forEach(function(m) {
            rest._registerMethodRouteHandlers(router, m.method, m.route);
        });

        // Convert requests for unknown methods of this sharedClass into 404.
        // Do not allow other middleware to invade our URL space.
        router.use(Rest.remoteMethodNotFoundHandler(className));

        // Mount the remoteClass router on all class routes.
        restClass
            .routes
            .forEach(function (route) {
                debug('    at %s', route.path);
                root.use(route.path, router);
            });

    });

    // Convert requests for unknown URLs into 404.
    // Do not allow other middleware to invade our URL space.
    root.use(Rest.urlNotFoundHandler());

    // Use our own error handler to make sure the error response has
    // always the format expected by remoting clients.
    root.use(Rest.errorHandler());

    return root;
};

Rest.prototype.buildClasses = function() {
    return this.remotes.classes().map(function(c) {
        return new RestClass(c);
    });
};

Rest.prototype._registerMethodRouteHandlers = function(router, sharedMethod, route) {
    debug('        %s %s %s', route.verb, route.path, sharedMethod.stringName);
    var verb = route.verb;
    if(verb === 'del') {
        // Express 4.x only supports delete
        verb = 'delete';
    }
    var self = this;
    router[verb](route.path, function (req, res, next) {
        var context = new RestContext(req, res, self.handler);
        self._handleRequest(context, sharedMethod, next);
    });
};

Rest.prototype._handleRequest = function(context, method, next) {
    context.handle(method, function (err) {
        if (err) return next(err);
    })
};

Rest.remoteMethodNotFoundHandler = function(className) {
    className = className || '(unknown)';
    return function restRemoteMethodNotFound(req, res, next) {
        var message = 'Shared class "' + className + '"' +
            ' has no method handling ' + req.method + ' ' + req.url;
        var error = new Error(message);
        error.status = error.statusCode = 404;
        next(error);
    };
};

Rest.urlNotFoundHandler = function() {
    return function restUrlNotFound(req, res, next) {
        var message = 'There is no method to handle ' + req.method + ' ' + req.url;
        var error = new Error(message);
        error.status = error.statusCode = 404;
        next(error);
    };
};

Rest.errorHandler = function() {
    return function restErrorHandler(err, req, res, next) {
        if(typeof err === 'string') {
            err = new Error(err);
            err.status = err.statusCode = 500;
        }

        res.statusCode = err.statusCode || err.status || 500;

        debug('Error in %s %s: %s', req.method, req.url, err.stack);
        var data = {
            name: err.name,
            status: res.statusCode,
            message: err.message || 'An unknown error occurred'
        };

        for (var prop in err)
            data[prop] = err[prop];

        // TODO(bajtos) Remove stack info when running in production
        data.stack = err.stack;

        res.send({ error: data });
    };
};

Rest.prototype.allRoutes = function () {
    var routes = [];
    var adapter = this;
    var classes = this.remotes.classes();
    var currentRoot = '';

    classes.forEach(function (sc) {
        adapter
            .getRoutes(sc)
            .forEach(function (classRoute) {
                currentRoot = classRoute.path;
                var methods = sc.methods();

                methods.forEach(function (method) {
                    adapter.getRoutes(method).forEach(function (route) {
                        if(method.isStatic) {
                            addRoute(route.verb, route.path, method);
                        } else {
                            adapter
                                .getRoutes(method.sharedCtor)
                                .forEach(function (sharedCtorRoute) {
                                    addRoute(route.verb, sharedCtorRoute.path + route.path, method);
                                });
                        }
                    });
                });
            });
    });

    return routes;

    function addRoute(verb, path, method) {
        if(path === '/' || path === '//') {
            path = currentRoot;
        } else {
            path = currentRoot + path;
        }

        if(path[path.length - 1] === '/') {
            path = path.substr(0, path.length - 1);
        }

        // TODO this could be cleaner
        path = path.replace(/\/\//g, '/');

        routes.push({
            verb: verb,
            path: path,
            description: method.description,
            method: method.stringName,
            accepts: (method.accepts && method.accepts.length) ? method.accepts : undefined,
            returns: (method.returns && method.returns.length) ? method.returns : undefined
        });
    }
};

/*!
 * Compare two routes
 * @param {Object} r1 The first route {route: {verb: 'get', path: '/:id'}, method: ...}
 * @param [Object} r2 The second route route: {verb: 'get', path: '/findOne'}, method: ...}
 * @returns {number} 1: r1 comes after 2, -1: r1 comes before r2, 0: equal
 */
function sortRoutes(r1, r2) {
    var a = r1.route;
    var b = r2.route;

    // Normalize the verbs
    var verb1 = a.verb.toLowerCase();
    var verb2 = b.verb.toLowerCase();

    if (verb1 === 'del') {
        verb1 = 'delete';
    }
    if (verb2 === 'del') {
        verb2 = 'delete';
    }
    // First sort by verb
    if (verb1 > verb2) {
        return -1;
    } else if (verb1 < verb2) {
        return 1;
    }

    // Sort by path part by part using the / delimiter
    // For example '/:id' will become ['', ':id'], '/findOne' will become
    // ['', 'findOne']
    var p1 = a.path.split('/');
    var p2 = b.path.split('/');
    var len = Math.min(p1.length, p2.length);

    // Loop through the parts and decide which path should come first
    for (var i = 0; i < len; i++) {
        // Empty part has lower weight
        if (p1[i] === '' && p2[i] !== '') {
            return 1;
        } else if (p1[i] !== '' && p2[i] === '') {
            return -1;
        }
        // Wildcard has lower weight
        if (p1[i][0] === ':' && p2[i][0] !== ':') {
            return 1;
        } else if (p1[i][0] !== ':' && p2[i][0] === ':') {
            return -1;
        }
        // Now the regular string comparision
        if (p1[i] > p2[i]) {
            return 1;
        } else if (p1[i] < p2[i]) {
            return -1;
        }
    }
    // Both paths have the common parts. The longer one should come before the
    // shorter one
    return p2.length - p1.length;
}

/**
 * Get the path for the given method.
 */

//Rest.prototype.buildRoutes = buildRoutes;
function buildRoutes(obj) {
    var routes = obj.http;

    if(routes && !Array.isArray(routes)) {
        routes = [routes];
    }

    // overidden
    if(routes) {
        // patch missing verbs / routes
        routes.forEach(function (r) {
            r.verb = String(r.verb || 'all').toLowerCase();
            r.path = r.path || ('/' + obj.name);
        });
    } else {
        if(obj.name === 'sharedCtor') {
            routes = [{
                verb: 'all',
                path: '/prototype'
            }];
        } else {
            // build default route
            routes = [{
                verb: 'all',
                path: obj.name ? ('/' + obj.name) : ''
            }];
        }
    }

    return routes;
}

function RestClass(sharedClass) {
    hiddenConstProperty(this, 'sharedClass', sharedClass);

    var self = this;
    this.name = sharedClass.name;
    this.routes = buildRoutes(sharedClass);

    this.ctor = sharedClass.sharedCtor && new RestMethod(this, sharedClass.sharedCtor);

    this.methods = sharedClass.methods()
        .filter(function(sm) {
            return !sm.isSharedCtor;
        })
        .map(function(sm) {
            return new RestMethod(self, sm);
        });
}

RestClass.prototype.getPath = function() {
    return this.routes[0].path;
};

function RestMethod(restClass, sharedMethod) {
    hiddenConstProperty(this, 'restClass', restClass);
    hiddenConstProperty(this, 'sharedMethod', sharedMethod);

    // The full name is ClassName.methodName or ClassName.prototype.methodName
    this.fullName = sharedMethod.stringName;
    this.name = this.fullName.split('.').slice(1).join('.');

    this.accepts = sharedMethod.accepts;
    this.returns = sharedMethod.returns;
    this.description = sharedMethod.description;

    var methodRoutes = buildRoutes(sharedMethod);
    if (sharedMethod.isStatic || !restClass.ctor) {
        this.routes = methodRoutes;
    } else {
        var routes = this.routes = [];
        methodRoutes.forEach(function(route) {
            restClass.ctor.routes.forEach(function(ctorRoute) {
                var fullRoute = util._extend({}, route);
                fullRoute.path = joinPaths(ctorRoute.path, route.path);
                routes.push(fullRoute);
            });
        });
    }
}

RestMethod.prototype.isReturningArray = function() {
    return this.returns.length == 1 &&
        this.returns[0].root &&
        getTypeString(this.returns[0].type) === 'array' || false;
};

RestMethod.prototype.acceptsSingleBodyArgument = function() {
    if (this.accepts.length != 1) return false;
    var accepts = this.accepts[0];

    return accepts.http &&
        accepts.http.source == 'body' &&
        getTypeString(accepts.type) == 'object' || false;
};

RestMethod.prototype.getHttpMethod = function() {
    var verb = this.routes[0].verb;
    if (verb == 'all') return 'POST';
    if (verb == 'del') return 'DELETE';
    return verb.toUpperCase();
};

RestMethod.prototype.getPath = function() {
    return this.routes[0].path;
};

RestMethod.prototype.getFullPath = function() {
    return joinPaths(this.restClass.getPath(), this.getPath());
};

function RestContext(req, res, handler) {
    this.req = req;
    this.res = res;
    this.handler = handler;
}

RestContext.prototype._buildRequest = function (method) {
    return sira.rekuest(method, this.req.query, this.req.params, this.req.body)
        .prop('body', this.req.body)
        .prop('query', this.req.query)
        .prop('path', this.req.params)
        .prop('accessToken', this.req.accessToken)
        .req;
};

RestContext.prototype.handle = function (method, cb) {
    var self = this;
    this.handler(this._buildRequest(method), function (err, ctx) { // sira context
        if (err) return cb(err);
        self.done(ctx.result);
        cb();
    });
};

RestContext.prototype.done = function (data) {
    // send the result back as
    // the requested content type
    var res = this.res;
    var accepts = this.req.accepts(SUPPORTED_TYPES);
    var dataExists = typeof data !== 'undefined';

    if(dataExists) {
        switch(accepts) {
            case 'json':
                res.json(data);
                break;
            case 'application/javascript':
            case 'text/javascript':
                res.jsonp(data);
                break;
            default:
                // not acceptable
                res.send(406);
                break;
        }
    } else {
        res.header('Content-Type', 'application/json');
        res.statusCode = 204;
        res.end();
    }
};

function hiddenConstProperty(where, property, value) {
    Object.defineProperty(where, property, {
        writable: false,
        enumerable: false,
        configurable: false,
        value: value
    });
}

function getTypeString(ctorOrName) {
    if (typeof ctorOrName === 'function')
        ctorOrName = ctorOrName.name;
    if (typeof ctorOrName === 'string') {
        return ctorOrName.toLowerCase();
    } else {
        debug('WARNING: unknown ctorOrName of type %s: %j',  typeof ctorOrName, ctorOrName);
        return typeof undefined;
    }
}

function joinPaths(left, right) {
    if (!left) return right;
    if (!right || right == '/') return left;

    var glue = left[left.length-1] + right[0];
    if (glue == '//')
        return left + right.slice(1);
    else if (glue[0] == '/' || glue[1] == '/')
        return left + right;
    else
        return left + '/' + right;
}

<|endoftext|>