<commit_before>/*
 * Copyright 2013, All Rights Reserved.
 *
 * Code licensed under the BSD License:
 * https://github.com/eduardolundgren/dotfiles/blob/master/LICENSE.md
 *
 * @author Eduardo Lundgren <eduardo.lundgren@gmail.com>
 */

'use strict';

var userhome = require('userhome');

var choicesDock = require('./templates/.osx-dock');
var choicesFinder = require('./templates/.osx-finder');
var choicesGeneral = require('./templates/.osx-general');
var choicesIterm = require('./templates/.osx-iterm');
var choicesTrackpad = require('./templates/.osx-trackpad');

function copyConfigChoicesAsBooleans(config, choices, from, to) {
    choices.forEach(function(choice) {
        config[to][choice.value] =
            config.choices[from].indexOf(choice.value) > -1;
    });
}

module.exports = function(grunt) {

    grunt.initConfig({

        // -- Bump -------------------------------------------------------------

        bump: {

            options: {
                commit: true,
                commitFiles: ['package.json'],
                commitMessage: 'Release v%VERSION%',
                createTag: true,
                files: ['package.json'],
                push: true,
                pushTo: 'origin',
                tagMessage: '',
                tagName: 'v%VERSION%'
            }

        },

        // -- Config -----------------------------------------------------------

        config: {

            aliases: {
                path_aliases: userhome('.dotfiles/.aliases')
            },

            git: {
                path_gitconfig: userhome('.dotfiles/.gitconfig'),
                path_gitconfig_system: userhome('.gitconfig'),
                path_gitignore: userhome('.dotfiles/.gitignore_global'),
                path_gitignore_system: userhome('.gitignore_global')
            },

            osx: {
                path_osx: userhome('.dotfiles/.osx')
            },

            ruby: {
                path_build: userhome('.dotfiles/.rbenv/plugins/ruby-build'),
                path_rbenv: userhome('.dotfiles/.rbenv'),
                path_rbenv_system: userhome('.rbenv')
            },

            themes: {
                path_dracula: userhome('.dotfiles/themes/dracula'),
            },

            z: {
                path_z_system: userhome('.z')
            },

            zsh: {
                path_oh_my_zsh: userhome('.dotfiles/.oh-my-zsh'),
                path_plugin_syntax: userhome('.dotfiles/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting'),
                path_theme_dracula: userhome('.dotfiles/.oh-my-zsh/themes/dracula.zsh-theme'),
                path_zshrc: userhome('.dotfiles/.zshrc'),
                path_zshrc_system: userhome('.zshrc')
            }

        },

        // -- Prompt -----------------------------------------------------------

        prompt: {

            config: {
                options: {
                    questions: [
                        {
                            config: 'config.osx.computername',
                            default: 'eduardo',
                            message: 'Which computer name would you like to use?'
                        },
                        {
                            config: 'config.git.name',
                            default: 'Eduardo Lundgren',
                            message: 'Which Git name would you like to use?'
                        },
                        {
                            config: 'config.git.email',
                            default: 'eduardo.lundgren@liferay.com',
                            message: 'Which Git email would you like to use?'
                        },
                        {
                            config: 'config.editor',
                            default: 'subl',
                            message: 'Which editor would you like to use?'
                        },
                        {
                            config: 'config.zsh.plugins',
                            default: 'ant git history-substring-search z zsh-syntax-highlighting',
                            message: 'Which Oh My Zsh plugins would you like to use?'
                        },
                        {
                            config: 'config.zsh.theme_oh_my_zsh',
                            default: 'dracula',
                            message: 'Which Oh My Zsh theme would you like to use?'
                        },
                        {
                            choices: choicesGeneral,
                            config: 'config.choices.general',
                            message: 'Which OSX general options would you like to use?',
                            type: 'checkbox'
                        },
                        {
                            choices: choicesDock,
                            config: 'config.choices.dock',
                            message: 'Which Dock options would you like to use?',
                            type: 'checkbox'
                        },
                        {
                            choices: choicesFinder,
                            config: 'config.choices.finder',
                            message: 'Which Finder options would you like to use?',
                            type: 'checkbox'
                        },
                        {
                            choices: choicesIterm,
                            config: 'config.choices.iterm',
                            message: 'Which iTerm options would you like to use?',
                            type: 'checkbox'
                        },
                        {
                            choices: choicesTrackpad,
                            config: 'config.choices.trackpad',
                            message: 'Which Trackpad options would you like to use?',
                            type: 'checkbox'
                        }
                    ]
                }
            }

        },

        // -- Clean ------------------------------------------------------------

        clean: {

            all: {
                options: {
                    force: true
                },
                src: [
                    userhome('.dotfiles'),
                    '<%= config.ruby.path_rbenv_system %>',
                    '<%= config.z.path_z_system %>',
                    '<%= config.zsh.path_zshrc_system %>'
                ]
            }

        },

        // -- Templates --------------------------------------------------------

        template: {

            aliases: {
                options: {
                    data: '<%= config %>'
                },
                files: {
                    '<%= config.aliases.path_aliases %>': ['templates/.aliases']
                }
            },

            git: {
                options: {
                    data: '<%= config %>'
                },
                files: {
                    '<%= config.git.path_gitconfig %>': ['templates/.gitconfig'],
                    '<%= config.git.path_gitignore %>': ['templates/.gitignore_global']
                }
            },

            osx: {
                options: {
                    data: function() {
                        var config = grunt.config.data.config;
                        copyConfigChoicesAsBooleans(config, choicesDock, 'dock', 'osx');
                        copyConfigChoicesAsBooleans(config, choicesFinder, 'finder', 'osx');
                        copyConfigChoicesAsBooleans(config, choicesGeneral, 'general', 'osx');
                        copyConfigChoicesAsBooleans(config, choicesIterm, 'iterm', 'osx');
                        copyConfigChoicesAsBooleans(config, choicesTrackpad, 'trackpad', 'osx');
                        return config;
                    }
                },
                files: {
                    '<%= config.osx.path_osx %>': ['templates/.osx']
                }
            },

            zsh: {
                options: {
                    data: '<%= config %>'
                },
                files: {
                    '<%= config.zsh.path_zshrc %>': ['templates/.zshrc']
                }
            }

        },

        // -- Git --------------------------------------------------------------

        gitclone: {

            ruby_rbenv: {
                options: {
                    directory: '<%= config.ruby.path_rbenv %>',
                    repository: 'https://github.com/sstephenson/rbenv.git'
                }
            },

            ruby_build: {
                options: {
                    directory: '<%= config.ruby.path_build %>',
                    repository: 'https://github.com/sstephenson/ruby-build.git'
                }
            },

            oh_my_zsh: {
                options: {
                    directory: '<%= config.zsh.path_oh_my_zsh %>',
                    repository: 'https://github.com/robbyrussell/oh-my-zsh.git'
                }
            },

            theme_dracula: {
                options: {
                    directory: '<%= config.themes.path_dracula %>',
                    repository: 'https://github.com/zenorocha/dracula-theme.git'
                }
            },

            zsh_syntax_highlighting: {
                options: {
                    directory: '<%= config.zsh.path_plugin_syntax %>',
                    repository: 'https://github.com/zsh-users/zsh-syntax-highlighting.git'
                }
            }

        },

        // -- Symbolic links ---------------------------------------------------

        symlink: {

            git_config: {
                dest: '<%= config.git.path_gitconfig_system %>',
                relativeSrc: '<%= config.git.path_gitconfig %>'
            },

            git_ignore: {
                dest: '<%= config.git.path_gitignore_system %>',
                relativeSrc: '<%= config.git.path_gitignore %>'
            },

            ruby: {
                dest: '<%= config.ruby.path_rbenv_system %>',
                relativeSrc: '<%= config.ruby.path_rbenv %>'
            },

            sublime: {
                dest: '/usr/local/bin/subl',
                relativeSrc: '/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl'
            },

            zsh: {
                dest: '<%= config.zsh.path_zshrc_system %>',
                relativeSrc: '<%= config.zsh.path_zshrc %>'
            },

            zsh_theme_dracula: {
                dest: '<%= config.zsh.path_theme_dracula %>',
                relativeSrc: '<%= config.themes.path_dracula %>/zsh/dracula.zsh-theme'
            }

        },

        // -- Exec -------------------------------------------------------------

        shell: {

            osx: {
                command: 'source <%= config.osx.path_osx %>',
                options: {
                    stdout: true
                }
            },

            z: {
                command: 'touch <%= config.z.path_z_system %>',
                options: {
                    stdout: true
                }
            },

            zsh: {
                command: 'chsh -s /bin/zsh',
                options: {
                    stdout: true
                }
            },

            theme_alfred: {
                command: 'open <%= config.themes.path_dracula %>/alfred/Dracula.alfredappearance'
            },

            theme_iterm: {
                command: 'open <%= config.themes.path_dracula %>/iterm/Dracula.itermcolors'
            },

            node_latest: {
                command: 'sudo n latest',
                options: {
                    stdout: true
                }
            },

            node_stable: {
                command: 'sudo n stable',
                options: {
                    stdout: true
                }
            },

            ruby_compass: {
                command: 'sudo gem install compass',
                options: {
                    stdout: true
                }
            },

            ruby_jekyll: {
                command: 'sudo gem install jekyll',
                options: {
                    stdout: true
                }
            },

            ruby_update: {
                command: 'sudo gem update --system',
                options: {
                    stdout: true
                }
            },

            brew: {
                command: 'ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)"',
                options: {
                    stdout: true
                }
            },

            brew_tig: {
                command: 'brew install tig'
            }

        }

    });

    grunt.task.registerTask('banner', function() {
        console.log(grunt.file.read('templates/.banner'));
    });

    grunt.loadNpmTasks('grunt-bump');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-git');
    grunt.loadNpmTasks('grunt-prompt');
    grunt.loadNpmTasks('grunt-shell');
    grunt.loadNpmTasks('grunt-symlink');
    grunt.loadNpmTasks('grunt-template');

    grunt.registerTask('setup', ['banner', 'prompt', 'clean', 'template', 'gitclone', 'shell', 'symlink']);

};<commit_msg>Add stderr to grunt shell tasks<commit_after>/*
 * Copyright 2013, All Rights Reserved.
 *
 * Code licensed under the BSD License:
 * https://github.com/eduardolundgren/dotfiles/blob/master/LICENSE.md
 *
 * @author Eduardo Lundgren <eduardo.lundgren@gmail.com>
 */

