<commit_before>'use strict';

// Requires
// ========

// Node
// ----
// https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
const exec = require('child_process').exec;

// Gulp
// ----
const gulp = require('gulp');
const gulpif = require('gulp-if');
// const ignore
const gutil = require('gulp-util');
const del = require('del');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const browserSync = require('browser-sync').create();

// Pug -> HTML
// -----------
const pug = require('gulp-pug');

// JSX/ES6 -> ES5
// --------------
const browserify = require('browserify');
const babelify = require('babelify');
const envify = require('envify');
const uglifyify = require('uglifyify');
const collapse = require('bundle-collapser/plugin');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const merge = require('merge-stream');
const browserifyInc = require('browserify-incremental');

// SCSS -> CSS
// -----------
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const cssmin = require('gulp-cssmin');

// Image processing
// ----------------
const imagemin = require('gulp-imagemin'); // supports png, jpg, gif, and svg only
const cache = require('gulp-cache');

// JSON processing
// ---------------
const jsoncombine = require('gulp-jsoncombine');

// Appcache creation
// -----------------
const manifest = require('gulp-manifest');

// Configuration Objects
// =====================

// Environmental variables
// const isProduction = process.env.NODE_ENV === 'production';
const isGitHubPages = process.env.DEST === 'github';

let ghPages = '';

if (isGitHubPages) {
  ghPages = '.publish/';
}

// Entry points and sources
// ------------------------
const paths = {
  entry: { // entry points
    scripts: [
      'client/scripts/arcademode/main.jsx',
      'client/scripts/public/index.js',
      'client/scripts/public/standalones/ww.js',
      'client/scripts/public/standalones/wwBenchmark.js',
      'client/scripts/public/standalones/sw.js'
    ],
    stylesheets: ['client/stylesheets/style.scss']
  },
  fonts: ['client/fonts/**/*'], // font sources
  images: ['client/images/**/*'], // image sources
  jsons: { // json-related items
    appConfig: ['client/jsons/appConfig.json'],
    fccInterviewSeed: ['client/jsons/seed/**/*'],
    js2jsonScript: ['bin/js2json_challenges.js']
  },
  challengesJs: ['client/scripts/challenges/**/*'],
  scripts: ['client/scripts/**/*'],
  stylesheets: ['client/stylesheets/**/*'],
  vendor: {
    scripts: ['client/scripts/vendor/**/*'], // browserify currently imports loop-protect
    stylesheets: ['client/stylesheets/vendor/**/*.css']
  },
  views: ['server/views/*.pug'] // generated for static sites
};

// Gulp Tasks
// ==========

// Build tasks
// -----------
gulp.task('build-font', () =>
  gulp.src(paths.fonts, { base: 'client/fonts' })
    .pipe(gulp.dest(`${ghPages}public/font`)) // no processing: fonts are already optimized
    .pipe(browserSync.reload({ stream: true }))
);

