<commit_before>module.exports = function(grunt) {
  /*
   * Include grunt configuration
   */
  var gruntConfig = require( './config/grunt.conf.js' );

  /*
   * Helpers (preparing for grunt util deprecation)
   */
  var glob = require('glob');

  /*
   * Time grunt execution
   */
  require('time-grunt')(grunt);

  /*
   * JIT Grunt will automatically load other npm tasks
   */
  require('jit-grunt')(grunt);
  grunt.loadNpmTasks('grunt-protractor-runner');

  /*
   * Configuration
   */
  var gruntTasks = {
    pkg: grunt.file.readJSON('package.json'),
    /*
     * Placed at the top of the compiled source files.
     * Use the 'banner' -> banner: '<%= meta.banner %>'
     *
     */
    meta: {
      banner:
        '/*\n' +
        ' * Compiled <%= grunt.template.today("yyyy-mm-dd") %>\n' +
        ' * Docs @ <%= pkg.repository.url %>\n' +
        ' */\n'
    },
    /*
     * The shell task can run handy shell commands.
     * To configure the dev/prod server check out the 'sh' files
     * in './server'.
     *
     */
    shell: {
      dev_server: {
        command: './server/build-server.sh'
      },
      prod_server: {
        command: './server/production-server.sh'
      },
      run_selenium: {
        command: './node_modules/protractor/bin/webdriver-manager start'
      },
      update_selenium: {
        command: './node_modules/protractor/bin/webdriver-manager update'
      }
    },
    /*
     * The copy task copies files for both build and compile
     * phases, as well as test files.
     *
     * 'build_index' will process the 'index.html' file and write
     * <script> tags for all files (modules or vendor scripts).
     *
     * 'compile_index' will process the 'index.html' file without
     * providing any scripts. In this case, a single script will
     * be included: 'app.min.js'.
     *
     * See './src/index.html' for more details.
     *
     */
    copy: {
      build_app_js: {
        src: [
          findModuleFilesIn('./src/app/'),
          findModuleFilesIn('./src/common/')
        ],
        dest: '<%= build_dir %>'
      },
      build_app_data: {
        src: ['./src/app/**/*.json'],
        dest: '<%= build_dir %>/data/',
        expand: true,
        flatten: true,
        filter: 'isFile'
      },
      build_unit: {
        src: ['./src/**/*.spec.js'],
        dest: '<%= build_dir %>'
      },
      build_vendor_js: {
        src: ['<%= build.vendor_js %>'],
        dest: '<%= build_dir %>'
      },
      build_views: {
        cwd: './src',
        src: ['app/**/*.html', '!app/shared/**/*.html'],
        dest: '<%= build_dir %>/views/',
        expand: true,
        flatten: true,
        filter: 'isFile'
      },
      build_shared_views: {
        cwd: './src',
        src: ['app/shared/**/*.html'],
        dest: '<%= build_dir %>/shared-views/',
        expand: true,
        flatten: true,
        filter: 'isFile'
      },
      build_index: {
        cwd: './src',
        src: ['index.html'],
        dest: '<%= build_dir %>',
        expand: true,
        options: {
          process: processBuildScripts
        }
      },
      build_assets: {
        cwd: './src/assets',
        src: [
          'img/**/*',
          'fonts/**/*',
          '!**/*.less',
          '!**/*.css'
        ],
        dest: '<%= build_dir %>src/assets/',
        expand: true
      },
      build_fonts: {
        src: ['<%= common.vendor_fonts %>'],
        dest: '<%= build_dir %>src/assets/fonts/',
        expand: true,
        flatten: true,
        filter: 'isFile'
      },
      build_karma: {
        src: ['./config/karma.conf.js'],
        dest: '<%= build_dir %>',
        options: {
          process: processBuildScripts
        }
      },
      build_protractor: {
        cwd: './src',
        src: ['**/*.protractor.js', '**/*.e2e.js'],
        dest: '<%= build_dir %>src/e2e/',
        expand: true,
        flatten: true
      },
      compile_app_data: {
        cwd: '<%= build_dir %>',
        src: ['data/*.json'],
        dest: '<%= compile_dir %>',
        expand: true
      },
      compile_views: {
        cwd: '<%= build_dir %>',
        src: ['views/**/*.html'],
        dest: '<%= compile_dir %>',
        expand: true
      },
      compile_index: {
        cwd: './src',
        src: ['index.html'],
        dest: '<%= compile_dir %>',
        expand: true,
        options: {
          process: function processCompileIndex(content){
            return grunt.template.process(content);
          }
        }
      },
      compile_app_assets: {
        cwd: '<%= build_dir %>',
        src: ['src/assets/**/*', '!src/assets/**/*.md'],
        dest: '<%= compile_dir %>',
        expand: true
      }
    },
    /*
     * The clean task is used to remove files / directories that
     * are used and not needed anymore.
     *
     * It's also used to remove the build directory before a new
     * compile, see 'build_clean' below.
     *
     */
    clean: {
      build_clean: ['<%= build_dir %>'],
      build_css_clean: ['<%= build_dir %>/src/assets/css/app.custom.css'],
      compile_js_clean: ['<%= compile_dir %>/src/app/modules.min.js'],
      compile_shared_views_clean: ['<%= compile_dir %>/shared-views/'],
      clean_samples: [
        './src/app/about/',
        './src/app/home/',
        './src/app/profile-feature/',
        './src/app//shared/profile-model'
      ]
    },
    /*
     * The less task compiles all less files.
     * They will be afterwards concatenated with vendor
     * stylesheet, see the 'cssmin' task.
     *
     */
    less: {
      build_less: {
        src: ['./src/assets/**/*.less'],
        dest: '<%= build_dir %>/src/assets/css/app.custom.css',
        options: {
          cleancss: true,
          compress: true
        }
      }
    },
    /*
     * The cssmin task minifies css files and merges them into a
     * single file (done during build).
     *
     */
    cssmin: {
      build_css: {
        src: [
          '<%= build.vendor_css %>',
          './src/assets/**/*.css',
          '<%= build_dir %>/src/assets/css/app.custom.css'
        ],
        dest: '<%= build_dir %>/src/assets/css/app.min.css',
        options: {
          keepSpecialComments: 0,
          banner: '<%= meta.banner %>'
        }
      }
    },
    /*
     * The uglify task mainly minifies and mangles module scripts.
     * After all scripts are concatenated, it minifies without
     * mangling to remove comments, line breaks, etc that come
     * from vendor scripts.
     *
     */
    uglify: {
      compile_module_js: {
        options: {
          wrap: 'moduleExports',
          mangle: {
            except: ['exceptionLoggingService']
          }
        },
        src: [
          '<%= compile.vendor_js %>',
          findModuleFilesIn('./build/src/app/'),
          findModuleFilesIn('./build/src/common/')
        ],
        dest: '<%= compile_dir %>/src/app/modules.min.js'
      },
      compile_soft_uglify: {
        options: {
          mangle: false,
          banner: '<%= meta.banner %>'
        },
        src: ['<%= compile_dir %>/src/app/app.min.js'],
        dest: '<%= compile_dir %>/src/app/app.min.js'
      }
    },
    /*
     * The concat task is used in the compile phase to merge all
     * scripts into one.
     *
     */
    concat: {
      compile_js: {
        src: [
          '<%= compile.vendor_min_js %>',
          '<%= compile_dir %>/src/app/modules.min.js',
          '<%= compile_dir %>/shared-views/views.min.js'
        ],
        dest: '<%= compile_dir %>/src/app/app.min.js',
        options: {
          banner: '<%= meta.banner %>'
        }
      }
    },
    /*
     * The html2js task is used to convert all shared views into a module
     * that adds them to $templateCache. It also minifies HTML
     * markup.
     *
     */
    html2js: {
      options: {
        htmlmin: {
          collapseBooleanAttributes: false,
          collapseWhitespace: true,
          removeAttributeQuotes: false,
          removeComments: true,
          removeEmptyAttributes: false,
          removeRedundantAttributes: true,
          removeScriptTypeAttributes: true,
          removeStyleLinkTypeAttributes: true
        }
      },
      compile_shared_views: {
        src: ['<%= build_dir %>/shared-views/**/*.html'],
        dest: '<%= compile_dir %>/shared-views/views.min.js',
        options: {
          module: 'sharedViewsModule',
          base: './build',
          singleModule: true
        }
      }
    },
    /*
     * The jshint task detects errors and potential problems in
     * the JavaScript source and grunt files.
     *
     */
    jshint: {
      options: {
        jshintrc: true
      },
      src_js: ['./src/**/*.js'],
      gruntfiles: ['./gruntfile.js', 'grunt.conf.js']
    },
    /*
     * Karma is used to run unit tests.
     * It can run continiously (similar to the watch task).
     *
     */
    karma: {
      options: {
        configFile: '<%= build_dir %>/config/karma.conf.js'
      },
      unit: {
        port: 9191,
        background: false
      },
      continuous: {
        singleRun: false,
        autoWatch: true
      }
    },
    /*
     * Protractor is used to run E2E tests. (need a running
     * selenium server).
     *
     * To run locally, 'grunt test', 'grunt test:e2e' and
     * 'grunt protractor:build' will do the job.
     *
     * It also contains configuration for Travis CI.
     * Both '/build' (development) and '/application' (
     * production) paths are covered.
     *
     */
    protractor: {
      options: {
        keepAlive: true, // If false, the grunt process stops when the test fails.
        noColor: false,
        args: {}
      },
      build: {
        options: {
          configFile: './config/protractor.conf.js', //Local tests
        }
      },
      ci_dev: {
        options: {
          configFile: './config/protractor-ci.conf.js'
        }
      },
      ci_prod: {
        options: {
          configFile: './config/protractor-ci-prod.conf.js'
        }
      }
    },
    /*
     * The `watch` task builds JavaScript, HTML and all assets
     * (including tests and the gruntfiles themselves) when any
     * of them are changed.
     *
     */
    watch: {
      options: {
        livereload: true
      },
      src_js: {
        files: ['./src/**/*.js', './src/**/*.json'],
        tasks: ['newer:jshint:src_js', 'newer:copy:build_app_js']
      },
      src_html: {
        files: ['./src/**/*.html', '!./src/index.html'],
        tasks: ['newer:copy:build_views']
      },
      src_index: {
        files: ['./src/index.html'],
        tasks: ['copy:build_index']
      },
      src_stylesheets: {
        files: ['./src/assets/**/*.less', './src/assets/**/*.css'],
        tasks: ['newer:less:build_less', 'cssmin:build_css', 'clean:build_css_clean']
      },
      src_assets: {
        files: ['./src/assets/**/*', '!./src/assets/**/*.less', '!./src/assets/**/*.css'],
        tasks: ['newer:copy:build_assets']
      },
      gruntfiles: {
        files: ['./gruntfile.js', 'grunt.conf.js'],
        tasks: ['newer:jshint:gruntfiles'],
        options: {
          livereload: false
        }
      },
      tests: {
        files: ['src/**/*.spec.js', 'src/**/*.e2e.js', 'src/**/*.protractor.js'],
        tasks: ['newer:copy:build_karma', 'newer:copy:build_unit', 'newer:copy:build_protractor']
      }
    }
  };

  /*
   * When initializing Grunt, it needs to be extended with the
   * 'gruntConfig' object (imported from './config/grunt.conf.js')
   *
   */
  grunt.initConfig(
    grunt.util._.extend(gruntTasks, gruntConfig)
  );

  /*
   * Tasks.
   * Running 'grunt' should be enough for development.
   * When ready for production, 'grunt compile' will compile the
   * application into the './application' directory.
   *
   */
  grunt.registerTask('default', ['build', 'karma:unit', 'watch']);
  grunt.registerTask('build', [
    'jshint',
    'copy:build_app_js',
    'copy:build_app_data',
    'copy:build_vendor_js',
    'copy:build_views',
    'copy:build_shared_views',
    'copy:build_fonts',
    'copy:build_index',
    'copy:build_unit',
    'copy:build_protractor',
    'copy:build_karma',
    'copy:build_assets',
    'less:build_less',
    'cssmin:build_css',
    'clean:build_css_clean'
  ]);
  grunt.registerTask('compile', [
    'jshint',
    'clean:build_clean',
    'build',
    'copy:compile_views',
    'html2js:compile_shared_views',
    'uglify:compile_module_js',
    'concat:compile_js',
    'uglify:compile_soft_uglify',
    'clean:compile_js_clean',
    'clean:compile_shared_views_clean',
    'copy:compile_app_data',
    'copy:compile_app_assets',
    'copy:compile_index'
  ]);
  grunt.registerTask('test', ['karma:unit', 'protractor:build']);
  grunt.registerTask('test:unit', ['karma:unit']);
  grunt.registerTask('test:ci', ['karma:unit', 'protractor:ci_dev', 'protractor:ci_prod']);
  grunt.registerTask('test:e2e', ['protractor:build']);
  grunt.registerTask('dev', ['shell:dev_server']);
  grunt.registerTask('prod', ['shell:prod_server']);

  /*
   * Helper methods.
   * The methods below use the 'module_file_order' Array in
   * 'grunt.conf.js' to easily load modules in a consistent
   * manner, generate globbing patterns or process files.
   *
   * (i.e. the 'index.html' is processed in order to
   * automatically write <script> tags)
   *
   */

  /*
   * Generates a globbing pattern that matches the
   * 'module_file_order' Array in 'grunt.conf.js'.
   *
   * @param {String} modulePath - The module path
   * @returns {Array} output - An Array of globbing patterns
   *
   * (i.e. findModuleFilesIn('./src/app/') loads all module
   * files in './src/app' in the defined order)
   *
   */
  function findModuleFilesIn(modulePath){
    var output = [],
        i;

    for(i = 0; i <= gruntConfig.module_file_order.length-1; i++){
      output.push(modulePath + gruntConfig.module_file_order[i]);
    }

    return output;
  }

  /*
   * 'Manually globs (using 'node-glob')' for all JavaScript files
   * that should be included in the build phase, then stores them
   * into the 'buildScripts' Array. 'buildScripts' is then passed * as 'scripts' to the template.
   * The template is processed (usually loops through 'scripts').
   * (See 'index.html')
   *
   * @param {String} content - File content
   * @returns {String} - Processed content
   *
   */
  function processBuildScripts(content){
    var buildScripts = [],
        globFiles,
        customModules = gruntConfig.build.vendor_js
                        .concat(findModuleFilesIn('./src/app/'))
                        .concat(findModuleFilesIn('./src/common/'));

    customModules.forEach(function(module){
      globFiles = glob.sync(module);

      if(globFiles.length > 0){
        buildScripts = buildScripts.concat(globFiles);
      }
    });

    return grunt.template.process(content, {
      data: {
        scripts: buildScripts
      }
    });
  }
};<commit_msg>added missing 'build:shared_views' task from 'watch'<commit_after>module.exports = function(grunt) {
  /*
   * Include grunt configuration
   */
  var gruntConfig = require( './config/grunt.conf.js' );

  /*
   * Helpers (preparing for grunt util deprecation)
   */
  var glob = require('glob');

  /*
   * Time grunt execution
   */
  require('time-grunt')(grunt);

  /*
   * JIT Grunt will automatically load other npm tasks
   */
  require('jit-grunt')(grunt);
  grunt.loadNpmTasks('grunt-protractor-runner');

  /*
   * Configuration
   */
  var gruntTasks = {
    pkg: grunt.file.readJSON('package.json'),
    /*
     * Placed at the top of the compiled source files.
     * Use the 'banner' -> banner: '<%= meta.banner %>'
     *
     */
    meta: {
      banner:
        '/*\n' +
        ' * Compiled <%= grunt.template.today("yyyy-mm-dd") %>\n' +
        ' * Docs @ <%= pkg.repository.url %>\n' +
        ' */\n'
    },
    /*
     * The shell task can run handy shell commands.
     * To configure the dev/prod server check out the 'sh' files
     * in './server'.
     *
     */
    shell: {
      dev_server: {
        command: './server/build-server.sh'
      },
      prod_server: {
        command: './server/production-server.sh'
      },
      run_selenium: {
        command: './node_modules/protractor/bin/webdriver-manager start'
      },
      update_selenium: {
        command: './node_modules/protractor/bin/webdriver-manager update'
      }
    },
    /*
     * The copy task copies files for both build and compile
     * phases, as well as test files.
     *
     * 'build_index' will process the 'index.html' file and write
     * <script> tags for all files (modules or vendor scripts).
     *
     * 'compile_index' will process the 'index.html' file without
     * providing any scripts. In this case, a single script will
     * be included: 'app.min.js'.
     *
     * See './src/index.html' for more details.
     *
     */
    copy: {
      build_app_js: {
        src: [
          findModuleFilesIn('./src/app/'),
          findModuleFilesIn('./src/common/')
        ],
        dest: '<%= build_dir %>'
      },
      build_app_data: {
        src: ['./src/app/**/*.json'],
        dest: '<%= build_dir %>/data/',
        expand: true,
        flatten: true,
        filter: 'isFile'
      },
      build_unit: {
        src: ['./src/**/*.spec.js'],
        dest: '<%= build_dir %>'
      },
      build_vendor_js: {
        src: ['<%= build.vendor_js %>'],
        dest: '<%= build_dir %>'
      },
      build_views: {
        cwd: './src',
        src: ['app/**/*.html', '!app/shared/**/*.html'],
        dest: '<%= build_dir %>/views/',
        expand: true,
        flatten: true,
        filter: 'isFile'
      },
      build_shared_views: {
        cwd: './src',
        src: ['app/shared/**/*.html'],
        dest: '<%= build_dir %>/shared-views/',
        expand: true,
        flatten: true,
        filter: 'isFile'
      },
      build_index: {
        cwd: './src',
        src: ['index.html'],
        dest: '<%= build_dir %>',
        expand: true,
        options: {
          process: processBuildScripts
        }
      },
      build_assets: {
        cwd: './src/assets',
        src: [
          'img/**/*',
          'fonts/**/*',
          '!**/*.less',
          '!**/*.css'
        ],
        dest: '<%= build_dir %>src/assets/',
        expand: true
      },
      build_fonts: {
        src: ['<%= common.vendor_fonts %>'],
        dest: '<%= build_dir %>src/assets/fonts/',
        expand: true,
        flatten: true,
        filter: 'isFile'
      },
      build_karma: {
        src: ['./config/karma.conf.js'],
        dest: '<%= build_dir %>',
        options: {
          process: processBuildScripts
        }
      },
      build_protractor: {
        cwd: './src',
        src: ['**/*.protractor.js', '**/*.e2e.js'],
        dest: '<%= build_dir %>src/e2e/',
        expand: true,
        flatten: true
      },
      compile_app_data: {
        cwd: '<%= build_dir %>',
        src: ['data/*.json'],
        dest: '<%= compile_dir %>',
        expand: true
      },
      compile_views: {
        cwd: '<%= build_dir %>',
        src: ['views/**/*.html'],
        dest: '<%= compile_dir %>',
        expand: true
      },
      compile_index: {
        cwd: './src',
        src: ['index.html'],
        dest: '<%= compile_dir %>',
        expand: true,
        options: {
          process: function processCompileIndex(content){
            return grunt.template.process(content);
          }
        }
      },
      compile_app_assets: {
        cwd: '<%= build_dir %>',
        src: ['src/assets/**/*', '!src/assets/**/*.md'],
        dest: '<%= compile_dir %>',
        expand: true
      }
    },
    /*
     * The clean task is used to remove files / directories that
     * are used and not needed anymore.
     *
     * It's also used to remove the build directory before a new
     * compile, see 'build_clean' below.
     *
     */
    clean: {
      build_clean: ['<%= build_dir %>'],
      build_css_clean: ['<%= build_dir %>/src/assets/css/app.custom.css'],
      compile_js_clean: ['<%= compile_dir %>/src/app/modules.min.js'],
      compile_shared_views_clean: ['<%= compile_dir %>/shared-views/'],
      clean_samples: [
        './src/app/about/',
        './src/app/home/',
        './src/app/profile-feature/',
        './src/app//shared/profile-model'
      ]
    },
    /*
     * The less task compiles all less files.
     * They will be afterwards concatenated with vendor
     * stylesheet, see the 'cssmin' task.
     *
     */
    less: {
      build_less: {
        src: ['./src/assets/**/*.less'],
        dest: '<%= build_dir %>/src/assets/css/app.custom.css',
        options: {
          cleancss: true,
          compress: true
        }
      }
    },
    /*
     * The cssmin task minifies css files and merges them into a
     * single file (done during build).
     *
     */
    cssmin: {
      build_css: {
        src: [
          '<%= build.vendor_css %>',
          './src/assets/**/*.css',
          '<%= build_dir %>/src/assets/css/app.custom.css'
        ],
        dest: '<%= build_dir %>/src/assets/css/app.min.css',
        options: {
          keepSpecialComments: 0,
          banner: '<%= meta.banner %>'
        }
      }
    },
    /*
     * The uglify task mainly minifies and mangles module scripts.
     * After all scripts are concatenated, it minifies without
     * mangling to remove comments, line breaks, etc that come
     * from vendor scripts.
     *
     */
    uglify: {
      compile_module_js: {
        options: {
          wrap: 'moduleExports',
          mangle: {
            except: ['exceptionLoggingService']
          }
        },
        src: [
          '<%= compile.vendor_js %>',
          findModuleFilesIn('./build/src/app/'),
          findModuleFilesIn('./build/src/common/')
        ],
        dest: '<%= compile_dir %>/src/app/modules.min.js'
      },
      compile_soft_uglify: {
        options: {
          mangle: false,
          banner: '<%= meta.banner %>'
        },
        src: ['<%= compile_dir %>/src/app/app.min.js'],
        dest: '<%= compile_dir %>/src/app/app.min.js'
      }
    },
    /*
     * The concat task is used in the compile phase to merge all
     * scripts into one.
     *
     */
    concat: {
      compile_js: {
        src: [
          '<%= compile.vendor_min_js %>',
          '<%= compile_dir %>/src/app/modules.min.js',
          '<%= compile_dir %>/shared-views/views.min.js'
        ],
        dest: '<%= compile_dir %>/src/app/app.min.js',
        options: {
          banner: '<%= meta.banner %>'
        }
      }
    },
    /*
     * The html2js task is used to convert all shared views into a module
     * that adds them to $templateCache. It also minifies HTML
     * markup.
     *
     */
    html2js: {
      options: {
        htmlmin: {
          collapseBooleanAttributes: false,
          collapseWhitespace: true,
          removeAttributeQuotes: false,
          removeComments: true,
          removeEmptyAttributes: false,
          removeRedundantAttributes: true,
          removeScriptTypeAttributes: true,
          removeStyleLinkTypeAttributes: true
        }
      },
      compile_shared_views: {
        src: ['<%= build_dir %>/shared-views/**/*.html'],
        dest: '<%= compile_dir %>/shared-views/views.min.js',
        options: {
          module: 'sharedViewsModule',
          base: './build',
          singleModule: true
        }
      }
    },
    /*
     * The jshint task detects errors and potential problems in
     * the JavaScript source and grunt files.
     *
     */
    jshint: {
      options: {
        jshintrc: true
      },
      src_js: ['./src/**/*.js'],
      gruntfiles: ['./gruntfile.js', 'grunt.conf.js']
    },
    /*
     * Karma is used to run unit tests.
     * It can run continiously (similar to the watch task).
     *
     */
    karma: {
      options: {
        configFile: '<%= build_dir %>/config/karma.conf.js'
      },
      unit: {
        port: 9191,
        background: false
      },
      continuous: {
        singleRun: false,
        autoWatch: true
      }
    },
    /*
     * Protractor is used to run E2E tests. (need a running
     * selenium server).
     *
     * To run locally, 'grunt test', 'grunt test:e2e' and
     * 'grunt protractor:build' will do the job.
     *
     * It also contains configuration for Travis CI.
     * Both '/build' (development) and '/application' (
     * production) paths are covered.
     *
     */
    protractor: {
      options: {
        keepAlive: true, // If false, the grunt process stops when the test fails.
        noColor: false,
        args: {}
      },
      build: {
        options: {
          configFile: './config/protractor.conf.js', //Local tests
        }
      },
      ci_dev: {
        options: {
          configFile: './config/protractor-ci.conf.js'
        }
      },
      ci_prod: {
        options: {
          configFile: './config/protractor-ci-prod.conf.js'
        }
      }
    },
    /*
     * The `watch` task builds JavaScript, HTML and all assets
     * (including tests and the gruntfiles themselves) when any
     * of them are changed.
     *
     */
    watch: {
      options: {
        livereload: true
      },
      src_js: {
        files: ['./src/**/*.js', './src/**/*.json'],
        tasks: ['newer:jshint:src_js', 'newer:copy:build_app_js']
      },
      src_html: {
        files: ['./src/**/*.html', '!./src/index.html'],
        tasks: ['newer:copy:build_views', 'copy:build_shared_views']
      },
      src_index: {
        files: ['./src/index.html'],
        tasks: ['copy:build_index']
      },
      src_stylesheets: {
        files: ['./src/assets/**/*.less', './src/assets/**/*.css'],
        tasks: ['newer:less:build_less', 'cssmin:build_css', 'clean:build_css_clean']
      },
      src_assets: {
        files: ['./src/assets/**/*', '!./src/assets/**/*.less', '!./src/assets/**/*.css'],
        tasks: ['newer:copy:build_assets']
      },
      gruntfiles: {
        files: ['./gruntfile.js', 'grunt.conf.js'],
        tasks: ['newer:jshint:gruntfiles'],
        options: {
          livereload: false
        }
      },
      tests: {
        files: ['src/**/*.spec.js', 'src/**/*.e2e.js', 'src/**/*.protractor.js'],
        tasks: ['newer:copy:build_karma', 'newer:copy:build_unit', 'newer:copy:build_protractor']
      }
    }
  };

  /*
   * When initializing Grunt, it needs to be extended with the
   * 'gruntConfig' object (imported from './config/grunt.conf.js')
   *
   */
  grunt.initConfig(
    grunt.util._.extend(gruntTasks, gruntConfig)
  );

  /*
   * Tasks.
   * Running 'grunt' should be enough for development.
   * When ready for production, 'grunt compile' will compile the
   * application into the './application' directory.
   *
   */
  grunt.registerTask('default', ['build', 'karma:unit', 'watch']);
  grunt.registerTask('build', [
    'jshint',
    'copy:build_app_js',
    'copy:build_app_data',
    'copy:build_vendor_js',
    'copy:build_views',
    'copy:build_shared_views',
    'copy:build_fonts',
    'copy:build_index',
    'copy:build_unit',
    'copy:build_protractor',
    'copy:build_karma',
    'copy:build_assets',
    'less:build_less',
    'cssmin:build_css',
    'clean:build_css_clean'
  ]);
  grunt.registerTask('compile', [
    'jshint',
    'clean:build_clean',
    'build',
    'copy:compile_views',
    'html2js:compile_shared_views',
    'uglify:compile_module_js',
    'concat:compile_js',
    'uglify:compile_soft_uglify',
    'clean:compile_js_clean',
    'clean:compile_shared_views_clean',
    'copy:compile_app_data',
    'copy:compile_app_assets',
    'copy:compile_index'
  ]);
  grunt.registerTask('test', ['karma:unit', 'protractor:build']);
  grunt.registerTask('test:unit', ['karma:unit']);
  grunt.registerTask('test:ci', ['karma:unit', 'protractor:ci_dev', 'protractor:ci_prod']);
  grunt.registerTask('test:e2e', ['protractor:build']);
  grunt.registerTask('dev', ['shell:dev_server']);
  grunt.registerTask('prod', ['shell:prod_server']);

  /*
   * Helper methods.
   * The methods below use the 'module_file_order' Array in
   * 'grunt.conf.js' to easily load modules in a consistent
   * manner, generate globbing patterns or process files.
   *
   * (i.e. the 'index.html' is processed in order to
   * automatically write <script> tags)
   *
   */

  /*
   * Generates a globbing pattern that matches the
   * 'module_file_order' Array in 'grunt.conf.js'.
   *
   * @param {String} modulePath - The module path
   * @returns {Array} output - An Array of globbing patterns
   *
   * (i.e. findModuleFilesIn('./src/app/') loads all module
   * files in './src/app' in the defined order)
   *
   */
  function findModuleFilesIn(modulePath){
    var output = [],
        i;

    for(i = 0; i <= gruntConfig.module_file_order.length-1; i++){
      output.push(modulePath + gruntConfig.module_file_order[i]);
    }

    return output;
  }

  /*
   * 'Manually globs (using 'node-glob')' for all JavaScript files
   * that should be included in the build phase, then stores them
   * into the 'buildScripts' Array. 'buildScripts' is then passed * as 'scripts' to the template.
   * The template is processed (usually loops through 'scripts').
   * (See 'index.html')
   *
   * @param {String} content - File content
   * @returns {String} - Processed content
   *
   */
  function processBuildScripts(content){
    var buildScripts = [],
        globFiles,
        customModules = gruntConfig.build.vendor_js
                        .concat(findModuleFilesIn('./src/app/'))
                        .concat(findModuleFilesIn('./src/common/'));

    customModules.forEach(function(module){
      globFiles = glob.sync(module);

      if(globFiles.length > 0){
        buildScripts = buildScripts.concat(globFiles);
      }
    });

    return grunt.template.process(content, {
      data: {
        scripts: buildScripts
      }
    });
  }
};<|endoftext|>


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

	// Initialize config
	grunt.initConfig({

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

		// Project paths
		project: {
			assets: 'assets',
			design_assets: 'design/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 %>/domdelegate/domdelegate.js',
					'<%= project.scripts_plugins %>/domready/domready.js',
					'<%= project.scripts_plugins %>/fontfaceobserver/fontfaceobserver.js',
					'<%= project.scripts_plugins %>/lazysizes/lazysizes.min.js',           // Out-comment when using lazyload
					// '<%= project.scripts_plugins %>/lazysizes/ls.respimg.js',             // Out-comment when using lazyload, and need to polyfill responsive images
					'<%= project.scripts_plugins %>/lazysizes/ls.bgset.js',               // Out-comment when using lazyload + multiple background images with a width descriptor, similar to how img[srcset] works
					'<%= project.scripts_plugins %>/lazysizes/ls.parent-fit.js',          // Out-comment when using lazyload + bgset, to calculate the right sizes for object-fit: contain|cover image elements
					// '<%= project.scripts_plugins %>/lazysizes/ls.unload.js',              // Out-comment when using lazyload, and want to unload not in view images to improve memory consumption and orientationchange/resize performance
					// '<%= project.scripts_plugins %>/lazysizes/ls.unveilhooks.js',         // Out-comment when using lazyload + unveil/lazyload scripts/widgets, background images, styles and video/audio elements
					'<%= project.scripts_plugins %>/lazysizes/ls.print.js',               // Out-comment when there's a need to be able to print lazyloaded images
					'<%= project.scripts_plugins %>/transitionend/transitionend.js',
					'<%= project.scripts_plugins %>/smooth-scroll/smooth-scroll.js',
					// '<%= project.scripts_plugins %>/gumshoe/gumshoe.js',
				],
				polyfills: [
					'<%= project.scripts_polyfills %>/classlist.js',
					// '<%= project.scripts_polyfills %>/promise.js',
				],
				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',
				],
				modules: [
					'<%= project.scripts_modules %>/alerts.module.js',
					'<%= project.scripts_modules %>/expand.module.js',
					// '<%= project.scripts_modules %>/lazysizes.module.js',     // Out-comment when apply custom actions on lazysizes init (also out-comment `lazysizes.init();` in main and mobile scripts)
					'<%= 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 %>/domdelegate/domdelegate.js',
					'<%= project.scripts_plugins %>/domready/domready.js',
					'<%= project.scripts_plugins %>/fontfaceobserver/fontfaceobserver.js',
					'<%= project.scripts_plugins %>/lazysizes/lazysizes.min.js',           // Out-comment when using lazyload
					// '<%= project.scripts_plugins %>/lazysizes/ls.respimg.js',             // Out-comment when using lazyload, and need to polyfill responsive images
					'<%= project.scripts_plugins %>/lazysizes/ls.bgset.js',               // Out-comment when using lazyload + multiple background images with a width descriptor, similar to how img[srcset] works
					'<%= project.scripts_plugins %>/lazysizes/ls.parent-fit.js',          // Out-comment when using lazyload + bgset, to calculate the right sizes for object-fit: contain|cover image elements
					// '<%= project.scripts_plugins %>/lazysizes/ls.unload.js',              // Out-comment when using lazyload, and want to unload not in view images to improve memory consumption and orientationchange/resize performance
					// '<%= project.scripts_plugins %>/lazysizes/ls.unveilhooks.js',         // Out-comment when using lazyload + unveil/lazyload scripts/widgets, background images, styles and video/audio elements
					'<%= project.scripts_plugins %>/lazysizes/ls.print.js',               // Out-comment when there's a need to be able to print lazyloaded images
					'<%= project.scripts_plugins %>/transitionend/transitionend.js',
					'<%= project.scripts_plugins %>/smooth-scroll/smooth-scroll.js',
				],
				polyfills: [
					'<%= project.scripts_polyfills %>/classlist.js',
					// '<%= project.scripts_polyfills %>/promise.js',
				],
				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',
				],
				modules: [
					'<%= project.scripts_modules %>/alerts.module.js',
					'<%= project.scripts_modules %>/expand.module.js',
					// '<%= project.scripts_modules %>/lazysizes.module.js',     // Out-comment when apply custom actions on lazysizes init (also out-comment `lazysizes.init();` in main and mobile scripts)
					'<%= project.scripts_modules %>/fontobserver.module.js',
					'<%= project.scripts_modules %>/navmain.module.js',
				// Main
					'<%= project.scripts %>/mobile.scripts.js',
				],
			},
			photoswipe: {
				plugins: [
					'<%= project.scripts_plugins %>/domready/domready.js',
					'<%= project.scripts_plugins %>/photoswipe/pswp.startfile.js',              // Photoswipe **required**, always first!
					'<%= project.scripts_plugins %>/photoswipe/pswp.framework-bridge.js',       // Photoswipe **required**
					'<%= project.scripts_plugins %>/photoswipe/pswp.core.js',                   // Photoswipe **required**
					'<%= project.scripts_plugins %>/photoswipe/pswp.gestures.js',               // Photoswipe **required**
					'<%= project.scripts_plugins %>/photoswipe/pswp.show-hide-transition.js',   // Photoswipe **required**
					'<%= project.scripts_plugins %>/photoswipe/pswp.items-controller.js',       // Photoswipe **required**
					'<%= project.scripts_plugins %>/photoswipe/pswp.tap.js',                    // Photoswipe optional
					'<%= project.scripts_plugins %>/photoswipe/pswp.history.js',                // Photoswipe optional
					'<%= project.scripts_plugins %>/photoswipe/pswp.endfile.js',                // Photoswipe **required**, always last!
					'<%= project.scripts_plugins %>/photoswipe/pswp.photoswipe-ui-default.js',  // Photoswipe UI **required**
				],
				modules: [
					'<%= project.scripts_modules %>/photoswipe.module.js',
				// Main
					'<%= project.scripts %>/photoswipe.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>Eanble respimg polyfill for un-supporting browsers.<commit_after>module.exports = function(grunt) {

	// Initialize config
	grunt.initConfig({

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

		// Project paths
		project: {
			assets: 'assets',
			design_assets: 'design/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 %>/domdelegate/domdelegate.js',
					'<%= project.scripts_plugins %>/domready/domready.js',
					'<%= project.scripts_plugins %>/fontfaceobserver/fontfaceobserver.js',
					'<%= project.scripts_plugins %>/lazysizes/lazysizes.min.js',           // Out-comment when using lazyload
					'<%= project.scripts_plugins %>/lazysizes/ls.respimg.js',             // Out-comment when using lazyload, and need to polyfill responsive images
					'<%= project.scripts_plugins %>/lazysizes/ls.bgset.js',               // Out-comment when using lazyload + multiple background images with a width descriptor, similar to how img[srcset] works
					'<%= project.scripts_plugins %>/lazysizes/ls.parent-fit.js',          // Out-comment when using lazyload + bgset, to calculate the right sizes for object-fit: contain|cover image elements
					// '<%= project.scripts_plugins %>/lazysizes/ls.unload.js',              // Out-comment when using lazyload, and want to unload not in view images to improve memory consumption and orientationchange/resize performance
					// '<%= project.scripts_plugins %>/lazysizes/ls.unveilhooks.js',         // Out-comment when using lazyload + unveil/lazyload scripts/widgets, background images, styles and video/audio elements
					'<%= project.scripts_plugins %>/lazysizes/ls.print.js',               // Out-comment when there's a need to be able to print lazyloaded images
					'<%= project.scripts_plugins %>/transitionend/transitionend.js',
					'<%= project.scripts_plugins %>/smooth-scroll/smooth-scroll.js',
					// '<%= project.scripts_plugins %>/gumshoe/gumshoe.js',
				],
				polyfills: [
					'<%= project.scripts_polyfills %>/classlist.js',
					// '<%= project.scripts_polyfills %>/promise.js',
				],
				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',
				],
				modules: [
					'<%= project.scripts_modules %>/alerts.module.js',
					'<%= project.scripts_modules %>/expand.module.js',
					// '<%= project.scripts_modules %>/lazysizes.module.js',     // Out-comment when apply custom actions on lazysizes init (also out-comment `lazysizes.init();` in main and mobile scripts)
					'<%= 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 %>/domdelegate/domdelegate.js',
					'<%= project.scripts_plugins %>/domready/domready.js',
					'<%= project.scripts_plugins %>/fontfaceobserver/fontfaceobserver.js',
					'<%= project.scripts_plugins %>/lazysizes/lazysizes.min.js',           // Out-comment when using lazyload
					// '<%= project.scripts_plugins %>/lazysizes/ls.respimg.js',             // Out-comment when using lazyload, and need to polyfill responsive images
					'<%= project.scripts_plugins %>/lazysizes/ls.bgset.js',               // Out-comment when using lazyload + multiple background images with a width descriptor, similar to how img[srcset] works
					'<%= project.scripts_plugins %>/lazysizes/ls.parent-fit.js',          // Out-comment when using lazyload + bgset, to calculate the right sizes for object-fit: contain|cover image elements
					// '<%= project.scripts_plugins %>/lazysizes/ls.unload.js',              // Out-comment when using lazyload, and want to unload not in view images to improve memory consumption and orientationchange/resize performance
					// '<%= project.scripts_plugins %>/lazysizes/ls.unveilhooks.js',         // Out-comment when using lazyload + unveil/lazyload scripts/widgets, background images, styles and video/audio elements
					'<%= project.scripts_plugins %>/lazysizes/ls.print.js',               // Out-comment when there's a need to be able to print lazyloaded images
					'<%= project.scripts_plugins %>/transitionend/transitionend.js',
					'<%= project.scripts_plugins %>/smooth-scroll/smooth-scroll.js',
				],
				polyfills: [
					'<%= project.scripts_polyfills %>/classlist.js',
					// '<%= project.scripts_polyfills %>/promise.js',
				],
				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',
				],
				modules: [
					'<%= project.scripts_modules %>/alerts.module.js',
					'<%= project.scripts_modules %>/expand.module.js',
					// '<%= project.scripts_modules %>/lazysizes.module.js',     // Out-comment when apply custom actions on lazysizes init (also out-comment `lazysizes.init();` in main and mobile scripts)
					'<%= project.scripts_modules %>/fontobserver.module.js',
					'<%= project.scripts_modules %>/navmain.module.js',
				// Main
					'<%= project.scripts %>/mobile.scripts.js',
				],
			},
			photoswipe: {
				plugins: [
					'<%= project.scripts_plugins %>/domready/domready.js',
					'<%= project.scripts_plugins %>/photoswipe/pswp.startfile.js',              // Photoswipe **required**, always first!
					'<%= project.scripts_plugins %>/photoswipe/pswp.framework-bridge.js',       // Photoswipe **required**
					'<%= project.scripts_plugins %>/photoswipe/pswp.core.js',                   // Photoswipe **required**
					'<%= project.scripts_plugins %>/photoswipe/pswp.gestures.js',               // Photoswipe **required**
					'<%= project.scripts_plugins %>/photoswipe/pswp.show-hide-transition.js',   // Photoswipe **required**
					'<%= project.scripts_plugins %>/photoswipe/pswp.items-controller.js',       // Photoswipe **required**
					'<%= project.scripts_plugins %>/photoswipe/pswp.tap.js',                    // Photoswipe optional
					'<%= project.scripts_plugins %>/photoswipe/pswp.history.js',                // Photoswipe optional
					'<%= project.scripts_plugins %>/photoswipe/pswp.endfile.js',                // Photoswipe **required**, always last!
					'<%= project.scripts_plugins %>/photoswipe/pswp.photoswipe-ui-default.js',  // Photoswipe UI **required**
				],
				modules: [
					'<%= project.scripts_modules %>/photoswipe.module.js',
				// Main
					'<%= project.scripts %>/photoswipe.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>module.exports = function(grunt) {
	// load all grunt tasks
  	require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    var pkg = grunt.file.readJSON('package.json');
    var banner =

	grunt.initConfig({
		pkg: pkg,
		banner: '/**'+
 '* <%= pkg.description %>\n'+
 '* @author <%= pkg.author %>\n'+
 '* @version v<%= pkg.version %>\n'+
 '* @link <%= pkg.repository.url %>\n' +
 '* @license <%= pkg.license %>\n'+
 '*/',
 		bump: {
 			options: {
 				files: ['package.json'],
 				commit: false,
 				createTag: false,
 				push: false
 			}
 		},
		karma: {
			options: {
				configFile: 'karma.conf.js'
			},
			unit: {
				singleRun: true
			},
			server: {
				autoWatch: true
			}
		},
		clean: pkg.main,
		concat: {
			options: {
				stripBanners: true,
				banner: '<%= banner %>'
			},
			js: {
				src: ['src/angular-busy.js'],
				dest: 'build/angular-busy.js'
			}
		},
		uglify: {
			js: {
				src: ['build/angular-busy.js'],
				dest: 'build/angular-busy.min.js',
				options: {
					banner: '<%= banner %>',
					sourceMap: true,
					sourceMapName: 'build/angular-busy.map'
				}
			}
		}
	});

	grunt.registerTask('test', ['karma:unit']);
	grunt.registerTask('test-server', ['karma:server']);
	grunt.registerTask('build', ['clean', 'concat:js', 'uglify']);
};<commit_msg>bump bower.json too<commit_after>module.exports = function(grunt) {
	// load all grunt tasks
  	require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

    var pkg = grunt.file.readJSON('package.json');
    var banner =

	grunt.initConfig({
		pkg: pkg,
		banner: '/**'+
 '* <%= pkg.description %>\n'+
 '* @author <%= pkg.author %>\n'+
 '* @version v<%= pkg.version %>\n'+
 '* @link <%= pkg.repository.url %>\n' +
 '* @license <%= pkg.license %>\n'+
 '*/',
 		bump: {
 			options: {
 				files: ['package.json', 'bower.json'],
 				commit: false,
 				createTag: false,
 				push: false
 			}
 		},
		karma: {
			options: {
				configFile: 'karma.conf.js'
			},
			unit: {
				singleRun: true
			},
			server: {
				autoWatch: true
			}
		},
		clean: pkg.main,
		concat: {
			options: {
				stripBanners: true,
				banner: '<%= banner %>'
			},
			js: {
				src: ['src/angular-busy.js'],
				dest: 'build/angular-busy.js'
			}
		},
		uglify: {
			js: {
				src: ['build/angular-busy.js'],
				dest: 'build/angular-busy.min.js',
				options: {
					banner: '<%= banner %>',
					sourceMap: true,
					sourceMapName: 'build/angular-busy.map'
				}
			}
		}
	});

	grunt.registerTask('test', ['karma:unit']);
	grunt.registerTask('test-server', ['karma:server']);
	grunt.registerTask('build', ['clean', 'concat:js', 'uglify']);
};<|endoftext|>


<commit_before>'use strict';

WaveSurfer.Drawer.MultiCanvas = Object.create(WaveSurfer.Drawer);

WaveSurfer.util.extend(WaveSurfer.Drawer.MultiCanvas, {

    initDrawer: function (params) {
        this.maxCanvasWidth = params.maxCanvasWidth != null ? params.maxCanvasWidth : 4000;
        this.maxCanvasElementWidth = Math.round(this.maxCanvasWidth / this.params.pixelRatio);

        if (this.maxCanvasWidth <= 1) {
            throw 'maxCanvasWidth must be greater than 1.';
        } else if (this.maxCanvasWidth % 2 == 1) {
            throw 'maxCanvasWidth must be an even number.';
        }

        this.hasProgressCanvas = this.params.waveColor != this.params.progressColor;
        this.halfPixel = 0.5 / this.params.pixelRatio;
        this.canvases = [];
    },

    createElements: function () {
        this.progressWave = this.wrapper.appendChild(
            this.style(document.createElement('wave'), {
                position: 'absolute',
                zIndex: 2,
                left: 0,
                top: 0,
                bottom: 0,
                overflow: 'hidden',
                width: '0',
                display: 'none',
                boxSizing: 'border-box',
                borderRightStyle: 'solid',
                borderRightWidth: this.params.cursorWidth + 'px',
                borderRightColor: this.params.cursorColor,
                pointerEvents: 'none'
            })
        );

        this.addCanvas();
    },

    updateSize: function () {
        var totalWidth = Math.round(this.width / this.params.pixelRatio),
            requiredCanvases = Math.ceil(totalWidth / this.maxCanvasElementWidth);

        while (this.canvases.length < requiredCanvases) {
            this.addCanvas();
        }

        while (this.canvases.length > requiredCanvases) {
            this.removeCanvas();
        }

        this.canvases.forEach(function (entry, i) {
            // Add some overlap to prevent vertical white stripes, keep the width even for simplicity.
            var canvasWidth = this.maxCanvasWidth + 2 * Math.ceil(this.params.pixelRatio / 2);

            if (i == this.canvases.length - 1) {
                canvasWidth = this.width - (this.maxCanvasWidth * (this.canvases.length - 1));
            }

            this.updateDimensions(entry, canvasWidth, this.height);
            this.clearWaveForEntry(entry);
        }, this);
    },

    addCanvas: function () {
        var entry = {},
            leftOffset = this.maxCanvasElementWidth * this.canvases.length;

        entry.wave = this.wrapper.appendChild(
            this.style(document.createElement('canvas'), {
                position: 'absolute',
                zIndex: 2,
                left: leftOffset + 'px',
                top: 0,
                bottom: 0,
                height: '100%',
                pointerEvents: 'none'
            })
        );
        entry.waveCtx = entry.wave.getContext('2d');

        if (this.hasProgressCanvas) {
            entry.progress = this.progressWave.appendChild(
                this.style(document.createElement('canvas'), {
                    position: 'absolute',
                    left: leftOffset + 'px',
                    top: 0,
                    bottom: 0,
                    height: '100%'
                })
            );
            entry.progressCtx = entry.progress.getContext('2d');
        }

        this.canvases.push(entry);
    },

    removeCanvas: function () {
        var lastEntry = this.canvases.pop();
        lastEntry.wave.parentElement.removeChild(lastEntry.wave);
        if (this.hasProgressCanvas) {
            lastEntry.progress.parentElement.removeChild(lastEntry.progress);
        }
    },

    updateDimensions: function (entry, width, height) {
        var elementWidth = Math.round(width / this.params.pixelRatio),
            totalWidth = Math.round(this.width / this.params.pixelRatio);

        // Where the canvas starts and ends in the waveform, represented as a decimal between 0 and 1.
        entry.start = (entry.waveCtx.canvas.offsetLeft / totalWidth) || 0;
        entry.end = entry.start + elementWidth / totalWidth;

        entry.waveCtx.canvas.width = width;
        entry.waveCtx.canvas.height = height;
        this.style(entry.waveCtx.canvas, { width: elementWidth + 'px' });

        this.style(this.progressWave, { display: 'block' });

        if (this.hasProgressCanvas) {
            entry.progressCtx.canvas.width = width;
            entry.progressCtx.canvas.height = height;
            this.style(entry.progressCtx.canvas, { width: elementWidth + 'px' });
        }
    },

    clearWave: function () {
        this.canvases.forEach(function (entry) {
            this.clearWaveForEntry(entry);
        }, this);
    },

    clearWaveForEntry: function (entry) {
        entry.waveCtx.clearRect(0, 0, entry.waveCtx.canvas.width, entry.waveCtx.canvas.height);
        if (this.hasProgressCanvas) {
            entry.progressCtx.clearRect(0, 0, entry.progressCtx.canvas.width, entry.progressCtx.canvas.height);
        }
    },

    drawBars: function (peaks, channelIndex, start, end) {
        // Split channels
        if (peaks[0] instanceof Array) {
            var channels = peaks;
            if (this.params.splitChannels) {
                this.setHeight(channels.length * this.params.height * this.params.pixelRatio);
                channels.forEach(function(channelPeaks, i) {
                    this.drawBars(channelPeaks, i, start, end);
                }, this);
                return;
            } else {
                peaks = channels[0];
            }
        }

        // Bar wave draws the bottom only as a reflection of the top,
        // so we don't need negative values
        var hasMinVals = [].some.call(peaks, function (val) {return val < 0;});
        // Skip every other value if there are negatives.
        var peakIndexScale = 1;
        if (hasMinVals) {
            peakIndexScale = 2;
        }

        // A half-pixel offset makes lines crisp
        var width = this.width;
        var height = this.params.height * this.params.pixelRatio;
        var offsetY = height * channelIndex || 0;
        var halfH = height / 2;
        var length = peaks.length / peakIndexScale;
        var bar = this.params.barWidth * this.params.pixelRatio;
        var gap = Math.max(this.params.pixelRatio, ~~(bar / 2));
        var step = bar + gap;

        var absmax = 1 / this.params.barHeight;
        if (this.params.normalize) {
            var max = WaveSurfer.util.max(peaks);
            var min = WaveSurfer.util.min(peaks);
            absmax = -min > max ? -min : max;
        }

        var scale = length / width;

        for (var i = (start / scale); i < (end / scale); i += step) {
            var peak = peaks[Math.floor(i * scale * peakIndexScale)] || 0;
            var h = Math.round(peak / absmax * halfH);
            this.fillRect(i + this.halfPixel, halfH - h + offsetY, bar + this.halfPixel, h * 2);
        }
    },

    drawWave: function (peaks, channelIndex, start, end) {
        // Split channels
        if (peaks[0] instanceof Array) {
            var channels = peaks;
            if (this.params.splitChannels) {
                this.setHeight(channels.length * this.params.height * this.params.pixelRatio);
                channels.forEach(function(channelPeaks, i) {
                    this.drawWave(channelPeaks, i, start, end);
                }, this);
                return;
            } else {
                peaks = channels[0];
            }
        }

        // Support arrays without negative peaks
        var hasMinValues = [].some.call(peaks, function (val) { return val < 0; });
        if (!hasMinValues) {
            var reflectedPeaks = [];
            for (var i = 0, len = peaks.length; i < len; i++) {
                reflectedPeaks[2 * i] = peaks[i];
                reflectedPeaks[2 * i + 1] = -peaks[i];
            }
            peaks = reflectedPeaks;
        }

        // A half-pixel offset makes lines crisp
        var height = this.params.height * this.params.pixelRatio;
        var offsetY = height * channelIndex || 0;
        var halfH = height / 2;

        var absmax = 1 / this.params.barHeight;
        if (this.params.normalize) {
            var max = WaveSurfer.util.max(peaks);
            var min = WaveSurfer.util.min(peaks);
            absmax = -min > max ? -min : max;
        }

        this.drawLine(peaks, absmax, halfH, offsetY, start, end);

        // Always draw a median line
        this.fillRect(0, halfH + offsetY - this.halfPixel, this.width, this.halfPixel);
    },

    drawLine: function (peaks, absmax, halfH, offsetY, start, end) {
        this.canvases.forEach (function (entry) {
            this.setFillStyles(entry);
            this.drawLineToContext(entry, entry.waveCtx, peaks, absmax, halfH, offsetY, start, end);
            this.drawLineToContext(entry, entry.progressCtx, peaks, absmax, halfH, offsetY, start, end);
        }, this);
    },

    drawLineToContext: function (entry, ctx, peaks, absmax, halfH, offsetY, start, end) {
        if (!ctx) { return; }

        var length = peaks.length / 2;

        var scale = 1;
        if (this.params.fillParent && this.width != length) {
            scale = this.width / length;
        }

        var first = Math.round(length * entry.start),
            last = Math.round(length * entry.end);
        if (first > end || last < start) { return; }
        var canvasStart = Math.max(first, start);
        var canvasEnd = Math.min(last, end);

        ctx.beginPath();
        ctx.moveTo((canvasStart - first) * scale + this.halfPixel, halfH + offsetY);

        for (var i = canvasStart; i < canvasEnd; i++) {
            var peak = peaks[2 * i] || 0;
            var h = Math.round(peak / absmax * halfH);
            ctx.lineTo((i - first) * scale + this.halfPixel, halfH - h + offsetY);
        }

        // Draw the bottom edge going backwards, to make a single
        // closed hull to fill.
        for (var i = canvasEnd - 1; i >= canvasStart; i--) {
            var peak = peaks[2 * i + 1] || 0;
            var h = Math.round(peak / absmax * halfH);
            ctx.lineTo((i - first) * scale + this.halfPixel, halfH - h + offsetY);
        }

        ctx.closePath();
        ctx.fill();
    },

    fillRect: function (x, y, width, height) {
        var startCanvas = Math.floor(x / this.maxCanvasWidth);
        var endCanvas = Math.min(Math.ceil((x + width) / this.maxCanvasWidth) + 1,
                                this.canvases.length);
        for (var i = startCanvas; i < endCanvas; i++) {
            var entry = this.canvases[i],
                leftOffset = i * this.maxCanvasWidth;
            var intersection = {
                x1: Math.max(x, i * this.maxCanvasWidth),
                y1: y,
                x2: Math.min(x + width, i * this.maxCanvasWidth + entry.waveCtx.canvas.width),
                y2: y + height
            };

            if (intersection.x1 < intersection.x2) {
                this.setFillStyles(entry);

                this.fillRectToContext(entry.waveCtx,
                        intersection.x1 - leftOffset,
                        intersection.y1,
                        intersection.x2 - intersection.x1,
                        intersection.y2 - intersection.y1);

                this.fillRectToContext(entry.progressCtx,
                        intersection.x1 - leftOffset,
                        intersection.y1,
                        intersection.x2 - intersection.x1,
                        intersection.y2 - intersection.y1);
            }
        }
    },

    fillRectToContext: function (ctx, x, y, width, height) {
        if (!ctx) { return; }
        ctx.fillRect(x, y, width, height);
    },

    setFillStyles: function (entry) {
        entry.waveCtx.fillStyle = this.params.waveColor;
        if (this.hasProgressCanvas) {
            entry.progressCtx.fillStyle = this.params.progressColor;
        }
    },

    updateProgress: function (pos) {
        this.style(this.progressWave, { width: pos + 'px' });
    },

    /**
     * Combine all available canvases together.
     *
     * @param {String} type - an optional value of a format type. Default is image/png.
     * @param {Number} quality - an optional value between 0 and 1. Default is 0.92.
     *
     */
    getImage: function (type, quality) {
        var availableCanvas = [];
        this.canvases.forEach(function (entry) {
            availableCanvas.push(entry.wave.toDataURL(type, quality));
        });
        return availableCanvas.length > 1 ? availableCanvas : availableCanvas[0];
    }
});
<commit_msg>Wrap drawing in requestAnimationFrame (multicanvas). (#1106)<commit_after>'use strict';

WaveSurfer.Drawer.MultiCanvas = Object.create(WaveSurfer.Drawer);

WaveSurfer.util.extend(WaveSurfer.Drawer.MultiCanvas, {

    initDrawer: function (params) {
        this.maxCanvasWidth = params.maxCanvasWidth != null ? params.maxCanvasWidth : 4000;
        this.maxCanvasElementWidth = Math.round(this.maxCanvasWidth / this.params.pixelRatio);

        if (this.maxCanvasWidth <= 1) {
            throw 'maxCanvasWidth must be greater than 1.';
        } else if (this.maxCanvasWidth % 2 == 1) {
            throw 'maxCanvasWidth must be an even number.';
        }

        this.hasProgressCanvas = this.params.waveColor != this.params.progressColor;
        this.halfPixel = 0.5 / this.params.pixelRatio;
        this.canvases = [];
    },

    createElements: function () {
        this.progressWave = this.wrapper.appendChild(
            this.style(document.createElement('wave'), {
                position: 'absolute',
                zIndex: 2,
                left: 0,
                top: 0,
                bottom: 0,
                overflow: 'hidden',
                width: '0',
                display: 'none',
                boxSizing: 'border-box',
                borderRightStyle: 'solid',
                borderRightWidth: this.params.cursorWidth + 'px',
                borderRightColor: this.params.cursorColor,
                pointerEvents: 'none'
            })
        );

        this.addCanvas();
    },

    updateSize: function () {
        var totalWidth = Math.round(this.width / this.params.pixelRatio),
            requiredCanvases = Math.ceil(totalWidth / this.maxCanvasElementWidth);

        while (this.canvases.length < requiredCanvases) {
            this.addCanvas();
        }

        while (this.canvases.length > requiredCanvases) {
            this.removeCanvas();
        }

        this.canvases.forEach(function (entry, i) {
            // Add some overlap to prevent vertical white stripes, keep the width even for simplicity.
            var canvasWidth = this.maxCanvasWidth + 2 * Math.ceil(this.params.pixelRatio / 2);

            if (i == this.canvases.length - 1) {
                canvasWidth = this.width - (this.maxCanvasWidth * (this.canvases.length - 1));
            }

            this.updateDimensions(entry, canvasWidth, this.height);
            this.clearWaveForEntry(entry);
        }, this);
    },

    addCanvas: function () {
        var entry = {},
            leftOffset = this.maxCanvasElementWidth * this.canvases.length;

        entry.wave = this.wrapper.appendChild(
            this.style(document.createElement('canvas'), {
                position: 'absolute',
                zIndex: 2,
                left: leftOffset + 'px',
                top: 0,
                bottom: 0,
                height: '100%',
                pointerEvents: 'none'
            })
        );
        entry.waveCtx = entry.wave.getContext('2d');

        if (this.hasProgressCanvas) {
            entry.progress = this.progressWave.appendChild(
                this.style(document.createElement('canvas'), {
                    position: 'absolute',
                    left: leftOffset + 'px',
                    top: 0,
                    bottom: 0,
                    height: '100%'
                })
            );
            entry.progressCtx = entry.progress.getContext('2d');
        }

        this.canvases.push(entry);
    },

    removeCanvas: function () {
        var lastEntry = this.canvases.pop();
        lastEntry.wave.parentElement.removeChild(lastEntry.wave);
        if (this.hasProgressCanvas) {
            lastEntry.progress.parentElement.removeChild(lastEntry.progress);
        }
    },

    updateDimensions: function (entry, width, height) {
        var elementWidth = Math.round(width / this.params.pixelRatio),
            totalWidth = Math.round(this.width / this.params.pixelRatio);

        // Where the canvas starts and ends in the waveform, represented as a decimal between 0 and 1.
        entry.start = (entry.waveCtx.canvas.offsetLeft / totalWidth) || 0;
        entry.end = entry.start + elementWidth / totalWidth;

        entry.waveCtx.canvas.width = width;
        entry.waveCtx.canvas.height = height;
        this.style(entry.waveCtx.canvas, { width: elementWidth + 'px' });

        this.style(this.progressWave, { display: 'block' });

        if (this.hasProgressCanvas) {
            entry.progressCtx.canvas.width = width;
            entry.progressCtx.canvas.height = height;
            this.style(entry.progressCtx.canvas, { width: elementWidth + 'px' });
        }
    },

    clearWave: function () {
        this.canvases.forEach(function (entry) {
            this.clearWaveForEntry(entry);
        }, this);
    },

    clearWaveForEntry: function (entry) {
        entry.waveCtx.clearRect(0, 0, entry.waveCtx.canvas.width, entry.waveCtx.canvas.height);
        if (this.hasProgressCanvas) {
            entry.progressCtx.clearRect(0, 0, entry.progressCtx.canvas.width, entry.progressCtx.canvas.height);
        }
    },

    drawBars: WaveSurfer.util.frame(function (peaks, channelIndex, start, end) {
        // Split channels
        if (peaks[0] instanceof Array) {
            var channels = peaks;
            if (this.params.splitChannels) {
                this.setHeight(channels.length * this.params.height * this.params.pixelRatio);
                channels.forEach(function(channelPeaks, i) {
                    this.drawBars(channelPeaks, i, start, end);
                }, this);
                return;
            } else {
                peaks = channels[0];
            }
        }

        // Bar wave draws the bottom only as a reflection of the top,
        // so we don't need negative values
        var hasMinVals = [].some.call(peaks, function (val) {return val < 0;});
        // Skip every other value if there are negatives.
        var peakIndexScale = 1;
        if (hasMinVals) {
            peakIndexScale = 2;
        }

        // A half-pixel offset makes lines crisp
        var width = this.width;
        var height = this.params.height * this.params.pixelRatio;
        var offsetY = height * channelIndex || 0;
        var halfH = height / 2;
        var length = peaks.length / peakIndexScale;
        var bar = this.params.barWidth * this.params.pixelRatio;
        var gap = Math.max(this.params.pixelRatio, ~~(bar / 2));
        var step = bar + gap;

        var absmax = 1 / this.params.barHeight;
        if (this.params.normalize) {
            var max = WaveSurfer.util.max(peaks);
            var min = WaveSurfer.util.min(peaks);
            absmax = -min > max ? -min : max;
        }

        var scale = length / width;

        for (var i = (start / scale); i < (end / scale); i += step) {
            var peak = peaks[Math.floor(i * scale * peakIndexScale)] || 0;
            var h = Math.round(peak / absmax * halfH);
            this.fillRect(i + this.halfPixel, halfH - h + offsetY, bar + this.halfPixel, h * 2);
        }
    }),

    drawWave: WaveSurfer.util.frame(function (peaks, channelIndex, start, end) {
        // Split channels
        if (peaks[0] instanceof Array) {
            var channels = peaks;
            if (this.params.splitChannels) {
                this.setHeight(channels.length * this.params.height * this.params.pixelRatio);
                channels.forEach(function(channelPeaks, i) {
                    this.drawWave(channelPeaks, i, start, end);
                }, this);
                return;
            } else {
                peaks = channels[0];
            }
        }

        // Support arrays without negative peaks
        var hasMinValues = [].some.call(peaks, function (val) { return val < 0; });
        if (!hasMinValues) {
            var reflectedPeaks = [];
            for (var i = 0, len = peaks.length; i < len; i++) {
                reflectedPeaks[2 * i] = peaks[i];
                reflectedPeaks[2 * i + 1] = -peaks[i];
            }
            peaks = reflectedPeaks;
        }

        // A half-pixel offset makes lines crisp
        var height = this.params.height * this.params.pixelRatio;
        var offsetY = height * channelIndex || 0;
        var halfH = height / 2;

        var absmax = 1 / this.params.barHeight;
        if (this.params.normalize) {
            var max = WaveSurfer.util.max(peaks);
            var min = WaveSurfer.util.min(peaks);
            absmax = -min > max ? -min : max;
        }

        this.drawLine(peaks, absmax, halfH, offsetY, start, end);

        // Always draw a median line
        this.fillRect(0, halfH + offsetY - this.halfPixel, this.width, this.halfPixel);
    }),

    drawLine: function (peaks, absmax, halfH, offsetY, start, end) {
        this.canvases.forEach (function (entry) {
            this.setFillStyles(entry);
            this.drawLineToContext(entry, entry.waveCtx, peaks, absmax, halfH, offsetY, start, end);
            this.drawLineToContext(entry, entry.progressCtx, peaks, absmax, halfH, offsetY, start, end);
        }, this);
    },

    drawLineToContext: function (entry, ctx, peaks, absmax, halfH, offsetY, start, end) {
        if (!ctx) { return; }

        var length = peaks.length / 2;

        var scale = 1;
        if (this.params.fillParent && this.width != length) {
            scale = this.width / length;
        }

        var first = Math.round(length * entry.start),
            last = Math.round(length * entry.end);
        if (first > end || last < start) { return; }
        var canvasStart = Math.max(first, start);
        var canvasEnd = Math.min(last, end);

        ctx.beginPath();
        ctx.moveTo((canvasStart - first) * scale + this.halfPixel, halfH + offsetY);

        for (var i = canvasStart; i < canvasEnd; i++) {
            var peak = peaks[2 * i] || 0;
            var h = Math.round(peak / absmax * halfH);
            ctx.lineTo((i - first) * scale + this.halfPixel, halfH - h + offsetY);
        }

        // Draw the bottom edge going backwards, to make a single
        // closed hull to fill.
        for (var i = canvasEnd - 1; i >= canvasStart; i--) {
            var peak = peaks[2 * i + 1] || 0;
            var h = Math.round(peak / absmax * halfH);
            ctx.lineTo((i - first) * scale + this.halfPixel, halfH - h + offsetY);
        }

        ctx.closePath();
        ctx.fill();
    },

    fillRect: function (x, y, width, height) {
        var startCanvas = Math.floor(x / this.maxCanvasWidth);
        var endCanvas = Math.min(Math.ceil((x + width) / this.maxCanvasWidth) + 1,
                                this.canvases.length);
        for (var i = startCanvas; i < endCanvas; i++) {
            var entry = this.canvases[i],
                leftOffset = i * this.maxCanvasWidth;
            var intersection = {
                x1: Math.max(x, i * this.maxCanvasWidth),
                y1: y,
                x2: Math.min(x + width, i * this.maxCanvasWidth + entry.waveCtx.canvas.width),
                y2: y + height
            };

            if (intersection.x1 < intersection.x2) {
                this.setFillStyles(entry);

                this.fillRectToContext(entry.waveCtx,
                        intersection.x1 - leftOffset,
                        intersection.y1,
                        intersection.x2 - intersection.x1,
                        intersection.y2 - intersection.y1);

                this.fillRectToContext(entry.progressCtx,
                        intersection.x1 - leftOffset,
                        intersection.y1,
                        intersection.x2 - intersection.x1,
                        intersection.y2 - intersection.y1);
            }
        }
    },

    fillRectToContext: function (ctx, x, y, width, height) {
        if (!ctx) { return; }
        ctx.fillRect(x, y, width, height);
    },

    setFillStyles: function (entry) {
        entry.waveCtx.fillStyle = this.params.waveColor;
        if (this.hasProgressCanvas) {
            entry.progressCtx.fillStyle = this.params.progressColor;
        }
    },

    updateProgress: function (pos) {
        this.style(this.progressWave, { width: pos + 'px' });
    },

    /**
     * Combine all available canvases together.
     *
     * @param {String} type - an optional value of a format type. Default is image/png.
     * @param {Number} quality - an optional value between 0 and 1. Default is 0.92.
     *
     */
    getImage: function (type, quality) {
        var availableCanvas = [];
        this.canvases.forEach(function (entry) {
            availableCanvas.push(entry.wave.toDataURL(type, quality));
        });
        return availableCanvas.length > 1 ? availableCanvas : availableCanvas[0];
    }
});
<|endoftext|>


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

  var lyriaOrigin = 'src/**/*.js';
  var generatedFiles = 'generated/**/*.js';

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat_sourcemap: {
      options: {
        sourcesContent: true,
        sourceRoot: '/'
      },
      scripts: {
        src: [lyriaOrigin, generatedFiles],
        dest: 'dist/js/<%= pkg.name %>.js'
      }
    },
    concat: {
      styles: {
        src: ['dist/css/*.css'],
        dest: 'dist/css/<%= pkg.name %>.css'
      }
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> */\n',
        report: 'gzip'
      },
      dist: {
        files: {
          'dist/js/<%= pkg.name %>.min.js': ['<%= concat_sourcemap.scripts.dest %>']
        }
      }
    },
    cssmin: {
      minify: {
        expand: true,
        cwd: 'dist/css/',
        src: ['*.css', '!*.min.css'],
        dest: 'dist/css/min',
        ext: '.min.css'
      }
    },
    jshint: {
      files: ['gruntfile.js', lyriaOrigin, 'test/**/*.js'],
      options: grunt.file.readJSON('.jshintrc')
    },
    yuidoc: {
      compile: {
        name: '<%= pkg.name %>',
        description: '<%= pkg.description %>',
        version: '<%= pkg.version %>',
        url: '<%= pkg.homepage %>',
        options: {
          linkNatives: true,
          paths: 'src/',
          outdir: 'doc/api'
        }
      }
    },
    stylus: {
      options: {
        paths: ['stylus'],
        urlfunc: 'embedurl',
        import: ['nib']
      },
      compile: {
        options: {
          compress: false,
        },
        files: [{
          expand: true,
          cwd: 'stylus/',
          src: ['**/*.styl'],
          dest: 'dist/css/',
          ext: '.css'
        }]
      }
    },
    handlebars: {
      options: {
        namespace: 'lyria/template/list',
      },
      compile: {
        files: {
          'generated/templates.js': ['templates/*.html']
        }
      }
    },
    clean: ['dist', 'generated'],
    dependo: {
      targetPath: 'src',
      outputPath: './doc/dependencies',
      format: 'amd'
    },
    plato: {
      all: {
        options: {
          jshint: grunt.file.readJSON('.jshintrc'),
          complexity: {
            logicalor: false,
            switchcase: false,
            forin: true,
            trycatch: true
          }
        },
        files: {
          'doc/reports/': ['src/**/*.js', 'gruntfile.js']
        }
      }
    },
    connect: {
      test: {
        options: {
          port: 9001,
          base: 'test/'
        }
      }
    }/*,
    mocha: {
      options: {
        reporter: 'Spec',
        log: true
      },
      all: {
        options: {
          urls: ['http://localhost:9001/test/game.html']
        }
      }
    }*/
  });

  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
  grunt.loadTasks('./tasks');

  grunt.registerTask('test', 'Lints and unit tests', ['jshint', 'connect:test', 'mocha']);
  grunt.registerTask('doc', 'Generated documentation', ['yuidoc', 'dependo', 'plato']);
  grunt.registerTask('default', 'Default task', ['clean', 'handlebars', 'stylus', 'concat', 'concat_sourcemap', 'test', 'uglify', 'cssmin', 'doc']);

};
<commit_msg>Yeah, still not working :(<commit_after>module.exports = function(grunt) {

  var lyriaOrigin = 'src/**/*.js';
  var generatedFiles = 'generated/**/*.js';

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat_sourcemap: {
      options: {
        sourcesContent: true,
        sourceRoot: '/'
      },
      scripts: {
        src: [lyriaOrigin, generatedFiles],
        dest: 'dist/js/<%= pkg.name %>.js'
      }
    },
    concat: {
      styles: {
        src: ['dist/css/*.css'],
        dest: 'dist/css/<%= pkg.name %>.css'
      }
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> */\n',
        report: 'gzip'
      },
      dist: {
        files: {
          'dist/js/<%= pkg.name %>.min.js': ['<%= concat_sourcemap.scripts.dest %>']
        }
      }
    },
    cssmin: {
      minify: {
        expand: true,
        cwd: 'dist/css/',
        src: ['*.css', '!*.min.css'],
        dest: 'dist/css/min',
        ext: '.min.css'
      }
    },
    jshint: {
      files: ['gruntfile.js', lyriaOrigin, 'test/**/*.js'],
      options: grunt.file.readJSON('.jshintrc')
    },
    yuidoc: {
      compile: {
        name: '<%= pkg.name %>',
        description: '<%= pkg.description %>',
        version: '<%= pkg.version %>',
        url: '<%= pkg.homepage %>',
        options: {
          linkNatives: true,
          paths: 'src/',
          outdir: 'doc/api'
        }
      }
    },
    stylus: {
      options: {
        paths: ['stylus'],
        urlfunc: 'embedurl',
        import: ['nib']
      },
      compile: {
        options: {
          compress: false,
        },
        files: [{
          expand: true,
          cwd: 'stylus/',
          src: ['**/*.styl'],
          dest: 'dist/css/',
          ext: '.css'
        }]
      }
    },
    handlebars: {
      options: {
        namespace: 'lyria/template/list',
      },
      compile: {
        files: {
          'generated/templates.js': ['templates/*.html']
        }
      }
    },
    clean: ['dist', 'generated'],
    dependo: {
      targetPath: 'src',
      outputPath: './doc/dependencies',
      format: 'amd'
    },
    plato: {
      all: {
        options: {
          jshint: grunt.file.readJSON('.jshintrc'),
          complexity: {
            logicalor: false,
            switchcase: false,
            forin: true,
            trycatch: true
          }
        },
        files: {
          'doc/reports/': ['src/**/*.js', 'gruntfile.js']
        }
      }
    },
    connect: {
      test: {
        options: {
          port: 9001,
          base: 'test/'
        }
      }
    }/*,
    mocha: {
      options: {
        reporter: 'Spec',
        log: true
      },
      all: {
        options: {
          urls: ['http://localhost:9001/test/game.html']
        }
      }
    }*/
  });

  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
  grunt.loadTasks('./tasks');

  grunt.registerTask('test', 'Lints and unit tests', ['jshint']);
  grunt.registerTask('doc', 'Generated documentation', ['yuidoc', 'dependo', 'plato']);
  grunt.registerTask('default', 'Default task', ['clean', 'handlebars', 'stylus', 'concat', 'concat_sourcemap', 'test', 'uglify', 'cssmin', 'doc']);

};
<|endoftext|>


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

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-shell-spawn');
  grunt.loadNpmTasks('grunt-express-server');
  grunt.loadNpmTasks('grunt-casper');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-simple-mocha');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-browserify');

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        watch: {
            source: {
                files: ['sass/**/*.scss'],
                tasks: ['sass'],
                options: {
                    livereload: true
                }
            },
            express: {
                files: ['**/*.js'],
                tasks: ['express:dev'],
                options: {
                    spawn: false // for grunt-contrib-watch v0.5.0+, "nospawn: true" for lower versions. Without this option specified express won't be reloaded
                }
            }
        },

        shell: {
            mongodb: {
                command: 'mongod',
                options: {
                    async: true,
                    stdout: false,
                    stderr: true,
                    //set to false to keep from failing if mongodb already running as can happen when a test fails and stops grunt without stoping the database
                    failOnError: false,
                    execOptions: {
                        cwd: '.'
                    }
                }
            }
        },

        express: {
            options: {
                port: 8080
            },
            dev: {
                options: {
                    script: 'server.js'
                }
            },
            prod: {
                options: {
                    script: 'server.js',
                    node_env: 'production'
                }
            },
            test: {
                options: {
                    script: 'server.js'
                }
            }
        },

        casper: {
            acceptance: {
                options: {
                    test: true,
                },
                files: {
                    'test/acceptance/casper-results.xml': ['test/acceptance/*_test.js']
                }
            }
        },

      simplemocha: {
        options: {
          colors: true,
          globals: ['should'],
          timeout: 3000,
          ignoreLeaks: false,
          ui: 'bdd',
          reporter: 'tap'
        },

        all: { src: ['test/unit/*.js', 'test/api/*.js'] }
      },

      jshint: {
        all: ['Gruntfile.js', 'server.js', 'api/models/**/*.js', 'test/**/*.js'],
        options: {
          jshintrc: true,
          globals: {
            console: true,
            module: true
          }
        }

      },
      concat:{
        options: {
          separator: ';'
        },
        dist: {
          src: ['app/**/*.js'],
          dest: 'dist/<%= pkg.name %>.js'
        }
      },
      clean:{
        build: ['build'],
        prod: ['dist']
      },
      copy: {
        prod: {
          expand: true,
          cwd: 'app/assets',
          src: ['css/*.css', '*.html', 'images/**/*' ],
          dest: 'dist/',
          flatten: false,
          filter: 'isFile'
        },
        dev: {
          expand: true,
          cwd: 'app/assets',
          src: ['css/*.css', '*.html', 'images/**/*' ],
          dest: 'build/',
          flatten: false,
          filter: 'isFile'
        }
      },
      browserify: {
        prod: {
          src: ['app/assets/js/*.js'],
          dest: 'build/browser.js',
          options: {
            transform: ['debowerify', 'hbsfy'],
            debug: true
          }
        }
      }

    });

  //when using watch, all the watch tasks must preceed watch in the registerTask statement
  grunt.registerTask('default', ['shell:mongodb', 'express:dev', 'watch']);
  grunt.registerTask('server', ['shell:mongodb', 'express:dev', 'watch']);
  grunt.registerTask('test', ['jshint', 'shell:mongodb', 'express:dev', 'casper','simplemocha', 'watch']);
  grunt.registerTask('Ctest', ['concat']);
  grunt.registerTask('Cltest', ['clean']);
  grunt.registerTask('build',['clean:build','copy:dev','browserify']);

};
<commit_msg>Change gruntfile.js<commit_after>module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-shell-spawn');
  grunt.loadNpmTasks('grunt-express-server');
  grunt.loadNpmTasks('grunt-casper');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-simple-mocha');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-browserify');

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        watch: {
            source: {
                files: ['sass/**/*.scss'],
                tasks: ['sass'],
                options: {
                    livereload: true
                }
            },
            express: {
                files: ['**/*.js'],
                tasks: ['express:dev'],
                options: {
                    spawn: false // for grunt-contrib-watch v0.5.0+, "nospawn: true" for lower versions. Without this option specified express won't be reloaded
                }
            }
        },

        shell: {
            mongodb: {
                command: 'mongod',
                options: {
                    async: true,
                    stdout: false,
                    stderr: true,
                    //set to false to keep from failing if mongodb already running as can happen when a test fails and stops grunt without stoping the database
                    failOnError: false,
                    execOptions: {
                        cwd: '.'
                    }
                }
            }
        },

        express: {
            options: {
                port: 8080
            },
            dev: {
                options: {
                    script: 'server.js'
                }
            },
            prod: {
                options: {
                    script: 'server.js',
                    node_env: 'production'
                }
            },
            test: {
                options: {
                    script: 'server.js'
                }
            }
        },

        casper: {
            acceptance: {
                options: {
                    test: true,
                },
                files: {
                    'test/acceptance/casper-results.xml': ['test/acceptance/*_test.js']
                }
            }
        },

      simplemocha: {
        options: {
          colors: true,
          globals: ['should'],
          timeout: 3000,
          ignoreLeaks: false,
          ui: 'bdd',
          reporter: 'tap'
        },

        all: { src: ['test/unit/*.js', 'test/api/*.js'] }
      },

      jshint: {
        all: ['Gruntfile.js', 'server.js', 'api/models/**/*.js', 'test/**/*.js'],
        options: {
          jshintrc: true,
          globals: {
            console: true,
            module: true
          }
        }

      },
      concat:{
        options: {
          separator: ';'
        },
        dist: {
          src: ['app/**/*.js'],
          dest: 'dist/<%= pkg.name %>.js'
        }
      },
      clean:{
        build: ['build'],
        prod: ['dist']
      },
      copy: {
        prod: {
          expand: true,
          cwd: 'app/assets',
          src: ['css/*.css', '*.html', 'images/**/*' ],
          dest: 'dist/',
          flatten: false,
          filter: 'isFile'
        },
        dev: {
          expand: true,
          cwd: 'app/assets',
          src: ['css/*.css', '*.html', 'images/**/*' ],
          dest: 'build/',
          flatten: false,
          filter: 'isFile'
        }
      },
      browserify: {
        prod: {
          src: ['app/assets/js/*.js'],
          dest: 'build/browser.js',
          options: {
            transform: ['debowerify', 'hbsfy'],
            debug: true
          }
        }
      }

    });

  //when using watch, all the watch tasks must preceed watch in the registerTask statement
  grunt.registerTask('default', ['clean:build', 'copy:dev', 'browserify', 'shell:mongodb', 'express:dev', 'watch']);
  grunt.registerTask('server', ['shell:mongodb', 'express:dev', 'watch']);
  grunt.registerTask('test', ['jshint', 'shell:mongodb', 'express:dev', 'casper','simplemocha', 'watch']);
  grunt.registerTask('Ctest', ['concat']);
  grunt.registerTask('Cltest', ['clean']);
  grunt.registerTask('build',['clean:build', 'copy:dev', 'browserify']);

};
<|endoftext|>


