<commit_before>/*
 * Backstretch
 * http://srobbin.com/jquery-plugins/backstretch/
 *
 * Copyright (c) 2013 Scott Robbin
 * Licensed under the MIT license.
 */

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

  /* PLUGIN DEFINITION
   * ========================= */

  $.fn.backstretch = function (images, options) {
    // We need at least one image or method name
    if (images === undefined || images.length === 0) {
      $.error("No images were supplied for Backstretch");
    }

    /*
     * Scroll the page one pixel to get the right window height on iOS
     * Pretty harmless for everyone else
    */
    if ($(window).scrollTop() === 0 ) {
      window.scrollTo(0, 0);
    }

    return this.each(function () {
      var $this = $(this)
        , obj = $this.data('backstretch');

      // Do we already have an instance attached to this element?
      if (obj) {

        // Is this a method they're trying to execute?
        if (typeof images === 'string' && typeof obj[images] === 'function') {
          // Call the method
          obj[images](options);

          // No need to do anything further
          return;
        }

        // Merge the old options with the new
        options = $.extend(obj.options, options);

        // Remove the old instance
        obj.destroy(true);
      }

      obj = new Backstretch(this, images, options || {});
      $this.data('backstretch', obj);
    });
  };

  // If no element is supplied, we'll attach to body
  $.backstretch = function (images, options) {
    // Return the instance
    return $('body')
            .backstretch(images, options)
            .data('backstretch');
  };

  // Custom selector
  $.expr[':'].backstretch = function(elem) {
    return $(elem).data('backstretch') !== undefined;
  };

  /* DEFAULTS
   * ========================= */

  $.fn.backstretch.defaults = {
      centeredX: true   // Should we center the image on the X axis?
    , centeredY: true   // Should we center the image on the Y axis?
    , duration: 5000    // Amount of time in between slides (if slideshow)
    , fade: 0           // Speed of fade transition between slides
    , paused: false   // Whether the images should slide after given duration
    , lazyload: false // Should the images be lazy loaded?
    , start: 0      // Index of the first image to show
  };

  /* STYLES
   *
   * Baked-in styles that we'll apply to our elements.
   * In an effort to keep the plugin simple, these are not exposed as options.
   * That said, anyone can override these in their own stylesheet.
   * ========================= */
  var styles = {
      wrap: {
          left: 0
        , top: 0
        , overflow: 'hidden'
        , margin: 0
        , padding: 0
        , height: '100%'
        , width: '100%'
        , zIndex: -999999
      }
    , img: {
          position: 'absolute'
        , display: 'none'
        , margin: 0
        , padding: 0
        , border: 'none'
        , width: 'auto'
        , height: 'auto'
        , maxHeight: 'none'
        , maxWidth: 'none'
        , zIndex: -999999
      }
  };

  /* CLASS DEFINITION
   * ========================= */
  var Backstretch = function (container, images, options) {
    this.options = $.extend({}, $.fn.backstretch.defaults, options || {});

    /* In its simplest form, we allow Backstretch to be called on an image path.
     * e.g. $.backstretch('/path/to/image.jpg')
     * So, we need to turn this back into an array.
     */
    this.images = $.isArray(images) ? images : [images];

    /**
     * Paused-Option
     */
    if (this.options.paused) {
        this.paused = true;
    }
    /**
     * Start-Option (Index)
     */
    if (this.options.start >= this.images.length)
    {
        this.options.start = this.images.length - 1;
    }
    if (this.options.start < 0)
    {
        this.options.start = 0;
    }

    /**
     * Lazy-Loading
     */
    if (options.lazyload && this.images[this.options.start])
    {
        $('')[0].src = this.images[this.options.start];
    }
    /**
     * Pre-Loading
     */
    else{
        $.each(this.images, function () {
            $('')[0].src = this;
        });
    }

    // Convenience reference to know if the container is body.
    this.isBody = container === document.body;

    /* We're keeping track of a few different elements
     *
     * Container: the element that Backstretch was called on.
     * Wrap: a DIV that we place the image into, so we can hide the overflow.
     * Root: Convenience reference to help calculate the correct height.
     */
    this.$container = $(container);
    this.$root = this.isBody ? supportsFixedPosition ? $(window) : $(document) : this.$container;

    // Don't create a new wrap if one already exists (from a previous instance of Backstretch)
    var $existing = this.$container.children(".backstretch").first();
    this.$wrap = $existing.length ? $existing : $('

').css(styles.wrap).appendTo(this.$container);

    // Non-body elements need some style adjustments
    if (!this.isBody) {
      // If the container is statically positioned, we need to make it relative,
      // and if no zIndex is defined, we should set it to zero.
      var position = this.$container.css('position')
        , zIndex = this.$container.css('zIndex');

      this.$container.css({
          position: position === 'static' ? 'relative' : position
        , zIndex: zIndex === 'auto' ? 0 : zIndex
        , background: 'none'
      });

      // Needs a higher z-index
      this.$wrap.css({zIndex: -999998});
    }

    // Fixed or absolute positioning?
    this.$wrap.css({
      position: this.isBody && supportsFixedPosition ? 'fixed' : 'absolute'
    });

    // Set the first image
    this.index = this.options.start;
    this.show(this.index);

    // Listen for resize
    $(window).on('resize.backstretch', $.proxy(this.resize, this))
             .on('orientationchange.backstretch', $.proxy(function () {
                // Need to do this in order to get the right window height
                if (this.isBody && window.pageYOffset === 0) {
                  window.scrollTo(0, 1);
                  this.resize();
                }
             }, this));
  };

  /* PUBLIC METHODS
   * ========================= */
  Backstretch.prototype = {
      resize: function () {
        try {
          var bgCSS = {left: 0, top: 0}
            , rootWidth = this.isBody ? this.$root.width() : this.$root.innerWidth()
            , bgWidth = rootWidth
            , rootHeight = this.isBody ? ( window.innerHeight ? window.innerHeight : this.$root.height() ) : this.$root.innerHeight()
            , bgHeight = bgWidth / this.$img.data('ratio')
            , bgOffset;

            // Make adjustments based on image ratio
            if (bgHeight >= rootHeight) {
                bgOffset = (bgHeight - rootHeight) / 2;
                if(this.options.centeredY) {
                  bgCSS.top = '-' + bgOffset + 'px';
                }
            } else {
                bgHeight = rootHeight;
                bgWidth = bgHeight * this.$img.data('ratio');
                bgOffset = (bgWidth - rootWidth) / 2;
                if(this.options.centeredX) {
                  bgCSS.left = '-' + bgOffset + 'px';
                }
            }

            this.$wrap.css({width: rootWidth, height: rootHeight})
                      .find('img:not(.deleteable)').css({width: bgWidth, height: bgHeight}).css(bgCSS);
        } catch(err) {
            // IE7 seems to trigger resize before the image is loaded.
            // This try/catch block is a hack to let it fail gracefully.
        }

        return this;
      }

      // Show the slide at a certain position
    , show: function (newIndex) {

        // Validate index
        if (Math.abs(newIndex) > this.images.length - 1) {
          return;
        }

        // Vars
        var self = this
          , oldImage = self.$wrap.find('img').addClass('deleteable')
          , evtOptions = { relatedTarget: self.$container[0] };

        // Trigger the "before" event
        self.$container.trigger($.Event('backstretch.before', evtOptions), [self, newIndex]);

        // Set the new index
        this.index = newIndex;

        // Pause the slideshow
        clearInterval(self.interval);

        // New image
        self.$img = $('')
                      .css(styles.img)
                      .bind('load', function (e) {
                        var imgWidth = this.width || $(e.target).width()
                          , imgHeight = this.height || $(e.target).height();

                        // Save the ratio
                        $(this).data('ratio', imgWidth / imgHeight);

                        // Show the image, then delete the old one
                        // "speed" option has been deprecated, but we want backwards compatibilty
                        $(this).fadeIn(self.options.speed || self.options.fade, function () {
                          oldImage.remove();

                          // Resume the slideshow
                          if (!self.paused) {
                            self.cycle();
                          }

                          // Trigger the "after" and "show" events
                          // "show" is being deprecated
                          $(['after', 'show']).each(function () {
                            self.$container.trigger($.Event('backstretch.' + this, evtOptions), [self, newIndex]);
                          });
                        });

                        // Resize
                        self.resize();
                      })
                      .appendTo(self.$wrap);

        // Hack for IE img onload event
        self.$img.attr('src', self.images[newIndex]);
        return self;
      }

    , next: function () {
        // Next slide
        return this.show(this.index < this.images.length - 1 ? this.index + 1 : 0);
      }

    , prev: function () {
        // Previous slide
        return this.show(this.index === 0 ? this.images.length - 1 : this.index - 1);
      }

    , pause: function () {
        // Pause the slideshow
        this.paused = true;
        return this;
      }

    , resume: function () {
        // Resume the slideshow
        this.paused = false;
        this.next();
        return this;
      }

    , cycle: function () {
        // Start/resume the slideshow
        if(this.images.length > 1) {
          // Clear the interval, just in case
          clearInterval(this.interval);

          this.interval = setInterval($.proxy(function () {
            // Check for paused slideshow
            if (!this.paused) {
              this.next();
            }
          }, this), this.options.duration);
        }
        return this;
      }

    , destroy: function (preserveBackground) {
        // Stop the resize events
        $(window).off('resize.backstretch orientationchange.backstretch');

        // Clear the interval
        clearInterval(this.interval);

        // Remove Backstretch
        if(!preserveBackground) {
          this.$wrap.remove();
        }
        this.$container.removeData('backstretch');
      }
  };

  /* SUPPORTS FIXED POSITION?
   *
   * Based on code from jQuery Mobile 1.1.0
   * http://jquerymobile.com/
   *
   * In a nutshell, we need to figure out if fixed positioning is supported.
   * Unfortunately, this is very difficult to do on iOS, and usually involves
   * injecting content, scrolling the page, etc.. It's ugly.
   * jQuery Mobile uses this workaround. It's not ideal, but works.
   *
   * Modified to detect IE6
   * ========================= */

  var supportsFixedPosition = (function () {
    var ua = navigator.userAgent
      , platform = navigator.platform
        // Rendering engine is Webkit, and capture major version
      , wkmatch = ua.match( /AppleWebKit\/([0-9]+)/ )
      , wkversion = !!wkmatch && wkmatch[ 1 ]
      , ffmatch = ua.match( /Fennec\/([0-9]+)/ )
      , ffversion = !!ffmatch && ffmatch[ 1 ]
      , operammobilematch = ua.match( /Opera Mobi\/([0-9]+)/ )
      , omversion = !!operammobilematch && operammobilematch[ 1 ]
      , iematch = ua.match( /MSIE ([0-9]+)/ )
      , ieversion = !!iematch && iematch[ 1 ];

    return !(
      // iOS 4.3 and older : Platform is iPhone/Pad/Touch and Webkit version is less than 534 (ios5)
      ((platform.indexOf( "iPhone" ) > -1 || platform.indexOf( "iPad" ) > -1  || platform.indexOf( "iPod" ) > -1 ) && wkversion && wkversion < 534) ||

      // Opera Mini
      (window.operamini && ({}).toString.call( window.operamini ) === "[object OperaMini]") ||
      (operammobilematch && omversion < 7458) ||

      //Android lte 2.1: Platform is Android and Webkit version is less than 533 (Android 2.2)
      (ua.indexOf( "Android" ) > -1 && wkversion && wkversion < 533) ||

      // Firefox Mobile before 6.0 -
      (ffversion && ffversion < 6) ||

      // WebOS less than 3
      ("palmGetResource" in window && wkversion && wkversion < 534) ||

      // MeeGo
      (ua.indexOf( "MeeGo" ) > -1 && ua.indexOf( "NokiaBrowser/8.5.0" ) > -1) ||

      // IE6
      (ieversion && ieversion <= 6)
    );
  }());

}(jQuery, window));<commit_msg>Fixes orientation bug on mobile Updates jquery.backstretch.js<commit_after>/*
 * Backstretch
 * http://srobbin.com/jquery-plugins/backstretch/
 *
 * Copyright (c) 2013 Scott Robbin
 * Licensed under the MIT license.
 */

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

  /* PLUGIN DEFINITION
   * ========================= */

  $.fn.backstretch = function (images, options) {
    // We need at least one image or method name
    if (images === undefined || images.length === 0) {
      $.error("No images were supplied for Backstretch");
    }

    /*
     * Scroll the page one pixel to get the right window height on iOS
     * Pretty harmless for everyone else
    */
    if ($(window).scrollTop() === 0 ) {
      window.scrollTo(0, 0);
    }

    return this.each(function () {
      var $this = $(this)
        , obj = $this.data('backstretch');

      // Do we already have an instance attached to this element?
      if (obj) {

        // Is this a method they're trying to execute?
        if (typeof images === 'string' && typeof obj[images] === 'function') {
          // Call the method
          obj[images](options);

          // No need to do anything further
          return;
        }

        // Merge the old options with the new
        options = $.extend(obj.options, options);

        // Remove the old instance
        obj.destroy(true);
      }

      obj = new Backstretch(this, images, options || {});
      $this.data('backstretch', obj);
    });
  };

  // If no element is supplied, we'll attach to body
  $.backstretch = function (images, options) {
    // Return the instance
    return $('body')
            .backstretch(images, options)
            .data('backstretch');
  };

  // Custom selector
  $.expr[':'].backstretch = function(elem) {
    return $(elem).data('backstretch') !== undefined;
  };

  /* DEFAULTS
   * ========================= */

  $.fn.backstretch.defaults = {
      centeredX: true   // Should we center the image on the X axis?
    , centeredY: true   // Should we center the image on the Y axis?
    , duration: 5000    // Amount of time in between slides (if slideshow)
    , fade: 0           // Speed of fade transition between slides
    , paused: false   // Whether the images should slide after given duration
    , lazyload: false // Should the images be lazy loaded?
    , start: 0      // Index of the first image to show
  };

  /* STYLES
   *
   * Baked-in styles that we'll apply to our elements.
   * In an effort to keep the plugin simple, these are not exposed as options.
   * That said, anyone can override these in their own stylesheet.
   * ========================= */
  var styles = {
      wrap: {
          left: 0
        , top: 0
        , overflow: 'hidden'
        , margin: 0
        , padding: 0
        , height: '100%'
        , width: '100%'
        , zIndex: -999999
      }
    , img: {
          position: 'absolute'
        , display: 'none'
        , margin: 0
        , padding: 0
        , border: 'none'
        , width: 'auto'
        , height: 'auto'
        , maxHeight: 'none'
        , maxWidth: 'none'
        , zIndex: -999999
      }
  };

  /* CLASS DEFINITION
   * ========================= */
  var Backstretch = function (container, images, options) {
    this.options = $.extend({}, $.fn.backstretch.defaults, options || {});

    /* In its simplest form, we allow Backstretch to be called on an image path.
     * e.g. $.backstretch('/path/to/image.jpg')
     * So, we need to turn this back into an array.
     */
    this.images = $.isArray(images) ? images : [images];

    /**
     * Paused-Option
     */
    if (this.options.paused) {
        this.paused = true;
    }
    /**
     * Start-Option (Index)
     */
    if (this.options.start >= this.images.length)
    {
        this.options.start = this.images.length - 1;
    }
    if (this.options.start < 0)
    {
        this.options.start = 0;
    }

    /**
     * Lazy-Loading
     */
    if (options.lazyload && this.images[this.options.start])
    {
        $('')[0].src = this.images[this.options.start];
    }
    /**
     * Pre-Loading
     */
    else{
        $.each(this.images, function () {
            $('')[0].src = this;
        });
    }

    // Convenience reference to know if the container is body.
    this.isBody = container === document.body;

    /* We're keeping track of a few different elements
     *
     * Container: the element that Backstretch was called on.
     * Wrap: a DIV that we place the image into, so we can hide the overflow.
     * Root: Convenience reference to help calculate the correct height.
     */
    this.$container = $(container);
    this.$root = this.isBody ? supportsFixedPosition ? $(window) : $(document) : this.$container;

    // Don't create a new wrap if one already exists (from a previous instance of Backstretch)
    var $existing = this.$container.children(".backstretch").first();
    this.$wrap = $existing.length ? $existing : $('

').css(styles.wrap).appendTo(this.$container);

    // Non-body elements need some style adjustments
    if (!this.isBody) {
      // If the container is statically positioned, we need to make it relative,
      // and if no zIndex is defined, we should set it to zero.
      var position = this.$container.css('position')
        , zIndex = this.$container.css('zIndex');

      this.$container.css({
          position: position === 'static' ? 'relative' : position
        , zIndex: zIndex === 'auto' ? 0 : zIndex
        , background: 'none'
      });

      // Needs a higher z-index
      this.$wrap.css({zIndex: -999998});
    }

    // Fixed or absolute positioning?
    this.$wrap.css({
      position: this.isBody && supportsFixedPosition ? 'fixed' : 'absolute'
    });

    // Set the first image
    this.index = this.options.start;
    this.show(this.index);

    // Listen for resize
    $(window).on('resize.backstretch', $.proxy(this.resize, this))
             .on('orientationchange.backstretch', $.proxy(function () {
                // Need to do this in order to get the right window height
                if (this.isBody && window.pageYOffset === 0) {
                  window.scrollTo(0, 1);
                  this.resize();
                }
             }, this));
  };

  /* PUBLIC METHODS
   * ========================= */
  Backstretch.prototype = {
      resize: function () {
        try {
          var bgCSS = {left: 0, top: 0}
            , landscape = (Math.ceil(window.innerWidth / window.innerHeight) > Math.ceil(screen.width / screen.height))
            , rootWidth = this.isBody ? (isMobile ? (landscape ? screen.height : screen.width) : this.$root.width()) : this.$root.innerWidth()
            , bgWidth = rootWidth
            , rootHeight = this.isBody ? ( window.innerHeight ? window.innerHeight : this.$root.height() ) : this.$root.innerHeight()
            , bgHeight = bgWidth / this.$img.data('ratio')
            , bgOffset;

            // Make adjustments based on image ratio
            if (bgHeight >= rootHeight) {
                bgOffset = (bgHeight - rootHeight) / 2;
                if(this.options.centeredY) {
                  bgCSS.top = '-' + bgOffset + 'px';
                }
            } else {
                bgHeight = rootHeight;
                bgWidth = bgHeight * this.$img.data('ratio');
                bgOffset = (bgWidth - rootWidth) / 2;
                if(this.options.centeredX) {
                  bgCSS.left = '-' + bgOffset + 'px';
                }
            }

            this.$wrap.css({width: rootWidth, height: rootHeight})
                      .find('img:not(.deleteable)').css({width: bgWidth, height: bgHeight}).css(bgCSS);
        } catch(err) {
            // IE7 seems to trigger resize before the image is loaded.
            // This try/catch block is a hack to let it fail gracefully.
        }

        return this;
      }

      // Show the slide at a certain position
    , show: function (newIndex) {

        // Validate index
        if (Math.abs(newIndex) > this.images.length - 1) {
          return;
        }

        // Vars
        var self = this
          , oldImage = self.$wrap.find('img').addClass('deleteable')
          , evtOptions = { relatedTarget: self.$container[0] };

        // Trigger the "before" event
        self.$container.trigger($.Event('backstretch.before', evtOptions), [self, newIndex]);

        // Set the new index
        this.index = newIndex;

        // Pause the slideshow
        clearInterval(self.interval);

        // New image
        self.$img = $('')
                      .css(styles.img)
                      .bind('load', function (e) {
                        var imgWidth = this.width || $(e.target).width()
                          , imgHeight = this.height || $(e.target).height();

                        // Save the ratio
                        $(this).data('ratio', imgWidth / imgHeight);

                        // Show the image, then delete the old one
                        // "speed" option has been deprecated, but we want backwards compatibilty
                        $(this).fadeIn(self.options.speed || self.options.fade, function () {
                          oldImage.remove();

                          // Resume the slideshow
                          if (!self.paused) {
                            self.cycle();
                          }

                          // Trigger the "after" and "show" events
                          // "show" is being deprecated
                          $(['after', 'show']).each(function () {
                            self.$container.trigger($.Event('backstretch.' + this, evtOptions), [self, newIndex]);
                          });
                        });

                        // Resize
                        self.resize();
                      })
                      .appendTo(self.$wrap);

        // Hack for IE img onload event
        self.$img.attr('src', self.images[newIndex]);
        return self;
      }

    , next: function () {
        // Next slide
        return this.show(this.index < this.images.length - 1 ? this.index + 1 : 0);
      }

    , prev: function () {
        // Previous slide
        return this.show(this.index === 0 ? this.images.length - 1 : this.index - 1);
      }

    , pause: function () {
        // Pause the slideshow
        this.paused = true;
        return this;
      }

    , resume: function () {
        // Resume the slideshow
        this.paused = false;
        this.next();
        return this;
      }

    , cycle: function () {
        // Start/resume the slideshow
        if(this.images.length > 1) {
          // Clear the interval, just in case
          clearInterval(this.interval);

          this.interval = setInterval($.proxy(function () {
            // Check for paused slideshow
            if (!this.paused) {
              this.next();
            }
          }, this), this.options.duration);
        }
        return this;
      }

    , destroy: function (preserveBackground) {
        // Stop the resize events
        $(window).off('resize.backstretch orientationchange.backstretch');

        // Clear the interval
        clearInterval(this.interval);

        // Remove Backstretch
        if(!preserveBackground) {
          this.$wrap.remove();
        }
        this.$container.removeData('backstretch');
      }
  };

  /* SUPPORTS FIXED POSITION?
   *
   * Based on code from jQuery Mobile 1.1.0
   * http://jquerymobile.com/
   *
   * In a nutshell, we need to figure out if fixed positioning is supported.
   * Unfortunately, this is very difficult to do on iOS, and usually involves
   * injecting content, scrolling the page, etc.. It's ugly.
   * jQuery Mobile uses this workaround. It's not ideal, but works.
   *
   * Modified to detect IE6
   * ========================= */

  var supportsFixedPosition = (function () {
    var ua = navigator.userAgent
      , platform = navigator.platform
        // Rendering engine is Webkit, and capture major version
      , wkmatch = ua.match( /AppleWebKit\/([0-9]+)/ )
      , wkversion = !!wkmatch && wkmatch[ 1 ]
      , ffmatch = ua.match( /Fennec\/([0-9]+)/ )
      , ffversion = !!ffmatch && ffmatch[ 1 ]
      , operammobilematch = ua.match( /Opera Mobi\/([0-9]+)/ )
      , omversion = !!operammobilematch && operammobilematch[ 1 ]
      , iematch = ua.match( /MSIE ([0-9]+)/ )
      , ieversion = !!iematch && iematch[ 1 ];

    return !(
      // iOS 4.3 and older : Platform is iPhone/Pad/Touch and Webkit version is less than 534 (ios5)
      ((platform.indexOf( "iPhone" ) > -1 || platform.indexOf( "iPad" ) > -1  || platform.indexOf( "iPod" ) > -1 ) && wkversion && wkversion < 534) ||

      // Opera Mini
      (window.operamini && ({}).toString.call( window.operamini ) === "[object OperaMini]") ||
      (operammobilematch && omversion < 7458) ||

      //Android lte 2.1: Platform is Android and Webkit version is less than 533 (Android 2.2)
      (ua.indexOf( "Android" ) > -1 && wkversion && wkversion < 533) ||

      // Firefox Mobile before 6.0 -
      (ffversion && ffversion < 6) ||

      // WebOS less than 3
      ("palmGetResource" in window && wkversion && wkversion < 534) ||

      // MeeGo
      (ua.indexOf( "MeeGo" ) > -1 && ua.indexOf( "NokiaBrowser/8.5.0" ) > -1) ||

      // IE6
      (ieversion && ieversion <= 6)
    );
  }());

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


<commit_before>/*
 * Grunt Remove Logging
 * https://github.com/ehynds/grunt-remove-logging
 *
 * Copyright (c) 2013 Eric Hynds
 * Licensed under the MIT license.
 */

module.exports = function(grunt) {
  "use strict";

  var task = require("./lib/removelogging").init(grunt);

  grunt.registerMultiTask("removelogging", "Remove console logging", function() {
    var opts = this.options();

    this.files.forEach(function(f) {
      var ret = f.src.map(function(srcFile) {
        var result = task(grunt.file.read(srcFile), opts);
        grunt.log.writeln("Removed " + result.count + " logging statements from " + srcFile);
        return result.src;
      }).join("");

      grunt.file.write(f.dest, ret);
    });
  });
};
<commit_msg>Added check to see if grunt.file.isFile before treating is as such<commit_after>/*
 * Grunt Remove Logging
 * https://github.com/ehynds/grunt-remove-logging
 *
 * Copyright (c) 2013 Eric Hynds
 * Licensed under the MIT license.
 */

module.exports = function(grunt) {
  "use strict";

  var task = require("./lib/removelogging").init(grunt);

  grunt.registerMultiTask("removelogging", "Remove console logging", function() {
    var opts = this.options();

    this.files.forEach(function(f) {
      var ret = f.src.map(function(srcFile) {
        if (grunt.file.isFile(srcFile)){
          var result = task(grunt.file.read(srcFile), opts);
          grunt.log.writeln("Removed " + result.count + " logging statements from " + srcFile);
          return result.src;
        }else{
          grunt.log.error("File not found " + srcFile);
        }
      }).join("");

      if(ret){
        grunt.file.write(f.dest, ret);
      }
    });
  });
};
<|endoftext|>


<commit_before>var gulp = require('gulp');
var sass = require('gulp-sass');
//var watch = require('gulp-watch');
var bower = require('gulp-bower');

var childTheme = 'leo';
var parentTheme = '/theme-open-ent/**/*';

var themePath = './assets/themes';
var localcsslib = '../entcore-css-lib/**/*';
var localparentTheme = '../theme-open-ent/**/*';

var sourceDependency = [];

//recupere theme sur git & copy dans springboard
gulp.task('update-libs', function () {
    return bower({ directory: themePath, cwd: '.' });
});

//copy dans childTheme ce qu'il a recup du theme (git)
gulp.task('fill-theme', sourceDependency, function () {
    return gulp.src(themePath + parentTheme)
        .pipe(gulp.dest(themePath + '/' + childTheme));
});

////////////////////////

//copy dans childTheme les dependances locales
gulp.task('copy-local', function () {
    //copy css-lib local
    return gulp.src([localcsslib, localparentTheme], {base: '../'})
        .pipe(gulp.dest(themePath));
});

////////////////////////

//override dans childTheme les el specifique
gulp.task('override-theme', ['fill-theme'], function () {
    gulp.src([themePath + '/' + childTheme+'/override-img/**/*'])
        .pipe(gulp.dest(themePath + '/' + childTheme + '/img'));

    gulp.src([themePath + '/' + childTheme + '/override-js/**/*'])
        .pipe(gulp.dest(themePath + '/' + childTheme+'/js'));

    gulp.src([themePath + '/' + childTheme + '/override-template/**/*'])
        .pipe(gulp.dest(themePath + '/' + childTheme + '/template'));
});

//compile sass
gulp.task('compile-sass', ['override-theme'], function () {
    //compile le css specifique dans le fichier default et ecrase le theme.css
    gulp.src(themePath + '/' + childTheme + '/override-css/default/theme.scss')
      .pipe(sass())
      .pipe(gulp.dest(themePath + '/' + childTheme + '/default'));

    gulp.src(themePath + '/' + childTheme + '/dyslexic/*.scss')
      .pipe(sass())
      .pipe(gulp.dest(themePath + '/' + childTheme + '/dyslexic'));
});

gulp.task('themes-local', function(){
    sourceDependency.push('copy-local')
    return gulp.start('compile-sass')
});
gulp.task('themes', function(){
    sourceDependency.push('update-libs')
    return gulp.start('compile-sass')
});

//attention supprimer le theme open-ent si on switch entre les 2 taches

// //watcher
// gulp.task('watch-css', function() {
//
//     function compileTheme() {
//         // //compile css-lib local
//         // gulp.src(['../css-lib/**/*'])
//         //     .pipe(gulp.dest('./assets/themes/entcore-css-lib'));
//         //
//         // //compile theme-open-ent local
//         // gulp.src(['../theme-open-ent/**/*'])
//         //     .pipe(gulp.dest('./assets/themes/theme-open-ent'));
//
//         //compile childTheme
//         gulp.src('./assets/themes/'+childTheme+'/default/theme.scss')
//             .pipe(sass())
//             .pipe(gulp.dest('./assets/themes/'+childTheme+'/default'));
//     }
//     watch('../css-lib/**/*.scss', compileTheme);
//     //watch theme-open-ent local
//     watch('../theme-open-ent/**/*.scss', compileTheme);
//     watch('./assets/themes/'+childTheme+'/**/*.scss', compileTheme);
//
// });
<commit_msg>[Gulp] Add clean task<commit_after>var gulp = require('gulp');
var sass = require('gulp-sass');
//var watch = require('gulp-watch');
var bower = require('gulp-bower');
var del = require('del');

var childTheme = 'leo';
var parentTheme = '/theme-open-ent/**/*';

var themePath = './assets/themes';
var localcsslib = '../entcore-css-lib/**/*';
var localparentTheme = '../theme-open-ent/**/*';

var sourceDependency = [];

gulp.task('clean', function(){
    return del([themePath + '/*', '!' + themePath + '/' + childTheme, themePath + '/' + childTheme + '/*',  '!' + themePath + '/' + childTheme + '/override*']);
});

//recupere theme sur git & copy dans springboard
gulp.task('update-libs', ['clean'], function () {
    return bower({ directory: themePath, cwd: '.' });
});

//copy dans childTheme ce qu'il a recup du theme (git)
gulp.task('fill-theme', sourceDependency, function () {
    return gulp.src(themePath + parentTheme)
        .pipe(gulp.dest(themePath + '/' + childTheme));
});

////////////////////////

//copy dans childTheme les dependances locales
gulp.task('copy-local', function () {
    //copy css-lib local
    return gulp.src([localcsslib, localparentTheme], {base: '../'})
        .pipe(gulp.dest(themePath));
});

////////////////////////

//override dans childTheme les el specifique
gulp.task('override-theme', ['fill-theme'], function () {
    gulp.src([themePath + '/' + childTheme+'/override-img/**/*'])
        .pipe(gulp.dest(themePath + '/' + childTheme + '/img'));

    gulp.src([themePath + '/' + childTheme + '/override-js/**/*'])
        .pipe(gulp.dest(themePath + '/' + childTheme+'/js'));

    gulp.src([themePath + '/' + childTheme + '/override-template/**/*'])
        .pipe(gulp.dest(themePath + '/' + childTheme + '/template'));
});

//compile sass
gulp.task('compile-sass', ['override-theme'], function () {
    //compile le css specifique dans le fichier default et ecrase le theme.css
    gulp.src(themePath + '/' + childTheme + '/override-css/default/theme.scss')
      .pipe(sass())
      .pipe(gulp.dest(themePath + '/' + childTheme + '/default'));

    gulp.src(themePath + '/' + childTheme + '/dyslexic/*.scss')
      .pipe(sass())
      .pipe(gulp.dest(themePath + '/' + childTheme + '/dyslexic'));
});

gulp.task('themes-local', function(){
    sourceDependency.push('copy-local')
    return gulp.start('compile-sass')
});
gulp.task('themes', function(){
    sourceDependency.push('update-libs')
    return gulp.start('compile-sass')
});

//attention supprimer le theme open-ent si on switch entre les 2 taches

// //watcher
// gulp.task('watch-css', function() {
//
//     function compileTheme() {
//         // //compile css-lib local
//         // gulp.src(['../css-lib/**/*'])
//         //     .pipe(gulp.dest('./assets/themes/entcore-css-lib'));
//         //
//         // //compile theme-open-ent local
//         // gulp.src(['../theme-open-ent/**/*'])
//         //     .pipe(gulp.dest('./assets/themes/theme-open-ent'));
//
//         //compile childTheme
//         gulp.src('./assets/themes/'+childTheme+'/default/theme.scss')
//             .pipe(sass())
//             .pipe(gulp.dest('./assets/themes/'+childTheme+'/default'));
//     }
//     watch('../css-lib/**/*.scss', compileTheme);
//     //watch theme-open-ent local
//     watch('../theme-open-ent/**/*.scss', compileTheme);
//     watch('./assets/themes/'+childTheme+'/**/*.scss', compileTheme);
//
// });
<|endoftext|>


<commit_before>var fs = require('fs'),
    append = require('append');

// general function
var diveSync = function(dir, opt, action) {
  // default options
  var defaultOpt = {
    recursive: true,
    all: false,
    directories: false,
    filter: function filter() {
      return true;
    }
  };

  // action is the last argument
  action = arguments[arguments.length - 1];

  // ensure opt is an object
  if (typeof opt != 'object')
    opt = {};

  opt = append(defaultOpt, opt);

  // apply filter
  if (!opt.filter(dir, true)) return;

  try {
    // read the directory
    var list = fs.readdirSync(dir);

    // for every file in the list
    list.sort().some(function (file) {
      if (opt.all || file[0] != '.') {
        // full path of that file
        var path = dir + '/' + file;

        // get the file's stats
        var stat = fs.statSync(path);

        // if the file is a directory
        if (stat && stat.isDirectory()) {
          // call the action if enabled for directories
          if (opt.directories)
            if (action(null, path) === false) return false;

          // dive into the directory
          if (opt.recursive)
            diveSync(path, opt, action);
        } else {
          // apply filter
          if (!opt.filter(path, false)) return;

          // call the action
          return action(null, path) === false;
        }
      }
    });
  } catch(err) {
    action(err);
  }
};

module.exports = diveSync;
<commit_msg>Fix results<commit_after>var fs = require('fs'),
    append = require('append');

// general function
var diveSync = function(dir, opt, action) {
  // default options
  var defaultOpt = {
    recursive: true,
    all: false,
    directories: false,
    filter: function filter() {
      return true;
    }
  };

  // action is the last argument
  action = arguments[arguments.length - 1];

  // ensure opt is an object
  if (typeof opt != 'object')
    opt = {};

  opt = append(defaultOpt, opt);

  // apply filter
  if (!opt.filter(dir, true)) return;

  try {
    // read the directory
    var list = fs.readdirSync(dir);

    // for every file in the list
    list.sort().some(function (file) {
      if (opt.all || file[0] != '.') {
        // full path of that file
        var path = dir + '/' + file;

        // get the file's stats
        var stat = fs.statSync(path);

        // if the file is a directory
        if (stat && stat.isDirectory()) {
          // call the action if enabled for directories
          if (opt.directories)
            if (action(null, path) === false)
              return true;

          // dive into the directory
          if (opt.recursive)
            diveSync(path, opt, action);
        } else {
          // apply filter
          if (!opt.filter(path, false))
            return false;

          // call the action
          return action(null, path) === false;
        }
      }
    });
  } catch(err) {
    action(err);
  }
};

module.exports = diveSync;
<|endoftext|>


<commit_before>var gulp = require('gulp'),
  gutil = require('gulp-util'),

  coffee = require('gulp-coffee'),
  uglify = require('gulp-uglify'),
  concat = require('gulp-concat'),

  sass = require('gulp-sass'),
  prefix = require('gulp-autoprefixer'),
  minifyCss = require('gulp-minify-css'),

  jade = require('gulp-jade'),

  gulpDeployFtp = require('gulp-deploy-ftp'),
  zip = require('gulp-zip'),

  imagemin = require('gulp-imagemin'),
  connect = require('gulp-connect'),
  plumber = require('gulp-plumber'),
  sourcemaps = require('gulp-sourcemaps');

// Prefix is not assured when livereload, only when run $ gulp
// MinifyCss ( assured by sass ), Plumber, gutil, sourceMap not used

//

var modernizr = 'bower_components/modernizr/modernizr.js',
  classie = 'bower_components/classie/classie.js',
  velocity = 'bower_components/velocity/velocity.min.js',
  app = 'www/js/*.js';

var lib = [modernizr, classie, app];

var ftpOptions = {
  user: '',
  password: '',
  port: '',
  host: '',
  uploadPath: 'www/'
};

// Gulp DOM Tasks

gulp.task('coffee', function () {
  gulp.src('www/js/*.coffee')
    .pipe(coffee({
      bare: false
    }))
    .pipe(uglify())
    .pipe(gulp.dest('www/js/'));

  gulp.src('www/js/*.js')
    .pipe(connect.reload());
});

gulp.task('sass', function () {
  gulp.src('www/css/*.sass')
    .pipe(sass({
      outputStyle: 'uncompressed'
    }))
    .pipe(gulp.dest('www/css/'));

  gulp.src('www/css/*.css')
    .pipe(connect.reload());

  gulp.src('www/*.html')
    .pipe(connect.reload());
});

gulp.task('jade', function () {
  gulp.src('www/*.jade')
    .pipe(jade({
      pretty: true
    }))
    .pipe(gulp.dest('www/'));

  gulp.src('www/*.html')
    .pipe(connect.reload());
});

// FTP

gulp.task('ftp', function () {
  gulp.src('www/dist/*')
    .pipe(gulpDeployFtp(ftpOptions))
    .pipe(gulp.dest('www/ftp/'));
});

// Zip

gulp.task('zip', function () {
  gulp.src('www/dist/*')
    .pipe(zip('Dist.zip'))
    .pipe(gulp.dest('www/dist/'));
});

// Server

gulp.task('connect', function () {
  connect.server({
    root: 'www/',
    livereload: true
  });
});

// Watcher

gulp.task('watch', function () {

  gulp.watch('www/js/*.coffee', ['coffee']);
  gulp.watch('www/css/*.sass', ['sass']);
  gulp.watch('www/*.jade', ['jade']);

});

// Dist

gulp.task('default', function () {

  gulp.src('www/*.jade')
    .pipe(jade({
      pretty: false
    }))
    .pipe(gulp.dest('www/dist/'));

  gulp.src(lib)
    .pipe(uglify())
    .pipe(concat('app.js'))
    .pipe(gulp.dest('www/dist/js/'));

  gulp.src('www/img/*')
    .pipe(imagemin({
      progressive: true
    }))
    .pipe(gulp.dest('www/dist/img/'));

  gulp.src('www/css/*.sass')
    .pipe(sass({
      outputStyle: 'compressed'
    }))
    .pipe(prefix())
    .pipe(gulp.dest('www/dist/css/'));

});

gulp.task('serve', ['connect', 'watch']);<commit_msg>up gulpfile.js<commit_after>var gulp = require('gulp'),
  gutil = require('gulp-util'),

  coffee = require('gulp-coffee'),
  uglify = require('gulp-uglify'),
  concat = require('gulp-concat'),

  sass = require('gulp-sass'),
  prefix = require('gulp-autoprefixer'),
  minifyCss = require('gulp-minify-css'),

  jade = require('gulp-jade'),////////////////////////////////////////////////////////
    //  yolo putain//
  ////////////////////////////////////////////////////////

  gulpDeployFtp = require('gulp-deploy-ftp'),
  zip = require('gulp-zip'),

  imagemin = require('gulp-imagemin'),
  connect = require('gulp-connect'),
  plumber = require('gulp-plumber'),
  sourcemaps = require('gulp-sourcemaps');

// Prefix is not assured when livereload, only when run $ gulp
// MinifyCss ( assured by sass ), Plumber, gutil, sourceMap not used

//

var modernizr = 'bower_components/modernizr/modernizr.js',
  classie = 'bower_components/classie/classie.js',
  velocity = 'bower_components/velocity/velocity.min.js',
  app = 'www/js/*.js';

var lib = [modernizr, classie, app];

var ftpOptions = {
  user: '',
  password: '',
  port: '',
  host: '',
  uploadPath: 'www/'
};

// Gulp DOM Tasks

gulp.task('coffee', function () {
  gulp.src('www/js/*.coffee')
    .pipe(coffee({
      bare: false
    }))
    .pipe(uglify())
    .pipe(gulp.dest('www/js/'));

  gulp.src('www/js/*.js')
    .pipe(connect.reload());
});

gulp.task('sass', function () {
  gulp.src('www/css/*.sass')
    .pipe(sass({
      outputStyle: 'uncompressed'
    }))
    .pipe(gulp.dest('www/css/'));

  gulp.src('www/css/*.css')
    .pipe(connect.reload());

  gulp.src('www/*.html')
    .pipe(connect.reload());
});

gulp.task('jade', function () {
  gulp.src('www/*.jade')
    .pipe(jade({
      pretty: true
    }))
    .pipe(gulp.dest('www/'));

  gulp.src('www/*.html')
    .pipe(connect.reload());
});

// FTP

gulp.task('ftp', function () {
  gulp.src('www/dist/*')
    .pipe(gulpDeployFtp(ftpOptions))
    .pipe(gulp.dest('www/ftp/'));
});

// Zip

gulp.task('zip', function () {
  gulp.src('www/dist/*')
    .pipe(zip('Dist.zip'))
    .pipe(gulp.dest('www/dist/'));
});

// Server

gulp.task('connect', function () {
  connect.server({
    root: 'www/',
    livereload: true
  });
});

// Watcher

gulp.task('watch', function () {

  gulp.watch('www/js/*.coffee', ['coffee']);
  gulp.watch('www/css/*.sass', ['sass']);
  gulp.watch('www/*.jade', ['jade']);

});

// Dist

gulp.task('default', function () {

  gulp.src('www/*.jade')
    .pipe(jade({
      pretty: false
    }))
    .pipe(gulp.dest('www/dist/'));

  gulp.src(lib)
    .pipe(uglify())
    .pipe(concat('app.js'))
    .pipe(gulp.dest('www/dist/js/'));

  gulp.src('www/img/*')
    .pipe(imagemin({
      progressive: true
    }))
    .pipe(gulp.dest('www/dist/img/'));

  gulp.src('www/css/*.sass')
    .pipe(sass({
      outputStyle: 'compressed'
    }))
    .pipe(prefix())
    .pipe(gulp.dest('www/dist/css/'));

});

gulp.task('serve', ['connect', 'watch']);<|endoftext|>


<commit_before>/*
** Module: luftdaten-data-raw
**
**
**
**
*/
// **********************************************************************************
"use strict"; // This is for your code to comply with the ECMAScript 5 standard.

var request = require('request');
var fs 		= require('fs');
var sys 	= require('util');
var _options	= {};
var luftdatenUrl, luftdatenFileName, luftdatenLocalPathRoot, fileFolder, tmpFolder;
var secureSite;
var siteProtocol;
var openiodUrl;
var loopTimeMax;

// **********************************************************************************

module.exports = {

//1238: Zwolle

	init: function (options) {
		_options					= options;

		secureSite 			= true;
		siteProtocol 		= secureSite?'https://':'http://';
		openiodUrl			= siteProtocol + 'openiod.org/' + _options.systemCode; //SCAPE604';
		loopTimeMax			= 60000; //ms, 60000=60 sec

		luftdatenUrl 			= 'http://api.luftdaten.info/v1/sensor/';
		luftdatenFileName 		= 'luftdaten.txt';

		luftdatenLocalPathRoot = options.systemFolderParent + '/luftdaten/';
		fileFolder 			= 'luftdaten';
		tmpFolder 			= luftdatenLocalPathRoot + fileFolder + "/" + 'tmp/';

		// create subfolders
		try {fs.mkdirSync(tmpFolder );} catch (e) {};//console.log('ERROR: no tmp folder found, batch run aborted.'); return } ;

		console.dir(_options);

		if (options.argvStations == undefined) {
			console.log('Parameter with sensorId(s) is missing, processing aborted.');
			return;
		}
		this.processSensors ();

		console.log('All retrieve actions are activated.');

	},

	processSensors: function (sensorId) {
		var sensorIds = _options.argvStations.split(',');
		console.log(sensorIds);

		for (var i=0;i<sensorIds.length;i++) {
			console.log('Processing sensorId: ' + sensorIds[i]);

			this.reqFile (luftdatenUrl + sensorIds[i] + '/', luftdatenFileName,	false, 'luftdatendata');

		}

	},

	reqFile: function (url, fileName, unzip, desc) {

	var _wfsResult=null;
	console.log("Request start: " + desc + " (" + url + ")");

	function StreamBuffer(req) {
  		var self = this

  		var buffer = []
  		var ended  = false
  		var ondata = null
  		var onend  = null

  		self.ondata = function(f) {
    		console.log("self.ondata")
    		for(var i = 0; i < buffer.length; i++ ) {
      			f(buffer[i])
      			console.log(i);
    		}
    		console.log(f);
    		ondata = f
  		}

  		self.onend = function(f) {
    		onend = f
    		if( ended ) {
      			onend()
    		}
  		}

  		req.on('data', function(chunk) {
    		// console.log("req.on data: ");
    		if (_wfsResult) {
      			_wfsResult += chunk;
    		} else {
      			_wfsResult = chunk;
    		}

    		if( ondata ) {
      			ondata(chunk)
    		} else {
      			buffer.push(chunk)
    		}
  		})

  		req.on('end', function() {
    		//console.log("req.on end")
    		ended = true;

    		if( onend ) {
      			onend()
    		}
  		})

  		req.streambuffer = self
	}

	function writeFile(path, fileName, content) {
  		fs.writeFile(path + fileName, content, function(err) {
    		if(err) {
      			console.log(err);
    		} else {
      			console.log("The file is saved! " + tmpFolder + fileName + ' (unzip:' + unzip + ')');
				if (unzip) {
					var exec = require('child_process').exec;
					var puts = function(error, stdout, stderr) { sys.puts(stdout) }
					exec(" cd " + tmpFolder + " ;  unzip -o " + tmpFolder + fileName + " ", puts);
				}
    		}
  		});
	}

	// send data to SOS service via OpenIoD REST service
	var sendData = function(data) {
	// oud //		http://openiod.com/SCAPE604/openiod?SERVICE=WPS&REQUEST=Execute&identifier=transform_observation&inputformat=insertom&objectid=humansensor&format=xml
	// oud //			&region=EHV		&lat=50.1		&lng=4.0		&category=airquality		&value=1

	//http://localhost:4000/SCAPE604/openiod?SERVICE=WPS&REQUEST=Execute&identifier=transform_observation&action=insertom&sensorsystem=scapeler_shinyei&offering=offering_0439_initial&verbose=true&commit=true&observation=scapeler_shinyei:12.345&neighborhoodcode=BU04390402
	//https://openiod.org/SCAPE604/openiod?SERVICE=WPS&REQUEST=Execute&identifier=transform_observation&action=insertom&sensorsystem=scapeler_shinyei&offering=offering_0439_initial&verbose=true&commit=true&observation=scapeler_shinyei:12.345&neighborhoodcode=BU04390402

		var _url = openiodUrl + '/openiod?SERVICE=WPS&REQUEST=Execute&identifier=transform_observation&action=insertom&sensorsystem=apri-sensor-luftdaten&offering=offering_0439_initial&commit=true';
		_url = _url + '&region=0439' + '&neighborhoodcode=' + data.neighborhoodCode + '&citycode=' + data.cityCode + '&foi=' + data.foi + '&observation=' + data.observation ;

		console.log(_url);

		request.get(_url)
			.on('response', function(response) {
				console.log(response.statusCode) // 200
				console.log(response.headers['content-type']) // 'image/png'
  			})
			.on('error', function(err) {
				console.log(err)
			})
		;

	};

//	var milliKelvinToCelsius = function(n){return Math.round((n/1e3-273.15)*100)/100};

	var options = {
		uri: url,
		method: 'GET'
	};

	request(options, function (error, response, body) {
		if (!error && response.statusCode == 200) {
			//console.log(body.observations[0])
			var inRecord	= JSON.parse(body);

			if (inRecord.length  == 0) {
				console.log('No Luftdaten sensordata found for this url: ' + options.uri );
				return;
			}

//			console.dir(inRecord[0]);
//			console.dir(inRecord[1]);
/*
			var outFile	= '"foi";"sensor";"latlng";"measureDate";"measureValue";"measureUom"\n';

			for (var i=0;i<body.observations.length;i++) {
				console.log(i);
				var inRec			= body.observations[i];
				var outRec			= {};
				outRec.foi			= inRec.procedure; // eg. 'station-35'
				outRec.sensor		= inRec.observableProperty; // eg. 'coraw'
				outRec.latlng		= inRec.featureOfInterest.geometry.coordinates;
				outRec.measureDate	= inRec.resultTime;
				outRec.measureValue	= inRec.result.value;
				outRec.measureUom	= inRec.result.uom;

				var csvRec			= '';
				csvRec				+= '"' + outRec.foi + '";';
				csvRec				+= '"' + outRec.sensor + '";';
				csvRec				+= outRec.latlng + ';';
				csvRec				+= '"' + outRec.measureDate + '";';
				csvRec				+= outRec.measureValue + ';';
				csvRec				+= '"' + outRec.measureUom + '"';

				outFile				+= csvRec + "\n";

			}
			writeFile(tmpFolder, fileName, outFile);
*/

			var data				= {};
			data.neighborhoodCode	= 'BU07721111';//'BU04390603'; //geoLocation.neighborhoodCode;
			data.neighborhoodName	= '..'; //geoLocation.neighborhoodName;
			data.cityCode			= 'GM0772'; //geoLocation.cityCode;
			data.cityName			= '..'; //geoLocation.cityName;

			//observation=stress:01

			var tmpMeasurements = {};

			var i = inRecord.length - 1;  // only last retrieved measurement

//			for (var i=0; i <inRecord.length;i++) {
				var inMeasurement = inRecord[i];
				var measurementTime = new Date(inMeasurement.timestamp+'.000Z');
//				console.log(inMeasurement.timestamp);
//				console.log(measurementTime);
				var nowTime = new Date();
//				console.log(nowTime);
				var timeDiff = new Date().getTime() - measurementTime.getTime();
//				console.log(timeDiff);

				if (timeDiff <= 60000 || timeDiff > 120000 ) {  // must be in the minute one minute ago
					console.log('ID: '+ inMeasurement.sensor.id + ' '+ nowTime + ' measurementtime: ' + measurementTime + ' ignore message timediff > 60 seconds' );
					return; // ignore measurement
				}

				if (tmpMeasurements[inMeasurement.sensor.id] == undefined)  tmpMeasurements[inMeasurement.sensor.id]={};
				var _measurement = tmpMeasurements[inMeasurement.sensor.id];
				_measurement.sensorType = inMeasurement.sensor.sensor_type;
				_measurement.data = inMeasurement.sensordatavalues;

				data.foi = 'LUFTDATEN'+inMeasurement.location.country+inMeasurement.sensor.id;

//				console.dir(_measurement);
				if (_measurement.sensorType.id == 14) {  //name='SDS011'
				  	for (var j=0; j< _measurement.data.length;j++) {
						if (_measurement.data[j].value_type == 'P1' ) {
					  		_measurement.pm10 = _measurement.data[j].value;
						}
						if (_measurement.data[j].value_type == 'P2' ) {
					  		_measurement.pm25 = _measurement.data[j].value;
						}

					}

				}
//			}
//		    console.log(_measurement.pm25);
//		    console.log(_measurement.pm10);

			data.categories			= [];
			data.observation		=
				'apri-sensor-luftdaten-PM25:'+ _measurement.pm25 + ',' +
				'apri-sensor-luftdaten-PM10:'+ _measurement.pm10;
//				'apri-sensor-luftdaten-temperature:'+ milliKelvinToCelsius(inRecord.s_temperatureambient) + ',' +

			sendData(data);

		}
	});

/*
  	new StreamBuffer(request( options, function(error, response) {
		console.log("Request completed: " + desc + " " );
		var currDate = new Date();
		var iso8601 = currDate.toISOString();

		writeFile(tmpFolder, fileName, '{"retrievedDate": "' + iso8601 + '", "content":' +
			_wfsResult + ' }');
		})
  	);
*/

	} // end of reqFile

}  // end of module.exports
<commit_msg>catch on no valid json data<commit_after>/*
** Module: luftdaten-data-raw
**
**
**
**
*/
// **********************************************************************************
"use strict"; // This is for your code to comply with the ECMAScript 5 standard.

var request = require('request');
var fs 		= require('fs');
var sys 	= require('util');
var _options	= {};
var luftdatenUrl, luftdatenFileName, luftdatenLocalPathRoot, fileFolder, tmpFolder;
var secureSite;
var siteProtocol;
var openiodUrl;
var loopTimeMax;

// **********************************************************************************

module.exports = {

//1238: Zwolle

	init: function (options) {
		_options					= options;

		secureSite 			= true;
		siteProtocol 		= secureSite?'https://':'http://';
		openiodUrl			= siteProtocol + 'openiod.org/' + _options.systemCode; //SCAPE604';
		loopTimeMax			= 60000; //ms, 60000=60 sec

		luftdatenUrl 			= 'http://api.luftdaten.info/v1/sensor/';
		luftdatenFileName 		= 'luftdaten.txt';

		luftdatenLocalPathRoot = options.systemFolderParent + '/luftdaten/';
		fileFolder 			= 'luftdaten';
		tmpFolder 			= luftdatenLocalPathRoot + fileFolder + "/" + 'tmp/';

		// create subfolders
		try {fs.mkdirSync(tmpFolder );} catch (e) {};//console.log('ERROR: no tmp folder found, batch run aborted.'); return } ;

		console.dir(_options);

		if (options.argvStations == undefined) {
			console.log('Parameter with sensorId(s) is missing, processing aborted.');
			return;
		}
		this.processSensors ();

		console.log('All retrieve actions are activated.');

	},

	processSensors: function (sensorId) {
		var sensorIds = _options.argvStations.split(',');
		console.log(sensorIds);

		for (var i=0;i<sensorIds.length;i++) {
			console.log('Processing sensorId: ' + sensorIds[i]);

			this.reqFile (luftdatenUrl + sensorIds[i] + '/', luftdatenFileName,	false, 'luftdatendata');

		}

	},

	reqFile: function (url, fileName, unzip, desc) {

	var _wfsResult=null;
	console.log("Request start: " + desc + " (" + url + ")");

	function StreamBuffer(req) {
  		var self = this

  		var buffer = []
  		var ended  = false
  		var ondata = null
  		var onend  = null

  		self.ondata = function(f) {
    		console.log("self.ondata")
    		for(var i = 0; i < buffer.length; i++ ) {
      			f(buffer[i])
      			console.log(i);
    		}
    		console.log(f);
    		ondata = f
  		}

  		self.onend = function(f) {
    		onend = f
    		if( ended ) {
      			onend()
    		}
  		}

  		req.on('data', function(chunk) {
    		// console.log("req.on data: ");
    		if (_wfsResult) {
      			_wfsResult += chunk;
    		} else {
      			_wfsResult = chunk;
    		}

    		if( ondata ) {
      			ondata(chunk)
    		} else {
      			buffer.push(chunk)
    		}
  		})

  		req.on('end', function() {
    		//console.log("req.on end")
    		ended = true;

    		if( onend ) {
      			onend()
    		}
  		})

  		req.streambuffer = self
	}

	function writeFile(path, fileName, content) {
  		fs.writeFile(path + fileName, content, function(err) {
    		if(err) {
      			console.log(err);
    		} else {
      			console.log("The file is saved! " + tmpFolder + fileName + ' (unzip:' + unzip + ')');
				if (unzip) {
					var exec = require('child_process').exec;
					var puts = function(error, stdout, stderr) { sys.puts(stdout) }
					exec(" cd " + tmpFolder + " ;  unzip -o " + tmpFolder + fileName + " ", puts);
				}
    		}
  		});
	}

	// send data to SOS service via OpenIoD REST service
	var sendData = function(data) {
	// oud //		http://openiod.com/SCAPE604/openiod?SERVICE=WPS&REQUEST=Execute&identifier=transform_observation&inputformat=insertom&objectid=humansensor&format=xml
	// oud //			&region=EHV		&lat=50.1		&lng=4.0		&category=airquality		&value=1

	//http://localhost:4000/SCAPE604/openiod?SERVICE=WPS&REQUEST=Execute&identifier=transform_observation&action=insertom&sensorsystem=scapeler_shinyei&offering=offering_0439_initial&verbose=true&commit=true&observation=scapeler_shinyei:12.345&neighborhoodcode=BU04390402
	//https://openiod.org/SCAPE604/openiod?SERVICE=WPS&REQUEST=Execute&identifier=transform_observation&action=insertom&sensorsystem=scapeler_shinyei&offering=offering_0439_initial&verbose=true&commit=true&observation=scapeler_shinyei:12.345&neighborhoodcode=BU04390402

		var _url = openiodUrl + '/openiod?SERVICE=WPS&REQUEST=Execute&identifier=transform_observation&action=insertom&sensorsystem=apri-sensor-luftdaten&offering=offering_0439_initial&commit=true';
		_url = _url + '&region=0439' + '&neighborhoodcode=' + data.neighborhoodCode + '&citycode=' + data.cityCode + '&foi=' + data.foi + '&observation=' + data.observation ;

		console.log(_url);

		request.get(_url)
			.on('response', function(response) {
				console.log(response.statusCode) // 200
				console.log(response.headers['content-type']) // 'image/png'
  			})
			.on('error', function(err) {
				console.log(err)
			})
		;

	};

//	var milliKelvinToCelsius = function(n){return Math.round((n/1e3-273.15)*100)/100};

	var options = {
		uri: url,
		method: 'GET'
	};

	request(options, function (error, response, body) {
		if (!error && response.statusCode == 200) {
			//console.log(body.observations[0])
			var inRecord ={};
			try {
				inRecord	= JSON.parse(body);
			} catch (e) {
				console.log('No Json data in luftdaten response:\n' + body );
				return;
			};

			if (inRecord.length  == 0) {
				console.log('No Luftdaten sensordata found for this url: ' + options.uri );
				return;
			}

//			console.dir(inRecord[0]);
//			console.dir(inRecord[1]);
/*
			var outFile	= '"foi";"sensor";"latlng";"measureDate";"measureValue";"measureUom"\n';

			for (var i=0;i<body.observations.length;i++) {
				console.log(i);
				var inRec			= body.observations[i];
				var outRec			= {};
				outRec.foi			= inRec.procedure; // eg. 'station-35'
				outRec.sensor		= inRec.observableProperty; // eg. 'coraw'
				outRec.latlng		= inRec.featureOfInterest.geometry.coordinates;
				outRec.measureDate	= inRec.resultTime;
				outRec.measureValue	= inRec.result.value;
				outRec.measureUom	= inRec.result.uom;

				var csvRec			= '';
				csvRec				+= '"' + outRec.foi + '";';
				csvRec				+= '"' + outRec.sensor + '";';
				csvRec				+= outRec.latlng + ';';
				csvRec				+= '"' + outRec.measureDate + '";';
				csvRec				+= outRec.measureValue + ';';
				csvRec				+= '"' + outRec.measureUom + '"';

				outFile				+= csvRec + "\n";

			}
			writeFile(tmpFolder, fileName, outFile);
*/

			var data				= {};
			data.neighborhoodCode	= 'BU07721111';//'BU04390603'; //geoLocation.neighborhoodCode;
			data.neighborhoodName	= '..'; //geoLocation.neighborhoodName;
			data.cityCode			= 'GM0772'; //geoLocation.cityCode;
			data.cityName			= '..'; //geoLocation.cityName;

			//observation=stress:01

			var tmpMeasurements = {};

			var i = inRecord.length - 1;  // only last retrieved measurement

//			for (var i=0; i <inRecord.length;i++) {
				var inMeasurement = inRecord[i];
				var measurementTime = new Date(inMeasurement.timestamp+'.000Z');
//				console.log(inMeasurement.timestamp);
//				console.log(measurementTime);
				var nowTime = new Date();
//				console.log(nowTime);
				var timeDiff = new Date().getTime() - measurementTime.getTime();
//				console.log(timeDiff);

				if (timeDiff <= 60000 || timeDiff > 120000 ) {  // must be in the minute one minute ago
					console.log('ID: '+ inMeasurement.sensor.id + ' '+ nowTime + ' measurementtime: ' + measurementTime + ' ignore message timediff > 60 seconds' );
					return; // ignore measurement
				}

				if (tmpMeasurements[inMeasurement.sensor.id] == undefined)  tmpMeasurements[inMeasurement.sensor.id]={};
				var _measurement = tmpMeasurements[inMeasurement.sensor.id];
				_measurement.sensorType = inMeasurement.sensor.sensor_type;
				_measurement.data = inMeasurement.sensordatavalues;

				data.foi = 'LUFTDATEN'+inMeasurement.location.country+inMeasurement.sensor.id;

//				console.dir(_measurement);
				if (_measurement.sensorType.id == 14) {  //name='SDS011'
				  	for (var j=0; j< _measurement.data.length;j++) {
						if (_measurement.data[j].value_type == 'P1' ) {
					  		_measurement.pm10 = _measurement.data[j].value;
						}
						if (_measurement.data[j].value_type == 'P2' ) {
					  		_measurement.pm25 = _measurement.data[j].value;
						}

					}

				}
//			}
//		    console.log(_measurement.pm25);
//		    console.log(_measurement.pm10);

			data.categories			= [];
			data.observation		=
				'apri-sensor-luftdaten-PM25:'+ _measurement.pm25 + ',' +
				'apri-sensor-luftdaten-PM10:'+ _measurement.pm10;
//				'apri-sensor-luftdaten-temperature:'+ milliKelvinToCelsius(inRecord.s_temperatureambient) + ',' +

			sendData(data);

		}
	});

/*
  	new StreamBuffer(request( options, function(error, response) {
		console.log("Request completed: " + desc + " " );
		var currDate = new Date();
		var iso8601 = currDate.toISOString();

		writeFile(tmpFolder, fileName, '{"retrievedDate": "' + iso8601 + '", "content":' +
			_wfsResult + ' }');
		})
  	);
*/

	} // end of reqFile

}  // end of module.exports
<|endoftext|>


<commit_before>/* Copyright 2011 the Melange authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @author Mario Ferraro
 */
(function () {
  /** @lends melange.dependency */

  if (window.melange === undefined) {
    throw new Error("Melange not loaded");
  }

  var melange = window.melange;

  /** Package that handles melange JS dependencies
    * @name melange.dependency
    * @namespace melange.depencency
    * @borrows melange.logging.debugDecorator.log as log
    */
  melange.dependency = window.melange.dependency = function () {
    return new melange.dependency();
  };

  /** Shortcut to current package.
    * @private
    */
  var $m = melange.logging.debugDecorator(melange.dependency);

  melange.error.createErrors([
  ]);

  var script_dependencies_chains = {};

  var s = script_dependencies_chains;

  if (melange.config.google_api_key !== undefined) {
    s.google = [
      "http://www.google.com/jsapi?key=" + melange.config.google_api_key
    ];
  }
  else {
    s.google = [
      "http://www.google.com/jsapi"
    ];
  }

  if (melange.config.is_local !== undefined && melange.config.is_local === true) {
    s.jquery = [
      "/jquery/jquery-1.5.js"
    ];
  }
  else {
    s.jquery = [
      "http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"
    ];
  }

  s.json = [
    "/json/json2.js"
  ];

  s.tinymce = [
    "/tiny_mce/tiny_mce.js"
  ];

  s.purr = [
    s.jquery,
    null,
    "/jquery/jquery-purr.js"
  ];

  s.spin = [
    s.jquery,
    null,
    "/jquery/jquery-spin-1.1.1.js"
  ];

  s.bgiframe = [
    s.jquery,
    null,
    "/jquery/jquery-bgiframe.js"
  ];

  s.ajaxQueue = [
    s.jquery,
    null,
    "/jquery/jquery-ajaxQueue.js"
  ];

  s.autocomplete = [
    s.jquery,
    null,
    "/jquery/jquery-autocomplete.js"
  ];

  s.thickbox = [
    s.jquery,
    null,
    "/jquery/jquery-thickbox.js"
  ];

  s.progressbar = [
    s.jquery,
    null,
    "/jquery/jquery-progressbar.js"
  ];

  s.jqueryui = [
    s.jquery,
    null,
    "/jquery/jquery-ui.core.js"
  ];

  s.jqgrid = [
    s.jquery,
    null,
    "/jquery/jquery-jqgrid.locale-en.js",
    null,
    "/jquery/jquery-jqgrid.base.js",
    null,
    "/jquery/jquery-jqgrid.custom.js",
    "/jquery/jquery-jqgrid.setcolumns.js"
  ];

  s.jqgridediting = [
    s.jqgrid,
    null,
    "/jquery/jquery-jqgrid.common.js",
    "/jquery/jquery-jqgrid.formedit.js",
    null,
    "/jquery/jquery-jqgrid.searchFilter.js",
    "/jquery/jquery-jqgrid.inlinedit.js",
    null,
    "/jquery/jquery-jqgrid.jqDnR.js",
    null,
    "/jquery/jquery-jqgrid.jqModal.js"
  ];

  s.cookie = [
    s.jquery,
    null,
    "/jquery/jquery-cookie.js"
  ];

  s.jlinq = [
    "/jlinq/jLinq-2.2.1.js"
  ];

  /** Melange packages **/

  s.melange = {};

  s.melange.main = [
    s.jquery,
    s.json,
    s.google,
    null,
    "/soc/content/js/melange-091015.js"
  ];

  s.melange.datetimepicker = [
    s.jqueryui,
    null,
    "/jquery-ui.datetimepicker.js",
    null,
    "/soc/content/js/datetimepicker-090825.js",
    null,
    "/soc/content/js/datetime-loader-090825.js"
  ];

  s.melange.menu = [
    s.cookie,
    null,
    "/soc/content/js/menu-110128.js"
  ];

  s.melange.duplicates = [
    s.progressbar,
    null,
    "/soc/content/js/duplicate-slots-090825.js"
  ];

  s.melange.form = [
    s.melange.main
  ];

  s.melange.list = [
    s.jqgrid,
    s.jlinq,
    null,
    s.jqgridediting,
    null,
    "/soc/content/js/melange.list-110204.js"
  ];

  s.melange.tooltip = [
    s.melange,
    s.purr,
    null
  ];

  s.melange.autocomplete = [
    s.autocomplete,
    null,
    "/soc/content/js/melange.autocomplete-110204.js"
  ];

  s.melange.graph = [
    s.melange,
    s.google,
    null,
    "/soc/content/js/melange.graph-100501.js"
  ];

  s.melange.uploadform = [
    s.melange,
    null,
    "/soc/content/js/upload-form-101205.js"
  ];

  $m.s = s;

  var unpack = function (orig_array) {
    var array_to_return = [];
    for (var i = 0, len = orig_array.length; i < len; i++) {
      var current_element = orig_array[i];
      if (typeof current_element === 'object' && current_element instanceof
          Array) {
        var unpacks = unpack(current_element);
        array_to_return = array_to_return.concat(unpacks);
      }
      else {
        array_to_return.push(current_element);
      }
    }
    return array_to_return;
  };

  $m.loadScripts = function(requested_packages) {
    var _tempqueue = unpack(requested_packages);

    /* Remove duplicates from the queue, as allowDuplicates with LAB
     * fails randomly at least in Safari and Chrome
     */
    var _queue = [];

    for (var i = 0, len = _tempqueue.length; i < len; i++) {
      var temp_val = _tempqueue[i];
      if (typeof temp_val == "string") {
        if (jQuery.inArray(temp_val, _queue) === -1) {
          _queue.push(temp_val);
        }
      } else {
        _queue.push(temp_val);
      }
    }

    for (var i=0, len=_queue.length; i<len; i++) {
      if (typeof _queue[i] == "string") { // script string source found
          $LAB = $LAB.script(_queue[i]);
      }
      else if (!_queue[i]) { // null/false found
          $LAB = $LAB.wait();
      }
      else if (typeof _queue[i] == "object" && _queue[i] instanceof $m.templateWithContext) {
          $LAB = $LAB.script(_queue[i].script_template).wait(
            function (context_to_send) {
              return function () {
                melange.templates.setContextToLast(context_to_send);
              }
            }(_queue[i].context)
          ).wait();
      }
      else if (typeof _queue[i] == "object" && _queue[i] instanceof $m.cssFile) {
        jQuery("<link>", {
          href: _queue[i].css,
          media: "screen",
          rel: "stylesheet",
          type: "text/css",
        }).appendTo("head");
      }
      else if (typeof _queue[i] == "function") { // inline function found
          $LAB = $LAB.wait(_queue[i]);
      }
    }
  };

  $m.templateWithContext = function (script_template, context) {
    this.script_template = script_template;
    this.context = context;
  };

  $m.cssFile = function (css) {
    this.css = css;
  };

}());
<commit_msg>Updating minimized version of melange dependency script.<commit_after>/* Copyright 2011 the Melange authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @author Mario Ferraro
 */
(function () {
  /** @lends melange.dependency */

  if (window.melange === undefined) {
    throw new Error("Melange not loaded");
  }

  var melange = window.melange;

  /** Package that handles melange JS dependencies
    * @name melange.dependency
    * @namespace melange.depencency
    * @borrows melange.logging.debugDecorator.log as log
    */
  melange.dependency = window.melange.dependency = function () {
    return new melange.dependency();
  };

  /** Shortcut to current package.
    * @private
    */
  var $m = melange.logging.debugDecorator(melange.dependency);

  melange.error.createErrors([
  ]);

  $m.templateWithContext = function (script_template, context) {
    this.script_template = script_template;
    this.context = context;
  };

  $m.cssFile = function (css) {
    this.css = css;
  };

  var script_dependencies_chains = {};

  var s = script_dependencies_chains;

  if (melange.config.google_api_key !== undefined) {
    s.google = [
      "http://www.google.com/jsapi?key=" + melange.config.google_api_key
    ];
  }
  else {
    s.google = [
      "http://www.google.com/jsapi"
    ];
  }

  if (melange.config.is_local !== undefined && melange.config.is_local === true) {
    s.jquery = [
      "/jquery/jquery-1.5.js"
    ];
  }
  else {
    s.jquery = [
      "http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"
    ];
  }

  s.json = [
    "/json/json2.js"
  ];

  s.tinymce = [
    "/tiny_mce/tiny_mce.js"
  ];

  s.purr = [
    s.jquery,
    null,
    "/jquery/jquery-purr.js"
  ];

  s.spin = [
    s.jquery,
    null,
    "/jquery/jquery-spin-1.1.1.js"
  ];

  s.bgiframe = [
    s.jquery,
    null,
    "/jquery/jquery-bgiframe.js"
  ];

  s.ajaxQueue = [
    s.jquery,
    null,
    "/jquery/jquery-ajaxQueue.js"
  ];

  s.autocomplete = [
    s.jquery,
    null,
    "/jquery/jquery-autocomplete.js"
  ];

  s.thickbox = [
    s.jquery,
    null,
    "/jquery/jquery-thickbox.js"
  ];

  s.progressbar = [
    s.jquery,
    null,
    "/jquery/jquery-progressbar.js"
  ];

  s.jqueryui = [
    s.jquery,
    null,
    new $m.cssFile("/soc/content/css/v2/gsoc/jquery-ui.css"),
    "/jquery/jquery-ui.core.js"
  ];

  s.jqgrid = [
    s.jquery,
    null,
    s.jqueryui,
    null,
    new $m.cssFile("/soc/content/css/v2/gsoc/ui.jqgrid.css"),
    "/jquery/jquery-jqgrid.locale-en.js",
    null,
    "/jquery/jquery-jqgrid.base.js",
    null,
    "/jquery/jquery-jqgrid.custom.js",
    "/jquery/jquery-jqgrid.setcolumns.js"
  ];

  s.jqgridediting = [
    s.jqgrid,
    null,
    "/jquery/jquery-jqgrid.common.js",
    "/jquery/jquery-jqgrid.formedit.js",
    null,
    "/jquery/jquery-jqgrid.searchFilter.js",
    "/jquery/jquery-jqgrid.inlinedit.js",
    null,
    "/jquery/jquery-jqgrid.jqDnR.js",
    null,
    "/jquery/jquery-jqgrid.jqModal.js"
  ];

  s.cookie = [
    s.jquery,
    null,
    "/jquery/jquery-cookie.js"
  ];

  s.jlinq = [
    "/jlinq/jLinq-2.2.1.js"
  ];

  /** Melange packages **/

  s.melange = {};

  s.melange.main = [
    s.jquery,
    s.json,
    s.google,
    null,
    "/soc/content/js/melange-091015.js"
  ];

  s.melange.datetimepicker = [
    s.jqueryui,
    null,
    "/jquery-ui.datetimepicker.js",
    null,
    "/soc/content/js/datetimepicker-090825.js",
    null,
    "/soc/content/js/datetime-loader-090825.js"
  ];

  s.melange.menu = [
    s.cookie,
    null,
    "/soc/content/js/menu-110128.js"
  ];

  s.melange.duplicates = [
    s.progressbar,
    null,
    "/soc/content/js/duplicate-slots-090825.js"
  ];

  s.melange.form = [
    s.melange.main
  ];

  s.melange.list = [
    s.jqgrid,
    s.jlinq,
    null,
    s.jqgridediting,
    null,
    "/soc/content/js/melange.list-110204.js"
  ];

  s.melange.tooltip = [
    s.melange,
    s.purr,
    null
  ];

  s.melange.autocomplete = [
    s.autocomplete,
    null,
    "/soc/content/js/melange.autocomplete-110204.js"
  ];

  s.melange.graph = [
    s.melange,
    s.google,
    null,
    "/soc/content/js/melange.graph-100501.js"
  ];

  s.melange.uploadform = [
    s.melange,
    null,
    "/soc/content/js/upload-form-101205.js"
  ];

  $m.s = s;

  var unpack = function (orig_array) {
    var array_to_return = [];
    for (var i = 0, len = orig_array.length; i < len; i++) {
      var current_element = orig_array[i];
      if (typeof current_element === 'object' && current_element instanceof
          Array) {
        var unpacks = unpack(current_element);
        array_to_return = array_to_return.concat(unpacks);
      }
      else {
        array_to_return.push(current_element);
      }
    }
    return array_to_return;
  };

  $m.loadScripts = function(requested_packages) {
    var _tempqueue = unpack(requested_packages);

    /* Remove duplicates from the queue, as allowDuplicates with LAB
     * fails randomly at least in Safari and Chrome
     */
    var _queue = [];

    for (var i = 0, len = _tempqueue.length; i < len; i++) {
      var temp_val = _tempqueue[i];
      if (typeof temp_val == "string") {
        if (jQuery.inArray(temp_val, _queue) === -1) {
          _queue.push(temp_val);
        }
      } else {
        _queue.push(temp_val);
      }
    }

    for (var i=0, len=_queue.length; i<len; i++) {
      if (typeof _queue[i] == "string") { // script string source found
          $LAB = $LAB.script(_queue[i]);
      }
      else if (!_queue[i]) { // null/false found
          $LAB = $LAB.wait();
      }
      else if (typeof _queue[i] == "object" && _queue[i] instanceof $m.templateWithContext) {
          $LAB = $LAB.script(_queue[i].script_template).wait(
            function (context_to_send) {
              return function () {
                melange.templates.setContextToLast(context_to_send);
              }
            }(_queue[i].context)
          ).wait();
      }
      else if (typeof _queue[i] == "object" && _queue[i] instanceof $m.cssFile) {
        jQuery("<link>", {
          href: _queue[i].css,
          media: "screen",
          rel: "stylesheet",
          type: "text/css",
        }).appendTo("head");
      }
      else if (typeof _queue[i] == "function") { // inline function found
          $LAB = $LAB.wait(_queue[i]);
      }
    }
  };

}());
<|endoftext|>


<commit_before>(function(){

// This is for grouping buttons into a bar
// takes an array of `L.easyButton`s and
// then the usual `.addTo(map)`
L.Control.EasyBar = L.Control.extend({

  options: {
    position:       'topleft',  // part of leaflet's defaults
    id:             null,       // an id to tag the Bar with
    leafletClasses: true        // use leaflet classes?
  },

  initialize: function(buttons, options){

    if(options){
      L.Util.setOptions( this, options );
    }

    this._buildContainer();
    this._buttons = [];

    for(var i = 0; i < buttons.length; i++){
      buttons[i]._bar = this;
      buttons[i]._container = buttons[i].button;
      this._buttons.push(buttons[i]);
      this.container.appendChild(buttons[i].button);
    }

  },

  _buildContainer: function(){
    this._container = this.container = L.DomUtil.create('div', '');
    this.options.leafletClasses && L.DomUtil.addClass(this.container, 'leaflet-bar easy-button-container leaflet-control');
    this.options.id && (this.container.id = this.options.id);
  },

  enable: function(){
    L.DomUtil.addClass(this.container, 'enabled');
    L.DomUtil.removeClass(this.container, 'disabled');
    this.container.setAttribute('aria-hidden', 'false');
    return this;
  },

  disable: function(){
    L.DomUtil.addClass(this.container, 'disabled');
    L.DomUtil.removeClass(this.container, 'enabled');
    this.container.setAttribute('aria-hidden', 'true');
    return this;
  },

  onAdd: function () {
    return this.container;
  },

  addTo: function (map) {
    this._map = map;

    for(var i = 0; i < this._buttons.length; i++){
      this._buttons[i]._map = map;
    }

    var container = this._container = this.onAdd(map),
        pos = this.getPosition(),
        corner = map._controlCorners[pos];

    L.DomUtil.addClass(container, 'leaflet-control');

    if (pos.indexOf('bottom') !== -1) {
      corner.insertBefore(container, corner.firstChild);
    } else {
      corner.appendChild(container);
    }

    return this;
  }

});

L.easyBar = function(){
  var args = [L.Control.EasyBar];
  for(var i = 0; i < arguments.length; i++){
    args.push( arguments[i] );
  }
  return new (Function.prototype.bind.apply(L.Control.EasyBar, args));
};

// L.EasyButton is the actual buttons
// can be called without being grouped into a bar
L.Control.EasyButton = L.Control.extend({

  options: {
    position:  'topleft',       // part of leaflet's defaults

    id:        null,            // an id to tag the button with

    type:      'replace',       // [(replace|animate)]
                                // replace swaps out elements
                                // animate changes classes with all elements inserted

    states:    [],              // state names look like this
                                // {
                                //   stateName: 'untracked',
                                //   onClick: function(){ handle_nav_manually(); };
                                //   title: 'click to make inactive',
                                //   icon: 'fa-circle',    // wrapped with
                                // }

    leafletClasses:   true,     // use leaflet styles for the button
    tagName:          'button',
  },

  initialize: function(icon, onClick, title, id){

    // clear the states manually
    this.options.states = [];

    // add id to options
    if(id != null){
      this.options.id = id;
    }

    // storage between state functions
    this.storage = {};

    // is the last item an object?
    if( typeof arguments[arguments.length-1] === 'object' ){

      // if so, it should be the options
      L.Util.setOptions( this, arguments[arguments.length-1] );
    }

    // if there aren't any states in options
    // use the early params
    if( this.options.states.length === 0 &&
        typeof icon  === 'string' &&
        typeof onClick === 'function'){

      // turn the options object into a state
      this.options.states.push({
        icon: icon,
        onClick: onClick,
        title: typeof title === 'string' ? title : ''
      });
    }

    // curate and move user's states into
    // the _states for internal use
    this._states = [];

    for(var i = 0; i < this.options.states.length; i++){
      this._states.push( new State(this.options.states[i], this) );
    }

    this._buildButton();

    this._activateState(this._states[0]);

  },

  _buildButton: function(){

    this.button = L.DomUtil.create(this.options.tagName, '');

    if (this.options.tagName === 'button') {
        this.button.setAttribute('type', 'button');
    }

    if (this.options.id ){
      this.button.id = this.options.id;
    }

    if (this.options.leafletClasses){
      L.DomUtil.addClass(this.button, 'easy-button-button leaflet-bar-part leaflet-interactive');
    }

    // don't let double clicks and mousedown get to the map
    L.DomEvent.addListener(this.button, 'dblclick', L.DomEvent.stop);
    L.DomEvent.addListener(this.button, 'mousedown', L.DomEvent.stop);
    L.DomEvent.addListener(this.button, 'mouseup', L.DomEvent.stop);

    // take care of normal clicks
    L.DomEvent.addListener(this.button,'click', function(e){
      L.DomEvent.stop(e);
      this._currentState.onClick(this, this._map ? this._map : null );
      this._map && this._map.getContainer().focus();
    }, this);

    // prep the contents of the control
    if(this.options.type == 'replace'){
      this.button.appendChild(this._currentState.icon);
    } else {
      for(var i=0;i<this._states.length;i++){
        this.button.appendChild(this._states[i].icon);
      }
    }
  },

  _currentState: {
    // placeholder content
    stateName: 'unnamed',
    icon: (function(){ return document.createElement('span'); })()
  },

  _states: null, // populated on init

  state: function(newState){

    // activate by name
    if(typeof newState == 'string'){

      this._activateStateNamed(newState);

    // activate by index
    } else if (typeof newState == 'number'){

      this._activateState(this._states[newState]);
    }

    return this;
  },

  _activateStateNamed: function(stateName){
    for(var i = 0; i < this._states.length; i++){
      if( this._states[i].stateName == stateName ){
        this._activateState( this._states[i] );
      }
    }
  },

  _activateState: function(newState){

    if( newState === this._currentState ){

      // don't touch the dom if it'll just be the same after
      return;

    } else {

      // swap out elements... if you're into that kind of thing
      if( this.options.type == 'replace' ){
        this.button.appendChild(newState.icon);
        this.button.removeChild(this._currentState.icon);
      }

      if( newState.title ){
        this.button.title = newState.title;
      } else {
        this.button.removeAttribute('title');
      }

      // update classes for animations
      for(var i=0;i<this._states.length;i++){
        L.DomUtil.removeClass(this._states[i].icon, this._currentState.stateName + '-active');
        L.DomUtil.addClass(this._states[i].icon, newState.stateName + '-active');
      }

      // update classes for animations
      L.DomUtil.removeClass(this.button, this._currentState.stateName + '-active');
      L.DomUtil.addClass(this.button, newState.stateName + '-active');

      // update the record
      this._currentState = newState;

    }
  },

  enable: function(){
    L.DomUtil.addClass(this.button, 'enabled');
    L.DomUtil.removeClass(this.button, 'disabled');
    this.button.setAttribute('aria-hidden', 'false');
    return this;
  },

  disable: function(){
    L.DomUtil.addClass(this.button, 'disabled');
    L.DomUtil.removeClass(this.button, 'enabled');
    this.button.setAttribute('aria-hidden', 'true');
    return this;
  },

  onAdd: function(map){
    var bar = L.easyBar([this], {
      position: this.options.position,
      leafletClasses: this.options.leafletClasses
    });
    this._anonymousBar = bar;
    this._container = bar.container;
    return this._anonymousBar.container;
  },

  removeFrom: function (map) {
    if (this._map === map)
      this.remove();
    return this;
  },

});

L.easyButton = function(/* args will pass automatically */){
  var args = Array.prototype.concat.apply([L.Control.EasyButton],arguments);
  return new (Function.prototype.bind.apply(L.Control.EasyButton, args));
};

/*************************
 *
 * util functions
 *
 *************************/

// constructor for states so only curated
// states end up getting called
function State(template, easyButton){

  this.title = template.title;
  this.stateName = template.stateName ? template.stateName : 'unnamed-state';

  // build the wrapper
  this.icon = L.DomUtil.create('span', '');

  L.DomUtil.addClass(this.icon, 'button-state state-' + this.stateName.replace(/(^\s*|\s*$)/g,''));
  this.icon.innerHTML = buildIcon(template.icon);
  this.onClick = L.Util.bind(template.onClick?template.onClick:function(){}, easyButton);
}

function buildIcon(ambiguousIconString) {

  var tmpIcon;

  // does this look like html? (i.e. not a class)
  if( ambiguousIconString.match(/[&;=<>"']/) ){

    // if so, the user should have put in html
    // so move forward as such
    tmpIcon = ambiguousIconString;

  // then it wasn't html, so
  // it's a class list, figure out what kind
  } else {
      ambiguousIconString = ambiguousIconString.replace(/(^\s*|\s*$)/g,'');
      tmpIcon = L.DomUtil.create('span', '');

      if( ambiguousIconString.indexOf('fa-') === 0 ){
        L.DomUtil.addClass(tmpIcon, 'fa '  + ambiguousIconString)
      } else if ( ambiguousIconString.indexOf('glyphicon-') === 0 ) {
        L.DomUtil.addClass(tmpIcon, 'glyphicon ' + ambiguousIconString)
      } else {
        L.DomUtil.addClass(tmpIcon, /*rollwithit*/ ambiguousIconString)
      }

      // make this a string so that it's easy to set innerHTML below
      tmpIcon = tmpIcon.outerHTML;
  }

  return tmpIcon;
}

})();
<commit_msg>provide simple access to the current state-name<commit_after>(function(){

// This is for grouping buttons into a bar
// takes an array of `L.easyButton`s and
// then the usual `.addTo(map)`
L.Control.EasyBar = L.Control.extend({

  options: {
    position:       'topleft',  // part of leaflet's defaults
    id:             null,       // an id to tag the Bar with
    leafletClasses: true        // use leaflet classes?
  },

  initialize: function(buttons, options){

    if(options){
      L.Util.setOptions( this, options );
    }

    this._buildContainer();
    this._buttons = [];

    for(var i = 0; i < buttons.length; i++){
      buttons[i]._bar = this;
      buttons[i]._container = buttons[i].button;
      this._buttons.push(buttons[i]);
      this.container.appendChild(buttons[i].button);
    }

  },

  _buildContainer: function(){
    this._container = this.container = L.DomUtil.create('div', '');
    this.options.leafletClasses && L.DomUtil.addClass(this.container, 'leaflet-bar easy-button-container leaflet-control');
    this.options.id && (this.container.id = this.options.id);
  },

  enable: function(){
    L.DomUtil.addClass(this.container, 'enabled');
    L.DomUtil.removeClass(this.container, 'disabled');
    this.container.setAttribute('aria-hidden', 'false');
    return this;
  },

  disable: function(){
    L.DomUtil.addClass(this.container, 'disabled');
    L.DomUtil.removeClass(this.container, 'enabled');
    this.container.setAttribute('aria-hidden', 'true');
    return this;
  },

  onAdd: function () {
    return this.container;
  },

  addTo: function (map) {
    this._map = map;

    for(var i = 0; i < this._buttons.length; i++){
      this._buttons[i]._map = map;
    }

    var container = this._container = this.onAdd(map),
        pos = this.getPosition(),
        corner = map._controlCorners[pos];

    L.DomUtil.addClass(container, 'leaflet-control');

    if (pos.indexOf('bottom') !== -1) {
      corner.insertBefore(container, corner.firstChild);
    } else {
      corner.appendChild(container);
    }

    return this;
  }

});

L.easyBar = function(){
  var args = [L.Control.EasyBar];
  for(var i = 0; i < arguments.length; i++){
    args.push( arguments[i] );
  }
  return new (Function.prototype.bind.apply(L.Control.EasyBar, args));
};

// L.EasyButton is the actual buttons
// can be called without being grouped into a bar
L.Control.EasyButton = L.Control.extend({

  options: {
    position:  'topleft',       // part of leaflet's defaults

    id:        null,            // an id to tag the button with

    type:      'replace',       // [(replace|animate)]
                                // replace swaps out elements
                                // animate changes classes with all elements inserted

    states:    [],              // state names look like this
                                // {
                                //   stateName: 'untracked',
                                //   onClick: function(){ handle_nav_manually(); };
                                //   title: 'click to make inactive',
                                //   icon: 'fa-circle',    // wrapped with
                                // }

    leafletClasses:   true,     // use leaflet styles for the button
    tagName:          'button',
  },

  initialize: function(icon, onClick, title, id){

    // clear the states manually
    this.options.states = [];

    // add id to options
    if(id != null){
      this.options.id = id;
    }

    // storage between state functions
    this.storage = {};

    // is the last item an object?
    if( typeof arguments[arguments.length-1] === 'object' ){

      // if so, it should be the options
      L.Util.setOptions( this, arguments[arguments.length-1] );
    }

    // if there aren't any states in options
    // use the early params
    if( this.options.states.length === 0 &&
        typeof icon  === 'string' &&
        typeof onClick === 'function'){

      // turn the options object into a state
      this.options.states.push({
        icon: icon,
        onClick: onClick,
        title: typeof title === 'string' ? title : ''
      });
    }

    // curate and move user's states into
    // the _states for internal use
    this._states = [];

    for(var i = 0; i < this.options.states.length; i++){
      this._states.push( new State(this.options.states[i], this) );
    }

    this._buildButton();

    this._activateState(this._states[0]);

  },

  _buildButton: function(){

    this.button = L.DomUtil.create(this.options.tagName, '');

    if (this.options.tagName === 'button') {
        this.button.setAttribute('type', 'button');
    }

    if (this.options.id ){
      this.button.id = this.options.id;
    }

    if (this.options.leafletClasses){
      L.DomUtil.addClass(this.button, 'easy-button-button leaflet-bar-part leaflet-interactive');
    }

    // don't let double clicks and mousedown get to the map
    L.DomEvent.addListener(this.button, 'dblclick', L.DomEvent.stop);
    L.DomEvent.addListener(this.button, 'mousedown', L.DomEvent.stop);
    L.DomEvent.addListener(this.button, 'mouseup', L.DomEvent.stop);

    // take care of normal clicks
    L.DomEvent.addListener(this.button,'click', function(e){
      L.DomEvent.stop(e);
      this._currentState.onClick(this, this._map ? this._map : null );
      this._map && this._map.getContainer().focus();
    }, this);

    // prep the contents of the control
    if(this.options.type == 'replace'){
      this.button.appendChild(this._currentState.icon);
    } else {
      for(var i=0;i<this._states.length;i++){
        this.button.appendChild(this._states[i].icon);
      }
    }
  },

  _currentState: {
    // placeholder content
    stateName: 'unnamed',
    icon: (function(){ return document.createElement('span'); })()
  },

  _states: null, // populated on init

  state: function(newState){

    // when called with no args, it's a getter
    if (arguments.length === 0) {
      return this._currentState.stateName;
    }

    // activate by name
    if(typeof newState == 'string'){

      this._activateStateNamed(newState);

    // activate by index
    } else if (typeof newState == 'number'){

      this._activateState(this._states[newState]);
    }

    return this;
  },

  _activateStateNamed: function(stateName){
    for(var i = 0; i < this._states.length; i++){
      if( this._states[i].stateName == stateName ){
        this._activateState( this._states[i] );
      }
    }
  },

  _activateState: function(newState){

    if( newState === this._currentState ){

      // don't touch the dom if it'll just be the same after
      return;

    } else {

      // swap out elements... if you're into that kind of thing
      if( this.options.type == 'replace' ){
        this.button.appendChild(newState.icon);
        this.button.removeChild(this._currentState.icon);
      }

      if( newState.title ){
        this.button.title = newState.title;
      } else {
        this.button.removeAttribute('title');
      }

      // update classes for animations
      for(var i=0;i<this._states.length;i++){
        L.DomUtil.removeClass(this._states[i].icon, this._currentState.stateName + '-active');
        L.DomUtil.addClass(this._states[i].icon, newState.stateName + '-active');
      }

      // update classes for animations
      L.DomUtil.removeClass(this.button, this._currentState.stateName + '-active');
      L.DomUtil.addClass(this.button, newState.stateName + '-active');

      // update the record
      this._currentState = newState;

    }
  },

  enable: function(){
    L.DomUtil.addClass(this.button, 'enabled');
    L.DomUtil.removeClass(this.button, 'disabled');
    this.button.setAttribute('aria-hidden', 'false');
    return this;
  },

  disable: function(){
    L.DomUtil.addClass(this.button, 'disabled');
    L.DomUtil.removeClass(this.button, 'enabled');
    this.button.setAttribute('aria-hidden', 'true');
    return this;
  },

  onAdd: function(map){
    var bar = L.easyBar([this], {
      position: this.options.position,
      leafletClasses: this.options.leafletClasses
    });
    this._anonymousBar = bar;
    this._container = bar.container;
    return this._anonymousBar.container;
  },

  removeFrom: function (map) {
    if (this._map === map)
      this.remove();
    return this;
  },

});

L.easyButton = function(/* args will pass automatically */){
  var args = Array.prototype.concat.apply([L.Control.EasyButton],arguments);
  return new (Function.prototype.bind.apply(L.Control.EasyButton, args));
};

/*************************
 *
 * util functions
 *
 *************************/

// constructor for states so only curated
// states end up getting called
function State(template, easyButton){

  this.title = template.title;
  this.stateName = template.stateName ? template.stateName : 'unnamed-state';

  // build the wrapper
  this.icon = L.DomUtil.create('span', '');

  L.DomUtil.addClass(this.icon, 'button-state state-' + this.stateName.replace(/(^\s*|\s*$)/g,''));
  this.icon.innerHTML = buildIcon(template.icon);
  this.onClick = L.Util.bind(template.onClick?template.onClick:function(){}, easyButton);
}

function buildIcon(ambiguousIconString) {

  var tmpIcon;

  // does this look like html? (i.e. not a class)
  if( ambiguousIconString.match(/[&;=<>"']/) ){

    // if so, the user should have put in html
    // so move forward as such
    tmpIcon = ambiguousIconString;

  // then it wasn't html, so
  // it's a class list, figure out what kind
  } else {
      ambiguousIconString = ambiguousIconString.replace(/(^\s*|\s*$)/g,'');
      tmpIcon = L.DomUtil.create('span', '');

      if( ambiguousIconString.indexOf('fa-') === 0 ){
        L.DomUtil.addClass(tmpIcon, 'fa '  + ambiguousIconString)
      } else if ( ambiguousIconString.indexOf('glyphicon-') === 0 ) {
        L.DomUtil.addClass(tmpIcon, 'glyphicon ' + ambiguousIconString)
      } else {
        L.DomUtil.addClass(tmpIcon, /*rollwithit*/ ambiguousIconString)
      }

      // make this a string so that it's easy to set innerHTML below
      tmpIcon = tmpIcon.outerHTML;
  }

  return tmpIcon;
}

})();
<|endoftext|>