gulp.task('build-img', () => {
  const s1 = gulp.src('client/images/favicon.ico')
    .pipe(isGitHubPages ? gulp.dest(ghPages) : gulp.dest('public/img'));

  const s2 = gulp.src(paths.images)
    .pipe(cache(imagemin([
      imagemin.gifsicle({ interlaced: true }),
      // imagemin.jpegtran({ progressive: true }), // Tuomas: Cannot get this to work, crashes gulp
      imagemin.optipng({ optimizationLevel: 5 })
    ])))
    .pipe(gulp.dest(`${ghPages}public/img`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-json', () => {
  // pass through individual files (currently algo+ds) for individual mode display:
  const s1 = gulp.src(paths.jsons.fccInterviewSeed)
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  // pass through a bundled version for mixed mode display:
  const s2 = gulp.src(paths.jsons.fccInterviewSeed)
    .pipe(jsoncombine('challenges-combined.json', data =>
      new Buffer(JSON.stringify(data))
    ))
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  const s3 = gulp.src(paths.jsons.appConfig)
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2, s3);
});

// Builds the arcade-mode json from js challenge files
gulp.task('build-js2json', done => {
  const arcade2json = `bin/js2json_challenges.js\
    --force -f client/scripts/challenges/arcade/*.js -o ${ghPages}public/json/challenges-arcade.json`;
  const rosetta2json = `bin/js2json_challenges.js\
    --force -f client/scripts/challenges/rosettacode/formatted/**/*.js -o ${ghPages}public/json/challenges-rosetta.json`;

  return Promise.all([arcade2json, rosetta2json].map(js2json =>
    new Promise((resolve, reject) => {
      exec(js2json, err => {
        if (err) {
          console.error(`exec error: ${err}`);
          reject(err);
        }
        else resolve();
      });
    })
  ))
  .then(() => {
    done();
  });
});

gulp.task('build-js', () => {
  console.log('gulpfile.js: build-js: Building production js. Takes approximately 60 seconds.');
  console.log('gulpfile.js: build-js: For development, use build-js-inc instead for faster iteration cycles.');
  console.log('gulpfile.js: build-js: Top-level gulp tasks used in development are:');
  console.log('gulpfile.js: build-js: build-dev - includes build-js-inc.');
  console.log('gulpfile.js: build-js: watch-dev - includes build-dev; watches for changes.');
  console.log('gulpfile.js: build-js: watch-sync - includes build-dev; watches for changes and hot reloads with browserSync at port 3000. TODO: fix this task. Currently buggy in that it only hot reloads automatically some of the time and at other times require a complete restart of the gulp task.');
  return merge(...paths.entry.scripts.map(script =>
    browserify({
      entries: script,
      extensions: ['.jsx'],
      debug: true
    })
      .transform(babelify, { presets: ['env', 'react'] })
      .transform(envify)
      .transform({
        global: true,
        ignore: ['**/node_modules/benchmark/*']
      }, uglifyify)
      .plugin(collapse)
      .bundle()
      .on('error', gutil.log.bind(gutil, 'Browserify error.'))
      .pipe(source(`./${script.split('/')[script.split('/').length - 1]}`))
      .pipe(buffer())
      .pipe(plumber())
      .pipe(rename(path => {
        path.extname = '.bundle.js';
      }))
      .pipe(uglify({ mangle: true }))
      .pipe(gulp.dest(`${ghPages}public/js`))
      .pipe(isGitHubPages ? gulpif('*sw.bundle.js', gulp.dest(ghPages)) : gutil.noop())
      .pipe(browserSync.reload({ stream: true }))
  ));
});

gulp.task('build-css', () => {
  const s1 = gulp.src(paths.entry.stylesheets[0]) // only the entry/index sheet, style.scss
    .pipe(plumber())
    .pipe(sass())
    .pipe(autoprefixer())
    .pipe(cssmin())
    .pipe(gulp.dest(`${ghPages}public/css`))
    .pipe(browserSync.reload({ stream: true }));

  // any vendor css files, minify then pass through
  const s2 = gulp.src(paths.vendor.stylesheets, { base: 'client/stylesheets/vendor' })
    .pipe(plumber())
    .pipe(autoprefixer())
    .pipe(cssmin())
    .pipe(rename(path => {
      path.extname = '.min.css';
    }))
    .pipe(gulp.dest(`${ghPages}public/css/vendor`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-view', () =>
  gulp.src(paths.views, { base: 'server/views' })
    .pipe(plumber())
    .pipe(pug({ pretty: true, basedir: 'server/views' }))
    .pipe(isGitHubPages ? gulp.dest(ghPages) : gutil.noop())
    .pipe(browserSync.reload({ stream: true }))
);

// Appcache file creation
// ----------------------
gulp.task('build-appcache', () =>
  gulp.src('public/**/*', { base: 'public' })
    .pipe(manifest({
      hash: true,
      preferOnline: true,
      network: ['*'],
      // fallback:
      filename: 'offline.appcache',
      exclude: 'offline.appcache'
    }))
    .pipe(gulp.dest(`${ghPages}public`))
    .pipe(browserSync.reload({ stream: true }))
);

// DEV-tasks (not used in production)
//-----------------------------------
function handleErrors(...errorArgs) {
  const args = Array.prototype.slice.call(errorArgs);
  notify.onError({
    title: 'Compile Error',
    message: '<%= error.message %>'
  }).apply(this, args);
  this.emit('end'); // Keep gulp from hanging on this task
}

// Incrementally building the js
gulp.task('build-js-inc', () =>
  merge(...paths.entry.scripts.map(script => {
    const b = browserify(Object.assign({}, browserifyInc.args,
      {
        entries: script,
        extensions: ['.jsx'],
        debug: true
      }
    ));

    browserifyInc(b, { cacheFile: './browserify-cache.json' });

    return b.transform(babelify, { presets: ['env', 'react'] })
      .bundle()
        .on('error', handleErrors)
        .pipe(source(`./${script.split('/')[script.split('/').length - 1]}`))
        .pipe(buffer())
        .pipe(plumber())
        .pipe(rename(path => {
          path.extname = '.bundle.js';
        }))
        .pipe(gulp.dest('public/js'))
        .pipe(browserSync.reload({ stream: true }));
  }))
);

gulp.task('build-appcache-dev', () =>
  gulp.src('public/**/*', { base: 'public' })
    .pipe(manifest({
      hash: true,
      preferOnline: true,
      network: ['*'],
      // fallback:
      filename: 'offline.appcache',
      exclude: 'offline.appcache'
    }))
    .pipe(gulp.dest('public'))
    .pipe(browserSync.reload({ stream: true }))
);

// Cleaners
// --------

// rm -rf public directory
gulp.task('clean:static', () => {
  if (isGitHubPages) {
    return del(['.publish/**/*']);
  }
  return del(['public/**/*']);
});

gulp.task('clear-cache', done => cache.clearAll(done)); // clears img cache

// Bundled tasks
// -------------
gulp.task('build-types',
  gulp.series(
    'build-json',
    'build-js2json',
    gulp.parallel('build-font', 'build-img', 'build-js', 'build-css', 'build-view')
  )
);

gulp.task('build-types-dev',
  gulp.series(
    'build-json',
    'build-js2json',
    gulp.parallel('build-font', 'build-img', 'build-js-inc', 'build-css', 'build-view')
  )
);

gulp.task('build', gulp.series('clean:static', 'build-types', 'build-appcache'));
gulp.task('build-dev', gulp.series('build-types-dev', 'build-appcache-dev'));

gulp.task('watch', gulp.series('build', done => {
  gulp.watch(paths.fonts, gulp.task('build-font'));
  gulp.watch(paths.images, gulp.task('build-img'));
  gulp.watch([...Object.values(paths.jsons)], gulp.task('build-json'));
  gulp.watch(paths.challengesJs, gulp.task('build-js2json'));
  gulp.watch(paths.scripts, gulp.task('build-js'));
  gulp.watch(paths.stylesheets, gulp.task('build-css'));
  done();
}));

gulp.task('watch-dev', gulp.series('build-dev', done => {
  const jsonFiles = Object.keys(paths.jsons).map(item => paths.jsons[item]);
  gulp.watch(paths.fonts, gulp.task('build-font'));
  gulp.watch(paths.images, gulp.task('build-img'));
  gulp.watch(jsonFiles, gulp.task('build-json'));
  gulp.watch(paths.challengesJs, gulp.task('build-js2json'));
  gulp.watch(paths.scripts, gulp.task('build-js-inc'));
  gulp.watch(paths.stylesheets, gulp.task('build-css'));
  done();
}));

// Hot-reloading
// -------------
gulp.task('browser-sync', gulp.series('watch-dev', done => {
  browserSync.init({
    proxy: {
      target: 'localhost:8080',
      ws: true // websockets
    },
    ghostMode: true, // sync across all browsers
    reloadDelay: 2000, // give gulp tasks time to reprocess files
    port: 3000 // browserSync port
  }, done);
}));

// GitHub pages deploy
// -------------------

// gulp.task('deploy-gh-pages', gulp.series('build', () =>
//   gulp.src('public/**/*')
//     .pipe(ghPages())
// ));

// Helper tasks
// ------------
/*
gulp.task('bundle', ['build'], () =>
  gulp.src(paths.scripts.map(script =>
    `./public/js/${script.split('/')[script.split('/').length - 1]}`
  ))
    .pipe(concat('bundle.js'))
    .pipe(gulp.dest('public/js'))
);

gulp.task('bundle-dev', ['build-dev'], () =>
  gulp.src(paths.scripts.map(script =>
    `./public/js/${script.split('/')[script.split('/').length - 1]}`
  ))
    .pipe(concat('bundle.js'))
    .pipe(gulp.dest('public/js'))
);
*/
<commit_msg>update to process appConfig files<commit_after>'use strict';

// Requires
// ========

// Node
// ----
// https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
const exec = require('child_process').exec;

// Gulp
// ----
const gulp = require('gulp');
const gulpif = require('gulp-if');
// const ignore
const gutil = require('gulp-util');
const del = require('del');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const browserSync = require('browser-sync').create();

// Pug -> HTML
// -----------
const pug = require('gulp-pug');

// JSX/ES6 -> ES5
// --------------
const browserify = require('browserify');
const babelify = require('babelify');
const envify = require('envify');
const uglifyify = require('uglifyify');
const collapse = require('bundle-collapser/plugin');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const merge = require('merge-stream');
const browserifyInc = require('browserify-incremental');

// SCSS -> CSS
// -----------
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const cssmin = require('gulp-cssmin');

// Image processing
// ----------------
const imagemin = require('gulp-imagemin'); // supports png, jpg, gif, and svg only
const cache = require('gulp-cache');

// JSON processing
// ---------------
const jsoncombine = require('gulp-jsoncombine');

// Appcache creation
// -----------------
const manifest = require('gulp-manifest');

// Configuration Objects
// =====================

// Environmental variables
const isProduction = process.env.NODE_ENV === 'production';
const isGitHubPages = process.env.DEST === 'github';

let ghPages = '';

if (isGitHubPages) {
  ghPages = '.publish/';
}

// Entry points and sources
// ------------------------
const paths = {
  entry: { // entry points
    scripts: [
      'client/scripts/arcademode/main.jsx',
      'client/scripts/public/index.js',
      'client/scripts/public/standalones/ww.js',
      'client/scripts/public/standalones/wwBenchmark.js',
      'client/scripts/public/standalones/sw.js'
    ],
    stylesheets: ['client/stylesheets/style.scss']
  },
  fonts: ['client/fonts/**/*'], // font sources
  images: ['client/images/**/*'], // image sources
  jsons: { // json-related items
    appConfig: ['client/jsons/appConfig.*'],
    fccInterviewSeed: ['client/jsons/seed/**/*'],
    js2jsonScript: ['bin/js2json_challenges.js']
  },
  challengesJs: ['client/scripts/challenges/**/*'],
  scripts: ['client/scripts/**/*'],
  stylesheets: ['client/stylesheets/**/*'],
  vendor: {
    scripts: ['client/scripts/vendor/**/*'], // browserify currently imports loop-protect
    stylesheets: ['client/stylesheets/vendor/**/*.css']
  },
  views: ['server/views/*.pug'] // generated for static sites
};

// Gulp Tasks
// ==========

// Build tasks
// -----------
gulp.task('build-font', () =>
  gulp.src(paths.fonts, { base: 'client/fonts' })
    .pipe(gulp.dest(`${ghPages}public/font`)) // no processing: fonts are already optimized
    .pipe(browserSync.reload({ stream: true }))
);

gulp.task('build-img', () => {
  const s1 = gulp.src('client/images/favicon.ico')
    .pipe(isGitHubPages ? gulp.dest(ghPages) : gulp.dest('public/img'));

  const s2 = gulp.src(paths.images)
    .pipe(cache(imagemin([
      imagemin.gifsicle({ interlaced: true }),
      // imagemin.jpegtran({ progressive: true }), // Tuomas: Cannot get this to work, crashes gulp
      imagemin.optipng({ optimizationLevel: 5 })
    ])))
    .pipe(gulp.dest(`${ghPages}public/img`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-json', () => {
  // pass through individual files (currently algo+ds) for individual mode display:
  const s1 = gulp.src(paths.jsons.fccInterviewSeed)
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  // pass through a bundled version for mixed mode display:
  const s2 = gulp.src(paths.jsons.fccInterviewSeed)
    .pipe(jsoncombine('challenges-combined.json', data =>
      new Buffer(JSON.stringify(data))
    ))
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  const appConfigFile = isProduction ? 'client/jsons/appConfig.production.json' : 'client/jsons/appConfig.devel.json';

  const s3 = gulp.src(appConfigFile)
    .pipe(rename('appConfig.json'))
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2, s3);
});

// Builds the arcade-mode json from js challenge files
gulp.task('build-js2json', done => {
  const arcade2json = `bin/js2json_challenges.js\
    --force -f client/scripts/challenges/arcade/*.js -o ${ghPages}public/json/challenges-arcade.json`;
  const rosetta2json = `bin/js2json_challenges.js\
    --force -f client/scripts/challenges/rosettacode/formatted/**/*.js -o ${ghPages}public/json/challenges-rosetta.json`;

  return Promise.all([arcade2json, rosetta2json].map(js2json =>
    new Promise((resolve, reject) => {
      exec(js2json, err => {
        if (err) {
          console.error(`exec error: ${err}`);
          reject(err);
        }
        else resolve();
      });
    })
  ))
  .then(() => {
    done();
  });
});

gulp.task('build-js', () => {
  console.log('gulpfile.js: build-js: Building production js. Takes approximately 60 seconds.');
  console.log('gulpfile.js: build-js: For development, use build-js-inc instead for faster iteration cycles.');
  console.log('gulpfile.js: build-js: Top-level gulp tasks used in development are:');
  console.log('gulpfile.js: build-js: build-dev - includes build-js-inc.');
  console.log('gulpfile.js: build-js: watch-dev - includes build-dev; watches for changes.');
  console.log('gulpfile.js: build-js: watch-sync - includes build-dev; watches for changes and hot reloads with browserSync at port 3000. TODO: fix this task. Currently buggy in that it only hot reloads automatically some of the time and at other times require a complete restart of the gulp task.');
  return merge(...paths.entry.scripts.map(script =>
    browserify({
      entries: script,
      extensions: ['.jsx'],
      debug: true
    })
      .transform(babelify, { presets: ['env', 'react'] })
      .transform(envify)
      .transform({
        global: true,
        ignore: ['**/node_modules/benchmark/*']
      }, uglifyify)
      .plugin(collapse)
      .bundle()
      .on('error', gutil.log.bind(gutil, 'Browserify error.'))
      .pipe(source(`./${script.split('/')[script.split('/').length - 1]}`))
      .pipe(buffer())
      .pipe(plumber())
      .pipe(rename(path => {
        path.extname = '.bundle.js';
      }))
      .pipe(uglify({ mangle: true }))
      .pipe(gulp.dest(`${ghPages}public/js`))
      .pipe(isGitHubPages ? gulpif('*sw.bundle.js', gulp.dest(ghPages)) : gutil.noop())
      .pipe(browserSync.reload({ stream: true }))
  ));
});

gulp.task('build-css', () => {
  const s1 = gulp.src(paths.entry.stylesheets[0]) // only the entry/index sheet, style.scss
    .pipe(plumber())
    .pipe(sass())
    .pipe(autoprefixer())
    .pipe(cssmin())
    .pipe(gulp.dest(`${ghPages}public/css`))
    .pipe(browserSync.reload({ stream: true }));

  // any vendor css files, minify then pass through
  const s2 = gulp.src(paths.vendor.stylesheets, { base: 'client/stylesheets/vendor' })
    .pipe(plumber())
    .pipe(autoprefixer())
    .pipe(cssmin())
    .pipe(rename(path => {
      path.extname = '.min.css';
    }))
    .pipe(gulp.dest(`${ghPages}public/css/vendor`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-view', () =>
  gulp.src(paths.views, { base: 'server/views' })
    .pipe(plumber())
    .pipe(pug({ pretty: true, basedir: 'server/views' }))
    .pipe(isGitHubPages ? gulp.dest(ghPages) : gutil.noop())
    .pipe(browserSync.reload({ stream: true }))
);

// Appcache file creation
// ----------------------
gulp.task('build-appcache', () =>
  gulp.src('public/**/*', { base: 'public' })
    .pipe(manifest({
      hash: true,
      preferOnline: true,
      network: ['*'],
      // fallback:
      filename: 'offline.appcache',
      exclude: 'offline.appcache'
    }))
    .pipe(gulp.dest(`${ghPages}public`))
    .pipe(browserSync.reload({ stream: true }))
);

// DEV-tasks (not used in production)
//-----------------------------------
function handleErrors(...errorArgs) {
  const args = Array.prototype.slice.call(errorArgs);
  notify.onError({
    title: 'Compile Error',
    message: '<%= error.message %>'
  }).apply(this, args);
  this.emit('end'); // Keep gulp from hanging on this task
}

// Incrementally building the js
gulp.task('build-js-inc', () =>
  merge(...paths.entry.scripts.map(script => {
    const b = browserify(Object.assign({}, browserifyInc.args,
      {
        entries: script,
        extensions: ['.jsx'],
        debug: true
      }
    ));

    browserifyInc(b, { cacheFile: './browserify-cache.json' });

    return b.transform(babelify, { presets: ['env', 'react'] })
      .bundle()
        .on('error', handleErrors)
        .pipe(source(`./${script.split('/')[script.split('/').length - 1]}`))
        .pipe(buffer())
        .pipe(plumber())
        .pipe(rename(path => {
          path.extname = '.bundle.js';
        }))
        .pipe(gulp.dest('public/js'))
        .pipe(browserSync.reload({ stream: true }));
  }))
);

gulp.task('build-appcache-dev', () =>
  gulp.src('public/**/*', { base: 'public' })
    .pipe(manifest({
      hash: true,
      preferOnline: true,
      network: ['*'],
      // fallback:
      filename: 'offline.appcache',
      exclude: 'offline.appcache'
    }))
    .pipe(gulp.dest('public'))
    .pipe(browserSync.reload({ stream: true }))
);

// Cleaners
// --------

// rm -rf public directory
gulp.task('clean:static', () => {
  if (isGitHubPages) {
    return del(['.publish/**/*']);
  }
  return del(['public/**/*']);
});

gulp.task('clear-cache', done => cache.clearAll(done)); // clears img cache

// Bundled tasks
// -------------
gulp.task('build-types',
  gulp.series(
    'build-json',
    'build-js2json',
    gulp.parallel('build-font', 'build-img', 'build-js', 'build-css', 'build-view')
  )
);

gulp.task('build-types-dev',
  gulp.series(
    'build-json',
    'build-js2json',
    gulp.parallel('build-font', 'build-img', 'build-js-inc', 'build-css', 'build-view')
  )
);

gulp.task('build', gulp.series('clean:static', 'build-types', 'build-appcache'));
gulp.task('build-dev', gulp.series('build-types-dev', 'build-appcache-dev'));

gulp.task('watch', gulp.series('build', done => {
  gulp.watch(paths.fonts, gulp.task('build-font'));
  gulp.watch(paths.images, gulp.task('build-img'));
  gulp.watch([...Object.values(paths.jsons)], gulp.task('build-json'));
  gulp.watch(paths.challengesJs, gulp.task('build-js2json'));
  gulp.watch(paths.scripts, gulp.task('build-js'));
  gulp.watch(paths.stylesheets, gulp.task('build-css'));
  done();
}));

gulp.task('watch-dev', gulp.series('build-dev', done => {
  // const jsonFiles = Object.keys(paths.jsons).map(item => paths.jsons[item]);
  gulp.watch(paths.fonts, gulp.task('build-font'));
  gulp.watch(paths.images, gulp.task('build-img'));
  gulp.watch([...Object.values(paths.jsons)], gulp.task('build-json'));
  gulp.watch(paths.challengesJs, gulp.task('build-js2json'));
  gulp.watch(paths.scripts, gulp.task('build-js-inc'));
  gulp.watch(paths.stylesheets, gulp.task('build-css'));
  done();
}));

// Hot-reloading
// -------------
gulp.task('browser-sync', gulp.series('watch-dev', done => {
  browserSync.init({
    proxy: {
      target: 'localhost:8080',
      ws: true // websockets
    },
    ghostMode: true, // sync across all browsers
    reloadDelay: 2000, // give gulp tasks time to reprocess files
    port: 3000 // browserSync port
  }, done);
}));

// GitHub pages deploy
// -------------------

// gulp.task('deploy-gh-pages', gulp.series('build', () =>
//   gulp.src('public/**/*')
//     .pipe(ghPages())
// ));

// Helper tasks
// ------------
/*
gulp.task('bundle', ['build'], () =>
  gulp.src(paths.scripts.map(script =>
    `./public/js/${script.split('/')[script.split('/').length - 1]}`
  ))
    .pipe(concat('bundle.js'))
    .pipe(gulp.dest('public/js'))
);

gulp.task('bundle-dev', ['build-dev'], () =>
  gulp.src(paths.scripts.map(script =>
    `./public/js/${script.split('/')[script.split('/').length - 1]}`
  ))
    .pipe(concat('bundle.js'))
    .pipe(gulp.dest('public/js'))
);
*/
<|endoftext|>


<commit_before>/*global module:false, require:false*/
module.exports = function (grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    meta: {
      banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + '<%= grunt.template.today("yyyy-mm-dd") %>\\n' + '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
    },
    connect: {
      server: {
        options: {
          port: 8085
        }
      }
    },
    concat: {
      options: {
        banner: '<%= meta.banner %>',
        stripBanners: true
      },
      dist: {
        src: ['src/<%= pkg.name %>.js'],
        dest: 'dist/<%= pkg.name %>.js'
      },
      distcss: {
        src: ['src/<%= pkg.name %>.css'],
        dest: 'dist/<%= pkg.name %>.css'
      }
    },
    uglify: {
      dist: {
        files: {
          'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
        }
      }
    },
    cssmin: {
      dist: {
        files: {
          'dist/<%= pkg.name %>.min.css': ['<%= concat.distcss.dest %>']
        }
      },
      docs: {
        files: {
          'dist/index.min.css': ['<%= less.index.dest %>']
        }
      }
    },
    jade: {
      compile: {
        files: {
          "dist/index.html": ["src/index.jade"]
        },
        options: {
          client: false
        }
      }
    },
    less: {
      index: {
        src: "src/index.less",
        dest: "dist/index.css"
      }
    },
    qunit: {
      all: {
        options: {
          urls: ['1.9.1', '1.10.0', '1.11.0-beta2', '2.0.1', '2.1.0-beta2'].map(function (version) {
            return 'http://localhost:<%= connect.server.options.port %>/test/jquery.placeholder.html?jquery=' + version;
          })
        }
      }
    },
    beautify: {
      files: '<%= jshint.files.src %>'
    },
    watch: {
      files: '<%= jshint.files.src %>',
      tasks: ['test']
    },
    replace: {
      dist: {
        options: {
          variables: {
            'version': '<%= pkg.version %>'
          }
        },
        files: {
          'dist/index.html': ['dist/index.html']
        }
      }
    },
    copy: {
      dist: {
        options: {
          flatten: true
        },
        files: [{
          expand: true,
          flatten: true,
          dest: 'dist/',
          src: ['CHANGES', 'LICENSE', 'README', 'ext/bootstrap/bootstrap.min.css']
        }]
      }
    },
    compress: {
      zip: {
        options: {
          mode: "zip",
          rootDir: "jquery-placeholder-plugin",
          archive: "jquery-placeholder-plugin-<%= pkg.version %>.zip"
        },
        files: [{
          expand: true,
          flatten: true,
          cwd: 'dist/',
          dest: "",
          src: ["**"]
        }]
      }
    }
  });

  // Default task.
  grunt.registerTask('default', ['jshint', 'beautify']);
  grunt.registerTask('test', ['connect', 'jshint', 'qunit']);
  grunt.registerTask('build', ['jade', 'less', 'concat', 'uglify', 'cssmin', 'copy']);
  grunt.registerTask('dist', ['build', 'replace:dist', 'compress']);

  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-compress');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-bump');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jade');
  grunt.loadNpmTasks('grunt-beautify');
  grunt.loadNpmTasks('grunt-replace');

  grunt.registerTask('tidy', 'beautify');
};
<commit_msg>accidently deleted some tasks<commit_after>/*global module:false, require:false*/
module.exports = function (grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    meta: {
      banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + '<%= grunt.template.today("yyyy-mm-dd") %>\\n' + '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */'
    },
    connect: {
      server: {
        options: {
          port: 8085
        }
      }
    },
    concat: {
      options: {
        banner: '<%= meta.banner %>',
        stripBanners: true
      },
      dist: {
        src: ['src/<%= pkg.name %>.js'],
        dest: 'dist/<%= pkg.name %>.js'
      },
      distcss: {
        src: ['src/<%= pkg.name %>.css'],
        dest: 'dist/<%= pkg.name %>.css'
      }
    },
    uglify: {
      dist: {
        files: {
          'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
        }
      }
    },
    cssmin: {
      dist: {
        files: {
          'dist/<%= pkg.name %>.min.css': ['<%= concat.distcss.dest %>']
        }
      },
      docs: {
        files: {
          'dist/index.min.css': ['<%= less.index.dest %>']
        }
      }
    },
    jade: {
      compile: {
        files: {
          "dist/index.html": ["src/index.jade"]
        },
        options: {
          client: false
        }
      }
    },
    less: {
      index: {
        src: "src/index.less",
        dest: "dist/index.css"
      }
    },
    qunit: {
      all: {
        options: {
          urls: ['1.9.1', '1.10.0', '1.11.0-beta2', '2.0.1', '2.1.0-beta2'].map(function (version) {
            return 'http://localhost:<%= connect.server.options.port %>/test/jquery.placeholder.html?jquery=' + version;
          })
        }
      }
    },
    beautify: {
      files: '<%= jshint.files.src %>'
    },
    watch: {
      files: '<%= jshint.files.src %>',
      tasks: ['test']
    },
    replace: {
      dist: {
        options: {
          variables: {
            'version': '<%= pkg.version %>'
          }
        },
        files: {
          'dist/index.html': ['dist/index.html']
        }
      }
    },
    clean: ['dist', '*zip'],
    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        browser: true,
        globals: {
          jQuery: true
        }
      },
      files: {
        src: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js']
      }
    },
    copy: {
      dist: {
        options: {
          flatten: true
        },
        files: [{
          expand: true,
          flatten: true,
          dest: 'dist/',
          src: ['CHANGES', 'LICENSE', 'README', 'ext/bootstrap/bootstrap.min.css']
        }]
      }
    },
    compress: {
      zip: {
        options: {
          mode: "zip",
          rootDir: "jquery-placeholder-plugin",
          archive: "jquery-placeholder-plugin-<%= pkg.version %>.zip"
        },
        files: [{
          expand: true,
          flatten: true,
          cwd: 'dist/',
          dest: "",
          src: ["**"]
        }]
      }
    }
  });

  // Default task.
  grunt.registerTask('default', ['jshint', 'beautify']);
  grunt.registerTask('test', ['connect', 'jshint', 'qunit']);
  grunt.registerTask('build', ['jade', 'less', 'concat', 'uglify', 'cssmin', 'copy']);
  grunt.registerTask('dist', ['build', 'replace:dist', 'compress']);

  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-compress');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-bump');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jade');
  grunt.loadNpmTasks('grunt-beautify');
  grunt.loadNpmTasks('grunt-replace');

  grunt.registerTask('tidy', 'beautify');
};
<|endoftext|>


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

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      files: ['js/app/**/*.js', 'js/shims/**/*.js'],
      options: {
        globals: {
          console: true,
          module: true,
          require: true,
          navigator: true,
          Parse: true
        },
        undef: true,
        debug: true
      }
    },
    watch: {
      files: ['Gruntfile.js', '<%= jshint.files %>'],
      tasks: ['jshint', 'browserify']
    }
  });

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

  grunt.registerTask('browserify', 'Browserify and concatenate app sources', function() {

    var browserify  = require('browserify'),
        shim        = require('browserify-shim'),
        done        = this.async();

    // this will be the js src'd in <script> tags
    var output;

    // vendor js
    output = shim(browserify(), {
      jquery: { path: './js/vendor/jquery.min.js', exports: '$' },
      'jquery-serialize-object': { path: './js/vendor/jquery.serialize-object.js', exports: '' }
    })
      .require('./js/shims/parse.js', {expose: 'parse'})
      .require('./js/shims/google-maps.js', {expose: 'google-maps'});

    // use hbsfy transform to support requiring .hbs files
    output = output.transform('hbsfy');

    // application modules
    //   note: this is optional as browserify traverses the AST from the entry point for require calls.
    //   this gives us consistent require paths by exposing modules using a nicer name.
    [
      './js/app/lib/*.js',
      './js/app/models/*.js',
      './js/app/views/*.js',
      './js/app/templates/*.hbs'
    ].forEach(function(modules) {
      require('glob')(modules, function(er, files) {
        files.forEach(function(file) {
          var name = file
            .replace('./js/app/','')
            .replace(/\.(js|hbs)$/,'');

          output = output.require(file, {expose: name});
        });
      });
    });

    // add entry point; browserify will traverse the AST tree from here for require calls
    output = output.require('./js/app/index.js', { entry: true });

    // now bundle it all up!
    output.bundle(function (err, src) {
      if (err) return console.error(err);

      require('fs').writeFileSync("./js/static/output.js", src);

      // keep grunt alive until the write stream completes
      done();
    });
  });

  grunt.registerTask('default', ['jshint', 'browserify']);
};
<commit_msg>watch handlebars templates<commit_after>module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      files: ['js/app/**/*.js', 'js/shims/**/*.js'],
      options: {
        globals: {
          console: true,
          module: true,
          require: true,
          navigator: true,
          Parse: true
        },
        undef: true,
        debug: true
      }
    },
    watch: {
      files: ['Gruntfile.js', '<%= jshint.files %>', 'js/app/**/*.hbs'],
      tasks: ['jshint', 'browserify']
    }
  });

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

  grunt.registerTask('browserify', 'Browserify and concatenate app sources', function() {

    var browserify  = require('browserify'),
        shim        = require('browserify-shim'),
        done        = this.async();

    // this will be the js src'd in <script> tags
    var output;

    // vendor js
    output = shim(browserify(), {
      jquery: { path: './js/vendor/jquery.min.js', exports: '$' },
      'jquery-serialize-object': { path: './js/vendor/jquery.serialize-object.js', exports: '' }
    })
      .require('./js/shims/parse.js', {expose: 'parse'})
      .require('./js/shims/google-maps.js', {expose: 'google-maps'});

    // use hbsfy transform to support requiring .hbs files
    output = output.transform('hbsfy');

    // application modules
    //   note: this is optional as browserify traverses the AST from the entry point for require calls.
    //   this gives us consistent require paths by exposing modules using a nicer name.
    [
      './js/app/lib/*.js',
      './js/app/models/*.js',
      './js/app/views/*.js',
      './js/app/templates/*.hbs'
    ].forEach(function(modules) {
      require('glob')(modules, function(er, files) {
        files.forEach(function(file) {
          var name = file
            .replace('./js/app/','')
            .replace(/\.(js|hbs)$/,'');

          output = output.require(file, {expose: name});
        });
      });
    });

    // add entry point; browserify will traverse the AST tree from here for require calls
    output = output.require('./js/app/index.js', { entry: true });

    // now bundle it all up!
    output.bundle(function (err, src) {
      if (err) return console.error(err);

      require('fs').writeFileSync("./js/static/output.js", src);

      // keep grunt alive until the write stream completes
      done();
    });
  });

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


