<commit_before>/**
 *
 *  Matrix Group Branding Area jQuery Plugin
 *  Author: Roger Vandawalker <rvandawalker@matrixgroup.net>, @rjv
 *  Version: 1.1.1
 *
 *  Dependencies: jQuery 1.4+ (http://jquery.com)
 *  Supports: IE7+, Chrome, Safari, Firefox 3.6+
 *
 *  Copyright (c) 2012 Matrix Group International <http://matrixgroup.net>
 *  Released under the MIT license
 *  http://www.opensource.org/licenses/mit-license.php
 *
 */

;(function( $, window, document, undefined ) {
  var Branding = {

    _classes: {
      slide: 'slide',
      element: 'mtx-branding',
      container: 'slides-container',
      indicators: 'slide-indicators',
      background: 'slide-background',
      thumbnails: 'slide-thumbnails',
      thumbnail: 'slide-thumbnail'
    },

    _init: function( options, elem ) {
      var self = this;

      self.elem = elem;
      self.$elem = $(elem);

      self.options = $.extend( {}, $.fn.matrixBranding.options, options );

      self.$elem.addClass(self._classes.element);
      self.wrapSlides();

      if ( self.getSlideCount() > 1 ) { // only append slide navigation if there is more than one slide
        self.appendSlideNavigation();
      }

      if ( self.options.showSlideIndicators && self.getSlideCount() > 1 ) { // only append slide
        self.appendSlideIndicators();
      }

      if ( self.options.showSlideThumbnails && self.getSlideCount() > 1 ) {
        self.appendThumbnails();
      }

      self.selectInitialSlide();

      if ( self.options.autoPlay ) {
        self.showTimer = setTimeout(function() {
          self.playSlideshow();
        }, self.options.slideDuration);
      }
    },

    wrapSlides: function() {
      var self = this;

      self.$elem.children().addClass(self._classes.slide).wrapAll($('<div/>', { "class": self._classes.container }));
    },

    selectInitialSlide: function() {
      var self = this,
          slideNumber = self.options.initialSlide - 1;

      if ( self.options.startWithRandomSlide ) {
        slideNumber = Math.floor(Math.random() * self.getSlideCount());
      }

      self.showSlide(self.$elem.find("."+self._classes.slide).eq(slideNumber));
    },

    appendSlideNavigation: function() {
      var self = this,
          $apn = self.options.assignPreviousNavigation,
          $ann = self.options.assignNextNavigation;

      // assign or create the "previous slide" navigation button

      // if the previous button has been explicitly assigned with a jquery object,
      // add the "previous" click event to it
      if ( $apn instanceof jQuery ) {
        $apn.bind("click",function(e) {
          e.preventDefault();
          if (self.options.pauseOnClick) {
            self.pauseSlideshow();
          }
          self.showPreviousSlide();
        });
      } else {
        $("<a/>", {
          href: 'javascript:void(0);',
          html: self.options.previousButtonText,
          title: "Previous Slide",
          "class": self.options.previousButtonClass,
          click: function(e) {
            e.preventDefault();
            if (self.options.pauseOnClick) {
              self.pauseSlideshow();
            }
            self.showPreviousSlide();
          }
        }).appendTo(self.$elem);
      }

      // if the next button has been explicitly assigned with a jquery object,
      // add the "next" click event to it
      if ( $ann instanceof jQuery ) {
        $ann.bind("click",function(e) {
          e.preventDefault();
          if (self.options.pauseOnClick) {
            self.pauseSlideshow();
          }
          self.showNextSlide();
        });
      } else {
        $("<a/>", {
          href: 'javascript:void(0);',
          html: self.options.nextButtonText,
          title: "Next Slide",
          "class": self.options.nextButtonClass,
          click: function(e) {
            e.preventDefault();
            if (self.options.pauseOnClick) {
              self.pauseSlideshow();
            }
            self.showNextSlide();
          }
        }).appendTo(self.$elem);
      }
    },

    appendSlideIndicators: function() {
      var self = this,
          $indicators = $('<ul/>', { "class": self._classes.indicators }),
          $slides = self.$elem.find("."+self._classes.slide);

      $slides.each( function(i) {
        $('<a>',
          {
            text: (i+1),
            href: 'javascript:void(0);',
            click: function() {
              var $li = $(this).parent();

              if ( self.options.pauseOnClick ) {
                self.pauseSlideshow();
              }
              self.showSlide( $slides.eq($li.index()) );
            }
          }
        ).appendTo($indicators);
      });

      $indicators.children().wrap('<li/>');
      $indicators.appendTo(self.$elem);
    },

    appendThumbnails: function() {
      var self = this,
          $thumbnails = self.options.assignThumbnailsContainer != null
            ? self.options.assignThumbnailsContainer.addClass(self._classes.thumbnails)
            : $('<div/>', { "class": self._classes.thumbnails }),
          $slides = self.$elem.find("."+self._classes.slide);

      // recalculate the container width after all the images have loaded
      $(window).load(function(){
        $(window).trigger("resize");
      }).resize(function(){
        // if ($thumbnails.data('thumbs') !== undefined) { return; }
        $thumbnails.data( "thumbs", { "width": 0, "count": 0 } ); // set the default width to 0
        $thumbnails.find(".thumb").each(function(){

          $thumbnails.data( 'thumbs', {
            "width": $thumbnails.data("thumbs").width + $(this).outerWidth() + Number($(this).css("margin-left").replace("px","")),
            "count": $thumbnails.data("thumbs").count + 1
          });

        });

        var newWidth = Math.ceil($thumbnails.data('thumbs').width) + 1;
        // alert(newWidth);

        $thumbnails.children("div").css({
          // round up the width and add 1px in order to account for improper subpixel rendering in IE<9
          width: newWidth
        });
      });

      $slides.each( function(i) {

        // check to see if the slide has a pre-set thumbnail image
        // if not, use the slide background image

        $theThumbnail = $(this).find("."+self._classes.thumbnail).length === 1
          ? $(this).find("."+self._classes.thumbnail).eq(0)
          : $(this).find("img."+self._classes.background);

        var $newThumb = $("<span/>",
        {
          "class": "thumb",
          click: function() {
            if ( self.options.pauseOnClick ) {
              self.pauseSlideshow();
            }
            self.showSlide( $slides.eq($(this).index()) );
          }
        });

        $theThumbnail.clone().removeClass("slide-background").removeAttr("id").appendTo($newThumb);

        $newThumb.appendTo($thumbnails);

      });

      $thumbnails.children().wrapAll('<div/>');

      if ( self.options.assignThumbnailsContainer === null ){
        $thumbnails.insertAfter(self.$elem);
      }

      self.options.assignThumbnailsContainer = $thumbnails;
    },

    showNextSlide: function() {
      var self = this,
          $slides = self.$elem.find("."+self._classes.slide),
          $current = $slides.filter("."+self.options.selectedSlideClass);

      if ( ($current.index() + 1) % $slides.length === 0 ) {
        // the last slide has been reached; jump to first slide
        self.showSlide($slides.first());
      } else {
        self.showSlide($current.next("."+self._classes.slide));
      }
    },

    showPreviousSlide: function() {
      var self = this,
        $slides = self.$elem.find("."+self._classes.slide),
        $current = $slides.filter("."+self.options.selectedSlideClass);

      if ( $current.index() === 0 ) {
        // we're at the first slide; jump to last slide
        self.showSlide($slides.last());
      } else {
        self.showSlide($current.prev("."+self._classes.slide));
      }
    },

    showSlide: function( $slide ) {
      var self = this,
        index = $slide.index();

      $slide.addClass(self.options.selectedSlideClass).fadeIn(self.options.transitionDuration)
        .siblings().removeClass(self.options.selectedSlideClass).fadeOut(self.options.transitionDuration);

      if ( self.options.showSlideIndicators ) {
        self.showSlideIndicator($slide);
      }

      if ( self.options.showSlideThumbnails ) {
        self.showSlideThumbnail($slide);
      }
    },

    showSlideIndicator: function( $slide ) {
      var self = this,
        index = $slide.index();

      if ( self.options.showSlideIndicators ) {
        self.$elem.find("."+self._classes.indicators).children().eq(index).addClass(self.options.selectedSlideClass)
          .siblings().removeClass(self.options.selectedSlideClass);
      }
    },

    showSlideThumbnail: function ( $slide ) {
      var self = this,
        index = $slide.index(),
        $thumbContainer = self.options.assignThumbnailsContainer, // self.$elem.next("."+self._classes.thumbnails),
        $thumb = $thumbContainer.find(".thumb").eq(index);

      if ( self.options.showSlideThumbnails ) {
        $thumb.addClass(self.options.selectedSlideClass)
          .siblings().removeClass(self.options.selectedSlideClass);

        self.slideToThumbnail( $thumbContainer, $thumb );
      }
    },

    slideToThumbnail: function ( $thumbContainer, $thumb ) {
      var self = this,
        leftScrollTo = -1,
        topScrollTo = -1,
        thumbPos = $thumb.position(),
        thumbWidth = $thumb.outerWidth(),
        thumbHeight = $thumb.outerHeight(),
        containerWidth = $thumbContainer.outerWidth(),
        containerHeight = $thumbContainer.outerHeight();

      if ( ((thumbWidth + thumbPos.left) > (containerWidth + $thumbContainer.scrollLeft()))
           || ($thumbContainer.scrollLeft() > thumbPos.left) ){
        leftScrollTo = thumbPos.left;
      }

      if ( ((thumbHeight + thumbPos.top) > (containerHeight + $thumbContainer.scrollTop()))
           || ($thumbContainer.scrollTop() > thumbPos.top) ){
        topScrollTo = thumbPos.top;
      }

      if ( leftScrollTo > -1 || topScrollTo > -1 ){
        $thumbContainer.animate({
          scrollLeft: leftScrollTo < 0 ? 0 : leftScrollTo,
          scrollTop: topScrollTo < 0 ? 0 : topScrollTo
        }, self.options.transitionDuration);
      }
    },

    playSlideshow: function() {
      var self = this;

      self.showNextSlide();

      self.showTimer = setTimeout(function() {
        self.playSlideshow();
      }, self.options.slideDuration);
    },

    pauseSlideshow: function() {
      var self = this;
      clearTimeout(self.showTimer);
    },

    getSlideCount: function() {
      var self = this,
          $slides = self.$elem.find("."+self._classes.slide);

      return $slides.length;
    }

  };

  $.fn.matrixBranding = function( options ) {
    return this.each(function() {

      var branding = Object.create( Branding );
      branding._init( options, this );

    });
  };

  $.fn.matrixBranding.options = {
    nextButtonClass: 'next',        // class name applied to the "next" button
    previousButtonClass: 'prev',    // class name applied to the "previous" button
    nextButtonText: '→',       // text for the auto-generated "next" button
    previousButtonText: '←',   // text for the auto-generated "previous" button
    selectedSlideClass: 'current',  // class name applied to the visible slide
    transitionDuration: 800,        // number in ms for how long a slide transition should be
    slideDuration: 7000,            // number in ms for how long a slide should show
    autoPlay: true,                 // set to false to prevent an automatic slideshow
    pauseOnClick: true,             // set to false to prevent pausing the slideshow on clicking slide navigation
    showSlideIndicators: false,     // set to true to automatically add a slide navigation list
    showSlideThumbnails: false,
    assignThumbnailsContainer: null,
    initialSlide: 1,                // explictly set a slide to show first
    startWithRandomSlide: false,    // set to true for a random initial slide
    assignNextNavigation: null,       // a jquery object to be binded as slide navigation
    assignPreviousNavigation: null    // a jquery object to be binded as slide navigation
  };
})( jQuery, window, document );

