<commit_before>// var eyes = require('eyes');
var path = require('path');
var util = require('./lib/grunt/utils.js');

/*global module:false*/
module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    version: util.getVersion(),
    stable_version: util.getStableVersion(),
    dist: 'dist',
    site: process.env.TRAVIS ? 'ui-grid.info' : '127.0.0.1:<%= connect.docs.options.port %>',
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= version %> - ' +
      '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Licensed <%= pkg.license %> */\n',

    shell: {
      options: {
        stdout: true
      },
      selenium: {
        command: './selenium/start',
        options: {
          stdout: false,
          async: true
        }
      },
      'protractor-install': {
        command: './node_modules/protractor/bin/webdriver-manager update'
      },
      'protractor-start': {
        command: 'node ./node_modules/protractor/bin/webdriver-manager start',
        options: {
          stdout: true,
          async: true
        }
      }
    },

    // Clean the temp directory
    clean: ['.tmp', '<%= dist %>', 'docs'],

    // Templates
    ngtemplates: {
      'ui-grid': {
        cwd: 'src/templates',
        src: ['**/*.html'],
        dest: '.tmp/template.js',
        options: {
          module: 'ui.grid',
          htmlmin:  { collapseWhitespace: true, collapseBooleanAttributes: true },
          // Strip .html extension
          url: function(url) { return url.replace('.html', ''); }
        }
      }
    },

    // ngtemplates: {
    //   'ui-grid': {
    //     cwd: 'src/templates',
    //     src: '_partials/**/*.html',
    //     dest: '.tmp/template.js',
    //     options: {
    //       htmlmin:  { collapseWhitespace: true, collapseBooleanAttributes: true }
    //     }
    //   }
    // },

    // Task configuration.
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['src/js/**/*.js', '.tmp/template.js'],
        dest: '<%= dist %>/release/<%= pkg.name %>.js'
      }
    },

    less: {
      dist: {
        // paths: ['/bower_components/bootstrap'],
        files: {
          'dist/release/<%= pkg.name %>.css': 'src/less/main.less',
        }
      },
      min: {
        files: {
          'dist/release/<%= pkg.name %>.min.css': 'src/less/main.less',
        },
        options: {
          compress: true
        }
      }
    },

    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      concat: {
        src: '<%= concat.dist.dest %>',
        dest: '<%= dist %>/release/<%= pkg.name %>.min.js'
      }
    },

    karma: {
      options: {
        configFile: 'test/karma.conf.js',
        files: util.angularFiles(util.latestAngular()).concat(util.testFiles.unit),
        background: true
      },
      // dev: {
      //   singleRun: false,
      //   background: true
      // },
      single: {
        background: false,
        singleRun: true,
        reporters: ['progress'],
      },

      travis: {
        background: false,
        singleRun: true,
        reporters: ['dots'],
      }
    },

    protractor: {
      options: {
        keepAlive: true,
        configFile: "./test/protractor.conf.js"
      },
      singlerun: {
        options: {
          keepAlive: false,
          args: {
            seleniumPort: 4444,
            baseUrl: 'http://127.0.0.1:9999',
            specs: ['.tmp/doc-scenarios/**/*.spec.js', 'test/e2e/**/*.spec.js']
          }
        }
      },
      ci: {
        options: {
          keepAlive: false,
          args: {
            // seleniumAddress: 'http://localhost:4445',
            // seleniumPort: 4445,
            baseUrl: 'http://127.0.0.1:9999',
            specs: ['.tmp/doc-scenarios/**/*.spec.js', 'test/e2e/**/*.spec.js'],
            sauceUser: process.env.SAUCE_USERNAME,
            sauceKey: process.env.SAUCE_ACCESS_KEY
          }
        }
      },
      auto: {
        options: {
          keepAlive: true,
          args: {
            seleniumPort: 4444,
            baseUrl: 'http://127.0.0.1:9999',
            specs: ['.tmp/doc-scenarios/**/*.spec.js', 'test/e2e/**/*.spec.js']
          }
        }
      }
      // docs: {
      //   options: {
      //     args: {
      //       seleniumPort: 4444,

      //     }
      //   }
      // }
    },

    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: false,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        unused: false,
        boss: true,
        eqnull: true,
        browser: true,
        globals: {
          angular: false,
          console: false,

          /* grunt */
          process: false,
          require: false,

          /* Jasmine */
          after: false,
          afterEach: false,
          before: false,
          beforeEach: false,
          dump: false,
          describe: false,
          ddescribe: false,
          expect: false,
          inject: false,
          it: false,
          iit: false,
          module: false
        }
      },
      gruntfile: {
        src: 'Gruntfile.js'
      },
      src_test: {
        src: ['src/**/*.js', 'test/**/*.spec.js']
      }
    },

    watch: {
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },

      ngtemplates: {
        files: 'src/templates/**/*.html',
        tasks: ['ngtemplates']
      },

      // src_test: {
      //   files: '<%= jshint.src_test.src %>',
      //   tasks: ['jshint:src_test', 'jasmine']
      // },
      rebuild: {
        files: util.testFiles.unit,
        tasks: ['jshint:src_test', 'karmangular:run', 'concat', 'uglify', 'ngdocs'],
        options: {
          // livereload: true
        }
      },
      protractor: {
        files: ['.tmp/doc-scenarios/**/*.spec.js', 'test/e2e/**/*.spec.js'],
        tasks: ['protractor:auto']
      },

      less: {
        files: 'src/**/*.less',
        tasks: ['less']
      },

      docs: {
        files: ['misc/tutorial/**/*.ngdoc', 'misc/doc/**'],
        tasks: 'ngdocs'
      },

      copy: {
        files: ['misc/site/**'],
        tasks: 'copy'
      },

      // karma: {
      //   files: ['src/**/*.js', 'test/unit/**/*.spec.js'],
      //   tasks: ['karma:dev:run'] //NOTE the :run flag
      // },

      livereload: {
        options: { livereload: true },
        files: ['dist/**/*', 'misc/demo/**/*.html', 'docs/**/*'],
      }
    },

    'gh-pages': {
      'gh-pages': {
        options: {
          base: '<%= dist %>',
          repo: 'https://github.com/angular-ui/ui-grid.info.git',
          message: 'gh-pages v<%= version %>',
          add: true
        },
        src: ['**/*']
      }
    },

    connect: {
      dev: {
        options: {
          port: process.env.DEV_PORT || 9002,
          base: '.',
          livereload: true
        }
      },
      docs: {
        options: {
          port: process.env.DOCS_PORT || 9003,
          base: '<%= dist %>',
          livereload: true
        }
      },
      testserver: {
        options: {
          port: process.env.TEST_PORT || 9999,
          base: '<%= dist %>'
        }
      }
    },

    ngdocs: {
      options: {
        dest: '<%= dist %>/docs',
        testingUrlPrefix: '<%= protractor.auto.options.args.baseUrl %>/docs/#/',
        scripts: [
          '//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js',
          'http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular-animate.js',
          'bower_components/google-code-prettify/src/prettify.js',
          'node_modules/marked/lib/marked.js'
        ],
        httpScripts: [
          '/release/<%= pkg.name %>.js'
        ],
        styles: [
          'misc/doc/css/prettify.css',
          'misc/doc/css/bootstrap-flatly.css',
          '<%= dist %>/release/ui-grid.css'
        ],
        title: 'UI Grid',
        titleLink: 'http://<%= site %>',
        html5Mode: false,
        analytics: {
          account: 'UA-46391685-1',
          domainName: 'ui-grid.info'
        },
        navTemplate: 'misc/doc/templates/nav.html'
      },
      api: {
        src: ['src/**/*.js'],
        title: 'API'
      },
      tutorial: {
        src: ['misc/tutorial/**/*.ngdoc'],
        title: 'Tutorial'
      }
    },

    copy: {
      site: {
        options: {
          processContent: grunt.template.process
        },
        files: [
          {
            expand: true,
            cwd: 'misc/site/',
            src: '**',
            dest: '<%= dist %>'
          }
        ]
      }
    },

    changelog: {
      options: {
        dest: 'CHANGELOG.md',
        github: 'angular-ui/ng-grid'
      }
    },

    'cut-release': {
      options: {
        cleanup: true,
        keepUnstable: false
      },
      dist: {
        src: '<%= dist %>/release/*.{js,css}',
        dest: '<%= dist %>/release/'
      }
    }
  });
  util.updateConfig();

  grunt.loadTasks('lib/grunt');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-angular-templates');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-protractor-runner');
  grunt.loadNpmTasks('grunt-ngdocs');
  grunt.loadNpmTasks('grunt-conventional-changelog');
  grunt.loadNpmTasks('grunt-gh-pages');
  grunt.loadNpmTasks('grunt-shell-spawn');

  grunt.registerTask('install', ['shell:protractor-install']);

  // register before and after test tasks so we don't have to change cli
  // options on the CI server
  grunt.registerTask('before-test', ['clean', 'jshint', 'ngtemplates']);
  grunt.registerTask('after-test', ['build']);

  // Default task.
  // grunt.registerTask('default', ['clean', 'jshint', 'ngtemplates', 'karma:single', 'concat', 'uglify', 'less', 'ngdocs']);
  grunt.registerTask('default', ['before-test', 'test', 'after-test']);

  // Build with no testing
  grunt.registerTask('build', ['concat', 'uglify', 'less', 'ngdocs', 'copy']);

  // Auto-test tasks for development
  grunt.registerTask('autotest:unit', ['karmangular:start']);
  grunt.registerTask('autotest:e2e', ['shell:protractor-start']);

  // Development watch task
  grunt.registerTask('dev', ['before-test', 'after-test', 'connect', 'autotest:unit', 'autotest:e2e', 'watch']);

  // Testing tasks
  // grunt.registerTask('test:ci', ['clean', 'jshint', 'ngtemplates', 'karma:sauce']);
  grunt.registerTask('test:ci', ['clean', 'jshint', 'ngtemplates', 'serialsauce']);
  grunt.registerTask('test:docs', ['connect:testserver', 'protractor:docs']);
  grunt.registerTask('test:e2e', ['connect:testserver', 'protractor:singlerun']);
  grunt.registerTask('test:e2e:ci', ['clean', 'build', 'connect:testserver', 'protractor:ci']);

  // Test
  grunt.registerTask('test', 'Run tests on singleRun karma server', function() {
    // This task can be executed in 2 different environments: local, and Travis-CI
    if (process.env.TRAVIS) {
      grunt.task.run('karma:travis');
    }
    else {
      // grunt.task.run(this.args.length ? 'karma:single' : 'karma:continuous');
      grunt.task.run('karmangular');
    }
  });

  grunt.registerTask('release', ['clean', 'build', 'cut-release', 'gh-pages']);
};
<commit_msg>chore(grunt): Update protractor settings<commit_after>// var eyes = require('eyes');
var path = require('path');
var util = require('./lib/grunt/utils.js');