'use strict';

var userhome = require('userhome');

var choicesDock = require('./templates/.osx-dock');
var choicesFinder = require('./templates/.osx-finder');
var choicesGeneral = require('./templates/.osx-general');
var choicesIterm = require('./templates/.osx-iterm');
var choicesTrackpad = require('./templates/.osx-trackpad');

function copyConfigChoicesAsBooleans(config, choices, from, to) {
    choices.forEach(function(choice) {
        config[to][choice.value] =
            config.choices[from].indexOf(choice.value) > -1;
    });
}

module.exports = function(grunt) {

    grunt.initConfig({

        // -- Bump -------------------------------------------------------------

        bump: {

            options: {
                commit: true,
                commitFiles: ['package.json'],
                commitMessage: 'Release v%VERSION%',
                createTag: true,
                files: ['package.json'],
                push: true,
                pushTo: 'origin',
                tagMessage: '',
                tagName: 'v%VERSION%'
            }

        },

        // -- Config -----------------------------------------------------------

        config: {

            aliases: {
                path_aliases: userhome('.dotfiles/.aliases')
            },

            git: {
                path_gitconfig: userhome('.dotfiles/.gitconfig'),
                path_gitconfig_system: userhome('.gitconfig'),
                path_gitignore: userhome('.dotfiles/.gitignore_global'),
                path_gitignore_system: userhome('.gitignore_global')
            },

            osx: {
                path_osx: userhome('.dotfiles/.osx')
            },

            ruby: {
                path_build: userhome('.dotfiles/.rbenv/plugins/ruby-build'),
                path_rbenv: userhome('.dotfiles/.rbenv'),
                path_rbenv_system: userhome('.rbenv')
            },

            themes: {
                path_dracula: userhome('.dotfiles/themes/dracula'),
            },

            z: {
                path_z_system: userhome('.z')
            },

            zsh: {
                path_oh_my_zsh: userhome('.dotfiles/.oh-my-zsh'),
                path_plugin_syntax: userhome('.dotfiles/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting'),
                path_theme_dracula: userhome('.dotfiles/.oh-my-zsh/themes/dracula.zsh-theme'),
                path_zshrc: userhome('.dotfiles/.zshrc'),
                path_zshrc_system: userhome('.zshrc')
            }

        },

        // -- Prompt -----------------------------------------------------------

        prompt: {

            config: {
                options: {
                    questions: [
                        {
                            config: 'config.osx.computername',
                            default: 'eduardo',
                            message: 'Which computer name would you like to use?'
                        },
                        {
                            config: 'config.git.name',
                            default: 'Eduardo Lundgren',
                            message: 'Which Git name would you like to use?'
                        },
                        {
                            config: 'config.git.email',
                            default: 'eduardo.lundgren@liferay.com',
                            message: 'Which Git email would you like to use?'
                        },
                        {
                            config: 'config.editor',
                            default: 'subl',
                            message: 'Which editor would you like to use?'
                        },
                        {
                            config: 'config.zsh.plugins',
                            default: 'ant git history-substring-search z zsh-syntax-highlighting',
                            message: 'Which Oh My Zsh plugins would you like to use?'
                        },
                        {
                            config: 'config.zsh.theme_oh_my_zsh',
                            default: 'dracula',
                            message: 'Which Oh My Zsh theme would you like to use?'
                        },
                        {
                            choices: choicesGeneral,
                            config: 'config.choices.general',
                            message: 'Which OSX general options would you like to use?',
                            type: 'checkbox'
                        },
                        {
                            choices: choicesDock,
                            config: 'config.choices.dock',
                            message: 'Which Dock options would you like to use?',
                            type: 'checkbox'
                        },
                        {
                            choices: choicesFinder,
                            config: 'config.choices.finder',
                            message: 'Which Finder options would you like to use?',
                            type: 'checkbox'
                        },
                        {
                            choices: choicesIterm,
                            config: 'config.choices.iterm',
                            message: 'Which iTerm options would you like to use?',
                            type: 'checkbox'
                        },
                        {
                            choices: choicesTrackpad,
                            config: 'config.choices.trackpad',
                            message: 'Which Trackpad options would you like to use?',
                            type: 'checkbox'
                        }
                    ]
                }
            }

        },

        // -- Clean ------------------------------------------------------------

        clean: {

            all: {
                options: {
                    force: true
                },
                src: [
                    userhome('.dotfiles'),
                    '<%= config.ruby.path_rbenv_system %>',
                    '<%= config.z.path_z_system %>',
                    '<%= config.zsh.path_zshrc_system %>'
                ]
            }

        },

        // -- Templates --------------------------------------------------------

        template: {

            aliases: {
                options: {
                    data: '<%= config %>'
                },
                files: {
                    '<%= config.aliases.path_aliases %>': ['templates/.aliases']
                }
            },

            git: {
                options: {
                    data: '<%= config %>'
                },
                files: {
                    '<%= config.git.path_gitconfig %>': ['templates/.gitconfig'],
                    '<%= config.git.path_gitignore %>': ['templates/.gitignore_global']
                }
            },

            osx: {
                options: {
                    data: function() {
                        var config = grunt.config.data.config;
                        copyConfigChoicesAsBooleans(config, choicesDock, 'dock', 'osx');
                        copyConfigChoicesAsBooleans(config, choicesFinder, 'finder', 'osx');
                        copyConfigChoicesAsBooleans(config, choicesGeneral, 'general', 'osx');
                        copyConfigChoicesAsBooleans(config, choicesIterm, 'iterm', 'osx');
                        copyConfigChoicesAsBooleans(config, choicesTrackpad, 'trackpad', 'osx');
                        return config;
                    }
                },
                files: {
                    '<%= config.osx.path_osx %>': ['templates/.osx']
                }
            },

            zsh: {
                options: {
                    data: '<%= config %>'
                },
                files: {
                    '<%= config.zsh.path_zshrc %>': ['templates/.zshrc']
                }
            }

        },

        // -- Git --------------------------------------------------------------

        gitclone: {

            ruby_rbenv: {
                options: {
                    directory: '<%= config.ruby.path_rbenv %>',
                    repository: 'https://github.com/sstephenson/rbenv.git'
                }
            },

            ruby_build: {
                options: {
                    directory: '<%= config.ruby.path_build %>',
                    repository: 'https://github.com/sstephenson/ruby-build.git'
                }
            },

            oh_my_zsh: {
                options: {
                    directory: '<%= config.zsh.path_oh_my_zsh %>',
                    repository: 'https://github.com/robbyrussell/oh-my-zsh.git'
                }
            },

            theme_dracula: {
                options: {
                    directory: '<%= config.themes.path_dracula %>',
                    repository: 'https://github.com/zenorocha/dracula-theme.git'
                }
            },

            zsh_syntax_highlighting: {
                options: {
                    directory: '<%= config.zsh.path_plugin_syntax %>',
                    repository: 'https://github.com/zsh-users/zsh-syntax-highlighting.git'
                }
            }

        },

        // -- Symbolic links ---------------------------------------------------

        symlink: {

            git_config: {
                dest: '<%= config.git.path_gitconfig_system %>',
                relativeSrc: '<%= config.git.path_gitconfig %>'
            },

            git_ignore: {
                dest: '<%= config.git.path_gitignore_system %>',
                relativeSrc: '<%= config.git.path_gitignore %>'
            },

            ruby: {
                dest: '<%= config.ruby.path_rbenv_system %>',
                relativeSrc: '<%= config.ruby.path_rbenv %>'
            },

            sublime: {
                dest: '/usr/local/bin/subl',
                relativeSrc: '/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl'
            },

            zsh: {
                dest: '<%= config.zsh.path_zshrc_system %>',
                relativeSrc: '<%= config.zsh.path_zshrc %>'
            },

            zsh_theme_dracula: {
                dest: '<%= config.zsh.path_theme_dracula %>',
                relativeSrc: '<%= config.themes.path_dracula %>/zsh/dracula.zsh-theme'
            }

        },

        // -- Exec -------------------------------------------------------------

        shell: {

            osx: {
                command: 'source <%= config.osx.path_osx %>',
                options: {
                    stdout: true,
                    stderr: true
                }
            },

            z: {
                command: 'touch <%= config.z.path_z_system %>',
                options: {
                    stdout: true,
                    stderr: true
                }
            },

            zsh: {
                command: 'chsh -s /bin/zsh',
                options: {
                    stdout: true,
                    stderr: true
                }
            },

            theme_alfred: {
                command: 'open <%= config.themes.path_dracula %>/alfred/Dracula.alfredappearance'
            },

            theme_iterm: {
                command: 'open <%= config.themes.path_dracula %>/iterm/Dracula.itermcolors'
            },

            node_latest: {
                command: 'sudo n latest',
                options: {
                    stdout: true,
                    stderr: true
                }
            },

            node_stable: {
                command: 'sudo n stable',
                options: {
                    stdout: true,
                    stderr: true
                }
            },

            ruby_compass: {
                command: 'sudo gem install compass',
                options: {
                    stdout: true,
                    stderr: true
                }
            },

            ruby_jekyll: {
                command: 'sudo gem install jekyll',
                options: {
                    stdout: true,
                    stderr: true
                }
            },

            ruby_update: {
                command: 'sudo gem update --system',
                options: {
                    stdout: true,
                    stderr: true
                }
            },

            brew: {
                command: 'ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)"',
                options: {
                    stdout: true,
                    stderr: true
                }
            },

            brew_tig: {
                command: 'brew install tig'
            }

        }

    });

    grunt.task.registerTask('banner', function() {
        console.log(grunt.file.read('templates/.banner'));
    });

    grunt.loadNpmTasks('grunt-bump');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-git');
    grunt.loadNpmTasks('grunt-prompt');
    grunt.loadNpmTasks('grunt-shell');
    grunt.loadNpmTasks('grunt-symlink');
    grunt.loadNpmTasks('grunt-template');

    grunt.registerTask('setup', ['banner', 'prompt', 'clean', 'template', 'gitclone', 'shell', 'symlink']);

};<|endoftext|>


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

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      // define the files to lint

      web: {
        files: {
          //src: ['public/js/*.js']
        },
        options: {
          browser: true,
          devel: true,
          strict: true,
          jquery: true,
          unused: true,
          trailing: true,
          undef: true
        }
      },
      lib: {
        files: {
          src: ['lib/**/*.js']
        },
        options: {
          node: true,
          curly: true,
          quotmark: 'single',
          //unused: true,
          trailing: true,
          strict: true,
          undef: true
        }
      },
      test: {
        files: {
          src: ['test/**/*.js']
        },
        options: {
          node: true,
          curly: true,
          quotmark: 'single',
          undef: false,
          trailing: true,
          //strict: true
        }
      },
      gruntfile: {
        files: {
          src: ['Gruntfile.js']
        }
      },
    },
    // Configure a mochaTest task
    mochaTest: {
      test: {
        options: {
          reporter: 'list',
          require: 'coverage/blanket'
        },
        src: ['test/**/*.js']
      },
      coverage: {
        options: {
          reporter: 'html-cov',
          // use the quiet flag to suppress the mocha console output
          quiet: true
        },
        src: ['test/**/*.js'],
        // specify a destination file to capture the mocha
        // output (the quiet option does not suppress this)
        dest: 'coverage.html'
      }
    },

    watch: {
      gruntfile: {
        files: 'Gruntfile.js' ,
        tasks: ['jshint:gruntfile']
      },
      lib: {
        files: ['lib/**/*.js','bin/*','test/**/*.js'],
        tasks: ['test']
      },
      web: {
        files: ['public/js/*.js'],
        tasks: ['test']
      },
      options: {
        nospawn: false
      }
    },
    docco: {
      docs: {
        src: ['lib/**/*.js'],
        options: {
          output: 'docs/annotated-source'
        }
      }
    },
    htmllint: {
        all: ["public/index.html"]
    }
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.loadNpmTasks('grunt-release');
  grunt.loadNpmTasks('grunt-docco2');
  grunt.loadNpmTasks('grunt-html');

  grunt.registerTask('test', ['jshint','mochaTest']);

  // Default task(s).
  grunt.registerTask('default', ['jshint']);

};
<commit_msg>remove html-lint and docco from Gruntfile<commit_after>module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      // define the files to lint

      web: {
        files: {
          //src: ['public/js/*.js']
        },
        options: {
          browser: true,
          devel: true,
          strict: true,
          jquery: true,
          unused: true,
          trailing: true,
          undef: true
        }
      },
      lib: {
        files: {
          src: ['lib/**/*.js']
        },
        options: {
          node: true,
          curly: true,
          quotmark: 'single',
          //unused: true,
          trailing: true,
          strict: true,
          undef: true
        }
      },
      test: {
        files: {
          src: ['test/**/*.js']
        },
        options: {
          node: true,
          curly: true,
          quotmark: 'single',
          undef: false,
          trailing: true,
          //strict: true
        }
      },
      gruntfile: {
        files: {
          src: ['Gruntfile.js']
        }
      },
    },
    // Configure a mochaTest task
    mochaTest: {
      test: {
        options: {
          reporter: 'list',
        },
        src: ['test/**/*.js']
      }
    },

    watch: {
      gruntfile: {
        files: 'Gruntfile.js' ,
        tasks: ['jshint:gruntfile']
      },
      lib: {
        files: ['lib/**/*.js','bin/*','test/**/*.js'],
        tasks: ['test']
      },
      web: {
        files: ['public/js/*.js'],
        tasks: ['test']
      },
      options: {
        nospawn: false
      }
    },
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.loadNpmTasks('grunt-release');

  grunt.registerTask('test', ['jshint','mochaTest']);

  // Default task(s).
  grunt.registerTask('default', ['jshint']);

};
<|endoftext|>