// Polyfill for Object.create method
if ( typeof Object.create !== 'function' ) {
  Object.create = function( obj ) {
    function F() {};
    F.prototype = obj;
    return new F();
  };
}
<commit_msg>Fix bug that causes an error when there is only one thumbnail<commit_after>/**
 *
 *  Matrix Group Branding Area jQuery Plugin
 *  Author: Roger Vandawalker <rvandawalker@matrixgroup.net>, @rjv
 *  Version: 1.1.2
 *
 *  Dependencies: jQuery 1.4+ (http://jquery.com)
 *  Supports: IE7+, Chrome, Safari, Firefox 3.6+
 *
 *  Copyright (c) 2012 Matrix Group International <http://matrixgroup.net>
 *  Released under the MIT license
 *  http://www.opensource.org/licenses/mit-license.php
 *
 */

;(function( $, window, document, undefined ) {
  var Branding = {

    _classes: {
      slide: 'slide',
      element: 'mtx-branding',
      container: 'slides-container',
      indicators: 'slide-indicators',
      background: 'slide-background',
      thumbnails: 'slide-thumbnails',
      thumbnail: 'slide-thumbnail'
    },

    _init: function( options, elem ) {
      var self = this;

      self.elem = elem;
      self.$elem = $(elem);

      self.options = $.extend( {}, $.fn.matrixBranding.options, options );

      self.$elem.addClass(self._classes.element);
      self.wrapSlides();

      if ( self.getSlideCount() > 1 ) { // only append slide navigation if there is more than one slide
        self.appendSlideNavigation();
      }

      if ( self.options.showSlideIndicators && self.getSlideCount() > 1 ) { // only append slide
        self.appendSlideIndicators();
      }

      if ( self.options.showSlideThumbnails ) {
        self.appendThumbnails();
      }

      self.selectInitialSlide();

      if ( self.options.autoPlay ) {
        self.showTimer = setTimeout(function() {
          self.playSlideshow();
        }, self.options.slideDuration);
      }
    },

    wrapSlides: function() {
      var self = this;

      self.$elem.children().addClass(self._classes.slide).wrapAll($('<div/>', { "class": self._classes.container }));
    },

    selectInitialSlide: function() {
      var self = this,
          slideNumber = self.options.initialSlide - 1;

      if ( self.options.startWithRandomSlide ) {
        slideNumber = Math.floor(Math.random() * self.getSlideCount());
      }

      self.showSlide(self.$elem.find("."+self._classes.slide).eq(slideNumber));
    },

    appendSlideNavigation: function() {
      var self = this,
          $apn = self.options.assignPreviousNavigation,
          $ann = self.options.assignNextNavigation;

      // assign or create the "previous slide" navigation button

      // if the previous button has been explicitly assigned with a jquery object,
      // add the "previous" click event to it
      if ( $apn instanceof jQuery ) {
        $apn.bind("click",function(e) {
          e.preventDefault();
          if (self.options.pauseOnClick) {
            self.pauseSlideshow();
          }
          self.showPreviousSlide();
        });
      } else {
        $("<a/>", {
          href: 'javascript:void(0);',
          html: self.options.previousButtonText,
          title: "Previous Slide",
          "class": self.options.previousButtonClass,
          click: function(e) {
            e.preventDefault();
            if (self.options.pauseOnClick) {
              self.pauseSlideshow();
            }
            self.showPreviousSlide();
          }
        }).appendTo(self.$elem);
      }

      // if the next button has been explicitly assigned with a jquery object,
      // add the "next" click event to it
      if ( $ann instanceof jQuery ) {
        $ann.bind("click",function(e) {
          e.preventDefault();
          if (self.options.pauseOnClick) {
            self.pauseSlideshow();
          }
          self.showNextSlide();
        });
      } else {
        $("<a/>", {
          href: 'javascript:void(0);',
          html: self.options.nextButtonText,
          title: "Next Slide",
          "class": self.options.nextButtonClass,
          click: function(e) {
            e.preventDefault();
            if (self.options.pauseOnClick) {
              self.pauseSlideshow();
            }
            self.showNextSlide();
          }
        }).appendTo(self.$elem);
      }
    },

    appendSlideIndicators: function() {
      var self = this,
          $indicators = $('<ul/>', { "class": self._classes.indicators }),
          $slides = self.$elem.find("."+self._classes.slide);

      $slides.each( function(i) {
        $('<a>',
          {
            text: (i+1),
            href: 'javascript:void(0);',
            click: function() {
              var $li = $(this).parent();

              if ( self.options.pauseOnClick ) {
                self.pauseSlideshow();
              }
              self.showSlide( $slides.eq($li.index()) );
            }
          }
        ).appendTo($indicators);
      });

      $indicators.children().wrap('<li/>');
      $indicators.appendTo(self.$elem);
    },

    appendThumbnails: function() {
      var self = this,
          $thumbnails = self.options.assignThumbnailsContainer != null
            ? self.options.assignThumbnailsContainer.addClass(self._classes.thumbnails)
            : $('<div/>', { "class": self._classes.thumbnails }),
          $slides = self.$elem.find("."+self._classes.slide);

      // recalculate the container width after all the images have loaded
      $(window).load(function(){
        $(window).trigger("resize");
      }).resize(function(){
        // if ($thumbnails.data('thumbs') !== undefined) { return; }
        $thumbnails.data( "thumbs", { "width": 0, "count": 0 } ); // set the default width to 0
        $thumbnails.find(".thumb").each(function(){

          $thumbnails.data( 'thumbs', {
            "width": $thumbnails.data("thumbs").width + $(this).outerWidth() + Number($(this).css("margin-left").replace("px","")),
            "count": $thumbnails.data("thumbs").count + 1
          });

        });

        var newWidth = Math.ceil($thumbnails.data('thumbs').width) + 1;
        // alert(newWidth);

        $thumbnails.children("div").css({
          // round up the width and add 1px in order to account for improper subpixel rendering in IE<9
          width: newWidth
        });
      });

      $slides.each( function(i) {

        // check to see if the slide has a pre-set thumbnail image
        // if not, use the slide background image

        $theThumbnail = $(this).find("."+self._classes.thumbnail).length === 1
          ? $(this).find("."+self._classes.thumbnail).eq(0)
          : $(this).find("img."+self._classes.background);

        var $newThumb = $("<span/>",
        {
          "class": "thumb",
          click: function() {
            if ( self.options.pauseOnClick ) {
              self.pauseSlideshow();
            }
            self.showSlide( $slides.eq($(this).index()) );
          }
        });

        $theThumbnail.clone().removeClass("slide-background").removeAttr("id").appendTo($newThumb);

        $newThumb.appendTo($thumbnails);

      });

      $thumbnails.children().wrapAll('<div/>');

      if ( self.options.assignThumbnailsContainer === null ){
        $thumbnails.insertAfter(self.$elem);
      }

      self.options.assignThumbnailsContainer = $thumbnails;
    },

    showNextSlide: function() {
      var self = this,
          $slides = self.$elem.find("."+self._classes.slide),
          $current = $slides.filter("."+self.options.selectedSlideClass);

      if ( ($current.index() + 1) % $slides.length === 0 ) {
        // the last slide has been reached; jump to first slide
        self.showSlide($slides.first());
      } else {
        self.showSlide($current.next("."+self._classes.slide));
      }
    },

    showPreviousSlide: function() {
      var self = this,
        $slides = self.$elem.find("."+self._classes.slide),
        $current = $slides.filter("."+self.options.selectedSlideClass);

      if ( $current.index() === 0 ) {
        // we're at the first slide; jump to last slide
        self.showSlide($slides.last());
      } else {
        self.showSlide($current.prev("."+self._classes.slide));
      }
    },

    showSlide: function( $slide ) {
      var self = this,
        index = $slide.index();

      $slide.addClass(self.options.selectedSlideClass).fadeIn(self.options.transitionDuration)
        .siblings().removeClass(self.options.selectedSlideClass).fadeOut(self.options.transitionDuration);

      if ( self.options.showSlideIndicators ) {
        self.showSlideIndicator($slide);
      }

      if ( self.options.showSlideThumbnails ) {
        self.showSlideThumbnail($slide);
      }
    },

    showSlideIndicator: function( $slide ) {
      var self = this,
        index = $slide.index();

      if ( self.options.showSlideIndicators ) {
        self.$elem.find("."+self._classes.indicators).children().eq(index).addClass(self.options.selectedSlideClass)
          .siblings().removeClass(self.options.selectedSlideClass);
      }
    },

    showSlideThumbnail: function ( $slide ) {
      var self = this,
        index = $slide.index(),
        $thumbContainer = self.options.assignThumbnailsContainer, // self.$elem.next("."+self._classes.thumbnails),
        $thumb = $thumbContainer.find(".thumb").eq(index);

      if ( self.options.showSlideThumbnails ) {
        $thumb.addClass(self.options.selectedSlideClass)
          .siblings().removeClass(self.options.selectedSlideClass);

        self.slideToThumbnail( $thumbContainer, $thumb );
      }
    },

    slideToThumbnail: function ( $thumbContainer, $thumb ) {
      var self = this,
        leftScrollTo = -1,
        topScrollTo = -1,
        thumbPos = $thumb.position(),
        thumbWidth = $thumb.outerWidth(),
        thumbHeight = $thumb.outerHeight(),
        containerWidth = $thumbContainer.outerWidth(),
        containerHeight = $thumbContainer.outerHeight();

      if ( ((thumbWidth + thumbPos.left) > (containerWidth + $thumbContainer.scrollLeft()))
           || ($thumbContainer.scrollLeft() > thumbPos.left) ){
        leftScrollTo = thumbPos.left;
      }

      if ( ((thumbHeight + thumbPos.top) > (containerHeight + $thumbContainer.scrollTop()))
           || ($thumbContainer.scrollTop() > thumbPos.top) ){
        topScrollTo = thumbPos.top;
      }

      if ( leftScrollTo > -1 || topScrollTo > -1 ){
        $thumbContainer.animate({
          scrollLeft: leftScrollTo < 0 ? 0 : leftScrollTo,
          scrollTop: topScrollTo < 0 ? 0 : topScrollTo
        }, self.options.transitionDuration);
      }
    },

    playSlideshow: function() {
      var self = this;

      self.showNextSlide();

      self.showTimer = setTimeout(function() {
        self.playSlideshow();
      }, self.options.slideDuration);
    },

    pauseSlideshow: function() {
      var self = this;
      clearTimeout(self.showTimer);
    },

    getSlideCount: function() {
      var self = this,
          $slides = self.$elem.find("."+self._classes.slide);

      return $slides.length;
    }

  };

  $.fn.matrixBranding = function( options ) {
    return this.each(function() {

      var branding = Object.create( Branding );
      branding._init( options, this );

    });
  };

  $.fn.matrixBranding.options = {
    nextButtonClass: 'next',        // class name applied to the "next" button
    previousButtonClass: 'prev',    // class name applied to the "previous" button
    nextButtonText: '→',       // text for the auto-generated "next" button
    previousButtonText: '←',   // text for the auto-generated "previous" button
    selectedSlideClass: 'current',  // class name applied to the visible slide
    transitionDuration: 800,        // number in ms for how long a slide transition should be
    slideDuration: 7000,            // number in ms for how long a slide should show
    autoPlay: true,                 // set to false to prevent an automatic slideshow
    pauseOnClick: true,             // set to false to prevent pausing the slideshow on clicking slide navigation
    showSlideIndicators: false,     // set to true to automatically add a slide navigation list
    showSlideThumbnails: false,
    assignThumbnailsContainer: null,
    initialSlide: 1,                // explictly set a slide to show first
    startWithRandomSlide: false,    // set to true for a random initial slide
    assignNextNavigation: null,       // a jquery object to be binded as slide navigation
    assignPreviousNavigation: null    // a jquery object to be binded as slide navigation
  };
})( jQuery, window, document );

