<commit_before>/*
 * Copyright 2012, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of his
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * Various 2d math functions.
 *
 * @module webgl-2d-math
 */
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], factory);
  } else {
    // Browser globals
    var lib = factory();
    Object.keys(lib).forEach(function(key) {
      root[key] = lib[key];
    });
  }
}(this, function () {
  "use strict";

  function make2DProjection(width, height) {
    // Note: This matrix flips the Y axis so 0 is at the top.
    return [
      2 / width, 0, 0,
      0, -2 / height, 0,
      -1, 1, 1
    ];
  }

  function makeTranslation(tx, ty) {
    return [
      1, 0, 0,
      0, 1, 0,
      tx, ty, 1
    ];
  }

  function makeRotation(angleInRadians) {
    var c = Math.cos(angleInRadians);
    var s = Math.sin(angleInRadians);
    return [
      c,-s, 0,
      s, c, 0,
      0, 0, 1
    ];
  }

  function makeScale(sx, sy) {
    return [
      sx, 0, 0,
      0, sy, 0,
      0, 0, 1
    ];
  }

  function matrixMultiply(a, b) {
    var a00 = a[0*3+0];
    var a01 = a[0*3+1];
    var a02 = a[0*3+2];
    var a10 = a[1*3+0];
    var a11 = a[1*3+1];
    var a12 = a[1*3+2];
    var a20 = a[2*3+0];
    var a21 = a[2*3+1];
    var a22 = a[2*3+2];
    var b00 = b[0*3+0];
    var b01 = b[0*3+1];
    var b02 = b[0*3+2];
    var b10 = b[1*3+0];
    var b11 = b[1*3+1];
    var b12 = b[1*3+2];
    var b20 = b[2*3+0];
    var b21 = b[2*3+1];
    var b22 = b[2*3+2];
    return [a00 * b00 + a01 * b10 + a02 * b20,
            a00 * b01 + a01 * b11 + a02 * b21,
            a00 * b02 + a01 * b12 + a02 * b22,
            a10 * b00 + a11 * b10 + a12 * b20,
            a10 * b01 + a11 * b11 + a12 * b21,
            a10 * b02 + a11 * b12 + a12 * b22,
            a20 * b00 + a21 * b10 + a22 * b20,
            a20 * b01 + a21 * b11 + a22 * b21,
            a20 * b02 + a21 * b12 + a22 * b22];
  }

  return {
    make2DProjection: make2DProjection,
    makeTranslation: makeTranslation,
    makeRotation: makeRotation,
    makeScale: makeScale,
    matrixMultiply: matrixMultiply,
  };

}));

<commit_msg>add docs to webgl-2d-math.js<commit_after>/*
 * Copyright 2012, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of his
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * Various 2d math functions.
 *
 * @module webgl-2d-math
 */
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], factory);
  } else {
    // Browser globals
    var lib = factory();
    Object.keys(lib).forEach(function(key) {
      root[key] = lib[key];
    });
  }
}(this, function () {
  "use strict";

  /**
   * An array or typed array with 9 values.
   * @typedef {number[]|TypedArray} Matrix3
   * @memberOf module:webgl-2d-math
   */

  /**
   * Creates a 2D projection matrix
   * @param {number} width width in pixels
   * @param {number} height height in pixels
   * @return {module:webgl-2d-math.Matrix3} a projection matrix that converts from pixels to clipspace with Y = 0 at the top.
   * @memberOf module:webgl-2d-math
   */
  function make2DProjection(width, height) {
    // Note: This matrix flips the Y axis so 0 is at the top.
    return [
      2 / width, 0, 0,
      0, -2 / height, 0,
      -1, 1, 1
    ];
  }

  /**
   * Creates a 2D translation matrix
   * @param {number} tx amount to translate in x
   * @param {number} ty amount to translate in y
   * @return {module:webgl-2d-math.Matrix3} a translation matrix that translates by tx and ty.
   * @memberOf module:webgl-2d-math
   */
  function makeTranslation(tx, ty) {
    return [
      1, 0, 0,
      0, 1, 0,
      tx, ty, 1
    ];
  }

  /**
   * Creates a 2D rotation matrix
   * @param {number} angleInRadians amount to rotate in radians
   * @return {module:webgl-2d-math.Matrix3} a rotation matrix that rotates by angleInRadians
   * @memberOf module:webgl-2d-math
   */
  function makeRotation(angleInRadians) {
    var c = Math.cos(angleInRadians);
    var s = Math.sin(angleInRadians);
    return [
      c,-s, 0,
      s, c, 0,
      0, 0, 1
    ];
  }

  /**
   * Creates a 2D scaling matrix
   * @param {number} sx amount to scale in x
   * @param {number} sy amount to scale in y
   * @return {module:webgl-2d-math.Matrix3} a scale matrix that scales by sx and sy.
   * @memberOf module:webgl-2d-math
   */
  function makeScale(sx, sy) {
    return [
      sx, 0, 0,
      0, sy, 0,
      0, 0, 1
    ];
  }

  /**
   * Takes twoMatrix3s, a and b, and computes the product in the order
   * that pre-composes b with a.  In other words, the matrix returned will
   * @param {module:webgl-2d-math.Matrix3} a A matrix.
   * @param {module:webgl-2d-math.Matrix3} b A matrix.
   * @return {module:webgl-2d-math.Matrix3} the result.
  * @memberOf module:webgl-2d-math
   */
  function matrixMultiply(a, b) {
    var a00 = a[0*3+0];
    var a01 = a[0*3+1];
    var a02 = a[0*3+2];
    var a10 = a[1*3+0];
    var a11 = a[1*3+1];
    var a12 = a[1*3+2];
    var a20 = a[2*3+0];
    var a21 = a[2*3+1];
    var a22 = a[2*3+2];
    var b00 = b[0*3+0];
    var b01 = b[0*3+1];
    var b02 = b[0*3+2];
    var b10 = b[1*3+0];
    var b11 = b[1*3+1];
    var b12 = b[1*3+2];
    var b20 = b[2*3+0];
    var b21 = b[2*3+1];
    var b22 = b[2*3+2];
    return [a00 * b00 + a01 * b10 + a02 * b20,
            a00 * b01 + a01 * b11 + a02 * b21,
            a00 * b02 + a01 * b12 + a02 * b22,
            a10 * b00 + a11 * b10 + a12 * b20,
            a10 * b01 + a11 * b11 + a12 * b21,
            a10 * b02 + a11 * b12 + a12 * b22,
            a20 * b00 + a21 * b10 + a22 * b20,
            a20 * b01 + a21 * b11 + a22 * b21,
            a20 * b02 + a21 * b12 + a22 * b22];
  }

  return {
    make2DProjection: make2DProjection,
    makeTranslation: makeTranslation,
    makeRotation: makeRotation,
    makeScale: makeScale,
    matrixMultiply: matrixMultiply,
  };

}));

