<commit_before>var fs = require('fs')
	, path = require('path')
	, _ = require('underscore');

// Generate a list of top-level templates (make-shift menu)
var menuItems = _.chain(fs.readdirSync(path.resolve(__dirname, 'builds')))
	.filter(function(f) {
		// Only get html files, excluding index
		return ~f.indexOf('.html') && f != "index.html";
	})
	.map(function(f){
		// Format strings
		capitalized = f[0].toUpperCase() + f.slice(1);
		return {
			path: '/dist/builds/' + f,
			title: capitalized.replace(/-/g, ' ').replace('.html', '')
		};
	})
	.reduce(function(out, f){
		// Turn into markup
		return out + "
" + f.title + "
"
	}, "")
	.value();

module.exports = function (grunt) {
	var globalConfig = {
		path: {
			// Add additional src dirs for the "developed" templates
			cachebust: [
				'builds/includes/*.html',
				'dist/builds/*.html'
			],
			css: {
				root: 'css',
				site: 'css/site',
				src: 'css/src'
			},
			js: {
				root: 'js',
				src: 'js/src',
				site: 'js/site',
				build: 'js/build'
			},
			images: {
				site: 'images/site'
			}
		}
	};

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		globalConfig: globalConfig,

		sass: {
			dev: {
				options: {
					require: './sass/functions/base64-encode.rb',
					style: 'expanded'
				},
				files: {
					'<%= globalConfig.path.css.site %>/all.css': '<%= globalConfig.path.css.src %>/all.scss',
					'<%= globalConfig.path.css.site %>/ltie9.css': '<%= globalConfig.path.css.src %>/ltie9.scss'
				}
			},
			dist: {
				options: {
					require: './sass/functions/base64-encode.rb',
					style: 'compressed'
				},
				files: {
					'<%= globalConfig.path.css.site %>/all.css': '<%= globalConfig.path.css.src %>/all.scss',
					'<%= globalConfig.path.css.site %>/ltie9.css': '<%= globalConfig.path.css.src %>/ltie9.scss'
				}
			}
		},

		concat: {
			base: {
				src: [
					'<%= globalConfig.path.js.root %>/cssua.min.js',
					'<%= globalConfig.path.js.root %>/modernizr.min.js',
					'<%= globalConfig.path.js.root %>/supports.touch.min.js',
					'<%= globalConfig.path.js.root %>/izilla.gup.min.js',
					'<%= globalConfig.path.js.root %>/layout.engine.min.js',
					'<%= globalConfig.path.js.root %>/mq.genie.min.js'
				],
				dest: '<%= globalConfig.path.js.build %>/base.js'
			},
			all: {
				src: [
					'<%= globalConfig.path.js.root %>/class.query.min.js',
					'<%= globalConfig.path.js.root %>/swipe.min.js',
					'<%= globalConfig.path.js.root %>/firefox.hwa.min.js',
					'<%= globalConfig.path.js.root %>/fastclick.min.js',
					'<%= globalConfig.path.js.root %>/jquery.rwdImages.min.js',
					'<%= globalConfig.path.js.site %>/all.js'
				],
				dest: '<%= globalConfig.path.js.build %>/all.js'
			}
		},

		uglify: {
			base: {
				src: '<%= globalConfig.path.js.build %>/base.js',
				dest: '<%= globalConfig.path.js.build %>/base.js'
			},
			all: {
				src: '<%= globalConfig.path.js.build %>/all.js',
				dest: '<%= globalConfig.path.js.build %>/all.js'
			}
		},

		includereplace: {
			options: {
				includesDir: 'builds/includes/',
				globals: {
					currentYear: grunt.template.today('yyyy'),
					menuItems: menuItems,
					siteTitle: 'Project Name'
				}
			},
			templates: {
				src: 'builds/*.html',
				dest: 'dist/'
			}
		},

		'regex-replace': {
			version: {
				src: [
					'README.md',
					'<%= globalConfig.path.css.src %>/all.scss'
				],
				actions: [
					{
						search: /v\d+\.\d+\.\d+\ \(\d{4}-\d{2}-\d{2}\)/g,
						replace: 'v<%= pkg.version %> (' + grunt.template.today('yyyy-mm-dd') + ')'
					}
				]
			},
			cachebustcss: {
				src: globalConfig.path.cachebust,
				actions: [
					{
						search: /(.css\?v=)\d+?(")/g,
						replace: '$1' + grunt.template.today('yymmddHHMMss') + (Math.random() * 10000000000000000) + '$2'
					}
				]
			},
			cachebustjs: {
				src: globalConfig.path.cachebust,
				actions: [
					{
						search: /(.js\?v=)\d+?(")/g,
						replace: '$1' + grunt.template.today('yymmddHHMMss') + (Math.random() * 10000000000000000) + '$2'
					}
				]
			}
		},

		imagemin: {
			dynamic: {
				files: [{
					expand: true,
					cwd: '<%= globalConfig.path.images.site %>',
					src: ['**/*.{png,jpg,gif}'],
					dest: '<%= globalConfig.path.images.site %>'
				}]
			}
		},

		watch: {
			css: {
				files: ['<%= globalConfig.path.css.root %>/**/*.scss'],
				tasks: ['sass:dist', 'regex-replace:cachebustcss'],
				options: {
					spawn: false,
				}
			},
			scripts: {
				files: ['<%= globalConfig.path.js.root %>/**/*.js'],
				tasks: ['concat', 'uglify', 'regex-replace:cachebustjs'],
				options: {
					spawn: false
				}
			},
			images: {
				files: ['<%= globalConfig.path.images.site %>/*.{png,jpg,gif}'],
				tasks: ['imagemin'],
				options: {
					spawn: false
				}
			},
			html: {
				files: ['builds/**/*.html'],
				tasks: ['includereplace'],
				options: {
					spawn: false
				}
			}
		},

		watchdev: {
			css: {
				files: ['<%= globalConfig.path.css.root %>/**/*.scss'],
				tasks: ['sass:dev', 'regex-replace:cachebustcss'],
				options: {
					spawn: false,
				}
			},
			scripts: {
				files: ['<%= globalConfig.path.js.root %>/**/*.js'],
				tasks: ['concat', 'regex-replace:cachebustjs'],
				options: {
					spawn: false
				}
			},
			images: {
				files: ['<%= globalConfig.path.images.site %>/*.{png,jpg,gif}'],
				tasks: ['imagemin'],
				options: {
					spawn: false
				}
			},
			html: {
				files: ['builds/**/*.html'],
				tasks: ['includereplace'],
				options: {
					spawn: false
				}
			}
		}

	});

	grunt.loadNpmTasks('grunt-contrib-sass');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-include-replace');
	grunt.loadNpmTasks('grunt-regex-replace');
	grunt.loadNpmTasks('grunt-contrib-imagemin');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.renameTask('watch', 'watchdev');
	grunt.loadNpmTasks('grunt-contrib-watch');

	grunt.registerTask('default', ['sass:dist', 'concat', 'uglify', 'includereplace', 'imagemin', 'watch']);
	grunt.registerTask('dev', ['sass:dev', 'concat', 'includereplace', 'imagemin', 'watchdev']);
	grunt.registerTask('bust', ['regex-replace:cachebustcss', 'regex-replace:cachebustjs']);
	grunt.registerTask('version', ['sass:dist', 'regex-replace:version']);
};<commit_msg>Don't need Math.random as cache doesn't bust more than once in a watch session<commit_after>var fs = require('fs')
	, path = require('path')
	, _ = require('underscore');

// Generate a list of top-level templates (make-shift menu)
var menuItems = _.chain(fs.readdirSync(path.resolve(__dirname, 'builds')))
	.filter(function(f) {
		// Only get html files, excluding index
		return ~f.indexOf('.html') && f != "index.html";
	})
	.map(function(f){
		// Format strings
		capitalized = f[0].toUpperCase() + f.slice(1);
		return {
			path: '/dist/builds/' + f,
			title: capitalized.replace(/-/g, ' ').replace('.html', '')
		};
	})
	.reduce(function(out, f){
		// Turn into markup
		return out + "
" + f.title + "
"
	}, "")
	.value();