// Polyfill for Object.create method
if ( typeof Object.create !== 'function' ) {
  Object.create = function( obj ) {
    function F() {};
    F.prototype = obj;
    return new F();
  };
}
<|endoftext|>


<commit_before>'use strict';
var assert = require('core-assert');
var x = module.exports;

Object.defineProperty(x, 'AssertionError', {value: assert.AssertionError});

function create(val, expected, operator, msg, fn) {
	return {
		actual: val,
		expected: expected,
		message: msg,
		operator: operator,
		stackStartFunction: fn
	};
}

function test(ok, opts) {
	if (!ok) {
		throw new assert.AssertionError(opts);
	}
}

x.pass = function (msg) {
	test(true, create(true, true, 'pass', msg, x.pass));
};

x.fail = function (msg) {
	test(false, create(false, false, 'fail', msg, x.fail));
};

x.ok = x.assert = function (val, msg) {
	test(val, create(val, true, '==', msg, x.ok));
};

x.notOk = function (val, msg) {
	test(!val, create(val, false, '==', msg, x.notOk));
};

x.true = function (val, msg) {
	test(val === true, create(val, true, '===', msg, x.true));
};

x.false = function (val, msg) {
	test(val === false, create(val, false, '===', msg, x.false));
};

x.is = function (val, expected, msg) {
	test(val === expected, create(val, expected, '===', msg, x.is));
};

x.not = function (val, expected, msg) {
	test(val !== expected, create(val, expected, '!==', msg, x.not));
};

x.same = function (val, expected, msg) {
	try {
		assert.deepStrictEqual(val, expected, msg);
	} catch (err) {
		test(false, create(val, expected, '===', msg, x.same));
	}
};

x.notSame = function (val, expected, msg) {
	try {
		assert.notDeepStrictEqual(val, expected, msg);
	} catch (err) {
		test(false, create(val, expected, '!==', msg, x.notSame));
	}
};

x.throws = function (fn, err, msg) {
	if (fn && fn.then) {
		var isFailed = false;

		return fn
			.catch(function (err) {
				isFailed = true;

				return err;
			})
			.then(function (fnErr) {
				if (!isFailed) {
					x.throws(function () {}, err, msg);
				}

				x.throws(function () {
					throw fnErr;
				}, err, msg);
			});
	}

	try {
		if (typeof err === 'string') {
			var errMsg = err;
			err = function (err) {
				return err.message === errMsg;
			};
		}

		assert.throws(fn, err, msg);
	} catch (err) {
		test(false, create(err.actual, err.expected, err.operator, err.message, x.throws));
	}
};

x.doesNotThrow = function (fn, msg) {
	if (fn && fn.then) {
		return fn
			.catch(function (err) {
				x.doesNotThrow(function () {
					throw err;
				}, msg);
			});
	}

	try {
		assert.doesNotThrow(fn, msg);
	} catch (err) {
		test(false, create(err.actual, err.expected, err.operator, err.message, x.doesNotThrow));
	}
};

x.regexTest = function (regex, contents, msg) {
	test(regex.test(contents), create(regex, contents, '===', msg, x.regexTest));
};

x.ifError = x.error = function (err, msg) {
	test(!err, create(err, 'Error', '!==', msg, x.ifError));
};

require('./enhance-assert')(x);
<commit_msg>Close #124 PR: Refactor promises in throws method.<commit_after>'use strict';
var assert = require('core-assert');
var x = module.exports;

Object.defineProperty(x, 'AssertionError', {value: assert.AssertionError});

function create(val, expected, operator, msg, fn) {
	return {
		actual: val,
		expected: expected,
		message: msg,
		operator: operator,
		stackStartFunction: fn
	};
}

function test(ok, opts) {
	if (!ok) {
		throw new assert.AssertionError(opts);
	}
}

x.pass = function (msg) {
	test(true, create(true, true, 'pass', msg, x.pass));
};

x.fail = function (msg) {
	test(false, create(false, false, 'fail', msg, x.fail));
};

x.ok = x.assert = function (val, msg) {
	test(val, create(val, true, '==', msg, x.ok));
};

x.notOk = function (val, msg) {
	test(!val, create(val, false, '==', msg, x.notOk));
};

x.true = function (val, msg) {
	test(val === true, create(val, true, '===', msg, x.true));
};

x.false = function (val, msg) {
	test(val === false, create(val, false, '===', msg, x.false));
};

x.is = function (val, expected, msg) {
	test(val === expected, create(val, expected, '===', msg, x.is));
};

x.not = function (val, expected, msg) {
	test(val !== expected, create(val, expected, '!==', msg, x.not));
};

x.same = function (val, expected, msg) {
	try {
		assert.deepStrictEqual(val, expected, msg);
	} catch (err) {
		test(false, create(val, expected, '===', msg, x.same));
	}
};

x.notSame = function (val, expected, msg) {
	try {
		assert.notDeepStrictEqual(val, expected, msg);
	} catch (err) {
		test(false, create(val, expected, '!==', msg, x.notSame));
	}
};

x.throws = function (fn, err, msg) {
	if (fn && fn.then) {
		return fn
			.then(function () {
				x.throws(function () {}, err, msg);
			}, function (fnErr) {
				x.throws(function () {
					throw fnErr;
				}, err, msg);
			});
	}

	try {
		if (typeof err === 'string') {
			var errMsg = err;
			err = function (err) {
				return err.message === errMsg;
			};
		}

		assert.throws(fn, err, msg);
	} catch (err) {
		test(false, create(err.actual, err.expected, err.operator, err.message, x.throws));
	}
};

x.doesNotThrow = function (fn, msg) {
	if (fn && fn.then) {
		return fn
			.catch(function (err) {
				x.doesNotThrow(function () {
					throw err;
				}, msg);
			});
	}

	try {
		assert.doesNotThrow(fn, msg);
	} catch (err) {
		test(false, create(err.actual, err.expected, err.operator, err.message, x.doesNotThrow));
	}
};

x.regexTest = function (regex, contents, msg) {
	test(regex.test(contents), create(regex, contents, '===', msg, x.regexTest));
};

x.ifError = x.error = function (err, msg) {
	test(!err, create(err, 'Error', '!==', msg, x.ifError));
};

require('./enhance-assert')(x);
<|endoftext|>


<commit_before>var players = new Bloodhound({
    datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.name); },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    prefetch: '/api/public/player'
});

players.initialize();