<|endoftext|>


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

	// Initialize config
	grunt.initConfig({

		// Load package.json
		pkg: require('./package.json'),

		// Project paths
		project: {
			assets: 'assets',
			styles: '<%= project.assets %>/stylesheets',
			styles_scss: '<%= project.styles %>/scss',
			styles_dev: '<%= project.styles %>/dev',
			styles_min: '<%= project.styles %>/min',
			styles_critical: '<%= project.styles %>/critical',
			scripts: '<%= project.assets %>/javascript',
			scripts_dev: '<%= project.scripts %>/dev',
			scripts_min: '<%= project.scripts %>/min',
			scripts_modules: '<%= project.scripts %>/modules',
			scripts_plugins: '<%= project.scripts %>/lib/plugins',
			scripts_polyfills: '<%= project.scripts %>/lib/polyfills',
			scripts_utils: '<%= project.scripts %>/lib/utils',
		},

		// Project banner
		tag: {
			banner_basic: '/**\n' +
					' * <%= pkg.description %> — v<%= pkg.version %> — <%= grunt.template.today("yyyy-mm-dd") %>\n' +
					' * <%= pkg.url %>\n' +
					' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.copyright %>\n' +
					' */\n',
			banner_extended: '/**\n' +
					' * <%= pkg.description %>\n' +
					' *\n' +
					' * @authors   <%= pkg.author %>\n' +
					' * @link      <%= pkg.url %>\n' +
					' * @version   <%= pkg.version %>\n' +
					' * @generated <%= grunt.template.today("yyyy-mm-dd:hh:mm") %>\n' +
					' * @copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.copyright %>\n' +
					' * @license   <%= pkg.license %>\n' +
					' */\n'
		},

		// JS files and order
		jsfiles: {
			head: [
				'<%= project.scripts_plugins %>/enhance/enhance.js',
				'<%= project.scripts_plugins %>/modernizr/modernizr.dev.js',
				// '<%= project.scripts_plugins %>/modernizr/modernizr.min.js',    // ALWAYS use custom build modernizr in production!
				'<%= project.scripts %>/head.scripts.js',
			],
			main: {
				plugins: [
					'<%= project.scripts_plugins %>/debounce/debounce.js',      // Out-comment when using filters module!
					'<%= project.scripts_plugins %>/domready/domready.js',      // ALWAYS out-comment. It is used in the `main` and `mobile` scripts files!
					'<%= project.scripts_plugins %>/fontfaceobserver/fontfaceobserver.js',
					// '<%= project.scripts_plugins %>/gumshoe/gumshoe.js',
					'<%= project.scripts_plugins %>/imageset/imageset.js',      // Out-comment when using imageset's lazyload
					'<%= project.scripts_plugins %>/imageset/ls.bgset.js',      // Out-comment when using imageset's lazyload + background images with a width descriptor, similar to how `srcset` works (e.g. for Safari 10.x)
					'<%= project.scripts_plugins %>/imageset/ls.parent-fit.js', // Out-comment when using imageset's lazyload + background images; when `bgset` plugin (background images) is used in combination with data-sizes="auto" and `background-size: cover|contain` (e.g. for Edge, IE11 and older, iOS 9, etc.)
					// '<%= project.scripts_plugins %>/transitionend/transitionend.js', // Out-comment when using alerts or navmain module!
					// '<%= project.scripts_plugins %>/smooth-scroll/smooth-scroll.js',
					// '<%= project.scripts_plugins %>/debounce/throttle.js',
				],
				polyfills: [
					'<%= project.scripts_polyfills %>/classlist.js',            // Adds cross-browser full `element.classList` support (IE11)
					// '<%= project.scripts_polyfills %>/promise.js',
					// '<%= project.scripts_polyfills %>/respimage.js',            // Out-comment when using imageset's lazyload, to add support for the `srcset` and `picture` element to browsers that do not provide native support (e.g. for IE11 and older, iOS 9.2 and older, Opera Mini, etc.)!!1
					'<%= project.scripts_polyfills %>/ls.respimg.js',           // Only partial `respimage` polyfill (see: https://github.com/aFarkas/lazysizes/tree/gh-pages/plugins/respimg)
				],
				utils: [
					// '<%= project.scripts_utils %>/ajax.util.js',
					// '<%= project.scripts_utils %>/cookie.util.js',              // Out-comment when enhance (and thus enhance.cookie) is not used
					'<%= project.scripts_utils %>/domparents.util.js',
					// '<%= project.scripts_utils %>/extend.util.js',              // Out-comment when using alerts module!
					'<%= project.scripts_utils %>/isvisible.util.js',           // Out-comment when using filters module!
				],
				modules: [
					// '<%= project.scripts_modules %>/alerts.module.js',
					// '<%= project.scripts_modules %>/expand.module.js',
					'<%= project.scripts_modules %>/filters.module.js',
					'<%= project.scripts_modules %>/fontobserver.module.js',
					// '<%= project.scripts_modules %>/navmain.module.js',
					// '<%= project.scripts_modules %>/popup.module.js',
				// Main
					'<%= project.scripts %>/main.scripts.js',
				],
			},
			mobile: {
				plugins: [
					'<%= project.scripts_plugins %>/domready/domready.js',      // ALWAYS out-comment! It is used in the `main` and `mobile` scripts files!
					'<%= project.scripts_plugins %>/domready/domready.js',      // Used in main.scripts.js!
					'<%= project.scripts_plugins %>/fontfaceobserver/fontfaceobserver.js',
					'<%= project.scripts_plugins %>/imageset/imageset.js',      // Out-comment when using imageset's lazyload
					'<%= project.scripts_plugins %>/imageset/ls.bgset.js',     // Out-comment when using imageset's lazyload + background images with a width descriptor, similar to how `srcset` works (e.g. for Safari 10.x)
					'<%= project.scripts_plugins %>/imageset/ls.parent-fit.js', // Out-comment when using imageset's lazyload + background images; when `bgset` plugin (background images) is used in combination with data-sizes="auto" and `background-size: cover|contain` (e.g. for Edge, IE11 and older, iOS 9, etc.)
					'<%= project.scripts_plugins %>/resize-end/resize-end.js',
					// '<%= project.scripts_plugins %>/transitionend/transitionend.js',
					// '<%= project.scripts_plugins %>/smooth-scroll/smooth-scroll.js',
					// '<%= project.scripts_plugins %>/debounce/throttle.js',
				],
				polyfills: [
					'<%= project.scripts_polyfills %>/classlist.js',            // Adds cross-browser full `element.classList` support (IE11)
					// '<%= project.scripts_polyfills %>/promise.js',
					// '<%= project.scripts_polyfills %>/respimage.js',            // Out-comment when using imageset's lazyload, to add support for the `srcset` and `picture` element to browsers that do not provide native support (e.g. for IE11 and older, iOS 9.2 and older, Opera Mini, etc.)!!1
				],
				utils: [
					// '<%= project.scripts_utils %>/ajax.util.js',
					// '<%= project.scripts_utils %>/cookie.util.js',              // Out-comment when enhance (and thus enhance.cookie) is not used
					'<%= project.scripts_utils %>/domparents.util.js',
					// '<%= project.scripts_utils %>/extend.util.js',              // Out-comment when using alerts module!
					'<%= project.scripts_utils %>/isvisible.util.js',           // Out-comment when using filters module!
				],
				modules: [
					// '<%= project.scripts_modules %>/alerts.module.js',
					// '<%= project.scripts_modules %>/expand.module.js',
					'<%= project.scripts_modules %>/filters.module.js',
					'<%= project.scripts_modules %>/fontobserver.module.js',
					// '<%= project.scripts_modules %>/navmain.module.js',
				// Main
					'<%= project.scripts %>/mobile.scripts.js',
				],
			},
		},
	});

	// Load per-task config from separate files
	grunt.loadTasks('grunt/config');

	// Register alias tasks from separate files
	grunt.loadTasks('grunt/tasks');

	// Register default task
	grunt.registerTask('default', ['develop']);

};
<commit_msg>Also add (but out-comment) `ls.respimg` to mobile scripts.<commit_after>module.exports = function(grunt) {

	// Initialize config
	grunt.initConfig({

		// Load package.json
		pkg: require('./package.json'),

		// Project paths
		project: {
			assets: 'assets',
			styles: '<%= project.assets %>/stylesheets',
			styles_scss: '<%= project.styles %>/scss',
			styles_dev: '<%= project.styles %>/dev',
			styles_min: '<%= project.styles %>/min',
			styles_critical: '<%= project.styles %>/critical',
			scripts: '<%= project.assets %>/javascript',
			scripts_dev: '<%= project.scripts %>/dev',
			scripts_min: '<%= project.scripts %>/min',
			scripts_modules: '<%= project.scripts %>/modules',
			scripts_plugins: '<%= project.scripts %>/lib/plugins',
			scripts_polyfills: '<%= project.scripts %>/lib/polyfills',
			scripts_utils: '<%= project.scripts %>/lib/utils',
		},

		// Project banner
		tag: {
			banner_basic: '/**\n' +
					' * <%= pkg.description %> — v<%= pkg.version %> — <%= grunt.template.today("yyyy-mm-dd") %>\n' +
					' * <%= pkg.url %>\n' +
					' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.copyright %>\n' +
					' */\n',
			banner_extended: '/**\n' +
					' * <%= pkg.description %>\n' +
					' *\n' +
					' * @authors   <%= pkg.author %>\n' +
					' * @link      <%= pkg.url %>\n' +
					' * @version   <%= pkg.version %>\n' +
					' * @generated <%= grunt.template.today("yyyy-mm-dd:hh:mm") %>\n' +
					' * @copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.copyright %>\n' +
					' * @license   <%= pkg.license %>\n' +
					' */\n'
		},

		// JS files and order
		jsfiles: {
			head: [
				'<%= project.scripts_plugins %>/enhance/enhance.js',
				'<%= project.scripts_plugins %>/modernizr/modernizr.dev.js',
				// '<%= project.scripts_plugins %>/modernizr/modernizr.min.js',    // ALWAYS use custom build modernizr in production!
				'<%= project.scripts %>/head.scripts.js',
			],
			main: {
				plugins: [
					'<%= project.scripts_plugins %>/debounce/debounce.js',      // Out-comment when using filters module!
					'<%= project.scripts_plugins %>/domready/domready.js',      // ALWAYS out-comment. It is used in the `main` and `mobile` scripts files!
					'<%= project.scripts_plugins %>/fontfaceobserver/fontfaceobserver.js',
					// '<%= project.scripts_plugins %>/gumshoe/gumshoe.js',
					'<%= project.scripts_plugins %>/imageset/imageset.js',      // Out-comment when using imageset's lazyload
					'<%= project.scripts_plugins %>/imageset/ls.bgset.js',      // Out-comment when using imageset's lazyload + background images with a width descriptor, similar to how `srcset` works (e.g. for Safari 10.x)
					'<%= project.scripts_plugins %>/imageset/ls.parent-fit.js', // Out-comment when using imageset's lazyload + background images; when `bgset` plugin (background images) is used in combination with data-sizes="auto" and `background-size: cover|contain` (e.g. for Edge, IE11 and older, iOS 9, etc.)
					// '<%= project.scripts_plugins %>/transitionend/transitionend.js', // Out-comment when using alerts or navmain module!
					// '<%= project.scripts_plugins %>/smooth-scroll/smooth-scroll.js',
					// '<%= project.scripts_plugins %>/debounce/throttle.js',
				],
				polyfills: [
					'<%= project.scripts_polyfills %>/classlist.js',            // Adds cross-browser full `element.classList` support (IE11)
					// '<%= project.scripts_polyfills %>/promise.js',
					// '<%= project.scripts_polyfills %>/respimage.js',            // Out-comment when using imageset's lazyload, to add support for the `srcset` and `picture` element to browsers that do not provide native support (e.g. for IE11 and older, iOS 9.2 and older, Opera Mini, etc.)!!1
					'<%= project.scripts_polyfills %>/ls.respimg.js',           // Only partial `respimage` polyfill (see: https://github.com/aFarkas/lazysizes/tree/gh-pages/plugins/respimg)
				],
				utils: [
					// '<%= project.scripts_utils %>/ajax.util.js',
					// '<%= project.scripts_utils %>/cookie.util.js',              // Out-comment when enhance (and thus enhance.cookie) is not used
					'<%= project.scripts_utils %>/domparents.util.js',
					// '<%= project.scripts_utils %>/extend.util.js',              // Out-comment when using alerts module!
					'<%= project.scripts_utils %>/isvisible.util.js',           // Out-comment when using filters module!
				],
				modules: [
					// '<%= project.scripts_modules %>/alerts.module.js',
					// '<%= project.scripts_modules %>/expand.module.js',
					'<%= project.scripts_modules %>/filters.module.js',
					'<%= project.scripts_modules %>/fontobserver.module.js',
					// '<%= project.scripts_modules %>/navmain.module.js',
					// '<%= project.scripts_modules %>/popup.module.js',
				// Main
					'<%= project.scripts %>/main.scripts.js',
				],
			},
			mobile: {
				plugins: [
					'<%= project.scripts_plugins %>/domready/domready.js',      // ALWAYS out-comment! It is used in the `main` and `mobile` scripts files!
					'<%= project.scripts_plugins %>/domready/domready.js',      // Used in main.scripts.js!
					'<%= project.scripts_plugins %>/fontfaceobserver/fontfaceobserver.js',
					'<%= project.scripts_plugins %>/imageset/imageset.js',      // Out-comment when using imageset's lazyload
					'<%= project.scripts_plugins %>/imageset/ls.bgset.js',     // Out-comment when using imageset's lazyload + background images with a width descriptor, similar to how `srcset` works (e.g. for Safari 10.x)
					'<%= project.scripts_plugins %>/imageset/ls.parent-fit.js', // Out-comment when using imageset's lazyload + background images; when `bgset` plugin (background images) is used in combination with data-sizes="auto" and `background-size: cover|contain` (e.g. for Edge, IE11 and older, iOS 9, etc.)
					'<%= project.scripts_plugins %>/resize-end/resize-end.js',
					// '<%= project.scripts_plugins %>/transitionend/transitionend.js',
					// '<%= project.scripts_plugins %>/smooth-scroll/smooth-scroll.js',
					// '<%= project.scripts_plugins %>/debounce/throttle.js',
				],
				polyfills: [
					'<%= project.scripts_polyfills %>/classlist.js',            // Adds cross-browser full `element.classList` support (IE11)
					// '<%= project.scripts_polyfills %>/promise.js',
					// '<%= project.scripts_polyfills %>/respimage.js',            // Out-comment when using imageset's lazyload, to add support for the `srcset` and `picture` element to browsers that do not provide native support (e.g. for IE11 and older, iOS 9.2 and older, Opera Mini, etc.)!!1
					// '<%= project.scripts_polyfills %>/ls.respimg.js',           // Only partial `respimage` polyfill (see: https://github.com/aFarkas/lazysizes/tree/gh-pages/plugins/respimg)
				],
				utils: [
					// '<%= project.scripts_utils %>/ajax.util.js',
					// '<%= project.scripts_utils %>/cookie.util.js',              // Out-comment when enhance (and thus enhance.cookie) is not used
					'<%= project.scripts_utils %>/domparents.util.js',
					// '<%= project.scripts_utils %>/extend.util.js',              // Out-comment when using alerts module!
					'<%= project.scripts_utils %>/isvisible.util.js',           // Out-comment when using filters module!
				],
				modules: [
					// '<%= project.scripts_modules %>/alerts.module.js',
					// '<%= project.scripts_modules %>/expand.module.js',
					'<%= project.scripts_modules %>/filters.module.js',
					'<%= project.scripts_modules %>/fontobserver.module.js',
					// '<%= project.scripts_modules %>/navmain.module.js',
				// Main
					'<%= project.scripts %>/mobile.scripts.js',
				],
			},
		},
	});

	// Load per-task config from separate files
	grunt.loadTasks('grunt/config');

	// Register alias tasks from separate files
	grunt.loadTasks('grunt/tasks');

	// Register default task
	grunt.registerTask('default', ['develop']);

};
<|endoftext|>