<commit_before>/*jslint node: true */
'use strict';

/*****************
 * Configuration *
 *****************/
var config = {
  source_folder : "src", // dossier source
  dev_folder : "serve", // dossier pour le serveur local
  prod_folder : "prod", // dossier de build :)

  uncss : {
    html : ['src/index.html'], // have to fix?
    ignore : [
      '.content',
      '.type',
      '.geoJson',
      '.headmasked',
      '.nohead',
      '.geo',
      '.on',
      'ul',
      'li',
      /ath/,
      /input/,
      /reverse-/,
      /leaflet-/,
      /photon-/
      ]
    },
  colorguard : {
      logOk: true,
      threshold: 3,
      ignore: ['#030303'],
      whitelist: [
        ['#000000', '#010101'],
        ['#cccccc', '#c3c3c3'],
        ['#cccccc', '#d1d1d1'],
        ['#bbbbbb', '#c3c3c3'],
        ['#dddddd', '#d1d1d1'],
        ['#eeeeee', '#f4f4f4'],
        ['#fefefe', '#f4f4f4'],
        ['#ffffff', '#f4f4f4'], // Can-i reduce?
        ['#ffffff', '#fefefe']
        ]
      }
};

/************
 * Includes *
 ************/
var gulp = require('gulp');
var $ = require('gulp-load-plugins')(); // auto load :)
// Permet de supprimer les dossier de destination
var del = require('del'); // ce n'est pas un plugin Gulp.
var argv = require('minimist')(process.argv.slice(2));