function addNewPlayerRowToGameTable() {
    var table = $("#newGameTable");

    var numberOfRows = $(table).children(".enterPlayerRow").length+1;

    $(table).append('
' +
        '
'+numberOfRows+'
' +
        '

<input class="typeahead" type="text" placeholder="name" />

' +
        '
<button type="button" class="fa fa-level-down" onclick="addTiePlayer(this)"></button>
' +
        '
')
}

function setTypeAhead() {
    $('.typeahead').typeahead(null, {
        displayKey: 'name',
        source: players.ttAdapter(),
        templates: {
            suggestion: Handlebars.compile([
                '

{{name}} – {{email}}

'
            ].join(''))
        }
    });
}
function addTiePlayer(reference) {
    $(reference).parents('div').siblings('.newPlayerTextArea').first().append('
<input class="typeahead" type="text" placeholder="name" />
');
    setTypeAhead();
}

function publicRefreshScoreBoard() {
    $.ajax({
        type: "GET",
        url: "/api/public/score",
        processData: false,
        success: updateScoreBoard,
        dataType: 'JSON'
    });
}

function updateScoreBoard(values) {
    var table = document.getElementById("scoreTableData");
    table.innerHTML = '';

    for (var i = 0; i < values.length; i++) {
        var player = values[i];

        var row = table.insertRow(-1);
        row.insertCell(0).innerHTML = player['place'];
        row.insertCell(1).innerHTML = player['name'];
        row.insertCell(2).innerHTML = player['score'];
        row.insertCell(3).innerHTML = player['gamesPlayed'];
        row.insertCell(4).innerHTML = player['averageScore'].toFixed(3);
    }
}

function performPostAndClearTable() {
    var json = { };
    var nodeList = $('#newGameTable').children('.enterPlayerRow');

    var gameResults = new Array();
    var numberOfPlayers = 0;
    for (var i = 0; i < nodeList.length; ++i) {
        var textBoxes = nodeList[i].getElementsByTagName("input");
        var result = {}
        var nameResults = [];

        for (var j=0; j<textBoxes.length; j++) {
            if(textBoxes[j].value != "") {
                nameResults.push(textBoxes[j].value);
            }
        }

        if(nameResults.length != 0){
            result['name'] = nameResults;
            gameResults.push(result);
            numberOfPlayers++;
        }
    }

    json['results'] = gameResults;
    json['cd-dropdown'] = $('#cd-dropdown').val();
    console.log(json);
    setTypeAhead();

    if(numberOfPlayers > 7) {
        alert("This game is invalid, due to there being space for 2 games");
    }  else if(numberOfPlayers >= 4){
        $.ajax({
            type: "POST",
            url: "/api/game",
            processData: false,
            data: JSON.stringify(json),
            success: function () {
                alert("Booyah! Success!");
                publicRefreshScoreBoard();
                updateRecentGames();
                clearGameTable();
            },
            error: reportNewGameError,
            contentType: "application/json"
        });
    } else {
        alert("You need at least 4 players");
    }
}

function reportNewGameError(jqXHR, textStatus, errorThrown){
    alert(jQuery.parseJSON(jqXHR.responseText).error);
}

function clearGameTable() {

    $("#newGameTable").html('');

    for(var i = 0; i < 4; i++) {
        addNewPlayerRowToGameTable();
    }
}

function createNewPlayer() {
    var playerName = {};
    playerName['name'] = document.getElementById("newPlayer").value;
    playerName['emailAddress'] = document.getElementById("newPlayerEmail").value;
    console.log(JSON.stringify(playerName));
    $.ajax({
        type: "POST",
        url: "/api/player",
        processData: false,
        data: JSON.stringify(playerName),
        success: function() {
            alert("Player has been added");
            document.getElementById("newPlayer").value = "";
        },
        error: function(xhr) {
            alert("The player was not added because: " + jQuery.parseJSON(xhr.responseText).badValue)
        },
        contentType: "application/json"
    });
}

function updateRecentGames() {
    $.getJSON("/api/public/game", function(games) {
        var recentGamesHtml = '';
        $.each(games, function(i, game) {
            recentGamesHtml += '

';
            $.each(game.results, function (j, result){
                recentGamesHtml += '
' + (result.place + 1) + ":   " + result.playerName + ' ('+ formatScore(result.score) +')
';
            });
            recentGamesHtml += '
';
            recentGamesHtml += '
'+ moment(game.postingDate).calendar() +'
';
            recentGamesHtml += '
';
        });

        $('#recentGamesArea').html(recentGamesHtml);
    });

}

function formatScore(score) {
    if (score > 0) {
        return "+" + score;
    } else {
        return score.toString();
    }
}
<commit_msg>moving the player type ahead to a better location<commit_after>function addNewPlayerRowToGameTable() {
    var table = $("#newGameTable");

    var numberOfRows = $(table).children(".enterPlayerRow").length+1;

    $(table).append('
' +
        '
'+numberOfRows+'
' +
        '

<input class="typeahead" type="text" placeholder="name" />

' +
        '
<button type="button" class="fa fa-level-down" onclick="addTiePlayer(this)"></button>
' +
        '
')
}

function setTypeAhead() {
    var players = new Bloodhound({
        datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.name); },
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        prefetch: '/api/public/player'
    });

    players.initialize();

    $('.typeahead').typeahead(null, {
        displayKey: 'name',
        source: players.ttAdapter(),
        templates: {
            suggestion: Handlebars.compile([
                '

{{name}} – {{email}}

'
            ].join(''))
        }
    });
}
function addTiePlayer(reference) {
    $(reference).parents('div').siblings('.newPlayerTextArea').first().append('
<input class="typeahead" type="text" placeholder="name" />
');
    setTypeAhead();
}

function publicRefreshScoreBoard() {
    $.ajax({
        type: "GET",
        url: "/api/public/score",
        processData: false,
        success: updateScoreBoard,
        dataType: 'JSON'
    });
}

function updateScoreBoard(values) {
    var table = document.getElementById("scoreTableData");
    table.innerHTML = '';

    for (var i = 0; i < values.length; i++) {
        var player = values[i];

        var row = table.insertRow(-1);
        row.insertCell(0).innerHTML = player['place'];
        row.insertCell(1).innerHTML = player['name'];
        row.insertCell(2).innerHTML = player['score'];
        row.insertCell(3).innerHTML = player['gamesPlayed'];
        row.insertCell(4).innerHTML = player['averageScore'].toFixed(3);
    }
}

function performPostAndClearTable() {
    var json = { };
    var nodeList = $('#newGameTable').children('.enterPlayerRow');

    var gameResults = new Array();
    var numberOfPlayers = 0;
    for (var i = 0; i < nodeList.length; ++i) {
        var textBoxes = nodeList[i].getElementsByTagName("input");
        var result = {}
        var nameResults = [];

        for (var j=0; j<textBoxes.length; j++) {
            if(textBoxes[j].value != "") {
                nameResults.push(textBoxes[j].value);
            }
        }

        if(nameResults.length != 0){
            result['name'] = nameResults;
            gameResults.push(result);
            numberOfPlayers++;
        }
    }

    json['results'] = gameResults;
    json['cd-dropdown'] = $('#cd-dropdown').val();
    console.log(json);
    setTypeAhead();

    if(numberOfPlayers > 7) {
        alert("This game is invalid, due to there being space for 2 games");
    }  else if(numberOfPlayers >= 4){
        $.ajax({
            type: "POST",
            url: "/api/game",
            processData: false,
            data: JSON.stringify(json),
            success: function () {
                alert("Booyah! Success!");
                publicRefreshScoreBoard();
                updateRecentGames();
                clearGameTable();
            },
            error: reportNewGameError,
            contentType: "application/json"
        });
    } else {
        alert("You need at least 4 players");
    }
}

function reportNewGameError(jqXHR, textStatus, errorThrown){
    alert(jQuery.parseJSON(jqXHR.responseText).error);
}

function clearGameTable() {

    $("#newGameTable").html('');

    for(var i = 0; i < 4; i++) {
        addNewPlayerRowToGameTable();
    }
}

function createNewPlayer() {
    var playerName = {};
    playerName['name'] = document.getElementById("newPlayer").value;
    playerName['emailAddress'] = document.getElementById("newPlayerEmail").value;
    console.log(JSON.stringify(playerName));
    $.ajax({
        type: "POST",
        url: "/api/player",
        processData: false,
        data: JSON.stringify(playerName),
        success: function() {
            alert("Player has been added");
            document.getElementById("newPlayer").value = "";
        },
        error: function(xhr) {
            alert("The player was not added because: " + jQuery.parseJSON(xhr.responseText).badValue)
        },
        contentType: "application/json"
    });
}

function updateRecentGames() {
    $.getJSON("/api/public/game", function(games) {
        var recentGamesHtml = '';
        $.each(games, function(i, game) {
            recentGamesHtml += '

';
            $.each(game.results, function (j, result){
                recentGamesHtml += '
' + (result.place + 1) + ":   " + result.playerName + ' ('+ formatScore(result.score) +')
';
            });
            recentGamesHtml += '
';
            recentGamesHtml += '
'+ moment(game.postingDate).calendar() +'
';
            recentGamesHtml += '
';
        });

        $('#recentGamesArea').html(recentGamesHtml);
    });

}

function formatScore(score) {
    if (score > 0) {
        return "+" + score;
    } else {
        return score.toString();
    }
}
<|endoftext|>


<commit_before>var spawn = require('child_process').spawn;

var MongoURI = require('mongo-uri');
var Promise = require('bluebird');
var fs = require('fs');
var os = require('os');
var path = require('path');

/**
 * @param {Object} opts
 * @param {String} opts.collection
 * @param {String} [opts.uri]
 * @param {Array<String>} [opts.ports]
 * @param {Array<String>} [opts.hosts]
 * @param {String} [opts.username]
 * @param {String} [opts.password]
 * @param {String} [opts.database]
 * @returns {Array}
 */
function createDumpArgs(opts) {
  var args = [];
  var _hostInfo = opts.uri ? MongoURI.parse(opts.uri) : opts;
  // We assume we connect to the first instance
  var host = _hostInfo.ports[0] ? _hostInfo.hosts[0] + ':' + _hostInfo.ports[0] : _hostInfo.hosts[0];

  if (host) {
    args.push('-h', host);
  }
  if (_hostInfo.username) {
    args.push('-u', _hostInfo.username);
  }
  if (_hostInfo.password) {
    args.push('-p', _hostInfo.password);
  }
  args.push('-d', _hostInfo.database);
  args.push('-c', opts.collection);
  // Output (stdout)
  args.push('-o', '-');

  return args;
}

/**
 * @param opts
 * @param {string} opts.uri
 * @param {string} opts.collection
 * @param {Function} [_log]
 * @returns {bluebird}
 */
module.exports = function spawnMongodump(opts, _log) {
  var log = _log === undefined ? console.log : _log;

  return new Promise(function(resolve, reject) {
    var args = createDumpArgs(opts);
    var fileName = opts.collection + '.bson';
    var output = path.join(os.tmpDir(), fileName);
    var mongodump = spawn('mongodump', args);

    mongodump.stdout.pipe(fs.createWriteStream(output));
    if (typeof log === 'function') {
      mongodump.stderr.on('data', function(data) {
        log(data.toString('ascii'), opts.collection);
      });
    }
    mongodump.on('error', reject);
    return mongodump.stdout.on('end', function() {
      return resolve({
        name: fileName,
        path: output
      });
    });
  });
};
<commit_msg>Coding style<commit_after>var spawn = require('child_process').spawn;

var MongoURI = require('mongo-uri');
var Promise = require('bluebird');
var fs = require('fs');
var os = require('os');
var path = require('path');

/**
 * @param {Object} opts
 * @param {String} opts.collection
 * @param {String} [opts.uri]
 * @param {Array<String>} [opts.ports]
 * @param {Array<String>} [opts.hosts]
 * @param {String} [opts.username]
 * @param {String} [opts.password]
 * @param {String} [opts.database]
 * @returns {Array}
 */
function createDumpArgs(opts) {
  var args = [];
  var _hostInfo = opts.uri ? MongoURI.parse(opts.uri) : opts;
  // We assume we connect to the first instance
  var host = _hostInfo.ports[0] ? _hostInfo.hosts[0] + ':' + _hostInfo.ports[0] : _hostInfo.hosts[0];

  if (host) {
    args.push('-h', host);
  }
  if (_hostInfo.username) {
    args.push('-u', _hostInfo.username);
  }
  if (_hostInfo.password) {
    args.push('-p', _hostInfo.password);
  }
  args.push('-d', _hostInfo.database);
  args.push('-c', opts.collection);
  // Output (stdout)
  args.push('-o', '-');

  return args;
}

/**
 * @param opts
 * @param {string} opts.uri
 * @param {string} opts.collection
 * @param {Function} [_log]
 * @returns {bluebird}
 */
module.exports = function spawnMongodump(opts, _log) {
  var log = _log === undefined ? console.log : _log;

  return new Promise(function(resolve, reject) {
    var args = createDumpArgs(opts);
    var fileName = opts.collection + '.bson';
    var output = path.join(os.tmpDir(), fileName);
    var mongodump = spawn('mongodump', args);

    mongodump.stdout.pipe(fs.createWriteStream(output));
    if (typeof log === 'function') {
      mongodump.stderr.on('data', function(data) {
        log(data.toString('ascii'), opts.collection);
      });
    }
    mongodump.on('error', reject);

    return mongodump.stdout.on('end', function() {
      return resolve({
        name: fileName,
        path: output
      });
    });
  });
};
<|endoftext|>


<commit_before>var events = require('events');
var util = require('util');

var I2C = require('./i2c');

var INT_TEMP_MSB_REGISTER = 0x5e;
var INT_TEMP_LSB_REGISTER = 0x5f;
var BAT_VOLT_MSB_REGISTER = 0x78;
var BAT_VOLT_LSB_REGISTER = 0x79;
var BAT_ADC_REGISTER      = 0x82;
var GPIO2_REGISTER        = 0x93;

function AXP209(bus, address) {
  this._i2c = new I2C(bus, address);

  this._reads = {};
}

util.inherits(AXP209, events.EventEmitter);

AXP209.prototype.open = function(callback) {
  this._i2c.open(callback);
};

AXP209.prototype.pinMode = function(pin, mode) {
  if (pin === 'BAT') {
    this._configureBatAdc();
  }
};

AXP209.prototype.analogRead = function(pin) {
  this._reads[pin] = true;
};

AXP209.prototype.digitalWrite = function(pin, value) {
  if (pin === 'STATUS') {
    this._writeGpio2(value);
  }
};

AXP209.prototype.tick = function() {
  if (this._reads.BAT) {
    this._readBatVolt(function(err, value) {
      if (!err) {
        this.emit('analog-read', 'BAT', value);
      }
    }.bind(this));
  }

  if (this._reads.INTTEMP) {
    this._readIntTemp(function(err, value) {
      if (!err) {
        this.emit('analog-read', 'INTTEMP', value);
      }
    }.bind(this));
  }
};

AXP209.prototype.close = function(callback) {
  this._i2c.close(callback);
};

AXP209.prototype._readIntTemp = function(callback) {
  this._readAdc(INT_TEMP_MSB_REGISTER, INT_TEMP_LSB_REGISTER, callback);
};

AXP209.prototype._readBatVolt = function(callback) {
  this._readAdc(BAT_VOLT_MSB_REGISTER, BAT_VOLT_LSB_REGISTER, callback);
};

AXP209.prototype._configureBatAdc = function(callback) {
  // force ADC enable for battery voltage and current
  this._i2c.writeRegister(BAT_ADC_REGISTER, new Buffer([0xc3]), callback);
};

AXP209.prototype._writeGpio2 = function(value, callback) {
  this._i2c.writeRegister(GPIO2_REGISTER, new Buffer([value]), callback);
};

AXP209.prototype._readAdc = function(msbRegister, lsbRegister, callback) {
  this._i2c.readRegister(msbRegister, 1, function(err, msbData) {
    if (err) {
      return callback(err);
    }

    this._i2c.readRegister(lsbRegister, 1, function(err, lsbData) {
      if (err) {
        return callback(err);
      }

      var value = (msbData[0] << 4) | (lsbData[0] & 0x0f);

      callback(null, value);
    }.bind(this));
  }.bind(this));
};

module.exports = AXP209;
<commit_msg>AXP209: check if a read is in progress before attempting to read<commit_after>var events = require('events');
var util = require('util');

var I2C = require('./i2c');

var INT_TEMP_MSB_REGISTER = 0x5e;
var INT_TEMP_LSB_REGISTER = 0x5f;
var BAT_VOLT_MSB_REGISTER = 0x78;
var BAT_VOLT_LSB_REGISTER = 0x79;
var BAT_ADC_REGISTER      = 0x82;
var GPIO2_REGISTER        = 0x93;

function AXP209(bus, address) {
  this._i2c = new I2C(bus, address);

  this._reads = {};
  this._readInProgress = {};
}

util.inherits(AXP209, events.EventEmitter);

AXP209.prototype.open = function(callback) {
  this._i2c.open(callback);
};

AXP209.prototype.pinMode = function(pin, mode) {
  if (pin === 'BAT') {
    this._configureBatAdc();
  }
};

AXP209.prototype.analogRead = function(pin) {
  this._reads[pin] = true;
};

AXP209.prototype.digitalWrite = function(pin, value) {
  if (pin === 'STATUS') {
    this._writeGpio2(value);
  }
};

AXP209.prototype.tick = function() {
  if (this._reads.BAT && !this._readInProgress.BAT) {
    this._readInProgress.BAT = true;

    this._readBatVolt(function(err, value) {
      if (!err) {
        this.emit('analog-read', 'BAT', value);
      }

      this._readInProgress.BAT = false;
    }.bind(this));
  }

  if (this._reads.INTTEMP && !this._readInProgress.INTTEMP) {
    this._readInProgress.INTTEMP = true;

    this._readIntTemp(function(err, value) {
      if (!err) {
        this.emit('analog-read', 'INTTEMP', value);
      }

      this._readInProgress.INTTEMP = false;
    }.bind(this));
  }
};

AXP209.prototype.close = function(callback) {
  this._i2c.close(callback);
};

AXP209.prototype._readIntTemp = function(callback) {
  this._readAdc(INT_TEMP_MSB_REGISTER, INT_TEMP_LSB_REGISTER, callback);
};

AXP209.prototype._readBatVolt = function(callback) {
  this._readAdc(BAT_VOLT_MSB_REGISTER, BAT_VOLT_LSB_REGISTER, callback);
};

AXP209.prototype._configureBatAdc = function(callback) {
  // force ADC enable for battery voltage and current
  this._i2c.writeRegister(BAT_ADC_REGISTER, new Buffer([0xc3]), callback);
};

AXP209.prototype._writeGpio2 = function(value, callback) {
  this._i2c.writeRegister(GPIO2_REGISTER, new Buffer([value]), callback);
};

AXP209.prototype._readAdc = function(msbRegister, lsbRegister, callback) {
  this._i2c.readRegister(msbRegister, 1, function(err, msbData) {
    if (err) {
      return callback(err);
    }

    this._i2c.readRegister(lsbRegister, 1, function(err, lsbData) {
      if (err) {
        return callback(err);
      }

      var value = (msbData[0] << 4) | (lsbData[0] & 0x0f);

      callback(null, value);
    }.bind(this));
  }.bind(this));
};

module.exports = AXP209;
<|endoftext|>


<commit_before>
var express = require('express');
var cors = require('cors');

var environment = process.env.NODE_ENV || 'production';

var app = express();

app.use(express.static(__dirname + '/'));

app.listen(9000, function () {
  console.log('Glimpse listening on port 9000!');
});

if (environment == "test") {
    var test_atoms = express();

    test_atoms.use(cors());

    test_atoms.use('/api/v1.1/atoms', function(req, res) {
       res.sendFile( __dirname + '/test_jsons/atoms.json');
    });

    test_atoms.use('/api/v1.1/types', function(req, res) {
       res.sendFile( __dirname + '/test_jsons/types.json');
    });

    test_atoms.use('/api/v1.1/scheme', function(req, res) {
       res.send('{\"arousal\": '+Math.random()+', \"sadness\": '+Math.random()+'}');
    });

    test_atoms.listen(5000, function() {
      console.log('Debug Atoms are listening on port 5000!');
    });
}
<commit_msg>added new experimental opspsi debug values<commit_after>
var express = require('express');
var cors = require('cors');

var environment = process.env.NODE_ENV || 'production';

var app = express();

app.use(express.static(__dirname + '/'));

app.listen(9000, function () {
  console.log('Glimpse listening on port 9000!');
});

if (environment == "test") {
    var test_atoms = express();

    test_atoms.use(cors());

    test_atoms.use('/api/v1.1/atoms', function(req, res) {
       res.sendFile( __dirname + '/test_jsons/atoms.json');
    });

    test_atoms.use('/api/v1.1/types', function(req, res) {
       res.sendFile( __dirname + '/test_jsons/types.json');
    });

    test_atoms.use('/api/v1.1/scheme', function(req, res) {
       var foo = {
        'negative-valence': (0.1+(Math.random()*0.15)),
        'positive-valence': (0.2+(Math.random()*0.4)),
        'arousal': (0.3+(Math.random()*0.19)),
        'power': (0.35+(Math.random()*0.24)),
        'voice width': (0.8+(Math.random()*0.21))
       }
       res.send({ 'response' : JSON.stringify(foo)});
    });

    test_atoms.listen(5000, function() {
      console.log('Debug Atoms are listening on port 5000!');
    });
}
<|endoftext|>


<commit_before>/**
 * nanoAudioPlayer plugin for jQuery
 * by Lasse Nielsen
 * @version 0.1
 * 03.02.2013
 * http://github.com/nano-entertainment/NanoAudioPlayer
 */
(function($){
  $.fn.nanoAudioPlayer = function( options ){
    var defaults = {
      autoplay: false,
      loop: false,
      element: new Audio()
    };

    var opts = $.extend(defaults, options);

    // EventListener

    // autoplay
    opts.element.addEventListener('canplay', function() {
      if( opts.autoplay ) opts.element.play();
    }, false);

    var suffix;

    if(opts.element.canPlayType("audio/ogg"))
      {
        suffix = "ogg";
      } else {
        suffix = "mp3";
      }
    opts.element.src = opts.file + "." + suffix;

    //loop
    if( typeof opts.element.loop == 'boolean') {
      opts.element.loop = opts.loop;
    } else {
      opts.element.addEventListener('ended', function() {
        if( opts.loop ) {
          opts.element.duration = opts.element.startTime;
          opts.element.play();
        }
      }, false)
    }

    // Html-Event Listener

    //play
    $(this).find('.play').bind('click', function() {
      opts.audioElement.play();
    });

    //pause
    $(this).find('.pause').bind('click', function() {
      opts.audioElement.pause();
    });

    // playToggle
    $(this).find('.play-toggle').bind('click', function() {
      if(opts.audioElement.paused) {
    	opts.audioElement.play();
      } else {
        opts.audioElement.pause();
      }

    });

  }
})(jQuery);<commit_msg>add volume listener<commit_after>/**
 * nanoAudioPlayer plugin for jQuery
 * by Lasse Nielsen
 * @version 0.1
 * 03.02.2013
 * http://github.com/nano-entertainment/NanoAudioPlayer
 */
(function($){
  $.fn.nanoAudioPlayer = function( options ){
    var defaults = {
      autoplay: false,
      loop: false,
      progressBar: true,
      element: new Audio(),
      cssPrefix: 'audio-player-'
    };

    var opts = $.extend(defaults, options);
    var player = this;

    /**
     * EventListener
     */

    // autoplay
    opts.element.addEventListener('canplay', function() {
      if( opts.autoplay ) opts.element.play();
    }, false);

    //loop
    if( typeof opts.element.loop == 'boolean') {
      opts.element.loop = opts.loop;
    } else {
      opts.element.addEventListener('ended', function() {
        if( opts.loop ) {
          opts.element.currentTime = opts.element.startTime;
          opts.element.play();
        }
      }, false)
    }

    //current time update
    opts.element.addEventListener('timeupdate', function() {

      $(player).find('.'+ opts.cssPrefix +'progressBar').attr('value', opts.element.currentTime);

    }, false);

    //max time update
    opts.element.addEventListener('durationchange', function() {
      $(player).find('.'+ opts.cssPrefix +'progressBar').attr('max', opts.element.duration);
    }, false);

    var suffix;

    //add audio
    if(opts.element.canPlayType("audio/ogg"))
    {
      suffix = "ogg";
    } else {
      suffix = "mp3";
    }

    opts.element.src = opts.file + "." + suffix;

    // Html-Event Listener

    //play
    $(this).find('.'+ opts.cssPrefix +'play').bind('click', function(e) {
      e.preventDefault();
      opts.element.play();

    });

    //pause
    $(this).find('.'+ opts.cssPrefix +'pause').bind('click', function(e) {
      e.preventDefault();
      opts.element.pause();
    });

    // playToggle
    $(this).find('.'+ opts.cssPrefix +'play-toggle').bind('click', function(e) {
      e.preventDefault();
      if(opts.element.paused) {
    	opts.element.play();
      } else {
        opts.element.pause();
      }

    });

    // volumeUp
    $(player).find('.'+ opts.cssPrefix +'control-volume-up').bind('click', function(e) {
      e.preventDefault();
      if(opts.element.volume < 1.0) opts.element.volume = opts.element.volume + 0.1;
    });

    $(player).find('.'+ opts.cssPrefix +'control-volume-down').bind('click', function(e) {
      e.preventDefault();
      if(opts.element.volume > 0.0) opts.element.volume = opts.element.volume - 0.1;
    });

    return this;

  }
})(jQuery);<|endoftext|>


<commit_before>import * from './vendor/algoliasearch';
import * from './vendor/flexdatalist';
import * from './vendor/MathJax';
import * from './vendor/izimodal';
import * from './vendor/stripe';
import * from './vendor/timeago';

import * from './components/alert';
import * from './components/copy';

import * from './packages/calculations/calculations';
import * from './packages/welcome/welcome';

import * from './cable';
<commit_msg>cleanup<commit_after><|endoftext|>


<commit_before>module.exports = function (basePath) {
    'use strict';

    //noinspection JSUnresolvedVariable
    var express = require('express'),
        https = require('https'),
        path = require('path'),
        fs = require('fs'),
        logging = require('./logging'),
        config = require('./config')(path, fs, basePath, logging),
        syslog = logging.syslog,
        audit = logging.audit,
        redis = require('redis'),
        redisClient = redis.createClient(6379, 'localhost'),
        RedisSessionStore = require('connect-redis')(express),
        consolidate = require('consolidate'),
        handlebars = require('handlebars'),
        middleware = {},
        app = express(),
        serverOptions = {
            key: fs.readFileSync('ssl/ssl.key'),
            cert: fs.readFileSync('ssl/ssl.crt')
        },
        server = https.createServer(serverOptions, app),
        io = require('socket.io').listen(server),
        RedisSocketStore = require('socket.io/lib/stores/redis'),
        pub = redis.createClient(6379, 'localhost'),
        sub = redis.createClient(6379, 'localhost');

    // check redis client
    redisClient.on('error', function (err) {
        var msg = 'error event - ' + redisClient.host + ':' + redisClient.port + ' - ' + err;
        syslog.error(msg);
        throw new Error(msg);
    });

    // middleware
    middleware = require('./middleware')(config);

    // server

    // start server
    var startServer = function () {
        //noinspection JSCheckFunctionSignatures
        server.listen(app.get('port'), function () {
            if (config.mode !== 'production') {
                syslog.warn('application server has been started in ' + config.mode + ' mode');
            }
            else {
                syslog.info('application server has been started in ' + config.mode + ' mode');
            }

            syslog.info('application server listening on port ' + app.get('port'));
        });
    };

    // view engine for application
    app.engine('html', consolidate.handlebars);

    // partial vars
    var stylesHtml, scriptsHtml, navigationHtml, sessionControlHtml;

    // register styles
    stylesHtml = path.join(config.partialPath, 'styles.html');
    //noinspection JSUnresolvedFunction
    handlebars.registerPartial('styles', fs.readFileSync(stylesHtml, 'utf8'));

    // register scripts
    scriptsHtml = path.join(config.partialPath, 'scripts.html');
    var tmpSocket = 'https://' + config.host + ':' + config.port;
    //noinspection JSUnresolvedFunction
    handlebars.registerPartial('scripts', fs.readFileSync(scriptsHtml, 'utf8')
        .replace('<!--baboon-socketConnection-->', 'var socket = io.connect(\'' + tmpSocket + '\');'));

    // register navigation
    navigationHtml = path.join(config.partialPath, 'navigation.html');
    //noinspection JSUnresolvedFunction
    handlebars.registerPartial('navigation', fs.readFileSync(navigationHtml, 'utf8'));

    // register sessionControl
    sessionControlHtml = path.join(config.partialPath, 'sessionControl.html');
    //noinspection JSUnresolvedFunction
    handlebars.registerPartial('sessionControl', fs.readFileSync(sessionControlHtml, 'utf8'));

    // express

    // express default config
    var expressDefaultConfig = function () {

        //noinspection JSUnresolvedVariable
        app.set('port', config.port);
        //noinspection JSUnresolvedVariable
        app.set('views', config.basePath + '/views');
        app.set('view engine', 'html');
        //noinspection JSUnresolvedFunction
        app.use(express.favicon());
        //noinspection JSUnresolvedVariable
        if (config.mode === 'production') {
            //noinspection JSUnresolvedVariable
            app.use(express.logger({format: config.logging.express}));
        }
        else {
            //noinspection JSUnresolvedVariable
            app.use(express.logger({format: config.logging.express}));
        }
        //noinspection JSUnresolvedFunction
        app.use(express.bodyParser());
        //noinspection JSUnresolvedFunction
        app.use(express.methodOverride());

        // Static content before session middleware,
        // prevents the session checking for static files in public.

        //noinspection JSUnresolvedFunction,JSUnresolvedVariable
        app.use(express.static(config.publicPath));
        //noinspection JSUnresolvedFunction,JSUnresolvedVariable
        app.use(express.cookieParser());

        // Session has session cookie with expires:false.
        // Session is only destroyed when the user closes the browser.
        // Redis ttl is maximal lifetime of session, after this time session is destroyed
        // Middleware checks the inactive period of the session by user.
        // When this period is over, the session destroyed.

        //noinspection JSUnresolvedFunction,JSUnresolvedVariable
        app.use(express.session({

            key: config.sessionKey,
            store: new RedisSessionStore({
                client: redisClient,
                ttl: config.sessionMaxLife
            }),
            secret: config.sessionSecret,
            cookie: {expires: false}
        }));
        // Check session activity. Is session activity time over, session destroy and redirect /login.
        app.use(middleware.auth.sessionActivity);
        // Check if exists session. If not exists, setting guest.
        app.use(middleware.auth.sessionExists);
        // site context vars middleware
        app.use(middleware.auth.siteContext);
        // routing
        app.use(app.router);
        // middleware catch 404 error and send 404 error page
        app.use(function (req, res) {
            res.status(404);
            res.render('404');
        });
        // error handling middleware
        app.use(middleware.errorHandler);
    };

    //noinspection JSValidateTypes
    app.configure(expressDefaultConfig);

    // socket.io
    io.set('store', new RedisSocketStore({
        redisPub : pub,
        redisSub : sub,
        redisClient : redisClient
    }));

    return {
        express: {
            app: app
        },
        middleware: {
            auth: {
                restricted: middleware.auth.restricted,
                login: middleware.auth.login,
                logout: middleware.auth.logout
            }
        },
        server: {
            start: startServer,
            io: io,
            config: config,
            audit: audit,
            syslog: syslog
        }
    };
};<commit_msg>update<commit_after>module.exports = function (basePath) {
    'use strict';

    //noinspection JSUnresolvedVariable
    var express = require('express'),
        https = require('https'),
        path = require('path'),
        fs = require('fs'),
        logging = require('./logging'),
        config = require('./config')(path, fs, basePath, logging),
        syslog = logging.syslog,
        audit = logging.audit,
        redis = require('redis'),
        redisClient = redis.createClient(6379, 'localhost'),
        RedisSessionStore = require('connect-redis')(express),
        consolidate = require('consolidate'),
        handlebars = require('handlebars'),
        middleware = {},
        app = express(),
        serverOptions = {
            key: fs.readFileSync('ssl/ssl.key'),
            cert: fs.readFileSync('ssl/ssl.crt')
        },
        server = https.createServer(serverOptions, app),
        io = require('socket.io').listen(server),
        RedisSocketStore = require('socket.io/lib/stores/redis'),
        pub = redis.createClient(6379, 'localhost'),
        sub = redis.createClient(6379, 'localhost');

    // check redis client
    redisClient.on('error', function (err) {
        var msg = 'error event - ' + redisClient.host + ':' + redisClient.port + ' - ' + err;
        syslog.error(msg);
        throw new Error(msg);
    });

    // middleware
    middleware = require('./middleware')(config);

    // server

    // start server
    var startServer = function () {
        //noinspection JSCheckFunctionSignatures
        server.listen(app.get('port'), function () {
            if (config.mode !== 'production') {
                syslog.warn('application server has been started in ' + config.mode + ' mode');
            }
            else {
                syslog.info('application server has been started in ' + config.mode + ' mode');
            }

            syslog.info('application server listening on port ' + app.get('port'));
        });
    };

    // view engine for application
    app.engine('html', consolidate.handlebars);

    // partial vars
    var stylesHtml, scriptsHtml, navigationHtml, sessionControlHtml;

    // register styles
    stylesHtml = path.join(config.partialPath, 'styles.html');
    //noinspection JSUnresolvedFunction
    handlebars.registerPartial('styles', fs.readFileSync(stylesHtml, 'utf8'));

    // register scripts
    scriptsHtml = path.join(config.partialPath, 'scripts.html');
    var tmpSocket = 'https://' + config.host + ':' + config.port;
    //noinspection JSUnresolvedFunction
    handlebars.registerPartial('scripts', fs.readFileSync(scriptsHtml, 'utf8')
        .replace('<!--baboon-socketConnection-->', 'var socket = io.connect(\'' + tmpSocket + '\');'));

    // register navigation
    navigationHtml = path.join(config.partialPath, 'navigation.html');
    //noinspection JSUnresolvedFunction
    handlebars.registerPartial('navigation', fs.readFileSync(navigationHtml, 'utf8'));

    // register sessionControl
    sessionControlHtml = path.join(config.partialPath, 'sessionControl.html');
    //noinspection JSUnresolvedFunction
    handlebars.registerPartial('sessionControl', fs.readFileSync(sessionControlHtml, 'utf8'));

    // express

    // express default config
    var expressDefaultConfig = function () {

        //noinspection JSUnresolvedVariable
        app.set('port', config.port);
        //noinspection JSUnresolvedVariable
        app.set('views', config.basePath + '/views');
        app.set('view engine', 'html');
        //noinspection JSUnresolvedFunction
        app.use(express.favicon());
        //noinspection JSUnresolvedVariable
        if (config.mode === 'production') {
            //noinspection JSUnresolvedVariable
            app.use(express.logger({format: config.logging.express}));
        }
        else {
            //noinspection JSUnresolvedVariable
            app.use(express.logger({format: config.logging.express}));
        }
        //noinspection JSUnresolvedFunction
        app.use(express.bodyParser());
        //noinspection JSUnresolvedFunction
        app.use(express.methodOverride());

        // Static content before session middleware,
        // prevents the session checking for static files in public.

        //noinspection JSUnresolvedFunction,JSUnresolvedVariable
        app.use(express.static(config.publicPath));
        //noinspection JSUnresolvedFunction,JSUnresolvedVariable
        app.use(express.cookieParser());

        // Session has session cookie with expires:false.
        // Session is only destroyed when the user closes the browser.
        // Redis ttl is maximal lifetime of session, after this time session is destroyed
        // Middleware checks the inactive period of the session by user.
        // When this period is over, the session destroyed.

        //noinspection JSUnresolvedFunction,JSUnresolvedVariable
        app.use(express.session({

            key: config.sessionKey,
            store: new RedisSessionStore({
                client: redisClient,
                ttl: config.sessionMaxLife
            }),
            secret: config.sessionSecret,
            cookie: {expires: false}
        }));
        // Check session activity. Is session activity time over, session destroy and redirect /login.
        app.use(middleware.auth.sessionActivity);
        // Check if exists session. If not exists, setting guest.
        app.use(middleware.auth.sessionExists);
        // site context vars middleware
        app.use(middleware.auth.siteContext);
        // routing
        app.use(app.router);
        // middleware catch 404 error and send 404 error page
        app.use(function (req, res) {
            res.status(404);
            res.render('404');
        });
        // error handling middleware
        app.use(middleware.errorHandler);
    };

    //noinspection JSValidateTypes
    app.configure(expressDefaultConfig);

    // socket.io
    io.set('store', new RedisSocketStore({
        redisPub : pub,
        redisSub : sub,
        redisClient : redisClient
    }));

    // baboon api

    return {
        express: {
            app: app
        },
        middleware: {
            auth: {
                restricted: middleware.auth.restricted,
                login: middleware.auth.login,
                logout: middleware.auth.logout
            }
        },
        server: {
            start: startServer,
            io: io,
            config: config,
            audit: audit,
            syslog: syslog
        }
    };
};<|endoftext|>


<commit_before>'use babel';

import * as ramda from 'ramda';
import BananaView from './banana-view';
import { CompositeDisposable } from 'atom';
import * as esprima from 'esprima';
import * as parser from './parser';

// scrollbar indicator
// ref: https://github.com/Aakash1312/scroll-searcher/blob/master/lib/scroll-marker.coffee

function flatten(listOfLists) {
    return listOfLists.reduce((results, i) => results.concat(i), []);
}

function indexs(line, word) {
    function ps(line, word, startIndex) {
        let idx = line.indexOf(word, startIndex);
        return idx === -1 ? [] : [idx].concat(ps(line, word, idx + word.length));
    }
    return ps(line, word, 0);
}

function ranges(txt, word, identifiers) {
    if (identifiers) {
        return identifiers.filter(i => i.name === word).map(i => [
            [i.loc.start.line-1, i.loc.start.column],
            [i.loc.end.line-1, i.loc.end.column],
        ]);
    } else {
        let lines = txt.split('\n');
        let points = flatten(ramda.zip(
            ramda.range(0, lines.length),
            lines.map(line => indexs(line, word)))
            .map(i => i[1].map(col => [i[0], col])));
        return points.map(p => [p, [p[0], p[1] + word.length]]);
    }
}

function indicatorBar(editor) {
    let bar = atom.views.getView(editor).component.domNodeValue.querySelector('.indicator-bar');
    if (! bar) {
        bar = document.createElement('div');
        bar.classList.add('indicator-bar');
        atom.views.getView(editor).component.domNodeValue.appendChild(bar);
    }
    return bar;
}

function clearIndicators(editor) {
    indicatorBar(editor).innerHTML = '';
}

function showIndicator(editor, screenPosition) {
    // 只處理單行 range (因為 identifier 只會有一行)
    // todo: 用 atom.views.getView(editor).component.domNodeValue.querySelector('.vertical-scrollbar')
    let row = screenPosition.row;
    let rowCount = editor.getScreenLineCount();
    let scrollHeight = atom.views.getView(editor).getScrollHeight();
    let displayHeight = editor.displayBuffer.height;

    let indicator = document.createElement('div');
    indicator.classList.add('indicator');
    indicator.style.top = Math.round((row / rowCount) * displayHeight) + 'px';
    indicatorBar(editor).appendChild(indicator);
}

export default {

  bananaView: null,
  modalPanel: null,
  subscriptions: null,

  enabled: true,
  lastWord: null,
  identifiersInEditor: {},
  markerLayerInEditor: {},

  activate(state) {
    this.bananaView = new BananaView(state.bananaViewState);
    this.modalPanel = atom.workspace.addModalPanel({
      item: this.bananaView.getElement(),
      visible: false
    });

    // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable
    this.subscriptions = new CompositeDisposable();

    // Register command that toggles this view
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'banana:toggle': () => this.toggle()
    }));

    atom.workspace.observeTextEditors(editor => {
        if (! this.markerLayerInEditor[editor.id]) {
            this.markerLayerInEditor[editor.id] = editor.addMarkerLayer();
        }

        editor.onDidDestroy(event => {
            delete this.identifiersInEditor[editor.id];
            delete this.markerLayerInEditor[editor.id];
        });

        editor.onDidStopChanging(event => {
            if (!this.enabled || editor.getGrammar().name !== 'JavaScript') {
                return;
            }
            delete this.identifiersInEditor[editor.id];
            let jst = new parser.Jst();
            let ok = jst.parse(editor.getText(), {sourceType: 'module'});
            if (ok) {
                this.identifiersInEditor[editor.id] = parser.identifiers(jst);
            }
        });

        editor.onDidChangeCursorPosition(event => {
            if (!this.enabled || editor.getSelectedText()) {
                return;
            }
            let markerLayer = this.markerLayerInEditor[editor.id];
            let word = editor.getWordUnderCursor();
            if (word.match(/^\w+$/)) {
                if (word !== this.lastWord) {
                    this.lastWord = word;
                    markerLayer.clear();
                    clearIndicators(editor);
                    ranges(editor.getText(), word, this.identifiersInEditor[editor.id])
                    .forEach(range => {
                        markerLayer.markBufferRange(range, {invalidate: 'touch'});
                        showIndicator(editor, editor.screenPositionForBufferPosition(range[0]));
                    });
                    editor.decorateMarkerLayer(markerLayer, {
                        type: 'highlight',
                        class: 'aaa',
                    });
                }
            } else {
                this.lastWord = null;
                markerLayer.clear();
                clearIndicators(editor);
            }
        });
    });
  },

  deactivate() {
    this.modalPanel.destroy();
    this.subscriptions.dispose();
    this.bananaView.destroy();
  },

  serialize() {
    return {
      bananaViewState: this.bananaView.serialize()
    };
  },

  toggle() {
    this.enabled = ! this.enabled;
    // let editor
    // if (editor = atom.workspace.getActiveTextEditor()) {
    //   let selection = editor.getSelectedText()
    //   let reversed = selection.split('').reverse().join('')
    //   editor.insertText(reversed)
    // }
  }

};
<commit_msg>啟用/禁用 plugins 時出現提示及一些必要之處理<commit_after>'use babel';