/*global module:false*/
module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    version: util.getVersion(),
    stable_version: util.getStableVersion(),
    dist: 'dist',
    site: process.env.TRAVIS ? 'ui-grid.info' : '127.0.0.1:<%= connect.docs.options.port %>',
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= version %> - ' +
      '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Licensed <%= pkg.license %> */\n',

    shell: {
      options: {
        stdout: true
      },
      selenium: {
        command: './selenium/start',
        options: {
          stdout: false,
          async: true
        }
      },
      'protractor-install': {
        command: 'node ./node_modules/protractor/bin/webdriver-manager update'
      },
      'protractor-start': {
        command: 'node ./node_modules/protractor/bin/webdriver-manager start',
        options: {
          stdout: true,
          async: true
        }
      },
      'npm-install': {
        command: 'npm install'
      },
      'bower-install': {
        command: 'bower install'
      }
    },

    // Clean the temp directory
    clean: ['.tmp', '<%= dist %>', 'docs'],

    // Templates
    ngtemplates: {
      'ui-grid': {
        cwd: 'src/templates',
        src: ['**/*.html'],
        dest: '.tmp/template.js',
        options: {
          module: 'ui.grid',
          htmlmin:  { collapseWhitespace: true, collapseBooleanAttributes: true },
          // Strip .html extension
          url: function(url) { return url.replace('.html', ''); }
        }
      }
    },

    // ngtemplates: {
    //   'ui-grid': {
    //     cwd: 'src/templates',
    //     src: '_partials/**/*.html',
    //     dest: '.tmp/template.js',
    //     options: {
    //       htmlmin:  { collapseWhitespace: true, collapseBooleanAttributes: true }
    //     }
    //   }
    // },

    // Task configuration.
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['src/js/**/*.js', '.tmp/template.js'],
        dest: '<%= dist %>/release/<%= pkg.name %>.js'
      }
    },

    less: {
      dist: {
        // paths: ['/bower_components/bootstrap'],
        files: {
          'dist/release/<%= pkg.name %>.css': 'src/less/main.less',
        }
      },
      min: {
        files: {
          'dist/release/<%= pkg.name %>.min.css': 'src/less/main.less',
        },
        options: {
          compress: true
        }
      }
    },

    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      concat: {
        src: '<%= concat.dist.dest %>',
        dest: '<%= dist %>/release/<%= pkg.name %>.min.js'
      }
    },

    karma: {
      options: {
        configFile: 'test/karma.conf.js',
        files: util.angularFiles(util.latestAngular()).concat(util.testFiles.unit),
        background: true
      },
      // dev: {
      //   singleRun: false,
      //   background: true
      // },
      single: {
        background: false,
        singleRun: true,
        reporters: ['progress'],
      },

      travis: {
        background: false,
        singleRun: true,
        reporters: ['dots'],
      }
    },

    protractor: {
      options: {
        keepAlive: true,
        configFile: "./test/protractor.conf.js"
      },
      singlerun: {
        options: {
          keepAlive: false,
          args: {
            seleniumPort: 4444,
            baseUrl: 'http://127.0.0.1:9999',
            specs: ['.tmp/doc-scenarios/**/*.spec.js', 'test/e2e/**/*.spec.js']
          }
        }
      },
      ci: {
        options: {
          keepAlive: false,
          args: {
            // seleniumAddress: 'http://localhost:4445',
            // seleniumPort: 4445,
            baseUrl: 'http://127.0.0.1:9999',
            specs: ['.tmp/doc-scenarios/**/*.spec.js', 'test/e2e/**/*.spec.js'],
            sauceUser: process.env.SAUCE_USERNAME,
            sauceKey: process.env.SAUCE_ACCESS_KEY
          }
        }
      },
      auto: {
        options: {
          keepAlive: true,
          args: {
            seleniumPort: 4444,
            baseUrl: 'http://127.0.0.1:9999',
            specs: ['.tmp/doc-scenarios/**/*.spec.js', 'test/e2e/**/*.spec.js']
          }
        }
      }
      // docs: {
      //   options: {
      //     args: {
      //       seleniumPort: 4444,

      //     }
      //   }
      // }
    },

    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: false,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        unused: false,
        boss: true,
        eqnull: true,
        browser: true,
        globals: {
          angular: false,
          console: false,

          /* grunt */
          process: false,
          require: false,

          /* Jasmine */
          after: false,
          afterEach: false,
          before: false,
          beforeEach: false,
          dump: false,
          describe: false,
          ddescribe: false,
          expect: false,
          inject: false,
          it: false,
          iit: false,
          module: false
        }
      },
      gruntfile: {
        src: 'Gruntfile.js'
      },
      src_test: {
        src: ['src/**/*.js', 'test/**/*.spec.js']
      }
    },

    watch: {
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },

      ngtemplates: {
        files: 'src/templates/**/*.html',
        tasks: ['ngtemplates']
      },

      // src_test: {
      //   files: '<%= jshint.src_test.src %>',
      //   tasks: ['jshint:src_test', 'jasmine']
      // },
      rebuild: {
        files: util.testFiles.unit,
        tasks: ['jshint:src_test', 'karmangular:run', 'concat', 'uglify', 'ngdocs'],
        options: {
          // livereload: true
        }
      },
      protractor: {
        files: ['.tmp/doc-scenarios/**/*.spec.js', 'test/e2e/**/*.spec.js'],
        tasks: ['protractor-watch:auto']
      },

      less: {
        files: 'src/**/*.less',
        tasks: ['less']
      },

      docs: {
        files: ['misc/tutorial/**/*.ngdoc', 'misc/doc/**'],
        tasks: 'ngdocs'
      },

      copy: {
        files: ['misc/site/**'],
        tasks: 'copy'
      },

      // karma: {
      //   files: ['src/**/*.js', 'test/unit/**/*.spec.js'],
      //   tasks: ['karma:dev:run'] //NOTE the :run flag
      // },

      livereload: {
        options: { livereload: true },
        files: ['dist/**/*', 'misc/demo/**/*.html', 'docs/**/*'],
      }
    },

    'gh-pages': {
      'gh-pages': {
        options: {
          base: '<%= dist %>',
          repo: 'https://github.com/angular-ui/ui-grid.info.git',
          message: 'gh-pages v<%= version %>',
          add: true
        },
        src: ['**/*']
      }
    },

    connect: {
      dev: {
        options: {
          port: process.env.DEV_PORT || 9002,
          base: '.',
          livereload: true
        }
      },
      docs: {
        options: {
          port: process.env.DOCS_PORT || 9003,
          base: '<%= dist %>',
          livereload: true
        }
      },
      testserver: {
        options: {
          port: process.env.TEST_PORT || 9999,
          base: '<%= dist %>'
        }
      }
    },

    ngdocs: {
      options: {
        dest: '<%= dist %>/docs',
        testingUrlPrefix: '<%= protractor.auto.options.args.baseUrl %>/docs/#/',
        scripts: [
          '//ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular.js',
        ],
        hiddenScripts: [
          'http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular-animate.js',
          'bower_components/google-code-prettify/src/prettify.js',
          'node_modules/marked/lib/marked.js'
        ],
        httpScripts: [
          '/release/<%= pkg.name %>.js'
        ],
        styles: [
          'misc/doc/css/prettify.css',
          'misc/doc/css/bootstrap-flatly.css',
          '<%= dist %>/release/ui-grid.css'
        ],
        title: 'UI Grid',
        titleLink: 'http://<%= site %>',
        html5Mode: false,
        analytics: {
          account: 'UA-46391685-1',
          domainName: 'ui-grid.info'
        },
        navTemplate: 'misc/doc/templates/nav.html'
      },
      api: {
        src: ['src/**/*.js'],
        title: 'API'
      },
      tutorial: {
        src: ['misc/tutorial/**/*.ngdoc'],
        title: 'Tutorial'
      }
    },

    copy: {
      site: {
        options: {
          processContent: grunt.template.process
        },
        files: [
          {
            expand: true,
            cwd: 'misc/site/',
            src: '**',
            dest: '<%= dist %>'
          }
        ]
      }
    },

    changelog: {
      options: {
        dest: 'CHANGELOG.md',
        github: 'angular-ui/ng-grid'
      }
    },

    'cut-release': {
      options: {
        cleanup: true,
        keepUnstable: false
      },
      dist: {
        src: '<%= dist %>/release/*.{js,css}',
        dest: '<%= dist %>/release/'
      }
    }
  });
  util.updateConfig();

  grunt.loadTasks('lib/grunt');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-angular-templates');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-protractor-runner');
  grunt.loadNpmTasks('grunt-ngdocs');
  grunt.loadNpmTasks('grunt-conventional-changelog');
  grunt.loadNpmTasks('grunt-gh-pages');
  grunt.loadNpmTasks('grunt-shell-spawn');

  // grunt.renameTask('protractor', 'protractor-old');
  grunt.registerTask('protractor-watch', function () {
    var e2e = grunt.option('e2e');

    if (e2e !== false) {
      var args = '';
      if (this.args) {
        args = ':' + this.args.join(':');
      }

      grunt.task.run('protractor' + args);
    }
    else {
      grunt.log.writeln("Skipping e2e testing...");
    }
  });

  grunt.registerTask('install', ['shell:npm-install', 'shell:bower-install', 'shell:protractor-install']);

  // register before and after test tasks so we don't have to change cli
  // options on the CI server
  grunt.registerTask('before-test', ['clean', 'jshint', 'ngtemplates']);
  grunt.registerTask('after-test', ['build']);

  // Default task.
  // grunt.registerTask('default', ['clean', 'jshint', 'ngtemplates', 'karma:single', 'concat', 'uglify', 'less', 'ngdocs']);
  grunt.registerTask('default', ['before-test', 'test', 'after-test']);

  // Build with no testing
  grunt.registerTask('build', ['concat', 'uglify', 'less', 'ngdocs', 'copy']);

  // Auto-test tasks for development
  grunt.registerTask('autotest:unit', ['karmangular:start']);
  grunt.registerTask('autotest:e2e', ['shell:protractor-start']);

  // Development watch task
  grunt.registerTask('dev', function() {
    var e2e = grunt.option('e2e');

    var tasks = ['before-test', 'after-test', 'connect', 'autotest:unit', 'autotest:e2e', 'watch'];
    if (e2e === false) {
      tasks = ['before-test', 'after-test', 'connect', 'autotest:unit', 'watch'];
    }

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

  // Testing tasks
  // grunt.registerTask('test:ci', ['clean', 'jshint', 'ngtemplates', 'karma:sauce']);
  grunt.registerTask('test:ci', ['clean', 'jshint', 'ngtemplates', 'serialsauce']);
  grunt.registerTask('test:docs', ['connect:testserver', 'protractor:docs']);
  grunt.registerTask('test:e2e', ['connect:testserver', 'protractor:singlerun']);
  grunt.registerTask('test:e2e:ci', ['clean', 'build', 'connect:testserver', 'protractor:ci']);

  // Test
  grunt.registerTask('test', 'Run tests on singleRun karma server', function() {
    // This task can be executed in 2 different environments: local, and Travis-CI
    if (process.env.TRAVIS) {
      grunt.task.run('karma:travis');
    }
    else {
      // grunt.task.run(this.args.length ? 'karma:single' : 'karma:continuous');
      grunt.task.run('karmangular');
    }
  });

  grunt.registerTask('release', ['clean', 'build', 'cut-release', 'gh-pages']);
};
<|endoftext|>


<commit_before>var extend = require("xtend");

var getRequirejsConfig = function () {
  var requirejsConfig;
  global.define = function (config) {
    requirejsConfig = config({ isBuild: true });
  };
  require('./app/config');
  return requirejsConfig;
};

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

  // Project configuration.
  grunt.initConfig({
    clean: ["public/"],
    sass: {
      development: {
        files: {
          'public/stylesheets/spotlight.css': 'styles/index.scss'
        },
        options: {
          loadPath: [
            'node_modules/govuk_frontend_toolkit/govuk_frontend_toolkit/stylesheets'
          ],
          style: 'nested'
        }
      },
      production: {
        files: [
          { 'public/stylesheets/spotlight.css': 'styles/index.scss' },
          {
            expand: true,
            cwd: 'node_modules/govuk_template_mustache/assets/stylesheets',
            src: ['*.css'],
            dest: 'public',
            ext: '.css'
          }
        ],
        options: {
          loadPath: [
            'node_modules/govuk_frontend_toolkit/govuk_frontend_toolkit/stylesheets'
          ],
          style: 'compressed'
        }
      }
    },
    jasmine: {
      limelight: {
        src: 'app/**/*.js',
        options: {
          specs: 'test/spec/**/spec.*.js',
          helpers: 'test/spec/helpers/*.js',
          template: 'test/spec/index.html',
          keepRunner: true
        }
      }
    },
    jshint: {
      files: "app/**/*.js",
      options: {
        ignores: ['app/vendor/**'],
        eqnull: true
      }
    },
    requirejs: {
      production: {
        options: extend(getRequirejsConfig(), {
          baseUrl: 'app',
          out: "public/javascripts/spotlight.js",
          name: "client",
          include: ["vendor/almond"],
          deps: [
            'client'
          ],
          wrap: false
        })
      }
    },
    copy: {
      govuk_template: {
        src: 'node_modules/govuk_template_mustache/views/layouts/govuk_template.html',
        dest: 'app/common/templates/',
        expand: true,
        flatten: true,
        filter: 'isFile'
      },
      govuk_assets: {
        files: [
          {
            expand: true,
            src: '**',
            cwd: 'node_modules/govuk_template_mustache/assets',
            dest: 'public/'
          }
        ]
      }
    }
  });

  [
    'grunt-contrib-jasmine',
    'grunt-contrib-jshint',
    'grunt-contrib-clean',
    'grunt-contrib-sass',
    'grunt-contrib-requirejs',
    'grunt-contrib-copy'
  ].forEach(function (task) {
    grunt.loadNpmTasks(task);
  });

  // Default task.
  grunt.registerTask('build:development', [
    'copy:govuk_template', 'jshint', 'clean', 'copy:govuk_assets', 'sass:development'
  ]);
  grunt.registerTask('build:production', [
    'copy:govuk_template', 'jshint', 'jasmine', 'clean', 'copy:govuk_assets', 'sass:production', 'requirejs'
  ]);
  grunt.registerTask('default', ['build:development']);

};