<commit_before>import test from 'ava';
import readPatterns from '../source/read-patterns';

test('when calling with no arguments', t => {
	const actual = readPatterns();
	t.throws(actual, Error, 'it should throw an Error');
});

test('when calling with an empty array', async t => {
	const actual = await readPatterns([]);
	t.same(actual, [], 'it should return an empty array');
});
<commit_msg>test(read-patterns): read directory contents for each pattern<commit_after>import test from 'ava';
import mockFs from 'mock-fs';
import readPatterns from '../source/read-patterns';

test('when calling with no arguments', t => {
	const actual = readPatterns();
	t.throws(actual, Error, 'it should throw an Error');
});

test('when calling with an empty array', async t => {
	const actual = await readPatterns([]);
	t.same(actual, [], 'it should return an empty array');
});

test(`when calling with valid pattern folders`, async t => {
	mockFs({
		'components/button': {
			'package.json': '{"name":"button","version":"0.1.0","main":"button.js"}',
			'button.js': 'blub'
		}
	});
	const actual = await readPatterns([{path: './components/button'}]);
	const expected = [{
		path: './components/button',
		files: ['button.js', 'package.json']
	}];
	console.log(actual, expected);
	t.same(actual, expected, 'it should read the directory contents');
	mockFs.restore();
});
<|endoftext|>


<commit_before>angular.module('hsgc')
  .directive('basketballShotChart', ['$log', function($log) {
    return {
      restrict: 'EA',
      templateUrl: 'templates/basketballShotChart.html',
      link: function(scope) {
        scope.selectedShotChartPeriod = 0;
        scope.publicAvailability = scope.playByPlayAvailable;
        var firstLoad = true;
        var previousPeriod = -1;
        scope.$on('datacastLoaded', function() {
          var twentyForHoursFromStart = new Date(),
              periods = [], i;

          // since this is start time, assume an hour of playtime so we don't have to check for the actual End event time stamp, so guesss 25 hours
          twentyForHoursFromStart.setTime(scope.localStartTime.getTime() + (25*60*60*1000));
          scope.publicAvailability = scope.playByPlayAvailable && twentyForHoursFromStart > new Date();
          $log.debug('Is basketball box score publicly availabile still?', scope.publicAvailability);

          if (firstLoad) {
            firstLoad = false;
            scope.selectedShotChartPeriod = null;
            previousPeriod = scope.currentPeriod;

            // set the court image, so it doesn't load over the network for non-basketball sports
            angular.element('.nfhs-scout-basketball-court').attr('src', 'https://cdn.digitalscout.com/img/basketball-court.png');
          }

          for (i = 1; i <= scope.currentPeriod; i++) {
            if (i == 1)
              periods.push({
                value: i,
                display: "1st"
              });
            else if (i == 2)
              periods.push({
                value: i,
                display: "2nd"
              });
            else if (i == 3)
              periods.push({
                value: i,
                display: "3rd"
              });
            else if (i == 4)
              periods.push({
                value: i,
                display: "4th"
              });
            else {
              if (scope.currentPeriod == 5)
                periods.push({
                  value: i,
                  display: "OT"
                });
              else
                periods.push({
                  value: i,
                  display: (i - 4) + " OT"
                });
            }
          }
          scope.shotChartPeriods = periods;
        });

        scope.getLogo = function(play) {
          return play.TeamSeasonId == scope.homeTeamSeasonId ? scope.homeLogo : scope.awayLogo;
        };

        scope.getShotLeft = function(shot) {
          //the image used here does not have the same ratio as a regulation high school court
          //the percentage returned by the service assumes a court size of 84'x50', but our image is 637x424, so scale the x percentage appropriately
          var xScale = (84.0 / 50.0) / (637.0 / 424.0);
          var percent = shot.X * 100 * xScale;
          if (shot.TeamSeasonId != scope.awayTeamSeasonId) {
            percent = 100 - percent;
          }
          return percent;
        };

        scope.getShotTop = function(shot) {
          var percent = shot.Y * 100;
          if (shot.TeamSeasonId != scope.awayTeamSeasonId) {
            percent = 100 - percent;
          }
          return percent;
        };

        scope.getShotImageClass = function(shot) {
          if (shot.TeamSeasonId == scope.homeTeamSeasonId) {
            if (shot.IsScoring) {
              return "digital-scout-shot-chart-shot-made-home";
            } else {
              return "digital-scout-shot-chart-shot-missed-home";
            }
          } else {
            if (shot.IsScoring) {
              return "digital-scout-shot-chart-shot-made-away";
            } else {
              return "digital-scout-shot-chart-shot-missed-away";
            }
          }
        };
      }
    };
  }])
  .filter('filterShots', function() {
    return function(plays, awayPlayerFilter, homePlayerFilter, period, includeMade, includeMissed) {
      var shots = [];
      if (typeof(plays) != "undefined") {
        for (var i = 0; i < plays.length; i++) {
          if (plays[i].IsShot) {
            if (awayPlayerFilter != null && typeof(awayPlayerFilter) != "undefined" && plays[i].TeamSeasonId == awayPlayerFilter.TeamSeasonId && plays[i].PlayerId != awayPlayerFilter.PlayerId) {
              continue;
            }
            if (homePlayerFilter != null && typeof(homePlayerFilter) != "undefined" && plays[i].TeamSeasonId == homePlayerFilter.TeamSeasonId && plays[i].PlayerId != homePlayerFilter.PlayerId) {
              continue;
            }
            if (period != null && typeof(period) != "undefined" && plays[i].Quarter != period) {
              //handle OT
              if (plays[i].Quarter <= 4 || period != 5) {
                continue;
              }
            }
            shots.push(plays[i]);
          }
        }
      }

      return shots;
    };
  });<commit_msg>Widgets: Only load the basketball court image when applicable<commit_after>angular.module('hsgc')
  .directive('basketballShotChart', ['$log', function($log) {
    return {
      restrict: 'EA',
      templateUrl: 'templates/basketballShotChart.html',
      link: function(scope) {
        scope.selectedShotChartPeriod = 0;
        scope.publicAvailability = scope.playByPlayAvailable;
        var firstLoad = true;
        var previousPeriod = -1;
        scope.$on('datacastLoaded', function() {
          var twentyForHoursFromStart = new Date(),
              shotChartBackgroundImageElement = angular.element('.digital-scout-basketball-court'),
              periods = [], i;

          // since this is start time, assume an hour of playtime so we don't have to check for the actual End event time stamp, so guesss 25 hours
          twentyForHoursFromStart.setTime(scope.localStartTime.getTime() + (25*60*60*1000));
          scope.publicAvailability = scope.playByPlayAvailable && twentyForHoursFromStart > new Date();
          $log.debug('Is basketball box score publicly availabile still?', scope.publicAvailability);
          if (scope.publicAvailability === true && shotChartBackgroundImageElement && shotChartBackgroundImageElement.attr('src') === '') {
            // only set the court image when needed, so it doesn't load over the network when not
            shotChartBackgroundImageElement.attr('src', 'https://cdn.digitalscout.com/img/basketball-court.png');
          }

          if (firstLoad) {
            firstLoad = false;
            scope.selectedShotChartPeriod = null;
            previousPeriod = scope.currentPeriod;
          }

          for (i = 1; i <= scope.currentPeriod; i++) {
            if (i == 1)
              periods.push({
                value: i,
                display: "1st"
              });
            else if (i == 2)
              periods.push({
                value: i,
                display: "2nd"
              });
            else if (i == 3)
              periods.push({
                value: i,
                display: "3rd"
              });
            else if (i == 4)
              periods.push({
                value: i,
                display: "4th"
              });
            else {
              if (scope.currentPeriod == 5)
                periods.push({
                  value: i,
                  display: "OT"
                });
              else
                periods.push({
                  value: i,
                  display: (i - 4) + " OT"
                });
            }
          }
          scope.shotChartPeriods = periods;
        });

        scope.getLogo = function(play) {
          return play.TeamSeasonId == scope.homeTeamSeasonId ? scope.homeLogo : scope.awayLogo;
        };

        scope.getShotLeft = function(shot) {
          //the image used here does not have the same ratio as a regulation high school court
          //the percentage returned by the service assumes a court size of 84'x50', but our image is 637x424, so scale the x percentage appropriately
          var xScale = (84.0 / 50.0) / (637.0 / 424.0);
          var percent = shot.X * 100 * xScale;
          if (shot.TeamSeasonId != scope.awayTeamSeasonId) {
            percent = 100 - percent;
          }
          return percent;
        };

        scope.getShotTop = function(shot) {
          var percent = shot.Y * 100;
          if (shot.TeamSeasonId != scope.awayTeamSeasonId) {
            percent = 100 - percent;
          }
          return percent;
        };

        scope.getShotImageClass = function(shot) {
          if (shot.TeamSeasonId == scope.homeTeamSeasonId) {
            if (shot.IsScoring) {
              return "digital-scout-shot-chart-shot-made-home";
            } else {
              return "digital-scout-shot-chart-shot-missed-home";
            }
          } else {
            if (shot.IsScoring) {
              return "digital-scout-shot-chart-shot-made-away";
            } else {
              return "digital-scout-shot-chart-shot-missed-away";
            }
          }
        };
      }
    };
  }])
  .filter('filterShots', function() {
    return function(plays, awayPlayerFilter, homePlayerFilter, period, includeMade, includeMissed) {
      var shots = [];
      if (typeof(plays) != "undefined") {
        for (var i = 0; i < plays.length; i++) {
          if (plays[i].IsShot) {
            if (awayPlayerFilter != null && typeof(awayPlayerFilter) != "undefined" && plays[i].TeamSeasonId == awayPlayerFilter.TeamSeasonId && plays[i].PlayerId != awayPlayerFilter.PlayerId) {
              continue;
            }
            if (homePlayerFilter != null && typeof(homePlayerFilter) != "undefined" && plays[i].TeamSeasonId == homePlayerFilter.TeamSeasonId && plays[i].PlayerId != homePlayerFilter.PlayerId) {
              continue;
            }
            if (period != null && typeof(period) != "undefined" && plays[i].Quarter != period) {
              //handle OT
              if (plays[i].Quarter <= 4 || period != 5) {
                continue;
              }
            }
            shots.push(plays[i]);
          }
        }
      }

      return shots;
    };
  });<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