<commit_before>// Copyright 2016, University of Colorado Boulder

/**
 * Node representing the biker in the view.
 *
 * @author John Blanco
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // Modules
  var Biker = require( 'ENERGY_FORMS_AND_CHANGES/energy-systems/model/Biker' );
  var Dimension2 = require( 'DOT/Dimension2' );
  var EFACBaseNode = require( 'ENERGY_FORMS_AND_CHANGES/energy-systems/view/EFACBaseNode' );
  var EFACConstants = require( 'ENERGY_FORMS_AND_CHANGES/common/EFACConstants' );
  var EFACModelImageNode = require( 'ENERGY_FORMS_AND_CHANGES/energy-systems/view/EFACModelImageNode' );
  var energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );
  var HSlider = require( 'SUN/HSlider' );
  // var Image = require( 'SCENERY/nodes/Image' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Panel = require( 'SUN/Panel' );

  /**
   * @param {Biker} biker EnergySource
   * @param {Property<boolean>} energyChunksVisible
   * @param {ModelViewTransform2} modelViewTransform
   * @constructor
   */
  function BikerNode( biker, energyChunksVisible, modelViewTransform ) {

    // Add args to constructor as needed
    EFACBaseNode.call( this, biker, modelViewTransform );

    var spokesImage = new EFACModelImageNode( Biker.REAR_WHEEL_SPOKES_IMAGE, modelViewTransform );
    var backLegRootNode = new Node();
    var frontLegRootNode = new Node();
    var backLegImageNodes = [];
    var frontLegImageNodes = [];

    for ( var i = 0; i < Biker.NUM_LEG_IMAGES; i++ ) {
      // Back leg image nodes
      backLegImageNodes.push( new EFACModelImageNode( Biker.BACK_LEG_IMAGES[ i ], modelViewTransform ) );
      backLegImageNodes[ i ].setVisible( false );
      backLegRootNode.addChild( backLegImageNodes[ i ] );

      // Front leg image nodes
      frontLegImageNodes.push( new EFACModelImageNode( Biker.FRONT_LEG_IMAGES[ i ], modelViewTransform ) );
      frontLegImageNodes[ i ].setVisible( false );
      frontLegRootNode.addChild( frontLegImageNodes[ i ] );
    }

    var upperBodyNormal = new EFACModelImageNode( Biker.RIDER_NORMAL_UPPER_BODY_IMAGE, modelViewTransform );
    var upperBodyTired = new EFACModelImageNode( Biker.RIDER_TIRED_UPPER_BODY_IMAGE, modelViewTransform );

    // Animate legs by setting image visibility based on crank arm angle
    var visibleBackLeg = backLegImageNodes[ 0 ];
    var visibleFrontLeg = frontLegImageNodes[ 0 ];
    biker.crankAngleProperty.link( function( angle ) {
      assert && assert( angle >= 0 && angle <= 2 * Math.PI, 'Angle out of range: ' + angle );
      var i = biker.mapAngleToImageIndex( angle );
      visibleFrontLeg.setVisible( false );
      visibleBackLeg.setVisible( false );
      visibleFrontLeg = frontLegImageNodes[ i ];
      visibleBackLeg = backLegImageNodes[ i ];
      visibleFrontLeg.setVisible( true );
      visibleBackLeg.setVisible( true );
    } );

    // TODO "feed me" button

    biker.bikerHasEnergyProperty.link( function( hasEnergy ) {
      // feedMeButton.setVisible(!hasEnergy);
      upperBodyNormal.setVisible( hasEnergy );
      upperBodyTired.setVisible( !hasEnergy );
    } );

    // Add and observer that will turn the back wheel.
    var wheelRotationPoint = spokesImage.bounds.center;
    biker.rearWheelAngleProperty.link( function( angle ) {
      assert && assert( angle < 2 * Math.PI, 'Angle is out of bounds' );
      // Scenery doesn't use the convention in physics where a
      // positive rotation is counter-clockwise, so we have to
      // invert the angle in the following calculation.
      var compensatedAngle = ( 2 * Math.PI - spokesImage.getRotation() ) % ( 2 * Math.PI );
      var delta = angle - compensatedAngle;
      spokesImage.rotateAround( wheelRotationPoint, -delta );
    } );

    // final Point2D wheelRotationPoint = new Point2D.Double( spokesImage.getFullBoundsReference().getCenterX(),
    // biker.getRearWheelAngle().addObserver( new VoidFunction1 < Double > () {
    //   public void apply( Double angle ) {
    //     assert angle < 2 * Math.PI; // Limit this to one rotation.
    //     double compensatedAngle = ( 2 * Math.PI - spokesImage.getRotation() ) % ( 2 * Math.PI );
    //     double delta = angle - compensatedAngle;
    //     spokesImage.rotateAboutPoint( -delta, wheelRotationPoint );
    //   }
    // } );

    // Slider to control crank speed
    // TODO: these numeric literals are brittle. Ask about correct way to control positions.
    var crankSlider = new HSlider( biker.targetCrankAngularVelocityProperty, {
      min: 0,
      max: Biker.MAX_ANGULAR_VELOCITY_OF_CRANK
    }, {
      trackSize: new Dimension2( 200, 5 ),
      thumbSize: new Dimension2( 20, 40 ) // Default: ( 22, 45 )
    } );

    this.addChild( new Panel( crankSlider, {
      fill: EFACConstants.CONTROL_PANEL_BACKGROUND_COLOR,
      centerX: 0,
      centerY: 110,
      cornerRadius: 8,
      resize: false
    } ) );

    this.addChild( spokesImage );
    this.addChild( backLegRootNode );
    this.addChild( new EFACModelImageNode( Biker.FRAME_IMAGE, modelViewTransform ) );
    this.addChild( frontLegRootNode );
    this.addChild( upperBodyNormal );
    this.addChild( upperBodyTired );

  }

  energyFormsAndChanges.register( 'BikerNode', BikerNode );

  return inherit( EFACBaseNode, BikerNode );
} );
<commit_msg>Remove commented code<commit_after>// Copyright 2016, University of Colorado Boulder