module.exports = function (grunt) {
	var globalConfig = {
		path: {
			// Add additional src dirs for the "developed" templates
			cachebust: [
				'builds/includes/*.html',
				'dist/builds/*.html'
			],
			css: {
				root: 'css',
				site: 'css/site',
				src: 'css/src'
			},
			js: {
				root: 'js',
				src: 'js/src',
				site: 'js/site',
				build: 'js/build'
			},
			images: {
				site: 'images/site'
			}
		}
	};

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		globalConfig: globalConfig,

		sass: {
			dev: {
				options: {
					require: './sass/functions/base64-encode.rb',
					style: 'expanded'
				},
				files: {
					'<%= globalConfig.path.css.site %>/all.css': '<%= globalConfig.path.css.src %>/all.scss',
					'<%= globalConfig.path.css.site %>/ltie9.css': '<%= globalConfig.path.css.src %>/ltie9.scss'
				}
			},
			dist: {
				options: {
					require: './sass/functions/base64-encode.rb',
					style: 'compressed'
				},
				files: {
					'<%= globalConfig.path.css.site %>/all.css': '<%= globalConfig.path.css.src %>/all.scss',
					'<%= globalConfig.path.css.site %>/ltie9.css': '<%= globalConfig.path.css.src %>/ltie9.scss'
				}
			}
		},

		concat: {
			base: {
				src: [
					'<%= globalConfig.path.js.root %>/cssua.min.js',
					'<%= globalConfig.path.js.root %>/modernizr.min.js',
					'<%= globalConfig.path.js.root %>/supports.touch.min.js',
					'<%= globalConfig.path.js.root %>/izilla.gup.min.js',
					'<%= globalConfig.path.js.root %>/layout.engine.min.js',
					'<%= globalConfig.path.js.root %>/mq.genie.min.js'
				],
				dest: '<%= globalConfig.path.js.build %>/base.js'
			},
			all: {
				src: [
					'<%= globalConfig.path.js.root %>/class.query.min.js',
					'<%= globalConfig.path.js.root %>/swipe.min.js',
					'<%= globalConfig.path.js.root %>/firefox.hwa.min.js',
					'<%= globalConfig.path.js.root %>/fastclick.min.js',
					'<%= globalConfig.path.js.root %>/jquery.rwdImages.min.js',
					'<%= globalConfig.path.js.site %>/all.js'
				],
				dest: '<%= globalConfig.path.js.build %>/all.js'
			}
		},

		uglify: {
			base: {
				src: '<%= globalConfig.path.js.build %>/base.js',
				dest: '<%= globalConfig.path.js.build %>/base.js'
			},
			all: {
				src: '<%= globalConfig.path.js.build %>/all.js',
				dest: '<%= globalConfig.path.js.build %>/all.js'
			}
		},

		includereplace: {
			options: {
				includesDir: 'builds/includes/',
				globals: {
					currentYear: grunt.template.today('yyyy'),
					menuItems: menuItems,
					siteTitle: 'Project Name'
				}
			},
			templates: {
				src: 'builds/*.html',
				dest: 'dist/'
			}
		},

		'regex-replace': {
			version: {
				src: [
					'README.md',
					'<%= globalConfig.path.css.src %>/all.scss'
				],
				actions: [
					{
						search: /v\d+\.\d+\.\d+\ \(\d{4}-\d{2}-\d{2}\)/g,
						replace: 'v<%= pkg.version %> (' + grunt.template.today('yyyy-mm-dd') + ')'
					}
				]
			},
			cachebustcss: {
				src: globalConfig.path.cachebust,
				actions: [
					{
						search: /(.css\?v=)\d+?(")/g,
						replace: '$1' + grunt.template.today('yymmddHHMMss') + '$2'
					}
				]
			},
			cachebustjs: {
				src: globalConfig.path.cachebust,
				actions: [
					{
						search: /(.js\?v=)\d+?(")/g,
						replace: '$1' + grunt.template.today('yymmddHHMMss') + '$2'
					}
				]
			}
		},

		imagemin: {
			dynamic: {
				files: [{
					expand: true,
					cwd: '<%= globalConfig.path.images.site %>',
					src: ['**/*.{png,jpg,gif}'],
					dest: '<%= globalConfig.path.images.site %>'
				}]
			}
		},

		watch: {
			css: {
				files: ['<%= globalConfig.path.css.root %>/**/*.scss'],
				tasks: ['sass:dist', 'regex-replace:cachebustcss'],
				options: {
					spawn: false,
				}
			},
			scripts: {
				files: ['<%= globalConfig.path.js.root %>/**/*.js'],
				tasks: ['concat', 'uglify', 'regex-replace:cachebustjs'],
				options: {
					spawn: false
				}
			},
			images: {
				files: ['<%= globalConfig.path.images.site %>/*.{png,jpg,gif}'],
				tasks: ['imagemin'],
				options: {
					spawn: false
				}
			},
			html: {
				files: ['builds/**/*.html'],
				tasks: ['includereplace'],
				options: {
					spawn: false
				}
			}
		},

		watchdev: {
			css: {
				files: ['<%= globalConfig.path.css.root %>/**/*.scss'],
				tasks: ['sass:dev', 'regex-replace:cachebustcss'],
				options: {
					spawn: false,
				}
			},
			scripts: {
				files: ['<%= globalConfig.path.js.root %>/**/*.js'],
				tasks: ['concat', 'regex-replace:cachebustjs'],
				options: {
					spawn: false
				}
			},
			images: {
				files: ['<%= globalConfig.path.images.site %>/*.{png,jpg,gif}'],
				tasks: ['imagemin'],
				options: {
					spawn: false
				}
			},
			html: {
				files: ['builds/**/*.html'],
				tasks: ['includereplace'],
				options: {
					spawn: false
				}
			}
		}

	});

	grunt.loadNpmTasks('grunt-contrib-sass');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-include-replace');
	grunt.loadNpmTasks('grunt-regex-replace');
	grunt.loadNpmTasks('grunt-contrib-imagemin');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.renameTask('watch', 'watchdev');
	grunt.loadNpmTasks('grunt-contrib-watch');

	grunt.registerTask('default', ['sass:dist', 'concat', 'uglify', 'includereplace', 'imagemin', 'watch']);
	grunt.registerTask('dev', ['sass:dev', 'concat', 'includereplace', 'imagemin', 'watchdev']);
	grunt.registerTask('bust', ['regex-replace:cachebustcss', 'regex-replace:cachebustjs']);
	grunt.registerTask('version', ['sass:dist', 'regex-replace:version']);
};<|endoftext|>


<commit_before>module.exports = function(grunt) {
    var browsers = [
        {
            browserName: 'internet explorer',
            platform: 'Windows 10',
            version: '11.285'
        }
    ];

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        connect: {
            server: {
                options: {
                    base: '',
                    port: 9999
                }
            }
        },

        'saucelabs-jasmine': {
            all: {
                options: {
                    urls: ['http://127.0.0.1:9999/test'],
                    browsers: browsers,
                    build: process.env.TRAVIS_JOB_ID,
                    testname: 'JSON-Patch test',
                    throttled: 3,
                    sauceConfig: {
                        'video-upload-on-pass': false
                    }
                }
            }
        },
        watch: {}
    });

    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-saucelabs');

    grunt.registerTask('default', ['connect', 'saucelabs-jasmine']);
};
<commit_msg>Add FF, Safari and Chrome to tests<commit_after>module.exports = function(grunt) {
    var browsers = [
        {
            browserName: 'internet explorer',
            platform: 'Windows 10',
            version: '11.285'
        },
        {
            browserName: 'chrome',
            platform: 'Linux'
        },
        {
            browserName: 'firefox',
            platform: 'Linux'
        },
        {
            browserName: 'safari',
            platform: 'Linux'
        }
    ];

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        connect: {
            server: {
                options: {
                    base: '',
                    port: 9999
                }
            }
        },

        'saucelabs-jasmine': {
            all: {
                options: {
                    urls: ['http://127.0.0.1:9999/test'],
                    browsers: browsers,
                    build: process.env.TRAVIS_JOB_ID,
                    testname: 'JSON-Patch test',
                    throttled: 3,
                    sauceConfig: {
                        'video-upload-on-pass': false
                    }
                }
            }
        },
        watch: {}
    });

    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-saucelabs');

    grunt.registerTask('default', ['connect', 'saucelabs-jasmine']);
};
<|endoftext|>


<commit_before>var carto = global.carto || require('carto');
var torque = require('../');

require('./canvas_layer');

/**
 * torque layer
 */
L.TorqueLayer = L.CanvasLayer.extend({

  providers: {
    'sql_api': torque.providers.json,
    'url_template': torque.providers.jsonarray,
    'windshaft': torque.providers.windshaft
  },

  renderers: {
    'point': torque.renderer.Point,
    'pixel': torque.renderer.Rectangle
  },

  initialize: function(options) {
    var self = this;
    if (!torque.isBrowserSupported()) {
      throw new Error("browser is not supported by torque");
    }
    options.tileLoader = true;
    this.key = 0;
    this.prevRenderedKey = 0;
    if (options.cartocss) {
      torque.extend(options, torque.common.TorqueLayer.optionsFromCartoCSS(options.cartocss));
    }

    options.resolution = options.resolution || 2;
    options.steps = options.steps || 100;
    options.visible = options.visible === undefined ? true: options.visible;
    this.hidden = !options.visible;

    this.animator = new torque.Animator(function(time) {
      var k = time | 0;
      if(self.key !== k) {
        self.setKey(k, { direct: true });
      }
    }, torque.extend(torque.clone(options), {
      onPause: function() {
        self.fire('pause');
      },
      onStop: function() {
        self.fire('stop');
      },
      onStart: function() {
        self.fire('play');
      }
    }));

    this.play = this.animator.start.bind(this.animator);
    this.stop = this.animator.stop.bind(this.animator);
    this.pause = this.animator.pause.bind(this.animator);
    this.toggle = this.animator.toggle.bind(this.animator);
    this.setDuration = this.animator.duration.bind(this.animator);
    this.isRunning = this.animator.isRunning.bind(this.animator);

    L.CanvasLayer.prototype.initialize.call(this, options);

    this.options.renderer = this.options.renderer || 'point';
    this.options.provider = this.options.provider || 'windshaft';

    options.ready = function() {
      self.fire("change:bounds", {
        bounds: self.provider.getBounds()
      });
      self.animator.steps(self.provider.getSteps());
      self.animator.rescale();
      self.fire('change:steps', {
        steps: self.provider.getSteps()
      });
      self.setKey(self.key);
    };

    this.provider = new this.providers[this.options.provider](options);
    this.renderer = new this.renderers[this.options.renderer](this.getCanvas(), options);

    this.renderer.on("allIconsLoaded", this.render.bind(this));

    // for each tile shown on the map request the data
    this.on('tileAdded', function(t) {
      var tileData = this.provider.getTileData(t, t.zoom, function(tileData) {
        // don't load tiles that are not being shown
        if (t.zoom !== self._map.getZoom()) return;
        self._tileLoaded(t, tileData);
        self._clearTileCaches();
        if (tileData) {
          self.redraw();
        }
      });
    }, this);

  },

  _clearTileCaches: function() {
    var t, tile;
    for(t in this._tiles) {
      tile = this._tiles[t];
      if (tile && tile._tileCache) {
        tile._tileCache = null;
      }
    }
  },

  _clearCaches: function() {
    this.renderer && this.renderer.clearSpriteCache();
    this._clearTileCaches();
  },

  onAdd: function (map) {
    map.on({
      'zoomend': this._clearCaches,
      'zoomstart': this._pauseOnZoom,
    }, this);

    map.on({
      'zoomend': this._resumeOnZoom
    }, this);
    L.CanvasLayer.prototype.onAdd.call(this, map);
  },

  onRemove: function(map) {
    this._removeTileLoader();
    map.off({
      'zoomend': this._clearCaches,
      'zoomstart': this._pauseOnZoom,
    }, this);
    map.off({
      'zoomend': this._resumeOnZoom
    }, this);
    L.CanvasLayer.prototype.onRemove.call(this, map);
  },

  _pauseOnZoom: function() {
    this.wasRunning = this.isRunning();
    if (this.wasRunning) {
      this.pause();
    }
  },

  _resumeOnZoom: function() {
    if (this.wasRunning) {
      this.play();
    }
  },

  hide: function() {
    if(this.hidden) return this;
    this.pause();
    this.clear();
    this.hidden = true;
    return this;
  },

  show: function() {
    if(!this.hidden) return this;
    this.hidden = false;
    this.play();
    return this;
  },

  setSQL: function(sql) {
    if (!this.provider || !this.provider.setSQL) {
      throw new Error("this provider does not support SQL");
    }
    this.provider.setSQL(sql);
    this._reloadTiles();
    return this;
  },

  setBlendMode: function(_) {
    this.renderer.setBlendMode(_);
    this.redraw();
  },

  setSteps: function(steps) {
    this.provider.setSteps(steps);
    this._reloadTiles();
  },

  setColumn: function(column, isTime) {
    this.provider.setColumn(column, isTime);
    this._reloadTiles();
  },

  getTimeBounds: function() {
    return this.provider && this.provider.getKeySpan();
  },

  clear: function() {
    var canvas = this.getCanvas();
    canvas.width = canvas.width;
  },

  /**
   * render the selectef key
   * don't call this function directly, it's called by
   * requestAnimationFrame. Use redraw to refresh it
   */
  render: function() {
    if(this.hidden) return;
    var t, tile, pos;
    var canvas = this.getCanvas();
    this.renderer.clearCanvas();
    var ctx = canvas.getContext('2d');

    for(t in this._tiles) {
      tile = this._tiles[t];
      if (tile) {
        // clear cache
        if (this.animator.isRunning()) {
          tile._tileCache = null;
        }

        pos = this.getTilePos(tile.coord);
        ctx.setTransform(1, 0, 0, 1, pos.x, pos.y);

        if (tile._tileCache) {
          // when the tile has a cached image just render it and avoid to render
          // all the points
          this.renderer._ctx.drawImage(tile._tileCache, 0, 0);
        } else {
          this.renderer.renderTile(tile, this.key);
        }
      }
    }
    this.renderer.applyFilters();

    // prepare caches if the animation is not running
    // don't cache if the key has just changed, this avoids to cache
    // when the user is dragging, it only cache when the map is still
    if (!this.animator.isRunning() && this.key === this.prevRenderedKey) {
      var tile_size = this.renderer.TILE_SIZE;
      for(t in this._tiles) {
        tile = this._tiles[t];
        if (tile && !tile._tileCache) {
          var c = tile._tileCache = document.createElement('canvas');
          c.width = c.height = tile_size;
          pos = this.getTilePos(tile.coord);
          // clip bounds, firefox raise an exception when try to get data from outside canvas
          var x = Math.max(0, pos.x)
          var y = Math.max(0, pos.y)
          var w = Math.min(tile_size, this.getCanvas().width - x);
          var h = Math.min(tile_size, this.getCanvas().height - y);
          if (w > 0 && h > 0) {
            c.getContext('2d').drawImage(this.getCanvas(), x, y, w, h, x - pos.x, y - pos.y, w, h);
          }
        }
      }
    }

    this.prevRenderedKey = this.key;

  },

  /**
   * set key to be shown. If it's a single value
   * it renders directly, if it's an array it renders
   * accumulated
   */
  setKey: function(key, options) {
    this.key = key;
    this.animator.step(key);
    this._clearTileCaches();
    this.redraw(options && options.direct);
    this.fire('change:time', { time: this.getTime(), step: this.key });
  },

  /**
   * helper function, does the same than ``setKey`` but only
   * accepts scalars.
   */
  setStep: function(time) {
    if(time === undefined || time.length !== undefined) {
      throw new Error("setTime only accept scalars");
    }
    this.setKey(time);
  },

  /**
   * transform from animation step to Date object
   * that contains the animation time
   *
   * ``step`` should be between 0 and ``steps - 1``
   */
  stepToTime: function(step) {
    var times = this.provider.getKeySpan();
    var time = times.start + (times.end - times.start)*(step/this.provider.getSteps());
    return new Date(time);
  },

  getStep: function() {
    return this.key;
  },

  /**
   * returns the animation time defined by the data
   * in the defined column. Date object
   */
  getTime: function() {
    return this.stepToTime(this.key);
  },

  /**
   * returns an object with the start and end times
   */
  getTimeSpan: function() {
    var times = this.provider.getKeySpan();
  },

  /**
   * set the cartocss for the current renderer
   */
  setCartoCSS: function(cartocss) {
    if (!this.renderer) throw new Error('renderer is not valid');
    var shader = new carto.RendererJS().render(cartocss);
    this.renderer.setShader(shader);

    // provider options
    var options = torque.common.TorqueLayer.optionsFromLayer(shader.findLayer({ name: 'Map' }));
    this.provider.setCartoCSS && this.provider.setCartoCSS(cartocss);
    if(this.provider.setOptions(options)) {
      this._reloadTiles();
    }

    torque.extend(this.options, options);

    // animator options
    if (options.animationDuration) {
      this.animator.duration(options.animationDuration);
    }

    this.redraw();
    return this;
  },

  /**
   * get active points for a step in active zoom
   * returns a list of bounding boxes [[] , [], []]
   * empty list if there is no active pixels
   */
  getActivePointsBBox: function(step) {
    var positions = [];
    for(var t in this._tiles) {
      var tile = this._tiles[t];
      positions = positions.concat(this.renderer.getActivePointsBBox(tile, step));
    }
    return positions;
  },

  /**
   * return the value for position relative to map coordinates. null for no value
   */
  getValueForPos: function(x, y, step) {
    step = step === undefined ? this.key: step;
    var t, tile, pos, value = null, xx, yy;
    for(t in this._tiles) {
      tile = this._tiles[t];
      pos = this.getTilePos(tile.coord);
      xx = x - pos.x;
      yy = y - pos.y;
      if (xx >= 0 && yy >= 0 && xx < this.renderer.TILE_SIZE && yy <= this.renderer.TILE_SIZE) {
        value = this.renderer.getValueFor(tile, step, xx, yy);
      }
      if (value !== null) {
        return value;
      }
    }
    return null;
  },

  invalidate: function() {
    this.provider.reload();
  }
});
<commit_msg>clears cache when setCartoCSS is called<commit_after>var carto = global.carto || require('carto');
var torque = require('../');