function loadSessionsTable(sessions) {
  $.each(sessions, function(index, session) {
    $("#interactive-sessions .sessions-table-body").append(
      "
" +
        tdWrap(uiLink("session/" + session.id, session.id)) +
        tdWrap(appIdLink(session)) +
        tdWrap(session.name) +
        tdWrap(session.owner) +
        tdWrap(session.proxyUser) +
        tdWrap(session.kind) +
        tdWrap(session.state) +
        tdWrap(logLinks(session, "session")) +
        "
"
    );
  });
}

function loadBatchesTable(sessions) {
  $.each(sessions, function(index, session) {
    $("#batches .sessions-table-body").append(
      "
" +
        tdWrap(session.id) +
        tdWrap(appIdLink(session)) +
        tdWrap(session.name) +
        tdWrap(session.owner) +
        tdWrap(session.proxyUser) +
        tdWrap(session.state) +
        tdWrap(logLinks(session, "batch")) +
        "
"
    );
  });
}

var numSessions = 0;
var numBatches = 0;

$(document).ready(function () {
  var sessionsReq = $.getJSON(location.origin + prependBasePath("/sessions"), function(response) {
    if (response && response.total > 0) {
      $("#interactive-sessions").load(prependBasePath("/static/html/sessions-table.html .sessions-template"), function() {
        loadSessionsTable(response.sessions);
        $("#interactive-sessions-table").DataTable();
        $('#interactive-sessions [data-toggle="tooltip"]').tooltip();
      });
    }
    numSessions = response.total;
  });

  var batchesReq = $.getJSON(location.origin + prependBasePath("/batches"), function(response) {
    if (response && response.total > 0) {
      $("#batches").load(prependBasePath("/static/html/batches-table.html .sessions-template"), function() {
        loadBatchesTable(response.sessions);
        $("#batches-table").DataTable();
        $('#batches [data-toggle="tooltip"]').tooltip();
      });
    }
    numBatches = response.total;
  });

  $.when(sessionsReq, batchesReq).done(function () {
    if (numSessions + numBatches == 0) {
      $("#all-sessions").append('
No Sessions or Batches have been created yet.
');
    }
  });
});<commit_msg>Add html escape to session name<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

function escapeHtml(unescapedText) {
  return $("
").text(unescapedText).html()
}

function loadSessionsTable(sessions) {
  $.each(sessions, function(index, session) {
    $("#interactive-sessions .sessions-table-body").append(
      "
" +
        tdWrap(uiLink("session/" + session.id, session.id)) +
        tdWrap(appIdLink(session)) +
        tdWrap(escapeHtml(session.name)) +
        tdWrap(session.owner) +
        tdWrap(session.proxyUser) +
        tdWrap(session.kind) +
        tdWrap(session.state) +
        tdWrap(logLinks(session, "session")) +
        "
"
    );
  });
}

function loadBatchesTable(sessions) {
  $.each(sessions, function(index, session) {
    $("#batches .sessions-table-body").append(
      "
" +
        tdWrap(session.id) +
        tdWrap(appIdLink(session)) +
        tdWrap(escapeHtml(session.name)) +
        tdWrap(session.owner) +
        tdWrap(session.proxyUser) +
        tdWrap(session.state) +
        tdWrap(logLinks(session, "batch")) +
        "
"
    );
  });
}

var numSessions = 0;
var numBatches = 0;

$(document).ready(function () {
  var sessionsReq = $.getJSON(location.origin + prependBasePath("/sessions"), function(response) {
    if (response && response.total > 0) {
      $("#interactive-sessions").load(prependBasePath("/static/html/sessions-table.html .sessions-template"), function() {
        loadSessionsTable(response.sessions);
        $("#interactive-sessions-table").DataTable();
        $('#interactive-sessions [data-toggle="tooltip"]').tooltip();
      });
    }
    numSessions = response.total;
  });

  var batchesReq = $.getJSON(location.origin + prependBasePath("/batches"), function(response) {
    if (response && response.total > 0) {
      $("#batches").load(prependBasePath("/static/html/batches-table.html .sessions-template"), function() {
        loadBatchesTable(response.sessions);
        $("#batches-table").DataTable();
        $('#batches [data-toggle="tooltip"]').tooltip();
      });
    }
    numBatches = response.total;
  });

  $.when(sessionsReq, batchesReq).done(function () {
    if (numSessions + numBatches == 0) {
      $("#all-sessions").append('
No Sessions or Batches have been created yet.
');
    }
  });
});
<|endoftext|>


<commit_before>
// Initialize map & set initial location / view
//var map = L.mapbox.map('map', 'examples.map-4l7djmvo')

var map = L.mapbox.map('map', 'louh.map-vio2jxma', {
                detectRetina: true,
                retinaVersion: 'louh.map-2lywy8ei'
            })
            .setView([36.1665, -115.1479], 17)

/*
var map = L.map('map')
    .setView([36.1665, -115.1479], 17)
    .addLayer(L.mapbox.tileLayer('louh.map-vio2jxma', {
        detectRetina: true,
        retinaVersion: 'elouh.map-2lywy8ei'
    }));
*/
// Map imagery attribution
// Note that mapbox.js provides its own separate attribution, which I don't know how to edit, so I've hidden it with CSS (super hacky!)
var control = L.control.attribution({
    prefix: 'Map imagery by MapBox. Data © OpenStreetMap contributors.'
}).addTo(map)

// Set up truck icon
var truckMarker = L.icon({
    iconUrl: 'img/marker-truck.svg',

    iconSize:     [70, 60], // size of the icon
    iconAnchor:   [35, 50], // point of the icon which will correspond to marker's location
    popupAnchor:  [3, -55] // point from which the popup should open relative to the iconAnchor
})

var truckMarkerOff = L.icon({
    iconUrl: 'img/marker-truck-off.svg',

    iconSize:     [70, 60],
    iconAnchor:   [35, 50],
    popupAnchor:  [3, -55]
})

// Get data
var data = document.data()

// This information is now also available back in main.js
var locations = data.locations // this is a GeoJSON format
var trucks = data.trucks
var calendar = data.calendar

// Populate map with locations
var markers = L.mapbox.markerLayer(locations, {
    filter: function (feature) {
        return true
        // disabled active filter
        // return feature.properties.status === 'active'
    }
}).eachLayer(function (marker) {

    // set options here directly on the marker object
    marker.options.icon = truckMarkerOff  // set this to be off by default
    marker.options.riseOnHover = true

    // shorthand for where things are stored in the GeoJSON
    var markerID = marker.feature.id

    for (i = 0; i < calendar.now.length; i++) {
        if (calendar.now[i].at == markerID ) {
            for (j =0; j < trucks.length; j++) {
                if (trucks[j].id == calendar.now[i].truck) {
                    marker.truck = trucks[j]
                    break
                }
            }
            marker.calendar = calendar.now[i]
            break
        }
    }

    // Popup construction
    var popupHTML = 'No truck at ' + marker.feature.properties.name + '
' + marker.feature.properties.address
    if (marker.truck) {
        var popupHTML = '' + marker.truck.name + ' is at ' + marker.feature.properties.name + '
' + marker.feature.properties.address + '
until ' + marker.calendar.until
        marker.options.icon = truckMarker //turn on truck
    }

    marker.bindPopup(popupHTML, {
        closeButton: false,
        minWidth: 200,
        autoPanPadding: [20, 40]
    })

    // Center marker on click
    marker.on('click', function (e) {
        map.panTo(marker.getLatLng())
    })
}).addTo(map)

// Set view based on locations
map.fitBounds(markers.getBounds().pad(0.25))
map.setMaxBounds(markers.getBounds().pad(6))

// Open popups on mouseover (test)
markers.on('mouseover', function (e) {
    e.layer.openPopup()
})
/*
markers.on('mouseout', function (e) {
    e.layer.closePopup()
})
*/

// Popups test
/*
markers.on('click',function (e) {
    e.layer.unbindPopup();

    var mPopup = $('#m-popup').html()
    var popupObject = {}

    var i = 1

    var feature = e.layer.feature;
    popupObject.location = feature.properties.name
    popupObject.address = feature.properties.address
    popupObject.name = trucks[i].name
    popupObject.until = trucks[i].until

    $('#popup-layer').html(Mustache.render(mPopup, popupObject))
    $('#popup').fadeIn(200)
});
// Clear the tooltip when map is clicked
map.on('click',function (e) {
    $('#popup').fadeOut(200)
});
*/<commit_msg>Retina try 2<commit_after>
// Initialize map & set initial location / view
//var map = L.mapbox.map('map', 'examples.map-4l7djmvo')
/*
var map = L.mapbox.map('map', 'louh.map-vio2jxma', {
                detectRetina: true,
                retinaVersion: 'louh.map-2lywy8ei'
            })
            .setView([36.1665, -115.1479], 17)
*/

var map = L.map('map')
    .setView([36.1665, -115.1479], 17)
    .addLayer(L.mapbox.tileLayer('louh.map-vio2jxma', {
        detectRetina: true,
        retinaVersion: 'elouh.map-2lywy8ei'
    }))

// Map imagery attribution
// Note that mapbox.js provides its own separate attribution, which I don't know how to edit, so I've hidden it with CSS (super hacky!)
var control = L.control.attribution({
    prefix: 'Map imagery by MapBox. Data © OpenStreetMap contributors.'
}).addTo(map)

// Set up truck icon
var truckMarker = L.icon({
    iconUrl: 'img/marker-truck.svg',

    iconSize:     [70, 60], // size of the icon
    iconAnchor:   [35, 50], // point of the icon which will correspond to marker's location
    popupAnchor:  [3, -55] // point from which the popup should open relative to the iconAnchor
})

var truckMarkerOff = L.icon({
    iconUrl: 'img/marker-truck-off.svg',

    iconSize:     [70, 60],
    iconAnchor:   [35, 50],
    popupAnchor:  [3, -55]
})

// Get data
var data = document.data()

// This information is now also available back in main.js
var locations = data.locations // this is a GeoJSON format
var trucks = data.trucks
var calendar = data.calendar

// Populate map with locations
var markers = L.mapbox.markerLayer(locations, {
    filter: function (feature) {
        return true
        // disabled active filter
        // return feature.properties.status === 'active'
    }
}).eachLayer(function (marker) {

    // set options here directly on the marker object
    marker.options.icon = truckMarkerOff  // set this to be off by default
    marker.options.riseOnHover = true

    // shorthand for where things are stored in the GeoJSON
    var markerID = marker.feature.id

    for (i = 0; i < calendar.now.length; i++) {
        if (calendar.now[i].at == markerID ) {
            for (j =0; j < trucks.length; j++) {
                if (trucks[j].id == calendar.now[i].truck) {
                    marker.truck = trucks[j]
                    break
                }
            }
            marker.calendar = calendar.now[i]
            break
        }
    }

    // Popup construction
    var popupHTML = 'No truck at ' + marker.feature.properties.name + '
' + marker.feature.properties.address
    if (marker.truck) {
        var popupHTML = '' + marker.truck.name + ' is at ' + marker.feature.properties.name + '
' + marker.feature.properties.address + '
until ' + marker.calendar.until
        marker.options.icon = truckMarker //turn on truck
    }

    marker.bindPopup(popupHTML, {
        closeButton: false,
        minWidth: 200,
        autoPanPadding: [20, 40]
    })

    // Center marker on click
    marker.on('click', function (e) {
        map.panTo(marker.getLatLng())
    })
}).addTo(map)

// Set view based on locations
map.fitBounds(markers.getBounds().pad(0.25))
map.setMaxBounds(markers.getBounds().pad(6))

// Open popups on mouseover (test)
markers.on('mouseover', function (e) {
    e.layer.openPopup()
})
/*
markers.on('mouseout', function (e) {
    e.layer.closePopup()
})
*/

// Popups test
/*
markers.on('click',function (e) {
    e.layer.unbindPopup();

    var mPopup = $('#m-popup').html()
    var popupObject = {}

    var i = 1

    var feature = e.layer.feature;
    popupObject.location = feature.properties.name
    popupObject.address = feature.properties.address
    popupObject.name = trucks[i].name
    popupObject.until = trucks[i].until

    $('#popup-layer').html(Mustache.render(mPopup, popupObject))
    $('#popup').fadeIn(200)
});
// Clear the tooltip when map is clicked
map.on('click',function (e) {
    $('#popup').fadeOut(200)
});
*/<|endoftext|>


<commit_before>module.exports = function (grunt)
{
	grunt.initConfig
	({
		pkg: grunt.file.readJSON('package.json'),

		concat:
		{
			all:
			{
				files:
				{
					// conbo-lite.js

					'build/conbo-lite.js':
					[
					 	'src/conbo/header-lite.txt',
					 	'src/conbo/conbo.js',
					 	'src/conbo/utils/utils.js',
					 	'src/conbo/core/Class.js',
					 	'src/conbo/core/Namespace.js',
						'src/conbo/core/ServerApplication.js',
						'src/conbo/events/Event.js',
						'src/conbo/events/ConboEvent.js',
						'src/conbo/events/EventDispatcher.js',
						'src/conbo/data/Hash.js',
						'src/conbo/data/LocalHash.js',
					 	'src/conbo/utils/Promise.js',
						'src/conbo/view/Glimpse.js',
						'src/conbo/footer.txt'
					],

					// conbo.js

					'build/conbo.js':
					[
						'src/conbo/header.txt',
					 	'src/conbo/conbo.js',
					 	'src/conbo/utils/utils.js',
					 	'src/conbo/utils/dom.js',
					 	'src/conbo/utils/css.js',
					 	'src/conbo/core/Class.js',
					 	'src/conbo/core/Namespace.js',
					 	'src/conbo/core/IInjectable.js',
					 	'src/conbo/core/IPreinitialize.js',
						'src/conbo/events/Event.js',
						'src/conbo/events/ConboEvent.js',
						'src/conbo/events/EventDispatcher.js',
						'src/conbo/core/Context.js',
						'src/conbo/data/Hash.js',
						'src/conbo/data/LocalHash.js',
						'src/conbo/collections/List.js',
						'src/conbo/collections/LocalList.js',
						'src/conbo/utils/AttributeBindings.js',
						'src/conbo/utils/BindingUtils.js',
						'src/conbo/utils/MutationObserver.js',
					 	'src/conbo/utils/Promise.js',
					 	'src/conbo/view/IDataRenderer.js',
						'src/conbo/view/Glimpse.js',
						'src/conbo/view/View.js',
						'src/conbo/view/ItemRenderer.js',
						'src/conbo/core/Application.js',
						'src/conbo/core/Command.js',
						'src/conbo/net/HttpService.js',
						'src/conbo/net/AsyncToken.js',
						'src/conbo/net/Responder.js',
						'src/conbo/net/ISyncable.js',
						'src/conbo/data/RemoteHash.js',
						'src/conbo/collections/RemoteList.js',
						'src/conbo/net/History.js',
						'src/conbo/net/Router.js',
						'src/conbo/footer.txt'
					]
				}
			}
		},

		uglify:
		{
			options:
			{
				mangle:
				{
					screw_ie8: true,
					toplevel: true
				},

				compress:
				{
					screw_ie8: true,
					negate_iife: true
				}
			},

			lite:
			{
				src: 'build/conbo-lite.js',
				dest: 'build/conbo-lite.min.js'
			},

			complete:
			{
				src: 'build/conbo.js',
				dest: 'build/conbo.min.js',
				mangle: true
			}
		},

		watch:
		{
			js:
			{
				files: ['src/conbo/**/*.js', 'src/conbo/*.txt'],
				tasks: ['concat','uglify']
			}
		},

		jsdoc:
		{
			dist:
			{
				src: ['build/conbo.js'],
				options:
				{
					configure: 'jsdoc.json',
					destination: 'docs',
					readme: 'README.md',
					package: 'package.json',
					access: 'public'
				}
			}
		},

		'string-replace':
		{
			version:
			{
				files:
				{
					'build/conbo.js': 'build/conbo.js',
					'build/conbo-lite.js': 'build/conbo-lite.js',
					'bower.json': 'bower.json'
				},

				options:
				{
					replacements:
					[
						// JS
						{
							pattern: /{{VERSION}}/g,
							replacement: '<%= pkg.version %>'
						},
						// JSON
						{
							pattern: /\"version\": \"\d+.\d+.\d+\"/,
							replacement: '"version": "<%= pkg.version %>"'
						}
					]
				}
			}
		},

	});

//	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-jsdoc');
	grunt.loadNpmTasks('grunt-string-replace');

	grunt.registerTask('default', ['concat','string-replace','uglify']);//,'jsdoc']);
};
<commit_msg>Updated gruntfile.js<commit_after>module.exports = function (grunt)
{
	grunt.initConfig
	({
		pkg: grunt.file.readJSON('package.json'),

		concat:
		{
			all:
			{
				files:
				{
					// conbo-lite.js

					'build/conbo-lite.js':
					[
					 	'src/conbo/header-lite.txt',
					 	'src/conbo/conbo.js',
					 	'src/conbo/utils/utils.js',
					 	'src/conbo/core/Class.js',
					 	'src/conbo/core/Namespace.js',
						'src/conbo/core/ServerApplication.js',
						'src/conbo/events/Event.js',
						'src/conbo/events/ConboEvent.js',
						'src/conbo/events/EventDispatcher.js',
						'src/conbo/data/Hash.js',
						'src/conbo/data/LocalHash.js',
					 	'src/conbo/utils/Promise.js',
						'src/conbo/view/Glimpse.js',
						'src/conbo/footer.txt'
					],

					// conbo.js

					'build/conbo.js':
					[
						'src/conbo/header.txt',
					 	'src/conbo/conbo.js',
					 	'src/conbo/utils/utils.js',
					 	'src/conbo/utils/dom.js',
					 	'src/conbo/utils/css.js',
					 	'src/conbo/core/Class.js',
					 	'src/conbo/core/Namespace.js',
					 	'src/conbo/core/IInjectable.js',
					 	'src/conbo/core/IPreinitialize.js',
						'src/conbo/events/Event.js',
						'src/conbo/events/ConboEvent.js',
						'src/conbo/events/EventDispatcher.js',
						'src/conbo/core/Context.js',
						'src/conbo/data/Hash.js',
						'src/conbo/data/LocalHash.js',
						'src/conbo/collections/List.js',
						'src/conbo/collections/LocalList.js',
						'src/conbo/utils/AttributeBindings.js',
						'src/conbo/utils/BindingUtils.js',
						'src/conbo/utils/MutationObserver.js',
					 	'src/conbo/utils/Promise.js',
					 	'src/conbo/view/IDataRenderer.js',
						'src/conbo/view/Glimpse.js',
						'src/conbo/view/View.js',
						'src/conbo/view/ItemRenderer.js',
						'src/conbo/core/Application.js',
						'src/conbo/core/Command.js',
						'src/conbo/net/HttpService.js',
						'src/conbo/net/AsyncToken.js',
						'src/conbo/net/Responder.js',
						'src/conbo/net/ISyncable.js',
						'src/conbo/data/RemoteHash.js',
						'src/conbo/collections/RemoteList.js',
						'src/conbo/net/History.js',
						'src/conbo/net/Router.js',
						'src/conbo/footer.txt'
					]
				}
			}
		},

		uglify:
		{
			options:
			{
				mangle:
				{
					screw_ie8: true,
					toplevel: true
				},

				compress:
				{
					screw_ie8: true,
					negate_iife: true
				}
			},

			lite:
			{
				src: 'build/conbo-lite.js',
				dest: 'build/conbo-lite.min.js'
			},

			complete:
			{
				src: 'build/conbo.js',
				dest: 'build/conbo.min.js',
				mangle: true
			}
		},

		watch:
		{
			js:
			{
				files: ['src/conbo/**/*.js', 'src/conbo/*.txt'],
				tasks: ['concat','string-replace','uglify']
			}
		},

		jsdoc:
		{
			dist:
			{
				src: ['build/conbo.js'],
				options:
				{
					configure: 'jsdoc.json',
					destination: 'docs',
					readme: 'README.md',
					package: 'package.json',
					access: 'public'
				}
			}
		},

		'string-replace':
		{
			version:
			{
				files:
				{
					'build/conbo.js': 'build/conbo.js',
					'build/conbo-lite.js': 'build/conbo-lite.js',
					'bower.json': 'bower.json'
				},

				options:
				{
					replacements:
					[
						// JS
						{
							pattern: /{{VERSION}}/g,
							replacement: '<%= pkg.version %>'
						},
						// JSON
						{
							pattern: /\"version\": \"\d+.\d+.\d+\"/,
							replacement: '"version": "<%= pkg.version %>"'
						}
					]
				}
			}
		},

	});

//	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-jsdoc');
	grunt.loadNpmTasks('grunt-string-replace');

	grunt.registerTask('default', ['concat','string-replace','uglify']);//,'jsdoc']);
};
<|endoftext|>


<commit_before>var crudlet = require("../");
var expect  = require("expect.js");
var through = require("through2");
var _       = require("highland");

describe(__filename + "#", function() {

  it("can map data to another value", function(next) {

    function db(name, props) {
      return _([{ name: "a" }, { name: "b" }]);
    }

    db().
    pipe(_.pipeline(
      _.map(function(d) { return d.name; }),
      _.collect
    )).
    on("data", function(items) {
      expect(items[0]).to.be("a");
      expect(items[1]).to.be("b");
      next();
    });
  });

});
<commit_msg>cleanup<commit_after>var crudlet = require("../");
var expect  = require("expect.js");
var through = require("through2");
var _       = require("highland");

describe(__filename + "#", function() {

  it("can map data to another value", function(next) {

    function db(name, props) {
      return _([{ name: "a" }, { name: "b" }]);
    }

    db().
    pipe(_.pipeline(
      _.map(function(d) { return d.name; }),
      _.collect
    )).
    on("data", function(items) {
      expect(items[0]).to.be("a");
      expect(items[1]).to.be("b");
      next();
    });
  });
});
<|endoftext|>


<commit_before>Map = {
  markers: [],
  newHitReceived: function(data) {
    var latLng = new google.maps.LatLng(data.lat, data.lng);

    var amount = (data.amount > 0) ? data.amount : 1;
    var marker = new StyledMarker({
      styleIcon: new StyledIcon(
        StyledIconTypes.BUBBLE,
        {
          color:"fff",
          text: "€" + amount
        }),
      position: latLng,
      map: Map.google_map,
      animation: google.maps.Animation.DROP,
      created_at: new Date()
    });
    Map.markers.push(marker);

  },
  google_map: null,

  createMap: function() {
    if (Map.google_map == null) {
      layer = "watercolor"
      var mapOptions = {
        zoom: 2,
        center: new google.maps.LatLng(35,13),
        mapTypeId: layer
      };

      Map.google_map = new google.maps.Map(document.getElementById("map"), mapOptions);
      Map.google_map.mapTypes.set(layer, new google.maps.StamenMapType(layer));

      var map_height = $(window).height() - $("header").height() - $("#last_donation").height() - 3; //3 is for #last_donation border
      $('#map').css({'height': map_height + "px", 'width': '100%'});
    }
  },

  clearOldMarkers: function() {
    for (var n = Map.markers.length -1; n >= 0; n--) {
      marker = Map.markers[n];

      if(isOlderThan24hours(marker.created_at)){
        Map.markers.remove(n);
        marker.setMap(null);
      }
    }
  }

}

function isOlderThan24hours(date){
  now = new Date();
  diff = now.getTime() - date.getTime();

  one_day = 1000 * 60 * 60 * 24;

  return (diff > one_day)
}<commit_msg>Avoid hacking vendored StyledMarker class<commit_after>Map = {
  markers: [],
  newHitReceived: function(data) {
    var latLng = new google.maps.LatLng(data.lat, data.lng);

    var amount = (data.amount > 0) ? data.amount : 1;
    var marker = new StyledMarker({
      styleIcon: new StyledIcon(
        StyledIconTypes.BUBBLE,
        {
          color:"fff",
          text: "€" + amount
        }),
      position: latLng,
      map: Map.google_map,
      animation: google.maps.Animation.DROP,
      created_at: new Date()
    });
    Map.markers.push(marker);

  },
  google_map: null,

  createMap: function() {
    if (Map.google_map == null) {
      layer = "watercolor"
      var mapOptions = {
        zoom: 2,
        center: new google.maps.LatLng(35,13),
        mapTypeId: layer
      };

      Map.google_map = new google.maps.Map(document.getElementById("map"), mapOptions);
      Map.google_map.mapTypes.set(layer, new google.maps.StamenMapType(layer));

      var map_height = $(window).height() - $("header").height() - $("#last_donation").height() - 3; //3 is for #last_donation border
      $('#map').css({'height': map_height + "px", 'width': '100%'});
    }
  },

  clearOldMarkers: function() {
    for (var n = Map.markers.length -1; n >= 0; n--) {
      marker = Map.markers[n];

      if(isOlderThan24hours(marker.get("created_at"))){
        Map.markers.remove(n);
        marker.setMap(null);
      }
    }
  }

}

function isOlderThan24hours(date){
  now = new Date();
  diff = now.getTime() - date.getTime();

  one_day = 1000 * 60 * 60 * 24;

  return (diff > one_day)
}
<|endoftext|>


<commit_before>// gruntfile.js
//
// Author: blinklv <blinklv@icloud.com>
// Create Time: 2017-03-22
// Maintainer: blinklv <blinklv@icloud.com>
// Last Change: 2017-05-03
// Purpose: The gruntfile.js for Web development.

module.exports = function(grunt) {

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

        // Watch all files.
        watch: {
            sass: {
                files: ["sass/*.sass", "sass/*.scss"],
                tasks: ["sass", "concat:css"]
            },
            css: {
                files: ["css/*.css", "!css/*.min.css"],
                tasks: ["concat:css"]
            },
            js: {
                files: ["js/*.js", "!js/main.js","!js/*.min.js"],
                tasks: ["concat:js", "jshint"]
            },
            html: {
                files: ["index.html", "html/**/*.html"],
                tasks: ["copy:devel"]
            },
            img: {
                files: ["img/**/*.{gif,jpg,jpeg,png,svg}"],
                tasks: ["responsive_images", "copy:devel"]
            }
        },

        // Copy files to build/devel directory.
        copy: {
            devel: {
                files: [{
                    expand: true,
                    flatten: true,
                    cwd: "vendor/",
                    src: ["**/*.css", "!**/*.min.css"],
                    dest: "build/devel/css/",
                },{
                    expand: true,
                    flatten: true,
                    cwd: "vendor/",
                    src: ["**/*.js", "!**/*.min.js"],
                    dest: "build/devel/js/",
                },{
                    expand: true,
                    src: ["index.html", "html/**/*.html"],
                    dest: "build/devel/"
                },{
                    expand: true,
                    cwd: "img/",
                    src: ["**/*.svg"],
                    dest: "build/devel/img/"
                },{
                    expand: true,
                    cwd: "font/",
                    src: ["**/*.woff", "**/*.woff2"],
                    dest: "build/devel/font/"
                }]
            },
            release: {
                files: [{
                    expand: true,
                    cwd: "build/devel/",
                    src: ["index.html", "html/**/*.html"],
                    dest: "build/release/"
                },{
                    expand: true,
                    cwd: "build/devel/img/",
                    src: ["**/*.{gif,jpg,jpeg,png,svg}"],
                    dest: "build/release/img/"
                },{
                    expand: true,
                    cwd: "build/devel/font/",
                    src: ["**/*.woff", "**/*.woff2"],
                    dest: "build/release/font/"
                }]
            }
        },

        // Generate multi-resolution images.
        responsive_images: {
            normal: {
                options: {
                    engine: "im",
                    sizes: [{
                        name: "s",
                        width: 320,
                        quality: 70
                    },{
                        name: "m",
                        width: 480,
                        quality: 70
                    },{
                        name: "l",
                        width: 600,
                        quality: 70
                    },{
                        name: "xl",
                        width: 1024,
                        quality: 70
                    },{
                        name: "xxl",
                        width: 1440,
                        quality: 70
                    }]
                },
                files: [{
                    expand: true,
                    cwd: "img/",
                    src: ["**/*.{gif,jpg,jpeg,png}","!**/logo.{gif,jpg,jpeg,png}","!**/*{-,_}logo.{gif,jpg,jpeg,png}"],
                    dest: "build/devel/img/"
                }]
            },

            // The shape of orignal logo picture is preferably square.
            logo: {
                options: {
                    engine: "im",
                    sizes: [{
                        name: "s",
                        width: 48
                    },{
                        name: "m",
                        width: 128,
                        quality: 90
                    },{
                        name: "l",
                        width: 256,
                        quality: 70
                    }]
                },
                files: [{
                    expand: true,
                    cwd: "img/",
                    src: ["**/logo.{gif,jpg,jpeg,png}", "**/*{-,_}logo.{gif,jpg,jpeg,png}"],
                    dest: "build/devel/img/"
                }]
            }
        },

        jshint: {
            options: {
                curly: true,
                eqeqeq: true,
                eqnull: true,
                browser: true,
                globals: {
                    jQuery: true
                },
            },
            target: ["gruntfile.js", "js/*.js", "build/devel/js/main.js"]
        },

        // Concatenate files, but exclude some files of 'min' suffix.
        concat: {
            css: {
                src: ["css/*.css", "font/*.css", "!css/main.css","!css/*.min.css"],
                dest: "build/devel/css/main.css"
            },
            js: {
                src: ["js/*.js", "!js/main.js", "!js/*.min.js"],
                dest: "build/devel/js/main.js"
            }
        },

        // Compiling SASS files to CSS files.
        sass: {
            target: {
                files: [{
                    expand: true,
                    cwd: "sass/",
                    src: ["*.sass", "*.scss"],
                    dest: "css/",
                    ext: ".css"
                }]
            }
        },

        // Remove unused CSS.
        uncss: {
            target: {
                files: {
                    "build/devel/css/tidy.css": "build/devel/**/*.html"
                }
            }
        },

        // Minifying CSS files.
        cssmin: {
            target: {
                src: "build/devel/css/tidy.css",
                dest: "build/release/css/main.min.css"
            }
        },

        // Minifying JS files.
        uglify: {
            options: {
                mangle: false,
                compress: {
                    drop_console: true
                }
            },
            target: {
                files: [{
                    expand: true,
                    flatten: true,
                    cwd: "build/devel/js/",
                    src: "**/*.js",
                    dest: "build/release/js/",
                    ext: ".min.js",
                    extDot: "last"
                }]
            }
        },

        // Adding a banner information to some files.
        usebanner: {
            options: {
                position: "top",
                banner: "<%= create_banner() %>"
            },
            css: {
                src: "build/devel/css/main.css"
            },
            js: {
                src: "build/devel/js/main.js"
            }
        },

        clean: {
            devel: ["build/devel"],
            release: ["build/release"]
        },

        // Auxiliary method.
        create_banner: function() {
            var str = "";
            var pkg = this.pkg;

            // If 'pkg.name' is empty, the 'banner' is empty too.
            if (pkg.name) {
                str = "/*! " + pkg.name;
                str = pkg.version ? str + " v" + pkg.version : str;
                str += " " + grunt.template.today("yyyy-mm-dd");
                str = pkg.license ? str + " | " + pkg.license : str;
                str = pkg.url ? str +  " | " + pkg.url : str;
                str += " */";
            }

            return str;
        }
    });

    grunt.loadNpmTasks("grunt-contrib-watch");
    grunt.loadNpmTasks("grunt-responsive-images");
    grunt.loadNpmTasks("grunt-contrib-jshint");
    grunt.loadNpmTasks("grunt-contrib-copy");
    grunt.loadNpmTasks("grunt-uncss");
    grunt.loadNpmTasks("grunt-contrib-sass");
    grunt.loadNpmTasks("grunt-contrib-concat");
    grunt.loadNpmTasks("grunt-contrib-cssmin");
    grunt.loadNpmTasks("grunt-contrib-uglify");
    grunt.loadNpmTasks("grunt-contrib-clean");
    grunt.loadNpmTasks("grunt-banner");

    grunt.registerTask("devel", ["sass", "concat", "jshint", "usebanner", "responsive_images", "copy:devel"]);
    grunt.registerTask("release", ["devel", "uncss", "cssmin", "uglify", "copy:release"]);
    grunt.registerTask("rebuild-devel", ["clean:devel", "devel"]);
    grunt.registerTask("rebuild", ["clean", "release"]);
    grunt.registerTask("default", ["release"]);
};

<commit_msg>Update gruntfile.js<commit_after>// gruntfile.js
//
// Author: blinklv <blinklv@icloud.com>
// Create Time: 2017-03-22
// Maintainer: blinklv <blinklv@icloud.com>
// Last Change: 2017-05-03
// Purpose: The gruntfile.js for Web development.

module.exports = function(grunt) {

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

        // Watch all files.
        watch: {
            sass: {
                files: ["sass/*.sass", "sass/*.scss"],
                tasks: ["sass", "concat:css"]
            },
            css: {
                files: ["css/*.css", "!css/*.min.css"],
                tasks: ["concat:css"]
            },
            js: {
                files: ["js/*.js", "!js/main.js","!js/*.min.js"],
                tasks: ["concat:js", "jshint"]
            },
            html: {
                files: ["index.html", "html/**/*.html"],
                tasks: ["copy:devel"]
            },
            img: {
                files: ["img/**/*.{gif,jpg,jpeg,png,svg}"],
                tasks: ["responsive_images", "copy:devel"]
            }
        },

        // Copy files to build/devel directory.
        copy: {
            devel: {
                files: [{
                    expand: true,
                    flatten: true,
                    cwd: "vendor/",
                    src: ["**/*.css", "!**/*.min.css"],
                    dest: "build/devel/css/",
                },{
                    expand: true,
                    flatten: true,
                    cwd: "vendor/",
                    src: ["**/*.js", "!**/*.min.js"],
                    dest: "build/devel/js/",
                },{
                    expand: true,
                    src: ["index.html", "html/**/*.html"],
                    dest: "build/devel/"
                },{
                    expand: true,
                    cwd: "img/",
                    src: ["**/*.svg"],
                    dest: "build/devel/img/"
                },{
                    expand: true,
                    cwd: "font/",
                    src: ["**/*.woff", "**/*.woff2"],
                    dest: "build/devel/css/font/"
                }]
            },
            release: {
                files: [{
                    expand: true,
                    cwd: "build/devel/",
                    src: ["index.html", "html/**/*.html"],
                    dest: "build/release/"
                },{
                    expand: true,
                    cwd: "build/devel/img/",
                    src: ["**/*.{gif,jpg,jpeg,png,svg}"],
                    dest: "build/release/img/"
                },{
                    expand: true,
                    cwd: "build/devel/css/font/",
                    src: ["**/*.woff", "**/*.woff2"],
                    dest: "build/release/css/font/"
                }]
            }
        },

        // Generate multi-resolution images.
        responsive_images: {
            normal: {
                options: {
                    engine: "im",
                    sizes: [{
                        name: "s",
                        width: 320,
                        quality: 70
                    },{
                        name: "m",
                        width: 480,
                        quality: 70
                    },{
                        name: "l",
                        width: 600,
                        quality: 70
                    },{
                        name: "xl",
                        width: 1024,
                        quality: 70
                    },{
                        name: "xxl",
                        width: 1440,
                        quality: 70
                    }]
                },
                files: [{
                    expand: true,
                    cwd: "img/",
                    src: ["**/*.{gif,jpg,jpeg,png}","!**/logo.{gif,jpg,jpeg,png}","!**/*{-,_}logo.{gif,jpg,jpeg,png}"],
                    dest: "build/devel/img/"
                }]
            },

            // The shape of orignal logo picture is preferably square.
            logo: {
                options: {
                    engine: "im",
                    sizes: [{
                        name: "s",
                        width: 48
                    },{
                        name: "m",
                        width: 128,
                        quality: 90
                    },{
                        name: "l",
                        width: 256,
                        quality: 70
                    }]
                },
                files: [{
                    expand: true,
                    cwd: "img/",
                    src: ["**/logo.{gif,jpg,jpeg,png}", "**/*{-,_}logo.{gif,jpg,jpeg,png}"],
                    dest: "build/devel/img/"
                }]
            }
        },

        jshint: {
            options: {
                curly: true,
                eqeqeq: true,
                eqnull: true,
                browser: true,
                globals: {
                    jQuery: true
                },
            },
            target: ["gruntfile.js", "js/*.js", "build/devel/js/main.js"]
        },

        // Concatenate files, but exclude some files of 'min' suffix.
        concat: {
            css: {
                src: ["css/*.css", "font/*.css", "!css/main.css","!css/*.min.css"],
                dest: "build/devel/css/main.css"
            },
            js: {
                src: ["js/*.js", "!js/main.js", "!js/*.min.js"],
                dest: "build/devel/js/main.js"
            }
        },

        // Compiling SASS files to CSS files.
        sass: {
            target: {
                files: [{
                    expand: true,
                    cwd: "sass/",
                    src: ["*.sass", "*.scss"],
                    dest: "css/",
                    ext: ".css"
                }]
            }
        },

        // Remove unused CSS.
        uncss: {
            target: {
                files: {
                    "build/devel/css/tidy.css": "build/devel/**/*.html"
                }
            }
        },

        // Minifying CSS files.
        cssmin: {
            target: {
                src: "build/devel/css/tidy.css",
                dest: "build/release/css/main.min.css"
            }
        },

        // Minifying JS files.
        uglify: {
            options: {
                mangle: false,
                compress: {
                    drop_console: true
                }
            },
            target: {
                files: [{
                    expand: true,
                    flatten: true,
                    cwd: "build/devel/js/",
                    src: "**/*.js",
                    dest: "build/release/js/",
                    ext: ".min.js",
                    extDot: "last"
                }]
            }
        },

        // Adding a banner information to some files.
        usebanner: {
            options: {
                position: "top",
                banner: "<%= create_banner() %>"
            },
            css: {
                src: "build/devel/css/main.css"
            },
            js: {
                src: "build/devel/js/main.js"
            }
        },

        clean: {
            devel: ["build/devel"],
            release: ["build/release"]
        },

        // Auxiliary method.
        create_banner: function() {
            var str = "";
            var pkg = this.pkg;

            // If 'pkg.name' is empty, the 'banner' is empty too.
            if (pkg.name) {
                str = "/*! " + pkg.name;
                str = pkg.version ? str + " v" + pkg.version : str;
                str += " " + grunt.template.today("yyyy-mm-dd");
                str = pkg.license ? str + " | " + pkg.license : str;
                str = pkg.url ? str +  " | " + pkg.url : str;
                str += " */";
            }

            return str;
        }
    });

    grunt.loadNpmTasks("grunt-contrib-watch");
    grunt.loadNpmTasks("grunt-responsive-images");
    grunt.loadNpmTasks("grunt-contrib-jshint");
    grunt.loadNpmTasks("grunt-contrib-copy");
    grunt.loadNpmTasks("grunt-uncss");
    grunt.loadNpmTasks("grunt-contrib-sass");
    grunt.loadNpmTasks("grunt-contrib-concat");
    grunt.loadNpmTasks("grunt-contrib-cssmin");
    grunt.loadNpmTasks("grunt-contrib-uglify");
    grunt.loadNpmTasks("grunt-contrib-clean");
    grunt.loadNpmTasks("grunt-banner");

    grunt.registerTask("devel", ["sass", "concat", "jshint", "usebanner", "responsive_images", "copy:devel"]);
    grunt.registerTask("release", ["devel", "uncss", "cssmin", "uglify", "copy:release"]);
    grunt.registerTask("rebuild-devel", ["clean:devel", "devel"]);
    grunt.registerTask("rebuild", ["clean", "release"]);
    grunt.registerTask("default", ["release"]);
};