<commit_before>'use strict';

module.exports = function(grunt) {
	// Unified Watch Object
	var watchFiles = {
		serverViews: ['app/views/**/*.*'],
		serverJS: ['gruntfile.js', 'server.js', 'config/**/*.js', 'app/**/*.js'],
		clientViews: ['public/modules/**/views/**/*.html'],
		clientJS: ['public/js/*.js', 'public/modules/**/*.js'],
		clientCSS: ['public/modules/**/*.css'],
		mochaTests: ['app/tests/**/*.js']
	};

	// Project Configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		watch: {
			serverViews: {
				files: watchFiles.serverViews,
				options: {
					livereload: true
				}
			},
			serverJS: {
				files: watchFiles.serverJS,
				tasks: ['jshint'],
				options: {
					livereload: true
				}
			},
			clientViews: {
				files: watchFiles.clientViews,
				options: {
					livereload: true,
				}
			},
			clientJS: {
				files: watchFiles.clientJS,
				tasks: ['jshint'],
				options: {
					livereload: true
				}
			},
			clientCSS: {
				files: watchFiles.clientCSS,
				tasks: ['csslint'],
				options: {
					livereload: true
				}
			}
		},
		jshint: {
			all: {
				src: watchFiles.clientJS.concat(watchFiles.serverJS),
				options: {
					jshintrc: true
				}
			}
		},
		csslint: {
			options: {
				csslintrc: '.csslintrc',
			},
			all: {
				src: watchFiles.clientCSS
			}
		},
		uglify: {
			production: {
				options: {
					mangle: false
				},
				files: {
					'public/dist/application.min.js': 'public/dist/application.js'
				}
			}
		},
		cssmin: {
			combine: {
				files: {
					'public/dist/application.min.css': '<%= applicationCSSFiles %>'
				}
			}
		},
		nodemon: {
			dev: {
				script: 'server.js',
				options: {
					nodeArgs: ['--debug'],
					ext: 'js,html',
					watch: watchFiles.serverViews.concat(watchFiles.serverJS)
				}
			}
		},
		'node-inspector': {
			custom: {
				options: {
					'web-port': 1337,
					'web-host': 'localhost',
					'debug-port': 5858,
					'save-live-edit': true,
					'no-preload': true,
					'stack-trace-limit': 50,
					'hidden': []
				}
			}
		},
		ngAnnotate: {
			production: {
				files: {
					'public/dist/application.js': '<%= applicationJavaScriptFiles %>'
				}
			}
		},
		concurrent: {
			default: ['nodemon', 'watch'],
			debug: ['nodemon', 'watch', 'node-inspector'],
			options: {
				logConcurrentOutput: true,
				limit: 10
			}
		},
		env: {
			test: {
				NODE_ENV: 'test'
			}
		},
		mochaTest: {
			src: watchFiles.mochaTests,
			options: {
				reporter: 'spec',
				require: 'server.js'
			}
		},
		karma: {
			unit: {
				configFile: 'karma.conf.js'
			}
		}
	});

	// Load NPM tasks
	require('load-grunt-tasks')(grunt);

	// Making grunt default to force in order not to break the project.
	grunt.option('force', true);

	// A Task for loading the configuration object
	grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() {
		var init = require('./config/init')();
		var config = require('./config/config');

		grunt.config.set('applicationJavaScriptFiles', config.assets.js);
		grunt.config.set('applicationCSSFiles', config.assets.css);
	});

	// Default task(s).
	grunt.registerTask('default', ['lint', 'concurrent:default']);

	// Debug task.
	grunt.registerTask('debug', ['lint', 'concurrent:debug']);

	// Lint task(s).
	grunt.registerTask('lint', ['jshint', 'csslint']);

	// Build task(s).
	grunt.registerTask('build', ['lint', 'loadConfig', 'ngAnnotate', 'uglify', 'cssmin']);

	// Test task.
	grunt.registerTask('test', ['env:test', 'mochaTest']);
};
<commit_msg>Remove linting from grunt build<commit_after>'use strict';

