<commit_before>// Gruntfile

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

        watch: {
            pug: {
                files: ['src/views/**/*.pug']
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.registerTask('default', ['watch']);
};<commit_msg>Full build task completed<commit_after>// Gruntfile

module.exports = function (grunt) {
    require('load-grunt-tasks')(grunt);

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

        // Configure watched files and tasks to fire
        watch: {
            // Watch for changes to the grunt configuration
            config: {
                files: ['Gruntfile.js']
            },

            // Check for changes in any files and run compile
            views: {
                files: ['src/views/**/*.pug'],
                tasks: ['views']
            },
            scripts: {
                files: ['src/scripts/**/*.js'],
                tasks: ['scripts']
            },
            styles: {
                files: ['src/styles/**/*.scss'],
                tasks: ['styles']
            }
        },

        sass: {
            styles: {
                options: {
                    quiet: false
                },
                files: {
                    '.grunt/theme.css': 'src/styles/theme.scss'
                }
            }
        },

        concat: {
            options: {

            },
            scripts: {
                src: ['src/scripts/**/*.js'],
                dest: '.grunt/theme.js'
            }
        },

        pug: {
            options: {

            },
            views: {
                src: 'src/views/theme.pug',
                dest: '.grunt/theme.html'
            }
        },

        copy: {
            options: {

            },
            theme: {
                src: '.grunt/theme.html',
                dest: 'dist/theme.html'
            }
        },

        // Insert all the JS and CSS into the single html file
        insert: {
            options: {

            },
            scripts: {
                src: '.grunt/theme.js',
                dest: 'dist/theme.html',
                match: '<!-- !import scripts -->'
            },
            styles: {
                src: '.grunt/theme.css',
                dest: 'dist/theme.html',
                match: '<!-- !import styles -->'
            }
        },

        // Minify the HTML, currently unused
        htmlmin: {
            options: {

            },
            theme: {
                src: 'dist/theme.html',
                dest: 'dist/theme.min.html'
            }
        }
    });

    grunt.registerTask('default', ['watch']);

    grunt.registerTask('views', ['pug:views', 'copy', 'insert']);
    grunt.registerTask('scripts', ['concat:scripts', 'copy', 'insert']);
    grunt.registerTask('styles', ['sass:styles', 'copy', 'insert']);

    grunt.registerTask('compile', ['pug:views', 'concat:scripts', 'sass:styles', 'copy', 'insert']);
};<|endoftext|>


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

  // List all files in the app directory.
  var templates = grunt.file.expand({
    filter: 'isFile',
    cwd: 'app'
  }, ['**/*.pug', '!_*/**/*.pug']);

  // Make actual choices out of them that grunt-prompt can use.
  var choices = templates.map(function(t) {
    return {
      name: t.substr(t.indexOf('/') + 1).replace('.pug', ''),
      value: t.replace('.pug', '')
    };
  });

  // Show elapsed time after tasks run
  require('time-grunt')(grunt);

  // Load all Grunt tasks
  require('load-grunt-tasks')(grunt);

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    settings: grunt.file.readJSON('gruntsettings.json'),

    /**
     * Project Paths Configuration
     * ===============================
     */
    paths: {
      images: 'img',
      src: 'app',
      directory: templates[0].substr(0, templates[0].indexOf('/')),
      file: templates[0].substr(templates[0].indexOf('/') + 1).replace('.pug', ''),
      tmp: '.tmp',
      dist: 'dist'
    },

    /**
     * Copy Tasks
     * ===============================
     */
    copy: {
      images: {
        files: [{
          expand: true,
          cwd: '<%= paths.src %>',
          src: ['<%= paths.directory %>/<%= paths.images %>/**/*.{png,jpg,jpeg,gif}', '_components/**/*.{png,jpg,jpeg,gif}'],
          dest: '<%= paths.tmp %>/<%= paths.directory %>/<%= paths.images %>',
          flatten: true
        }]
      },
      styles: {
        files: [{
          expand: true,
          cwd: '<%= paths.src %>',
          src: '{<%= paths.directory %>,_layouts,_components}/**/*.{scss,sass}',
          dest: '<%= paths.tmp %>/<%= paths.directory %>/styles',
          flatten: true
        }]
      }
    },

    /**
     * CSS Tasks
     * ===============================
     */
    sass: {
      dev: {
        options: {
          lineNumbers: true
        },
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/styles/**/*.{scss,sass}',
          dest: '<%= paths.tmp %>',
          ext: '.css'
        }]
      },
      dist: {
        options: {
          sourcemap: 'none',
          style: 'expanded'
        },
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/styles/**/*.{scss,sass}',
          dest: '<%= paths.tmp %>',
          ext: '.css'
        }]
      }
    },
    cssmin: {
      options: {
        keepBreaks: true
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: ['<%= paths.directory %>/styles/<%= paths.file %>.css'],
          dest: '<%= paths.tmp %>',
          ext: '.css'
        }]
      }
    },
    uncss: {
      dist: {
        options: {
          ignoreSheets : [/fonts.googleapis/],
        },
        files: [{
          src: '<%= paths.tmp %>/<%= paths.directory %>/<%= paths.file %>.html',
          dest: '<%= paths.tmp %>/<%= paths.directory %>/styles/styles.css'
        }]
      }
    },
    concat_css: {
      dist: {
        files: {
          '<%= paths.tmp %>/<%= paths.directory %>/styles/style.css': ['<%= paths.tmp %>/<%= paths.directory %>/styles/<%= paths.file %>.css', '<%= paths.tmp %>/<%= paths.directory %>/styles/<%= paths.file %>-editable.css']
        }
      }
    },
    cmq: {
      parts: {
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/styles/**/*.css',
          dest: '<%= paths.tmp %>'
        }]
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/styles/style.css',
          dest: '<%= paths.tmp %>'
        }]
      }
    },
    processhtml: {
      dist: {
        files: [{
          src: '<%= paths.tmp %>/<%= paths.directory %>/<%= paths.file %>.html',
          dest: '<%= paths.dist %>/<%= paths.directory %>/index.html'
        }]
      }
    },

    premailer: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/<%= paths.file %>.html',
          dest: '<%= paths.tmp %>'
        }]
      }
    },

    /**
     * Pug Compilation Tasks
     * ===============================
     */
    pug: {
      dev: {
        options: {
          pretty: true,
          data: function(dest, src) {
            return require('./' + src[0].replace(/(?=[\w-]+\.pug$).+/i,'') + 'data-dev.json');
          }
        },
        files: [{
          expand: true,
          cwd: '<%= paths.src %>',
          src: ['<%= paths.directory %>/*.pug'],
          dest: '<%= paths.tmp %>',
          ext: '.html'
        }]
      },
      dist: {
        options: {
          pretty: true,
          data: function(dest, src) {
            // Return an object of data to pass to templates
            return require('./' + src[0].replace(/(?=[\w-]+\.pug$).+/i,'') + 'data-prod.json');
          }
        },
        files: [{
          expand: true,
          cwd: '<%= paths.src %>',
          src: ['<%= paths.directory %>/*.pug'],
          dest: '<%= paths.tmp %>',
          ext: '.html'
        }]
      }
    },

    /**
     * Watch Task
     * ===============================
     */
    watch: {
      options: {
        spawn: false
      },
      sass: {
        files: ['<%= paths.src %>/{<%= paths.directory %>,_layouts,_components}/**/*.{scss,sass}'],
        tasks: ['copy:styles','sass:dev']
      },
      pug: {
        files: [
          '<%= paths.src %>/<%= paths.directory %>/*.json',
          '<%= paths.src %>/<%= paths.directory %>/<%= paths.file %>.pug',
          '<%= paths.src %>/{_layouts,_components}/**/*.pug'
        ],
        tasks: ['pug:dev']
      },
      image: {
        files: [
          '<%= paths.src %>/<%= paths.directory %>/<%= paths.images %>/**/*.{png,jpg,jpeg,gif}',
          '<%= paths.src %>/_components/**/*.{png,jpg,jpeg,gif}'
        ],
        tasks: ['copy:images']
      }
    },

    /**
     * Server Tasks
     * ===============================
     */

    browserSync: {
      dev: {
        bsFiles: {
          src: [
            '<%= paths.tmp %>/<%= paths.directory %>/<%= paths.file %>.html',
            '<%= paths.tmp %>/<%= paths.directory %>/styles/{,*/}*.css',
            '<%= paths.tmp %>/<%= paths.directory %>/<%= paths.images %>/{,*/}*.{png,jpg,jpeg,gif}'
          ]
        },
        options: {
          server: {
            baseDir: [
              '<%= paths.tmp %>/<%= paths.directory %>'
            ],
            index: "<%= paths.file %>.html"
          },
          port: 3000,
          watchTask: true
        }
      },
      dist: {
        options: {
          server: {
            baseDir: '<%= paths.dist %>/<%= paths.directory %>'
          }
        }
      }
    },

    /**
     * Cleanup Tasks
     * ===============================
     */
    clean: {
      dev: ['<%= paths.tmp %>'],
      dist: ['<%= paths.tmp %>', '<%= paths.dist %>/<%= paths.directory %>']
    },
    mkdir: {
      dist: {
        options: {
          create: ['<%= paths.tmp %>']
        }
      }
    },
    replace: {
      dist: {
        options: {
          patterns: [
            {
              match: /&/g,
              replacement: '&'
            }
          ]
        },
        files: [{
          expand: true,
          flatten: true,
          cwd: '<%= paths.dist %>/<%= paths.directory %>',
          src: ['index.html'],
          dest: '<%= paths.dist %>/<%= paths.directory %>'
        }]
      }
    },

    /**
     * Images Optimization Tasks
     * ===============================
     */
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/<%= paths.images %>/{,*/}*.{png,jpg,jpeg,gif}',
          dest: '<%= paths.dist %>'
        }]
      }
    },

    /**
     * Test Mailer Tasks
     * ===============================
     */
    nodemailer: {
      options: {
        transport: {
          type: 'SMTP',
          options: {
            service: '<%= paths.sender.service  %>',
            auth: {
              user: '<%= paths.sender.user  %>',
              pass: '<%= paths.sender.pass  %>'
            }
          }
        },
        message: {
          subject: '<%= paths.recipients.subject  %>'
        },
        recipients: [{
          name: '<%= paths.recipients.name  %>',
          email: '<%= paths.recipients.email %>'
        }]
      },
      dist: {
        src: ['<%= paths.dist %>/<%= paths.directory %>/index.html']
      }
    },
    prompt: {
      chooseFile: {
        options: {
          questions: [{
            config: 'paths.file',
            type: 'list',
            message: 'Which email should we build?',
            choices: choices,
            filter: function(answer) {
              grunt.config('paths.directory', answer.substr(0, answer.indexOf('/')));
              return answer.substr(answer.indexOf('/') + 1)
            }
          }]
        }
      },
      target: {
        options: {
          questions: [{
            config: 'paths.sender.service',
            type: 'input',
            message: 'What service should we use to send this email?',
            default: '<%= settings.mail.service %>'
          }, {
            config: 'paths.sender.user',
            type: 'input',
            message: 'What account should we send it from?',
            default: '<%= settings.mail.user %>'
          }, {
            config: 'paths.sender.pass',
            type: 'input',
            message: 'Account password?',
            default: '<%= settings.mail.pass %>'
          }, {
            config: 'paths.recipients.name',
            type: 'input',
            message: 'Who should we send this to (name)?',
            default: '<%= settings.mail.name %>'
          }, {
            config: 'paths.recipients.email',
            type: 'input',
            message: 'Who should we send this to (email)?',
            default: '<%= settings.mail.email %>'
          }, {
            config: 'paths.recipients.subject',
            type: 'input',
            message: 'What is the subject?',
            default: '<%= settings.mail.subject %>'
          }]
        }
      }
    }

  });

  grunt.registerTask('default', 'serve');

  grunt.registerTask('serve', function(target) {

    if (target === 'dist') {
      return grunt.task.run(['build', 'browserSync:dist']);
    }

    grunt.task.run([
      'chooseFile',
      'clean:dev',
      'copy',
      'sass:dev',
      'pug:dev',
      'browserSync:dev',
      'watch'
    ]);
  });

  grunt.registerTask('chooseFile', function(target) {

    if (templates.length > 1) {
      return grunt.task.run(['prompt:chooseFile']);
    }
  });

  grunt.registerTask('build', function(target) {

    var build = [
      'chooseFile',
      'clean:dist',
      'copy',
      'sass:dist',
      'cmq:parts',
      'cssmin'
    ];

    if (target === 'test') {
      build = build.concat([
        'pug:dev'
      ]);
    } else {
      build = build.concat([
        'pug:dist'
      ]);
    }

    build = build.concat([
      'imagemin',
      'concat_css',
      'cmq:dist',
      'premailer',
      'processhtml',
      'replace'
    ]);

    grunt.task.run(build);
  });

  grunt.registerTask('send', [
    'build',
    'prompt:target',
    'nodemailer'
  ]);

};<commit_msg>added 'clean' target to build script which removes mailchimp code<commit_after>module.exports = function(grunt) {
  'use strict';

  // List all files in the app directory.
  var templates = grunt.file.expand({
    filter: 'isFile',
    cwd: 'app'
  }, ['**/*.pug', '!_*/**/*.pug']);

  // Make actual choices out of them that grunt-prompt can use.
  var choices = templates.map(function(t) {
    return {
      name: t.substr(t.indexOf('/') + 1).replace('.pug', ''),
      value: t.replace('.pug', '')
    };
  });

  // Show elapsed time after tasks run
  require('time-grunt')(grunt);

  // Load all Grunt tasks
  require('load-grunt-tasks')(grunt);

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    settings: grunt.file.readJSON('gruntsettings.json'),

    /**
     * Project Paths Configuration
     * ===============================
     */
    paths: {
      images: 'img',
      src: 'app',
      directory: templates[0].substr(0, templates[0].indexOf('/')),
      file: templates[0].substr(templates[0].indexOf('/') + 1).replace('.pug', ''),
      tmp: '.tmp',
      dist: 'dist'
    },

    /**
     * Copy Tasks
     * ===============================
     */
    copy: {
      images: {
        files: [{
          expand: true,
          cwd: '<%= paths.src %>',
          src: ['<%= paths.directory %>/<%= paths.images %>/**/*.{png,jpg,jpeg,gif}', '_components/**/*.{png,jpg,jpeg,gif}'],
          dest: '<%= paths.tmp %>/<%= paths.directory %>/<%= paths.images %>',
          flatten: true
        }]
      },
      styles: {
        files: [{
          expand: true,
          cwd: '<%= paths.src %>',
          src: '{<%= paths.directory %>,_layouts,_components}/**/*.{scss,sass}',
          dest: '<%= paths.tmp %>/<%= paths.directory %>/styles',
          flatten: true
        }]
      }
    },

    /**
     * CSS Tasks
     * ===============================
     */
    sass: {
      dev: {
        options: {
          lineNumbers: true
        },
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/styles/**/*.{scss,sass}',
          dest: '<%= paths.tmp %>',
          ext: '.css'
        }]
      },
      dist: {
        options: {
          sourcemap: 'none',
          style: 'expanded'
        },
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/styles/**/*.{scss,sass}',
          dest: '<%= paths.tmp %>',
          ext: '.css'
        }]
      }
    },
    cssmin: {
      options: {
        keepBreaks: true
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: ['<%= paths.directory %>/styles/<%= paths.file %>.css'],
          dest: '<%= paths.tmp %>',
          ext: '.css'
        }]
      }
    },
    uncss: {
      dist: {
        options: {
          ignoreSheets : [/fonts.googleapis/],
        },
        files: [{
          src: '<%= paths.tmp %>/<%= paths.directory %>/<%= paths.file %>.html',
          dest: '<%= paths.tmp %>/<%= paths.directory %>/styles/styles.css'
        }]
      }
    },
    concat_css: {
      dist: {
        files: {
          '<%= paths.tmp %>/<%= paths.directory %>/styles/style.css': ['<%= paths.tmp %>/<%= paths.directory %>/styles/<%= paths.file %>.css', '<%= paths.tmp %>/<%= paths.directory %>/styles/<%= paths.file %>-editable.css']
        }
      },
      clean: {
        files: {
          '<%= paths.tmp %>/<%= paths.directory %>/styles/style.css': [
            '<%= paths.tmp %>/<%= paths.directory %>/styles/<%= paths.file %>.css',
            '<%= paths.tmp %>/<%= paths.directory %>/styles/<%= paths.file %>-editable.css',
            '<%= paths.tmp %>/<%= paths.directory %>/styles/<%= paths.file %>-inlined.css']
        }
      }
    },
    cmq: {
      parts: {
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/styles/**/*.css',
          dest: '<%= paths.tmp %>'
        }]
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/styles/style.css',
          dest: '<%= paths.tmp %>'
        }]
      }
    },
    processhtml: {
      dist: {
        files: [{
          src: '<%= paths.tmp %>/<%= paths.directory %>/<%= paths.file %>.html',
          dest: '<%= paths.dist %>/<%= paths.directory %>/index.html'
        }]
      }
    },

    premailer: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/<%= paths.file %>.html',
          dest: '<%= paths.tmp %>'
        }]
      }
    },

    /**
     * Pug Compilation Tasks
     * ===============================
     */
    pug: {
      dev: {
        options: {
          pretty: true,
          data: function(dest, src) {
            return require('./' + src[0].replace(/(?=[\w-]+\.pug$).+/i,'') + 'data-dev.json');
          }
        },
        files: [{
          expand: true,
          cwd: '<%= paths.src %>',
          src: ['<%= paths.directory %>/*.pug'],
          dest: '<%= paths.tmp %>',
          ext: '.html'
        }]
      },
      dist: {
        options: {
          pretty: true,
          data: function(dest, src) {
            // Return an object of data to pass to templates
            return require('./' + src[0].replace(/(?=[\w-]+\.pug$).+/i,'') + 'data-prod.json');
          }
        },
        files: [{
          expand: true,
          cwd: '<%= paths.src %>',
          src: ['<%= paths.directory %>/*.pug'],
          dest: '<%= paths.tmp %>',
          ext: '.html'
        }]
      }
    },

    /**
     * Watch Task
     * ===============================
     */
    watch: {
      options: {
        spawn: false
      },
      sass: {
        files: ['<%= paths.src %>/{<%= paths.directory %>,_layouts,_components}/**/*.{scss,sass}'],
        tasks: ['copy:styles','sass:dev']
      },
      pug: {
        files: [
          '<%= paths.src %>/<%= paths.directory %>/*.json',
          '<%= paths.src %>/<%= paths.directory %>/<%= paths.file %>.pug',
          '<%= paths.src %>/{_layouts,_components}/**/*.pug'
        ],
        tasks: ['pug:dev']
      },
      image: {
        files: [
          '<%= paths.src %>/<%= paths.directory %>/<%= paths.images %>/**/*.{png,jpg,jpeg,gif}',
          '<%= paths.src %>/_components/**/*.{png,jpg,jpeg,gif}'
        ],
        tasks: ['copy:images']
      }
    },

    /**
     * Server Tasks
     * ===============================
     */

    browserSync: {
      dev: {
        bsFiles: {
          src: [
            '<%= paths.tmp %>/<%= paths.directory %>/<%= paths.file %>.html',
            '<%= paths.tmp %>/<%= paths.directory %>/styles/{,*/}*.css',
            '<%= paths.tmp %>/<%= paths.directory %>/<%= paths.images %>/{,*/}*.{png,jpg,jpeg,gif}'
          ]
        },
        options: {
          server: {
            baseDir: [
              '<%= paths.tmp %>/<%= paths.directory %>'
            ],
            index: "<%= paths.file %>.html"
          },
          port: 3000,
          watchTask: true
        }
      },
      dist: {
        options: {
          server: {
            baseDir: '<%= paths.dist %>/<%= paths.directory %>'
          }
        }
      }
    },

    /**
     * Cleanup Tasks
     * ===============================
     */
    clean: {
      dev: ['<%= paths.tmp %>'],
      dist: ['<%= paths.tmp %>', '<%= paths.dist %>/<%= paths.directory %>']
    },
    mkdir: {
      dist: {
        options: {
          create: ['<%= paths.tmp %>']
        }
      }
    },
    replace: {
      amp: {
        options: {
          patterns: [
            {
              match: /&/g,
              replacement: '&'
            }
          ]
        },
        files: [{
          expand: true,
          flatten: true,
          cwd: '<%= paths.dist %>/<%= paths.directory %>',
          src: ['index.html'],
          dest: '<%= paths.dist %>/<%= paths.directory %>'
        }]
      },
      mailchimp: {
        options: {
          patterns: [
            {
              match: / mc:(.+?)="(.+?)"/gi,
              replacement: ''
            },
            {
              match: / \/\*@editable\*\//g,
              replacement: ''
            },
            {
              match: /\/\*\*[^]*?\*\//g,
              replacement: ''
            }
          ]
        },
        files: [{
          expand: true,
          flatten: true,
          cwd: '<%= paths.dist %>/<%= paths.directory %>',
          src: ['index.html'],
          dest: '<%= paths.dist %>/<%= paths.directory %>'
        }]
      }
    },

    /**
     * Images Optimization Tasks
     * ===============================
     */
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= paths.tmp %>',
          src: '<%= paths.directory %>/<%= paths.images %>/{,*/}*.{png,jpg,jpeg,gif}',
          dest: '<%= paths.dist %>'
        }]
      }
    },

    /**
     * Test Mailer Tasks
     * ===============================
     */
    nodemailer: {
      options: {
        transport: {
          type: 'SMTP',
          options: {
            service: '<%= paths.sender.service  %>',
            auth: {
              user: '<%= paths.sender.user  %>',
              pass: '<%= paths.sender.pass  %>'
            }
          }
        },
        message: {
          subject: '<%= paths.recipients.subject  %>'
        },
        recipients: [{
          name: '<%= paths.recipients.name  %>',
          email: '<%= paths.recipients.email %>'
        }]
      },
      dist: {
        src: ['<%= paths.dist %>/<%= paths.directory %>/index.html']
      }
    },
    prompt: {
      chooseFile: {
        options: {
          questions: [{
            config: 'paths.file',
            type: 'list',
            message: 'Which email should we build?',
            choices: choices,
            filter: function(answer) {
              grunt.config('paths.directory', answer.substr(0, answer.indexOf('/')));
              return answer.substr(answer.indexOf('/') + 1)
            }
          }]
        }
      },
      target: {
        options: {
          questions: [{
            config: 'paths.sender.service',
            type: 'input',
            message: 'What service should we use to send this email?',
            default: '<%= settings.mail.service %>'
          }, {
            config: 'paths.sender.user',
            type: 'input',
            message: 'What account should we send it from?',
            default: '<%= settings.mail.user %>'
          }, {
            config: 'paths.sender.pass',
            type: 'input',
            message: 'Account password?',
            default: '<%= settings.mail.pass %>'
          }, {
            config: 'paths.recipients.name',
            type: 'input',
            message: 'Who should we send this to (name)?',
            default: '<%= settings.mail.name %>'
          }, {
            config: 'paths.recipients.email',
            type: 'input',
            message: 'Who should we send this to (email)?',
            default: '<%= settings.mail.email %>'
          }, {
            config: 'paths.recipients.subject',
            type: 'input',
            message: 'What is the subject?',
            default: '<%= settings.mail.subject %>'
          }]
        }
      }
    }

  });

  grunt.registerTask('default', 'serve');

  grunt.registerTask('serve', function(target) {

    if (target === 'dist') {
      return grunt.task.run(['build', 'browserSync:dist']);
    }

    var tasks = [
      'chooseFile',
      'clean:dev',
      'copy',
      'sass:dev',
      'pug:dev',
      'browserSync:dev',
      'watch'
    ];

    grunt.task.run(tasks);
  });

  grunt.registerTask('chooseFile', function(target) {

    if (templates.length > 1) {
      return grunt.task.run(['prompt:chooseFile']);
    }
  });

  grunt.registerTask('build', function(target) {

    var tasks = [
      'chooseFile',
      'clean:dist',
      'copy',
      'sass:dist',
      'cmq:parts',
      'cssmin'
    ];

    if (target === 'test') {
      tasks = tasks.concat([
        'pug:dev'
      ]);
    } else {
      tasks = tasks.concat([
        'pug:dist'
      ]);
    }

    tasks = tasks.concat([
      'imagemin',
      'concat_css:dist',
      'cmq:dist',
      'premailer',
      'processhtml',
      'replace:amp'
    ]);

    if (target === 'clean'){
      tasks = tasks.concat([
        'replace:mailchimp'
      ]);

      var concat_i = tasks.indexOf('concat_css:dist');
      if (concat_i !== -1) {
        tasks[concat_i] = 'concat_css:clean';
      }
    }

    grunt.task.run(tasks);
  });

  grunt.registerTask('send', [
    'build',
    'prompt:target',
    'nodemailer'
  ]);

};<|endoftext|>


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

  // imports
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadNpmTasks('grunt-contrib-livereload');
  grunt.loadNpmTasks('grunt-jekyll');
  grunt.loadNpmTasks('grunt-regarde');
  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-open');

  // project configuration
  var happyPlan = grunt.file.readJSON('happy-plan.json');

  // grujnt configuration
  grunt.initConfig({

    happyPlan: happyPlan,

    jshint: happyPlan.grunt.jshint,

    // open in browser
    open : {
      dev : {
        path: 'http://127.0.0.1:8080/'
      }
    },

    // server
    connect: {
      server: {
        options: {
          port: 8080,
          base: 'dist',
          hostname: '' // Must be empty to be accessible everywhere and not only "localhost"
        }
      }
    },

    // livereload
    livereload: {
      port: 35728
    },

    // remove folders and files
    clean: {
      dist: {
        src: ['<%= happyPlan.dist.path %>']
      },
      build: {
        src: ['<%= happyPlan.build.path %>']
      },
      jekyll: {
        src: ['<%= happyPlan.build.jekyll.tmp.path %>', '<%= happyPlan.build.jekyll.compiled %>']
      }
    },

    // static file generator
    jekyll: {
      compile: {
        src:            '<%= happyPlan.build.jekyll.tmp.path %>',
        dest:           '<%= happyPlan.build.jekyll.compiled %>',
        baseurl:        '<%= happyPlan.baseUrl %>',
        pygments:       true
      }
    },

    // Copy folders and files
    copy: {
      cssAsScss: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.assets.components %>',
            src: ['**/*.css'],
            dest: '<%= happyPlan.src.assets.components %>',
            filter: 'isFile',
            ext:    ".scss"
          }
        ]
      },
      jekyllBuildToDist: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.build.jekyll.compiled %>',
            src: ['**'],
            dest: '<%= happyPlan.dist.root %>'
          }
        ]
      },
      jekyllPages: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.jekyll.pages %>',
            src: ['**'],
            dest: '<%= happyPlan.build.jekyll.tmp.pages %>'
          }
        ]
      },
      jekyllPosts: {
        files: [
          {
              expand: true,
              cwd: '<%= happyPlan.src.jekyll.posts %>',
              src: ['**', '!_*'],
              dest: '<%= happyPlan.build.jekyll.tmp.posts %>'
          }
        ]
      },
      jekyllLayouts: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.jekyll.layouts %>',
            src: ['**'],
            dest: '<%= happyPlan.build.jekyll.tmp.layouts %>'
          }
        ]
      },
      jekyllPartials: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.jekyll.partials %>',
            src: ['**'],
            dest: '<%= happyPlan.build.jekyll.tmp.partials %>'
          }
        ]
      },
      jekyllConfig: {
        files: [
          {
            src: '<%= happyPlan.src.jekyll.config %>',
            dest: '<%= happyPlan.build.jekyll.tmp.config %>'
          }
        ]
      },
      static: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.assets.static %>',
            src: ['**/*', '!**/_*/**'],
            dest: '<%= happyPlan.dist.assets.static %>'
          }
        ]
      },
      images: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.assets.images %>',
            src: ['**'],
            dest: '<%= happyPlan.dist.assets.images %>'
          }
        ]
      },
      medias: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.medias %>',
            src: ['**'],
            dest: '<%= happyPlan.dist.medias %>'
          }
        ]
      },
      root: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.path %>',
            src: ['**/*','!**/_*/**'],
            dest: '<%= happyPlan.dist.root %>'
          }
        ]
      }
    },

    // concat scripts
    concat: {
      dist: {
        files: {
          '<%= happyPlan.dist.assets.scripts %>/script.js': ['<%= happyPlan.src.assets.scripts %>/*.js']
        }
      }
    },

    // minify javascript
    uglify: {
      dist: {
        files: {
          '<%= happyPlan.dist.assets.scripts %>/script.js': ['<%= happyPlan.dist.assets.scripts %>/script.js']
        }
      }
    },

    /*
    Doesn't work
    webfont: {
      icons: {
        src: '<%= happyPlan.src.assets.fontcustom %>/*.svg',
        dest: '<%= happyPlan.dist.assets.fonts %>/icons',
        destCss: '<%= happyPlan.src.assets.styles %>',
        options: {
            styles: 'icon',
            stylesheet: 'scss',
            hashes: false
        }
      }
    },*/

    // some shell cmds
    shell: {
      svgToFonts: {
        command: './bin/fontcustom.sh',
        options: {
          stdout: true
        }
      }
    },

    // time to have some styles!
    compass: {
      dev: {
        options: {
          sassDir: '<%= happyPlan.src.assets.styles %>',
          cssDir: '<%= happyPlan.dist.assets.styles %>',
          imagesDir: '<%= happyPlan.src.assets.images %>',
          javascriptsDir: '<%= happyPlan.src.assets.scripts %>',
          fontsDir: '<%= happyPlan.src.assets.fonts %>',

          // here we give to compass dist path (without dist root)
          raw: [
              'httppath = "' + happyPlan.baseUrl + '"',
              'http_images_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.images.replace(happyPlan.dist.path, '') + '"',
              'http_javascripts_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.scripts.replace(happyPlan.dist.path, '') + '"',
              'http_fonts_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.static.replace(happyPlan.dist.path, '') + '/fonts"'
          ].join("\n"),

          outputStyle: 'expanded',
          noLineComments: false,
          debugInfo: true
        }
      },
      dist: {
        options: {
          sassDir: '<%= happyPlan.src.assets.styles %>',
          cssDir: '<%= happyPlan.dist.assets.styles %>',
          imagesDir: '<%= happyPlan.src.assets.images %>',
          javascriptsDir: '<%= happyPlan.src.assets.scripts %>',
          fontsDir: '<%= happyPlan.src.assets.fonts %>',

          // here we give to compass dist path (without dist root)
          raw: [
              'httppath = "' + happyPlan.baseUrl + '"',
              'http_images_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.images.replace(happyPlan.dist.path, '') + '"',
              'http_javascripts_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.scripts.replace(happyPlan.dist.path, '') + '"',
              'http_fonts_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.static.replace(happyPlan.dist.path, '') + '/fonts"'
          ].join("\n"),

          outputStyle: 'compressed',
          noLineComments: true,
          force: true
        }
      }
    },

    // optimise images
    imagemin: {
      dist: {
        options: {
          optimizationLevel: 3,
          progressive: true
        },
        files: [
          {
            expand: true,
            cwd: "<%= happyPlan.dist.assets.images %>",
            src: ["**/*"],
            dest: "<%= happyPlan.dist.assets.images %>"
          },
          {
            expand: true,
            cwd: "<%= happyPlan.dist.medias %>",
            src: ["**/*"],
            dest: "<%= happyPlan.dist.medias %>"
          }
        ]
      }
    },

    // watch
    regarde: {
      html: {
          files: ['<%= happyPlan.src.path %>**/*.{html,md,txt,xml}'],
          tasks: ['jekyll:dist']
      },
      js: {
          files: ['<%= happyPlan.src.assets.scripts %>/**/*'],
          tasks: ['concat:dist']
      },
      scss: {
          files: ['<%= happyPlan.src.assets.styles %>/**/*'],
          tasks: ['compass:dev']
      },
      static: {
          files: ['<%= happyPlan.src.assets.static %>**/*', '!<%= happyPlan.src.assets.static %>**/_*/**'],
          tasks: ['copy:static']
      },
      images: {
          files: ['<%= happyPlan.src.assets.images %>/**/*'],
          tasks: ['copy:images']
      },
      icons: {
          files: ['<%= happyPlan.src.assets.fontcustom %>/icons/*.svg'],
          tasks: ['']
      },
      livereload: {
          files: ['<%= happyPlan.dist.path %>**/*.*'],
          tasks: ['livereload']
      }
    }
  });

  // main commands
  grunt.registerTask('default', ['dev', 'livereload-start', 'server', 'open:dev', 'regarde']);
  grunt.registerTask('dist',    ['jshint', 'build', 'compass:dist', 'uglify:dist', 'imagemin:dist', 'clean:build']);
  grunt.registerTask('dev',     ['jshint', 'build', 'compass:dev']);
  grunt.registerTask('build',   ['clean:dist', 'jekyll:dist', 'copy:root', 'shell:svgToFonts', 'copy:images', 'copy:static', 'copy:medias', 'concat:dist']);

  // jekyll
  grunt.registerTask('jekyll:dist',   ['jekyll:build', 'copy:jekyllBuildToDist']);
  grunt.registerTask('jekyll:build',  ['clean:jekyll','jekyll:copy', 'jekyll:compile']);
  grunt.registerTask('jekyll:copy',   ['copy:jekyllPages', 'copy:jekyllPosts', 'copy:jekyllPartials', 'copy:jekyllConfig', 'copy:jekyllLayouts']);

  // server
  grunt.registerTask('server', 'connect:server');

  // waiting for https://github.com/gruntjs/grunt-contrib-imagemin/issues/11 to use just 'build' here
  grunt.registerTask('test', ['jshint', 'build', 'compass:dist', 'uglify:dist', 'copy:images']);
};<commit_msg>typo in Gruntfile.js<commit_after>module.exports = function(grunt) {

  // imports
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadNpmTasks('grunt-contrib-livereload');
  grunt.loadNpmTasks('grunt-jekyll');
  grunt.loadNpmTasks('grunt-regarde');
  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-open');

  // project configuration
  var happyPlan = grunt.file.readJSON('happy-plan.json');

  // grunt configuration
  grunt.initConfig({

    happyPlan: happyPlan,

    jshint: happyPlan.grunt.jshint,

    // open in browser
    open : {
      dev : {
        path: 'http://127.0.0.1:8080/'
      }
    },

    // server
    connect: {
      server: {
        options: {
          port: 8080,
          base: 'dist',
          hostname: '' // Must be empty to be accessible everywhere and not only "localhost"
        }
      }
    },

    // livereload
    livereload: {
      port: 35728
    },

    // remove folders and files
    clean: {
      dist: {
        src: ['<%= happyPlan.dist.path %>']
      },
      build: {
        src: ['<%= happyPlan.build.path %>']
      },
      jekyll: {
        src: ['<%= happyPlan.build.jekyll.tmp.path %>', '<%= happyPlan.build.jekyll.compiled %>']
      }
    },

    // static file generator
    jekyll: {
      compile: {
        src:            '<%= happyPlan.build.jekyll.tmp.path %>',
        dest:           '<%= happyPlan.build.jekyll.compiled %>',
        baseurl:        '<%= happyPlan.baseUrl %>',
        pygments:       true
      }
    },

    // Copy folders and files
    copy: {
      cssAsScss: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.assets.components %>',
            src: ['**/*.css'],
            dest: '<%= happyPlan.src.assets.components %>',
            filter: 'isFile',
            ext:    ".scss"
          }
        ]
      },
      jekyllBuildToDist: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.build.jekyll.compiled %>',
            src: ['**'],
            dest: '<%= happyPlan.dist.root %>'
          }
        ]
      },
      jekyllPages: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.jekyll.pages %>',
            src: ['**'],
            dest: '<%= happyPlan.build.jekyll.tmp.pages %>'
          }
        ]
      },
      jekyllPosts: {
        files: [
          {
              expand: true,
              cwd: '<%= happyPlan.src.jekyll.posts %>',
              src: ['**', '!_*'],
              dest: '<%= happyPlan.build.jekyll.tmp.posts %>'
          }
        ]
      },
      jekyllLayouts: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.jekyll.layouts %>',
            src: ['**'],
            dest: '<%= happyPlan.build.jekyll.tmp.layouts %>'
          }
        ]
      },
      jekyllPartials: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.jekyll.partials %>',
            src: ['**'],
            dest: '<%= happyPlan.build.jekyll.tmp.partials %>'
          }
        ]
      },
      jekyllConfig: {
        files: [
          {
            src: '<%= happyPlan.src.jekyll.config %>',
            dest: '<%= happyPlan.build.jekyll.tmp.config %>'
          }
        ]
      },
      static: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.assets.static %>',
            src: ['**/*', '!**/_*/**'],
            dest: '<%= happyPlan.dist.assets.static %>'
          }
        ]
      },
      images: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.assets.images %>',
            src: ['**'],
            dest: '<%= happyPlan.dist.assets.images %>'
          }
        ]
      },
      medias: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.medias %>',
            src: ['**'],
            dest: '<%= happyPlan.dist.medias %>'
          }
        ]
      },
      root: {
        files: [
          {
            expand: true,
            cwd: '<%= happyPlan.src.path %>',
            src: ['**/*','!**/_*/**'],
            dest: '<%= happyPlan.dist.root %>'
          }
        ]
      }
    },

    // concat scripts
    concat: {
      dist: {
        files: {
          '<%= happyPlan.dist.assets.scripts %>/script.js': ['<%= happyPlan.src.assets.scripts %>/*.js']
        }
      }
    },

    // minify javascript
    uglify: {
      dist: {
        files: {
          '<%= happyPlan.dist.assets.scripts %>/script.js': ['<%= happyPlan.dist.assets.scripts %>/script.js']
        }
      }
    },

    /*
    Doesn't work
    webfont: {
      icons: {
        src: '<%= happyPlan.src.assets.fontcustom %>/*.svg',
        dest: '<%= happyPlan.dist.assets.fonts %>/icons',
        destCss: '<%= happyPlan.src.assets.styles %>',
        options: {
            styles: 'icon',
            stylesheet: 'scss',
            hashes: false
        }
      }
    },*/

    // some shell cmds
    shell: {
      svgToFonts: {
        command: './bin/fontcustom.sh',
        options: {
          stdout: true
        }
      }
    },

    // time to have some styles!
    compass: {
      dev: {
        options: {
          sassDir: '<%= happyPlan.src.assets.styles %>',
          cssDir: '<%= happyPlan.dist.assets.styles %>',
          imagesDir: '<%= happyPlan.src.assets.images %>',
          javascriptsDir: '<%= happyPlan.src.assets.scripts %>',
          fontsDir: '<%= happyPlan.src.assets.fonts %>',

          // here we give to compass dist path (without dist root)
          raw: [
              'httppath = "' + happyPlan.baseUrl + '"',
              'http_images_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.images.replace(happyPlan.dist.path, '') + '"',
              'http_javascripts_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.scripts.replace(happyPlan.dist.path, '') + '"',
              'http_fonts_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.static.replace(happyPlan.dist.path, '') + '/fonts"'
          ].join("\n"),

          outputStyle: 'expanded',
          noLineComments: false,
          debugInfo: true
        }
      },
      dist: {
        options: {
          sassDir: '<%= happyPlan.src.assets.styles %>',
          cssDir: '<%= happyPlan.dist.assets.styles %>',
          imagesDir: '<%= happyPlan.src.assets.images %>',
          javascriptsDir: '<%= happyPlan.src.assets.scripts %>',
          fontsDir: '<%= happyPlan.src.assets.fonts %>',

          // here we give to compass dist path (without dist root)
          raw: [
              'httppath = "' + happyPlan.baseUrl + '"',
              'http_images_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.images.replace(happyPlan.dist.path, '') + '"',
              'http_javascripts_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.scripts.replace(happyPlan.dist.path, '') + '"',
              'http_fonts_path = "' + happyPlan.baseUrl + happyPlan.dist.assets.static.replace(happyPlan.dist.path, '') + '/fonts"'
          ].join("\n"),

          outputStyle: 'compressed',
          noLineComments: true,
          force: true
        }
      }
    },

    // optimise images
    imagemin: {
      dist: {
        options: {
          optimizationLevel: 3,
          progressive: true
        },
        files: [
          {
            expand: true,
            cwd: "<%= happyPlan.dist.assets.images %>",
            src: ["**/*"],
            dest: "<%= happyPlan.dist.assets.images %>"
          },
          {
            expand: true,
            cwd: "<%= happyPlan.dist.medias %>",
            src: ["**/*"],
            dest: "<%= happyPlan.dist.medias %>"
          }
        ]
      }
    },

    // watch
    regarde: {
      html: {
          files: ['<%= happyPlan.src.path %>**/*.{html,md,txt,xml}'],
          tasks: ['jekyll:dist']
      },
      js: {
          files: ['<%= happyPlan.src.assets.scripts %>/**/*'],
          tasks: ['concat:dist']
      },
      scss: {
          files: ['<%= happyPlan.src.assets.styles %>/**/*'],
          tasks: ['compass:dev']
      },
      static: {
          files: ['<%= happyPlan.src.assets.static %>**/*', '!<%= happyPlan.src.assets.static %>**/_*/**'],
          tasks: ['copy:static']
      },
      images: {
          files: ['<%= happyPlan.src.assets.images %>/**/*'],
          tasks: ['copy:images']
      },
      icons: {
          files: ['<%= happyPlan.src.assets.fontcustom %>/icons/*.svg'],
          tasks: ['']
      },
      livereload: {
          files: ['<%= happyPlan.dist.path %>**/*.*'],
          tasks: ['livereload']
      }
    }
  });

  // main commands
  grunt.registerTask('default', ['dev', 'livereload-start', 'server', 'open:dev', 'regarde']);
  grunt.registerTask('dist',    ['jshint', 'build', 'compass:dist', 'uglify:dist', 'imagemin:dist', 'clean:build']);
  grunt.registerTask('dev',     ['jshint', 'build', 'compass:dev']);
  grunt.registerTask('build',   ['clean:dist', 'jekyll:dist', 'copy:root', 'shell:svgToFonts', 'copy:images', 'copy:static', 'copy:medias', 'concat:dist']);

  // jekyll
  grunt.registerTask('jekyll:dist',   ['jekyll:build', 'copy:jekyllBuildToDist']);
  grunt.registerTask('jekyll:build',  ['clean:jekyll','jekyll:copy', 'jekyll:compile']);
  grunt.registerTask('jekyll:copy',   ['copy:jekyllPages', 'copy:jekyllPosts', 'copy:jekyllPartials', 'copy:jekyllConfig', 'copy:jekyllLayouts']);

  // server
  grunt.registerTask('server', 'connect:server');

  // waiting for https://github.com/gruntjs/grunt-contrib-imagemin/issues/11 to use just 'build' here
  grunt.registerTask('test', ['jshint', 'build', 'compass:dist', 'uglify:dist', 'copy:images']);
};
<|endoftext|>


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

    jshint: {
      files: [
        'app/**/*.js',
        'admin/**/*.js',
        'test/**/*.js',
        'shared/**/*.js',
        'server/**/*.js'
      ],
      options: {
        globals: {
          window: true,
          document: true,
          navigator: true,
          console: true,
          module: true,
          require: true,
          FastClick: true,
          $: true,
          Backbone: true,
          Parse: true,
          Handlebars: true,
          _: true,
          google: true,
          parseAppId: true,
          parseJSKey: true
        },
        undef: true,
        debug: true,
        '-W030': true
      }
    },

    // A simple Grunt invoker for mocha tests
    simplemocha: {
      options: {
        timeout: 3000,
        ignoreLeaks: false,
        ui: 'bdd',
        reporter: 'list'
      },

      all: {
        src: 'test/**/*.js'
      }
    },

    // run the 'default' task when any watched files change
    watch: {
      files: [
        'Gruntfile.js',
        'app/**/*',
        'admin/**/*',
        'shared/**/*',
        'server/**/*',
        'vendor/**/*',
        'test/**/*'
      ],
      tasks: ['default']
    },

    sass: {
      // generate app-specific css file
      // sass performs both the processing and concatenation steps for css
      app: {
        src: 'app/css/app.scss',
        dest: 'tmp/linksf.css'
      },

      admin: {
        src: 'admin/css/admin.scss',
        dest: 'tmp/linksf_admin.css'
      }
    },

    // Browserify
    browserify: {
      options: {
        // We want `.hbs` files to be `require`able. We use the hbsfy transform
        // to precompile Handlebars templates and let us require the compiled
        // JavaScript functions.
        transform: ['hbsfy']
      },
      app: {
        // The entry point where Browserify will begin searching the AST for `require` calls
        src: 'app/js/app.js',

        // The built file
        dest: 'tmp/app.js',

        options: {
          // We want alias mappings because we'd rather
          // `require('views/index_view')` than `require('./views/index_view.js')`
          //
          // There is a tradeoff for convenient here - all aliased files are exported
          // into the built app.js file, even if they're never explicitly
          // `require`d from the entry point tree.
          aliasMappings: [
            { cwd: 'shared/js/lib',         src: '*.js',  dest: 'shared/lib' },
            { cwd: 'shared/js/lib',         src: '*.js',  dest: 'cloud/lib' },
            { cwd: 'shared/js/models',      src: '*.js',  dest: 'shared/models' },
            { cwd: 'shared/js/models',      src: '*.js',  dest: 'cloud/models' },
            { cwd: 'shared/js/collections', src: '*.js',  dest: 'shared/collections' },
            { cwd: 'shared/js/views',       src: '*.js',  dest: 'shared/views' },
            { cwd: 'shared/js/templates',   src: '*.hbs', dest: 'shared/templates' },
            { cwd: 'app/js/lib',            src: '*.js',  dest: 'lib' },
            { cwd: 'app/js/models',         src: '*.js',  dest: 'models' },
            { cwd: 'app/js/collections',    src: '*.js',  dest: 'collections' },
            { cwd: 'app/js/routers',        src: '*.js',  dest: 'routers' },
            { cwd: 'app/js/templates',      src: '*.hbs', dest: 'templates' },
            { cwd: 'app/js/views',          src: '*.js',  dest: 'views' }
          ]
        }
      },
      // See browserify:app above
      admin: {
        src: 'admin/js/admin.js',
        dest: 'tmp/admin.js',
        options: {
          aliasMappings: [
            { cwd: 'shared/js/lib',         src: '*.js',  dest: 'shared/lib' },
            { cwd: 'shared/js/lib',         src: '*.js',  dest: 'cloud/lib' },
            { cwd: 'shared/js/models',      src: '*.js',  dest: 'shared/models' },
            { cwd: 'shared/js/models',      src: '*.js',  dest: 'cloud/models' },
            { cwd: 'shared/js/collections', src: '*.js',  dest: 'shared/collections' },
            { cwd: 'shared/js/views',       src: '*.js',  dest: 'shared/views' },
            { cwd: 'shared/js/templates',   src: '*.hbs', dest: 'shared/templates' },
            { cwd: 'admin/js/lib',          src: '*.js',  dest: 'lib' },
            { cwd: 'admin/js/models',       src: '*.js',  dest: 'models' },
            { cwd: 'admin/js/collections',  src: '*.js',  dest: 'collections' },
            { cwd: 'admin/js/routers',      src: '*.js',  dest: 'routers' },
            { cwd: 'admin/js/templates',    src: '*.hbs', dest: 'templates' },
            { cwd: 'admin/js/views',        src: '*.js',  dest: 'views' }
          ]
        }
      }
    },

    // Minify css files
    cssmin: {
      app: {
        src: 'tmp/linksf.css',
        dest: 'tmp/linksf.css'
      },
      admin: {
        src: 'tmp/linksf_admin.css',
        dest: 'tmp/linksf_admin.css'
      },
    },

    // Concatenate files together.
    concat: {
      // Not a target, just a variable that we can interpolate in elsewhere.
      shared_js: [
        'vendor/js/jquery-2.0.3.js',
        'vendor/js/jquery.serialize-object.js',
        'vendor/js/underscore.js',
        'vendor/js/backbone-1.0.0.js',
        'vendor/js/parse-1.2.12.js'
      ],

      shared_js_minified: [
        'vendor/js/jquery-2.0.3.min.js',
        'vendor/js/jquery.serialize-object.min.js',
        'vendor/js/underscore.min.js',
        'vendor/js/backbone-1.0.0.min.js',
        'vendor/js/parse-1.2.12.min.js'
      ],

      // App also uses the vendored fastclick library
      app: {
        src: [
          '<%= concat.shared_js %>',
          'vendor/js/bootstrap-button.js',
          'vendor/js/fastclick.js',
          'tmp/app.js'
        ],
        dest: 'tmp/linksf.js'
      },

      // Concat minified files
      app_min: {
        src: [
          '<%= concat.shared_js_minified %>',
          'vendor/js/bootstrap-button.min.js',
          'vendor/js/fastclick.min.js',
          'tmp/app.min.js'
        ],
        dest: 'tmp/linksf.js'
      },

      // Admin uses backbone filters for authentication and autosize for text entry
      admin: {
        src: [
          '<%= concat.shared_js %>',
          'vendor/js/backbone_filters.js',
          'vendor/js/jquery.autosize.js',
          'vendor/js/bootstrap.js',
          'tmp/admin.js'
        ],
        dest: 'tmp/linksf_admin.js'
      },

      admin_min: {
        src: [
          '<%= concat.shared_js_minified %>',
          'vendor/js/backbone_filters.min.js',
          'vendor/js/jquery.autosize.min.js',
          'vendor/js/bootstrap.min.js',
          'tmp/admin.min.js'
        ],
        dest: 'tmp/linksf_admin.js'
      }
    },

    uglify: {
      options: {
        mangle: false,
        preserveComments: false,
        report: 'min'
      },

      vendor: {
        files: {
          // These libraries are not distributed with minified versions, so we
          // minify them ourselves.
          'vendor/js/jquery.serialize-object.min.js': 'vendor/js/jquery.serialize-object.js',
          'vendor/js/backbone_filters.min.js': 'vendor/js/backbone_filters.js',
          'vendor/js/bootstrap-button.min.js': 'vendor/js/bootstrap-button.js'
        }
      },
      app: {files: {'tmp/app.min.js': 'tmp/app.js'}},
      admin: {files: {'tmp/admin.min.js': 'tmp/admin.js'}}
    },

    clean: {
      build: {
        src: 'build/*',
        filter: function(filepath) { return filepath !== 'build/.gitkeep'; }
      }
    },

    cachebuster: {
      dist: {
        files: {
          src: [
            'tmp/linksf.js',
            'tmp/linksf.css',
            'tmp/linksf_admin.js',
            'tmp/linksf_admin.css'
          ],
        },
        options: {
          complete: function(hashes) {
            // ugly but the only way to tag each file with a key
            var keyMap = {
                'tmp/linksf.js': 'linksf_js',
                'tmp/linksf.css': 'linksf_css',
                'tmp/linksf_admin.js': 'linksf_admin_js',
                'tmp/linksf_admin.css': 'linksf_admin_css'
               },
               context = {},
               Handlebars = require('handlebars'),
               template,
               output;

            context.parseAppId = process.env.PARSE_APP_ID;
            context.parseJSKey = process.env.PARSE_JS_KEY;

            Object.keys(hashes).forEach(function(key) {
              var matches = key.match(/^tmp\/(.*)(\..*)$/),
                  filename = matches[1],
                  extension = matches[2],
                  outputFile = 'build/' + filename + '-' + hashes[key] + extension;

              grunt.file.copy(key, outputFile);
              context[keyMap[key]] = outputFile;
            });

            template = Handlebars.compile(grunt.file.read('app/index.html'));
            output = template(context);
            grunt.file.write('index.html', output);

            template = Handlebars.compile(grunt.file.read('admin/admin.html'));
            output = template(context);
            grunt.file.write('admin.html', output);
          }
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-sass');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-simple-mocha');
  grunt.loadNpmTasks('grunt-cachebuster');
  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks('grunt-contrib-clean');

  grunt.loadTasks('tasks');

  grunt.registerTask('build:development', [
    'clean',
    'jshint',
    'simplemocha',
    'sass',
    'browserify',
    'concat:app',
    'concat:admin',
    'configure:development',
    'cachebuster'
  ]);

  grunt.registerTask('build:production', [
    'clean',
    'jshint',
    'simplemocha',
    'sass',
    'cssmin',
    'browserify',
    'uglify',
    'concat:app_min',
    'concat:admin_min',
    'configure:production',
    'cachebuster'
  ]);

  grunt.registerTask('default', [
    'build:development'
  ]);

  grunt.registerTask('release', [
    'build:production'
  ]);
};
<commit_msg>remove unused grunt alias<commit_after>module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    jshint: {
      files: [
        'app/**/*.js',
        'admin/**/*.js',
        'test/**/*.js',
        'shared/**/*.js',
        'server/**/*.js'
      ],
      options: {
        globals: {
          window: true,
          document: true,
          navigator: true,
          console: true,
          module: true,
          require: true,
          FastClick: true,
          $: true,
          Backbone: true,
          Parse: true,
          Handlebars: true,
          _: true,
          google: true,
          parseAppId: true,
          parseJSKey: true
        },
        undef: true,
        debug: true,
        '-W030': true
      }
    },

    // A simple Grunt invoker for mocha tests
    simplemocha: {
      options: {
        timeout: 3000,
        ignoreLeaks: false,
        ui: 'bdd',
        reporter: 'list'
      },

      all: {
        src: 'test/**/*.js'
      }
    },

    // run the 'default' task when any watched files change
    watch: {
      files: [
        'Gruntfile.js',
        'app/**/*',
        'admin/**/*',
        'shared/**/*',
        'server/**/*',
        'vendor/**/*',
        'test/**/*'
      ],
      tasks: ['default']
    },

    sass: {
      // generate app-specific css file
      // sass performs both the processing and concatenation steps for css
      app: {
        src: 'app/css/app.scss',
        dest: 'tmp/linksf.css'
      },

      admin: {
        src: 'admin/css/admin.scss',
        dest: 'tmp/linksf_admin.css'
      }
    },

    // Browserify
    browserify: {
      options: {
        // We want `.hbs` files to be `require`able. We use the hbsfy transform
        // to precompile Handlebars templates and let us require the compiled
        // JavaScript functions.
        transform: ['hbsfy']
      },
      app: {
        // The entry point where Browserify will begin searching the AST for `require` calls
        src: 'app/js/app.js',

        // The built file
        dest: 'tmp/app.js',

        options: {
          // We want alias mappings because we'd rather
          // `require('views/index_view')` than `require('./views/index_view.js')`
          //
          // There is a tradeoff for convenient here - all aliased files are exported
          // into the built app.js file, even if they're never explicitly
          // `require`d from the entry point tree.
          aliasMappings: [
            { cwd: 'shared/js/lib',         src: '*.js',  dest: 'shared/lib' },
            { cwd: 'shared/js/lib',         src: '*.js',  dest: 'cloud/lib' },
            { cwd: 'shared/js/models',      src: '*.js',  dest: 'shared/models' },
            { cwd: 'shared/js/models',      src: '*.js',  dest: 'cloud/models' },
            { cwd: 'shared/js/collections', src: '*.js',  dest: 'shared/collections' },
            { cwd: 'shared/js/views',       src: '*.js',  dest: 'shared/views' },
            { cwd: 'shared/js/templates',   src: '*.hbs', dest: 'shared/templates' },
            { cwd: 'app/js/lib',            src: '*.js',  dest: 'lib' },
            { cwd: 'app/js/models',         src: '*.js',  dest: 'models' },
            { cwd: 'app/js/collections',    src: '*.js',  dest: 'collections' },
            { cwd: 'app/js/routers',        src: '*.js',  dest: 'routers' },
            { cwd: 'app/js/templates',      src: '*.hbs', dest: 'templates' },
            { cwd: 'app/js/views',          src: '*.js',  dest: 'views' }
          ]
        }
      },
      // See browserify:app above
      admin: {
        src: 'admin/js/admin.js',
        dest: 'tmp/admin.js',
        options: {
          aliasMappings: [
            { cwd: 'shared/js/lib',         src: '*.js',  dest: 'shared/lib' },
            { cwd: 'shared/js/lib',         src: '*.js',  dest: 'cloud/lib' },
            { cwd: 'shared/js/models',      src: '*.js',  dest: 'shared/models' },
            { cwd: 'shared/js/models',      src: '*.js',  dest: 'cloud/models' },
            { cwd: 'shared/js/collections', src: '*.js',  dest: 'shared/collections' },
            { cwd: 'shared/js/views',       src: '*.js',  dest: 'shared/views' },
            { cwd: 'shared/js/templates',   src: '*.hbs', dest: 'shared/templates' },
            { cwd: 'admin/js/lib',          src: '*.js',  dest: 'lib' },
            { cwd: 'admin/js/models',       src: '*.js',  dest: 'models' },
            { cwd: 'admin/js/collections',  src: '*.js',  dest: 'collections' },
            { cwd: 'admin/js/routers',      src: '*.js',  dest: 'routers' },
            { cwd: 'admin/js/templates',    src: '*.hbs', dest: 'templates' },
            { cwd: 'admin/js/views',        src: '*.js',  dest: 'views' }
          ]
        }
      }
    },

    // Minify css files
    cssmin: {
      app: {
        src: 'tmp/linksf.css',
        dest: 'tmp/linksf.css'
      },
      admin: {
        src: 'tmp/linksf_admin.css',
        dest: 'tmp/linksf_admin.css'
      },
    },

    // Concatenate files together.
    concat: {
      // Not a target, just a variable that we can interpolate in elsewhere.
      shared_js: [
        'vendor/js/jquery-2.0.3.js',
        'vendor/js/jquery.serialize-object.js',
        'vendor/js/underscore.js',
        'vendor/js/backbone-1.0.0.js',
        'vendor/js/parse-1.2.12.js'
      ],

      shared_js_minified: [
        'vendor/js/jquery-2.0.3.min.js',
        'vendor/js/jquery.serialize-object.min.js',
        'vendor/js/underscore.min.js',
        'vendor/js/backbone-1.0.0.min.js',
        'vendor/js/parse-1.2.12.min.js'
      ],

      // App also uses the vendored fastclick library
      app: {
        src: [
          '<%= concat.shared_js %>',
          'vendor/js/bootstrap-button.js',
          'vendor/js/fastclick.js',
          'tmp/app.js'
        ],
        dest: 'tmp/linksf.js'
      },

      // Concat minified files
      app_min: {
        src: [
          '<%= concat.shared_js_minified %>',
          'vendor/js/bootstrap-button.min.js',
          'vendor/js/fastclick.min.js',
          'tmp/app.min.js'
        ],
        dest: 'tmp/linksf.js'
      },

      // Admin uses backbone filters for authentication and autosize for text entry
      admin: {
        src: [
          '<%= concat.shared_js %>',
          'vendor/js/backbone_filters.js',
          'vendor/js/jquery.autosize.js',
          'vendor/js/bootstrap.js',
          'tmp/admin.js'
        ],
        dest: 'tmp/linksf_admin.js'
      },

      admin_min: {
        src: [
          '<%= concat.shared_js_minified %>',
          'vendor/js/backbone_filters.min.js',
          'vendor/js/jquery.autosize.min.js',
          'vendor/js/bootstrap.min.js',
          'tmp/admin.min.js'
        ],
        dest: 'tmp/linksf_admin.js'
      }
    },

    uglify: {
      options: {
        mangle: false,
        preserveComments: false,
        report: 'min'
      },

      vendor: {
        files: {
          // These libraries are not distributed with minified versions, so we
          // minify them ourselves.
          'vendor/js/jquery.serialize-object.min.js': 'vendor/js/jquery.serialize-object.js',
          'vendor/js/backbone_filters.min.js': 'vendor/js/backbone_filters.js',
          'vendor/js/bootstrap-button.min.js': 'vendor/js/bootstrap-button.js'
        }
      },
      app: {files: {'tmp/app.min.js': 'tmp/app.js'}},
      admin: {files: {'tmp/admin.min.js': 'tmp/admin.js'}}
    },

    clean: {
      build: {
        src: 'build/*',
        filter: function(filepath) { return filepath !== 'build/.gitkeep'; }
      }
    },

    cachebuster: {
      dist: {
        files: {
          src: [
            'tmp/linksf.js',
            'tmp/linksf.css',
            'tmp/linksf_admin.js',
            'tmp/linksf_admin.css'
          ],
        },
        options: {
          complete: function(hashes) {
            // ugly but the only way to tag each file with a key
            var keyMap = {
                'tmp/linksf.js': 'linksf_js',
                'tmp/linksf.css': 'linksf_css',
                'tmp/linksf_admin.js': 'linksf_admin_js',
                'tmp/linksf_admin.css': 'linksf_admin_css'
               },
               context = {},
               Handlebars = require('handlebars'),
               template,
               output;

            context.parseAppId = process.env.PARSE_APP_ID;
            context.parseJSKey = process.env.PARSE_JS_KEY;

            Object.keys(hashes).forEach(function(key) {
              var matches = key.match(/^tmp\/(.*)(\..*)$/),
                  filename = matches[1],
                  extension = matches[2],
                  outputFile = 'build/' + filename + '-' + hashes[key] + extension;

              grunt.file.copy(key, outputFile);
              context[keyMap[key]] = outputFile;
            });

            template = Handlebars.compile(grunt.file.read('app/index.html'));
            output = template(context);
            grunt.file.write('index.html', output);

            template = Handlebars.compile(grunt.file.read('admin/admin.html'));
            output = template(context);
            grunt.file.write('admin.html', output);
          }
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-sass');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-simple-mocha');
  grunt.loadNpmTasks('grunt-cachebuster');
  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks('grunt-contrib-clean');

  grunt.loadTasks('tasks');

  grunt.registerTask('build:development', [
    'clean',
    'jshint',
    'simplemocha',
    'sass',
    'browserify',
    'concat:app',
    'concat:admin',
    'configure:development',
    'cachebuster'
  ]);

  grunt.registerTask('build:production', [
    'clean',
    'jshint',
    'simplemocha',
    'sass',
    'cssmin',
    'browserify',
    'uglify',
    'concat:app_min',
    'concat:admin_min',
    'configure:production',
    'cachebuster'
  ]);

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


<commit_before>'use strict';

module.exports = function(grunt) {

	// configure grunt
	grunt.initConfig({

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

	});

	// Load plug-ins
	// grunt.loadNpmTasks('grunt-contrib-whatever');

	// define tasks
	grunt.registerTask('default', [
		// No tasks, yet
	]);

};
<commit_msg>Load the correct Npm tasks.<commit_after>'use strict';

module.exports = function(grunt) {

	//Configure Grunt
	grunt.initConfig({

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

	});

	//Load plug-ins
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-uglify');

	//Define tasks
	grunt.registerTask('default', [
		//No tasks, yet
	]);

};
<|endoftext|>


<commit_before>// Generated on 2013-06-27 using generator-angular 0.3.0
'use strict';
var LIVERELOAD_PORT = 35729;
var lrSnippet = require('connect-livereload')({ port: LIVERELOAD_PORT });
var mountFolder = function (connect, dir) {
  return connect.static(require('path').resolve(dir));
};

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

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

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

  try {
    yeomanConfig.app = require('./bower.json').appPath || yeomanConfig.app;
  } catch (e) {}

  grunt.initConfig({
    yeoman: yeomanConfig,
    watch: {
      coffee: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
        tasks: ['coffee:dist']
      },
      coffeeTest: {
        files: ['test/spec/{,*/}*.coffee'],
        tasks: ['coffee:test']
      },
      compass: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
        tasks: ['compass:server']
      },
      livereload: {
        options: {
          livereload: LIVERELOAD_PORT
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css',
          '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost'
      },
      livereload: {
        options: {
          middleware: function (connect) {
            return [
              lrSnippet,
              mountFolder(connect, '.tmp'),
              mountFolder(connect, yeomanConfig.app)
            ];
          }
        }
      },
      test: {
        options: {
          middleware: function (connect) {
            return [
              mountFolder(connect, '.tmp'),
              mountFolder(connect, 'test')
            ];
          }
        }
      },
      dist: {
        options: {
          middleware: function (connect) {
            return [
              mountFolder(connect, yeomanConfig.dist)
            ];
          }
        }
      }
    },
    open: {
      server: {
        url: 'http://localhost:<%= connect.options.port %>'
      }
    },
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%= yeoman.dist %>/*',
            '!<%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: '.tmp'
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        '<%= yeoman.app %>/scripts/{,*/}*.js'
      ]
    },
    coffee: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/scripts',
          src: '{,*/}*.coffee',
          dest: '.tmp/scripts',
          ext: '.js'
        }]
      },
      test: {
        files: [{
          expand: true,
          cwd: 'test/spec',
          src: '{,*/}*.coffee',
          dest: '.tmp/spec',
          ext: '.js'
        }]
      }
    },
    compass: {
      options: {
        sassDir: '<%= yeoman.app %>/styles',
        cssDir: '.tmp/styles',
        generatedImagesDir: '.tmp/images/generated',
        imagesDir: '<%= yeoman.app %>/images',
        javascriptsDir: '<%= yeoman.app %>/scripts',
        fontsDir: '<%= yeoman.app %>/styles/fonts',
        importPath: '<%= yeoman.app %>/bower_components',
        httpImagesPath: '/images',
        httpGeneratedImagesPath: '/images/generated',
        httpFontsPath: '/styles/fonts',
        relativeAssets: false
      },
      dist: {},
      server: {
        options: {
          debugInfo: true
        }
      }
    },
    // not used since Uglify task does concat,
    // but still available if needed
    /*concat: {
      dist: {}
    },*/
    rev: {
      dist: {
        files: {
          src: [
            '<%= yeoman.dist %>/scripts/{,*/}*.js',
            '<%= yeoman.dist %>/styles/{,*/}*.css',
            '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
            '<%= yeoman.dist %>/styles/fonts/*'
          ]
        }
      }
    },
    useminPrepare: {
      html: '<%= yeoman.app %>/index.html',
      options: {
        dest: '<%= yeoman.dist %>'
      }
    },
    usemin: {
      html: ['<%= yeoman.dist %>/{,*/}*.html'],
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
      options: {
        dirs: ['<%= yeoman.dist %>']
      }
    },
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '{,*/}*.{png,jpg,jpeg}',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },
    cssmin: {
      // By default, your `index.html` <!-- Usemin Block --> will take care of
      // minification. This option is pre-configured if you do not wish to use
      // Usemin blocks.
      // dist: {
      //   files: {
      //     '<%= yeoman.dist %>/styles/main.css': [
      //       '.tmp/styles/{,*/}*.css',
      //       '<%= yeoman.app %>/styles/{,*/}*.css'
      //     ]
      //   }
      // }
    },
    htmlmin: {
      dist: {
        options: {
          /*removeCommentsFromCDATA: true,
          // https://github.com/yeoman/grunt-usemin/issues/44
          //collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeAttributeQuotes: true,
          removeRedundantAttributes: true,
          useShortDoctype: true,
          removeEmptyAttributes: true,
          removeOptionalTags: true*/
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>',
          src: ['*.html', 'views/*.html'],
          dest: '<%= yeoman.dist %>'
        }]
      }
    },
    // Put files not handled in other tasks here
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,png,txt}',
            '.htaccess',
            'bower_components/**/*',
            'images/{,*/}*.{gif,webp,svg}',
            'styles/fonts/*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: [
            'generated/*'
          ]
        }]
      }
    },
    concurrent: {
      server: [
        'coffee:dist',
        'compass:server'
      ],
      test: [
        'coffee',
        'compass'
      ],
      dist: [
        'coffee',
        'compass:dist',
        'imagemin',
        'htmlmin'
      ]
    },
    karma: {
      unit: {
        configFile: 'karma.conf.js',
        singleRun: true
      }
    },
    cdnify: {
      dist: {
        html: ['<%= yeoman.dist %>/*.html']
      }
    },
    ngmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.dist %>/scripts',
          src: '*.js',
          dest: '<%= yeoman.dist %>/scripts'
        }]
      }
    },
    uglify: {
      dist: {
        files: {
          '<%= yeoman.dist %>/scripts/scripts.js': [
            '<%= yeoman.dist %>/scripts/scripts.js'
          ]
        }
      }
    }
  });

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

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

  grunt.registerTask('test', [
    'clean:server',
    'concurrent:test',
    'connect:test',
    'karma'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'useminPrepare',
    'concurrent:dist',
    'concat',
    'copy',
    'cdnify',
    'ngmin',
    'cssmin',
    'uglify',
    'rev',
    'usemin'
  ]);

  grunt.registerTask('default', [
    'jshint',
    'test',
    'build'
  ]);
};
<commit_msg>Configure `grunt server` to be available outside of localhost<commit_after>// Generated on 2013-06-27 using generator-angular 0.3.0
'use strict';
var LIVERELOAD_PORT = 35729;
var lrSnippet = require('connect-livereload')({ port: LIVERELOAD_PORT });
var mountFolder = function (connect, dir) {
  return connect.static(require('path').resolve(dir));
};

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

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

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

  try {
    yeomanConfig.app = require('./bower.json').appPath || yeomanConfig.app;
  } catch (e) {}

  grunt.initConfig({
    yeoman: yeomanConfig,
    watch: {
      coffee: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
        tasks: ['coffee:dist']
      },
      coffeeTest: {
        files: ['test/spec/{,*/}*.coffee'],
        tasks: ['coffee:test']
      },
      compass: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
        tasks: ['compass:server']
      },
      livereload: {
        options: {
          livereload: LIVERELOAD_PORT
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css',
          '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        // Change this to 'localhost' to deny access to the server from outside.
        hostname: '0.0.0.0'
      },
      livereload: {
        options: {
          middleware: function (connect) {
            return [
              lrSnippet,
              mountFolder(connect, '.tmp'),
              mountFolder(connect, yeomanConfig.app)
            ];
          }
        }
      },
      test: {
        options: {
          middleware: function (connect) {
            return [
              mountFolder(connect, '.tmp'),
              mountFolder(connect, 'test')
            ];
          }
        }
      },
      dist: {
        options: {
          middleware: function (connect) {
            return [
              mountFolder(connect, yeomanConfig.dist)
            ];
          }
        }
      }
    },
    open: {
      server: {
        url: 'http://localhost:<%= connect.options.port %>'
      }
    },
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%= yeoman.dist %>/*',
            '!<%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: '.tmp'
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        '<%= yeoman.app %>/scripts/{,*/}*.js'
      ]
    },
    coffee: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/scripts',
          src: '{,*/}*.coffee',
          dest: '.tmp/scripts',
          ext: '.js'
        }]
      },
      test: {
        files: [{
          expand: true,
          cwd: 'test/spec',
          src: '{,*/}*.coffee',
          dest: '.tmp/spec',
          ext: '.js'
        }]
      }
    },
    compass: {
      options: {
        sassDir: '<%= yeoman.app %>/styles',
        cssDir: '.tmp/styles',
        generatedImagesDir: '.tmp/images/generated',
        imagesDir: '<%= yeoman.app %>/images',
        javascriptsDir: '<%= yeoman.app %>/scripts',
        fontsDir: '<%= yeoman.app %>/styles/fonts',
        importPath: '<%= yeoman.app %>/bower_components',
        httpImagesPath: '/images',
        httpGeneratedImagesPath: '/images/generated',
        httpFontsPath: '/styles/fonts',
        relativeAssets: false
      },
      dist: {},
      server: {
        options: {
          debugInfo: true
        }
      }
    },
    // not used since Uglify task does concat,
    // but still available if needed
    /*concat: {
      dist: {}
    },*/
    rev: {
      dist: {
        files: {
          src: [
            '<%= yeoman.dist %>/scripts/{,*/}*.js',
            '<%= yeoman.dist %>/styles/{,*/}*.css',
            '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
            '<%= yeoman.dist %>/styles/fonts/*'
          ]
        }
      }
    },
    useminPrepare: {
      html: '<%= yeoman.app %>/index.html',
      options: {
        dest: '<%= yeoman.dist %>'
      }
    },
    usemin: {
      html: ['<%= yeoman.dist %>/{,*/}*.html'],
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
      options: {
        dirs: ['<%= yeoman.dist %>']
      }
    },
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '{,*/}*.{png,jpg,jpeg}',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },
    cssmin: {
      // By default, your `index.html` <!-- Usemin Block --> will take care of
      // minification. This option is pre-configured if you do not wish to use
      // Usemin blocks.
      // dist: {
      //   files: {
      //     '<%= yeoman.dist %>/styles/main.css': [
      //       '.tmp/styles/{,*/}*.css',
      //       '<%= yeoman.app %>/styles/{,*/}*.css'
      //     ]
      //   }
      // }
    },
    htmlmin: {
      dist: {
        options: {
          /*removeCommentsFromCDATA: true,
          // https://github.com/yeoman/grunt-usemin/issues/44
          //collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeAttributeQuotes: true,
          removeRedundantAttributes: true,
          useShortDoctype: true,
          removeEmptyAttributes: true,
          removeOptionalTags: true*/
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>',
          src: ['*.html', 'views/*.html'],
          dest: '<%= yeoman.dist %>'
        }]
      }
    },
    // Put files not handled in other tasks here
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,png,txt}',
            '.htaccess',
            'bower_components/**/*',
            'images/{,*/}*.{gif,webp,svg}',
            'styles/fonts/*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: [
            'generated/*'
          ]
        }]
      }
    },
    concurrent: {
      server: [
        'coffee:dist',
        'compass:server'
      ],
      test: [
        'coffee',
        'compass'
      ],
      dist: [
        'coffee',
        'compass:dist',
        'imagemin',
        'htmlmin'
      ]
    },
    karma: {
      unit: {
        configFile: 'karma.conf.js',
        singleRun: true
      }
    },
    cdnify: {
      dist: {
        html: ['<%= yeoman.dist %>/*.html']
      }
    },
    ngmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.dist %>/scripts',
          src: '*.js',
          dest: '<%= yeoman.dist %>/scripts'
        }]
      }
    },
    uglify: {
      dist: {
        files: {
          '<%= yeoman.dist %>/scripts/scripts.js': [
            '<%= yeoman.dist %>/scripts/scripts.js'
          ]
        }
      }
    }
  });

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

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

  grunt.registerTask('test', [
    'clean:server',
    'concurrent:test',
    'connect:test',
    'karma'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'useminPrepare',
    'concurrent:dist',
    'concat',
    'copy',
    'cdnify',
    'ngmin',
    'cssmin',
    'uglify',
    'rev',
    'usemin'
  ]);

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