<|endoftext|>


<commit_before>Engine.NextLevel = {
	render: function(dt){
		app.layer.clear("#224");

		app.layer.font("48px Arial")
			.fillStyle("#fff")
			.fillText("" + Engine.player.level,app.width/2 - 10,app.height/2);
	},

	mousedown: function(event){
		if(event.button == "left")
			app.setState(Engine.Map);

	}
};

Engine.GameOver = {
	render: function(dt){
		app.layer.clear("#224");

		app.layer.font("48px Arial")
			.fillStyle("#fff")
			.fillText("Game Over: " + Engine.player.level,app.width/2 - 150,app.height/2);
	},

	mousedown: function(event){
		if(event.button == "left"){
			Engine.player = null;
			app.setState(Engine.Map);
		}
	}
};

Engine.Map = {
	create: function() {

	},

	enter: function() {
		this.bit = [0.5,0.5,0.5];
		Engine.generateMap();

		app.tween(this.bit).to({
			0: 1
		},Utils.randomR(1,2),"02130").loop();

		app.tween(this.bit).to({
			1: 1
		},Utils.randomR(1,2),"02130").loop();

		app.tween(this.bit).to({
			2: 1
		},Utils.randomR(1,2),"02130").loop();
	},

	leave: function() {

	},

	step: function(dt) {
		Engine.camera.x = (app.width / 2) - ((Engine.player.x) * (Engine.camera.scale * Engine.tileSize + Engine.tileMargin)) - Engine.tileMargin;
		Engine.camera.y = (app.height / 2) - ((Engine.player.y) * (Engine.camera.scale * Engine.tileSize + Engine.tileMargin)) - Engine.tileMargin;

	},

	render: function(dt) {
		app.layer.clear("#224");
		app.layer.save().translate(Engine.camera.x,Engine.camera.y);

		for(var i in Engine.go)
			Engine.go[i].render(dt);
		app.layer.restore();

		for(var i = 0; i < Engine.player.lifes; i++){
			app.layer
				.save()
				.translate(32 + 32 * i,32)
				.align(0.5)
				.scale(this.bit[i % 3],this.bit[i % 3])
				.drawAtlasFrame(app.atlases.ui,3 + i % 3,0,0)
				.restore();
		}

		if(Engine.player.key){
			app.layer
				.save()
				.translate(32,64+32)
				.align(0.5)
				.drawAtlasFrame(app.atlases.ui,6,0,0)
				.restore();
		}

	},

	mousedown: function(event) {
		if(event.button == "left"){
			var x = event.x - (Engine.camera.x);
			var y = event.y - (Engine.camera.y);
			x = Math.floor(x / (Engine.camera.scale * Engine.tileSize + Engine.tileMargin) + 0.5);
			y = Math.floor(y / (Engine.camera.scale * Engine.tileSize + Engine.tileMargin) + 0.5);
			Engine.player.player.input(x,y);
		}
	},

	touchstart: function(event) {
    	var x = event.x - (Engine.camera.x);
		var y = event.y - (Engine.camera.y);
		x = Math.floor(x / (Engine.camera.scale * Engine.tileSize + Engine.tileMargin) + 0.5);
		y = Math.floor(y / (Engine.camera.scale * Engine.tileSize + Engine.tileMargin) + 0.5);
		Engine.player.player.input(x,y);
	},

	keyup: function(event){
	}
};<commit_msg>Keyboard support<commit_after>Engine.NextLevel = {
	render: function(dt){
		app.layer.clear("#224");

		app.layer.font("48px Arial")
			.fillStyle("#fff")
			.fillText("" + Engine.player.level,app.width/2 - 10,app.height/2);
	},

	mousedown: function(event){
		if(event.button == "left")
			app.setState(Engine.Map);

	},

	keydown: function(event){
		app.setState(Engine.Map);
	}
};