<commit_msg>Fix stylesheet minification in production builds<commit_after>var extend = require("xtend");

var getRequirejsConfig = function () {
  var requirejsConfig;
  global.define = function (config) {
    requirejsConfig = config({ isBuild: true });
  };
  require('./app/config');
  return requirejsConfig;
};

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

  // Project configuration.
  grunt.initConfig({
    clean: ["public/"],
    sass: {
      development: {
        files: {
          'public/stylesheets/spotlight.css': 'styles/index.scss'
        },
        options: {
          loadPath: [
            'node_modules/govuk_frontend_toolkit/govuk_frontend_toolkit/stylesheets'
          ],
          style: 'nested'
        }
      },
      production: {
        files: [
          { 'public/stylesheets/spotlight.css': 'styles/index.scss' },
          {
            expand: true,
            cwd: 'node_modules/govuk_template_mustache/assets/stylesheets',
            src: ['*.css'],
            dest: 'public/stylesheets',
            ext: '.css'
          }
        ],
        options: {
          loadPath: [
            'node_modules/govuk_frontend_toolkit/govuk_frontend_toolkit/stylesheets'
          ],
          style: 'compressed'
        }
      }
    },
    jasmine: {
      limelight: {
        src: 'app/**/*.js',
        options: {
          specs: 'test/spec/**/spec.*.js',
          helpers: 'test/spec/helpers/*.js',
          template: 'test/spec/index.html',
          keepRunner: true
        }
      }
    },
    jshint: {
      files: "app/**/*.js",
      options: {
        ignores: ['app/vendor/**'],
        eqnull: true
      }
    },
    requirejs: {
      production: {
        options: extend(getRequirejsConfig(), {
          baseUrl: 'app',
          out: "public/javascripts/spotlight.js",
          name: "client",
          include: ["vendor/almond"],
          deps: [
            'client'
          ],
          wrap: false
        })
      }
    },
    copy: {
      govuk_template: {
        src: 'node_modules/govuk_template_mustache/views/layouts/govuk_template.html',
        dest: 'app/common/templates/',
        expand: true,
        flatten: true,
        filter: 'isFile'
      },
      govuk_assets: {
        files: [
          {
            expand: true,
            src: '**',
            cwd: 'node_modules/govuk_template_mustache/assets',
            dest: 'public/'
          }
        ]
      }
    }
  });

  [
    'grunt-contrib-jasmine',
    'grunt-contrib-jshint',
    'grunt-contrib-clean',
    'grunt-contrib-sass',
    'grunt-contrib-requirejs',
    'grunt-contrib-copy'
  ].forEach(function (task) {
    grunt.loadNpmTasks(task);
  });

  // Default task.
  grunt.registerTask('build:development', [
    'copy:govuk_template', 'jshint', 'clean', 'copy:govuk_assets', 'sass:development'
  ]);
  grunt.registerTask('build:production', [
    'copy:govuk_template', 'jshint', 'jasmine', 'clean', 'copy:govuk_assets', 'sass:production', 'requirejs'
  ]);
  grunt.registerTask('default', ['build:development']);

};

<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2013-2015 CNRS

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

var _ = require('./controllers/utils');
var User = require('./controllers/User');
var Group = require('./controllers/Group');
var Corpus = require('./controllers/Corpus');
var Medium = require('./controllers/Medium');
var Layer = require('./controllers/Layer');
var Annotation = require('./controllers/Annotation');
var Queue = require('./controllers/Queue');
var Authentication = require('./controllers/Authentication');