require('./canvas_layer');

/**
 * torque layer
 */
L.TorqueLayer = L.CanvasLayer.extend({

  providers: {
    'sql_api': torque.providers.json,
    'url_template': torque.providers.jsonarray,
    'windshaft': torque.providers.windshaft
  },

  renderers: {
    'point': torque.renderer.Point,
    'pixel': torque.renderer.Rectangle
  },

  initialize: function(options) {
    var self = this;
    if (!torque.isBrowserSupported()) {
      throw new Error("browser is not supported by torque");
    }
    options.tileLoader = true;
    this.key = 0;
    this.prevRenderedKey = 0;
    if (options.cartocss) {
      torque.extend(options, torque.common.TorqueLayer.optionsFromCartoCSS(options.cartocss));
    }

    options.resolution = options.resolution || 2;
    options.steps = options.steps || 100;
    options.visible = options.visible === undefined ? true: options.visible;
    this.hidden = !options.visible;

    this.animator = new torque.Animator(function(time) {
      var k = time | 0;
      if(self.key !== k) {
        self.setKey(k, { direct: true });
      }
    }, torque.extend(torque.clone(options), {
      onPause: function() {
        self.fire('pause');
      },
      onStop: function() {
        self.fire('stop');
      },
      onStart: function() {
        self.fire('play');
      }
    }));

    this.play = this.animator.start.bind(this.animator);
    this.stop = this.animator.stop.bind(this.animator);
    this.pause = this.animator.pause.bind(this.animator);
    this.toggle = this.animator.toggle.bind(this.animator);
    this.setDuration = this.animator.duration.bind(this.animator);
    this.isRunning = this.animator.isRunning.bind(this.animator);

    L.CanvasLayer.prototype.initialize.call(this, options);

    this.options.renderer = this.options.renderer || 'point';
    this.options.provider = this.options.provider || 'windshaft';

    options.ready = function() {
      self.fire("change:bounds", {
        bounds: self.provider.getBounds()
      });
      self.animator.steps(self.provider.getSteps());
      self.animator.rescale();
      self.fire('change:steps', {
        steps: self.provider.getSteps()
      });
      self.setKey(self.key);
    };

    this.provider = new this.providers[this.options.provider](options);
    this.renderer = new this.renderers[this.options.renderer](this.getCanvas(), options);

    this.renderer.on("allIconsLoaded", this.render.bind(this));

    // for each tile shown on the map request the data
    this.on('tileAdded', function(t) {
      var tileData = this.provider.getTileData(t, t.zoom, function(tileData) {
        // don't load tiles that are not being shown
        if (t.zoom !== self._map.getZoom()) return;
        self._tileLoaded(t, tileData);
        self._clearTileCaches();
        if (tileData) {
          self.redraw();
        }
      });
    }, this);

  },

  _clearTileCaches: function() {
    var t, tile;
    for(t in this._tiles) {
      tile = this._tiles[t];
      if (tile && tile._tileCache) {
        tile._tileCache = null;
      }
    }
  },

  _clearCaches: function() {
    this.renderer && this.renderer.clearSpriteCache();
    this._clearTileCaches();
  },

  onAdd: function (map) {
    map.on({
      'zoomend': this._clearCaches,
      'zoomstart': this._pauseOnZoom,
    }, this);

    map.on({
      'zoomend': this._resumeOnZoom
    }, this);
    L.CanvasLayer.prototype.onAdd.call(this, map);
  },

  onRemove: function(map) {
    this._removeTileLoader();
    map.off({
      'zoomend': this._clearCaches,
      'zoomstart': this._pauseOnZoom,
    }, this);
    map.off({
      'zoomend': this._resumeOnZoom
    }, this);
    L.CanvasLayer.prototype.onRemove.call(this, map);
  },

  _pauseOnZoom: function() {
    this.wasRunning = this.isRunning();
    if (this.wasRunning) {
      this.pause();
    }
  },

  _resumeOnZoom: function() {
    if (this.wasRunning) {
      this.play();
    }
  },

  hide: function() {
    if(this.hidden) return this;
    this.pause();
    this.clear();
    this.hidden = true;
    return this;
  },

  show: function() {
    if(!this.hidden) return this;
    this.hidden = false;
    this.play();
    return this;
  },

  setSQL: function(sql) {
    if (!this.provider || !this.provider.setSQL) {
      throw new Error("this provider does not support SQL");
    }
    this.provider.setSQL(sql);
    this._reloadTiles();
    return this;
  },

  setBlendMode: function(_) {
    this.renderer.setBlendMode(_);
    this.redraw();
  },

  setSteps: function(steps) {
    this.provider.setSteps(steps);
    this._reloadTiles();
  },

  setColumn: function(column, isTime) {
    this.provider.setColumn(column, isTime);
    this._reloadTiles();
  },

  getTimeBounds: function() {
    return this.provider && this.provider.getKeySpan();
  },

  clear: function() {
    var canvas = this.getCanvas();
    canvas.width = canvas.width;
  },

  /**
   * render the selectef key
   * don't call this function directly, it's called by
   * requestAnimationFrame. Use redraw to refresh it
   */
  render: function() {
    if(this.hidden) return;
    var t, tile, pos;
    var canvas = this.getCanvas();
    this.renderer.clearCanvas();
    var ctx = canvas.getContext('2d');

    for(t in this._tiles) {
      tile = this._tiles[t];
      if (tile) {
        // clear cache
        if (this.animator.isRunning()) {
          tile._tileCache = null;
        }

        pos = this.getTilePos(tile.coord);
        ctx.setTransform(1, 0, 0, 1, pos.x, pos.y);

        if (tile._tileCache) {
          // when the tile has a cached image just render it and avoid to render
          // all the points
          this.renderer._ctx.drawImage(tile._tileCache, 0, 0);
        } else {
          this.renderer.renderTile(tile, this.key);
        }
      }
    }
    this.renderer.applyFilters();

    // prepare caches if the animation is not running
    // don't cache if the key has just changed, this avoids to cache
    // when the user is dragging, it only cache when the map is still
    if (!this.animator.isRunning() && this.key === this.prevRenderedKey) {
      var tile_size = this.renderer.TILE_SIZE;
      for(t in this._tiles) {
        tile = this._tiles[t];
        if (tile && !tile._tileCache) {
          var c = tile._tileCache = document.createElement('canvas');
          c.width = c.height = tile_size;
          pos = this.getTilePos(tile.coord);
          // clip bounds, firefox raise an exception when try to get data from outside canvas
          var x = Math.max(0, pos.x)
          var y = Math.max(0, pos.y)
          var w = Math.min(tile_size, this.getCanvas().width - x);
          var h = Math.min(tile_size, this.getCanvas().height - y);
          if (w > 0 && h > 0) {
            c.getContext('2d').drawImage(this.getCanvas(), x, y, w, h, x - pos.x, y - pos.y, w, h);
          }
        }
      }
    }

    this.prevRenderedKey = this.key;

  },

  /**
   * set key to be shown. If it's a single value
   * it renders directly, if it's an array it renders
   * accumulated
   */
  setKey: function(key, options) {
    this.key = key;
    this.animator.step(key);
    this._clearTileCaches();
    this.redraw(options && options.direct);
    this.fire('change:time', { time: this.getTime(), step: this.key });
  },

  /**
   * helper function, does the same than ``setKey`` but only
   * accepts scalars.
   */
  setStep: function(time) {
    if(time === undefined || time.length !== undefined) {
      throw new Error("setTime only accept scalars");
    }
    this.setKey(time);
  },

  /**
   * transform from animation step to Date object
   * that contains the animation time
   *
   * ``step`` should be between 0 and ``steps - 1``
   */
  stepToTime: function(step) {
    var times = this.provider.getKeySpan();
    var time = times.start + (times.end - times.start)*(step/this.provider.getSteps());
    return new Date(time);
  },

  getStep: function() {
    return this.key;
  },

  /**
   * returns the animation time defined by the data
   * in the defined column. Date object
   */
  getTime: function() {
    return this.stepToTime(this.key);
  },

  /**
   * returns an object with the start and end times
   */
  getTimeSpan: function() {
    var times = this.provider.getKeySpan();
  },

  /**
   * set the cartocss for the current renderer
   */
  setCartoCSS: function(cartocss) {
    if (!this.renderer) throw new Error('renderer is not valid');
    var shader = new carto.RendererJS().render(cartocss);
    this.renderer.setShader(shader);

    // provider options
    var options = torque.common.TorqueLayer.optionsFromLayer(shader.findLayer({ name: 'Map' }));
    this.provider.setCartoCSS && this.provider.setCartoCSS(cartocss);
    if(this.provider.setOptions(options)) {
      this._reloadTiles();
    }

    torque.extend(this.options, options);

    // animator options
    if (options.animationDuration) {
      this.animator.duration(options.animationDuration);
    }
    this._clearCaches();
    this.redraw();
    return this;
  },

  /**
   * get active points for a step in active zoom
   * returns a list of bounding boxes [[] , [], []]
   * empty list if there is no active pixels
   */
  getActivePointsBBox: function(step) {
    var positions = [];
    for(var t in this._tiles) {
      var tile = this._tiles[t];
      positions = positions.concat(this.renderer.getActivePointsBBox(tile, step));
    }
    return positions;
  },

  /**
   * return the value for position relative to map coordinates. null for no value
   */
  getValueForPos: function(x, y, step) {
    step = step === undefined ? this.key: step;
    var t, tile, pos, value = null, xx, yy;
    for(t in this._tiles) {
      tile = this._tiles[t];
      pos = this.getTilePos(tile.coord);
      xx = x - pos.x;
      yy = y - pos.y;
      if (xx >= 0 && yy >= 0 && xx < this.renderer.TILE_SIZE && yy <= this.renderer.TILE_SIZE) {
        value = this.renderer.getValueFor(tile, step, xx, yy);
      }
      if (value !== null) {
        return value;
      }
    }
    return null;
  },

  invalidate: function() {
    this.provider.reload();
  }
});
<|endoftext|>