Engine.GameOver = {
	render: function(dt){
		app.layer.clear("#224");

		app.layer.font("48px Arial")
			.fillStyle("#fff")
			.fillText("Game Over: " + Engine.player.level,app.width/2 - 150,app.height/2);
	},

	mousedown: function(event){
		if(event.button == "left"){
			Engine.player = null;
			app.setState(Engine.Map);
		}
	},

	keydown: function(event){
		Engine.player = null;
		app.setState(Engine.Map);
	}
};

Engine.Map = {
	create: function() {

	},

	enter: function() {
		this.bit = [0.5,0.5,0.5];
		Engine.generateMap();

		app.tween(this.bit).to({
			0: 1
		},Utils.randomR(1,2),"02130").loop();

		app.tween(this.bit).to({
			1: 1
		},Utils.randomR(1,2),"02130").loop();

		app.tween(this.bit).to({
			2: 1
		},Utils.randomR(1,2),"02130").loop();
	},

	leave: function() {

	},

	step: function(dt) {
		Engine.camera.x = (app.width / 2) - ((Engine.player.x) * (Engine.camera.scale * Engine.tileSize + Engine.tileMargin)) - Engine.tileMargin;
		Engine.camera.y = (app.height / 2) - ((Engine.player.y) * (Engine.camera.scale * Engine.tileSize + Engine.tileMargin)) - Engine.tileMargin;

	},

	render: function(dt) {
		app.layer.clear("#224");
		app.layer.save().translate(Engine.camera.x,Engine.camera.y);

		for(var i in Engine.go)
			Engine.go[i].render(dt);
		app.layer.restore();

		for(var i = 0; i < Engine.player.lifes; i++){
			app.layer
				.save()
				.translate(32 + 32 * i,32)
				.align(0.5)
				.scale(this.bit[i % 3],this.bit[i % 3])
				.drawAtlasFrame(app.atlases.ui,3 + i % 3,0,0)
				.restore();
		}

		if(Engine.player.key){
			app.layer
				.save()
				.translate(32,64+32)
				.align(0.5)
				.drawAtlasFrame(app.atlases.ui,6,0,0)
				.restore();
		}

	},

	mousedown: function(event) {
		if(event.button == "left"){
			var x = event.x - (Engine.camera.x);
			var y = event.y - (Engine.camera.y);
			x = Math.floor(x / (Engine.camera.scale * Engine.tileSize + Engine.tileMargin) + 0.5);
			y = Math.floor(y / (Engine.camera.scale * Engine.tileSize + Engine.tileMargin) + 0.5);
			Engine.player.player.input(x,y);
		}
	},

	touchstart: function(event) {
    	var x = event.x - (Engine.camera.x);
		var y = event.y - (Engine.camera.y);
		x = Math.floor(x / (Engine.camera.scale * Engine.tileSize + Engine.tileMargin) + 0.5);
		y = Math.floor(y / (Engine.camera.scale * Engine.tileSize + Engine.tileMargin) + 0.5);
		Engine.player.player.input(x,y);
	},

	keydown: function(event){
		var x = Engine.player.x, y = Engine.player.y;
		switch(event.key) {
			case "a":
			case "left":
				x--;
				break;
			case "d":
			case "right":
				x++;
				break;
			case "w":
			case "up":
				y--;
				break;
			case "s":
			case "down":
				y++;
				break;

		}
		Engine.player.player.input(x,y);
	}
};<|endoftext|>