var mUser = require('./models/User');
var mGroup = require('./models/Group');
var mCorpus = require('./models/Corpus');
var mMedium = require('./models/Medium');
var mLayer = require('./models/Layer');
var mAnnotation = require('./models/Annotation');
var mQueue = require('./models/Queue');

exports.initialize = function (app) {

  // UTILS

  app.get('/date',
    Authentication.middleware.isLoggedIn,
    _.route.date);

  // AUTHENTICATION

  // login
  app.post('/login',
    Authentication.login);

  // logout
  app.post('/logout',
    Authentication.middleware.isLoggedIn,
    Authentication.logout);

  // get logged in user
  app.get('/me',
    Authentication.middleware.isLoggedIn,
    Authentication.me);

  // get groups of logged in user
  app.get('/me/group',
    Authentication.middleware.isLoggedIn,
    Authentication.getGroups);

  // update password
  app.put('/me',
    Authentication.middleware.isLoggedIn,
    User.change_password);

  // USERS

  // create new user
  app.post('/user',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    User.create);

  // delete one user
  app.delete('/user/:id_user',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isRoot,
    _.middleware.fExists(mUser),
    User.remove);

  // get all users
  app.get('/user',
    Authentication.middleware.isLoggedIn,
    // Authentication.middleware.isAdmin,
    User.getAll);

  // get one user
  app.get('/user/:id_user',
    Authentication.middleware.isLoggedIn,
    // Authentication.middleware.isAdmin,
    _.middleware.fExists(mUser),
    User.getOne);

  // update one user
  app.put('/user/:id_user',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mUser),
    User.update);

  // get one user's groups
  app.get('/user/:id_user/group',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mUser),
    User.getGroups);

  // GROUPS

  // get all groups
  app.get('/group',
    Authentication.middleware.isLoggedIn,
    // Authentication.middleware.isAdmin,
    Group.getAll);

  // get one group
  app.get('/group/:id_group',
    Authentication.middleware.isLoggedIn,
    // Authentication.middleware.isAdmin,
    _.middleware.fExists(mGroup),
    Group.getOne);

  // create new group
  app.post("/group",
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    Group.create);

  // update one group
  app.put('/group/:id_group',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mGroup),
    Group.update);

  // delete one group
  app.delete('/group/:id_group',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isRoot,
    _.middleware.fExists(mGroup),
    Group.remove);

  // add one user to one group
  app.put("/group/:id_group/user/:id_user",
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mGroup),
    _.middleware.fExists(mUser),
    Group.addUser);

  // remove one user from one group
  app.delete('/group/:id_group/user/:id_user',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mGroup),
    _.middleware.fExists(mUser),
    Group.removeUser);

  // CORPUS

  // get all READable corpora
  app.get('/corpus',
    Authentication.middleware.isLoggedIn,
    Corpus.getAll);

  // get one corpus
  app.get('/corpus/:id_corpus',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.READ),
    Corpus.getOne);

  // create new corpus
  app.post('/corpus',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    Corpus.create);

  // update one corpus
  app.put('/corpus/:id_corpus',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.update);

  // delete one corpus
  app.delete('/corpus/:id_corpus',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.remove);

  // get one corpus' rights
  app.get('/corpus/:id_corpus/permissions',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.getRights);

  // give one user rights to one corpus
  app.put('/corpus/:id_corpus/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.updateUserRights);

  // remove one user's rights to one corpus
  app.delete('/corpus/:id_corpus/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.removeUserRights);

  // give one group rights to one corpus
  app.put('/corpus/:id_corpus/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.updateGroupRights);

  // remove one group's rights to one corpus
  app.delete('/corpus/:id_corpus/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.removeGroupRights);

  // MEDIUM

  // get all media
  app.get('/medium',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isRoot,
    Medium.getAll);

  // get one medium
  app.get('/medium/:id_medium',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.READ),
    Medium.getOne);

  // get one corpus' media
  app.get('/corpus/:id_corpus/medium',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.READ),
    Medium.getCorpusMedia);

  // create new medium(a) in one corpus
  app.post('/corpus/:id_corpus/medium',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Medium.create);

  // update one medium
  app.put('/medium/:id_medium',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.ADMIN),
    Medium.update);

  // delete one medium
  app.delete('/medium/:id_medium',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.ADMIN),
    Medium.remove);

  // stream one medium in default format
  app.get('/medium/:id_medium/video',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.READ),
    Medium.stream);

  // stream one medium in WebM
  app.get('/medium/:id_medium/webm',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.READ),
    Medium.streamWebM);

  // stream one medium in MP4
  app.get('/medium/:id_medium/mp4',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.READ),
    Medium.streamMp4);

  // stream one medium in OGV
  app.get('/medium/:id_medium/ogv',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.READ),
    Medium.streamOgv);

  // LAYER

  // get all layers
  app.get('/layer',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isRoot,
    Layer.getAll);

  // get one layer
  app.get('/layer/:id_layer',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.READ),
    Layer.getOne);

  // get one corpus' layers
  app.get('/corpus/:id_corpus/layer',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.READ),
    Layer.getCorpusLayers);

  // create new layer(s) in one corpus
  app.post('/corpus/:id_corpus/layer',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.WRITE),
    Layer.create);

  // update one layer
  app.put('/layer/:id_layer',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.update);

  // delete one layer
  app.delete('/layer/:id_layer',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.remove);

  // get one layer's rights
  app.get('/layer/:id_layer/permissions',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.getRights);

  // give one user rights to one layer
  app.put('/layer/:id_layer/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.updateUserRights);

  // remove one user's rights to one layer
  app.delete('/layer/:id_layer/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.removeUserRights);

  // give one group rights to one layer
  app.put('/layer/:id_layer/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.updateGroupRights);

  // remove on group's rights to one layer
  app.delete('/layer/:id_layer/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.removeGroupRights);

  // ANNOTATION

  // get all annotations
  app.get('/annotation',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isRoot,
    Annotation.getAll);

  // get one annotation
  app.get('/annotation/:id_annotation',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mAnnotation, _.READ),
    Annotation.getOne);

  // get one layer's annotations
  app.get('/layer/:id_layer/annotation',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.READ),
    Annotation.getLayerAnnotations);

  // create new annotation(s) in one layer
  app.post('/layer/:id_layer/annotation',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.WRITE),
    Annotation.create);

  // update one annotation
  app.put('/annotation/:id_annotation',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mAnnotation, _.WRITE),
    Annotation.update);

  // delete one annotation
  app.delete('/annotation/:id_annotation',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mAnnotation, _.ADMIN),
    Annotation.remove);

  // QUEUE

  // get all READable corpora
  app.get('/queue',
    Authentication.middleware.isLoggedIn,
    Queue.getAll);

  // get one queue
  app.get('/queue/:id_queue',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.READ),
    Queue.getOne);

  // create new queue
  app.post('/queue',
    Authentication.middleware.isLoggedIn,
    Queue.create);

  // update one queue
  app.put('/queue/:id_queue',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.update);

  // append items to one queue
  app.put('/queue/:id_queue/next',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.WRITE),
    Queue.push);

  // pop one item from one queue
  app.get('/queue/:id_queue/next',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.WRITE),
    Queue.pop);

  // remove one queue
  app.delete('/queue/:id_queue',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.remove);

  // get one queue' rights
  app.get('/queue/:id_queue/permissions',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.getRights);

  // give one user rights to one queue
  app.put('/queue/:id_queue/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.updateUserRights);

  // remove one user's rights to one queue
  app.delete('/queue/:id_queue/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.removeUserRights);

  // give one group rights to one queue
  app.put('/queue/:id_queue/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.updateGroupRights);

  // remove one group's rights to one queue
  app.delete('/queue/:id_queue/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.removeGroupRights);

};<commit_msg>feat: admin users are now allowed to delete users<commit_after>/*
The MIT License (MIT)

Copyright (c) 2013-2015 CNRS

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

var _ = require('./controllers/utils');
var User = require('./controllers/User');
var Group = require('./controllers/Group');
var Corpus = require('./controllers/Corpus');
var Medium = require('./controllers/Medium');
var Layer = require('./controllers/Layer');
var Annotation = require('./controllers/Annotation');
var Queue = require('./controllers/Queue');
var Authentication = require('./controllers/Authentication');

var mUser = require('./models/User');
var mGroup = require('./models/Group');
var mCorpus = require('./models/Corpus');
var mMedium = require('./models/Medium');
var mLayer = require('./models/Layer');
var mAnnotation = require('./models/Annotation');
var mQueue = require('./models/Queue');

exports.initialize = function (app) {

  // UTILS

  app.get('/date',
    Authentication.middleware.isLoggedIn,
    _.route.date);

  // AUTHENTICATION

  // login
  app.post('/login',
    Authentication.login);

  // logout
  app.post('/logout',
    Authentication.middleware.isLoggedIn,
    Authentication.logout);

  // get logged in user
  app.get('/me',
    Authentication.middleware.isLoggedIn,
    Authentication.me);

  // get groups of logged in user
  app.get('/me/group',
    Authentication.middleware.isLoggedIn,
    Authentication.getGroups);

  // update password
  app.put('/me',
    Authentication.middleware.isLoggedIn,
    User.change_password);

  // USERS

  // create new user
  app.post('/user',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    User.create);

  // delete one user
  app.delete('/user/:id_user',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mUser),
    User.remove);

  // get all users
  app.get('/user',
    Authentication.middleware.isLoggedIn,
    // Authentication.middleware.isAdmin,
    User.getAll);

  // get one user
  app.get('/user/:id_user',
    Authentication.middleware.isLoggedIn,
    // Authentication.middleware.isAdmin,
    _.middleware.fExists(mUser),
    User.getOne);

  // update one user
  app.put('/user/:id_user',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mUser),
    User.update);

  // get one user's groups
  app.get('/user/:id_user/group',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mUser),
    User.getGroups);

  // GROUPS

  // get all groups
  app.get('/group',
    Authentication.middleware.isLoggedIn,
    // Authentication.middleware.isAdmin,
    Group.getAll);

  // get one group
  app.get('/group/:id_group',
    Authentication.middleware.isLoggedIn,
    // Authentication.middleware.isAdmin,
    _.middleware.fExists(mGroup),
    Group.getOne);

  // create new group
  app.post("/group",
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    Group.create);

  // update one group
  app.put('/group/:id_group',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mGroup),
    Group.update);

  // delete one group
  app.delete('/group/:id_group',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isRoot,
    _.middleware.fExists(mGroup),
    Group.remove);

  // add one user to one group
  app.put("/group/:id_group/user/:id_user",
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mGroup),
    _.middleware.fExists(mUser),
    Group.addUser);

  // remove one user from one group
  app.delete('/group/:id_group/user/:id_user',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExists(mGroup),
    _.middleware.fExists(mUser),
    Group.removeUser);

  // CORPUS

  // get all READable corpora
  app.get('/corpus',
    Authentication.middleware.isLoggedIn,
    Corpus.getAll);

  // get one corpus
  app.get('/corpus/:id_corpus',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.READ),
    Corpus.getOne);

  // create new corpus
  app.post('/corpus',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    Corpus.create);

  // update one corpus
  app.put('/corpus/:id_corpus',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.update);

  // delete one corpus
  app.delete('/corpus/:id_corpus',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isAdmin,
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.remove);

  // get one corpus' rights
  app.get('/corpus/:id_corpus/permissions',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.getRights);

  // give one user rights to one corpus
  app.put('/corpus/:id_corpus/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.updateUserRights);

  // remove one user's rights to one corpus
  app.delete('/corpus/:id_corpus/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.removeUserRights);

  // give one group rights to one corpus
  app.put('/corpus/:id_corpus/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.updateGroupRights);

  // remove one group's rights to one corpus
  app.delete('/corpus/:id_corpus/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Corpus.removeGroupRights);

  // MEDIUM

  // get all media
  app.get('/medium',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isRoot,
    Medium.getAll);

  // get one medium
  app.get('/medium/:id_medium',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.READ),
    Medium.getOne);

  // get one corpus' media
  app.get('/corpus/:id_corpus/medium',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.READ),
    Medium.getCorpusMedia);

  // create new medium(a) in one corpus
  app.post('/corpus/:id_corpus/medium',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.ADMIN),
    Medium.create);

  // update one medium
  app.put('/medium/:id_medium',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.ADMIN),
    Medium.update);

  // delete one medium
  app.delete('/medium/:id_medium',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.ADMIN),
    Medium.remove);

  // stream one medium in default format
  app.get('/medium/:id_medium/video',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.READ),
    Medium.stream);

  // stream one medium in WebM
  app.get('/medium/:id_medium/webm',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.READ),
    Medium.streamWebM);

  // stream one medium in MP4
  app.get('/medium/:id_medium/mp4',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.READ),
    Medium.streamMp4);

  // stream one medium in OGV
  app.get('/medium/:id_medium/ogv',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mMedium, _.READ),
    Medium.streamOgv);

  // LAYER

  // get all layers
  app.get('/layer',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isRoot,
    Layer.getAll);

  // get one layer
  app.get('/layer/:id_layer',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.READ),
    Layer.getOne);

  // get one corpus' layers
  app.get('/corpus/:id_corpus/layer',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.READ),
    Layer.getCorpusLayers);

  // create new layer(s) in one corpus
  app.post('/corpus/:id_corpus/layer',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mCorpus, _.WRITE),
    Layer.create);

  // update one layer
  app.put('/layer/:id_layer',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.update);

  // delete one layer
  app.delete('/layer/:id_layer',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.remove);

  // get one layer's rights
  app.get('/layer/:id_layer/permissions',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.getRights);

  // give one user rights to one layer
  app.put('/layer/:id_layer/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.updateUserRights);

  // remove one user's rights to one layer
  app.delete('/layer/:id_layer/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.removeUserRights);

  // give one group rights to one layer
  app.put('/layer/:id_layer/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.updateGroupRights);

  // remove on group's rights to one layer
  app.delete('/layer/:id_layer/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mLayer, _.ADMIN),
    Layer.removeGroupRights);

  // ANNOTATION

  // get all annotations
  app.get('/annotation',
    Authentication.middleware.isLoggedIn,
    Authentication.middleware.isRoot,
    Annotation.getAll);

  // get one annotation
  app.get('/annotation/:id_annotation',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mAnnotation, _.READ),
    Annotation.getOne);

  // get one layer's annotations
  app.get('/layer/:id_layer/annotation',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.READ),
    Annotation.getLayerAnnotations);

  // create new annotation(s) in one layer
  app.post('/layer/:id_layer/annotation',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mLayer, _.WRITE),
    Annotation.create);

  // update one annotation
  app.put('/annotation/:id_annotation',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mAnnotation, _.WRITE),
    Annotation.update);

  // delete one annotation
  app.delete('/annotation/:id_annotation',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mAnnotation, _.ADMIN),
    Annotation.remove);

  // QUEUE

  // get all READable corpora
  app.get('/queue',
    Authentication.middleware.isLoggedIn,
    Queue.getAll);

  // get one queue
  app.get('/queue/:id_queue',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.READ),
    Queue.getOne);

  // create new queue
  app.post('/queue',
    Authentication.middleware.isLoggedIn,
    Queue.create);

  // update one queue
  app.put('/queue/:id_queue',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.update);

  // append items to one queue
  app.put('/queue/:id_queue/next',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.WRITE),
    Queue.push);

  // pop one item from one queue
  app.get('/queue/:id_queue/next',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.WRITE),
    Queue.pop);

  // remove one queue
  app.delete('/queue/:id_queue',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.remove);

  // get one queue' rights
  app.get('/queue/:id_queue/permissions',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.getRights);

  // give one user rights to one queue
  app.put('/queue/:id_queue/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.updateUserRights);

  // remove one user's rights to one queue
  app.delete('/queue/:id_queue/user/:id_user',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mUser),
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.removeUserRights);

  // give one group rights to one queue
  app.put('/queue/:id_queue/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.updateGroupRights);

  // remove one group's rights to one queue
  app.delete('/queue/:id_queue/group/:id_group',
    Authentication.middleware.isLoggedIn,
    _.middleware.fExists(mGroup),
    _.middleware.fExistsWithRights(mQueue, _.ADMIN),
    Queue.removeGroupRights);

};<|endoftext|>


<commit_before>'use strict';

var tracklist = require('./tracklist');
var resolver = require('./resolver');
var wManager = require('./worker_manager');
var socket = require('./socket')();
var redis = require('redis').createClient();
var crypto = require('crypto');
var volume = require('./volume');
var minVotes = 3;

var allowedMethods = 'GET,PUT,POST,DELETE,OPTIONS';
var allowedHeaders = 'Content-Length,Content-Type';
function allowCrossDomain(req, res, next) {
  var allowedHosts = [
    'http://soundcloud.com',
    'https://soundcloud.com',
    'http://youtube.com',
    'https://youtube.com',
    'http://www.youtube.com',
    'https://www.youtube.com'
  ];

  if (allowedHosts.indexOf(req.headers.origin) !== -1) {
    res.header('Access-Control-Allow-Origin', req.headers.origin);
    res.header('Access-Control-Allow-Methods', allowedMethods);
    res.header('Access-Control-Allow-Headers', allowedHeaders);
    if ('OPTIONS' === req.method) return res.send(200);
  }
  next();
}

module.exports = function (app) {
  app.get('/player', function (req, res) {
    res.send(wManager.state());
  });

  app.post('/player', function (req, res) {
    if (!wManager.state().playing) wManager.start();
    res.send(201);
  });

  app.delete('/player', function (req, res) {
    if (wManager.state().playing) wManager.stop();
    res.send(201);
  });

  app.get('/tracks', function (req, res) {
    tracklist.get()
    .then(function (list) {
      res.send(list);
    }, function (err) {
      res.send(503, err.message);
    });
  });

  app.options('/tracks', allowCrossDomain);

  app.post('/tracks', allowCrossDomain, function (req, res) {
    if (!req.body.url) return res.send(400, 'You need to provide a track URL.');
    resolver.resolve(req.body.url)
    .then(tracklist.add)
    .then(function (track) {
      socket.emit('new track', track);
      res.send(201, track);
    }, function (err) {
      res.send(500, err.message);
    });
  });

  app.get('/tracks/current', function (req, res) {
    tracklist.current()
    .then(function (track) {
      res.send(track);
    }, function (err) {
      res.send(500, err.message);
    });
  });

  app.post('/tracks/next', function (req, res) {
    tracklist.next()
    .then(function (track) {
      wManager.stop();
      wManager.start();
      res.send(track);
    }, function (err) {
      res.send(500, err.message);
    });
  });

  app.get('/tracks/history', function (req, res) {
    tracklist.history()
    .then(function (list) {
      res.send(list);
    }, function (err) {
      res.send(500, err.message);
    });
  });

  app.get('/votes', function (req, res) {
    redis.scard('jukebox:votes', function (err, count) {
      if (err) return res.send(500, err);
      res.send({
        favorable: count,
        total: minVotes
      });
    });
  });

  app.post('/votes', function (req, res) {
    var ua = req.headers['user-agent'];
    var hash = crypto.createHash('md5').update(ua).digest('hex');
    redis.sadd('jukebox:votes', hash, function (err, newCount) {
      if (err) return res.send(500, err);
      res.send(201);
      if (newCount > 0) {
        socket.emit('new vote', newCount);
        wManager.checkVotesNext();
      }
    });
  });

  app.post('/volume', function (req, res) {
    if (!req.body.p) return res.send(400, 'You need to provide a percentage.');
    var p = parseInt(req.body.p, 10);
    if (p < 0 || p > 100) return res.send(400, 'Percentage value out of range.');
    volume(p);
    res.send(201);
  });
};
<commit_msg>Changed: use the IP address instead of the user agent in votes It works better for us as we're on the same LAN.<commit_after>'use strict';

var tracklist = require('./tracklist');
var resolver = require('./resolver');
var wManager = require('./worker_manager');
var socket = require('./socket')();
var redis = require('redis').createClient();
var crypto = require('crypto');
var volume = require('./volume');
var minVotes = 3;

var allowedMethods = 'GET,PUT,POST,DELETE,OPTIONS';
var allowedHeaders = 'Content-Length,Content-Type';
function allowCrossDomain(req, res, next) {
  var allowedHosts = [
    'http://soundcloud.com',
    'https://soundcloud.com',
    'http://youtube.com',
    'https://youtube.com',
    'http://www.youtube.com',
    'https://www.youtube.com'
  ];

  if (allowedHosts.indexOf(req.headers.origin) !== -1) {
    res.header('Access-Control-Allow-Origin', req.headers.origin);
    res.header('Access-Control-Allow-Methods', allowedMethods);
    res.header('Access-Control-Allow-Headers', allowedHeaders);
    if ('OPTIONS' === req.method) return res.send(200);
  }
  next();
}

module.exports = function (app) {
  app.get('/player', function (req, res) {
    res.send(wManager.state());
  });

  app.post('/player', function (req, res) {
    if (!wManager.state().playing) wManager.start();
    res.send(201);
  });

  app.delete('/player', function (req, res) {
    if (wManager.state().playing) wManager.stop();
    res.send(201);
  });

  app.get('/tracks', function (req, res) {
    tracklist.get()
    .then(function (list) {
      res.send(list);
    }, function (err) {
      res.send(503, err.message);
    });
  });

  app.options('/tracks', allowCrossDomain);

  app.post('/tracks', allowCrossDomain, function (req, res) {
    if (!req.body.url) return res.send(400, 'You need to provide a track URL.');
    resolver.resolve(req.body.url)
    .then(tracklist.add)
    .then(function (track) {
      socket.emit('new track', track);
      res.send(201, track);
    }, function (err) {
      res.send(500, err.message);
    });
  });

  app.get('/tracks/current', function (req, res) {
    tracklist.current()
    .then(function (track) {
      res.send(track);
    }, function (err) {
      res.send(500, err.message);
    });
  });

  app.post('/tracks/next', function (req, res) {
    tracklist.next()
    .then(function (track) {
      wManager.stop();
      wManager.start();
      res.send(track);
    }, function (err) {
      res.send(500, err.message);
    });
  });

  app.get('/tracks/history', function (req, res) {
    tracklist.history()
    .then(function (list) {
      res.send(list);
    }, function (err) {
      res.send(500, err.message);
    });
  });

  app.get('/votes', function (req, res) {
    redis.scard('jukebox:votes', function (err, count) {
      if (err) return res.send(500, err);
      res.send({
        favorable: count,
        total: minVotes
      });
    });
  });

  app.post('/votes', function (req, res) {
    redis.sadd('jukebox:votes', req.ip, function (err, newCount) {
      if (err) return res.send(500, err);
      res.send(201);
      if (newCount > 0) {
        socket.emit('new vote', newCount);
        wManager.checkVotesNext();
      }
    });
  });

  app.post('/volume', function (req, res) {
    if (!req.body.p) return res.send(400, 'You need to provide a percentage.');
    var p = parseInt(req.body.p, 10);
    if (p < 0 || p > 100) return res.send(400, 'Percentage value out of range.');
    volume(p);
    res.send(201);
  });
};
<|endoftext|>


<commit_before>/* globals require, module */
// Generated on 2014-07-18 using generator-angular 0.7.1

// # 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) {

  'use strict';

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

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  // Define the configuration for all the tasks
  grunt.initConfig({

    // Project settings
    yeoman: {
      // configurable paths
      app: require('./bower.json').appPath || 'app',
      dist: 'dist'
    },

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      js: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
        tasks: ['newer:jshint:all'],
        options: {
          livereload: true
        }
      },
      // jsTest: {
      //   files: [
      //     'test/spec/{,*/}*.js',
      //     '<%= yeoman.app %>/scripts/{,*/}*.js'
      //   ],
      //   tasks: [
      //     'newer:jshint:test',
      //     'karma'
      //   ]
      // },
      //compass: {
      //  files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
      //  tasks: ['compass:server', 'autoprefixer']
      //},
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    // The actual grunt server settings
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: '0.0.0.0',
        livereload: 35729
      },
      livereload: {
        options: {
          open: true,
          base: [
            '.tmp',
            '<%= yeoman.app %>'
          ]
        }
      },
      test: {
        options: {
          port: 9001,
          base: [
            '.tmp',
            'test',
            '<%= yeoman.app %>'
          ]
        }
      },
      dist: {
        options: {
          base: '<%= yeoman.dist %>'
        }
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      ignores: [
        'Gruntfile.js'
      ],
      all: [
        'Gruntfile.js',
        '<%= yeoman.app %>/scripts/{,*/}*.js'
      ]
      //,
      //
      // test: {
      //   options: {
      //     jshintrc: 'test/.jshintrc'
      //   },
      //   src: ['test/spec/{,*/}*.js']
      // }
    },

    // Empties folders to start fresh
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%= yeoman.dist %>/*',
            '!<%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: '.tmp'
    },

    // Add vendor prefixed styles
    autoprefixer: {
      options: {
        browsers: ['last 1 version']
      },
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest: '.tmp/styles/'
        }]
      }
    },

    // Automatically inject Bower components into the app
    'bower-install': {
      app: {
        html: '<%= yeoman.app %>/index.html',
        ignorePath: '<%= yeoman.app %>/'
      }
    },

    // Compiles Sass to CSS and generates necessary files if requested
    /*
    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,
        assetCacheBuster: false,
        raw: 'Sass::Script::Number.precision = 10\n'
      },
      dist: {
        options: {
          generatedImagesDir: '<%= yeoman.dist %>/images/generated'
        }
      },
      server: {
        options: {
          debugInfo: true
        }
      }
    },
    */

    // Renames files for browser caching purposes
    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/*'
          ]
        }
      }
    },

    // Reads HTML for usemin blocks to enable smart builds that automatically
    // concat, minify and revision files. Creates configurations in memory so
    // additional tasks can operate on them
    useminPrepare: {
      html: '<%= yeoman.app %>/index.html',
      options: {
        dest: '<%= yeoman.dist %>'
      }
    },

    // Performs rewrites based on rev and the useminPrepare configuration
    usemin: {
      html: ['<%= yeoman.dist %>/{,*/}*.html'],
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
      options: {
        assetsDirs: ['<%= yeoman.dist %>']
      }
    },

    // The following *-min tasks produce minified files in the dist folder
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '{,*/}*.{png,jpg,jpeg,gif}',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },
    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '{,*/}*.svg',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },
    htmlmin: {
      dist: {
        options: {
          collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeCommentsFromCDATA: true,
          removeOptionalTags: true
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.dist %>',
          src: ['*.html'],
          dest: '<%= yeoman.dist %>'
        }]
      }
    },

    htmllint: {
      app: ['<%= yeoman.app %>/*.html'],
      dist: ['<%= yeoman.dist %>/*.html']
    },

    rsync: {
      options: {
        args: ['--verbose'],
        exclude: ['.git*','*.scss','node_modules'],
        recursive: true
      },
      prod: {
        options: {
          src: '<%= yeoman.dist %>/',
          dest: '/home/linguagil/2016.linguagil.com.br/',
          host: 'linguagil@linguagil.com.br',
          syncDestIgnoreExcl: true
        }
      }
    },

    // Replace Google CDN references
    cdnify: {
      dist: {
        html: ['<%= yeoman.dist %>/*.html']
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,png,txt}',
            '.htaccess',
            '*.html',
            'views/{,*/}*.html',
            'bower_components/**/*',
            'images/{,*/}*.{webp}',
            'fonts/*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: ['generated/*']
        }]
      },
      styles: {
        expand: true,
        cwd: '<%= yeoman.app %>/styles',
        dest: '.tmp/styles/',
        src: '{,*/}*.css'
      }
    },

    // Run some tasks in parallel to speed up the build process
    concurrent: {
      server: [
        //'compass:server'
      ],
      test: [
        //'compass'
      ],
      dist: [
        //'compass:dist',
        'imagemin',
        'svgmin'
      ]
    },

    // By default, your `index.html`'s <!-- Usemin block --> will take care of
    // minification. These next options are pre-configured if you do not wish
    // to use the Usemin blocks.
    // cssmin: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/styles/main.css': [
    //         '.tmp/styles/{,*/}*.css',
    //         '<%= yeoman.app %>/styles/{,*/}*.css'
    //       ]
    //     }
    //   }
    // },
    // uglify: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/scripts/scripts.js': [
    //         '<%= yeoman.dist %>/scripts/scripts.js'
    //       ]
    //     }
    //   }
    // },
    // concat: {
    //   dist: {}
    // },

    // Test settings
    // karma: {
    //   unit: {
    //     configFile: 'karma.conf.js',
    //     singleRun: true
    //   }
    // }
  });

  grunt.loadNpmTasks('grunt-html');
  grunt.loadNpmTasks('grunt-rsync');

  grunt.registerTask('modifyImageLinkInScript', 'Task for replace image link in script file.', function(filename, imageTarget, folder) {
    folder = (typeof folder !== 'undefined') ? '/' + folder : '';
    var fs = require('fs'),
        SCRIPTS_DIST_DIR = 'dist/scripts',
        IMAGE_DIST_DIR = 'dist/images' + folder,
        oldestImage = imageTarget
    ;

    fs.readdirSync(SCRIPTS_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(filename) !== (-1) ) {
        filename = SCRIPTS_DIST_DIR+'/'+file;
      }
    });

    fs.readdirSync(IMAGE_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(oldestImage) !== (-1) ) {
        imageTarget = file;
      }
    });

    var data = fs.readFileSync(filename, 'utf8');
    data = data.replace(new RegExp(oldestImage, 'g'), imageTarget);

    fs.writeFileSync(filename, data, 'utf8');

  });

  grunt.registerTask('modifyImageLinkInStyles', 'Task for replace image link in stylesheet file.', function(filename, imageTarget) {
    var fs = require('fs'),
        STYLES_DIST_DIR = 'dist/styles',
        IMAGE_DIST_DIR = 'dist/images',
        oldestImage = imageTarget
    ;

    fs.readdirSync(STYLES_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(filename) !== (-1) ) {
        filename = STYLES_DIST_DIR+'/'+file;
      }
    });

    fs.readdirSync(IMAGE_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(oldestImage) !== (-1) ) {
        imageTarget = file;
      }
    });

    var data = fs.readFileSync(filename, 'utf8');
    data = data.replace(new RegExp(oldestImage, 'g'), imageTarget);

    fs.writeFileSync(filename, data, 'utf8');

  });

  grunt.registerTask('modifyImageLinkInHtml', 'Task for replace image link in html files.', function(filename, folder, imageTarget) {
    folder = (typeof folder !== 'undefined') ? '/' + folder : '';
    var fs = require('fs'),
        HTML_DIST_DIR = 'dist/',
        IMAGE_DIST_DIR = 'dist/images' + folder,
        oldestImage = imageTarget
    ;

    fs.readdirSync(HTML_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(filename) !== (-1) ) {
        filename = HTML_DIST_DIR+'/'+file;
      }
    });

    fs.readdirSync(IMAGE_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(oldestImage) !== (-1) ) {
        imageTarget = file;
      }
    });

    var data = fs.readFileSync(filename, 'utf8');
    data = data.replace(new RegExp(oldestImage, 'g'), imageTarget);

    fs.writeFileSync(filename, data, 'utf8');

  });

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

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

  grunt.registerTask('server', function () {
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
    grunt.task.run(['serve']);
  });

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

  // var pages = [
  //   'index.html',
  //   'programacao.html',
  //   'videos.html',
  //   'codigo-de-conduta.html',
  //   'eventos-anteriores.html'
  // ];

  // var pagesLength = pages.length;

  var gruntBuildTasks = [
    'jshint:all',
    //'htmllint:app',
    'clean:dist',
    'bower-install',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer:dist',
    'concat',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'rev',
    'usemin',
    'htmlmin',

    'modifyImageLinkInScript:scripts.js:pin.png',
    'modifyImageLinkInScript:scripts.js:a-confirmar.jpg:talks',
    'modifyImageLinkInScript:scripts.js:achilles-froes.jpeg:talks',
    'modifyImageLinkInScript:scripts.js:guilherme-motta.jpg:talks',
    'modifyImageLinkInScript:scripts.js:juliano-ribeiro.jpg:talks',
    'modifyImageLinkInScript:scripts.js:luciano-borges.jpg:talks',
    'modifyImageLinkInScript:scripts.js:marcio-albuquerque.jpg:talks',
    'modifyImageLinkInScript:scripts.js:mauricio-vieira.jpg:talks',
    'modifyImageLinkInScript:scripts.js:morvana-bonin.jpg:talks',
    'modifyImageLinkInScript:scripts.js:otavio-santana.jpg:talks',
    'modifyImageLinkInScript:scripts.js:rafael-helm.jpeg:talks',
    'modifyImageLinkInScript:scripts.js:rafael-miranda.png:talks',

    'modifyImageLinkInStyles:main.css:home-background.jpg'
  ];

  grunt.registerTask('build', gruntBuildTasks);

  grunt.registerTask('default', [
    'newer:jshint',
    'test',
    'build'
  ]);

  grunt.registerTask('travis', [
    'bower-install',
    'jshint',
    'build',
    'htmllint:dist'
  ]);

  grunt.registerTask('deploy', [
    'travis',
    'rsync:prod'
  ]);

};
<commit_msg>deploy to official website<commit_after>/* globals require, module */
// Generated on 2014-07-18 using generator-angular 0.7.1

