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

    var jsFiles = module.exports.jsFiles;

    var output = {
        js: '<%= pkg.name %>.js',
        jsmin: '<%= pkg.name %>.min.js',
        map: '<%= pkg.name %>.min.js.map'
    };

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

        concat: {
            js: {
                src: jsFiles,
                dest: output.js
            }
        },
        uglify: {
            jsmin: {
                options: {
                    mangle: true,
                    compress: true,
                    sourceMap: output.map
                },
                src: output.js,
                dest: output.jsmin
            }
        },
        sed: {
            version: {
                pattern: '%VERSION%',
                replacement: '<%= pkg.version %>',
                path: [output.js, output.jsmin]
            }
        },
        jscs: {
            old: {
                src: ['spec/**/*.js'],
                options: {
                    validateIndentation: 4
                }
            },
            source: {
                src: ['src/**/*.js', '!src/{banner,footer}.js', 'Gruntfile.js', 'web/stock.js'],
                options: {
                    config: '.jscsrc'
                }
            }
        },
        jshint: {
            source: {
                src: ['src/**/*.js', 'Gruntfile.js', 'web/stock.js'],
                options: {
                    jshintrc: '.jshintrc',
                    ignores: ['src/banner.js', 'src/footer.js']
                }
            }
        },
        watch: {
            scripts: {
                files: ['src/**/*.js'],
                tasks: ['build', 'copy']
            },
            jasmineRunner: {
                files: ['spec/**/*.js'],
                tasks: ['jasmine:specs:build']
            },
            tests: {
                files: ['src/**/*.js', 'spec/**/*.js'],
                tasks: ['test']
            },
            reload: {
                files: ['dc.js', 'dc.css', 'web/js/dc.js', 'web/css/dc.css', 'dc.min.js'],
                options: {
                    livereload: true
                }
            }
        },
        connect: {
            server: {
                options: {
                    port: 8888,
                    base: '.'
                }
            }
        },
        jasmine: {
            specs: {
                options: {
                    display: 'short',
                    summary: true,
                    specs:  'spec/*-spec.js',
                    helpers: 'spec/helpers/*.js',
                    version: '2.0.0',
                    outfile: 'spec/index.html',
                    keepRunner: true
                },
                src: [
                    'web/js/d3.js',
                    'web/js/crossfilter.js',
                    'web/js/colorbrewer.js',
                    'dc.js'
                ]
            },
            coverage:{
                src: '<%= jasmine.specs.src %>',
                options:{
                    specs: '<%= jasmine.specs.options.specs %>',
                    helpers: '<%= jasmine.specs.options.helpers %>',
                    version: '<%= jasmine.specs.options.version %>',
                    template: require('grunt-template-jasmine-istanbul'),
                    templateOptions: {
                        coverage: 'coverage/jasmine/coverage.json',
                        report: [
                            {
                                type: 'html',
                                options: {
                                    dir: 'coverage/jasmine'
                                }
                            }
                        ]
                    }
                }
            },
            browserify: {
                options: {
                    display: 'short',
                    summary: true,
                    specs:  'spec/*-spec.js',
                    helpers: 'spec/helpers/*.js',
                    version: '2.0.0',
                    outfile: 'spec/index-browserify.html',
                    keepRunner: true
                },
                src: [
                    'bundle.js'
                ]
            }
        },
        'saucelabs-jasmine': {
            all: {
                options: {
                    urls: ['http://localhost:8888/spec/'],
                    tunnelTimeout: 5,
                    build: process.env.TRAVIS_JOB_ID,
                    concurrency: 3,
                    browsers: [
                        {
                            browserName: 'firefox',
                            version: '25',
                            platform: 'linux'
                        },
                        {
                            browserName: 'safari',
                            version: '7',
                            platform: 'OS X 10.9'
                        },
                        {
                            browserName: 'internet explorer',
                            version: '10',
                            platform: 'WIN8'
                        }
                    ],
                    testname: 'dc.js'
                }
            }
        },
        emu: {
            api: {
                src: output.js,
                dest: 'web/docs/api-latest.md'
            }
        },
        toc: {
            api: {
                src: '<%= emu.api.dest %>',
                dest: '<%= emu.api.dest %>'
            }
        },
        markdown: {
            html: {
                src: '<%= emu.api.dest %>',
                dest: 'web/docs/index.html'
            },
            options: {markdownOptions: {highlight: 'manual'}}
        },
        docco: {
            options: {
                dst: 'web/docs',
                basepath:'web'
            },
            howto: {
                files: [
                    {
                        src: ['web/stock.js']
                    }
                ]
            }
        },
        copy: {
            'dc-to-gh': {
                files: [
                    {expand: true, flatten: true, src: 'dc.css', dest: 'web/css/'},
                    {
                        expand: true,
                        flatten: true,
                        src: [
                            output.js,
                            output.js + '.map',
                            'node_modules/d3/d3.js',
                            'node_modules/crossfilter/crossfilter.js',
                            'test/env-data.js'
                        ],
                        dest: 'web/js/'
                    }
                ]
            }
        },
        fileindex: {
            'examples-listing': {
                options: {
                    format: function (list) {
                        var examples = list.sort().map(function (entry) {
                            return entry.replace(/.*examples\//, '');
                        }).filter(function (e) { return e !== 'index.html'; });
                        var rows = [];
                        for (var i = 0; i < examples.length; i += 5) {
                            var cols = [];
                            for (var j = 0; j < 5; ++j) {
                                if (i + j >= examples.length) {
                                    break;
                                }
                                var fname = examples[i + j];
                                cols.push('    ' + fname + '	');
                            }
                            rows.push('
\n' + cols.join('\n') + '\n
');
                        }
                        var body = '
\n' + rows.join('\n') + '\n
';
                        return [
                            '<title>Index of dc.js examples</title>',
                            '<link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css">',
                            '
',
                            '
Examples of using dc.js
',
                            '
An attempt to present a simple example of each chart type.',
                            '',
                            'Contributions welcome.
',
                            '
Source ',
                            'here.
',
                            body,
                            '
'
                        ].join('\n');
                    },
                    absolute: true
                },
                files: [
                    {dest: 'web/examples/index.html', src: ['web/examples/*.html']}
                ]
            }
        },

        'gh-pages': {
            options: {
                base: 'web',
                message: 'Synced from from master branch.'
            },
            src: ['**']
        },
        shell: {
            merge: {
                command: function (pr) {
                    return [
                        'git fetch origin',
                        'git checkout master',
                        'git reset --hard origin/master',
                        'git fetch origin',
                        'git merge --no-ff origin/pr/' + pr + ' -m \'Merge pull request #' + pr + '\''
                    ].join('&&');
                },
                options: {
                    stdout: true,
                    failOnError: true
                }
            },
            amend: {
                command: 'git commit -a --amend --no-edit',
                options: {
                    stdout: true,
                    failOnError: true
                }
            },
            hooks: {
                command: 'cp -n scripts/pre-commit.sh .git/hooks/pre-commit' +
                    ' || echo \'Cowardly refusing to overwrite your existing git pre-commit hook.\''
            }
        },
        browserify: {
            dev: {
                src: 'dc.js',
                dest: 'bundle.js',
                options: {
                    browserifyOptions: {
                        standalone: 'dc'
                    }
                }
            },
        }
    });

    // These plugins provide necessary tasks.
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-jasmine');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-docco2');
    grunt.loadNpmTasks('grunt-gh-pages');
    grunt.loadNpmTasks('grunt-jscs');
    grunt.loadNpmTasks('grunt-saucelabs');
    grunt.loadNpmTasks('grunt-markdown');
    grunt.loadNpmTasks('grunt-sed');
    grunt.loadNpmTasks('grunt-shell');
    grunt.loadNpmTasks('grunt-debug-task');
    grunt.loadNpmTasks('grunt-fileindex');
    grunt.loadNpmTasks('grunt-browserify');

    // custom tasks
    grunt.registerMultiTask('emu', 'Documentation extraction by emu.', function () {
        var emu = require('emu'),
            srcFile = this.files[0].src[0],
            destFile = this.files[0].dest,
            source = grunt.file.read(srcFile);
        grunt.file.write(destFile, emu.getComments(source));
        grunt.log.writeln('File \'' + destFile + '\' created.');
    });
    grunt.registerTask('merge', 'Merge a github pull request.', function (pr) {
        grunt.log.writeln('Merge Github Pull Request #' + pr);
        grunt.task.run(['shell:merge:' + pr, 'test' , 'shell:amend']);
    });
    grunt.registerMultiTask('toc', 'Generate a markdown table of contents.', function () {
        var marked = require('marked'),
            slugify = function (s) { return s.trim().replace(/[-_\s]+/g, '-').toLowerCase(); },
            srcFile = this.files[0].src[0],
            destFile = this.files[0].dest,
            source = grunt.file.read(srcFile),
            tokens = marked.lexer(source),
            toc = tokens.filter(function (item) {
                return item.type === 'heading' && item.depth === 2;
            }).reduce(function (toc, item) {
                return toc + '  * [' + item.text + '](#' + slugify(item.text) + ')\n';
            }, '');

        grunt.file.write(destFile, '# DC API\n' + toc + '\n' + source);
        grunt.log.writeln('Added TOC to \'' + destFile + '\'.');
    });
    grunt.registerTask('test-stock-example', 'Test a new rendering of the stock example web page against a ' +
        'baseline rendering', function (option) {
            require('./regression/stock-regression-test.js').testStockExample(this.async(), option === 'diff');
        });
    grunt.registerTask('update-stock-example', 'Update the baseline stock example web page.', function () {
        require('./regression/stock-regression-test.js').updateStockExample(this.async());
    });
    grunt.registerTask('watch:jasmine', function () {
        grunt.config('watch', {
            options: {
                interrupt: true
            },
            runner: grunt.config('watch').jasmineRunner,
            scripts: grunt.config('watch').scripts
        });
        grunt.task.run('watch');
    });

    // task aliases
    grunt.registerTask('build', ['concat', 'uglify', 'sed']);
    grunt.registerTask('docs', ['build', 'copy', 'emu', 'toc', 'markdown', 'docco']);
    grunt.registerTask('web', ['docs', 'gh-pages']);
    grunt.registerTask('server', ['docs', 'fileindex', 'jasmine:specs:build', 'connect:server', 'watch:jasmine']);
    grunt.registerTask('test', ['docs', 'jasmine:specs', 'test-stock-example', 'shell:hooks']);
    grunt.registerTask('test-browserify', ['docs', 'browserify', 'jasmine:browserify']);
    grunt.registerTask('coverage', ['docs', 'jasmine:coverage']);
    grunt.registerTask('ci', ['test', 'jasmine:specs:build', 'connect:server', 'saucelabs-jasmine']);
    grunt.registerTask('ci-pull', ['test', 'jasmine:specs:build', 'connect:server']);
    grunt.registerTask('lint', ['build', 'jshint', 'jscs']);
    grunt.registerTask('default', ['build']);
};