/**
 * Node representing the biker in the view.
 *
 * @author John Blanco
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // Modules
  var Biker = require( 'ENERGY_FORMS_AND_CHANGES/energy-systems/model/Biker' );
  var Dimension2 = require( 'DOT/Dimension2' );
  var EFACBaseNode = require( 'ENERGY_FORMS_AND_CHANGES/energy-systems/view/EFACBaseNode' );
  var EFACConstants = require( 'ENERGY_FORMS_AND_CHANGES/common/EFACConstants' );
  var EFACModelImageNode = require( 'ENERGY_FORMS_AND_CHANGES/energy-systems/view/EFACModelImageNode' );
  var energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );
  var HSlider = require( 'SUN/HSlider' );
  // var Image = require( 'SCENERY/nodes/Image' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Panel = require( 'SUN/Panel' );

  /**
   * @param {Biker} biker EnergySource
   * @param {Property<boolean>} energyChunksVisible
   * @param {ModelViewTransform2} modelViewTransform
   * @constructor
   */
  function BikerNode( biker, energyChunksVisible, modelViewTransform ) {

    // Add args to constructor as needed
    EFACBaseNode.call( this, biker, modelViewTransform );

    var spokesImage = new EFACModelImageNode( Biker.REAR_WHEEL_SPOKES_IMAGE, modelViewTransform );
    var backLegRootNode = new Node();
    var frontLegRootNode = new Node();
    var backLegImageNodes = [];
    var frontLegImageNodes = [];

    for ( var i = 0; i < Biker.NUM_LEG_IMAGES; i++ ) {
      // Back leg image nodes
      backLegImageNodes.push( new EFACModelImageNode( Biker.BACK_LEG_IMAGES[ i ], modelViewTransform ) );
      backLegImageNodes[ i ].setVisible( false );
      backLegRootNode.addChild( backLegImageNodes[ i ] );

      // Front leg image nodes
      frontLegImageNodes.push( new EFACModelImageNode( Biker.FRONT_LEG_IMAGES[ i ], modelViewTransform ) );
      frontLegImageNodes[ i ].setVisible( false );
      frontLegRootNode.addChild( frontLegImageNodes[ i ] );
    }

    var upperBodyNormal = new EFACModelImageNode( Biker.RIDER_NORMAL_UPPER_BODY_IMAGE, modelViewTransform );
    var upperBodyTired = new EFACModelImageNode( Biker.RIDER_TIRED_UPPER_BODY_IMAGE, modelViewTransform );

    // Animate legs by setting image visibility based on crank arm angle
    var visibleBackLeg = backLegImageNodes[ 0 ];
    var visibleFrontLeg = frontLegImageNodes[ 0 ];
    biker.crankAngleProperty.link( function( angle ) {
      assert && assert( angle >= 0 && angle <= 2 * Math.PI, 'Angle out of range: ' + angle );
      var i = biker.mapAngleToImageIndex( angle );
      visibleFrontLeg.setVisible( false );
      visibleBackLeg.setVisible( false );
      visibleFrontLeg = frontLegImageNodes[ i ];
      visibleBackLeg = backLegImageNodes[ i ];
      visibleFrontLeg.setVisible( true );
      visibleBackLeg.setVisible( true );
    } );

    // TODO "feed me" button

    biker.bikerHasEnergyProperty.link( function( hasEnergy ) {
      // feedMeButton.setVisible(!hasEnergy);
      upperBodyNormal.setVisible( hasEnergy );
      upperBodyTired.setVisible( !hasEnergy );
    } );

    // Add and observer that will turn the back wheel.
    var wheelRotationPoint = spokesImage.bounds.center;
    biker.rearWheelAngleProperty.link( function( angle ) {
      assert && assert( angle < 2 * Math.PI, 'Angle is out of bounds' );
      // Scenery doesn't use the convention in physics where a
      // positive rotation is counter-clockwise, so we have to
      // invert the angle in the following calculation.
      var compensatedAngle = ( 2 * Math.PI - spokesImage.getRotation() ) % ( 2 * Math.PI );
      var delta = angle - compensatedAngle;
      spokesImage.rotateAround( wheelRotationPoint, -delta );
    } );

    // Slider to control crank speed
    // TODO: these numeric literals are brittle. Ask about correct way to control positions.
    var crankSlider = new HSlider( biker.targetCrankAngularVelocityProperty, {
      min: 0,
      max: Biker.MAX_ANGULAR_VELOCITY_OF_CRANK
    }, {
      trackSize: new Dimension2( 200, 5 ),
      thumbSize: new Dimension2( 20, 40 ) // Default: ( 22, 45 )
    } );

    this.addChild( new Panel( crankSlider, {
      fill: EFACConstants.CONTROL_PANEL_BACKGROUND_COLOR,
      centerX: 0,
      centerY: 110,
      cornerRadius: 8,
      resize: false
    } ) );

    this.addChild( spokesImage );
    this.addChild( backLegRootNode );
    this.addChild( new EFACModelImageNode( Biker.FRAME_IMAGE, modelViewTransform ) );
    this.addChild( frontLegRootNode );
    this.addChild( upperBodyNormal );
    this.addChild( upperBodyTired );
  }

  energyFormsAndChanges.register( 'BikerNode', BikerNode );

  return inherit( EFACBaseNode, BikerNode );
} );
<|endoftext|>


<commit_before>export { Base };

import * as Pool from "../../util/Pool.js";
import * as Recyclable from "../../util/Recyclable.js";
import * as MultiLayerMap from "../../util/MultiLayerMap.js";
import * as FloatValue from "../../Unpacker/FloatValue.js";
import * as ValueDesc from "../../Unpacker/ValueDesc.js";
import * as NumberImage from "./NumberImage.js";

/**
 * Dynamically create random image data with specified channelCount, depthwise_AvgMax_Or_ChannelMultiplier, depthwiseFilterHeight,
 * depthwiseFilterWidth, depthwiseStridesPad. The same image data will be returned when same specification is requested. So that
 * the testing performance could be improved.
 */
class Base extends Recyclable.Root {

  /**
   * Used as default ImageSourceBag.Base provider for conforming to Recyclable interface.
   */
  static Pool = new Pool.Root( "ImageSourceBag.Base.Pool", Base, Base.setAsConstructor );

  /**
   */
  constructor() {
    super();
    Base.setAsConstructor_self.call( this );
  }

  /** @override */
  static setAsConstructor() {
    super.setAsConstructor();
    Base.setAsConstructor_self.call( this );
    return this;
  }

  /** @override */
  static setAsConstructor_self() {
    // Images indexed by [ originalHeight, originalWidth, channelCount, filterHeight, filterWidth, stridesPad ].

    if ( !this.images )
      this.images = new MultiLayerMap.Base();

    if ( !this.tensors )
      this.tensors = new MultiLayerMap.Base();
  }

  /** @override */
  disposeResources() {

    {
      for ( let tensor of this.tensors.values() ) {
        tensor.dispose();
      }
      this.tensors.clear();
    }

    {
      for ( let numberImage of this.images.values() ) {
        numberImage.disposeResources_and_recycleToPool();
      }
      this.images.clear();
    }

    super.disposeResources();
  }

  /** @override */
  clear() {
    for ( let channelShuffler of this.values() ) {
      channelShuffler.disposeResources_and_recycleToPool();
    }
    super.clear();
  }

  /**
   * If ( depthwiseFilterHeight == 1 ) and ( depthwiseFilterWidth == 1 ) and ( depthwiseStridesPad == 0 ), the original image will be
   * returned. The original image has the size ( originalHeight, originalWidth, channelCount ). Its value is generated randomly.
   *
   *
   * @param {number} originalHeight
   *   A positive integer which represents the returned image's original height.
   *
   * @param {number} originalWidth
   *   A positive integer which represents the returned image's original width.
   *
   * @param {number} channelCount
   *   A positive integer which represents the returned image's depth.
   *
   * @param {number} depthwise_AvgMax_Or_ChannelMultiplier
   *   An integer represents the returned image should be the original image processed by depthwise convolution filter of this kinds.
   * Its should be in the range of ValueDesc.AvgMax_Or_ChannelMultiplier.Singleton.range.
   *
   * @param {number} depthwiseFilterHeight
   *   An integer represents the returned image should be the original image processed by depthwise convolution filter of this height.
   * Its should be in the range of Block.Params.depthwiseFilterHeight.valueDesc.range.
   *
   * @param {number} depthwiseFilterWidth
   *   An integer represents the returned image should be the original image processed by depthwise convolution filter of this width.
   * Its should be in the range of Block.Params.depthwiseFilterWidth.valueDesc.range.
   *
   * @param {number} depthwiseStridesPad
   *   An integer represents the returned image should be the original image processed by depthwise convolution of this strides and pad.
   * Its should be in the range of ValueDesc.depthwiseStridesPad.Singleton.range.
   *
   * @return {NumberImage.Base}
   *   Return an image data with the specified specification.
   */
  getImage_by(
    originalHeight, originalWidth, channelCount,
    depthwise_AvgMax_Or_ChannelMultiplier = 0, depthwiseFilterHeight = 1, depthwiseFilterWidth = 1, depthwiseStridesPad = 0 ) {

    // 1. When no depthwise operation, the original image is returned directly (i.e. will not be shrinked).
    //
    // Because there is not depthwise operation, there is not possible to shrink.
    if ( depthwise_AvgMax_Or_ChannelMultiplier == ValueDesc.AvgMax_Or_ChannelMultiplier.Singleton.Ids.NONE ) {
      let originalImage = Base.internal_getImage_by.call( this, originalHeight, originalWidth, channelCount );
      return originalImage;
    }

    // 2. Otherwise, return image which is adjusted by depthwise operation.
    let image = Base.internal_getImage_by.call( this,
      originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad );

    return image;
  }