<commit_before>module.exports = function(grunt) {
	// Measures the time each task takes
	require('time-grunt')(grunt);

	// Load Grunt Configurations
	require('load-grunt-config')(grunt);

	// Load Tasks
	// This will load all grunt-* tasks that are in the package.json devDependencies
	require('load-grunt-tasks')(grunt, { scope: 'devDependencies' });

	/**
	 * Runs the phpdoc command to generate  PHPDocumentation.
	 *
	 * @return  {void}
	 */
	grunt.registerTask('phpdoc', 'Executes PHPDocumentor command.', function() {
		var exec = require('child_process').exec;

		exec('phpdoc', this.async());
	});

	// Register Tasks
	grunt.registerTask('default', [ 'watch' ]);
	grunt.registerTask('setup', [ '' ]);
	grunt.registerTask('conflict', [ 'sass:site', 'sass:ltie9', 'uglify:site' ]);
	grunt.registerTask('build', [ 'sass:siteBuild', 'sass:ltie9Build', 'sass:adminBuild', 'imagemin', 'uglify:build', 'autoprefixer', 'group_css_media_queries', 'cssmin', 'phpdoc' ]);
	grunt.registerTask('process', [ 'uglify:site', 'uglify:env', 'uglify:admin', 'copy', 'sass:site', 'sass:ltie9', 'sass:admin', 'autoprefixer', 'group_css_media_queries', 'cssmin' ]);
};
<commit_msg>Added imageoptim task to build process<commit_after>module.exports = function(grunt) {
	// Measures the time each task takes
	require('time-grunt')(grunt);

	// Load Grunt Configurations
	require('load-grunt-config')(grunt);

	// Load Tasks
	// This will load all grunt-* tasks that are in the package.json devDependencies
	require('load-grunt-tasks')(grunt, { scope: 'devDependencies' });

	/**
	 * Runs the phpdoc command to generate  PHPDocumentation.
	 *
	 * @return  {void}
	 */
	grunt.registerTask('phpdoc', 'Executes PHPDocumentor command.', function() {
		var exec = require('child_process').exec;

		exec('phpdoc', this.async());
	});

	// Register Tasks
	grunt.registerTask('default', [ 'watch' ]);
	grunt.registerTask('setup', [ '' ]);
	grunt.registerTask('conflict', [ 'sass:site', 'sass:ltie9', 'uglify:site' ]);
	grunt.registerTask('build', [ 'sass:siteBuild', 'sass:ltie9Build', 'sass:adminBuild', 'imageoptim:all', 'uglify:build', 'autoprefixer', 'group_css_media_queries', 'cssmin', 'phpdoc' ]);
	grunt.registerTask('process', [ 'uglify:site', 'uglify:env', 'uglify:admin', 'copy', 'sass:site', 'sass:ltie9', 'sass:admin', 'autoprefixer', 'group_css_media_queries', 'cssmin' ]);
};
<|endoftext|>


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

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    connect: {
      server: {
        options: {
          hostname: '127.0.0.1',
          base: '.',
          port: 8080
        }
      }
    },

    jshint: {
      files: ['src/*.js'],
      options: {
        jshintrc: '.jshintrc'
      }
    },

    uglify: {
      grouped: {
        options: {
          mangle: false,
          compress: false,
          beautify: true
        },
        files: {
          'build/date-enhancer.js': ['src/*.js']
        }
      },
      minified: {
        options: {
          mangle: true,
          compress: {
            sequences: true,
            properties: true,
            dead_code: true,
            booleans: true,
            loops: true,
            if_return: true,
            join_vars: true,
            drop_console: true,
          }
        },
        files: {
          'build/date-enhancer.min.js': ['src/*.js']
        }
      }
    },

    jasmine : {
      src : 'src/*.js',
      options : {
        specs : 'spec/*.js'
      }
    },

    watch: {
      scripts: {
        files: ['src/*', 'spec/*', 'Gruntfile.js'],
        tasks: ['default'],
        options: {
          interrupt: true,
        },
      },
    },

    karma: {
      options: {
        frameworks: ['jasmine'],
        files: ['spec/*.js', 'src/*.js', 'spec/env/' + process.env.tz + '.js'],
      },
      unit: {
        browsers: ['PhantomJS', 'Safari', 'Firefox'],
      },
      travis: {
        browsers: ['PhantomJS', 'Firefox'],
        singleRun: true,
        reporters: ['coverage'],
        coverageReporter: {
          type: "lcov",
          dir: "coverage/"
        },
        preprocessors: {
          "src/*js": "coverage"
        },
      }
    },

    coveralls: {
      options: {
        coverageDir: 'coverage/',
        force: true,
        recursive: true
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-karma-coveralls');

  grunt.registerTask('test', ['jshint', 'karma:travis']);
  grunt.registerTask('default', ['test', 'uglify', 'coveralls']);
};
<commit_msg>Test with "Europe/Paris" if $tz is not defined<commit_after>module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    connect: {
      server: {
        options: {
          hostname: '127.0.0.1',
          base: '.',
          port: 8080
        }
      }
    },

    jshint: {
      files: ['src/*.js'],
      options: {
        jshintrc: '.jshintrc'
      }
    },

    uglify: {
      grouped: {
        options: {
          mangle: false,
          compress: false,
          beautify: true
        },
        files: {
          'build/date-enhancer.js': ['src/*.js']
        }
      },
      minified: {
        options: {
          mangle: true,
          compress: {
            sequences: true,
            properties: true,
            dead_code: true,
            booleans: true,
            loops: true,
            if_return: true,
            join_vars: true,
            drop_console: true,
          }
        },
        files: {
          'build/date-enhancer.min.js': ['src/*.js']
        }
      }
    },

    jasmine : {
      src : 'src/*.js',
      options : {
        specs : 'spec/*.js'
      }
    },

    watch: {
      scripts: {
        files: ['src/*', 'spec/*', 'Gruntfile.js'],
        tasks: ['default'],
        options: {
          interrupt: true,
        },
      },
    },

    karma: {
      options: {
        frameworks: ['jasmine'],
        files: ['spec/*.js', 'src/*.js', 'spec/env/' + (process.env.tz ? process.env.tz : 'Europe/Paris') + '.js'],
      },
      unit: {
        browsers: ['PhantomJS', 'Safari', 'Firefox'],
      },
      travis: {
        browsers: ['PhantomJS', 'Firefox'],
        singleRun: true,
        reporters: ['coverage'],
        coverageReporter: {
          type: "lcov",
          dir: "coverage/"
        },
        preprocessors: {
          "src/*js": "coverage"
        },
      }
    },

    coveralls: {
      options: {
        coverageDir: 'coverage/',
        force: true,
        recursive: true
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-karma-coveralls');

  grunt.registerTask('test', ['jshint', 'karma:travis']);
  grunt.registerTask('default', ['test', 'uglify', 'coveralls']);
};
<|endoftext|>


<commit_before>var path = require('path');
var assert = require('assert');
global.ProjRequire = function(module) {
	return require(path.join(__dirname, '/../' + module));
}
var EvalParser = ProjRequire('app/lib/modBrowser/helperEvalParser.js');
describe('testEvalParser', function() {
  this.timeout(15000);
  function testParse(str, expected, ctx) {
		var parser = new EvalParser();
		var result = parser.parse(str, ctx);
		assert.equal(result, expected);
  }
  function testThrow(str, expected, ctx) {
		var parser = new EvalParser();
		var exception = false;
		try {
			var result = parser.parse(str, ctx);
		} catch (e) {
			exception = true;
		}
		assert.equal(exception, true);
  }

  describe('#evaluate', function() {

	it('able to eval single placeholder', function(done) {
		var str = 'My name is fyhao and {{age}} years old.';
		var parser = new EvalParser();
		var result = parser.evaluate(str);
		assert.equal(result.length, 1);
		assert.equal(result[0], 'age');
		done();
    });
	it('able to eval multiple placeholder', function(done) {
		var str = 'My name is {{name}} and {{age}} years old.';
		var parser = new EvalParser();
		var result = parser.evaluate(str);
		assert.equal(result.length, 2);
		assert.equal(result[0], 'name');
		assert.equal(result[1], 'age');
		done();
    });
	it('able to eval single placeholder with another sub placeholder inside code', function(done) {
		var str = "My name is fyhao and {{'pre {{age}} post'}} years old.";
		var parser = new EvalParser();
		var result = parser.evaluate(str);
		assert.equal(result.length, 1);
		assert.equal(result[0], "'pre {{age}} post'");
		done();
    });
	it('able to eval multi placeholder with another sub placeholder inside code', function(done) {
		var str = "My name is {{name}} and {{'pre {{age}} post'}} years old.";
		var parser = new EvalParser();
		var result = parser.evaluate(str);
		assert.equal(result.length, 2);
		assert.equal(result[0], 'name');
		assert.equal(result[1], "'pre {{age}} post'");
		done();
    });
  });

 describe('#evalCode', function() {
	it('able to eval a variable', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode('age', {age:123});
		assert.equal(result, '123');
		done();
    });
	it('able to eval JS operations', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode('3+6', {});
		assert.equal(result, '9');
		done();
    });
	it('able to eval string', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode("'fyhao'", {});
		assert.equal(result, 'fyhao');
		done();
    });
	it('able to eval variable and string', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode("'fyhao is ' + age + ' years old'", {age:123});
		assert.equal(result, 'fyhao is 123 years old');
		done();
    });
  });

  describe('#Basic Invalid Cases', function() {
	it('able to evaluate a str without {{xxx}} placeholder, to return original str', function(done) {
		var str = 'My name is fyhao and 123 years old.';
		testParse(str, str, {});
		done();
    });
	it('able to evaluate a str with single {xxxx} placeholder which is not the expected JS expression bracket, should return original str', function(done) {
		var str = 'My name is fyhao and {age} years old.';
		testParse(str, str, {age:123});
		done();
    });
	it('able to evaluate a str with multiple {xxxx} placeholder which is not the expected JS expression bracket, should return original str', function(done) {
		var str = 'My name is {name}} and {age} years old.';
		testParse(str, str, {age:123,name:'fyhao'});
		done();
    });
  });

  describe('#Basic Valid Cases', function() {

	it('able to evaluate a str with single {{xxx}} placeholder of variable', function(done) {
		var str = 'My name is fyhao and {{age}} years old.';
		var exp = 'My name is fyhao and 123 years old.';
		testParse(str, exp, {age:123});
		done();
    });
	it('able to evaluate a str with multiple {{xxx}} placeholder of variable', function(done) {
		var str = 'My name is {{name}} and {{age}} years old.';
		var exp = 'My name is fyhao and 123 years old.';
		testParse(str, exp, {age:123,name:'fyhao'});
		done();
    });
	it('able to evaluate a str with a {{xx}} placeholder of JS Operations', function(done) {
		var str = 'My name is fyhao and {{100+23}} years old.';
		var exp = 'My name is fyhao and 123 years old.';
		testParse(str, exp, {});
		done();
    });
	it('able to evaluate a str with multiple {{xx}} placeholder of JS Operations', function(done) {
		var str = "My name is {{'fyhao'}} and {{100+23}} years old.";
		var exp = 'My name is fyhao and 123 years old.';
		testParse(str, exp, {});
		done();
    });
	it('able to evaluate a str with multiple {{xx}} placeholder of JS Operation plus variables', function(done) {
		var str = "My name is {{'fyhao'}} and {{100+23}} {{criteria}}.";
		var exp = 'My name is fyhao and 123 years old.';
		testParse(str, exp, {criteria:'years old'});
		done();
    });

  });

  describe('#Intermediate Cases', function() {

	it('Testing on conditional statements', function(done) {
		testParse('I am {{age > 60 ? "old" : "young"}}', 'I am old', {age:123});
		testParse('I am {{if(age>60) return "old"; else return "young";}}', 'I am old', {age:123});
		testParse('I am {{if(age>60) {return "old"} else {return "young"} }}', 'I am old', {age:123});
		testParse('I am {{if(age>60 && age<=80) {return "old"} else {return "very old"} }}', 'I am very old', {age:123});
		testParse('I am {{if(age>60 && age<=80) {return "old"} else {return "very old"} }}', 'I am very old', {age:60});
		testParse('I am {{if(age>60 && age<=80) {return "old"} else {return "very old"} }}', 'I am old', {age:80});
		testParse('I am {{if(age>60 && age<=80) {return "old"} else {return "very old"} }}', 'I am very old', {age:59});
		testParse('I am {{if(age>60 && age<=80) {return "old"} else {return "very old"} }}', 'I am very old', {age:81});
		done();
    });
	it('Testing on while statements', function(done) {
		testParse('I am {{t=1;while(age>120){age-=50;t+=1;} return "age:"+age+";" + t}}', 'I am age:73;2', {age:123});
		done();
    });
	it('Testing on comment statements', function(done) {
		testParse('I am {{/*some comments return age*/return age}}', 'I am 123', {age:123});
		testParse('I am {{//some comments return age\nreturn age}}', 'I am 123', {age:123});
		done();
    });
  });

  describe('#Exception Cases', function() {

	it('Exception testing', function(done) {
		testThrow('I am {{if(age>60) {return "old"} else {return "young"}}}', 'I am old', {age:123});
		done();
    });
  });
});<commit_msg>more test case in evalparser<commit_after>var path = require('path');
var assert = require('assert');
global.ProjRequire = function(module) {
	return require(path.join(__dirname, '/../' + module));
}
var EvalParser = ProjRequire('app/lib/modBrowser/helperEvalParser.js');
describe('testEvalParser', function() {
  this.timeout(15000);
  function testParse(str, expected, ctx) {
		var parser = new EvalParser();
		var result = parser.parse(str, ctx);
		assert.equal(result, expected);
  }
  function testThrow(str, expected, ctx) {
		var parser = new EvalParser();
		var exception = false;
		try {
			var result = parser.parse(str, ctx);
		} catch (e) {
			exception = true;
		}
		assert.equal(exception, true);
  }

  describe('#evaluate', function() {

	it('able to eval single placeholder', function(done) {
		var str = 'My name is fyhao and {{age}} years old.';
		var parser = new EvalParser();
		var result = parser.evaluate(str);
		assert.equal(result.length, 1);
		assert.equal(result[0], 'age');
		done();
    });
	it('able to eval multiple placeholder', function(done) {
		var str = 'My name is {{name}} and {{age}} years old.';
		var parser = new EvalParser();
		var result = parser.evaluate(str);
		assert.equal(result.length, 2);
		assert.equal(result[0], 'name');
		assert.equal(result[1], 'age');
		done();
    });
	it('able to eval single placeholder with another sub placeholder inside code', function(done) {
		var str = "My name is fyhao and {{'pre {{age}} post'}} years old.";
		var parser = new EvalParser();
		var result = parser.evaluate(str);
		assert.equal(result.length, 1);
		assert.equal(result[0], "'pre {{age}} post'");
		done();
    });
	it('able to eval two placeholder with another sub placeholder inside code', function(done) {
		var str = "My name is {{name}} and {{'pre {{age}} post'}} years old.";
		var parser = new EvalParser();
		var result = parser.evaluate(str);
		assert.equal(result.length, 2);
		assert.equal(result[0], 'name');
		assert.equal(result[1], "'pre {{age}} post'");
		done();
    });
	it('able to eval multi placeholder with another sub placeholder inside code', function(done) {
		var str = "My name is {{name}} and {{'pre {{age}} post'}} years {{'pre2 {{age2}} post2'}}.";
		var parser = new EvalParser();
		var result = parser.evaluate(str);
		assert.equal(result.length, 3);
		assert.equal(result[0], 'name');
		assert.equal(result[1], "'pre {{age}} post'");
		assert.equal(result[2], "'pre2 {{age2}} post2'");
		done();
    });
  });

 describe('#evalCode', function() {
	it('able to eval a variable', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode('age', {age:123});
		assert.equal(result, '123');
		done();
    });
	it('able to eval JS operations', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode('3+6', {});
		assert.equal(result, '9');
		done();
    });
	it('able to eval string', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode("'fyhao'", {});
		assert.equal(result, 'fyhao');
		done();
    });
	it('able to eval variable and string', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode("'fyhao is ' + age + ' years old'", {age:123});
		assert.equal(result, 'fyhao is 123 years old');
		done();
    });
	it('able to eval object', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode("'fyhao is ' + y.age + ' years old'", {y:{age:123}});
		assert.equal(result, 'fyhao is 123 years old');
		done();
    });
	it('able to eval array', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode("'fyhao is ' + y[1] + ' years old'", {y:[123,456]});
		assert.equal(result, 'fyhao is 456 years old');
		done();
    });
	it('able to eval a variable with return', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode('return age', {age:123});
		assert.equal(result, '123');
		done();
    });
	it('able to eval string with return', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode("return 'fyhao'", {});
		assert.equal(result, 'fyhao');
		done();
    });
	it('able to eval JS operations with return', function(done) {
		var parser = new EvalParser();
		var result = parser.evalCode('return 3+6', {});
		assert.equal(result, '9');
		done();
    });
  });

  describe('#Basic Invalid Cases', function() {
	it('able to evaluate a str without {{xxx}} placeholder, to return original str', function(done) {
		var str = 'My name is fyhao and 123 years old.';
		testParse(str, str, {});
		done();
    });
	it('able to evaluate a str with single {xxxx} placeholder which is not the expected JS expression bracket, should return original str', function(done) {
		var str = 'My name is fyhao and {age} years old.';
		testParse(str, str, {age:123});
		done();
    });
	it('able to evaluate a str with multiple {xxxx} placeholder which is not the expected JS expression bracket, should return original str', function(done) {
		var str = 'My name is {name}} and {age} years old.';
		testParse(str, str, {age:123,name:'fyhao'});
		done();
    });
  });

  describe('#Basic Valid Cases', function() {

	it('able to evaluate a str with single {{xxx}} placeholder of variable', function(done) {
		var str = 'My name is fyhao and {{age}} years old.';
		var exp = 'My name is fyhao and 123 years old.';
		testParse(str, exp, {age:123});
		done();
    });
	it('able to evaluate a str with multiple {{xxx}} placeholder of variable', function(done) {
		var str = 'My name is {{name}} and {{age}} years old.';
		var exp = 'My name is fyhao and 123 years old.';
		testParse(str, exp, {age:123,name:'fyhao'});
		done();
    });
	it('able to evaluate a str with a {{xx}} placeholder of JS Operations', function(done) {
		var str = 'My name is fyhao and {{100+23}} years old.';
		var exp = 'My name is fyhao and 123 years old.';
		testParse(str, exp, {});
		done();
    });
	it('able to evaluate a str with multiple {{xx}} placeholder of JS Operations', function(done) {
		var str = "My name is {{'fyhao'}} and {{100+23}} years old.";
		var exp = 'My name is fyhao and 123 years old.';
		testParse(str, exp, {});
		done();
    });
	it('able to evaluate a str with multiple {{xx}} placeholder of JS Operation plus variables', function(done) {
		var str = "My name is {{'fyhao'}} and {{100+23}} {{criteria}}.";
		var exp = 'My name is fyhao and 123 years old.';
		testParse(str, exp, {criteria:'years old'});
		done();
    });

  });

  describe('#Intermediate Cases', function() {

	it('Testing on conditional statements', function(done) {
		testParse('I am {{age > 60 ? "old" : "young"}}', 'I am old', {age:123});
		testParse('I am {{if(age>60) return "old"; else return "young";}}', 'I am old', {age:123});
		testParse('I am {{if(age>60) {return "old"} else {return "young"} }}', 'I am old', {age:123});
		testParse('I am {{if(age>60 && age<=80) {return "old"} else {return "very old"} }}', 'I am very old', {age:123});
		testParse('I am {{if(age>60 && age<=80) {return "old"} else {return "very old"} }}', 'I am very old', {age:60});
		testParse('I am {{if(age>60 && age<=80) {return "old"} else {return "very old"} }}', 'I am old', {age:80});
		testParse('I am {{if(age>60 && age<=80) {return "old"} else {return "very old"} }}', 'I am very old', {age:59});
		testParse('I am {{if(age>60 && age<=80) {return "old"} else {return "very old"} }}', 'I am very old', {age:81});
		done();
    });
	it('Testing on while statements', function(done) {
		testParse('I am {{t=1;while(age>120){age-=50;t+=1;} return "age:"+age+";" + t}}', 'I am age:73;2', {age:123});
		done();
    });
	it('Testing on comment statements', function(done) {
		testParse('I am {{/*some comments return age*/return age}}', 'I am 123', {age:123});
		testParse('I am {{//some comments return age\nreturn age}}', 'I am 123', {age:123});
		done();
    });
  });

  describe('#Exception Cases', function() {

	it('Exception testing', function(done) {
		testThrow('I am {{if(age>60) {return "old"} else {return "young"}}}', 'I am old', {age:123});
		done();
    });
  });
});<|endoftext|>