import * as ramda from 'ramda';
import BananaView from './banana-view';
import { CompositeDisposable } from 'atom';
import * as esprima from 'esprima';
import * as parser from './parser';

// scrollbar indicator
// ref: https://github.com/Aakash1312/scroll-searcher/blob/master/lib/scroll-marker.coffee

function flatten(listOfLists) {
    return listOfLists.reduce((results, i) => results.concat(i), []);
}

function indexs(line, word) {
    function ps(line, word, startIndex) {
        let idx = line.indexOf(word, startIndex);
        return idx === -1 ? [] : [idx].concat(ps(line, word, idx + word.length));
    }
    return ps(line, word, 0);
}

function ranges(txt, word, identifiers) {
    if (identifiers) {
        return identifiers.filter(i => i.name === word).map(i => [
            [i.loc.start.line-1, i.loc.start.column],
            [i.loc.end.line-1, i.loc.end.column],
        ]);
    } else {
        let lines = txt.split('\n');
        let points = flatten(ramda.zip(
            ramda.range(0, lines.length),
            lines.map(line => indexs(line, word)))
            .map(i => i[1].map(col => [i[0], col])));
        return points.map(p => [p, [p[0], p[1] + word.length]]);
    }
}

function indicatorBar(editor) {
    let bar = atom.views.getView(editor).component.domNodeValue.querySelector('.indicator-bar');
    if (! bar) {
        bar = document.createElement('div');
        bar.classList.add('indicator-bar');
        atom.views.getView(editor).component.domNodeValue.appendChild(bar);
    }
    return bar;
}