// Idem, on doit le charger manuellement.
var browserSync = require('browser-sync');
var reload = browserSync.reload; // on met la commande dans une variable locale
var bs; // voir plus loin :)

var merge = require('merge-stream'); // permet de joindre 2 flux de sorties.

/*********
 * Tasks *
 *********/
// Deletes the directory that is used to serve the site during development
gulp.task('clean:dev', del.bind(null, [config.dev_folder]));

// Deletes the directory that the optimized site is output to
gulp.task('clean:prod', del.bind(null, [config.prod_folder]));

// SCSS
gulp.task('SCSS', function () {
  gulp.src(['bower_components/**/*.css',config.source_folder+'/scss/style.scss'])
    //  .pipe($.sourcemaps.init()) //useless ?
  .pipe($.sass())
  .pipe($.concat('style.css'))
  // AutoPrefix your CSS so it works between browsers
  .pipe($.autoprefixer('> 1%, last 2 versions, Firefox ESR, Opera 12.1', { cascade: true }))
  .pipe($.uncss(config.uncss))
  .pipe($.colorguard(config.colorguard))
  .pipe(gulp.dest(config.source_folder+'/css'))
  .pipe(gulp.dest(config.dev_folder+'/css'))
  // Outputs the size of the CSS file
  .pipe($.size({title: 'styles'}))
  // Injects the CSS changes to your browser since Jekyll doesn't rebuild the CSS
  .pipe(reload({stream: true}));
});

// Run JS Lint against your JS
gulp.task('jslint', function () {
  gulp.src(config.source_folder+'/js/*.js')
    // Checks your JS code quality against your .jshintrc file
    .pipe($.jshint('.jshintrc'))
    .pipe($.jshint.reporter());
});

// Copy over fonts to the 'site' directory
gulp.task('fonts', function () {
  return gulp.src([config.source_folder+'/fonts/**','bower_components/material-design-iconic-font/fonts/*'])
    .pipe(gulp.dest(config.dev_folder+'/fonts'))
    .pipe(gulp.dest(config.prod_folder+'/fonts'))
    .pipe($.size({ title: 'fonts' }));
});

gulp.task('js', function() {
  gulp.src(config.source_folder+'/js/*.js')
  //.pipe($.concat('all.js'))
  //.pipe($.uglify({preserveComments: 'some'}))
  .pipe($.size({title: 'js'}))
  .pipe(gulp.dest(config.dev_folder+'/js/'));
});

// Optimizes the images that exists
gulp.task('images', function () {
  return gulp.src([config.source_folder+'/images/**','bower_components/leaflet/dist/images/**'])
    .pipe(gulp.dest(config.dev_folder+'/images'))
    .pipe($.changed(config.prod_folder+'/images'))
    .pipe($.imagemin({
      // Lossless conversion to progressive JPGs
      progressive: true,
      // Interlace GIFs for progressive rendering
      interlaced: true
    }))
    .pipe(gulp.dest(config.prod_folder+'/images'))
    .pipe($.size({title: 'images'}));
});

gulp.task('bower', function() {
  return $.bower()
    .pipe(gulp.dest(config.dev_folder+'/vendor'));
});

gulp.task('dev',['bower','fonts','images','SCSS','jslint','js'],function(){

  gulp.src(config.source_folder+'/**/*.html')
  .pipe(gulp.dest(config.dev_folder));
});
gulp.task('serve:dev', ['dev'], function () {
  bs = browserSync({
    notify: true,
    // tunnel: '',
    server: {
      baseDir: config.dev_folder
    }
  });
});

gulp.task('watch', function () {
  gulp.watch([config.source_folder+'/**/*.html', config.source_folder+'/**/*.js'], ['dev']);
  gulp.watch([config.dev_folder+'/css/*.css'], reload);
  gulp.watch([config.source_folder+'/scss/**/*.scss'], ['SCSS']);
});

gulp.task('default', ['serve:dev', 'watch']);

// Optimizes all the CSS, HTML and concats the JS etc
gulp.task('prod', ['dev'], function () {
  var assets = $.useref.assets({searchPath: config.dev_folder});

  return gulp.src(config.dev_folder+'/*.html')
    .pipe(assets)
    // Concatenate JavaScript files and preserve important comments
    .pipe($.if('*.js',$.uglify({preserveComments: 'some'})))
    // Minify CSS
    .pipe($.if('*.css', $.minifyCss()))
    // Start cache busting the files
    .pipe($.revAll({ ignore: ['.eot', '.svg', '.ttf', '.woff','png'] }))
    .pipe(assets.restore())
    // Conctenate your files based on what you specified in _layout/header.html
    .pipe($.useref())
    // Replace the asset names with their cache busted names
    .pipe($.revReplace())
    // Add GA
    .pipe($.if('*.html',$.ga({
          url: 'julien-noblet.github.io/cad-killer',
          uid: 'UA-59363844-3'
        })))
    // Minify HTML
    .pipe($.if('*.html', $.htmlmin({
      removeComments: true,
      removeCommentsFromCDATA: true,
      removeCDATASectionsFromCDATA: true,
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeAttributeQuotes: true,
      removeRedundantAttributes: true
    // Send the output to the correct folder
    })))
    .pipe(gulp.dest(config.prod_folder))
    .pipe($.size({title: 'optimizations'}));
});
gulp.task('serve:prod', ['prod'], function () {
  bs = browserSync({
    notify: true,
    // tunnel: '',
    server: {
      baseDir: config.prod_folder
    }
  });
});

gulp.task('deploy',['prod'], function () {
  if (argv.clean) {
        var os = require('os');
        var path = require('path');
        var repoPath = path.join(os.tmpdir(), 'tmpRepo');
        $.util.log('Delete ' + $.util.colors.magenta(repoPath));
        del.sync(repoPath, {force: true});
    }
  // Deploys your optimized site, you can change the settings in the html task if you want to
  return gulp.src(config.prod_folder+'/**/*')
    .pipe($.ghPages({
      // Currently only personal GitHub Pages are supported so it will upload to the master
      // branch and automatically overwrite anything that is in the directory
      branch: 'gh-pages'
      }));
});
<commit_msg>uncss: .ath != ath ...<commit_after>/*jslint node: true */
'use strict';

/*****************
 * Configuration *
 *****************/
var config = {
  source_folder : "src", // dossier source
  dev_folder : "serve", // dossier pour le serveur local
  prod_folder : "prod", // dossier de build :)

  uncss : {
    html : ['src/index.html'], // have to fix?
    ignore : [
      '.content',
      '.type',
      '.geoJson',
      '.headmasked',
      '.nohead',
      '.geo',
      '.on',
      'ul',
      'li',
      /\.ath/,
      /input/,
      /reverse-/,
      /leaflet-/,
      /photon-/
      ]
    },
  colorguard : {
      logOk: true,
      threshold: 3,
      ignore: ['#030303'],
      whitelist: [
        ['#000000', '#010101'],
        ['#cccccc', '#c3c3c3'],
        ['#cccccc', '#d1d1d1'],
        ['#bbbbbb', '#c3c3c3'],
        ['#dddddd', '#d1d1d1'],
        ['#eeeeee', '#f4f4f4'],
        ['#fefefe', '#f4f4f4'],
        ['#ffffff', '#f4f4f4'], // Can-i reduce?
        ['#ffffff', '#fefefe']
        ]
      }
};

/************
 * Includes *
 ************/
var gulp = require('gulp');
var $ = require('gulp-load-plugins')(); // auto load :)
// Permet de supprimer les dossier de destination
var del = require('del'); // ce n'est pas un plugin Gulp.
var argv = require('minimist')(process.argv.slice(2));

// Idem, on doit le charger manuellement.
var browserSync = require('browser-sync');
var reload = browserSync.reload; // on met la commande dans une variable locale
var bs; // voir plus loin :)

var merge = require('merge-stream'); // permet de joindre 2 flux de sorties.

/*********
 * Tasks *
 *********/
// Deletes the directory that is used to serve the site during development
gulp.task('clean:dev', del.bind(null, [config.dev_folder]));

// Deletes the directory that the optimized site is output to
gulp.task('clean:prod', del.bind(null, [config.prod_folder]));