<commit_before>var fs = require('fs');
var cp = require('child_process');
var rimraf = require('rimraf');

var LINT = true;
var COVERALLS = true;

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      options: { // see http://www.jshint.com/docs/options/
        node: true,
        esnext: true,
        bitwise: true,
        camelcase: true,
        curly: true,
        eqeqeq: true,
        immed: true,
        indent: 2,
        latedef: true,
        newcap: true,
        noarg: true,
        undef: true,
        trailing: true,
        smarttabs: true
      },
      build: ['Gruntfile.js'],
      lib: ['index.js', 'lib/**/*.js'],
      test: {
        options: {
          '-W030': true, // Expected an assignment or function call and instead saw an expression: ...to.be.true
          globals: {
            describe: true,
            it: true,
            assert: true,
            expect: true
          }
        },
        files: {
          src: ['test/**/*.js']
        }
      }
    },
    mochaTest: {
      lib: {
        options: {
          ui: 'bdd',
          require: ['test/init.js']
        },
        src: ['test/**/*.js', '!test/init.js']
      }
    },
    replace: {
      results: {
        src: ['test-results/coverage.html', 'test-results/lcov.txt'],
        overwrite: true,
        replacements: [
          {
            // make coverage paths relative
            from: process.cwd().replace(/\\/g, '/') + '/',
            to: ''
          }
        ]
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.loadNpmTasks('grunt-text-replace');

  grunt.registerTask('test', 'Build, generate coverage, run tests.', function() {
    if (fs.existsSync('test-results')) {
      rimraf.sync('test-results');
    }
    fs.mkdirSync('test-results');
    if (process.env.TRAVIS) {
      if (COVERALLS) {
        grunt.config.set('mochaTest.lib.options.reporter', 'mocha-lcov-reporter');
        grunt.config.set('mochaTest.coverage.options.reporter', 'mocha-lcov-reporter');
        grunt.config.set('mochaTest.coverage.options.quiet', 'true');
        grunt.config.set('mochaTest.coverage.options.captureFile', 'test-results/lcov.txt');
        grunt.task.run(['build', 'mochaTest', 'replace:results', 'coveralls']);
      } else {
        grunt.config.set('mochaTest.lib.options.reporter', 'spec');
        grunt.task.run(['build', 'mochaTest']);
      }
    } else {
      process.env.multi = 'spec=- mocha-slow-reporter=test-results/slow.txt html-cov=test-results/coverage.html mocha-lcov-reporter=test-results/lcov.txt';
      grunt.config.set('mochaTest.lib.options.reporter', 'mocha-multi');

      // needed so that mocha-multi doesn't kill the process
      var program = require('mocha/node_modules/commander');
      program.name = 'mocha';
      program.exit = false;

      grunt.task.run(['build', 'mochaTest', 'replace:results']);
    }
  });

  grunt.registerTask('coveralls', 'Push to Coveralls.', function() {
    this.requires('mochaTest');
    var done = this.async();
    cp.exec('cat ../test-results/lcov.txt | ../node_modules/.bin/coveralls', { cwd: './' }, function(err, stdout, stderr) {
      grunt.log.writeln(stdout + stderr);
      done(err);
    });
  });

  grunt.registerTask('build', function() {
    if (LINT) {
      grunt.task.run('jshint');
    }
  });

  grunt.registerTask('default', ['build']);
};
<commit_msg>Fix Coveralls task, really<commit_after>var fs = require('fs');
var cp = require('child_process');
var rimraf = require('rimraf');

var LINT = true;
var COVERALLS = true;

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      options: { // see http://www.jshint.com/docs/options/
        node: true,
        esnext: true,
        bitwise: true,
        camelcase: true,
        curly: true,
        eqeqeq: true,
        immed: true,
        indent: 2,
        latedef: true,
        newcap: true,
        noarg: true,
        undef: true,
        trailing: true,
        smarttabs: true
      },
      build: ['Gruntfile.js'],
      lib: ['index.js', 'lib/**/*.js'],
      test: {
        options: {
          '-W030': true, // Expected an assignment or function call and instead saw an expression: ...to.be.true
          globals: {
            describe: true,
            it: true,
            assert: true,
            expect: true
          }
        },
        files: {
          src: ['test/**/*.js']
        }
      }
    },
    mochaTest: {
      lib: {
        options: {
          ui: 'bdd',
          require: ['test/init.js']
        },
        src: ['test/**/*.js', '!test/init.js']
      }
    },
    replace: {
      results: {
        src: ['test-results/coverage.html', 'test-results/lcov.txt'],
        overwrite: true,
        replacements: [
          {
            // make coverage paths relative
            from: process.cwd().replace(/\\/g, '/') + '/',
            to: ''
          }
        ]
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.loadNpmTasks('grunt-text-replace');

  grunt.registerTask('test', 'Build, generate coverage, run tests.', function() {
    if (fs.existsSync('test-results')) {
      rimraf.sync('test-results');
    }
    fs.mkdirSync('test-results');
    if (process.env.TRAVIS) {
      if (COVERALLS) {
        grunt.config.set('mochaTest.lib.options.reporter', 'mocha-lcov-reporter');
        grunt.config.set('mochaTest.coverage.options.reporter', 'mocha-lcov-reporter');
        grunt.config.set('mochaTest.coverage.options.quiet', 'true');
        grunt.config.set('mochaTest.coverage.options.captureFile', 'test-results/lcov.txt');
        grunt.task.run(['build', 'mochaTest', 'replace:results', 'coveralls']);
      } else {
        grunt.config.set('mochaTest.lib.options.reporter', 'spec');
        grunt.task.run(['build', 'mochaTest']);
      }
    } else {
      process.env.multi = 'spec=- mocha-slow-reporter=test-results/slow.txt html-cov=test-results/coverage.html mocha-lcov-reporter=test-results/lcov.txt';
      grunt.config.set('mochaTest.lib.options.reporter', 'mocha-multi');

      // needed so that mocha-multi doesn't kill the process
      var program = require('mocha/node_modules/commander');
      program.name = 'mocha';
      program.exit = false;

      grunt.task.run(['build', 'mochaTest', 'replace:results']);
    }
  });

  grunt.registerTask('coveralls', 'Push to Coveralls.', function() {
    this.requires('mochaTest');
    var done = this.async();
    cp.exec('cat ./test-results/lcov.txt | ./node_modules/.bin/coveralls', { cwd: './' }, function(err, stdout, stderr) {
      grunt.log.writeln(stdout + stderr);
      done(err);
    });
  });

  grunt.registerTask('build', function() {
    if (LINT) {
      grunt.task.run('jshint');
    }
  });

  grunt.registerTask('default', ['build']);
};
<|endoftext|>


<commit_before>// Generated on 2013-03-04 using generator-webapp 0.1.5
'use strict';
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var mountFolder = function (connect, dir) {
    return connect.static(require('path').resolve(dir));
};

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
    // load all grunt tasks
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    // configurable paths
    var yeomanConfig = {
        app: 'app',
        dist: 'dist'
    };

    grunt.initConfig({
        yeoman: yeomanConfig,
        watch: {

            compass: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
                tasks: ['compass']
            },
            livereload: {
                files: [
                    '<%= yeoman.app %>/*.html',
                    '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css',
                    '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
                    '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,webp}'
                ],
                tasks: ['livereload']
            }
        },
        connect: {
            options: {
                port: 9000,
                // change this to '0.0.0.0' to access the server from outside
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    middleware: function (connect) {
                        return [
                            lrSnippet,
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, 'app'),
                            mountFolder(connect, '.'),
                            mountFolder(connect, 'test')
                        ];
                    }
                }
            },
            test: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, '.'),
                            mountFolder(connect, 'test')
                        ];
                    }
                }
            },
            dist: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, 'dist')
                        ];
                    }
                }
            }
        },
        open: {
            server: {
                path: 'http://localhost:<%= connect.options.port %>'
            }
        },
        clean: {
            dist: ['.tmp', '<%= yeoman.dist %>/*'],
            server: '.tmp'
        },
        jshint: {
            options: {
                jshintrc: '.jshintrc'
            },
            all: [
                'Gruntfile.js',
                '<%= yeoman.app %>/scripts/{,*/}*.js',
                '!<%= yeoman.app %>/scripts/vendor/*',
                'test/spec/{,*/}*.js'
            ]
        },
        mocha: {
            all: {
                options: {
                    run: false,
                    reporter: 'spec',
                    urls: ['http://localhost:<%= connect.options.port %>/test/index.html']
                }
            }
        },
        compass: {
            options: {
                sassDir: '<%= yeoman.app %>/styles',
                cssDir: '.tmp/styles',
                imagesDir: '<%= yeoman.app %>/images',
                javascriptsDir: '<%= yeoman.app %>/scripts',
                fontsDir: '<%= yeoman.app %>/styles/fonts',
                importPath: 'app/components',
                relativeAssets: true
            },
            dist: {},
            server: {
                options: {
                    debugInfo: true
                }
            }
        },
        // not used since Uglify task does concat,
        // but still available if needed
        /*concat: {
            dist: {}
        },*/
        requirejs: {
            dist: {
                // Options: https://github.com/jrburke/r.js/blob/master/build/example.build.js
                options: {
                    // `name` and `out` is set by grunt-usemin
                    baseUrl: 'app/scripts',
                    optimize: 'none',
                    // TODO: Figure out how to make sourcemaps work with grunt-usemin
                    // https://github.com/yeoman/grunt-usemin/issues/30
                    //generateSourceMaps: true,
                    // required to support SourceMaps
                    // http://requirejs.org/docs/errors.html#sourcemapcomments
                    preserveLicenseComments: false,
                    useStrict: true,
                    wrap: true,
                    //uglify2: {} // https://github.com/mishoo/UglifyJS2
                    mainConfigFile: yeomanConfig.app + '/scripts/config.js'
                }
            }
        },
        useminPrepare: {
            html: '<%= yeoman.app %>/index.html',
            options: {
                dest: '<%= yeoman.dist %>'
            }
        },
        usemin: {
            html: ['<%= yeoman.dist %>/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
            options: {
                dirs: ['<%= yeoman.dist %>']
            }
        },
        imagemin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>/images',
                    src: '{,*/}*.{png,jpg,jpeg}',
                    dest: '<%= yeoman.dist %>/images'
                }]
            }
        },
        cssmin: {
            dist: {
                files: {
                    '<%= yeoman.dist %>/styles/main.css': [
                        '.tmp/styles/{,*/}*.css',
                        '<%= yeoman.app %>/styles/{,*/}*.css'
                    ]
                }
            }
        },
        htmlmin: {
            dist: {
                options: {
                    /*removeCommentsFromCDATA: true,
                    // https://github.com/yeoman/grunt-usemin/issues/44
                    //collapseWhitespace: true,
                    collapseBooleanAttributes: true,
                    removeAttributeQuotes: true,
                    removeRedundantAttributes: true,
                    useShortDoctype: true,
                    removeEmptyAttributes: true,
                    removeOptionalTags: true*/
                },
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>',
                    src: '*.html',
                    dest: '<%= yeoman.dist %>'
                }]
            }
        },
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%= yeoman.app %>',
                    dest: '<%= yeoman.dist %>',
                    src: [
                        '*.{ico,txt}',
                        '.htaccess'
                    ]
                }]
            }
        },
        bower: {
            all: {
                rjsConfig: '<%= yeoman.app %>/scripts/config.js'
            }
        },
        concurrent: {
            server: [
                'compass:server'
            ],
            test: [
                'compass'
            ],
            dist: [
                'compass:dist',
                'imagemin',
                'htmlmin'
            ]
        }
    });

    grunt.renameTask('regarde', 'watch');

    grunt.registerTask('server', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'concurrent:server',
            'livereload-start',
            'connect:livereload',
            'open',
            'watch'
        ]);
    });

    grunt.registerTask('test', [
        'clean:server',

        'concurrent:test',
        'connect:test',
        'mocha'
    ]);

    grunt.registerTask('build', [
        'clean:dist',
        'concurrent:dist',
        'useminPrepare',
        'requirejs',
        'imagemin',
        'htmlmin',
        'concat',
        'cssmin',
//        'uglify',
        'copy',
        'usemin'
    ]);

    grunt.registerTask('default', [
        'jshint',
        'test',
        'build'
    ]);
};
<commit_msg>updated watch stuffs<commit_after>// Generated on 2013-03-04 using generator-webapp 0.1.5
'use strict';
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var mountFolder = function (connect, dir) {
    return connect.static(require('path').resolve(dir));
};

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
    // load all grunt tasks
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    // configurable paths
    var yeomanConfig = {
        app: 'app',
        dist: 'dist'
    };

    grunt.initConfig({
        yeoman: yeomanConfig,
        watch: {

            compass: {
                files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
                tasks: ['compass']
            },
            livereload: {
                files: [
                    '<%= yeoman.app %>/*.html',
                    '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css',
                    '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
                    '{.tmp,<%= yeoman.app %>}/scripts/templates/{,*/}*.html',
                    '{.tmp,<%= yeoman.app %>}/test/spec/{,*/}*.js',
                    '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,webp}'
                ],
                tasks: ['livereload']
            }
        },
        connect: {
            options: {
                port: 9000,
                // change this to '0.0.0.0' to access the server from outside
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    middleware: function (connect) {
                        return [
                            lrSnippet,
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, 'app'),
                            mountFolder(connect, '.')
                        ];
                    }
                }
            },
            test: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, '.tmp'),
                            mountFolder(connect, '.'),
                            mountFolder(connect, 'test')
                        ];
                    }
                }
            },
            dist: {
                options: {
                    middleware: function (connect) {
                        return [
                            mountFolder(connect, 'dist')
                        ];
                    }
                }
            }
        },
        open: {
            server: {
                path: 'http://localhost:<%= connect.options.port %>'
            }
        },
        clean: {
            dist: ['.tmp', '<%= yeoman.dist %>/*'],
            server: '.tmp'
        },
        jshint: {
            options: {
                jshintrc: '.jshintrc'
            },
            all: [
                'Gruntfile.js',
                '<%= yeoman.app %>/scripts/{,*/}*.js',
                '!<%= yeoman.app %>/scripts/vendor/*',
                'test/spec/{,*/}*.js'
            ]
        },
        mocha: {
            all: {
                options: {
                    run: false,
                    reporter: 'spec',
                    urls: ['http://localhost:<%= connect.options.port %>/test/index.html']
                }
            }
        },
        compass: {
            options: {
                sassDir: '<%= yeoman.app %>/styles',
                cssDir: '.tmp/styles',
                imagesDir: '<%= yeoman.app %>/images',
                javascriptsDir: '<%= yeoman.app %>/scripts',
                fontsDir: '<%= yeoman.app %>/styles/fonts',
                importPath: 'app/components',
                relativeAssets: true
            },
            dist: {},
            server: {
                options: {
                    debugInfo: true
                }
            }
        },
        // not used since Uglify task does concat,
        // but still available if needed
        /*concat: {
            dist: {}
        },*/
        requirejs: {
            dist: {
                // Options: https://github.com/jrburke/r.js/blob/master/build/example.build.js
                options: {
                    // `name` and `out` is set by grunt-usemin
                    baseUrl: 'app/scripts',
                    optimize: 'none',
                    // TODO: Figure out how to make sourcemaps work with grunt-usemin
                    // https://github.com/yeoman/grunt-usemin/issues/30
                    //generateSourceMaps: true,
                    // required to support SourceMaps
                    // http://requirejs.org/docs/errors.html#sourcemapcomments
                    preserveLicenseComments: false,
                    useStrict: true,
                    wrap: true,
                    //uglify2: {} // https://github.com/mishoo/UglifyJS2
                    mainConfigFile: yeomanConfig.app + '/scripts/config.js'
                }
            }
        },
        useminPrepare: {
            html: '<%= yeoman.app %>/index.html',
            options: {
                dest: '<%= yeoman.dist %>'
            }
        },
        usemin: {
            html: ['<%= yeoman.dist %>/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
            options: {
                dirs: ['<%= yeoman.dist %>']
            }
        },
        imagemin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>/images',
                    src: '{,*/}*.{png,jpg,jpeg}',
                    dest: '<%= yeoman.dist %>/images'
                }]
            }
        },
        cssmin: {
            dist: {
                files: {
                    '<%= yeoman.dist %>/styles/main.css': [
                        '.tmp/styles/{,*/}*.css',
                        '<%= yeoman.app %>/styles/{,*/}*.css'
                    ]
                }
            }
        },
        htmlmin: {
            dist: {
                options: {
                    /*removeCommentsFromCDATA: true,
                    // https://github.com/yeoman/grunt-usemin/issues/44
                    //collapseWhitespace: true,
                    collapseBooleanAttributes: true,
                    removeAttributeQuotes: true,
                    removeRedundantAttributes: true,
                    useShortDoctype: true,
                    removeEmptyAttributes: true,
                    removeOptionalTags: true*/
                },
                files: [{
                    expand: true,
                    cwd: '<%= yeoman.app %>',
                    src: '*.html',
                    dest: '<%= yeoman.dist %>'
                }]
            }
        },
        copy: {
            dist: {
                files: [{
                    expand: true,
                    dot: true,
                    cwd: '<%= yeoman.app %>',
                    dest: '<%= yeoman.dist %>',
                    src: [
                        '*.{ico,txt}',
                        '.htaccess'
                    ]
                }]
            }
        },
        bower: {
            all: {
                rjsConfig: '<%= yeoman.app %>/scripts/config.js'
            }
        },
        concurrent: {
            server: [
                'compass:server'
            ],
            test: [
                'compass'
            ],
            dist: [
                'compass:dist',
                'imagemin',
                'htmlmin'
            ]
        }
    });

    grunt.renameTask('regarde', 'watch');

    grunt.registerTask('server', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'concurrent:server',
            'livereload-start',
            'connect:livereload',
            'open',
            'watch'
        ]);
    });

    grunt.registerTask('test', [
        'clean:server',

        'concurrent:test',
        'connect:test',
        'mocha'
    ]);

    grunt.registerTask('build', [
        'clean:dist',
        'concurrent:dist',
        'useminPrepare',
        'requirejs',
        'imagemin',
        'htmlmin',
        'concat',
        'cssmin',
//        'uglify',
        'copy',
        'usemin'
    ]);

    grunt.registerTask('default', [
        'jshint',
        'test',
        'build'
    ]);
};
<|endoftext|>