<commit_before>var request = require('request');

var safari_browsers = [
	{
		browserName: 'safari',
		platform: 'OS X 10.10',
		version: '8.0'
	}
];

var chrome_browsers = [
	{
		browserName: 'chrome',
		platform: 'OS X 10.10',
		version: '44.0'
	},
	{
		browserName: 'chrome',
		platform: 'Windows 10',
		version: '43.0'
	},
	{
		browserName: 'chrome',
		platform: 'Linux',
		version: '42.0'
	}
];

var firefox_browsers = [
	{
		browserName: 'firefox',
		platform: 'Windows 10',
		version: '40.0'
	},
	{
		browserName: 'firefox',
		platform: 'OS X 10.10',
		version: '39.0'
	},
	{
		browserName: 'firefox',
		platform: 'Linux',
		version: '38.0'
	}
];

var ios_browsers = [
	{
		browserName: 'iphone',
		deviceName: 'iPhone 6',
		deviceOrientation: 'portrait',
		platform: 'OS X 10.10',
		version: '9.0'
	},
	{
		browserName: 'iphone',
		deviceName: 'iPhone 6',
		deviceOrientation: 'portrait',
		platform: 'OS X 10.10',
		version: '9.1'
	},
	{
		browserName: 'iphone',
		deviceName: 'iPhone 6',
		deviceOrientation: 'portrait',
		platform: 'OS X 10.10',
		version: '9.2'
	}
];