// # 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) {

  'use strict';

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

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  // Define the configuration for all the tasks
  grunt.initConfig({

    // Project settings
    yeoman: {
      // configurable paths
      app: require('./bower.json').appPath || 'app',
      dist: 'dist'
    },

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      js: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
        tasks: ['newer:jshint:all'],
        options: {
          livereload: true
        }
      },
      // jsTest: {
      //   files: [
      //     'test/spec/{,*/}*.js',
      //     '<%= yeoman.app %>/scripts/{,*/}*.js'
      //   ],
      //   tasks: [
      //     'newer:jshint:test',
      //     'karma'
      //   ]
      // },
      //compass: {
      //  files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
      //  tasks: ['compass:server', 'autoprefixer']
      //},
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= yeoman.app %>/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    // The actual grunt server settings
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: '0.0.0.0',
        livereload: 35729
      },
      livereload: {
        options: {
          open: true,
          base: [
            '.tmp',
            '<%= yeoman.app %>'
          ]
        }
      },
      test: {
        options: {
          port: 9001,
          base: [
            '.tmp',
            'test',
            '<%= yeoman.app %>'
          ]
        }
      },
      dist: {
        options: {
          base: '<%= yeoman.dist %>'
        }
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      ignores: [
        'Gruntfile.js'
      ],
      all: [
        'Gruntfile.js',
        '<%= yeoman.app %>/scripts/{,*/}*.js'
      ]
      //,
      //
      // test: {
      //   options: {
      //     jshintrc: 'test/.jshintrc'
      //   },
      //   src: ['test/spec/{,*/}*.js']
      // }
    },

    // Empties folders to start fresh
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%= yeoman.dist %>/*',
            '!<%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: '.tmp'
    },

    // Add vendor prefixed styles
    autoprefixer: {
      options: {
        browsers: ['last 1 version']
      },
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest: '.tmp/styles/'
        }]
      }
    },

    // Automatically inject Bower components into the app
    'bower-install': {
      app: {
        html: '<%= yeoman.app %>/index.html',
        ignorePath: '<%= yeoman.app %>/'
      }
    },

    // Compiles Sass to CSS and generates necessary files if requested
    /*
    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,
        assetCacheBuster: false,
        raw: 'Sass::Script::Number.precision = 10\n'
      },
      dist: {
        options: {
          generatedImagesDir: '<%= yeoman.dist %>/images/generated'
        }
      },
      server: {
        options: {
          debugInfo: true
        }
      }
    },
    */

    // Renames files for browser caching purposes
    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/*'
          ]
        }
      }
    },

    // Reads HTML for usemin blocks to enable smart builds that automatically
    // concat, minify and revision files. Creates configurations in memory so
    // additional tasks can operate on them
    useminPrepare: {
      html: '<%= yeoman.app %>/index.html',
      options: {
        dest: '<%= yeoman.dist %>'
      }
    },

    // Performs rewrites based on rev and the useminPrepare configuration
    usemin: {
      html: ['<%= yeoman.dist %>/{,*/}*.html'],
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
      options: {
        assetsDirs: ['<%= yeoman.dist %>']
      }
    },

    // The following *-min tasks produce minified files in the dist folder
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '{,*/}*.{png,jpg,jpeg,gif}',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },
    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '{,*/}*.svg',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },
    htmlmin: {
      dist: {
        options: {
          collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeCommentsFromCDATA: true,
          removeOptionalTags: true
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.dist %>',
          src: ['*.html'],
          dest: '<%= yeoman.dist %>'
        }]
      }
    },

    htmllint: {
      app: ['<%= yeoman.app %>/*.html'],
      dist: ['<%= yeoman.dist %>/*.html']
    },

    rsync: {
      options: {
        args: ['--verbose'],
        exclude: ['.git*','*.scss','node_modules'],
        recursive: true
      },
      prod: {
        options: {
          src: '<%= yeoman.dist %>/',
          dest: '/home/linguagil/linguagil.com.br/',
          host: 'linguagil@linguagil.com.br',
          syncDestIgnoreExcl: true
        }
      }
    },

    // Replace Google CDN references
    cdnify: {
      dist: {
        html: ['<%= yeoman.dist %>/*.html']
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,png,txt}',
            '.htaccess',
            '*.html',
            'views/{,*/}*.html',
            'bower_components/**/*',
            'images/{,*/}*.{webp}',
            'fonts/*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: ['generated/*']
        }]
      },
      styles: {
        expand: true,
        cwd: '<%= yeoman.app %>/styles',
        dest: '.tmp/styles/',
        src: '{,*/}*.css'
      }
    },

    // Run some tasks in parallel to speed up the build process
    concurrent: {
      server: [
        //'compass:server'
      ],
      test: [
        //'compass'
      ],
      dist: [
        //'compass:dist',
        'imagemin',
        'svgmin'
      ]
    },

    // By default, your `index.html`'s <!-- Usemin block --> will take care of
    // minification. These next options are pre-configured if you do not wish
    // to use the Usemin blocks.
    // cssmin: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/styles/main.css': [
    //         '.tmp/styles/{,*/}*.css',
    //         '<%= yeoman.app %>/styles/{,*/}*.css'
    //       ]
    //     }
    //   }
    // },
    // uglify: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/scripts/scripts.js': [
    //         '<%= yeoman.dist %>/scripts/scripts.js'
    //       ]
    //     }
    //   }
    // },
    // concat: {
    //   dist: {}
    // },

    // Test settings
    // karma: {
    //   unit: {
    //     configFile: 'karma.conf.js',
    //     singleRun: true
    //   }
    // }
  });

  grunt.loadNpmTasks('grunt-html');
  grunt.loadNpmTasks('grunt-rsync');

  grunt.registerTask('modifyImageLinkInScript', 'Task for replace image link in script file.', function(filename, imageTarget, folder) {
    folder = (typeof folder !== 'undefined') ? '/' + folder : '';
    var fs = require('fs'),
        SCRIPTS_DIST_DIR = 'dist/scripts',
        IMAGE_DIST_DIR = 'dist/images' + folder,
        oldestImage = imageTarget
    ;

    fs.readdirSync(SCRIPTS_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(filename) !== (-1) ) {
        filename = SCRIPTS_DIST_DIR+'/'+file;
      }
    });

    fs.readdirSync(IMAGE_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(oldestImage) !== (-1) ) {
        imageTarget = file;
      }
    });

    var data = fs.readFileSync(filename, 'utf8');
    data = data.replace(new RegExp(oldestImage, 'g'), imageTarget);

    fs.writeFileSync(filename, data, 'utf8');

  });

  grunt.registerTask('modifyImageLinkInStyles', 'Task for replace image link in stylesheet file.', function(filename, imageTarget) {
    var fs = require('fs'),
        STYLES_DIST_DIR = 'dist/styles',
        IMAGE_DIST_DIR = 'dist/images',
        oldestImage = imageTarget
    ;

    fs.readdirSync(STYLES_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(filename) !== (-1) ) {
        filename = STYLES_DIST_DIR+'/'+file;
      }
    });

    fs.readdirSync(IMAGE_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(oldestImage) !== (-1) ) {
        imageTarget = file;
      }
    });

    var data = fs.readFileSync(filename, 'utf8');
    data = data.replace(new RegExp(oldestImage, 'g'), imageTarget);

    fs.writeFileSync(filename, data, 'utf8');

  });

  grunt.registerTask('modifyImageLinkInHtml', 'Task for replace image link in html files.', function(filename, folder, imageTarget) {
    folder = (typeof folder !== 'undefined') ? '/' + folder : '';
    var fs = require('fs'),
        HTML_DIST_DIR = 'dist/',
        IMAGE_DIST_DIR = 'dist/images' + folder,
        oldestImage = imageTarget
    ;

    fs.readdirSync(HTML_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(filename) !== (-1) ) {
        filename = HTML_DIST_DIR+'/'+file;
      }
    });

    fs.readdirSync(IMAGE_DIST_DIR).forEach(function(file) {
      if ( file.indexOf(oldestImage) !== (-1) ) {
        imageTarget = file;
      }
    });

    var data = fs.readFileSync(filename, 'utf8');
    data = data.replace(new RegExp(oldestImage, 'g'), imageTarget);

    fs.writeFileSync(filename, data, 'utf8');

  });

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

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

  grunt.registerTask('server', function () {
    grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
    grunt.task.run(['serve']);
  });

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

  // var pages = [
  //   'index.html',
  //   'programacao.html',
  //   'videos.html',
  //   'codigo-de-conduta.html',
  //   'eventos-anteriores.html'
  // ];

  // var pagesLength = pages.length;

  var gruntBuildTasks = [
    'jshint:all',
    //'htmllint:app',
    'clean:dist',
    'bower-install',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer:dist',
    'concat',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'rev',
    'usemin',
    'htmlmin',

    'modifyImageLinkInScript:scripts.js:pin.png',
    'modifyImageLinkInScript:scripts.js:a-confirmar.jpg:talks',
    'modifyImageLinkInScript:scripts.js:achilles-froes.jpeg:talks',
    'modifyImageLinkInScript:scripts.js:guilherme-motta.jpg:talks',
    'modifyImageLinkInScript:scripts.js:juliano-ribeiro.jpg:talks',
    'modifyImageLinkInScript:scripts.js:luciano-borges.jpg:talks',
    'modifyImageLinkInScript:scripts.js:marcio-albuquerque.jpg:talks',
    'modifyImageLinkInScript:scripts.js:mauricio-vieira.jpg:talks',
    'modifyImageLinkInScript:scripts.js:morvana-bonin.jpg:talks',
    'modifyImageLinkInScript:scripts.js:otavio-santana.jpg:talks',
    'modifyImageLinkInScript:scripts.js:rafael-helm.jpeg:talks',
    'modifyImageLinkInScript:scripts.js:rafael-miranda.png:talks',

    'modifyImageLinkInStyles:main.css:home-background.jpg'
  ];

  grunt.registerTask('build', gruntBuildTasks);

  grunt.registerTask('default', [
    'newer:jshint',
    'test',
    'build'
  ]);

  grunt.registerTask('travis', [
    'bower-install',
    'jshint',
    'build',
    'htmllint:dist'
  ]);

  grunt.registerTask('deploy', [
    'travis',
    'rsync:prod'
  ]);

};
<|endoftext|>