module.exports.jsFiles = [
    'src/banner.js',
    'src/core.js',
    'src/errors.js',
    'src/utils.js',
    'src/logger.js',
    'src/events.js',
    'src/filters.js',
    'src/base-mixin.js',
    'src/margin-mixin.js',
    'src/color-mixin.js',
    'src/coordinate-grid-mixin.js',
    'src/stack-mixin.js',
    'src/cap-mixin.js',
    'src/bubble-mixin.js',
    'src/pie-chart.js',
    'src/bar-chart.js',
    'src/line-chart.js',
    'src/data-count.js',
    'src/data-table.js',
    'src/data-grid.js',
    'src/bubble-chart.js',
    'src/composite-chart.js',
    'src/series-chart.js',
    'src/geo-choropleth-chart.js',
    'src/bubble-overlay.js',
    'src/row-chart.js',
    'src/legend.js',
    'src/scatter-plot.js',
    'src/number-display.js',
    'src/heatmap.js',
    'src/d3.box.js',
    'src/box-plot.js',
    'src/footer.js'  // NOTE: keep this last
];
<commit_msg>build dc.js file but not docs when testing<commit_after>module.exports = function (grunt) {
    'use strict';

    var jsFiles = module.exports.jsFiles;

    var output = {
        js: '<%= pkg.name %>.js',
        jsmin: '<%= pkg.name %>.min.js',
        map: '<%= pkg.name %>.min.js.map'
    };

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

        concat: {
            js: {
                src: jsFiles,
                dest: output.js
            }
        },
        uglify: {
            jsmin: {
                options: {
                    mangle: true,
                    compress: true,
                    sourceMap: output.map
                },
                src: output.js,
                dest: output.jsmin
            }
        },
        sed: {
            version: {
                pattern: '%VERSION%',
                replacement: '<%= pkg.version %>',
                path: [output.js, output.jsmin]
            }
        },
        jscs: {
            old: {
                src: ['spec/**/*.js'],
                options: {
                    validateIndentation: 4
                }
            },
            source: {
                src: ['src/**/*.js', '!src/{banner,footer}.js', 'Gruntfile.js', 'web/stock.js'],
                options: {
                    config: '.jscsrc'
                }
            }
        },
        jshint: {
            source: {
                src: ['src/**/*.js', 'Gruntfile.js', 'web/stock.js'],
                options: {
                    jshintrc: '.jshintrc',
                    ignores: ['src/banner.js', 'src/footer.js']
                }
            }
        },
        watch: {
            scripts: {
                files: ['src/**/*.js'],
                tasks: ['build', 'copy']
            },
            jasmineRunner: {
                files: ['spec/**/*.js'],
                tasks: ['jasmine:specs:build']
            },
            tests: {
                files: ['src/**/*.js', 'spec/**/*.js'],
                tasks: ['test']
            },
            reload: {
                files: ['dc.js', 'dc.css', 'web/js/dc.js', 'web/css/dc.css', 'dc.min.js'],
                options: {
                    livereload: true
                }
            }
        },
        connect: {
            server: {
                options: {
                    port: 8888,
                    base: '.'
                }
            }
        },
        jasmine: {
            specs: {
                options: {
                    display: 'short',
                    summary: true,
                    specs:  'spec/*-spec.js',
                    helpers: 'spec/helpers/*.js',
                    version: '2.0.0',
                    outfile: 'spec/index.html',
                    keepRunner: true
                },
                src: [
                    'web/js/d3.js',
                    'web/js/crossfilter.js',
                    'web/js/colorbrewer.js',
                    'dc.js'
                ]
            },
            coverage:{
                src: '<%= jasmine.specs.src %>',
                options:{
                    specs: '<%= jasmine.specs.options.specs %>',
                    helpers: '<%= jasmine.specs.options.helpers %>',
                    version: '<%= jasmine.specs.options.version %>',
                    template: require('grunt-template-jasmine-istanbul'),
                    templateOptions: {
                        coverage: 'coverage/jasmine/coverage.json',
                        report: [
                            {
                                type: 'html',
                                options: {
                                    dir: 'coverage/jasmine'
                                }
                            }
                        ]
                    }
                }
            },
            browserify: {
                options: {
                    display: 'short',
                    summary: true,
                    specs:  'spec/*-spec.js',
                    helpers: 'spec/helpers/*.js',
                    version: '2.0.0',
                    outfile: 'spec/index-browserify.html',
                    keepRunner: true
                },
                src: [
                    'bundle.js'
                ]
            }
        },
        'saucelabs-jasmine': {
            all: {
                options: {
                    urls: ['http://localhost:8888/spec/'],
                    tunnelTimeout: 5,
                    build: process.env.TRAVIS_JOB_ID,
                    concurrency: 3,
                    browsers: [
                        {
                            browserName: 'firefox',
                            version: '25',
                            platform: 'linux'
                        },
                        {
                            browserName: 'safari',
                            version: '7',
                            platform: 'OS X 10.9'
                        },
                        {
                            browserName: 'internet explorer',
                            version: '10',
                            platform: 'WIN8'
                        }
                    ],
                    testname: 'dc.js'
                }
            }
        },
        emu: {
            api: {
                src: output.js,
                dest: 'web/docs/api-latest.md'
            }
        },
        toc: {
            api: {
                src: '<%= emu.api.dest %>',
                dest: '<%= emu.api.dest %>'
            }
        },
        markdown: {
            html: {
                src: '<%= emu.api.dest %>',
                dest: 'web/docs/index.html'
            },
            options: {markdownOptions: {highlight: 'manual'}}
        },
        docco: {
            options: {
                dst: 'web/docs',
                basepath:'web'
            },
            howto: {
                files: [
                    {
                        src: ['web/stock.js']
                    }
                ]
            }
        },
        copy: {
            'dc-to-gh': {
                files: [
                    {expand: true, flatten: true, src: 'dc.css', dest: 'web/css/'},
                    {
                        expand: true,
                        flatten: true,
                        src: [
                            output.js,
                            output.js + '.map',
                            'node_modules/d3/d3.js',
                            'node_modules/crossfilter/crossfilter.js',
                            'test/env-data.js'
                        ],
                        dest: 'web/js/'
                    }
                ]
            }
        },
        fileindex: {
            'examples-listing': {
                options: {
                    format: function (list) {
                        var examples = list.sort().map(function (entry) {
                            return entry.replace(/.*examples\//, '');
                        }).filter(function (e) { return e !== 'index.html'; });
                        var rows = [];
                        for (var i = 0; i < examples.length; i += 5) {
                            var cols = [];
                            for (var j = 0; j < 5; ++j) {
                                if (i + j >= examples.length) {
                                    break;
                                }
                                var fname = examples[i + j];
                                cols.push('    ' + fname + '	');
                            }
                            rows.push('
\n' + cols.join('\n') + '\n
');
                        }
                        var body = '
\n' + rows.join('\n') + '\n
';
                        return [
                            '<title>Index of dc.js examples</title>',
                            '<link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css">',
                            '
',
                            '
Examples of using dc.js
',
                            '
An attempt to present a simple example of each chart type.',
                            '',
                            'Contributions welcome.
',
                            '
Source ',
                            'here.
',
                            body,
                            '
'
                        ].join('\n');
                    },
                    absolute: true
                },
                files: [
                    {dest: 'web/examples/index.html', src: ['web/examples/*.html']}
                ]
            }
        },

        'gh-pages': {
            options: {
                base: 'web',
                message: 'Synced from from master branch.'
            },
            src: ['**']
        },
        shell: {
            merge: {
                command: function (pr) {
                    return [
                        'git fetch origin',
                        'git checkout master',
                        'git reset --hard origin/master',
                        'git fetch origin',
                        'git merge --no-ff origin/pr/' + pr + ' -m \'Merge pull request #' + pr + '\''
                    ].join('&&');
                },
                options: {
                    stdout: true,
                    failOnError: true
                }
            },
            amend: {
                command: 'git commit -a --amend --no-edit',
                options: {
                    stdout: true,
                    failOnError: true
                }
            },
            hooks: {
                command: 'cp -n scripts/pre-commit.sh .git/hooks/pre-commit' +
                    ' || echo \'Cowardly refusing to overwrite your existing git pre-commit hook.\''
            }
        },
        browserify: {
            dev: {
                src: 'dc.js',
                dest: 'bundle.js',
                options: {
                    browserifyOptions: {
                        standalone: 'dc'
                    }
                }
            },
        }
    });

    // These plugins provide necessary tasks.
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-jasmine');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-docco2');
    grunt.loadNpmTasks('grunt-gh-pages');
    grunt.loadNpmTasks('grunt-jscs');
    grunt.loadNpmTasks('grunt-saucelabs');
    grunt.loadNpmTasks('grunt-markdown');
    grunt.loadNpmTasks('grunt-sed');
    grunt.loadNpmTasks('grunt-shell');
    grunt.loadNpmTasks('grunt-debug-task');
    grunt.loadNpmTasks('grunt-fileindex');
    grunt.loadNpmTasks('grunt-browserify');

    // custom tasks
    grunt.registerMultiTask('emu', 'Documentation extraction by emu.', function () {
        var emu = require('emu'),
            srcFile = this.files[0].src[0],
            destFile = this.files[0].dest,
            source = grunt.file.read(srcFile);
        grunt.file.write(destFile, emu.getComments(source));
        grunt.log.writeln('File \'' + destFile + '\' created.');
    });
    grunt.registerTask('merge', 'Merge a github pull request.', function (pr) {
        grunt.log.writeln('Merge Github Pull Request #' + pr);
        grunt.task.run(['shell:merge:' + pr, 'test' , 'shell:amend']);
    });
    grunt.registerMultiTask('toc', 'Generate a markdown table of contents.', function () {
        var marked = require('marked'),
            slugify = function (s) { return s.trim().replace(/[-_\s]+/g, '-').toLowerCase(); },
            srcFile = this.files[0].src[0],
            destFile = this.files[0].dest,
            source = grunt.file.read(srcFile),
            tokens = marked.lexer(source),
            toc = tokens.filter(function (item) {
                return item.type === 'heading' && item.depth === 2;
            }).reduce(function (toc, item) {
                return toc + '  * [' + item.text + '](#' + slugify(item.text) + ')\n';
            }, '');

        grunt.file.write(destFile, '# DC API\n' + toc + '\n' + source);
        grunt.log.writeln('Added TOC to \'' + destFile + '\'.');
    });
    grunt.registerTask('test-stock-example', 'Test a new rendering of the stock example web page against a ' +
        'baseline rendering', function (option) {
            require('./regression/stock-regression-test.js').testStockExample(this.async(), option === 'diff');
        });
    grunt.registerTask('update-stock-example', 'Update the baseline stock example web page.', function () {
        require('./regression/stock-regression-test.js').updateStockExample(this.async());
    });
    grunt.registerTask('watch:jasmine', function () {
        grunt.config('watch', {
            options: {
                interrupt: true
            },
            runner: grunt.config('watch').jasmineRunner,
            scripts: grunt.config('watch').scripts
        });
        grunt.task.run('watch');
    });

    // task aliases
    grunt.registerTask('build', ['concat', 'uglify', 'sed']);
    grunt.registerTask('docs', ['build', 'copy', 'emu', 'toc', 'markdown', 'docco']);
    grunt.registerTask('web', ['docs', 'gh-pages']);
    grunt.registerTask('server', ['docs', 'fileindex', 'jasmine:specs:build', 'connect:server', 'watch:jasmine']);
    grunt.registerTask('test', ['build', 'jasmine:specs', 'test-stock-example', 'shell:hooks']);
    grunt.registerTask('test-browserify', ['build', 'browserify', 'jasmine:browserify']);
    grunt.registerTask('coverage', ['build', 'jasmine:coverage']);
    grunt.registerTask('ci', ['test', 'jasmine:specs:build', 'connect:server', 'saucelabs-jasmine']);
    grunt.registerTask('ci-pull', ['test', 'jasmine:specs:build', 'connect:server']);
    grunt.registerTask('lint', ['build', 'jshint', 'jscs']);
    grunt.registerTask('default', ['build']);
};