var android_browsers = [
	{
		browserName: 'android',
		deviceName: 'Android Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '5.1'
	},
	{
		browserName: 'android',
		deviceName: 'Google Nexus 7 HD Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '4.4'
	},
	{
		browserName: 'android',
		deviceName: 'Google Nexus 7C Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '4.3'
	},
	{
		browserName: 'android',
		deviceName: 'LG Nexus 4 Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '4.2'
	},
	{
		browserName: 'android',
		deviceName: 'HTC One X Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '4.1'
	},
	{
		browserName: 'android',
		deviceName: 'HTC Evo 3D Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '4.0'
	}
];

var ie_browsers = [
	{
		browserName: 'internet explorer',
		platform: 'Windows 10',
		version: '11.0'
	},
	{
		browserName: 'internet explorer',
		platform: 'Windows 8.1',
		version: '11.0'
	},
	{
		browserName: 'internet explorer',
		platform: 'Windows 7',
		version: '10.0'
	}
];

var test_urls = [
	'http://0.0.0.0:9999/test/test.html',
	'http://0.0.0.0:9999/test/integration-test.html'
];

module.exports = function(grunt) {
	grunt.initConfig({
		'saucelabs-mocha': {
			all: {
				options: {
					username: 'branchmetrics',
					urls: test_urls,
					maxRetries: 3,
					testname: 'Web SDK Tests',
					browsers: [].concat(
						safari_browsers,
						chrome_browsers,
						// firefox_browsers,
						android_browsers,
						ios_browsers,
						ie_browsers)
				}
			},
			options: {
				force: true
			}
		},
		connect: {
			server: {
				options: {
					port: 9999,
					base: ''
				}
			}
		}
	});

	// Loading dependencies
	for (var key in grunt.file.readJSON("package.json").devDependencies) {
		if (key !== "grunt" && key.indexOf("grunt") === 0) {
			grunt.loadNpmTasks(key);
		}
	}

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

	grunt.registerTask('test', ['connect', 'saucelabs-mocha']);
};
<commit_msg>Increase pollInterval<commit_after>var request = require('request');