function clearIndicators(editor) {
    indicatorBar(editor).innerHTML = '';
}

function showIndicator(editor, screenPosition) {
    // 只處理單行 range (因為 identifier 只會有一行)
    // todo: 用 atom.views.getView(editor).component.domNodeValue.querySelector('.vertical-scrollbar')
    let row = screenPosition.row;
    let rowCount = editor.getScreenLineCount();
    let scrollHeight = atom.views.getView(editor).getScrollHeight();
    let displayHeight = editor.displayBuffer.height;

    let indicator = document.createElement('div');
    indicator.classList.add('indicator');
    indicator.style.top = Math.round((row / rowCount) * displayHeight) + 'px';
    indicatorBar(editor).appendChild(indicator);
}

export default {

  bananaView: null,
  modalPanel: null,
  subscriptions: null,

  enabled: true,
  lastWord: null,
  identifiersInEditor: {},
  markerLayerInEditor: {},

  activate(state) {
    this.bananaView = new BananaView(state.bananaViewState);
    this.modalPanel = atom.workspace.addModalPanel({
      item: this.bananaView.getElement(),
      visible: false
    });

    // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable
    this.subscriptions = new CompositeDisposable();

    // Register command that toggles this view
    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'banana:toggle': () => this.toggle()
    }));

    atom.workspace.observeTextEditors(editor => {
        if (! this.markerLayerInEditor[editor.id]) {
            this.markerLayerInEditor[editor.id] = editor.addMarkerLayer();
        }

        editor.onDidDestroy(event => {
            delete this.identifiersInEditor[editor.id];
            delete this.markerLayerInEditor[editor.id];
        });

        editor.onDidStopChanging(event => {
            if (!this.enabled || editor.getGrammar().name !== 'JavaScript') {
                return;
            }
            delete this.identifiersInEditor[editor.id];
            let jst = new parser.Jst();
            let ok = jst.parse(editor.getText(), {sourceType: 'module'});
            if (ok) {
                this.identifiersInEditor[editor.id] = parser.identifiers(jst);
            }
        });

        editor.onDidChangeCursorPosition(event => {
            if (!this.enabled || editor.getSelectedText()) {
                if (! this.enabled) {
                    this.markerLayerInEditor[editor.id].clear();
                    clearIndicators(editor);
                }
                return;
            }
            let markerLayer = this.markerLayerInEditor[editor.id];
            let word = editor.getWordUnderCursor();
            if (word.match(/^\w+$/)) {
                if (word !== this.lastWord) {
                    this.lastWord = word;
                    markerLayer.clear();
                    clearIndicators(editor);
                    ranges(editor.getText(), word, this.identifiersInEditor[editor.id])
                    .forEach(range => {
                        markerLayer.markBufferRange(range, {invalidate: 'touch'});
                        showIndicator(editor, editor.screenPositionForBufferPosition(range[0]));
                    });
                    editor.decorateMarkerLayer(markerLayer, {
                        type: 'highlight',
                        class: 'aaa',
                    });
                }
            } else {
                this.lastWord = null;
                markerLayer.clear();
                clearIndicators(editor);
            }
        });
    });
  },

  deactivate() {
    this.modalPanel.destroy();
    this.subscriptions.dispose();
    this.bananaView.destroy();
  },

  serialize() {
    return {
      bananaViewState: this.bananaView.serialize()
    };
  },

  toggle() {
    this.enabled = ! this.enabled;
    let msg = 'banana ' + (this.enabled ? 'enabled' : 'disabled');
    atom.notifications.addSuccess(msg);
  }

};
<|endoftext|>