// SCSS
gulp.task('SCSS', function () {
  gulp.src(['bower_components/**/*.css',config.source_folder+'/scss/style.scss'])
    //  .pipe($.sourcemaps.init()) //useless ?
  .pipe($.sass())
  .pipe($.concat('style.css'))
  // AutoPrefix your CSS so it works between browsers
  .pipe($.autoprefixer('> 1%, last 2 versions, Firefox ESR, Opera 12.1', { cascade: true }))
  .pipe($.uncss(config.uncss))
  .pipe($.colorguard(config.colorguard))
  .pipe(gulp.dest(config.source_folder+'/css'))
  .pipe(gulp.dest(config.dev_folder+'/css'))
  // Outputs the size of the CSS file
  .pipe($.size({title: 'styles'}))
  // Injects the CSS changes to your browser since Jekyll doesn't rebuild the CSS
  .pipe(reload({stream: true}));
});

// Run JS Lint against your JS
gulp.task('jslint', function () {
  gulp.src(config.source_folder+'/js/*.js')
    // Checks your JS code quality against your .jshintrc file
    .pipe($.jshint('.jshintrc'))
    .pipe($.jshint.reporter());
});

// Copy over fonts to the 'site' directory
gulp.task('fonts', function () {
  return gulp.src([config.source_folder+'/fonts/**','bower_components/material-design-iconic-font/fonts/*'])
    .pipe(gulp.dest(config.dev_folder+'/fonts'))
    .pipe(gulp.dest(config.prod_folder+'/fonts'))
    .pipe($.size({ title: 'fonts' }));
});

gulp.task('js', function() {
  gulp.src(config.source_folder+'/js/*.js')
  //.pipe($.concat('all.js'))
  //.pipe($.uglify({preserveComments: 'some'}))
  .pipe($.size({title: 'js'}))
  .pipe(gulp.dest(config.dev_folder+'/js/'));
});

// Optimizes the images that exists
gulp.task('images', function () {
  return gulp.src([config.source_folder+'/images/**','bower_components/leaflet/dist/images/**'])
    .pipe(gulp.dest(config.dev_folder+'/images'))
    .pipe($.changed(config.prod_folder+'/images'))
    .pipe($.imagemin({
      // Lossless conversion to progressive JPGs
      progressive: true,
      // Interlace GIFs for progressive rendering
      interlaced: true
    }))
    .pipe(gulp.dest(config.prod_folder+'/images'))
    .pipe($.size({title: 'images'}));
});

gulp.task('bower', function() {
  return $.bower()
    .pipe(gulp.dest(config.dev_folder+'/vendor'));
});

gulp.task('dev',['bower','fonts','images','SCSS','jslint','js'],function(){

  gulp.src(config.source_folder+'/**/*.html')
  .pipe(gulp.dest(config.dev_folder));
});
gulp.task('serve:dev', ['dev'], function () {
  bs = browserSync({
    notify: true,
    // tunnel: '',
    server: {
      baseDir: config.dev_folder
    }
  });
});

gulp.task('watch', function () {
  gulp.watch([config.source_folder+'/**/*.html', config.source_folder+'/**/*.js'], ['dev']);
  gulp.watch([config.dev_folder+'/css/*.css'], reload);
  gulp.watch([config.source_folder+'/scss/**/*.scss'], ['SCSS']);
});

gulp.task('default', ['serve:dev', 'watch']);

// Optimizes all the CSS, HTML and concats the JS etc
gulp.task('prod', ['dev'], function () {
  var assets = $.useref.assets({searchPath: config.dev_folder});

  return gulp.src(config.dev_folder+'/*.html')
    .pipe(assets)
    // Concatenate JavaScript files and preserve important comments
    .pipe($.if('*.js',$.uglify({preserveComments: 'some'})))
    // Minify CSS
    .pipe($.if('*.css', $.minifyCss()))
    // Start cache busting the files
    .pipe($.revAll({ ignore: ['.eot', '.svg', '.ttf', '.woff','png'] }))
    .pipe(assets.restore())
    // Conctenate your files based on what you specified in _layout/header.html
    .pipe($.useref())
    // Replace the asset names with their cache busted names
    .pipe($.revReplace())
    // Add GA
    .pipe($.if('*.html',$.ga({
          url: 'julien-noblet.github.io/cad-killer',
          uid: 'UA-59363844-3'
        })))
    // Minify HTML
    .pipe($.if('*.html', $.htmlmin({
      removeComments: true,
      removeCommentsFromCDATA: true,
      removeCDATASectionsFromCDATA: true,
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeAttributeQuotes: true,
      removeRedundantAttributes: true
    // Send the output to the correct folder
    })))
    .pipe(gulp.dest(config.prod_folder))
    .pipe($.size({title: 'optimizations'}));
});
gulp.task('serve:prod', ['prod'], function () {
  bs = browserSync({
    notify: true,
    // tunnel: '',
    server: {
      baseDir: config.prod_folder
    }
  });
});

gulp.task('deploy',['prod'], function () {
  if (argv.clean) {
        var os = require('os');
        var path = require('path');
        var repoPath = path.join(os.tmpdir(), 'tmpRepo');
        $.util.log('Delete ' + $.util.colors.magenta(repoPath));
        del.sync(repoPath, {force: true});
    }
  // Deploys your optimized site, you can change the settings in the html task if you want to
  return gulp.src(config.prod_folder+'/**/*')
    .pipe($.ghPages({
      // Currently only personal GitHub Pages are supported so it will upload to the master
      // branch and automatically overwrite anything that is in the directory
      branch: 'gh-pages'
      }));
});
<|endoftext|>


<commit_before>var ui = require('ui');
var ajax = require('ajax');

// Check for local activity data
var activityData = localStorage.getItem('activity_data');

var waitCard = new ui.Card({
	title: 'Loading',
	subtitle: '.'
});

if(activityData && false)
{
	console.log('Old data');
	console.log(activityData);
}
else
{
	AjaxWait();
	/*
	setTimeout(function(){
		ajax({
			url: 'http://www.bungie.net/Platform/Destiny/Advisors/',
			type: 'json'
		}, function(data){
			activityData = data;
			localStorage.setItem('activity_data', data);
			console.log('Fresh data');
			console.log(data);
			ClearWait();
		}, function(error){
			console.log('Error! ' + error);
			ClearWait();
		});
	}, 5000);
	*/
}

/*
var MainMenu = new ui.Menu({
	sections: [{
		title: 'Activities',
		items: [{
			title: 'Weekly Nightfall',
			subtitle: ['NF', 'E', 'AB', 'A', 'LS'].join('*')
	},{
			title: 'Weekly Heroic',
			subtitle: ['H', 'LS'].join('*')
		}]
	}]
});

MainMenu.show();
*/

var waitInterval;
var waitTick = 1;

function AjaxWait()
{
	waitCard.show();

	waitInterval = setInterval(function() {
		var sub = '.';

		if(waitTick == 10)
			waitTick = 1;

		for(var i = 0; i < waitTick; i++)
			sub += '.';

		waitTick++;

		waitCard.subtitle(sub);
	}, 500);
}

function ClearWait()
{
	clearInterval(waitInterval);
	waitCard.hide();
}
<commit_msg>Cleaned up code, added debug<commit_after>var ui = require('ui');
var ajax = require('ajax');

// Check for local activity data
var activityData = localStorage.getItem('activity_data');

var waitCard = new ui.Card({
	title: 'Loading',
	subtitle: '.'
});

if(!activityData)
{
	AjaxWait();
	ajax({
		url: 'http://www.bungie.net/Platform/Destiny/Advisors/',
		type: 'json'
	}, function(data){
		activityData = data;
		localStorage.setItem('activity_data', data);
		ClearWait();
	}, function(error){
		ClearWait();
	});
}

console.log('Got activity data. ' + activityData.Response.data.nightfallActivityHash);

var MainMenu = new ui.Menu({
	sections: [{
		title: 'Activities',
		items: [{
			title: 'Weekly Nightfall',
			subtitle: ['NF', 'E', 'AB', 'A', 'LS'].join('*')
	},{
			title: 'Weekly Heroic',
			subtitle: ['H', 'LS'].join('*')
		}]
	}]
});

MainMenu.show();

var waitInterval;
var waitTick = 1;

function AjaxWait()
{
	waitCard.show();
	MainMenu.hide();

	waitInterval = setInterval(function() {
		var sub = '.';

		if(waitTick == 10)
			waitTick = 1;

		for(var i = 0; i < waitTick; i++)
			sub += '.';

		waitTick++;

		waitCard.subtitle(sub);
	}, 500);
}

function ClearWait()
{
	clearInterval(waitInterval);
	MainMenu.show();
	waitCard.hide();
}
<|endoftext|>


<commit_before>/* global module */
module.exports = function (grunt) {
	grunt.initConfig({
		jshint: {
			src: [
				"**/*.js",
				"!{node_modules,out}/**/*.js"
			],
			options: {
				jshintrc: ".jshintrc"
			}
		},
		intern: {
			node: {
				options: {
					runType: "client",
					config: "tests/intern"
				}
			},
			local: {
				options: {
					runType: "runner",
					config: "tests/intern.local",
					reporters: ["runner"]
				}
			},
			remote: {
				options: {
					runType: "runner",
					config: "tests/intern",
					reporters: ["runner"]
				}
			}
		},
		"jsdoc-amddcl": {
			docs: {
				files: [
					{
						args: [
							"-r"
						],
						src: [
							".",
							"./README.md",
							"./package.json"
						],
						packagePathFormat: "${name}/docs/api/${version}"
					}
				]
			},
			export: {
				files: [
					{
						args: [
							"-X",
							"-r"
						],
						src: [
							".",
							"./README.md",
							"./package.json"
						],
						dest: "./out/doclets.json"
					}
				]
			}
		}
	});
	grunt.loadNpmTasks("grunt-contrib-jshint");
	grunt.loadNpmTasks("intern");
	grunt.loadNpmTasks("jsdoc-amddcl");
	grunt.registerTask("jsdoc", "jsdoc-amddcl");

	// Testing.
	// Always specify the target e.g. grunt test:remote, grunt test:remote
	// then add on any other flags afterwards e.g. console, lcovhtml.
	var testTaskDescription = "Run this task instead of the intern task directly! \n" +
		"Always specify the test target e.g. \n" +
		"grunt test:local\n" +
		"grunt test:remote\n\n" +
		"Add any optional reporters via a flag e.g. \n" +
		"grunt test:local:console\n" +
		"grunt test:local:lcovhtml\n" +
		"grunt test:local:console:lcovhtml";
	grunt.registerTask("test", testTaskDescription, function (target) {
		function addReporter(reporter) {
			var property = "intern." + target + ".options.reporters",
				value = grunt.config.get(property);
			if (value.indexOf(reporter) !== -1) {
				return;
			}
			value.push(reporter);
			grunt.config.set(property, value);
		}
		if (this.flags.lcovhtml) {
			addReporter("lcovhtml");
		}
		if (this.flags.console) {
			addReporter("console");
		}
		grunt.task.run("intern:" + target);
	});
};
<commit_msg>JSDoc: add flag in Gruntfile to disable inclusion of Events section in TOC of API doc<commit_after>/* global module */
module.exports = function (grunt) {
	grunt.initConfig({
		jshint: {
			src: [
				"**/*.js",
				"!{node_modules,out}/**/*.js"
			],
			options: {
				jshintrc: ".jshintrc"
			}
		},
		intern: {
			node: {
				options: {
					runType: "client",
					config: "tests/intern"
				}
			},
			local: {
				options: {
					runType: "runner",
					config: "tests/intern.local",
					reporters: ["runner"]
				}
			},
			remote: {
				options: {
					runType: "runner",
					config: "tests/intern",
					reporters: ["runner"]
				}
			}
		},
		"jsdoc-amddcl": {
			docs: {
				files: [
					{
						args: [
							"-r"
						],
						src: [
							".",
							"./README.md",
							"./package.json"
						],
						packagePathFormat: "${name}/docs/api/${version}",
						includeEventsInTOC: "false"
					}
				]
			},
			export: {
				files: [
					{
						args: [
							"-X",
							"-r"
						],
						src: [
							".",
							"./README.md",
							"./package.json"
						],
						dest: "./out/doclets.json"
					}
				]
			}
		}
	});
	grunt.loadNpmTasks("grunt-contrib-jshint");
	grunt.loadNpmTasks("intern");
	grunt.loadNpmTasks("jsdoc-amddcl");
	grunt.registerTask("jsdoc", "jsdoc-amddcl");

	// Testing.
	// Always specify the target e.g. grunt test:remote, grunt test:remote
	// then add on any other flags afterwards e.g. console, lcovhtml.
	var testTaskDescription = "Run this task instead of the intern task directly! \n" +
		"Always specify the test target e.g. \n" +
		"grunt test:local\n" +
		"grunt test:remote\n\n" +
		"Add any optional reporters via a flag e.g. \n" +
		"grunt test:local:console\n" +
		"grunt test:local:lcovhtml\n" +
		"grunt test:local:console:lcovhtml";
	grunt.registerTask("test", testTaskDescription, function (target) {
		function addReporter(reporter) {
			var property = "intern." + target + ".options.reporters",
				value = grunt.config.get(property);
			if (value.indexOf(reporter) !== -1) {
				return;
			}
			value.push(reporter);
			grunt.config.set(property, value);
		}
		if (this.flags.lcovhtml) {
			addReporter("lcovhtml");
		}
		if (this.flags.console) {
			addReporter("console");
		}
		grunt.task.run("intern:" + target);
	});
};
<|endoftext|>