  /**
   *
   * @return {tf.tensor3d}
   *   Return a tensor with the specified specification.
   */
  getTensor3d_by(
    originalHeight, originalWidth, channelCount,
    depthwise_AvgMax_Or_ChannelMultiplier = 0, depthwiseFilterHeight = 1, depthwiseFilterWidth = 1, depthwiseStridesPad = 0 ) {

    // 1. When no depthwise operation, the original image's tensor is returned directly (i.e. will not be shrinked).
    //
    // Because there is not depthwise operation, there is not possible to shrink.
    if ( depthwise_AvgMax_Or_ChannelMultiplier == ValueDesc.AvgMax_Or_ChannelMultiplier.Singleton.Ids.NONE ) {
      let originalTensor = Base.internal_getTensor3d_by.call( this, originalHeight, originalWidth, channelCount );
      return originalTensor;
    }

    // 2. Otherwise, return image tensor which is adjusted by depthwise operation.
    let tensor = Base.internal_getTensor3d_by.call( this,
      originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad );
    return tensor;
  }

  /**
   * Similiar to this.getImage_by() but does not consider depthwise_AvgMax_Or_ChannelMultiplier.
   */
  static internal_getImage_by(
    originalHeight, originalWidth, channelCount, depthwiseFilterHeight = 1, depthwiseFilterWidth = 1, depthwiseStridesPad = 0 ) {

    return this.images.get_or_create_by_arguments1_etc( Base.image_createBy, this,
      originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad );
  }

  /** Called when the requested image has not yet existed. */
  static image_createBy(
    originalHeight, originalWidth, channelCount, depthwiseFilterHeight = 1, depthwiseFilterWidth = 1, depthwiseStridesPad = 0 ) {

    let image;

    // 1. The original image is requested.
    if ( ( depthwiseFilterHeight == 1 ) && ( depthwiseFilterWidth == 1 ) && ( depthwiseStridesPad == 0 ) ) {

      //!!! (2022/04/21 Remarked) Using Weights.Base.ValueBounds is more like real use case.
      let bAutoBounds = true;  // Image pixel channel value bounds are inside the real generated value bounds.
      //!!! (2022/07/13 Remarked) Using small ValueBounds may reduce floating-point accumulated error.
      //let bAutoBounds = false; // Image pixel channel value bounds are inside the default value bounds (i.e. Weights.Base.ValueBounds).
      image = NumberImage.Base.create_bySequenceRandom( originalHeight, originalWidth, channelCount,
        Base.weightsRandomOffset.min, Base.weightsRandomOffset.max, bAutoBounds );

    // 2. The shrinked image requested.
    } else {

      // Use original image to create shrinked image.
      let originalImage = Base.internal_getImage_by.call( this, originalHeight, originalWidth, channelCount );

      // Borrow the clone_byDepthwise() function to create an input image which is shrinked by specified filter size and strides and pad.
      image = originalImage.clone_byDepthwise_NonPassThrough(
        ValueDesc.AvgMax_Or_ChannelMultiplier.Singleton.Ids.MAX, // Max Pooling is faster and without filter weights.
        depthwiseFilterHeight, depthwiseFilterWidth,
        depthwiseStridesPad,
        null, false,  // depthwiseFiltersArray, bDepthwiseBias,
        null, ValueDesc.ActivationFunction.Singleton.Ids.NONE, // depthwiseBiasesArray, depthwiseActivationId,
        "", "ImageSourceBag.Base.internal_getImage_by()"
      );
    }

    return image;
  }

  /**
   * Similiar to this.getTensor3d_by() but does not consider depthwise_AvgMax_Or_ChannelMultiplier.
   */
  static internal_getTensor3d_by(
    originalHeight, originalWidth, channelCount, depthwiseFilterHeight = 1, depthwiseFilterWidth = 1, depthwiseStridesPad = 0 ) {

    return this.tensors.get_or_create_by_arguments1_etc( Base.tensor_createBy, this,
      originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad );
  }

  /** Called when the requested tensor has not yet existed. */
  static tensor_createBy(
    originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad ) {

    let image = Base.internal_getImage_by.call( this,
      originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad );

    let shape = [ image.height, image.width, image.depth ];
    let tensor = tf.tensor3d( image.dataArray, shape ); // Create new tensor of specified specification.
    return tensor;
  }

}

//!!! (2022/07/14 Temp Remarked) Fixed to non-random to simplify debug.
Base.weightsRandomOffset = { min: -200, max: +200 };
//Base.weightsRandomOffset = { min: -0, max: +0 };
<commit_msg>Fix Base.weightsRandomOffset<commit_after>export { Base };

import * as Pool from "../../util/Pool.js";
import * as Recyclable from "../../util/Recyclable.js";
import * as MultiLayerMap from "../../util/MultiLayerMap.js";
import * as FloatValue from "../../Unpacker/FloatValue.js";
import * as ValueDesc from "../../Unpacker/ValueDesc.js";
import * as NumberImage from "./NumberImage.js";

/**
 * Dynamically create random image data with specified channelCount, depthwise_AvgMax_Or_ChannelMultiplier, depthwiseFilterHeight,
 * depthwiseFilterWidth, depthwiseStridesPad. The same image data will be returned when same specification is requested. So that
 * the testing performance could be improved.
 */
class Base extends Recyclable.Root {

  /**
   * Used as default ImageSourceBag.Base provider for conforming to Recyclable interface.
   */
  static Pool = new Pool.Root( "ImageSourceBag.Base.Pool", Base, Base.setAsConstructor );

  /**
   */
  constructor() {
    super();
    Base.setAsConstructor_self.call( this );
  }

  /** @override */
  static setAsConstructor() {
    super.setAsConstructor();
    Base.setAsConstructor_self.call( this );
    return this;
  }

  /** @override */
  static setAsConstructor_self() {
    // Images indexed by [ originalHeight, originalWidth, channelCount, filterHeight, filterWidth, stridesPad ].

    if ( !this.images )
      this.images = new MultiLayerMap.Base();

    if ( !this.tensors )
      this.tensors = new MultiLayerMap.Base();
  }

  /** @override */
  disposeResources() {

    {
      for ( let tensor of this.tensors.values() ) {
        tensor.dispose();
      }
      this.tensors.clear();
    }

    {
      for ( let numberImage of this.images.values() ) {
        numberImage.disposeResources_and_recycleToPool();
      }
      this.images.clear();
    }

    super.disposeResources();
  }

  /** @override */
  clear() {
    for ( let channelShuffler of this.values() ) {
      channelShuffler.disposeResources_and_recycleToPool();
    }
    super.clear();
  }

  /**
   * If ( depthwiseFilterHeight == 1 ) and ( depthwiseFilterWidth == 1 ) and ( depthwiseStridesPad == 0 ), the original image will be
   * returned. The original image has the size ( originalHeight, originalWidth, channelCount ). Its value is generated randomly.
   *
   *
   * @param {number} originalHeight
   *   A positive integer which represents the returned image's original height.
   *
   * @param {number} originalWidth
   *   A positive integer which represents the returned image's original width.
   *
   * @param {number} channelCount
   *   A positive integer which represents the returned image's depth.
   *
   * @param {number} depthwise_AvgMax_Or_ChannelMultiplier
   *   An integer represents the returned image should be the original image processed by depthwise convolution filter of this kinds.
   * Its should be in the range of ValueDesc.AvgMax_Or_ChannelMultiplier.Singleton.range.
   *
   * @param {number} depthwiseFilterHeight
   *   An integer represents the returned image should be the original image processed by depthwise convolution filter of this height.
   * Its should be in the range of Block.Params.depthwiseFilterHeight.valueDesc.range.
   *
   * @param {number} depthwiseFilterWidth
   *   An integer represents the returned image should be the original image processed by depthwise convolution filter of this width.
   * Its should be in the range of Block.Params.depthwiseFilterWidth.valueDesc.range.
   *
   * @param {number} depthwiseStridesPad
   *   An integer represents the returned image should be the original image processed by depthwise convolution of this strides and pad.
   * Its should be in the range of ValueDesc.depthwiseStridesPad.Singleton.range.
   *
   * @return {NumberImage.Base}
   *   Return an image data with the specified specification.
   */
  getImage_by(
    originalHeight, originalWidth, channelCount,
    depthwise_AvgMax_Or_ChannelMultiplier = 0, depthwiseFilterHeight = 1, depthwiseFilterWidth = 1, depthwiseStridesPad = 0 ) {

    // 1. When no depthwise operation, the original image is returned directly (i.e. will not be shrinked).
    //
    // Because there is not depthwise operation, there is not possible to shrink.
    if ( depthwise_AvgMax_Or_ChannelMultiplier == ValueDesc.AvgMax_Or_ChannelMultiplier.Singleton.Ids.NONE ) {
      let originalImage = Base.internal_getImage_by.call( this, originalHeight, originalWidth, channelCount );
      return originalImage;
    }

    // 2. Otherwise, return image which is adjusted by depthwise operation.
    let image = Base.internal_getImage_by.call( this,
      originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad );

    return image;
  }