<commit_before>// Copyright 2016-2020, University of Colorado Boulder

/**
 * A Scenery input listener that is able to find the closest in a list of items to a "down" event and trigger an action
 * (usually a drag) on that item. Usually this will be a drag listener start/press (e.g. SimpleDragHandler/DragListener),
 * but could accommodate other uses. It's similar in use to DragListener.createForwardingListener.
 *
 * Handles items of the form:
 * {
 *   startDrag: function( event ),
 *   computeDistance: function( globalPoint ) : number
 * }
 *
 * @author Jonathan Olson (PhET Interactive Simulations)
 */

import Mouse from '../../scenery/js/input/Mouse.js';
import Touch from '../../scenery/js/input/Touch.js';
import sun from './sun.js';

class ClosestDragListener {

  /**
   * @param {number} touchThreshold - The maximum distance from an item that will cause a touch to start a drag
   * @param {number} mouseThreshold - The maximum distance from an item that will cause a mouse down event to start a drag
   */
  constructor( touchThreshold, mouseThreshold ) {

    // @private
    this.touchThreshold = touchThreshold;
    this.mouseThreshold = mouseThreshold;

    // @private
    this.items = [];
  }

  /**
   * Adds an item that can be dragged.
   * @public
   *
   * @param {item} item
   */
  addDraggableItem( item ) {
    assert && assert( !!item.startDrag && !!item.computeDistance, 'Added an invalid item for ClosestDragListener' );
    this.items.push( item );
  }

  /**
   * Removes a previously-added item.
   * @public
   *
   * @param {item} item
   */
  removeDraggableItem( item ) {
    const index = _.indexOf( this.items, item );
    assert && assert( index >= 0 );
    this.items.splice( index, 1 );
  }

  /**
   * @public
   *
   * @param {SceneryEvent} event
   */
  down( event ) {
    // If there was nothing else in the way
    if ( event.target === event.currentTarget ) {
      let threshold = 0;
      if ( event.pointer instanceof Touch ) {
        threshold = this.touchThreshold;
      }
      if ( event.pointer instanceof Mouse ) {
        threshold = this.mouseThreshold;
      }
      if ( threshold ) {
        // search for the closest item
        let currentItem = null;
        let currentDistance = Number.POSITIVE_INFINITY;
        const globalPoint = event.pointer.point;
        const numItems = this.items.length;
        for ( let i = 0; i < numItems; i++ ) {
          const item = this.items[ i ];

          const distance = item.computeDistance( globalPoint );
          if ( distance < currentDistance ) {
            currentDistance = distance;
            currentItem = item;
          }
        }

        // if we have a closest item under the threshold, attempt to start a drag on it
        if ( currentItem && currentDistance < threshold ) {
          currentItem.startDrag( event );
        }
      }
    }
  }
}