<commit_before>/**
 * ExtendedProgrammingInterface (EPI)
 *
 * Licensed under the MIT Open Source license.
 *     See LICENSE.md for the full text.
 *
 *     The extended programming interface or EPI defines a set of methods that
 * makes fetching certain bits of data from the API easier than it is by
 * turning large AJAX calls into simple one liners using Promises to eliminate
 * the need to use callback.
 *
 *     By using Promises the EPI reduces and even eliminates the need to use
 * callbacks within your script making it both much cleaner to write but also
 * easier to read and follow along with. Promises also provide the ability to
 * handle errors through the .catch() method.
 *
 *     To learn more about how promises work see the link below as well as the
 * provided EPI documentation for explanations of each method included in the
 * EPI as well as how to use it within your own scripts.
 *
 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
 *
 * Current methods:
 *     _http:
 *         ajax
 *     user:
 *         action:
 *             ban
 *         info:
 *             userid
 */

/**
 * Some notes on contributing to the EPI
 *
 *     First, all functions that can be written on a single line must be
 * written as such using arrow functions. Functions that can be written on a
 * single line are ones that only consist of one statement. For an example of
 * this please see ExtendedProgrammingInterface::_http::ajax()
 *
 *     Second, when composing objects make sure that all keys start on the same
 * column and that all values do the same. Values should start no more than one
 * space after the end of the longest key and all values that would start
 * before this column must be brought up to this column using successive spaces
 *
 *     Third, try to keep all lines at a max of 80 characters. It is fine if a
 * line must go over this limit but try to wrap it at the earliest possible
 * point in order to prevent this.
 *
 *     Fourth, when using AJAX you must always do so in the context of a promises
 * in order to avoid the need to use a callback.
 */

(function(window, $, mw) {
    var ExtendedProgrammingInterface = {
        _http: {},
        user:  { info: {}, action: {} },
        wall:  {}
    }, epi = ExtendedProgrammingInterface;

/**
 * EPI::_http::ajax
 *
 * Make an AJAX call using jQuery when given the appopriate objects
 *
 * @param [Object] data: jQuery.ajax request object
 */
epi._http.ajax = data => $.ajax(data);

/**
 * EPI::user::ban
 *
 * Bans a user from chat (if user is admin or mod)
 *
 * @param [Object] data: {
 *                           'userId':   [Number],
 *                           'duration': [Number],
 *                           'reason':   [String]
 *                       }
 * @return [Promise]
 */
epi.user.ban = function(data) {
    return new Promise(function(resolve, reject) {
        epi._http.ajax({
            url:      mw.util.wikiScript('index'),
            type:     'POST',
            dataType: 'JSON',
            error:    (data) => reject(data),
            success:  (data) => (data.error) ? reject(data)
                                             : resolve(data),
            data:     {
	                      action:      'ajax',
	                      rs:          'ChatAjax',
	                      method:      'blockOrBanChat',
	                      userToBanId: data.userId,
	                      time:        data.duration,
	                      reason:      data.reason,
	                      mode:        'global',
	                      token:       mw.user.tokens.get('editToken')
                      }
        });
    });
};

/**
 * EPI::user::block
 *
 * Blocks a user from the wiki if they are admin
 *
 * Comments:
 *     Omit nocreate and autoblock to disable them
 *     Set them to true to enable them
 *
 * @param [Object] data: {
 *                           'username':  [Number],
 *                           'duration':  [Number],
 *                           'reason':    [String],
 *                           'nocreate':  [Boolean],
 *                           'autoblock': [Boolean]
 *                       }
 * @return [Promise]
 */
epi.user.block = function(data) {
    return new Promise(function(resolve, reject) {
        epi._http.ajax({
            url:        mw.util.wikiScript('api'),
            type:       'POST',
            dataType:   'JSON',
            error:      (data) => reject(data),
            success:    (data) => (data.error) ? reject(data['error'])
                                               : resolve(data['block']),
            beforeSend: function(xhr, settings) {
                if (data.nocreate) settings.data += '&nocreate';
                if (data.autoblock) settings.data += '&autoblock';
            },
            data:       {
                            action:    'block',
                            user:      data.username,
                            expiry:    data.duration,
                            reason:    data.reason,
                            format:    'json',
                            token:     mw.user.tokens.get('editToken')
                        }
        });
    });
};

/**
 * EPI::user::getUserId
 *
 * Get a user's ID from the API
 *
 * Comments:
 *     I use JSONP here because jQuery will automatically parse the result
 *     of the resquest for me and return a nice little object for use to
 *     return.
 *
 * @param [String] user: username of the user to get the ID of
 * @return [Promise]
 */
epi.user.getUserId = function(user) {
    return new Promise(function(resolve, reject) {
        epi._http.ajax({
            url:      mw.util.wikiScript('api'),
            type:     'POST',
            dataType: 'JSONP',
            error:    (data) => reject(data),
            success:  (data) => (data === 'undefined') ? reject('undefined')
                                                       : resolve(data['query']['users'][0]['userid']),
            data:     {
                          action:  'query',
                          list:    'users',
                          ususers: user,
                          usprop:  '|',
                          format:  'json'
                      }
        });
    });
};

    if (typeof window.ExtendedProgrammingInterface === 'undefined') {
        window.ExtendedProgrammingInterface = ExtendedProgrammingInterface;
        window.epi = ExtendedProgrammingInterface;
    }
})(window, jQuery, mediaWiki);<commit_msg>Fixing comments<commit_after>/**
 * ExtendedProgrammingInterface (EPI)
 *
 * Licensed under the MIT Open Source license.
 *     See LICENSE.md for the full text.
 *
 *     The extended programming interface or EPI defines a set of methods that
 * makes fetching certain bits of data from the API easier than it is by
 * turning large AJAX calls into simple one liners using Promises to eliminate
 * the need to use callback.
 *
 *     By using Promises the EPI reduces and even eliminates the need to use
 * callbacks within your script making it both much cleaner to write but also
 * easier to read and follow along with. Promises also provide the ability to
 * handle errors through the .catch() method.
 *
 *     To learn more about how promises work see the link below as well as the
 * provided EPI documentation for explanations of each method included in the
 * EPI as well as how to use it within your own scripts.
 *
 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
 */

/**
 * Some notes on contributing to the EPI
 *
 *     First, all functions that can be written on a single line must be
 * written as such using arrow functions. Functions that can be written on a
 * single line are ones that only consist of one statement. For an example of
 * this please see ExtendedProgrammingInterface::_http::ajax()
 *
 *     Second, when composing objects make sure that all keys start on the same
 * column and that all values do the same. Values should start no more than one
 * space after the end of the longest key and all values that would start
 * before this column must be brought up to this column using successive spaces
 *
 *     Third, try to keep all lines at a max of 80 characters. It is fine if a
 * line must go over this limit but try to wrap it at the earliest possible
 * point in order to prevent this.
 *
 *     Fourth, when using AJAX you must always do so in the context of a promises
 * in order to avoid the need to use a callback.
 */

(function(window, $, mw) {
    var ExtendedProgrammingInterface = {
        _http: {},
        user:  { info: {}, action: {} },
        wall:  {}
    }, epi = ExtendedProgrammingInterface;

/**
 * EPI::_http::ajax
 *
 * Make an AJAX call using jQuery when given the appopriate objects
 *
 * @param [Object] data: jQuery.ajax request object
 */
epi._http.ajax = data => $.ajax(data);

/**
 * EPI::user::ban
 *
 * Bans a user from chat (if user is admin or mod)
 *
 * @param [Object] data: {
 *                           'userId':   [Number],
 *                           'duration': [Number],
 *                           'reason':   [String]
 *                       }
 * @return [Promise]
 */
epi.user.ban = function(data) {
    return new Promise(function(resolve, reject) {
        epi._http.ajax({
            url:      mw.util.wikiScript('index'),
            type:     'POST',
            dataType: 'JSON',
            error:    (data) => reject(data),
            success:  (data) => (data.error) ? reject(data)
                                             : resolve(data),
            data:     {
	                      action:      'ajax',
	                      rs:          'ChatAjax',
	                      method:      'blockOrBanChat',
	                      userToBanId: data.userId,
	                      time:        data.duration,
	                      reason:      data.reason,
	                      mode:        'global',
	                      token:       mw.user.tokens.get('editToken')
                      }
        });
    });
};

/**
 * EPI::user::block
 *
 * Blocks a user from the wiki if they are admin
 *
 * Comments:
 *     Omit nocreate and autoblock to disable them
 *     Set them to true to enable them
 *
 * @param [Object] data: {
 *                           'username':  [Number],
 *                           'duration':  [Number],
 *                           'reason':    [String],
 *                           'nocreate':  [Boolean],
 *                           'autoblock': [Boolean]
 *                       }
 * @return [Promise]
 */
epi.user.block = function(data) {
    return new Promise(function(resolve, reject) {
        epi._http.ajax({
            url:        mw.util.wikiScript('api'),
            type:       'POST',
            dataType:   'JSON',
            error:      (data) => reject(data),
            success:    (data) => (data.error) ? reject(data['error'])
                                               : resolve(data['block']),
            beforeSend: function(xhr, settings) {
                if (data.nocreate) settings.data += '&nocreate';
                if (data.autoblock) settings.data += '&autoblock';
            },
            data:       {
                            action:    'block',
                            user:      data.username,
                            expiry:    data.duration,
                            reason:    data.reason,
                            format:    'json',
                            token:     mw.user.tokens.get('editToken')
                        }
        });
    });
};

/**
 * EPI::user::getUserId
 *
 * Get a user's ID from the API
 *
 * Comments:
 *     I use JSONP here because jQuery will automatically parse the result
 *     of the resquest for me and return a nice little object for use to
 *     return.
 *
 * @param [String] user: username of the user to get the ID of
 * @return [Promise]
 */
epi.user.getUserId = function(user) {
    return new Promise(function(resolve, reject) {
        epi._http.ajax({
            url:      mw.util.wikiScript('api'),
            type:     'POST',
            dataType: 'JSONP',
            error:    (data) => reject(data),
            success:  (data) => (data === 'undefined') ? reject('undefined')
                                                       : resolve(data['query']['users'][0]['userid']),
            data:     {
                          action:  'query',
                          list:    'users',
                          ususers: user,
                          usprop:  '|',
                          format:  'json'
                      }
        });
    });
};

    if (typeof window.ExtendedProgrammingInterface === 'undefined') {
        window.ExtendedProgrammingInterface = ExtendedProgrammingInterface;
        window.epi = ExtendedProgrammingInterface;
    }
})(window, jQuery, mediaWiki);<|endoftext|>