  /**
   *
   * @return {tf.tensor3d}
   *   Return a tensor with the specified specification.
   */
  getTensor3d_by(
    originalHeight, originalWidth, channelCount,
    depthwise_AvgMax_Or_ChannelMultiplier = 0, depthwiseFilterHeight = 1, depthwiseFilterWidth = 1, depthwiseStridesPad = 0 ) {

    // 1. When no depthwise operation, the original image's tensor is returned directly (i.e. will not be shrinked).
    //
    // Because there is not depthwise operation, there is not possible to shrink.
    if ( depthwise_AvgMax_Or_ChannelMultiplier == ValueDesc.AvgMax_Or_ChannelMultiplier.Singleton.Ids.NONE ) {
      let originalTensor = Base.internal_getTensor3d_by.call( this, originalHeight, originalWidth, channelCount );
      return originalTensor;
    }

    // 2. Otherwise, return image tensor which is adjusted by depthwise operation.
    let tensor = Base.internal_getTensor3d_by.call( this,
      originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad );
    return tensor;
  }

  /**
   * Similiar to this.getImage_by() but does not consider depthwise_AvgMax_Or_ChannelMultiplier.
   */
  static internal_getImage_by(
    originalHeight, originalWidth, channelCount, depthwiseFilterHeight = 1, depthwiseFilterWidth = 1, depthwiseStridesPad = 0 ) {

    return this.images.get_or_create_by_arguments1_etc( Base.image_createBy, this,
      originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad );
  }

  /** Called when the requested image has not yet existed. */
  static image_createBy(
    originalHeight, originalWidth, channelCount, depthwiseFilterHeight = 1, depthwiseFilterWidth = 1, depthwiseStridesPad = 0 ) {

    let image;

    // 1. The original image is requested.
    if ( ( depthwiseFilterHeight == 1 ) && ( depthwiseFilterWidth == 1 ) && ( depthwiseStridesPad == 0 ) ) {

      //!!! (2022/04/21 Remarked) Using Weights.Base.ValueBounds is more like real use case.
      let bAutoBounds = true;  // Image pixel channel value bounds are inside the real generated value bounds.
      //!!! (2022/07/13 Remarked) Using small ValueBounds may reduce floating-point accumulated error.
      //let bAutoBounds = false; // Image pixel channel value bounds are inside the default value bounds (i.e. Weights.Base.ValueBounds).
      image = NumberImage.Base.create_bySequenceRandom( originalHeight, originalWidth, channelCount,
        Base.weightsRandomOffset.min, Base.weightsRandomOffset.max, bAutoBounds );

    // 2. The shrinked image requested.
    } else {

      // Use original image to create shrinked image.
      let originalImage = Base.internal_getImage_by.call( this, originalHeight, originalWidth, channelCount );

      // Borrow the clone_byDepthwise() function to create an input image which is shrinked by specified filter size and strides and pad.
      image = originalImage.clone_byDepthwise_NonPassThrough(
        ValueDesc.AvgMax_Or_ChannelMultiplier.Singleton.Ids.MAX, // Max Pooling is faster and without filter weights.
        depthwiseFilterHeight, depthwiseFilterWidth,
        depthwiseStridesPad,
        null, false,  // depthwiseFiltersArray, bDepthwiseBias,
        null, ValueDesc.ActivationFunction.Singleton.Ids.NONE, // depthwiseBiasesArray, depthwiseActivationId,
        "", "ImageSourceBag.Base.internal_getImage_by()"
      );
    }

    return image;
  }

  /**
   * Similiar to this.getTensor3d_by() but does not consider depthwise_AvgMax_Or_ChannelMultiplier.
   */
  static internal_getTensor3d_by(
    originalHeight, originalWidth, channelCount, depthwiseFilterHeight = 1, depthwiseFilterWidth = 1, depthwiseStridesPad = 0 ) {

    return this.tensors.get_or_create_by_arguments1_etc( Base.tensor_createBy, this,
      originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad );
  }

  /** Called when the requested tensor has not yet existed. */
  static tensor_createBy(
    originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad ) {

    let image = Base.internal_getImage_by.call( this,
      originalHeight, originalWidth, channelCount, depthwiseFilterHeight, depthwiseFilterWidth, depthwiseStridesPad );

    let shape = [ image.height, image.width, image.depth ];
    let tensor = tf.tensor3d( image.dataArray, shape ); // Create new tensor of specified specification.
    return tensor;
  }

}

//!!! (2022/07/14 Temp Remarked) Fixed to non-random to simplify debug.
//Base.weightsRandomOffset = { min: -200, max: +200 };
Base.weightsRandomOffset = { min: -0, max: +0 };
<|endoftext|>


<commit_before>var dgraphLive  = require('./index'),
    DGraph      = require('dgraph').Graph,
    assert      = require('assert'),
    path        = require('path'),
    touch       = require('touch'),
    aggregate   = require('stream-aggregate-promise');

function fixture(filename) {
  return path.resolve(path.join(__dirname, 'fixtures', filename));
}

function bundle(graph) {
  return aggregate(graph.toStream());
}

describe('dgraph-live', function() {

  it('watches for changes in graph and emits "update" event', function(done) {
    var graph = dgraphLive(new DGraph(fixture('foo.js')));
    bundle(graph).then(function(mods) {
      assert.equal(mods.length, 3);
      assert.equal(Object.keys(graph.watching).length, 3);
      touch(fixture('bar.js'));
    }).fail(done);

    graph.on('update', function(id, when) {
      assert.equal(id, fixture('bar.js'));
      bundle(graph).then(function(mods) {
        graph.close();
        assert.equal(mods.length, 3);
        done();
      }).fail(done);
    });
  });

  it('watches for changes in entry and emits "update" event', function(done) {
    var graph = dgraphLive(new DGraph(fixture('foo.js')));
    bundle(graph).then(function(mods) {
      assert.equal(mods.length, 3);
      assert.equal(Object.keys(graph.watching).length, 3);
      touch(fixture('foo.js'));
    }).fail(done);

    graph.on('update', function(id, when) {
      assert.equal(id, fixture('foo.js'));
      bundle(graph).then(function(bundle) {
        graph.close();
        assert.equal(bundle.length, 3);
        done();
      }).fail(done);
    });
  });

});
<commit_msg>Check more in specs<commit_after>var dgraphLive  = require('./index'),
    DGraph      = require('dgraph').Graph,
    assert      = require('assert'),
    path        = require('path'),
    touch       = require('touch'),
    aggregate   = require('stream-aggregate-promise');

function fixture(filename) {
  return path.resolve(path.join(__dirname, 'fixtures', filename));
}

function bundle(graph) {
  return aggregate(graph.toStream());
}

describe('dgraph-live', function() {

  it('watches for changes in graph and emits "update" event', function(done) {
    var graph = dgraphLive(new DGraph(fixture('foo.js')));
    bundle(graph).then(function(mods) {
      assert.equal(mods.length, 3);
      assert.equal(Object.keys(graph.watching).length, 3);
      touch(fixture('bar.js'));
    }).fail(done);

    graph.on('update', function(id, when) {
      assert.equal(id, fixture('bar.js'));
      bundle(graph).then(function(mods) {
        assert.equal(Object.keys(graph.watching).length, 3);
        graph.close();
        assert.equal(mods.length, 3);
        done();
      }).fail(done);
    });
  });

  it('watches for changes in entry and emits "update" event', function(done) {
    var graph = dgraphLive(new DGraph(fixture('foo.js')));
    bundle(graph).then(function(mods) {
      assert.equal(mods.length, 3);
      assert.equal(Object.keys(graph.watching).length, 3);
      touch(fixture('foo.js'));
    }).fail(done);

    graph.on('update', function(id, when) {
      assert.equal(id, fixture('foo.js'));
      bundle(graph).then(function(bundle) {
        assert.equal(Object.keys(graph.watching).length, 3);
        graph.close();
        assert.equal(bundle.length, 3);
        done();
      }).fail(done);
    });
  });

});
<|endoftext|>