<commit_before>var Developers = require('./controllers/developers');
var Joi = require('hapi/node_modules/joi');

var routes = [];

// Create the routes for the api
// Test route for route
routes.push({
	method: 'GET',
	path: '/',
	config : {
		handler: function (request, reply) {
			reply('Hello World!');
		}

	}
});

// Routes for the users

// List all the users in the developers table or by search query
routes.push({
	method: 'GET',
	path: '/developers',
	config : {
		handler: Developers.list
		}
});

// List developer by parameter id
// # 'hostname/developers/id'
routes.push({
	method: 'GET',
	path: '/developers/{id}',
	config : {
		handler: Developers.show,
		validate: {
			params: {
				id: Joi.number().integer().min(1)
			}
		}
	}
});

// Add user to the Developers table
routes.push({
	method: 'POST',
	path: '/developers',
	config : {
		handler: Developers.create
	}
});

module.exports = routes;<commit_msg>clean up some comments<commit_after>var Developers = require('./controllers/developers');
var Joi = require('hapi/node_modules/joi');

var routes = [];

// Create the routes for the api
// Test route for route
routes.push({
	method: 'GET',
	path: '/',
	config : {
		handler: function (request, reply) {
			reply('Hello World!');
		}

	}
});

// Routes for the users

// List all the users in the developers table or by search query
routes.push({
	method: 'GET',
	path: '/developers',
	config : {
		handler: Developers.list
		}
});