<commit_before>module.exports = function (grunt) {
    "use strict";
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        env: {
            prod: {
                NODE_ENV: 'production'
            }
        },
        less: {
            publish: {
                options: {
                    compress: false,
                    optimization: 2
                },
                files: [
                    {
                        "public/css/styles.css": "public/less/styles.less" // destination file and source file
                    },
                    {
                        expand: true,        // Enable dynamic expansion.
                        cwd: 'extensions',  // Src matches are relative to this path.
                        src: ['**/less/*.less',],     // Actual pattern(s) to match.
                        dest: 'public/css/extensions',  // Destination path prefix.
                        ext: '.css',         // Dest filepaths will have this extension.
                    }
                ]
            }
        },
        cssmin: {
            build: {
                options: {
                    target: "./build",
                    rebase: true
                },
                files: {
                    'public/css/build/all.min.css': [
                        // Leaflet
                        'public/js/lib/leaflet/leaflet.css',
                        'public/js/lib/leaflet-draw/leaflet.draw.css',
                        'public/js/lib/leaflet.locatecontrol/L.Control.Locate.css',
                        'public/js/lib/leaflet.toolbar/leaflet.toolbar.css',
                        'public/js/lib/leaflet-measure-path/leaflet-measure-path.css',
                        'public/js/lib/leaflet-measure/leaflet-measure.css',
                        'public/js/lib/Leaflet.extra-markers/css/leaflet.extra-markers.css',
                        'public/js/lib/Leaflet.awesome-markers/leaflet.awesome-markers.css',
                        'public/js/lib/q-cluster/css/q-cluster.css',
                        // Bootstrap
                        'public/js/lib/bootstrap/dist/css/bootstrap.css',
                        'public/js/lib/snackbarjs/snackbar.min.css',
                        'public/js/lib/bootstrap-material-design/dist/css/ripples.css',
                        'public/js/lib/bootstrap-material-datetimepicker/bootstrap-material-datetimepicker.css',
                        'public/js/lib/bootstrap-select/bootstrap-select.css',
                        'public/js/lib/bootstrap-table/bootstrap-table.css',
                        'public/js/lib/bootstrap-material-design/dist/css/bootstrap-material-design.css',
                        'public/js/lib/bootstrap-colorpicker/css/bootstrap-colorpicker.css',
                        'public/css/jasny-bootstrap.css',
                        //custon
                        'public/css/styles.min.css'
                    ]
                }
            },
            extensions: {
                options: {
                    target: "./build",
                    rebase: true
                },
                files: {
                    'public/css/styles.min.css': [
                        'public/css/styles.css',
                        'public/css/extensions/**/less/*.css'
                    ]
                }
            }

        },
        jshint: {
            options: {
                funcscope: true,
                shadow: true,
                evil: true,
                validthis: true,
                asi: true,
                newcap: false,
                notypeof: false,
                eqeqeq: false,
                loopfunc: true,
                es3: true,
                devel: false,
                eqnull: true
            },
            all: ['public/js/*.js']
        },
        hogan: {
            publish: {
                options: {
                    defaultName: function (filename) {
                        return filename.split('/').pop();
                    }
                },
                files: {
                    "public/js/templates.js": [
                        "public/templates/**/*.tmpl",
                        "extensions/**/templates/*.tmpl"
                    ]
                }
            }
        },
        handlebars: {
            publish: {
                options: {
                    namespace: function (filename) {
                        var names = filename.replace(/modules\/(.*)(\/\w+\.hbs)/, '$1');
                        return names.split('/').join('.');
                    },
                    commonjs: true
                },
                files: {
                    "public/js/handlebars_templates.js": [
                        "extensions/**/templates/*.hbs"
                    ]
                }
            }
        },
        browserify: {
            publish: {
                files: {
                    'public/js/bundle.js': ['browser/index.js']
                },
                options: {
                    transform: [['babelify', {presets: [['es2015'], ['react']]}], 'require-globify']
                }
            },
            watch: {
                files: {
                    'public/js/bundle.js': ['browser/index.js']
                },
                options: {
                    transform: [['babelify', {presets: [['es2015'], ['react']]}], 'require-globify'],
                    watch: true,
                    keepAlive: true
                }
            }
        },
        uglify: {
            publish: {
                options: {
                    sourceMap: true,
                    sourceMapIncludeSources: true,
                    compress: false
                },
                files: {
                    'public/js/build/all.min.js': [
                        'public/js/lib/leaflet/leaflet-src.js',
                        'public/js/lib/leaflet-draw/leaflet.draw.js',
                        'public/js/lib/Path.Drag.js/src/Path.Drag.js',
                        'public/js/lib/leaflet.editable/Leaflet.Editable.js',
                        'public/js/lib/leaflet.locatecontrol/L.Control.Locate.js',
                        'public/js/lib/leaflet.toolbar/leaflet.toolbar.js',
                        'public/js/lib/leaflet-measure-path/leaflet-measure-path.js',
                        'public/js/lib/leaflet-measure/leaflet-measure.min.js',
                        'public/js/lib/Leaflet.utfgrid/leaflet.utfgrid.js',
                        'public/js/lib/Leaflet.extra-markers/leaflet.extra-markers.js',
                        'public/js/lib/leaflet-plugins/Yandex.js',
                        'public/js/lib/leaflet-plugins/Bing.js',
                        'public/js/lib/Leaflet.GridLayer.GoogleMutant/Leaflet.GoogleMutant.js',
                        'public/js/lib/q-cluster/src/utils.js',
                        'public/js/lib/q-cluster/src/clustering.js',
                        'public/js/point-clusterer.js',
                        'public/js/lib/Leaflet.awesome-markers/leaflet.awesome-markers.js',

                        'public/js/lib/jquery/jquery.js',
                        'public/js/lib/jrespond/jRespond.js',
                        'public/js/lib/mustache.js/mustache.js',
                        'public/js/lib/underscore/underscore.js',
                        //'public/js/lib/raphael/raphael.min.js',
                        'public/js/lib/backbone/backbone.js',
                        'public/js/lib/momentjs/moment-with-locales.js',
                        'public/js/lib/d3/d3.js',

                        'public/js/lib/typeahead.js/typeahead.jquery.js',
                        'public/js/lib/bootstrap-table/bootstrap-table.js',
                        'public/js/lib/bootstrap-table/bootstrap-table-locale-all.js',
                        'public/js/lib/bootstrap-table/extensions/export/bootstrap-table-export.min.js',
                        'public/js/lib/bootstrap-table/extensions/filter-control/bootstrap-table-filter-control.min.js',
                        'public/js/lib/tableExport.jquery.plugin/tableExport.js',
                        'public/js/lib/bootstrap-material-design/dist/js/ripples.js',
                        'public/js/lib/bootstrap-material-design/dist/js/material.js',
                        'public/js/lib/bootstrap-material-datetimepicker/bootstrap-material-datetimepicker.js',
                        'public/js/lib/bootstrap-select/bootstrap-select.js',
                        'public/js/lib/bootstrap-colorpicker/js/bootstrap-colorpicker.js',

                        'public/js/proj4js-combined.js',
                        'public/js/jasny-bootstrap.js',
                        'public/js/bundle.js',
                        'public/js/vidi.js',
                        'public/js/gc2/geocloud.js',
                        'public/js/gc2/gc2table.js'
                    ]
                }
            }
        },
        processhtml: {
            publish: {
                files: {
                    'public/index.html': ['public/index.html']
                }
            }
        },
        gitpull: {
            production: {
                options: {}
            }
        },
        gitreset: {
            production: {
                options: {
                    mode: 'hard'
                }
            }
        },
        shell: {
            default: {
                command: [
                    'cp ./config/_variables.less ./public/js/lib/bootstrap-material-design/less',
                    'grunt --gruntfile ./public/js/lib/bootstrap-material-design/Gruntfile.js dist-less'
                ].join('&&')
            }
        },
        cacheBust: {
            options: {
                assets: ['js/build/all.min.js', 'css/build/all.min.css'],
                queryString: false,
                baseDir: './public/',
                jsonOutput: false,
                deleteOriginals: false
            },
            production: {
                files: [{
                    expand: true,
                    cwd: 'public/',
                    src: ['index.html']
                }]
            }
        },
        bower: {
            install: {
                //just run 'grunt bower:install' and you'll see files from your Bower packages in lib directory
                options: {
                    targetDir: "./public/js/lib",
                    copy: true,
                    install: true,
                    cleanTargetDir: false,
                    verbose: true,
                }
            }
        }
    });
    grunt.loadNpmTasks('grunt-templates-hogan');
    grunt.loadNpmTasks('grunt-browserify');
    grunt.loadNpmTasks('grunt-git');
    grunt.loadNpmTasks('grunt-shell');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-processhtml');
    grunt.loadNpmTasks('grunt-cache-bust');
    grunt.loadNpmTasks('grunt-env');
    grunt.loadNpmTasks('grunt-contrib-handlebars');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-bower-task');

    grunt.registerTask('default', ['browserify', 'less', 'hogan', 'shell']);
    grunt.registerTask('production', ['env', 'gitreset', 'browserify:publish', 'extension-css', 'hogan', 'shell', 'uglify', 'processhtml', 'cssmin:build', 'cacheBust']);
    grunt.registerTask('extension-css', ['less', 'cssmin:extensions']);
};