<commit_before>module.exports = function(grunt) {
  //--------------------------------------------------
  //------------Project config------------------------
  //--------------------------------------------------
  var pkg = grunt.file.readJSON('package.json');
  grunt.initConfig({
    // Metadata.
    pkg: pkg,
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Released under the <%= pkg.license %> License */\n',
    // Task configuration.
    peg: {
      parser: {
        src: 'src/dust.pegjs',
        dest: 'lib/parser.js',
        options: {
          wrapper: function(src, parser) {
            var buildMsg = 'Do not edit this file directly. It is automatically generated from src/dust.pegjs';
            var wrapper = grunt.file.read("src/umdParserWrapper.js").replace('@@build', buildMsg).split('@@parser');
            return wrapper[0] + parser + wrapper[1];
          }
        }
      }
    },
    execute: {
      testRhino: {
        src: 'node_modules/.bin/rhino*',
        options: {
          args: ['-f', 'test/rhino.spec.js']
        }
      },
      buildParser: {
        src: 'src/build.js'
      }
    },
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      core: {
        src: ['lib/dust.js', 'src/amd-core.js'],
        dest: 'tmp/dust-core.js'
      },
      full: {
        src: ['lib/dust.js', 'lib/parser.js', 'lib/compiler.js', 'src/amd-full.js'],
        dest: 'tmp/dust-full.js'
      }
    },
    copy: {
      core: {
        src: 'tmp/dust-core.js',
        dest: 'dist/dust-core.js'
      },
      coreMin: {
        src: 'tmp/dust-core.min.js',
        dest: 'dist/dust-core.min.js'
      },
      full: {
        src: 'tmp/dust-full.js',
        dest: 'dist/dust-full.js'
      },
      fullMin: {
        src: 'tmp/dust-full.min.js',
        dest: 'dist/dust-full.min.js'
      },
      license: {
        src: 'LICENSE',
        dest: 'dist/'
      }
    },
    uglify: {
      options: {
        banner: '<%= banner %>',
        mangle: {
          except: ['require', 'define', 'module', 'dust']
        }
      },
      core: {
        src: '<%= concat.core.dest %>',
        dest: 'tmp/dust-core.min.js'
      },
      full: {
        src: '<%= concat.full.dest %>',
        dest: 'tmp/dust-full.min.js'
      }
    },
    clean: {
      build: ['tmp/*'],
      dist: ['dist/*']
    },
    jshint: {
      options: {
        jshintrc: true
      },
      gruntfile: {
        src: 'Gruntfile.js'
      },
      libs: {
        src: ['lib/**/*.js', '!lib/parser.js'] // don't hint the parser which is autogenerated from pegjs
      }
    },
    connect: {
     testServer: {
       options: {
         port: 3000,
         keepalive: false
       }
     }
    },
    'saucelabs-jasmine': {
      all: {
        options: {
          urls: ["http://localhost:3000/_SpecRunner.html"],
          build: process.env.TRAVIS_JOB_ID,
          throttled: 3,
          testname: 'core',
          browsers: [
            {browserName: 'chrome'},
            {browserName: 'firefox'},
            {browserName: 'safari', version: 7, platform: 'OS X 10.9'},
            {browserName: 'safari', version: 6, platform: 'OS X 10.8'},
            {browserName: 'internet explorer', version: 11, platform: 'Windows 8.1'},
            {browserName: 'internet explorer', version: 10, platform: 'Windows 8'},
            {browserName: 'internet explorer', version: 9, platform: 'Windows 7'},
            {browserName: 'internet explorer', version: 8, platform: 'Windows 7'}
          ],
          sauceConfig: {
            'video-upload-on-pass': false
          }
        }
      }
    },
    jasmine: {
      options: {
        outfile: 'index.html',
        display: 'short',
        specs: ['test/templates/all.js', 'test/helpers/template.helper.js', 'test/templates.spec.js'],
        vendor: ['node_modules/ayepromise/ayepromise.js', 'test/lib/highland.js', 'test/lib/jsreporter.js']
      },
      /*tests production (minified) code*/
      testProd: {
        src: 'tmp/dust-full.min.js'
      },
      /*tests unminified code, mostly used for debugging by `grunt dev` task*/
      testDev : {
        src: 'tmp/dust-full.js'
      },
      /*runs unit tests with jasmine and collects test coverage info via istanbul template
      * tests unminified version of dust to make sure test coverage starts are correctly calculated
      * istanbul jumbles source code in order to record coverage, so this task is not suited for
      * debugging while developing. Use jasmine:testClient instead, which runs on unminified code
      * and can be easily debugged*/
      coverage : {
        src: 'tmp/dust-full.js',
        options: {
          display: 'none',
          template: require('grunt-template-jasmine-istanbul'),
          templateOptions: {
            coverage: 'tmp/coverage/coverage.json',
            report: 'tmp/coverage',
            thresholds: {
              lines: 82,
              statements: 82,
              branches: 70,
              functions: 85
            }
          }
        }
      }
    },
    jasmine_nodejs: {
      options: {
        useHelpers: true,
        reporters: {
          console: {
            colors: false,
            verbosity: 0
          }
        }
      },
      core: {
        specs: ['test/core.spec.js']
      },
      cjs: {
        specs: ['test/commonJS.spec.js']
      },
      dustc: {
        helpers: ['test/cli/matchers.helper.js'],
        specs: ['test/cli/*']
      },
      templates: {
        specs: ['test/templates.spec.js']
      }
    },
    watch: {
      lib: {
        files: ['<%= jshint.libs.src %>'],
        tasks: ['clean:build', 'buildLib']
      },
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },
      lib_test: {
        files: ['<%= jshint.libs.src %>', '<%= jasmine.options.specs %>'],
        tasks: ['testPhantom']
      }
    },
    bump: {
      options: {
        files: ['package.json', 'bower.json', 'lib/dust.js'],
        updateConfigs: ['pkg'],
        push: false,
        commitFiles: ['-a']
      }
    },
    log: {
      coverage: {
        options: {
          message: 'Open <%=jasmine.coverage.options.templateOptions.report%>/index.html in a browser to view the coverage.'
        }
      },
      copyForRelease: {
        options: {
          message: 'OK. Done copying version <%= pkg.version %> build from tmp to dist'
        }
      },
      release: {
        options: {
          message: ['OK. Done bumping, adding, committing, tagging and pushing the new version',
                    '',
                    'You still need to manually do the following:',
                    '  * git push upstream && git push upstream --tags',
                    '  * npm publish'].join('\n')
        }
      }
    },
    githubChanges: {
      dist: {
        options: {
          owner: "linkedin",
          repository: "dustjs",
          tagName: "v<%= pkg.version %>",
          onlyPulls: true,
          useCommitBody: true,
          auth: true
        }
      }
    }
  });

  //--------------------------------------------------
  //------------Custom tasks -------------------------
  //--------------------------------------------------
  grunt.registerMultiTask('log', 'Print some messages', function() {
    grunt.log.ok(this.data.options.message);
  });

  //--------------------------------------------------
  //------------External tasks -----------------------
  //--------------------------------------------------
  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-bump');
  grunt.loadNpmTasks('grunt-execute');
  grunt.loadNpmTasks('grunt-peg');
  grunt.loadNpmTasks('grunt-jasmine-nodejs');
  grunt.loadNpmTasks('grunt-github-changes');
  grunt.loadNpmTasks('grunt-saucelabs');

  //--------------------------------------------------
  //------------Grunt task aliases -------------------
  //--------------------------------------------------
  grunt.registerTask('buildLib',       ['jshint:libs', 'concat']);
  grunt.registerTask('build',          ['clean:build', 'peg', 'buildLib', 'uglify']);

  //test tasks
  grunt.registerTask('testNode',       ['jasmine_nodejs:templates', 'jasmine_nodejs:core', 'jasmine_nodejs:cjs']);
  grunt.registerTask('testRhino',      ['build', 'execute:testRhino']);
  grunt.registerTask('testPhantom',    ['build', 'jasmine:testProd']);
  grunt.registerTask('testCli',        ['jasmine_nodejs:dustc']);
  grunt.registerTask('test',           ['build', 'jasmine:testProd', 'testCli', 'testNode', 'execute:testRhino', 'jasmine:coverage']);

  //sauce labs integration (browser testing)
  grunt.registerTask('sauce',          process.env.SAUCE_ACCESS_KEY ? ['jasmine:testProd:build', 'connect:testServer', 'saucelabs-jasmine'] : []);

  //decide whether to run all tests or just the Node tests for Travis CI
  grunt.registerTask('travis',         (process.env.TEST === 'all') ? ['test', 'sauce'] : ['testNode', 'testCli']);

  //task for debugging in browser
  grunt.registerTask('dev',            ['build', 'jasmine:testDev:build', 'connect:testServer', 'watch:lib']);

  //task to run unit tests on client against prod version of code
  grunt.registerTask('testClient',     ['build', 'jasmine:testProd:build', 'connect:testServer', 'watch:lib_test']);

  //coverage report
  grunt.registerTask('coverage',       ['build', 'jasmine:coverage', 'log:coverage']);

  //release tasks
  grunt.registerTask('copyForRelease', ['clean:dist', 'copy', 'log:copyForRelease']);
  grunt.registerTask('buildRelease',   ['test', 'githubChanges', 'copyForRelease']);
  grunt.registerTask('releasePatch',   ['bump-only:patch', 'buildRelease', 'bump-commit', 'log:release']);
  grunt.registerTask('releaseMinor',   ['bump-only:minor', 'buildRelease', 'bump-commit', 'log:release']);
  // major release should probably be done with care
  //grunt.registerTask('releaseMajor',   ['bump-only:major', 'buildRelease', 'bump-commit:major', 'log:release']);

  //default task - full test
  grunt.registerTask('default',        ['test']);
};
<commit_msg>Update test runner URL for Sauce integration<commit_after>module.exports = function(grunt) {
  //--------------------------------------------------
  //------------Project config------------------------
  //--------------------------------------------------
  var pkg = grunt.file.readJSON('package.json');
  grunt.initConfig({
    // Metadata.
    pkg: pkg,
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Released under the <%= pkg.license %> License */\n',
    // Task configuration.
    peg: {
      parser: {
        src: 'src/dust.pegjs',
        dest: 'lib/parser.js',
        options: {
          wrapper: function(src, parser) {
            var buildMsg = 'Do not edit this file directly. It is automatically generated from src/dust.pegjs';
            var wrapper = grunt.file.read("src/umdParserWrapper.js").replace('@@build', buildMsg).split('@@parser');
            return wrapper[0] + parser + wrapper[1];
          }
        }
      }
    },
    execute: {
      testRhino: {
        src: 'node_modules/.bin/rhino*',
        options: {
          args: ['-f', 'test/rhino.spec.js']
        }
      },
      buildParser: {
        src: 'src/build.js'
      }
    },
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      core: {
        src: ['lib/dust.js', 'src/amd-core.js'],
        dest: 'tmp/dust-core.js'
      },
      full: {
        src: ['lib/dust.js', 'lib/parser.js', 'lib/compiler.js', 'src/amd-full.js'],
        dest: 'tmp/dust-full.js'
      }
    },
    copy: {
      core: {
        src: 'tmp/dust-core.js',
        dest: 'dist/dust-core.js'
      },
      coreMin: {
        src: 'tmp/dust-core.min.js',
        dest: 'dist/dust-core.min.js'
      },
      full: {
        src: 'tmp/dust-full.js',
        dest: 'dist/dust-full.js'
      },
      fullMin: {
        src: 'tmp/dust-full.min.js',
        dest: 'dist/dust-full.min.js'
      },
      license: {
        src: 'LICENSE',
        dest: 'dist/'
      }
    },
    uglify: {
      options: {
        banner: '<%= banner %>',
        mangle: {
          except: ['require', 'define', 'module', 'dust']
        }
      },
      core: {
        src: '<%= concat.core.dest %>',
        dest: 'tmp/dust-core.min.js'
      },
      full: {
        src: '<%= concat.full.dest %>',
        dest: 'tmp/dust-full.min.js'
      }
    },
    clean: {
      build: ['tmp/*'],
      dist: ['dist/*']
    },
    jshint: {
      options: {
        jshintrc: true
      },
      gruntfile: {
        src: 'Gruntfile.js'
      },
      libs: {
        src: ['lib/**/*.js', '!lib/parser.js'] // don't hint the parser which is autogenerated from pegjs
      }
    },
    connect: {
     testServer: {
       options: {
         port: 3000,
         keepalive: false
       }
     }
    },
    'saucelabs-jasmine': {
      all: {
        options: {
          urls: ["http://localhost:3000/"],
          build: process.env.TRAVIS_JOB_ID,
          throttled: 3,
          testname: 'core',
          browsers: [
            {browserName: 'chrome'},
            {browserName: 'firefox'},
            {browserName: 'safari', version: 7, platform: 'OS X 10.9'},
            {browserName: 'safari', version: 6, platform: 'OS X 10.8'},
            {browserName: 'internet explorer', version: 11, platform: 'Windows 8.1'},
            {browserName: 'internet explorer', version: 10, platform: 'Windows 8'},
            {browserName: 'internet explorer', version: 9, platform: 'Windows 7'},
            {browserName: 'internet explorer', version: 8, platform: 'Windows 7'}
          ],
          sauceConfig: {
            'video-upload-on-pass': false
          }
        }
      }
    },
    jasmine: {
      options: {
        outfile: 'index.html',
        display: 'short',
        specs: ['test/templates/all.js', 'test/helpers/template.helper.js', 'test/templates.spec.js'],
        vendor: ['node_modules/ayepromise/ayepromise.js', 'test/lib/highland.js', 'test/lib/jsreporter.js']
      },
      /*tests production (minified) code*/
      testProd: {
        src: 'tmp/dust-full.min.js'
      },
      /*tests unminified code, mostly used for debugging by `grunt dev` task*/
      testDev : {
        src: 'tmp/dust-full.js'
      },
      /*runs unit tests with jasmine and collects test coverage info via istanbul template
      * tests unminified version of dust to make sure test coverage starts are correctly calculated
      * istanbul jumbles source code in order to record coverage, so this task is not suited for
      * debugging while developing. Use jasmine:testClient instead, which runs on unminified code
      * and can be easily debugged*/
      coverage : {
        src: 'tmp/dust-full.js',
        options: {
          display: 'none',
          template: require('grunt-template-jasmine-istanbul'),
          templateOptions: {
            coverage: 'tmp/coverage/coverage.json',
            report: 'tmp/coverage',
            thresholds: {
              lines: 82,
              statements: 82,
              branches: 70,
              functions: 85
            }
          }
        }
      }
    },
    jasmine_nodejs: {
      options: {
        useHelpers: true,
        reporters: {
          console: {
            colors: false,
            verbosity: 0
          }
        }
      },
      core: {
        specs: ['test/core.spec.js']
      },
      cjs: {
        specs: ['test/commonJS.spec.js']
      },
      dustc: {
        helpers: ['test/cli/matchers.helper.js'],
        specs: ['test/cli/*']
      },
      templates: {
        specs: ['test/templates.spec.js']
      }
    },
    watch: {
      lib: {
        files: ['<%= jshint.libs.src %>'],
        tasks: ['clean:build', 'buildLib']
      },
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },
      lib_test: {
        files: ['<%= jshint.libs.src %>', '<%= jasmine.options.specs %>'],
        tasks: ['testPhantom']
      }
    },
    bump: {
      options: {
        files: ['package.json', 'bower.json', 'lib/dust.js'],
        updateConfigs: ['pkg'],
        push: false,
        commitFiles: ['-a']
      }
    },
    log: {
      coverage: {
        options: {
          message: 'Open <%=jasmine.coverage.options.templateOptions.report%>/index.html in a browser to view the coverage.'
        }
      },
      copyForRelease: {
        options: {
          message: 'OK. Done copying version <%= pkg.version %> build from tmp to dist'
        }
      },
      release: {
        options: {
          message: ['OK. Done bumping, adding, committing, tagging and pushing the new version',
                    '',
                    'You still need to manually do the following:',
                    '  * git push upstream && git push upstream --tags',
                    '  * npm publish'].join('\n')
        }
      }
    },
    githubChanges: {
      dist: {
        options: {
          owner: "linkedin",
          repository: "dustjs",
          tagName: "v<%= pkg.version %>",
          onlyPulls: true,
          useCommitBody: true,
          auth: true
        }
      }
    }
  });

  //--------------------------------------------------
  //------------Custom tasks -------------------------
  //--------------------------------------------------
  grunt.registerMultiTask('log', 'Print some messages', function() {
    grunt.log.ok(this.data.options.message);
  });

  //--------------------------------------------------
  //------------External tasks -----------------------
  //--------------------------------------------------
  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-bump');
  grunt.loadNpmTasks('grunt-execute');
  grunt.loadNpmTasks('grunt-peg');
  grunt.loadNpmTasks('grunt-jasmine-nodejs');
  grunt.loadNpmTasks('grunt-github-changes');
  grunt.loadNpmTasks('grunt-saucelabs');

  //--------------------------------------------------
  //------------Grunt task aliases -------------------
  //--------------------------------------------------
  grunt.registerTask('buildLib',       ['jshint:libs', 'concat']);
  grunt.registerTask('build',          ['clean:build', 'peg', 'buildLib', 'uglify']);

  //test tasks
  grunt.registerTask('testNode',       ['jasmine_nodejs:templates', 'jasmine_nodejs:core', 'jasmine_nodejs:cjs']);
  grunt.registerTask('testRhino',      ['build', 'execute:testRhino']);
  grunt.registerTask('testPhantom',    ['build', 'jasmine:testProd']);
  grunt.registerTask('testCli',        ['jasmine_nodejs:dustc']);
  grunt.registerTask('test',           ['build', 'jasmine:testProd', 'testCli', 'testNode', 'execute:testRhino', 'jasmine:coverage']);

  //sauce labs integration (browser testing)
  grunt.registerTask('sauce',          process.env.SAUCE_ACCESS_KEY ? ['jasmine:testProd:build', 'connect:testServer', 'saucelabs-jasmine'] : []);

  //decide whether to run all tests or just the Node tests for Travis CI
  grunt.registerTask('travis',         (process.env.TEST === 'all') ? ['test', 'sauce'] : ['testNode', 'testCli']);

  //task for debugging in browser
  grunt.registerTask('dev',            ['build', 'jasmine:testDev:build', 'connect:testServer', 'watch:lib']);

  //task to run unit tests on client against prod version of code
  grunt.registerTask('testClient',     ['build', 'jasmine:testProd:build', 'connect:testServer', 'watch:lib_test']);

  //coverage report
  grunt.registerTask('coverage',       ['build', 'jasmine:coverage', 'log:coverage']);

  //release tasks
  grunt.registerTask('copyForRelease', ['clean:dist', 'copy', 'log:copyForRelease']);
  grunt.registerTask('buildRelease',   ['test', 'githubChanges', 'copyForRelease']);
  grunt.registerTask('releasePatch',   ['bump-only:patch', 'buildRelease', 'bump-commit', 'log:release']);
  grunt.registerTask('releaseMinor',   ['bump-only:minor', 'buildRelease', 'bump-commit', 'log:release']);
  // major release should probably be done with care
  //grunt.registerTask('releaseMajor',   ['bump-only:major', 'buildRelease', 'bump-commit:major', 'log:release']);

  //default task - full test
  grunt.registerTask('default',        ['test']);
};
<|endoftext|>


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

  grunt.initConfig({
    "gh-pages": {
      options: {
          base: "gh-pages"
      },
      src: "**/*"
    },

    less: {
      default: {
        files: {
            "gh-pages/css/style.css": "gh-pages/less/react-mentions.less"
        }
      }
    },

    copy: {
      default: {
        files: [
          { src: ["dist/react-mentions.js"], dest: "gh-pages/lib/react-mentions.js" }
        ]
      }
    }
  });

  grunt.loadNpmTasks("grunt-contrib-copy");
  grunt.loadNpmTasks("grunt-contrib-less");
  grunt.loadNpmTasks("grunt-gh-pages");

  grunt.registerTask("publish", [
    "copy",
    "less",
    "gh-pages"
  ]);
};
<commit_msg>changed config of gh-pages grunt task<commit_after>module.exports = function(grunt) {
  "use strict";

  grunt.initConfig({
    "gh-pages": {
      options: {
          base: "gh-pages"
      },
      src: [
        "index.html",
        "css/*",
        "lib/react-mentions.js",
        "lib/vendor/react/build/*"
      ]
    },

    less: {
      default: {
        files: {
            "gh-pages/css/style.css": "gh-pages/less/react-mentions.less"
        }
      }
    },

    copy: {
      default: {
        files: [
          { src: ["dist/react-mentions.js"], dest: "gh-pages/lib/react-mentions.js" }
        ]
      }
    }
  });

  grunt.loadNpmTasks("grunt-contrib-copy");
  grunt.loadNpmTasks("grunt-contrib-less");
  grunt.loadNpmTasks("grunt-gh-pages");

  grunt.registerTask("publish", [
    "copy",
    "less",
    "gh-pages"
  ]);
};
<|endoftext|>