var safari_browsers = [
	{
		browserName: 'safari',
		platform: 'OS X 10.10',
		version: '8.0'
	}
];

var chrome_browsers = [
	{
		browserName: 'chrome',
		platform: 'OS X 10.10',
		version: '44.0'
	},
	{
		browserName: 'chrome',
		platform: 'Windows 10',
		version: '43.0'
	},
	{
		browserName: 'chrome',
		platform: 'Linux',
		version: '42.0'
	}
];

var firefox_browsers = [
	{
		browserName: 'firefox',
		platform: 'Windows 10',
		version: '40.0'
	},
	{
		browserName: 'firefox',
		platform: 'OS X 10.10',
		version: '39.0'
	},
	{
		browserName: 'firefox',
		platform: 'Linux',
		version: '38.0'
	}
];

var ios_browsers = [
	{
		browserName: 'iphone',
		deviceName: 'iPhone 6',
		deviceOrientation: 'portrait',
		platform: 'OS X 10.10',
		version: '9.0'
	},
	{
		browserName: 'iphone',
		deviceName: 'iPhone 6',
		deviceOrientation: 'portrait',
		platform: 'OS X 10.10',
		version: '9.1'
	},
	{
		browserName: 'iphone',
		deviceName: 'iPhone 6',
		deviceOrientation: 'portrait',
		platform: 'OS X 10.10',
		version: '9.2'
	}
];