// List developer by id parameter
routes.push({
	method: 'GET',
	path: '/developers/{id}',
	config : {
		handler: Developers.show,
		validate: {
			params: {
				id: Joi.number().integer().min(1)
			}
		}
	}
});

// Add user to the Developers table
routes.push({
	method: 'POST',
	path: '/developers',
	config : {
		handler: Developers.create
	}
});

module.exports = routes;<|endoftext|>


<commit_before>app.get('/HV', function(req, res){
	res.render('widgets/HV.jade');
});

app.get('/GRIFFIN', function(req, res){
	res.render('detectors/GRIFFIN.jade');
});

app.post('/postHV', function(req, res){

	spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Variables/Demand["+req.body.chIndex+"] " + req.body.demandVoltage]);
	spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Up Speed["+req.body.chIndex+"] " + req.body.voltageUp]);
	spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Down Speed["+req.body.chIndex+"] " + req.body.voltageDown]);

/*
	var ls = spawn('ls', ['-lh', '/usr']);
	ls.stdout.on('data', function(data){
		console.log('stdout: ' + data);
	})
*/
	//var cmdString;

	//cmdString = '?cmd=jset&odb=/Equipment/HV-'+req.body.crateIndex+'/Variables/Demand['+req.body.chIndex+']'
	//cmdString += '&value='+req.body.demandVoltage

	//console.log(cmdString)

	return res.redirect('/HV');
});<commit_msg>routing HV controls to HV<commit_after>app.get('/HV', function(req, res){
	res.render('widgets/HV.jade');
});

app.get('/GRIFFIN', function(req, res){
	res.render('detectors/GRIFFIN.jade');
});

app.post('/postHV', function(req, res){

	spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Variables/Demand["+req.body.chIndex+"] " + req.body.demandVoltage]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Up Speed["+req.body.chIndex+"]' " + req.body.voltageUp]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Down Speed["+req.body.chIndex+"]' " + req.body.voltageDown]);

/*
	var ls = spawn('ls', ['-lh', '/usr']);
	ls.stdout.on('data', function(data){
		console.log('stdout: ' + data);
	})
*/
	//var cmdString;

	//cmdString = '?cmd=jset&odb=/Equipment/HV-'+req.body.crateIndex+'/Variables/Demand['+req.body.chIndex+']'
	//cmdString += '&value='+req.body.demandVoltage

	//console.log(cmdString)

	return res.redirect('/HV');
});<|endoftext|>