module.exports = function(grunt) {
	// Unified Watch Object
	var watchFiles = {
		serverViews: ['app/views/**/*.*'],
		serverJS: ['gruntfile.js', 'server.js', 'config/**/*.js', 'app/**/*.js'],
		clientViews: ['public/modules/**/views/**/*.html'],
		clientJS: ['public/js/*.js', 'public/modules/**/*.js'],
		clientCSS: ['public/modules/**/*.css'],
		mochaTests: ['app/tests/**/*.js']
	};

	// Project Configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		watch: {
			serverViews: {
				files: watchFiles.serverViews,
				options: {
					livereload: true
				}
			},
			serverJS: {
				files: watchFiles.serverJS,
				tasks: ['jshint'],
				options: {
					livereload: true
				}
			},
			clientViews: {
				files: watchFiles.clientViews,
				options: {
					livereload: true,
				}
			},
			clientJS: {
				files: watchFiles.clientJS,
				tasks: ['jshint'],
				options: {
					livereload: true
				}
			},
			clientCSS: {
				files: watchFiles.clientCSS,
				tasks: ['csslint'],
				options: {
					livereload: true
				}
			}
		},
		jshint: {
			all: {
				src: watchFiles.clientJS.concat(watchFiles.serverJS),
				options: {
					jshintrc: true
				}
			}
		},
		csslint: {
			options: {
				csslintrc: '.csslintrc',
			},
			all: {
				src: watchFiles.clientCSS
			}
		},
		uglify: {
			production: {
				options: {
					mangle: false
				},
				files: {
					'public/dist/application.min.js': 'public/dist/application.js'
				}
			}
		},
		cssmin: {
			combine: {
				files: {
					'public/dist/application.min.css': '<%= applicationCSSFiles %>'
				}
			}
		},
		nodemon: {
			dev: {
				script: 'server.js',
				options: {
					nodeArgs: ['--debug'],
					ext: 'js,html',
					watch: watchFiles.serverViews.concat(watchFiles.serverJS)
				}
			}
		},
		'node-inspector': {
			custom: {
				options: {
					'web-port': 1337,
					'web-host': 'localhost',
					'debug-port': 5858,
					'save-live-edit': true,
					'no-preload': true,
					'stack-trace-limit': 50,
					'hidden': []
				}
			}
		},
		ngAnnotate: {
			production: {
				files: {
					'public/dist/application.js': '<%= applicationJavaScriptFiles %>'
				}
			}
		},
		concurrent: {
			default: ['nodemon', 'watch'],
			debug: ['nodemon', 'watch', 'node-inspector'],
			options: {
				logConcurrentOutput: true,
				limit: 10
			}
		},
		env: {
			test: {
				NODE_ENV: 'test'
			}
		},
		mochaTest: {
			src: watchFiles.mochaTests,
			options: {
				reporter: 'spec',
				require: 'server.js'
			}
		},
		karma: {
			unit: {
				configFile: 'karma.conf.js'
			}
		}
	});

	// Load NPM tasks
	require('load-grunt-tasks')(grunt);

	// Making grunt default to force in order not to break the project.
	grunt.option('force', true);

	// A Task for loading the configuration object
	grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() {
		var init = require('./config/init')();
		var config = require('./config/config');

		grunt.config.set('applicationJavaScriptFiles', config.assets.js);
		grunt.config.set('applicationCSSFiles', config.assets.css);
	});

	// Default task(s).
	grunt.registerTask('default', ['lint', 'concurrent:default']);

	// Debug task.
	grunt.registerTask('debug', ['lint', 'concurrent:debug']);

	// Lint task(s).
	grunt.registerTask('lint', ['jshint', 'csslint']);

	// Build task(s).
	grunt.registerTask('build', ['loadConfig', 'ngAnnotate', 'uglify', 'cssmin']);

	// Test task.
	grunt.registerTask('test', ['env:test', 'mochaTest']);
};
<|endoftext|>