var android_browsers = [
	{
		browserName: 'android',
		deviceName: 'Android Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '5.1'
	},
	{
		browserName: 'android',
		deviceName: 'Google Nexus 7 HD Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '4.4'
	},
	{
		browserName: 'android',
		deviceName: 'Google Nexus 7C Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '4.3'
	},
	{
		browserName: 'android',
		deviceName: 'LG Nexus 4 Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '4.2'
	},
	{
		browserName: 'android',
		deviceName: 'HTC One X Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '4.1'
	},
	{
		browserName: 'android',
		deviceName: 'HTC Evo 3D Emulator',
		deviceOrientation: 'portrait',
		platform: 'Linux',
		version: '4.0'
	}
];

var ie_browsers = [
	{
		browserName: 'internet explorer',
		platform: 'Windows 10',
		version: '11.0'
	},
	{
		browserName: 'internet explorer',
		platform: 'Windows 8.1',
		version: '11.0'
	},
	{
		browserName: 'internet explorer',
		platform: 'Windows 7',
		version: '10.0'
	}
];

var test_urls = [
	'http://0.0.0.0:9999/test/test.html',
	'http://0.0.0.0:9999/test/integration-test.html'
];

module.exports = function(grunt) {
	grunt.initConfig({
		'saucelabs-mocha': {
			all: {
				options: {
					username: 'branchmetrics',
					urls: test_urls,
					maxRetries: 3,
					testname: 'Web SDK Tests',
					pollInterval: 10000,
					browsers: [].concat(
						safari_browsers,
						chrome_browsers,
						// firefox_browsers,
						android_browsers,
						ios_browsers,
						ie_browsers)
				}
			},
			options: {
				force: true
			}
		},
		connect: {
			server: {
				options: {
					port: 9999,
					base: ''
				}
			}
		}
	});

	// Loading dependencies
	for (var key in grunt.file.readJSON("package.json").devDependencies) {
		if (key !== "grunt" && key.indexOf("grunt") === 0) {
			grunt.loadNpmTasks(key);
		}
	}

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

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


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

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-mocha');

  var PORT = 8899;

  var auraRequireBaseConfig = {
    options: {
      baseUrl: '.',
      paths: {
        aura: 'lib',
        jquery: 'empty:',
        underscore: 'empty:',
        eventemitter: 'components/eventemitter2/lib/eventemitter2'
      },
      shim: {
        underscore: {
          exports: '_'
        }
      },
      include: [
        'aura/aura',
        'aura/aura.extensions',
        'aura/ext/debug',
        'aura/ext/mediator',
        'aura/ext/widgets'
      ],
      exclude: ['jquery']
    }
  };

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    connect: {
      server: {
        options: {
          port: PORT,
          base: '.'
        }
      }
    },
    requirejs: {
      dev: grunt.util._.merge({}, auraRequireBaseConfig, {
        options: {
          optimize: 'none',
          out: 'dist/aura.js'
        }
      }),
      build: grunt.util._.merge({}, auraRequireBaseConfig, {
        options: {
          optimize: 'none',
          out: 'dist/aura-<%= pkg.version %>.js'
        }
      }),
      buildMin: grunt.util._.merge({}, auraRequireBaseConfig, {
        options: {
          out: 'dist/aura-<%= pkg.version %>.min.js'
        }
      })
    },
    jshint: {
      all: {
        options: {
          jshintrc: '.jshintrc'
        },
        files: {
          src: [
            'lib/**/*.js',
            'spec/lib/**/*.js'
          ]
        }
      }
    },
    mocha: {
      all: {
          options: {
              urls: ['http://localhost:<%= connect.server.options.port %>/spec/index.html']
          }
      }
    },
    watch: {
      files: [
        'lib/**/*.js',
        'spec/lib/**/*.js'
      ],
      tasks: ['spec']
    }
  });

  grunt.registerTask('spec', ['jshint', 'mocha']);
  grunt.registerTask('build', ['connect', 'spec', 'requirejs:dev']);
  grunt.registerTask('version', ['connect', 'spec', 'requirejs:build', 'requirejs:buildMin']);
  grunt.registerTask('default', ['connect', 'spec', 'watch']);
};
<commit_msg>Removes version number from build files<commit_after>module.exports = function (grunt) {
  'use strict';

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-mocha');

  var PORT = 8899;

  var auraRequireBaseConfig = {
    options: {
      baseUrl: '.',
      paths: {
        aura: 'lib',
        jquery: 'empty:',
        underscore: 'empty:',
        eventemitter: 'components/eventemitter2/lib/eventemitter2'
      },
      shim: {
        underscore: {
          exports: '_'
        }
      },
      include: [
        'aura/aura',
        'aura/aura.extensions',
        'aura/ext/debug',
        'aura/ext/mediator',
        'aura/ext/widgets'
      ],
      exclude: ['jquery']
    }
  };

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    connect: {
      server: {
        options: {
          port: PORT,
          base: '.'
        }
      }
    },
    requirejs: {
      dev: grunt.util._.merge({}, auraRequireBaseConfig, {
        options: {
          optimize: 'none',
          out: 'dist/aura.js'
        }
      }),
      build: grunt.util._.merge({}, auraRequireBaseConfig, {
        options: {
          optimize: 'none',
          out: 'dist/aura.js'
        }
      }),
      buildMin: grunt.util._.merge({}, auraRequireBaseConfig, {
        options: {
          out: 'dist/aura.min.js'
        }
      })
    },
    jshint: {
      all: {
        options: {
          jshintrc: '.jshintrc'
        },
        files: {
          src: [
            'lib/**/*.js',
            'spec/lib/**/*.js'
          ]
        }
      }
    },
    mocha: {
      all: {
          options: {
              urls: ['http://localhost:<%= connect.server.options.port %>/spec/index.html']
          }
      }
    },
    watch: {
      files: [
        'lib/**/*.js',
        'spec/lib/**/*.js'
      ],
      tasks: ['spec']
    }
  });

  grunt.registerTask('spec', ['jshint', 'mocha']);
  grunt.registerTask('build', ['connect', 'spec', 'requirejs:dev']);
  grunt.registerTask('version', ['connect', 'spec', 'requirejs:build', 'requirejs:buildMin']);
  grunt.registerTask('default', ['connect', 'spec', 'watch']);
};
<|endoftext|>