<commit_before>var events = require('events'),
    util = require('util'),
    common = require('./common'),
    Resource = require('./resource');

var Engine = module.exports = function Engine(options) {
  if(!(this instanceof Engine)) {
    return new Engine(options);
  }

  events.EventEmitter.call(this);
  this.options = options;
};

util.inherits(Engine, events.EventEmitter);

Engine.prototype.resource = function resource(namespace, options) {
  if(!namespace) {
    throw Error('Must specify a namespace');
  }

  var attrs = { connection: this, namespace: namespace };
  common.extend(attrs, options);
  return new Resource(attrs);
};<commit_msg>slugify the namespace to use as a nosql key if needed<commit_after>var events = require('events'),
    util = require('util'),
    common = require('./common'),
    Resource = require('./resource');

var Engine = module.exports = function Engine(options) {
  if(!(this instanceof Engine)) {
    return new Engine(options);
  }

  events.EventEmitter.call(this);
  this.options = options;
};

util.inherits(Engine, events.EventEmitter);

Engine.prototype.resource = function resource(namespace, options) {
  if(!namespace) {
    throw Error('Must specify a namespace');
  }

  var attrs = { connection: this, namespace: common.slugify(namespace) };
  common.extend(attrs, options);
  return new Resource(attrs);
};<|endoftext|>


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

	//prepare frontend boilerplate
	var
		less = {}, concat = {}, watch = {},
		sizes = ['xsmall','small','medium','large','xlarge','xxlarge','xxxlarge','xxxxlarge'],
		basename = sizes[0],
		components_css_dir = "build/components/**/css",
		global_css_dir = "build/global/css",
		dist_dir = 'css/dist';

	for (var i = 0; i < sizes.length; i++) {

		var size = sizes[i], lessfiles = {};
		lessfiles['css/build/'+size+'.min.css'] = [
			global_css_dir+'/elements/**/*.'+size+'.less',
			components_css_dir+'/*.'+size+'.less'
		];
		lessfiles['css/build/'+size+'.retina.min.css'] = [components_css_dir+'/*.'+size+'.retina.less'];
		less[size] = {
			options: {
				paths: ['less'],
				compress: true
			},
			files: lessfiles
		};
		concat["css_"+size] = {
			src: [
				global_css_dir+'/helpers/queries.'+size+'.css',
				'css/build/'+size+'.min.css',
				global_css_dir+'/helpers/queries.close.css',
				global_css_dir+'/helpers/queries.'+size+'.retina.css',
				'css/build/'+size+'.retina.min.css',
				global_css_dir+'/queries.close2.css'
			],
			dest: 'css/dist/'+size+'.min.css',
			seperator: '\n'
		};
		watch["css_"+size] = {
			files: [
				global_css_dir+'/elements/**/*.'+size+'.less',
				global_css_dir+'/elements/**/*.'+size+'.retina.less',
				components_css_dir+'/*.'+size+'.less',
				components_css_dir+'/*.'+size+'.retina.less',
				global_css_dir+'/mixins/*.css',
				global_css_dir+'/helpers/*.css'
			],
			tasks: [
				'less:'+size,
				'concat:css_'+size,
				'concat:css_production'
			]
		};

	};
	//add in specific locations

	less[basename].files['css/build/'+basename+'.min.css'].unshift(global_css_dir+'/utility.less');
	less[basename].files['css/build/'+basename+'.min.css'].unshift(global_css_dir+'/reset.less');

	less['print'] = {
		options: {
			paths: ['less'],
			compress: true
		},
		files: {
			'css/dist/print.css': [
				global_css_dir+'/print.less'
			],
		}
	};

	concat['css_production'] = {
		src: [
			'<banner>',
			'css/dist/xsmall.min.css',
			'css/dist/small.min.css',
			'css/dist/medium.min.css',
			'css/dist/large.min.css',
			'css/dist/xlarge.min.css',
			'css/dist/xxlarge.min.css',
			'css/dist/xxxlarge.min.css',
			'css/dist/xxxxlarge.min.css',
			'css/dist/print.css'
		],
		dest: 'css/dist/production.min.css',
		seperator: '\n'
	};
	concat['js'] = {
		src: [

		],
		dest: 'js/dist/site.src.js',
		seperator: '\n'
	};
	//additional watch print, and watch js
	watch['css_print'] = {
		files: [
			'build/print.less',
		],
		tasks: [
			'less:print',
			'concat:css_production'
		]
	};
	watch['js'] = {
		files: [
			'build/components/**/js/vendor/*.js',
			'build/components/**/js/*.js',
		],
		tasks: [
			'concat:js'
		]
	};

	//do grunt configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner: '/*! DNA Designed Communications Limited | Copyright 2012 */'
		},
		imageoptim: {
			// these paths should match directories
			files: ['images'],
			options: {
				quitAfter: true
			}
		},
		less: less,
		concat: concat,
		watch: watch
	});

	grunt.loadNpmTasks('grunt-css');
	grunt.loadNpmTasks('grunt-contrib-less');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-imageoptim');

	grunt.registerTask('default', ['less', 'concat', 'watch']);
};
<commit_msg>Added missing javascript watches<commit_after>module.exports = function(grunt) {

	//prepare frontend boilerplate
	var
		less = {}, concat = {}, watch = {},
		sizes = ['xsmall','small','medium','large','xlarge','xxlarge','xxxlarge','xxxxlarge'],
		basename = sizes[0],
		components_css_dir = "build/components/**/css",
		global_css_dir = "build/global/css",
		dist_dir = 'css/dist';

	for (var i = 0; i < sizes.length; i++) {

		var size = sizes[i], lessfiles = {};
		lessfiles['css/build/'+size+'.min.css'] = [
			global_css_dir+'/elements/**/*.'+size+'.less',
			components_css_dir+'/*.'+size+'.less'
		];
		lessfiles['css/build/'+size+'.retina.min.css'] = [components_css_dir+'/*.'+size+'.retina.less'];
		less[size] = {
			options: {
				paths: ['less'],
				compress: true
			},
			files: lessfiles
		};
		concat["css_"+size] = {
			src: [
				global_css_dir+'/helpers/queries.'+size+'.css',
				'css/build/'+size+'.min.css',
				global_css_dir+'/helpers/queries.close.css',
				global_css_dir+'/helpers/queries.'+size+'.retina.css',
				'css/build/'+size+'.retina.min.css',
				global_css_dir+'/queries.close2.css'
			],
			dest: 'css/dist/'+size+'.min.css',
			seperator: '\n'
		};
		watch["css_"+size] = {
			files: [
				global_css_dir+'/elements/**/*.'+size+'.less',
				global_css_dir+'/elements/**/*.'+size+'.retina.less',
				components_css_dir+'/*.'+size+'.less',
				components_css_dir+'/*.'+size+'.retina.less',
				global_css_dir+'/mixins/*.css',
				global_css_dir+'/helpers/*.css'
			],
			tasks: [
				'less:'+size,
				'concat:css_'+size,
				'concat:css_production'
			]
		};

	};
	//add in specific locations

	less[basename].files['css/build/'+basename+'.min.css'].unshift(global_css_dir+'/utility.less');
	less[basename].files['css/build/'+basename+'.min.css'].unshift(global_css_dir+'/reset.less');

	less['print'] = {
		options: {
			paths: ['less'],
			compress: true
		},
		files: {
			'css/dist/print.css': [
				global_css_dir+'/print.less'
			],
		}
	};

	concat['css_production'] = {
		src: [
			'<banner>',
			'css/dist/xsmall.min.css',
			'css/dist/small.min.css',
			'css/dist/medium.min.css',
			'css/dist/large.min.css',
			'css/dist/xlarge.min.css',
			'css/dist/xxlarge.min.css',
			'css/dist/xxxlarge.min.css',
			'css/dist/xxxxlarge.min.css',
			'css/dist/print.css'
		],
		dest: 'css/dist/production.min.css',
		seperator: '\n'
	};
	concat['js'] = {
		src: [

		],
		dest: 'js/dist/site.src.js',
		seperator: '\n'
	};
	//additional watch print, and watch js
	watch['css_print'] = {
		files: [
			'build/print.less',
		],
		tasks: [
			'less:print',
			'concat:css_production'
		]
	};
	watch['js'] = {
		files: [
			'build/global/js/vendor/*.js',
			'build/global/js/*.js',
			'build/components/**/js/vendor/*.js',
			'build/components/**/js/*.js',
		],
		tasks: [
			'concat:js'
		]
	};

	//do grunt configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner: '/*! DNA Designed Communications Limited | Copyright 2012 */'
		},
		imageoptim: {
			// these paths should match directories
			files: ['images'],
			options: {
				quitAfter: true
			}
		},
		less: less,
		concat: concat,
		watch: watch
	});

	grunt.loadNpmTasks('grunt-css');
	grunt.loadNpmTasks('grunt-contrib-less');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-imageoptim');

	grunt.registerTask('default', ['less', 'concat', 'watch']);
};
<|endoftext|>