module.exports.jsFiles = [
    'src/banner.js',
    'src/core.js',
    'src/errors.js',
    'src/utils.js',
    'src/logger.js',
    'src/events.js',
    'src/filters.js',
    'src/base-mixin.js',
    'src/margin-mixin.js',
    'src/color-mixin.js',
    'src/coordinate-grid-mixin.js',
    'src/stack-mixin.js',
    'src/cap-mixin.js',
    'src/bubble-mixin.js',
    'src/pie-chart.js',
    'src/bar-chart.js',
    'src/line-chart.js',
    'src/data-count.js',
    'src/data-table.js',
    'src/data-grid.js',
    'src/bubble-chart.js',
    'src/composite-chart.js',
    'src/series-chart.js',
    'src/geo-choropleth-chart.js',
    'src/bubble-overlay.js',
    'src/row-chart.js',
    'src/legend.js',
    'src/scatter-plot.js',
    'src/number-display.js',
    'src/heatmap.js',
    'src/d3.box.js',
    'src/box-plot.js',
    'src/footer.js'  // NOTE: keep this last
];
<|endoftext|>


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

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    meta: {
      banner: '/* <%= pkg.name %> v<%= pkg.version %> | (c) <%= grunt.template.today("yyyy") %> by Matt Zabriskie */\n'
    },

    clean: {
      dist: 'dist/**'
    },

    update_json: {
      bower: {
        src: 'package.json',
        dest: 'bower.json',
        fields: [
          'name',
          'description',
          'version',
          'homepage',
          'license',
          'keywords'
        ]
      }
    },

    usebanner: {
      all: {
        options: {
          banner: '<%= meta.banner %>',
          linebreak: false
        },
        files: {
          src: ['dist/axios.min.js', 'dist/axios.amd.min.js']
        }
      }
    },

    karma: {
      options: {
        configFile: 'karma.conf.js'
      },
      single: {
        singleRun: true
      },
      continuous: {
        singleRun: false
      }
    },

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

    webpack: generateWebpackConfig(),

    watch: {
      build: {
        files: ['lib/**/*.js'],
        tasks: ['build']
      },
      test: {
        files: ['lib/**/*.js', 'test/**/*.js'],
        tasks: ['test']
      }
    }
  });

  grunt.registerTask('test', 'Run the jasmine and nodeunit tests', ['webpack:global', 'nodeunit', 'karma:single']);
  grunt.registerTask('build', 'Run webpack and bundle the source', ['webpack']);
  grunt.registerTask('publish', 'Prepare the code for release', ['clean', 'test', 'build', 'usebanner', 'update_json']);

  function generateWebpackConfig() {
    var webpack = require('webpack');
    var webpackConfig = {};
    var webpackBase = {
      entry: './index.js',
      output: {
        path: 'dist/',
        filename: 'axios.js',
        sourceMapFilename: 'axios.map',
        library: 'axios'
      },
      externals: [
        {
          './adapters/http': 'var undefined'
        }
      ],
      devtool: 'source-map'
    };

    ['amd', 'global', 'amd-standalone', 'global-standalone'].forEach(function (key) {
      webpackConfig[key] = JSON.parse(JSON.stringify(webpackBase));
      webpackConfig[key + '-min'] = JSON.parse(JSON.stringify(webpackBase));

      // TODO: UglifyJsPlugin doesn' work, but optimize.minimize is deprecated
      webpackConfig[key + '-min'].optimize = {minimize: true};
//      webpackConfig[key + '-min'].pugins = [
//        new webpack.optimize.UglifyJsPlugin()
//      ];
    });

    webpackConfig['amd'].output.filename = 'axios.amd.js';
    webpackConfig['amd'].output.sourceMapFilename = 'axios.amd.map';
    webpackConfig['amd'].output.libraryTarget = 'amd';

    webpackConfig['amd-standalone'].output.filename = 'axios.amd.standalone.js';
    webpackConfig['amd-standalone'].output.sourceMapFilename = 'axios.amd.standalone.map';
    webpackConfig['amd-standalone'].output.libraryTarget = 'amd';
    webpackConfig['amd-standalone'].externals[0]['es6-promise'] = 'var undefined';

    webpackConfig['amd-min'].output.filename = 'axios.amd.min.js';
    webpackConfig['amd-min'].output.sourceMapFilename = 'axios.amd.min.map';
    webpackConfig['amd-min'].output.libraryTarget = 'amd';

    webpackConfig['amd-standalone-min'].output.filename = 'axios.amd.standalone.min.js';
    webpackConfig['amd-standalone-min'].output.sourceMapFilename = 'axios.amd.standalone.min.map';
    webpackConfig['amd-standalone-min'].output.libraryTarget = 'amd';
    webpackConfig['amd-standalone-min'].externals[0]['es6-promise'] = 'var undefined';

    webpackConfig['global-standalone'].output.filename = 'axios.standalone.js';
    webpackConfig['global-standalone'].output.sourceMapFilename = 'axios.standalone.map';
    webpackConfig['global-standalone'].externals[0]['es6-promise'] = 'var undefined';

    webpackConfig['global-min'].output.filename = 'axios.min.js';
    webpackConfig['global-min'].output.sourceMapFilename = 'axios.min.map';

    webpackConfig['global-standalone-min'].output.filename = 'axios.standalone.min.js';
    webpackConfig['global-standalone-min'].output.sourceMapFilename = 'axios.standalone.min.map';
    webpackConfig['global-standalone-min'].externals[0]['es6-promise'] = 'var undefined';

    return webpackConfig;
  }
};<commit_msg>Adding banner to all min files<commit_after>module.exports = function(grunt) {
  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    meta: {
      banner: '/* <%= pkg.name %> v<%= pkg.version %> | (c) <%= grunt.template.today("yyyy") %> by Matt Zabriskie */\n'
    },

    clean: {
      dist: 'dist/**'
    },

    update_json: {
      bower: {
        src: 'package.json',
        dest: 'bower.json',
        fields: [
          'name',
          'description',
          'version',
          'homepage',
          'license',
          'keywords'
        ]
      }
    },

    usebanner: {
      all: {
        options: {
          banner: '<%= meta.banner %>',
          linebreak: false
        },
        files: {
          src: ['dist/*.min.js']
        }
      }
    },

    karma: {
      options: {
        configFile: 'karma.conf.js'
      },
      single: {
        singleRun: true
      },
      continuous: {
        singleRun: false
      }
    },

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

    webpack: generateWebpackConfig(),

    watch: {
      build: {
        files: ['lib/**/*.js'],
        tasks: ['build']
      },
      test: {
        files: ['lib/**/*.js', 'test/**/*.js'],
        tasks: ['test']
      }
    }
  });

  grunt.registerTask('test', 'Run the jasmine and nodeunit tests', ['webpack:global', 'nodeunit', 'karma:single']);
  grunt.registerTask('build', 'Run webpack and bundle the source', ['webpack']);
  grunt.registerTask('publish', 'Prepare the code for release', ['clean', 'test', 'build', 'usebanner', 'update_json']);

  function generateWebpackConfig() {
    var webpack = require('webpack');
    var webpackConfig = {};
    var webpackBase = {
      entry: './index.js',
      output: {
        path: 'dist/',
        filename: 'axios.js',
        sourceMapFilename: 'axios.map',
        library: 'axios'
      },
      externals: [
        {
          './adapters/http': 'var undefined'
        }
      ],
      devtool: 'source-map'
    };

    ['amd', 'global', 'amd-standalone', 'global-standalone'].forEach(function (key) {
      webpackConfig[key] = JSON.parse(JSON.stringify(webpackBase));
      webpackConfig[key + '-min'] = JSON.parse(JSON.stringify(webpackBase));

      // TODO: UglifyJsPlugin doesn' work, but optimize.minimize is deprecated
      webpackConfig[key + '-min'].optimize = {minimize: true};
//      webpackConfig[key + '-min'].pugins = [
//        new webpack.optimize.UglifyJsPlugin()
//      ];
    });

    webpackConfig['amd'].output.filename = 'axios.amd.js';
    webpackConfig['amd'].output.sourceMapFilename = 'axios.amd.map';
    webpackConfig['amd'].output.libraryTarget = 'amd';

    webpackConfig['amd-standalone'].output.filename = 'axios.amd.standalone.js';
    webpackConfig['amd-standalone'].output.sourceMapFilename = 'axios.amd.standalone.map';
    webpackConfig['amd-standalone'].output.libraryTarget = 'amd';
    webpackConfig['amd-standalone'].externals[0]['es6-promise'] = 'var undefined';

    webpackConfig['amd-min'].output.filename = 'axios.amd.min.js';
    webpackConfig['amd-min'].output.sourceMapFilename = 'axios.amd.min.map';
    webpackConfig['amd-min'].output.libraryTarget = 'amd';

    webpackConfig['amd-standalone-min'].output.filename = 'axios.amd.standalone.min.js';
    webpackConfig['amd-standalone-min'].output.sourceMapFilename = 'axios.amd.standalone.min.map';
    webpackConfig['amd-standalone-min'].output.libraryTarget = 'amd';
    webpackConfig['amd-standalone-min'].externals[0]['es6-promise'] = 'var undefined';

    webpackConfig['global-standalone'].output.filename = 'axios.standalone.js';
    webpackConfig['global-standalone'].output.sourceMapFilename = 'axios.standalone.map';
    webpackConfig['global-standalone'].externals[0]['es6-promise'] = 'var undefined';

    webpackConfig['global-min'].output.filename = 'axios.min.js';
    webpackConfig['global-min'].output.sourceMapFilename = 'axios.min.map';

    webpackConfig['global-standalone-min'].output.filename = 'axios.standalone.min.js';
    webpackConfig['global-standalone-min'].output.sourceMapFilename = 'axios.standalone.min.map';
    webpackConfig['global-standalone-min'].externals[0]['es6-promise'] = 'var undefined';

    return webpackConfig;
  }
};<|endoftext|>