sun.register( 'ClosestDragListener', ClosestDragListener );
export default ClosestDragListener;<commit_msg>Create Pointer.isTouchLike(), convert usages of instance Touch to use it, https://github.com/phetsims/scenery/issues/1156<commit_after>// Copyright 2016-2020, University of Colorado Boulder

/**
 * A Scenery input listener that is able to find the closest in a list of items to a "down" event and trigger an action
 * (usually a drag) on that item. Usually this will be a drag listener start/press (e.g. SimpleDragHandler/DragListener),
 * but could accommodate other uses. It's similar in use to DragListener.createForwardingListener.
 *
 * Handles items of the form:
 * {
 *   startDrag: function( event ),
 *   computeDistance: function( globalPoint ) : number
 * }
 *
 * @author Jonathan Olson (PhET Interactive Simulations)
 */

import Mouse from '../../scenery/js/input/Mouse.js';
import sun from './sun.js';

class ClosestDragListener {

  /**
   * @param {number} touchThreshold - The maximum distance from an item that will cause a touch-like (includes pen) to start a drag
   * @param {number} mouseThreshold - The maximum distance from an item that will cause a mouse down event to start a drag
   */
  constructor( touchThreshold, mouseThreshold ) {

    // @private
    this.touchThreshold = touchThreshold;
    this.mouseThreshold = mouseThreshold;

    // @private
    this.items = [];
  }

  /**
   * Adds an item that can be dragged.
   * @public
   *
   * @param {item} item
   */
  addDraggableItem( item ) {
    assert && assert( !!item.startDrag && !!item.computeDistance, 'Added an invalid item for ClosestDragListener' );
    this.items.push( item );
  }

  /**
   * Removes a previously-added item.
   * @public
   *
   * @param {item} item
   */
  removeDraggableItem( item ) {
    const index = _.indexOf( this.items, item );
    assert && assert( index >= 0 );
    this.items.splice( index, 1 );
  }

  /**
   * @public
   *
   * @param {SceneryEvent} event
   */
  down( event ) {
    // If there was nothing else in the way
    if ( event.target === event.currentTarget ) {
      let threshold = 0;
      if ( event.pointer.isTouchLike() ) {
        threshold = this.touchThreshold;
      }
      if ( event.pointer instanceof Mouse ) {
        threshold = this.mouseThreshold;
      }
      if ( threshold ) {
        // search for the closest item
        let currentItem = null;
        let currentDistance = Number.POSITIVE_INFINITY;
        const globalPoint = event.pointer.point;
        const numItems = this.items.length;
        for ( let i = 0; i < numItems; i++ ) {
          const item = this.items[ i ];

          const distance = item.computeDistance( globalPoint );
          if ( distance < currentDistance ) {
            currentDistance = distance;
            currentItem = item;
          }
        }

        // if we have a closest item under the threshold, attempt to start a drag on it
        if ( currentItem && currentDistance < threshold ) {
          currentItem.startDrag( event );
        }
      }
    }
  }
}

sun.register( 'ClosestDragListener', ClosestDragListener );
export default ClosestDragListener;<|endoftext|>


<commit_before>/*
* The MIT License (MIT)
*
* Product:      Paypal Basket
* Description:  A simple basket & product manager for the PayPal-node-SDK
*
* Copyright (c) 2020 Notixbit Creative <info@notixbit.net>
* Copyright (c) 2017-2020 Steven Agyekum <agyekum@posteo.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

import { T, ERR, callbackOrPromise } from './util'
import { Paypal, Product } from './main'

/**
 * @namespace Basket
 */
export default
class Basket
{
  /**
   * @class Basket
   * @param {Object} options | Options
   */
  constructor( options )
  {
    if( !options || typeof options !== T.OBJECT )
      throw ERR.PARAM_NON_OBJECT
    if( !options.hasOwnProperty('label') )
      throw ERR.PROP_NON_LABEL
    if( !options.hasOwnProperty('urls') )
      throw ERR.PROP_NON_URLS

    this.options = options
    this.products = []
    this.total = 0.00
  }

  /**
   * @function: add
   * @param {Object} product  | Instance of Product
   * @param {Number} amount   | Amount of product
   * @param {Function} cb     | Callback
   */
  add( product, amount, cb )
  {
    if( !product instanceof Product )
      return callbackOrPromise( cb, ERR.PARAM_NON_PRODUCT, null )

    if( !amount || typeof amount === T.FUNCT ) {
      cb = amount; amount = 1
    }

    if( amount <= 0 )
      return callbackOrPromise( cb, ERR.PARAM_INV_AMOUNT, null )

    let quantity = 0

    for( let prodidx in this.products ) {

      let prod = this.products[prodidx]

      if( prod.sku != product.sku )
        continue

      quantity = prod.quantity += amount
      break
    }

    if( quantity == 0 )
      this.products.push( Object.assign(
        { quantity: amount }, product )
      )

    this.total += (parseFloat( product.price ) * amount)

    return callbackOrPromise( cb, null, null )
  }

  /**
   * @function: del
   * @param {Object} product  | Instance of Product
   * @param {Function} cb     | Callback
   */
  del( product, cb )
  {
    if( !product instanceof Product )
      return callbackOrPromise( cb, ERR.PARAM_NON_PRODUCT, null )

    for( let prodidx in this.products ) {

      let prod = this.products[prodidx]

      if( prod.sku != product.sku )
        continue

      prod.quantity--

      if( prod.quantity <= 0 )
        this.products.splice( prodidx, 1 )

      this.total -= parseFloat( product.price )

      break
    }

    return callbackOrPromise( cb, null, null )
  }

  /**
   * @function: clear
   * @param {Function} cb | callback
   */
  clear( cb )
  {
    this.products.length = 0
    this.total = 0

    return callbackOrPromise( cb, null, null )
  }

  /**
   * @function: sell
   * @param {Object} opts | Options
   * @param {Function} cb | Callback
   */
  sell( opts, cb )
  {
    if( this.products.length == 0 )
      return callbackOrPromise( cb, ERR.BASKET_EMPTY, null )

    const currency = opts.currency || 'USD'
    const description = opts.description || ''
    const norequest = opts.norequest || false
    const redirect = this.options.urls || {}

    var manifest = {
      intent: 'order',
      payer: {
        payment_method: 'paypal'
      },
      redirect_urls: redirect,
      transactions: [{
        item_list: { items: [] }
      }]
    }

    let transactions = manifest.transactions[0]

    for( let prodidx in this.products ) {

      let prod = this.products[prodidx]

      prod.currency = currency

      transactions.item_list.items.push( prod )
    }

    transactions.amount = {
      currency: currency, total: this.total
    }

    transactions.description = description

    if( !norequest ) {
      return new Promise( (done, fail) => {
        Paypal.payment.create(manifest, (err, payment) => {
          if(err) { return fail( err ) }
          manifest.payment = payment || {}
          return done( manifest )
        })
      })
      .then( pmanifest => {
        return callbackOrPromise( cb, null, pmanifest )
      })
      .catch( err => {
        return callbackOrPromise( cb, err, manifest )
      })
    }

    return callbackOrPromise( cb, null, manifest )
  }

}
<commit_msg>improved formatting, const-correctness, def vals<commit_after>/*
* The MIT License (MIT)
*
* Product:      Paypal Basket
* Description:  A simple basket & product manager for the PayPal-node-SDK
*
* Copyright (c) 2020 Notixbit Creative <info@notixbit.net>
* Copyright (c) 2017-2020 Steven Agyekum <agyekum@posteo.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies
* or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

const { T, ERR, callbackOrPromise } = require('./util')
const Paypal = require('paypal-rest-sdk')
const Product = require('./product')

/**
 * @namespace Basket
 */
module.exports =
  class Basket {
    /**
     * @class Basket
     * @param {object} options
     */
    constructor(options) {
      if (!options || typeof options !== T.OBJECT)
        throw ERR.PARAM_NON_OBJECT
      if (!options.hasOwnProperty('label'))
        throw ERR.PROP_NON_LABEL
      if (!options.hasOwnProperty('urls'))
        throw ERR.PROP_NON_URLS

      this.options = options
      this.products = []
      this.total = 0.00
    }

    /**
     * Adds products to the basket.
     * @param {Product} product
     * @param {Number} amount
     * @param {Function|any} cb
     */
    add(product, amount = 1, cb = undefined) {
      if (!(product instanceof Product))
        return callbackOrPromise(cb, ERR.PARAM_NON_PRODUCT, null)

      if (!amount || typeof amount === T.FUNCT) {
        cb = amount; amount = 1
      }

      if (amount <= 0)
        return callbackOrPromise(cb, ERR.PARAM_INV_AMOUNT, null)

      let quantity = 0

      for (const prodidx in this.products) {
        const prod = this.products[prodidx]

        if (prod.sku != product.sku)
          continue

        quantity = prod.quantity += amount
        break
      }

      if (quantity == 0)
        this.products.push(Object.assign(
          { quantity: amount }, product)
        )

      this.total += (parseFloat(product.price) * amount)

      return callbackOrPromise(cb, null, null)
    }

    /**
     * Deletes a product from the basket.
     * @param {Product} product
     * @param {Function|any} cb
     */
    del(product, cb = undefined) {
      if (!(product instanceof Product))
        return callbackOrPromise(cb, ERR.PARAM_NON_PRODUCT, null)

      for (const prodidx in this.products) {
        const prod = this.products[prodidx]

        if (prod.sku != product.sku)
          continue

        prod.quantity--

        if (prod.quantity <= 0)
          this.products.splice(prodidx, 1)

        this.total -= parseFloat(product.price)

        break
      }

      return callbackOrPromise(cb, null, null)
    }

    /**
     * Deletes all products from a basket.
     * @param {Function|any} cb
     */
    clear(cb = undefined) {
      this.products.length = 0
      this.total = 0
      return callbackOrPromise(cb, null, null)
    }

    /**
     * Requests the paypal-payment manifest.
     * @param {Object} opts
     * @param {Function|any} cb
     */
    sell(opts, cb = undefined) {
      if (this.products.length == 0)
        return callbackOrPromise(cb, ERR.BASKET_EMPTY, null)

      const currency = opts.currency || 'USD'
      const description = opts.description || ''
      const norequest = opts.norequest || false
      const redirect = this.options.urls || {}

      const manifest = {
        intent: 'order',
        payer: {
          payment_method: 'paypal'
        },
        redirect_urls: redirect,
        transactions: [{
          item_list: { items: [] }
        }]
      }

      const transactions = manifest.transactions[0]

      for (const prodidx in this.products) {
        const prod = this.products[prodidx]
        prod.currency = currency
        transactions.item_list.items.push(prod)
      }

      transactions.amount = {
        currency: currency, total: this.total
      }

      transactions.description = description

      if (!norequest) {
        return new Promise((done, fail) => {
          Paypal.payment.create(manifest, (err, payment) => {
            if (err) { return fail(err) }
            manifest.payment = payment || {}
            return done(manifest)
          })
        })
          .then(pmanifest => {
            return callbackOrPromise(cb, null, pmanifest)
          })
          .catch(err => {
            return callbackOrPromise(cb, err, manifest)
          })
      }

      return callbackOrPromise(cb, null, manifest)
    }

  }
<|endoftext|>