<commit_before>'use strict';

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('jquery-trim-multiselect.jquery.json'),
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
      '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
    // Task configuration.
    clean: {
      files: ['dist']
    },
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['src/<%= pkg.name %>.js'],
        dest: 'dist/<%= pkg.name %>.js'
      },
    },
    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      dist: {
        src: '<%= concat.dist.dest %>',
        dest: 'dist/<%= pkg.name %>.min.js'
      },
    },
    qunit: {
      files: ['test/**/*.html']
    },
    jshint: {
      gruntfile: {
        options: {
          jshintrc: '.jshintrc'
        },
        src: 'Gruntfile.js'
      },
      src: {
        options: {
          jshintrc: 'src/.jshintrc'
        },
        src: ['src/**/*.js']
      },
      test: {
        options: {
          jshintrc: 'test/.jshintrc'
        },
        src: ['test/**/*.js']
      },
    },
    bump: {
      options: {
        files: ['package.json', 'jquery-trim-multiselect.jquery.json'],
        commit: true,
        commitMessage: 'Release v${version}',
        commitFiles: ['package.json', 'jquery-trim-multiselect.jquery.json'], // '-a' for all files
        createTag: true,
        tagName: 'v${version}',
        tagMessage: 'Version ${version}',
        push: true,
        pushTo: 'origin'
      }
    },
    watch: {
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },
      src: {
        files: '<%= jshint.src.src %>',
        tasks: ['jshint:src', 'qunit', 'clean', 'concat', 'uglify']
      },
      test: {
        files: '<%= jshint.test.src %>',
        tasks: ['jshint:test', 'qunit']
      },
    }
  });

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-bump');

  // Default task.
  grunt.registerTask('default', ['jshint', 'qunit', 'clean', 'concat', 'uglify']);
  grunt.registerTask('dev', ['qunit', 'clean', 'concat', 'uglify']);

};
<commit_msg>Grunt-bump config change.<commit_after>'use strict';

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('jquery-trim-multiselect.jquery.json'),
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
      '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
    // Task configuration.
    clean: {
      files: ['dist']
    },
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['src/<%= pkg.name %>.js'],
        dest: 'dist/<%= pkg.name %>.js'
      },
    },
    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      dist: {
        src: '<%= concat.dist.dest %>',
        dest: 'dist/<%= pkg.name %>.min.js'
      },
    },
    qunit: {
      files: ['test/**/*.html']
    },
    jshint: {
      gruntfile: {
        options: {
          jshintrc: '.jshintrc'
        },
        src: 'Gruntfile.js'
      },
      src: {
        options: {
          jshintrc: 'src/.jshintrc'
        },
        src: ['src/**/*.js']
      },
      test: {
        options: {
          jshintrc: 'test/.jshintrc'
        },
        src: ['test/**/*.js']
      },
    },
    bump: {
      options: {
        files: ['package.json', 'jquery-trim-multiselect.jquery.json'],
        commit: true,
        commitFiles: ['package.json', 'jquery-trim-multiselect.jquery.json'], // '-a' for all files
        createTag: true,
        push: true,
        pushTo: 'origin'
      }
    },
    watch: {
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },
      src: {
        files: '<%= jshint.src.src %>',
        tasks: ['jshint:src', 'qunit', 'clean', 'concat', 'uglify']
      },
      test: {
        files: '<%= jshint.test.src %>',
        tasks: ['jshint:test', 'qunit']
      },
    }
  });

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-bump');

  // Default task.
  grunt.registerTask('default', ['jshint', 'qunit', 'clean', 'concat', 'uglify']);
  grunt.registerTask('dev', ['qunit', 'clean', 'concat', 'uglify']);

};
<|endoftext|>