<commit_msg>remote conf<commit_after>module.exports = function (grunt) {
    "use strict";
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        env: {
            prod: {
                NODE_ENV: 'production'
            }
        },
        less: {
            publish: {
                options: {
                    compress: false,
                    optimization: 2
                },
                files: [
                    {
                        "public/css/styles.css": "public/less/styles.less" // destination file and source file
                    },
                    {
                        expand: true,        // Enable dynamic expansion.
                        cwd: 'extensions',  // Src matches are relative to this path.
                        src: ['**/less/*.less',],     // Actual pattern(s) to match.
                        dest: 'public/css/extensions',  // Destination path prefix.
                        ext: '.css',         // Dest filepaths will have this extension.
                    }
                ]
            }
        },
        cssmin: {
            build: {
                options: {
                    target: "./build",
                    rebase: true
                },
                files: {
                    'public/css/build/all.min.css': [
                        // Leaflet
                        'public/js/lib/leaflet/leaflet.css',
                        'public/js/lib/leaflet-draw/leaflet.draw.css',
                        'public/js/lib/leaflet.locatecontrol/L.Control.Locate.css',
                        'public/js/lib/leaflet.toolbar/leaflet.toolbar.css',
                        'public/js/lib/leaflet-measure-path/leaflet-measure-path.css',
                        'public/js/lib/leaflet-measure/leaflet-measure.css',
                        'public/js/lib/Leaflet.extra-markers/css/leaflet.extra-markers.css',
                        'public/js/lib/Leaflet.awesome-markers/leaflet.awesome-markers.css',
                        'public/js/lib/q-cluster/css/q-cluster.css',
                        // Bootstrap
                        'public/js/lib/bootstrap/dist/css/bootstrap.css',
                        'public/js/lib/snackbarjs/snackbar.min.css',
                        'public/js/lib/bootstrap-material-design/dist/css/ripples.css',
                        'public/js/lib/bootstrap-material-datetimepicker/bootstrap-material-datetimepicker.css',
                        'public/js/lib/bootstrap-select/bootstrap-select.css',
                        'public/js/lib/bootstrap-table/bootstrap-table.css',
                        'public/js/lib/bootstrap-material-design/dist/css/bootstrap-material-design.css',
                        'public/js/lib/bootstrap-colorpicker/css/bootstrap-colorpicker.css',
                        'public/css/jasny-bootstrap.css',
                        //custon
                        'public/css/styles.min.css'
                    ]
                }
            },
            extensions: {
                options: {
                    target: "./build",
                    rebase: true
                },
                files: {
                    'public/css/styles.min.css': [
                        'public/css/styles.css',
                        'public/css/extensions/**/less/*.css'
                    ]
                }
            }

        },
        jshint: {
            options: {
                funcscope: true,
                shadow: true,
                evil: true,
                validthis: true,
                asi: true,
                newcap: false,
                notypeof: false,
                eqeqeq: false,
                loopfunc: true,
                es3: true,
                devel: false,
                eqnull: true
            },
            all: ['public/js/*.js']
        },
        hogan: {
            publish: {
                options: {
                    defaultName: function (filename) {
                        return filename.split('/').pop();
                    }
                },
                files: {
                    "public/js/templates.js": [
                        "public/templates/**/*.tmpl",
                        "extensions/**/templates/*.tmpl"
                    ]
                }
            }
        },
        handlebars: {
            publish: {
                options: {
                    namespace: function (filename) {
                        var names = filename.replace(/modules\/(.*)(\/\w+\.hbs)/, '$1');
                        return names.split('/').join('.');
                    },
                    commonjs: true
                },
                files: {
                    "public/js/handlebars_templates.js": [
                        "extensions/**/templates/*.hbs"
                    ]
                }
            }
        },
        browserify: {
            publish: {
                files: {
                    'public/js/bundle.js': ['browser/index.js']
                },
                options: {
                    transform: [['babelify', {presets: [['es2015'], ['react']]}], 'require-globify']
                }
            },
            watch: {
                files: {
                    'public/js/bundle.js': ['browser/index.js']
                },
                options: {
                    transform: [['babelify', {presets: [['es2015'], ['react']]}], 'require-globify'],
                    watch: true,
                    keepAlive: true
                }
            }
        },
        uglify: {
            publish: {
                options: {
                    sourceMap: true,
                    sourceMapIncludeSources: true,
                    compress: false
                },
                files: {
                    'public/js/build/all.min.js': [
                        'public/js/lib/leaflet/leaflet-src.js',
                        'public/js/lib/leaflet-draw/leaflet.draw.js',
                        'public/js/lib/Path.Drag.js/src/Path.Drag.js',
                        'public/js/lib/leaflet.editable/Leaflet.Editable.js',
                        'public/js/lib/leaflet.locatecontrol/L.Control.Locate.js',
                        'public/js/lib/leaflet.toolbar/leaflet.toolbar.js',
                        'public/js/lib/leaflet-measure-path/leaflet-measure-path.js',
                        'public/js/lib/leaflet-measure/leaflet-measure.min.js',
                        'public/js/lib/Leaflet.utfgrid/leaflet.utfgrid.js',
                        'public/js/lib/Leaflet.extra-markers/leaflet.extra-markers.js',
                        'public/js/lib/leaflet-plugins/Yandex.js',
                        'public/js/lib/leaflet-plugins/Bing.js',
                        'public/js/lib/Leaflet.GridLayer.GoogleMutant/Leaflet.GoogleMutant.js',
                        'public/js/lib/q-cluster/src/utils.js',
                        'public/js/lib/q-cluster/src/clustering.js',
                        'public/js/point-clusterer.js',
                        'public/js/lib/Leaflet.awesome-markers/leaflet.awesome-markers.js',

                        'public/js/lib/jquery/jquery.js',
                        'public/js/lib/jrespond/jRespond.js',
                        'public/js/lib/mustache.js/mustache.js',
                        'public/js/lib/underscore/underscore.js',
                        //'public/js/lib/raphael/raphael.min.js',
                        'public/js/lib/backbone/backbone.js',
                        'public/js/lib/momentjs/moment-with-locales.js',
                        'public/js/lib/d3/d3.js',

                        'public/js/lib/typeahead.js/typeahead.jquery.js',
                        'public/js/lib/bootstrap-table/bootstrap-table.js',
                        'public/js/lib/bootstrap-table/bootstrap-table-locale-all.js',
                        'public/js/lib/bootstrap-table/extensions/export/bootstrap-table-export.min.js',
                        'public/js/lib/bootstrap-table/extensions/filter-control/bootstrap-table-filter-control.min.js',
                        'public/js/lib/tableExport.jquery.plugin/tableExport.js',
                        'public/js/lib/bootstrap-material-design/dist/js/ripples.js',
                        'public/js/lib/bootstrap-material-design/dist/js/material.js',
                        'public/js/lib/bootstrap-material-datetimepicker/bootstrap-material-datetimepicker.js',
                        'public/js/lib/bootstrap-select/bootstrap-select.js',
                        'public/js/lib/bootstrap-colorpicker/js/bootstrap-colorpicker.js',

                        'public/js/proj4js-combined.js',
                        'public/js/jasny-bootstrap.js',
                        'public/js/bundle.js',
                        'public/js/vidi.js',
                        'public/js/gc2/geocloud.js',
                        'public/js/gc2/gc2table.js'
                    ]
                }
            }
        },
        processhtml: {
            publish: {
                files: {
                    'public/index.html': ['public/index.html']
                }
            }
        },
        gitpull: {
            production: {
                options: {}
            }
        },
        gitreset: {
            production: {
                options: {
                    mode: 'hard'
                }
            }
        },
        shell: {
            default: {
                command: [
                    'cp ./config/_variables.less ./public/js/lib/bootstrap-material-design/less',
                    'grunt --gruntfile ./public/js/lib/bootstrap-material-design/Gruntfile.js dist-less'
                ].join('&&')
            }
        },
        cacheBust: {
            options: {
                assets: ['js/build/all.min.js', 'css/build/all.min.css'],
                queryString: false,
                baseDir: './public/',
                jsonOutput: false,
                deleteOriginals: false
            },
            production: {
                files: [{
                    expand: true,
                    cwd: 'public/',
                    src: ['index.html']
                }]
            }
        },
        bower: {
            install: {
                //just run 'grunt bower:install' and you'll see files from your Bower packages in lib directory
                options: {
                    targetDir: "./public/js/lib",
                    copy: true,
                    install: true,
                    cleanTargetDir: false,
                    verbose: true,
                }
            }
        }
    });
    grunt.loadNpmTasks('grunt-templates-hogan');
    grunt.loadNpmTasks('grunt-browserify');
    grunt.loadNpmTasks('grunt-git');
    grunt.loadNpmTasks('grunt-shell');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-processhtml');
    grunt.loadNpmTasks('grunt-cache-bust');
    grunt.loadNpmTasks('grunt-env');
    grunt.loadNpmTasks('grunt-contrib-handlebars');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-bower-task');

    grunt.registerTask('default', ['browserify:publish', 'extension-css', 'hogan']);
    grunt.registerTask('production', ['env', 'gitreset', 'browserify:publish', 'extension-css', 'hogan', 'shell', 'uglify', 'processhtml', 'cssmin:build', 'cacheBust']);
    grunt.registerTask('extension-css', ['less', 'cssmin:extensions']);
};

<|endoftext|>


<commit_before>#!/usr/bin/env node
/*!
 * -----------
 * ASPDB®-Data
 * -----------
 * Data of ASPDB — A manually curated dedicated acid shock proteins database.
 * ___________________________________________________________________________
 *
 * Grunt, http://gruntjs.com/ — The JavaScript Task Runner.
 * ___________________________________________________________________________
 *
 * Architecture and Code Handcrafted by Prabhat Kumar.
 * Architectuur en Code handgemaakt door Prabhat Kumar.
 * @author    : Prabhat Kumar [http://prabhatkumar.org/].
 * @copyright : Prabhat Kumar [http://prabhatkumar.org/].
 * @copyright : Sequømics Research [http://research.sequomics.com/].
 * @copyright : Sequømics Corporation [http://sequomics.com/].
 * ___________________________________________________________________________
 *
 * @date      : 10-Dec-2016
 * @license   : Apache, version 2.0
 * @require   : Node.js®
 * @require   : NPM
 * @require   : grunt-cli
 * @build     : SEED™ — Skövde
 *              └────── A Sequømics Product — http://seed.sequomics.com/.
 * ___________________________________________________________________________
 *
 * --/The Heart of Build System/-- of "ASPDB®-Data".
 * ___________________________________________________________________________
 */

// global __dirname: true
// global require: true

// # Usage: $ node -v
// # Usage: $ npm -v
// # Usage: $ grunt -version

// Invoking strict mode.
"use strict";

// To load required Node module.
// -----------------------------
var os         = require('os');
var fs         = require('fs');
<commit_msg>Initial commit<commit_after>#!/usr/bin/env node
/*!
 * -----------
 * ASPDB®-Data
 * -----------
 * Data of ASPDB — A manually curated dedicated acid shock proteins database.
 * ___________________________________________________________________________
 *
 * Grunt, http://gruntjs.com/ — The JavaScript Task Runner.
 * ___________________________________________________________________________
 *
 * Architecture and Code Handcrafted by Prabhat Kumar.
 * Architectuur en Code handgemaakt door Prabhat Kumar.
 * @author    : Prabhat Kumar [http://prabhatkumar.org/].
 * @copyright : Prabhat Kumar [http://prabhatkumar.org/].
 * @copyright : Sequømics Research [http://research.sequomics.com/].
 * @copyright : Sequømics Corporation [http://sequomics.com/].
 * ___________________________________________________________________________
 *
 * @date      : 10-Dec-2016
 * @license   : Apache, version 2.0
 * @require   : Node.js®
 * @require   : NPM
 * @require   : grunt-cli
 * @build     : SEED™ — Skövde
 *              └────── A Sequømics Product — http://seed.sequomics.com/.
 * ___________________________________________________________________________
 *
 * --/The Heart of Build System/-- of "ASPDB®-Data".
 * ___________________________________________________________________________
 */

// global __dirname: true
// global require: true

// # Usage: $ node -v
// # Usage: $ npm -v
// # Usage: $ grunt -version

// Invoking strict mode.
"use strict";

// To load required Node module.
// -----------------------------
var os         = require('os');
var fs         = require('fs');

// To load required NPM modules.
// -----------------------------
var chalk      = require('chalk');
<|endoftext|>