<commit_before>'use strict';

module.exports = function(grunt) {

    grunt.initConfig({
        dirs: {
            dest: '_site',
            src: 'src',
            tmp: '.tmp'
        },

        jekyll: {
            site: {
                options: {
                    bundleExec: true,
                    incremental: false
                }
            }
        },

        htmlmin: {
            dist: {
                options: {
                    collapseBooleanAttributes: true,
                    collapseWhitespace: true,
                    conservativeCollapse: false,
                    decodeEntities: true,
                    ignoreCustomComments: [/^\s*google(off|on):\s/],
                    minifyCSS: {
                        level: {
                            1: {
                                specialComments: 0
                            }
                        }
                    },
                    minifyJS: true,
                    minifyURLs: false,
                    processConditionalComments: true,
                    removeAttributeQuotes: true,
                    removeComments: true,
                    removeOptionalAttributes: true,
                    removeOptionalTags: true,
                    removeRedundantAttributes: true,
                    removeScriptTypeAttributes: true,
                    removeStyleLinkTypeAttributes: true,
                    removeTagWhitespace: false,
                    sortAttributes: true,
                    sortClassName: true
                },
                expand: true,
                cwd: '<%= dirs.dest %>',
                dest: '<%= dirs.dest %>',
                src: [
                    '**/*.aspx',
                    '**/*.html'
                ]
            }
        },

        concat: {
            foundation: {
                src: [
                    '<%= dirs.src %>/assets/css/foundation/normalize.css',
                    '<%= dirs.src %>/assets/css/foundation/foundation.css'
                ],
                dest: '<%= dirs.tmp %>/css/foundation.css'
            },
            css: {
                src: [
                    '<%= concat.foundation.dest %>',
                    '<%= dirs.src %>/assets/css/site/*.css',
                    '<%= dirs.src %>/assets/css/pages/*.css'
                ],
                dest: '<%= dirs.dest %>/assets/css/pack.css'
            },
            js: {
                src: [
                    '<%= dirs.src %>/assets/js/vendor/anchor.js',
                    '<%= dirs.src %>/assets/js/no-js-class.js',
                    '<%= dirs.src %>/assets/js/google-analytics.js',
                    '<%= dirs.src %>/assets/js/main.js'
                ],
                dest: '<%= dirs.dest %>/assets/js/pack.js'
            },
            jqueryJS: {
                src: [
                    '<%= dirs.src %>/assets/js/vendor/jquery-*.min.js',
                    '<%= dirs.src %>/assets/js/vendor/foundation/*.js',
                    '<%= dirs.src %>/assets/js/jquery.js'
                ],
                dest: '<%= dirs.dest %>/assets/js/jquery-pack.js'
            }
        },

        autoprefixer: {
            options: {
                browsers: [
                    'last 2 version',
                    '> 1%',
                    'Edge >= 12',
                    'Explorer >= 11',
                    'Firefox ESR',
                    'Opera 12.1'
                ]
            },
            pack: {
                src: '<%= concat.css.dest %>',
                dest: '<%= concat.css.dest %>'
            }
        },

        uncss: {
            options: {
                ignore: [
                    /(#|\.)top-bar(-[a-zA-Z]+)?/,
                    /(#|\.)topbar(-[a-zA-Z]+)?/,
                    /(#|\.)f-topbar-fixed(-[a-zA-Z]+)?/,
                    /(#|\.)dropdown(-[a-zA-Z]+)?/,
                    /\.no-js/,
                    /meta.foundation(-[a-zA-Z]+)?/,
                    '.anchorjs-link'
                ],
                htmlroot: '<%= dirs.dest %>',
                ignoreSheets: [/fonts.googleapis/],
                stylesheets: ['/assets/css/pack.css']
            },
            dist: {
                src: '<%= dirs.dest %>/**/*.html',
                dest: '<%= concat.css.dest %>'
            }
        },

        cssmin: {
            minify: {
                options: {
                    level: {
                        1: {
                            specialComments: 0
                        }
                    }
                },
                files: {
                    '<%= concat.css.dest %>': '<%= concat.css.dest %>'
                }
            }
        },

        uglify: {
            options: {
                compress: true,
                mangle: true,
                output: {
                    comments: false
                }
            },
            minify: {
                files: {
                    '<%= concat.js.dest %>': '<%= concat.js.dest %>',
                    '<%= concat.jqueryJS.dest %>': '<%= concat.jqueryJS.dest %>'
                }
            }
        },

        filerev: {
            css: {
                src: '<%= dirs.dest %>/assets/css/*.css'
            },
            js: {
                src: '<%= dirs.dest %>/assets/js/*.js'
            },
            images: {
                src: [
                    '<%= dirs.dest %>/assets/img/**/*.{jpg,jpeg,gif,png,svg}',
                    '!<%= dirs.dest %>/assets/img/favicons/*.{jpg,jpeg,gif,png,svg}',
                    '!<%= dirs.dest %>/assets/img/appveyor-logo*.png',
                    '!<%= dirs.dest %>/assets/img/testimonials/*.png'
                ]
            }
        },

        useminPrepare: {
            html: '<%= dirs.dest %>/index.html',
            options: {
                dest: '<%= dirs.dest %>',
                root: '<%= dirs.dest %>'
            }
        },

        usemin: {
            css: '<%= dirs.dest %>/assets/css/pack*.css',
            html: [
                '<%= dirs.dest %>/**/*.html',
                '<%= dirs.dest %>/**/*.aspx'
            ],
            options: {
                assetsDirs: [
                    '<%= dirs.dest %>/',
                    '<%= dirs.dest %>/assets/img/'
                ]
            }
        },

        connect: {
            options: {
                base: '<%= dirs.dest %>/',
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    base: '<%= dirs.dest %>/',
                    livereload: 35729,
                    open: true,  // Automatically open the webpage in the default browser
                    port: 4000
                }
            },
            linkChecker: {
                options: {
                    base: '<%= dirs.dest %>/',
                    port: 9001
                }
            }
        },

        watch: {
            options: {
                livereload: '<%= connect.livereload.options.livereload %>'
            },
            dev: {
                files: [
                    '<%= dirs.src %>/**',
                    '.eslintrc.json',
                    '_config.yml',
                    'Gruntfile.js'
                ],
                tasks: 'dev'
            },
            build: {
                files: [
                    '<%= dirs.src %>/**',
                    '.eslintrc.json',
                    '_config.yml',
                    'Gruntfile.js'
                ],
                tasks: 'build'
            }
        },

        csslint: {
            options: {
                csslintrc: '.csslintrc'
            },
            src: [
                '<%= dirs.src %>/assets/css/site/*.css',
                '<%= dirs.src %>/assets/css/pages/*.css'
            ]
        },

        eslint: {
            options: {
                config: '.eslintrc.json'
            },
            src: {
                src: [
                    'Gruntfile.js',
                    '<%= dirs.src %>/assets/js/*.js',
                    '!<%= dirs.src %>/assets/js/google-analytics.js'
                ]
            }
        },

        markdownlint: {
            all: {
                options: {
                    config: grunt.file.readJSON('./markdownlint.json')
                },
                src: [
                    'src/**/*.md'
                ]
            }
        },

        htmllint: {
            options: {
                ignore: [
                    'Consider using the "h1" element as a top-level heading only (all "h1" elements are treated as top-level headings by many screen readers and other tools).'
                ]
            },
            src: [
                '<%= dirs.dest %>/**/*.html',
                '!<%= dirs.dest %>/updates/index.html',
                '!<%= dirs.dest %>/updates/page/**/*.html'
            ]
        },

        linkChecker: {
            options: {
                callback: function (crawler) {
                    crawler.addFetchCondition(function (url) {
                        return url.path !== '/assets/js/l.src' &&
                               url.path !== '/assets/js/+a+' &&
                               url.path !== '/feed.xml' &&
                               url.port !== '9023';
                    });
                },
                interval: 1,        // 1 ms; default 250
                maxConcurrency: 5   // default; bigger doesn't seem to improve time
            },
            dev: {
                site: 'localhost',
                options: {
                    initialPort: '<%= connect.linkChecker.options.port %>'
                }
            }
        },

        clean: {
            dist: [
                '<%= dirs.dest %>/',
                '<%= dirs.tmp %>/'
            ]
        }

    });

    // Load any grunt plugins found in package.json.
    require('load-grunt-tasks')(grunt, { scope: 'dependencies' });
    require('time-grunt')(grunt);

    grunt.registerTask('build', [
        'clean',
        'jekyll',
        'useminPrepare',
        'concat',
        'autoprefixer',
        'uncss',
        'cssmin',
        'uglify',
        'filerev',
        'usemin',
        'htmlmin'
    ]);

    grunt.registerTask('test', [
        'build',
        'csslint',
        'eslint',
        'markdownlint',
        'htmllint',
        'connect:linkChecker',
        'linkChecker'
    ]);

    grunt.registerTask('dev', [
        'jekyll',
        'useminPrepare',
        'concat',
        'autoprefixer',
        'filerev',
        'usemin'
    ]);

    grunt.registerTask('server', [
        'build',
        'connect:livereload',
        'watch:build'
    ]);

    grunt.registerTask('default', [
        'dev',
        'connect:livereload',
        'watch:dev'
    ]);

};
<commit_msg>Update html-minifier's config.<commit_after>'use strict';

module.exports = function(grunt) {

    grunt.initConfig({
        dirs: {
            dest: '_site',
            src: 'src',
            tmp: '.tmp'
        },

        jekyll: {
            site: {
                options: {
                    bundleExec: true,
                    incremental: false
                }
            }
        },

        htmlmin: {
            dist: {
                options: {
                    collapseBooleanAttributes: true,
                    collapseWhitespace: true,
                    conservativeCollapse: false,
                    decodeEntities: true,
                    ignoreCustomComments: [/^\s*google(off|on):\s/],
                    minifyCSS: {
                        level: {
                            1: {
                                specialComments: 0
                            }
                        }
                    },
                    minifyJS: true,
                    minifyURLs: false,
                    processConditionalComments: true,
                    processScripts: ['application/ld+json'],
                    removeAttributeQuotes: true,
                    removeComments: true,
                    removeOptionalAttributes: true,
                    removeOptionalTags: true,
                    removeRedundantAttributes: true,
                    removeScriptTypeAttributes: true,
                    removeStyleLinkTypeAttributes: true,
                    removeTagWhitespace: false,
                    sortAttributes: true,
                    sortClassName: true
                },
                expand: true,
                cwd: '<%= dirs.dest %>',
                dest: '<%= dirs.dest %>',
                src: [
                    '**/*.aspx',
                    '**/*.html'
                ]
            }
        },

        concat: {
            foundation: {
                src: [
                    '<%= dirs.src %>/assets/css/foundation/normalize.css',
                    '<%= dirs.src %>/assets/css/foundation/foundation.css'
                ],
                dest: '<%= dirs.tmp %>/css/foundation.css'
            },
            css: {
                src: [
                    '<%= concat.foundation.dest %>',
                    '<%= dirs.src %>/assets/css/site/*.css',
                    '<%= dirs.src %>/assets/css/pages/*.css'
                ],
                dest: '<%= dirs.dest %>/assets/css/pack.css'
            },
            js: {
                src: [
                    '<%= dirs.src %>/assets/js/vendor/anchor.js',
                    '<%= dirs.src %>/assets/js/no-js-class.js',
                    '<%= dirs.src %>/assets/js/google-analytics.js',
                    '<%= dirs.src %>/assets/js/main.js'
                ],
                dest: '<%= dirs.dest %>/assets/js/pack.js'
            },
            jqueryJS: {
                src: [
                    '<%= dirs.src %>/assets/js/vendor/jquery-*.min.js',
                    '<%= dirs.src %>/assets/js/vendor/foundation/*.js',
                    '<%= dirs.src %>/assets/js/jquery.js'
                ],
                dest: '<%= dirs.dest %>/assets/js/jquery-pack.js'
            }
        },

        autoprefixer: {
            options: {
                browsers: [
                    'last 2 version',
                    '> 1%',
                    'Edge >= 12',
                    'Explorer >= 11',
                    'Firefox ESR',
                    'Opera 12.1'
                ]
            },
            pack: {
                src: '<%= concat.css.dest %>',
                dest: '<%= concat.css.dest %>'
            }
        },

        uncss: {
            options: {
                ignore: [
                    /(#|\.)top-bar(-[a-zA-Z]+)?/,
                    /(#|\.)topbar(-[a-zA-Z]+)?/,
                    /(#|\.)f-topbar-fixed(-[a-zA-Z]+)?/,
                    /(#|\.)dropdown(-[a-zA-Z]+)?/,
                    /\.no-js/,
                    /meta.foundation(-[a-zA-Z]+)?/,
                    '.anchorjs-link'
                ],
                htmlroot: '<%= dirs.dest %>',
                ignoreSheets: [/fonts.googleapis/],
                stylesheets: ['/assets/css/pack.css']
            },
            dist: {
                src: '<%= dirs.dest %>/**/*.html',
                dest: '<%= concat.css.dest %>'
            }
        },

        cssmin: {
            minify: {
                options: {
                    level: {
                        1: {
                            specialComments: 0
                        }
                    }
                },
                files: {
                    '<%= concat.css.dest %>': '<%= concat.css.dest %>'
                }
            }
        },

        uglify: {
            options: {
                compress: true,
                mangle: true,
                output: {
                    comments: false
                }
            },
            minify: {
                files: {
                    '<%= concat.js.dest %>': '<%= concat.js.dest %>',
                    '<%= concat.jqueryJS.dest %>': '<%= concat.jqueryJS.dest %>'
                }
            }
        },

        filerev: {
            css: {
                src: '<%= dirs.dest %>/assets/css/*.css'
            },
            js: {
                src: '<%= dirs.dest %>/assets/js/*.js'
            },
            images: {
                src: [
                    '<%= dirs.dest %>/assets/img/**/*.{jpg,jpeg,gif,png,svg}',
                    '!<%= dirs.dest %>/assets/img/favicons/*.{jpg,jpeg,gif,png,svg}',
                    '!<%= dirs.dest %>/assets/img/appveyor-logo*.png',
                    '!<%= dirs.dest %>/assets/img/testimonials/*.png'
                ]
            }
        },

        useminPrepare: {
            html: '<%= dirs.dest %>/index.html',
            options: {
                dest: '<%= dirs.dest %>',
                root: '<%= dirs.dest %>'
            }
        },

        usemin: {
            css: '<%= dirs.dest %>/assets/css/pack*.css',
            html: [
                '<%= dirs.dest %>/**/*.html',
                '<%= dirs.dest %>/**/*.aspx'
            ],
            options: {
                assetsDirs: [
                    '<%= dirs.dest %>/',
                    '<%= dirs.dest %>/assets/img/'
                ]
            }
        },

        connect: {
            options: {
                base: '<%= dirs.dest %>/',
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    base: '<%= dirs.dest %>/',
                    livereload: 35729,
                    open: true,  // Automatically open the webpage in the default browser
                    port: 4000
                }
            },
            linkChecker: {
                options: {
                    base: '<%= dirs.dest %>/',
                    port: 9001
                }
            }
        },

        watch: {
            options: {
                livereload: '<%= connect.livereload.options.livereload %>'
            },
            dev: {
                files: [
                    '<%= dirs.src %>/**',
                    '.eslintrc.json',
                    '_config.yml',
                    'Gruntfile.js'
                ],
                tasks: 'dev'
            },
            build: {
                files: [
                    '<%= dirs.src %>/**',
                    '.eslintrc.json',
                    '_config.yml',
                    'Gruntfile.js'
                ],
                tasks: 'build'
            }
        },

        csslint: {
            options: {
                csslintrc: '.csslintrc'
            },
            src: [
                '<%= dirs.src %>/assets/css/site/*.css',
                '<%= dirs.src %>/assets/css/pages/*.css'
            ]
        },

        eslint: {
            options: {
                config: '.eslintrc.json'
            },
            src: {
                src: [
                    'Gruntfile.js',
                    '<%= dirs.src %>/assets/js/*.js',
                    '!<%= dirs.src %>/assets/js/google-analytics.js'
                ]
            }
        },

        markdownlint: {
            all: {
                options: {
                    config: grunt.file.readJSON('./markdownlint.json')
                },
                src: [
                    'src/**/*.md'
                ]
            }
        },

        htmllint: {
            options: {
                ignore: [
                    'Consider using the "h1" element as a top-level heading only (all "h1" elements are treated as top-level headings by many screen readers and other tools).'
                ]
            },
            src: [
                '<%= dirs.dest %>/**/*.html',
                '!<%= dirs.dest %>/updates/index.html',
                '!<%= dirs.dest %>/updates/page/**/*.html'
            ]
        },

        linkChecker: {
            options: {
                callback: function (crawler) {
                    crawler.addFetchCondition(function (url) {
                        return url.path !== '/assets/js/l.src' &&
                               url.path !== '/assets/js/+a+' &&
                               url.path !== '/feed.xml' &&
                               url.port !== '9023';
                    });
                },
                interval: 1,        // 1 ms; default 250
                maxConcurrency: 5   // default; bigger doesn't seem to improve time
            },
            dev: {
                site: 'localhost',
                options: {
                    initialPort: '<%= connect.linkChecker.options.port %>'
                }
            }
        },

        clean: {
            dist: [
                '<%= dirs.dest %>/',
                '<%= dirs.tmp %>/'
            ]
        }

    });

    // Load any grunt plugins found in package.json.
    require('load-grunt-tasks')(grunt, { scope: 'dependencies' });
    require('time-grunt')(grunt);

    grunt.registerTask('build', [
        'clean',
        'jekyll',
        'useminPrepare',
        'concat',
        'autoprefixer',
        'uncss',
        'cssmin',
        'uglify',
        'filerev',
        'usemin',
        'htmlmin'
    ]);

    grunt.registerTask('test', [
        'build',
        'csslint',
        'eslint',
        'markdownlint',
        'htmllint',
        'connect:linkChecker',
        'linkChecker'
    ]);

    grunt.registerTask('dev', [
        'jekyll',
        'useminPrepare',
        'concat',
        'autoprefixer',
        'filerev',
        'usemin'
    ]);

    grunt.registerTask('server', [
        'build',
        'connect:livereload',
        'watch:build'
    ]);

    grunt.registerTask('default', [
        'dev',
        'connect:livereload',
        'watch:dev'
    ]);

};
<|endoftext|>


<commit_before>module.exports = function (grunt) {
    function sync(patterns) {
        return [...new Set(grunt.file.expand({
            filter: path => !new RegExp(/__test__/g).test(path),
        }, patterns))];
    }

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON("package.json"),
        concat: {
            options: {
                separator: "",
                sourceMap: true,
                sourceMapStyle: "link",
            },
            polyfillJs: {
                src: ["src/core/foundation.js", "src/polyfill/**/*.js"],
                dest: "dist/polyfill.js"
            },
            coreJs: {
                src: sync([
                    "src/core/foundation.js",
                    "src/core/lodash.js",
                    // 'src/core/mvc/**/*.js',
                    "src/core/base.js",
                    "src/core/ob.js",
                    "src/core/widget.js",
                    // 'src/core/model.js',
                    // 'src/core/view.js',
                    "src/core/shortcut.js",
                    "src/core/utils/**/*.js",
                    "src/core/behavior/behavior.js",
                    "src/core/wrapper/layout.js",
                    "src/core/plugin.js",
                    "src/core/**/*.js",

                    "src/data/data.js",
                    "src/data/**/*.js"
                ]),
                dest: "dist/core.js"
            },

            // 最基础的控件
            baseJs: {
                src: sync([
                    "src/third/**/*.js",
                    "src/base/pane.js",
                    "src/base/single/single.js",
                    "src/base/single/text.js",
                    "src/base/single/button/button.basic.js",
                    "src/base/single/button/button.node.js",
                    "src/base/single/tip/tip.js",
                    "src/base/combination/group.button.js",
                    "src/base/combination/tree.button.js",
                    "src/base/tree/ztree/treeview.js",
                    "src/base/tree/ztree/asynctree.js",
                    "src/base/tree/ztree/parttree.js",
                    "src/base/tree/ztree/list/listtreeview.js",
                    "src/base/tree/ztree/list/listasynctree.js",
                    "src/base/tree/ztree/list/listparttree.js",
                    "src/base/**/*.js"
                ]),
                dest: "dist/base.js"
            },
            // 实现好的一些基础实例
            caseJs: {
                src: sync([
                    "src/case/combo/popup.bubble.js",
                    "src/case/**/*.js"
                ]),
                dest: "dist/case.js"
            },
            widgetJs: {
                src: sync([
                    "src/widget/**/*.js",
                    "src/component/**/*.js"
                ]),
                dest: "dist/widget.js"
            },
            routerJs: {
                src: [
                    "src/router/**/*.js"
                ],
                dest: "dist/router.js"
            },
            coreCss: {
                src: ["src/css/core/**/*.css", "src/css/theme/**/*.css"],
                dest: "dist/core.css"
            },
            coreWithoutNormalizeCss: {
                src: ["src/css/core/**/*.css", "src/css/theme/**/*.css", "!src/css/core/normalize.css", "!src/css/core/normalize2.css"],
                dest: "dist/core_without_normalize.css"
            },
            baseCss: {
                src: ["src/css/base/**/*.css"],
                dest: "dist/base.css"
            },
            widgetCss: {
                src: ["src/css/widget/**/*.css"],
                dest: "dist/widget.css"
            },
            resourceCss: {
                src: ["src/css/resource/**/*.css"],
                dest: "dist/resource.css"
            },

            bundleJs: {
                src: ["dist/core.js", "dist/fix/fix.js", "dist/base.js", "dist/case.js", "dist/widget.js", "dist/fix/fix.compact.js", "dist/router.js", "public/js/**/*.js", "public/js/index.js", "i18n/i18n.cn.js"],
                dest: "dist/bundle.js",
            },

            versionFineuiJs: {
                src: ["dist/bundle.js"],
                dest: "dist/2.0/fineui.js"
            },

            bundleIEJs: {
                src: ["dist/core.js", "dist/fix/fix.ie.js", "dist/base.js", "dist/case.js", "dist/widget.js", "dist/fix/fix.compact.ie.js", "dist/router.js", "public/js/**/*.js", "public/js/index.js", "i18n/i18n.cn.js"],
                dest: "dist/bundle.ie.js"
            },

            versionFineuiIEJs: {
                src: ["dist/bundle.ie.js"],
                dest: "dist/2.0/fineui.ie.js"
            },

            bundleCss: {
                src: ["dist/core.css", "dist/base.css", "dist/widget.css", "public/css/app.css", "public/css/**/*.css", "fineui.typescript.css"],
                dest: "dist/bundle.css"
            },

            versionFineuiCss: {
                src: ["dist/bundle.css"],
                dest: "dist/2.0/fineui.css"
            },

            fineuiJs: {
                src: ["dist/es5.polyfill.js","dist/polyfill.js", "dist/core.js", "dist/fix/fix.js", "dist/base.js",
                    "dist/case.js", "dist/widget.js", "dist/router.js", "dist/fix/fix.compact.js", "ui/js/**/*.js"],
                dest: "dist/fineui.js"
            },

            fineuiIEJs: {
                src: ["dist/ie.polyfill.js", "dist/polyfill.js", "dist/core.js", "dist/fix/fix.ie.js", "dist/base.js",
                    "dist/case.js", "dist/widget.js", "dist/router.js", "dist/fix/fix.compact.ie.js", "ui/js/**/*.js"],
                dest: "dist/fineui.ie.js"
            },

            fineuiWithoutJqueryAndPolyfillJs: {
                src: sync(["src/core/foundation.js",
                    "src/core/lodash.js",
                    // 'src/core/mvc/**/*.js',
                    "src/core/base.js",
                    "src/core/ob.js",
                    "src/core/widget.js",
                    // 'src/core/model.js',
                    // 'src/core/view.js',
                    "src/core/shortcut.js",
                    "src/core/utils/*.js",
                    "src/core/behavior/behavior.js",
                    "src/core/wrapper/layout.js",
                    "src/core/plugin.js",
                    "src/core/**/*.js",
                    "!src/core/platform/web/**/*.js",

                    "src/data/data.js",
                    "src/data/**/*.js",

                    "dist/fix/fix.js",
                    "src/base/pane.js",
                    "src/base/single/single.js",
                    "src/base/single/text.js",
                    "src/base/single/button/button.basic.js",
                    "src/base/single/button/button.node.js",
                    "src/base/single/tip/tip.js",
                    "src/base/combination/group.button.js",
                    "src/base/combination/tree.button.js",
                    "src/base/combination/map.button.js",
                    "src/base/**/*.js",
                    "!src/base/tree/ztree/**/*.js",
                    "!src/base/single/input/file.js",

                    "src/case/combo/popup.bubble.js",
                    "src/case/**/*.js",
                    "!src/case/colorchooser/**/*.js",
                    "!src/case/tree/ztree/**/*.js",

                    "dist/widget.js", "dist/fix/fix.compact.js", "ui/js/**/*.js"]),
                dest: "dist/fineui_without_jquery_polyfill.js"
            },

            fineuiCss: {
                src: ["dist/core.css", "dist/base.css", "dist/widget.css", "ui/css/app.css", "ui/css/**/*.css", "fineui.typescript.css"],
                dest: "dist/fineui.css"
            },

            configJs: {
                src: ["demo/version.js", "i18n/i18n.cn.js"],
                dest: "dist/config.js"
            },
            demoJs: {
                src: ["demo/app.js", "demo/js/**/*.js", "demo/config.js"],
                dest: "dist/demo.js"
            },
            demoCss: {
                src: ["demo/css/**/*.css"],
                dest: "dist/demo.css"
            },
            utilsJs: {
                src: [
                    "src/core/foundation.js",
                    "src/core/lodash.js",
                    "src/core/var.js",
                    "src/core/func/array.js",
                    "src/core/func/number.js",
                    "src/core/func/string.js",
                    "src/core/func/date.js",
                    "src/core/func/function.js",
                    "src/core/base.js",
                    "src/core/ob.js",
                    "src/core/alias.js",
                    "src/core/inject.js",
                    "src/core/i18n.js",
                    "src/core/utils/*.js",
                    "i18n/i18n.cn.js",
                    "_mobile/date.i18n.cn.js",
                    "src/data/data.js",
                    "src/data/**/*.js"
                ],
                dest: "dist/utils.js"
            }
        },

        less: {
            demo: {
                expand: true,
                cwd: "demo/less",
                src: ["**/*.less"],
                dest: "demo/css/",
                ext: ".css"
            },
            main: {
                expand: true,
                cwd: "public/less",
                src: ["**/*.less"],
                dest: "public/css",
                ext: ".css"
            },
            ui: {
                expand: true,
                cwd: "ui/less",
                src: ["**/*.less"],
                dest: "ui/css",
                ext: ".css"
            },
            src: {
                expand: true,
                cwd: "src/less",
                src: ["**/*.less"],
                dest: "src/css",
                ext: ".css"
            },
            dev: {
                options: {
                    compress: true,
                    yuicompress: false
                }
            }
        },

        uglify: {
            options: {
                banner: "/*! <%= pkg.name %> <%= grunt.template.today(\"yyyy-mm-dd HH:MM:ss\") %> */\n",
                mangle: false,
                sourceMap: true,
                sourceMapIncludeSources: true,
                compress: {
                    unused: false,
                },
            },
            dist: {
                files: {
                    "dist/bundle.min.js": ["<%= concat.bundleJs.dest %>"],
                    "dist/bundle.ie.min.js": ["<%= concat.bundleIEJs.dest %>"],
                    "dist/utils.min.js": ["<%= concat.utilsJs.dest %>"],
                    "dist/fineui.min.js": ["<%= concat.fineuiJs.dest %>"],
                    "dist/fineui.ie.min.js": ["<%= concat.fineuiIEJs.dest %>"],
                    "dist/2.0/fineui.min.js": ["<%= concat.versionFineuiJs.dest %>"],
                    "dist/2.0/fineui.ie.min.js": ["<%= concat.versionFineuiIEJs.dest %>"]
                }
            }
        },

        cssmin: {

            bundleCss: {

                src: "<%= concat.bundleCss.dest %>",

                dest: "dist/bundle.min.css"

            },
            fineuiCss: {

                src: "<%= concat.fineuiCss.dest %>",

                dest: "dist/fineui.min.css"

            },

            versionFineuiMinCss: {
                src: "<%= concat.versionFineuiCss.dest %>",

                dest: "dist/2.0/fineui.min.css"
            }
        },

        jshint: {
            files: ["Gruntfile.js", "src/**/*.js"],
            options: {
                globals: {
                    jQuery: true,
                    console: true,
                    module: true,
                    document: true
                }
            }
        },
        copy: {
            js: {
                files: [
                    {
                        expand: true,
                        cwd: "dist",
                        src: [
                            "fineui.js"
                        ],
                        dest: "dist/",
                        rename: function (dest, src) {
                            return dest + src.replace(".js", ".min.js");
                        }
                    }
                ]
            }
        },
        watch: {
            scripts: {
                files: ["src/**/*.js", "src/**/*.less", "demo/js/**/*.js", "demo/app.js", "demo/version.js", "demo/config.js", "demo/less/**/*.less", "!src/**/__test__/*.js"],
                tasks: ["less", "concat"],
                options: {
                    spanw: true,
                    interrupt: true
                }
            },
            livereload: {
                options: {
                    livereload: "<%= connect.options.livereload %>"
                },
                files: ["src/**/*.js", "!src/**/__test__/*.js", "src/**/*.less"]
            }
        },
        connect: {
            options: {
                port: 9000,
                open: true,
                livereload: 35729,
                // Change this to '0.0.0.0' to access the server from outside
                hostname: "0.0.0.0"
            },
            server: {
                options: {
                    port: 9001
                }
            }
        },
        clean: ["src/css", "demo/css"]
    });

    grunt.loadNpmTasks("grunt-contrib-uglify");
    grunt.loadNpmTasks("grunt-contrib-jshint");
    grunt.loadNpmTasks("grunt-contrib-less");
    grunt.loadNpmTasks("grunt-contrib-watch");
    grunt.loadNpmTasks("grunt-contrib-concat");
    grunt.loadNpmTasks("grunt-contrib-cssmin");
    grunt.loadNpmTasks("grunt-contrib-connect");
    grunt.loadNpmTasks("grunt-contrib-clean");
    grunt.loadNpmTasks("grunt-contrib-copy");

    grunt.registerTask("analyze", "code analysis", function () {
        const authors = ["test_author_imp", "test_author_teller", "test_author_fay", "test_author_young", "test_author_windy", "test_author_lei.wang", "test_author_Kira", "test_author_Zhenfei.Li"];
        const info = [];
        authors.forEach(function (auth) {
            info.push({
                author: auth,
                reg: new RegExp(auth, "g"),
                count: 0
            });
        });
        const testFiles = grunt.file.expand(["src/**/*.test.js", "test/**/*.test.js"]);
        testFiles.forEach(function (el) {
            const fileStr = grunt.file.read(el);
            authors.forEach(function (auth, idx) {
                const res = fileStr.match(info[idx].reg);
                if (res != null) {
                    info[idx].count += res.length;
                }
            });
        });

        const todayStat = {};
        info.forEach(function (inf) {
            todayStat[inf.author] = inf.count;
        });
        const date = grunt.template.today("yyyy-mm-dd");
        const dest = "test/unit.test.statistic.json";
        let stat;
        try {
            stat = grunt.file.readJSON(dest);
        } catch (e) {
            stat = {};
        }
        if (!stat.date || stat.date === {}) {
            stat[date] = todayStat;
        }
        grunt.file.write(dest, JSON.stringify(stat));
    });

    var defaultTask = ["clean", "less", "concat", "watch"];
    grunt.registerTask("default", defaultTask);
    grunt.registerTask("compile", function () {
        grunt.config.set("connect.options.open", false);
        grunt.task.run(defaultTask);
    });
    grunt.registerTask("build", ["clean", "less", "cssmin", "concat", "uglify"]);
    grunt.registerTask("fake-build", ["clean", "less", "cssmin", "concat", "copy"]);
};
<commit_msg>chore: 提供不含normalize的css<commit_after>module.exports = function (grunt) {
    function sync(patterns) {
        return [...new Set(grunt.file.expand({
            filter: path => !new RegExp(/__test__/g).test(path),
        }, patterns))];
    }

    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON("package.json"),
        concat: {
            options: {
                separator: "",
                sourceMap: true,
                sourceMapStyle: "link",
            },
            polyfillJs: {
                src: ["src/core/foundation.js", "src/polyfill/**/*.js"],
                dest: "dist/polyfill.js"
            },
            coreJs: {
                src: sync([
                    "src/core/foundation.js",
                    "src/core/lodash.js",
                    // 'src/core/mvc/**/*.js',
                    "src/core/base.js",
                    "src/core/ob.js",
                    "src/core/widget.js",
                    // 'src/core/model.js',
                    // 'src/core/view.js',
                    "src/core/shortcut.js",
                    "src/core/utils/**/*.js",
                    "src/core/behavior/behavior.js",
                    "src/core/wrapper/layout.js",
                    "src/core/plugin.js",
                    "src/core/**/*.js",

                    "src/data/data.js",
                    "src/data/**/*.js"
                ]),
                dest: "dist/core.js"
            },

            // 最基础的控件
            baseJs: {
                src: sync([
                    "src/third/**/*.js",
                    "src/base/pane.js",
                    "src/base/single/single.js",
                    "src/base/single/text.js",
                    "src/base/single/button/button.basic.js",
                    "src/base/single/button/button.node.js",
                    "src/base/single/tip/tip.js",
                    "src/base/combination/group.button.js",
                    "src/base/combination/tree.button.js",
                    "src/base/tree/ztree/treeview.js",
                    "src/base/tree/ztree/asynctree.js",
                    "src/base/tree/ztree/parttree.js",
                    "src/base/tree/ztree/list/listtreeview.js",
                    "src/base/tree/ztree/list/listasynctree.js",
                    "src/base/tree/ztree/list/listparttree.js",
                    "src/base/**/*.js"
                ]),
                dest: "dist/base.js"
            },
            // 实现好的一些基础实例
            caseJs: {
                src: sync([
                    "src/case/combo/popup.bubble.js",
                    "src/case/**/*.js"
                ]),
                dest: "dist/case.js"
            },
            widgetJs: {
                src: sync([
                    "src/widget/**/*.js",
                    "src/component/**/*.js"
                ]),
                dest: "dist/widget.js"
            },
            routerJs: {
                src: [
                    "src/router/**/*.js"
                ],
                dest: "dist/router.js"
            },
            coreCss: {
                src: ["src/css/core/**/*.css", "src/css/theme/**/*.css"],
                dest: "dist/core.css"
            },
            coreWithoutNormalizeCss: {
                src: ["src/css/core/**/*.css", "src/css/theme/**/*.css", "!src/css/core/normalize.css", "!src/css/core/normalize2.css"],
                dest: "dist/core_without_normalize.css"
            },
            baseCss: {
                src: ["src/css/base/**/*.css"],
                dest: "dist/base.css"
            },
            widgetCss: {
                src: ["src/css/widget/**/*.css"],
                dest: "dist/widget.css"
            },
            resourceCss: {
                src: ["src/css/resource/**/*.css"],
                dest: "dist/resource.css"
            },

            bundleJs: {
                src: ["dist/core.js", "dist/fix/fix.js", "dist/base.js", "dist/case.js", "dist/widget.js", "dist/fix/fix.compact.js", "dist/router.js", "public/js/**/*.js", "public/js/index.js", "i18n/i18n.cn.js"],
                dest: "dist/bundle.js",
            },

            versionFineuiJs: {
                src: ["dist/bundle.js"],
                dest: "dist/2.0/fineui.js"
            },

            bundleIEJs: {
                src: ["dist/core.js", "dist/fix/fix.ie.js", "dist/base.js", "dist/case.js", "dist/widget.js", "dist/fix/fix.compact.ie.js", "dist/router.js", "public/js/**/*.js", "public/js/index.js", "i18n/i18n.cn.js"],
                dest: "dist/bundle.ie.js"
            },

            versionFineuiIEJs: {
                src: ["dist/bundle.ie.js"],
                dest: "dist/2.0/fineui.ie.js"
            },

            bundleCss: {
                src: ["dist/core.css", "dist/base.css", "dist/widget.css", "public/css/app.css", "public/css/**/*.css", "fineui.typescript.css"],
                dest: "dist/bundle.css"
            },

            bundleWithoutNormalizeCss: {
                src: ["dist/core_without_normalize.css", "dist/base.css", "dist/widget.css", "public/css/app.css", "public/css/**/*.css", "fineui.typescript.css"],
                dest: "dist/bundle_without_normalize.css"
            },

            versionFineuiCss: {
                src: ["dist/bundle.css"],
                dest: "dist/2.0/fineui.css"
            },

            versionFineuiWithoutNormalizeCss: {
                src: ["dist/bundle_without_normalize.css"],
                dest: "dist/2.0/fineui_without_normalize.css"
            },

            fineuiJs: {
                src: ["dist/es5.polyfill.js","dist/polyfill.js", "dist/core.js", "dist/fix/fix.js", "dist/base.js",
                    "dist/case.js", "dist/widget.js", "dist/router.js", "dist/fix/fix.compact.js", "ui/js/**/*.js"],
                dest: "dist/fineui.js"
            },

            fineuiIEJs: {
                src: ["dist/ie.polyfill.js", "dist/polyfill.js", "dist/core.js", "dist/fix/fix.ie.js", "dist/base.js",
                    "dist/case.js", "dist/widget.js", "dist/router.js", "dist/fix/fix.compact.ie.js", "ui/js/**/*.js"],
                dest: "dist/fineui.ie.js"
            },

            fineuiWithoutJqueryAndPolyfillJs: {
                src: sync(["src/core/foundation.js",
                    "src/core/lodash.js",
                    // 'src/core/mvc/**/*.js',
                    "src/core/base.js",
                    "src/core/ob.js",
                    "src/core/widget.js",
                    // 'src/core/model.js',
                    // 'src/core/view.js',
                    "src/core/shortcut.js",
                    "src/core/utils/*.js",
                    "src/core/behavior/behavior.js",
                    "src/core/wrapper/layout.js",
                    "src/core/plugin.js",
                    "src/core/**/*.js",
                    "!src/core/platform/web/**/*.js",

                    "src/data/data.js",
                    "src/data/**/*.js",

                    "dist/fix/fix.js",
                    "src/base/pane.js",
                    "src/base/single/single.js",
                    "src/base/single/text.js",
                    "src/base/single/button/button.basic.js",
                    "src/base/single/button/button.node.js",
                    "src/base/single/tip/tip.js",
                    "src/base/combination/group.button.js",
                    "src/base/combination/tree.button.js",
                    "src/base/combination/map.button.js",
                    "src/base/**/*.js",
                    "!src/base/tree/ztree/**/*.js",
                    "!src/base/single/input/file.js",

                    "src/case/combo/popup.bubble.js",
                    "src/case/**/*.js",
                    "!src/case/colorchooser/**/*.js",
                    "!src/case/tree/ztree/**/*.js",

                    "dist/widget.js", "dist/fix/fix.compact.js", "ui/js/**/*.js"]),
                dest: "dist/fineui_without_jquery_polyfill.js"
            },

            fineuiCss: {
                src: ["dist/core.css", "dist/base.css", "dist/widget.css", "ui/css/app.css", "ui/css/**/*.css", "fineui.typescript.css"],
                dest: "dist/fineui.css"
            },

            configJs: {
                src: ["demo/version.js", "i18n/i18n.cn.js"],
                dest: "dist/config.js"
            },
            demoJs: {
                src: ["demo/app.js", "demo/js/**/*.js", "demo/config.js"],
                dest: "dist/demo.js"
            },
            demoCss: {
                src: ["demo/css/**/*.css"],
                dest: "dist/demo.css"
            },
            utilsJs: {
                src: [
                    "src/core/foundation.js",
                    "src/core/lodash.js",
                    "src/core/var.js",
                    "src/core/func/array.js",
                    "src/core/func/number.js",
                    "src/core/func/string.js",
                    "src/core/func/date.js",
                    "src/core/func/function.js",
                    "src/core/base.js",
                    "src/core/ob.js",
                    "src/core/alias.js",
                    "src/core/inject.js",
                    "src/core/i18n.js",
                    "src/core/utils/*.js",
                    "i18n/i18n.cn.js",
                    "_mobile/date.i18n.cn.js",
                    "src/data/data.js",
                    "src/data/**/*.js"
                ],
                dest: "dist/utils.js"
            }
        },

        less: {
            demo: {
                expand: true,
                cwd: "demo/less",
                src: ["**/*.less"],
                dest: "demo/css/",
                ext: ".css"
            },
            main: {
                expand: true,
                cwd: "public/less",
                src: ["**/*.less"],
                dest: "public/css",
                ext: ".css"
            },
            ui: {
                expand: true,
                cwd: "ui/less",
                src: ["**/*.less"],
                dest: "ui/css",
                ext: ".css"
            },
            src: {
                expand: true,
                cwd: "src/less",
                src: ["**/*.less"],
                dest: "src/css",
                ext: ".css"
            },
            dev: {
                options: {
                    compress: true,
                    yuicompress: false
                }
            }
        },

        uglify: {
            options: {
                banner: "/*! <%= pkg.name %> <%= grunt.template.today(\"yyyy-mm-dd HH:MM:ss\") %> */\n",
                mangle: false,
                sourceMap: true,
                sourceMapIncludeSources: true,
                compress: {
                    unused: false,
                },
            },
            dist: {
                files: {
                    "dist/bundle.min.js": ["<%= concat.bundleJs.dest %>"],
                    "dist/bundle.ie.min.js": ["<%= concat.bundleIEJs.dest %>"],
                    "dist/utils.min.js": ["<%= concat.utilsJs.dest %>"],
                    "dist/fineui.min.js": ["<%= concat.fineuiJs.dest %>"],
                    "dist/fineui.ie.min.js": ["<%= concat.fineuiIEJs.dest %>"],
                    "dist/2.0/fineui.min.js": ["<%= concat.versionFineuiJs.dest %>"],
                    "dist/2.0/fineui.ie.min.js": ["<%= concat.versionFineuiIEJs.dest %>"]
                }
            }
        },

        cssmin: {

            bundleCss: {

                src: "<%= concat.bundleCss.dest %>",

                dest: "dist/bundle.min.css"

            },
            fineuiCss: {

                src: "<%= concat.fineuiCss.dest %>",

                dest: "dist/fineui.min.css"

            },

            versionFineuiMinCss: {
                src: "<%= concat.versionFineuiCss.dest %>",

                dest: "dist/2.0/fineui.min.css"
            },

            versionFineuiWithoutNormalizeMinCss: {
                src: "<%= concat.versionFineuiWithoutNormalizeCss.dest %>",

                dest: "dist/2.0/fineui_without_normalize.min.css"
            },
        },

        jshint: {
            files: ["Gruntfile.js", "src/**/*.js"],
            options: {
                globals: {
                    jQuery: true,
                    console: true,
                    module: true,
                    document: true
                }
            }
        },
        copy: {
            js: {
                files: [
                    {
                        expand: true,
                        cwd: "dist",
                        src: [
                            "fineui.js"
                        ],
                        dest: "dist/",
                        rename: function (dest, src) {
                            return dest + src.replace(".js", ".min.js");
                        }
                    }
                ]
            }
        },
        watch: {
            scripts: {
                files: ["src/**/*.js", "src/**/*.less", "demo/js/**/*.js", "demo/app.js", "demo/version.js", "demo/config.js", "demo/less/**/*.less", "!src/**/__test__/*.js"],
                tasks: ["less", "concat"],
                options: {
                    spanw: true,
                    interrupt: true
                }
            },
            livereload: {
                options: {
                    livereload: "<%= connect.options.livereload %>"
                },
                files: ["src/**/*.js", "!src/**/__test__/*.js", "src/**/*.less"]
            }
        },
        connect: {
            options: {
                port: 9000,
                open: true,
                livereload: 35729,
                // Change this to '0.0.0.0' to access the server from outside
                hostname: "0.0.0.0"
            },
            server: {
                options: {
                    port: 9001
                }
            }
        },
        clean: ["src/css", "demo/css"]
    });

    grunt.loadNpmTasks("grunt-contrib-uglify");
    grunt.loadNpmTasks("grunt-contrib-jshint");
    grunt.loadNpmTasks("grunt-contrib-less");
    grunt.loadNpmTasks("grunt-contrib-watch");
    grunt.loadNpmTasks("grunt-contrib-concat");
    grunt.loadNpmTasks("grunt-contrib-cssmin");
    grunt.loadNpmTasks("grunt-contrib-connect");
    grunt.loadNpmTasks("grunt-contrib-clean");
    grunt.loadNpmTasks("grunt-contrib-copy");

    grunt.registerTask("analyze", "code analysis", function () {
        const authors = ["test_author_imp", "test_author_teller", "test_author_fay", "test_author_young", "test_author_windy", "test_author_lei.wang", "test_author_Kira", "test_author_Zhenfei.Li"];
        const info = [];
        authors.forEach(function (auth) {
            info.push({
                author: auth,
                reg: new RegExp(auth, "g"),
                count: 0
            });
        });
        const testFiles = grunt.file.expand(["src/**/*.test.js", "test/**/*.test.js"]);
        testFiles.forEach(function (el) {
            const fileStr = grunt.file.read(el);
            authors.forEach(function (auth, idx) {
                const res = fileStr.match(info[idx].reg);
                if (res != null) {
                    info[idx].count += res.length;
                }
            });
        });

        const todayStat = {};
        info.forEach(function (inf) {
            todayStat[inf.author] = inf.count;
        });
        const date = grunt.template.today("yyyy-mm-dd");
        const dest = "test/unit.test.statistic.json";
        let stat;
        try {
            stat = grunt.file.readJSON(dest);
        } catch (e) {
            stat = {};
        }
        if (!stat.date || stat.date === {}) {
            stat[date] = todayStat;
        }
        grunt.file.write(dest, JSON.stringify(stat));
    });

    var defaultTask = ["clean", "less", "concat", "watch"];
    grunt.registerTask("default", defaultTask);
    grunt.registerTask("compile", function () {
        grunt.config.set("connect.options.open", false);
        grunt.task.run(defaultTask);
    });
    grunt.registerTask("build", ["clean", "less", "cssmin", "concat", "uglify"]);
    grunt.registerTask("fake-build", ["clean", "less", "cssmin", "concat", "copy"]);
};
<|endoftext|>