<commit_before>const gulp = require('gulp');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const tslint = require('gulp-tslint');
const webpack = require('webpack-stream');
const karma = require('karma').Server;
const fs = require('fs');
const ts = require('gulp-typescript');
const path = require('path');

gulp.task('build:webpack', () => {
  return gulp.src('src/main.ts')
    .pipe(webpack(require('./webpack.config.js'), require('webpack')))
    .pipe(gulp.dest('dist/'));
});

gulp.task('build:uglify', () => {
  return gulp.src('dist/elpong.js')
    .pipe(uglify())
    .pipe(rename('elpong.min.js'))
    .pipe(gulp.dest('dist/'));
});

gulp.task('build:tsc', () => {
  const tsProject = ts.createProject('tsconfig.json');
  const tsResult = tsProject.src().pipe(tsProject());
  return tsResult.js.pipe(gulp.dest('built'));
});

gulp.task('build:dts', (done) => {
  require('dts-generator').default({
		name: 'elpong',
		project: '.',
		out: './dist/elpong.generated.d.ts',
    main: 'elpong',
    eol: '\n'
  }).then(() => {
    done();
  });
});

gulp.task('build', gulp.series('build:webpack', 'build:uglify', 'build:tsc'));
gulp.task('build:ts', gulp.series('build:tsc'));

gulp.task('lint', () => {
  return gulp.src('src/**/*.ts')
    .pipe(tslint({
      formatter: 'verbose'
    }))
    .pipe(tslint.report());
});

testWithFramework = (framework, done) => {
  process.env.FRAMEWORK = framework;
  console.log('Testing ' + framework);
  new karma({
    configFile: path.join(__dirname, 'karma.conf.js'),
    browsers: ['PhantomJS']
  }, done).start();
}

gulp.task('test:karma', (done) => {
  return testWithFramework(process.env.FRAMEWORK || 'fetch', done);
});

gulp.task('test', gulp.series('test:karma'));

gulp.task('default', gulp.series('test'));

gulp.task('test:saucelabs', (done) => {
  process.env.FRAMEWORK = 'fetch'
  new karma({
    configFile: path.join(__dirname, 'karma.conf.js')
  }, done).start();
});

gulp.task('test:frameworks', (done) => {
  let frameworks = ['angularjs', 'jquery', 'fetch'];
  let i = 0;
  let partlyDone = function(exitcode){
    if (exitcode) {
      process.exit(exitcode);
    }
    if (++i === frameworks.length) {
      done();
      return;
    }
    testWithFramework(frameworks[i], partlyDone);
  };
  testWithFramework(frameworks[0], partlyDone);
});

gulp.task('test:karma:debug', (done) => {
  process.env.FRAMEWORK = process.env.FRAMEWORK || 'fetch'
  new karma({
    configFile: path.join(__dirname, 'karma.conf.js'),
    singleRun: false,
    autoWatch: true,
    browsers: ['Chrome']
  }, done).start();
});

gulp.task('test:examples:node', (done) => {
  require('./examples/node-app');
  done();
});

gulp.task('test:travis', gulp.parallel('test:frameworks', 'test:saucelabs'));

gulp.task('ensure-built', (done) => {
  let dir_files = (dir) => fs.readdirSync(dir).map((f) => path.join(dir, f));

  let dist_files = dir_files('./dist');
  let src_files = dir_files('./src');

  let mtimes = (f) => fs.statSync(f).mtime;

  let dist_mtime = Math.min.apply(null, dist_files.map(mtimes));
  let src_mtime = Math.max.apply(null, src_files.map(mtimes));

  console.log(dist_mtime, src_mtime);

  if (dist_mtime < src_mtime - 100) {
    throw new Error('Dist outdated, run `gulp build`');
  }
  done();
});
<commit_msg>Fix ensure-built by excluding .d.ts<commit_after>const gulp = require('gulp');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const tslint = require('gulp-tslint');
const webpack = require('webpack-stream');
const karma = require('karma').Server;
const fs = require('fs');
const ts = require('gulp-typescript');
const path = require('path');

gulp.task('build:webpack', () => {
  return gulp.src('src/main.ts')
    .pipe(webpack(require('./webpack.config.js'), require('webpack')))
    .pipe(gulp.dest('dist/'));
});

gulp.task('build:uglify', () => {
  return gulp.src('dist/elpong.js')
    .pipe(uglify())
    .pipe(rename('elpong.min.js'))
    .pipe(gulp.dest('dist/'));
});

gulp.task('build:tsc', () => {
  const tsProject = ts.createProject('tsconfig.json');
  const tsResult = tsProject.src().pipe(tsProject());
  return tsResult.js.pipe(gulp.dest('built'));
});

gulp.task('build:dts', (done) => {
  require('dts-generator').default({
		name: 'elpong',
		project: '.',
		out: './dist/elpong.generated.d.ts',
    main: 'elpong',
    eol: '\n'
  }).then(() => {
    done();
  });
});

gulp.task('build', gulp.series('build:webpack', 'build:uglify', 'build:tsc'));
gulp.task('build:ts', gulp.series('build:tsc'));

gulp.task('lint', () => {
  return gulp.src('src/**/*.ts')
    .pipe(tslint({
      formatter: 'verbose'
    }))
    .pipe(tslint.report());
});

testWithFramework = (framework, done) => {
  process.env.FRAMEWORK = framework;
  console.log('Testing ' + framework);
  new karma({
    configFile: path.join(__dirname, 'karma.conf.js'),
    browsers: ['PhantomJS']
  }, done).start();
}

gulp.task('test:karma', (done) => {
  return testWithFramework(process.env.FRAMEWORK || 'fetch', done);
});

gulp.task('test', gulp.series('test:karma'));

gulp.task('default', gulp.series('test'));

gulp.task('test:saucelabs', (done) => {
  process.env.FRAMEWORK = 'fetch'
  new karma({
    configFile: path.join(__dirname, 'karma.conf.js')
  }, done).start();
});

gulp.task('test:frameworks', (done) => {
  let frameworks = ['angularjs', 'jquery', 'fetch'];
  let i = 0;
  let partlyDone = function(exitcode){
    if (exitcode) {
      process.exit(exitcode);
    }
    if (++i === frameworks.length) {
      done();
      return;
    }
    testWithFramework(frameworks[i], partlyDone);
  };
  testWithFramework(frameworks[0], partlyDone);
});

gulp.task('test:karma:debug', (done) => {
  process.env.FRAMEWORK = process.env.FRAMEWORK || 'fetch'
  new karma({
    configFile: path.join(__dirname, 'karma.conf.js'),
    singleRun: false,
    autoWatch: true,
    browsers: ['Chrome']
  }, done).start();
});

gulp.task('test:examples:node', (done) => {
  require('./examples/node-app');
  done();
});

gulp.task('test:travis', gulp.parallel('test:frameworks', 'test:saucelabs'));

gulp.task('ensure-built', (done) => {
  let dir_files = (dir) => fs.readdirSync(dir).map((f) => path.join(dir, f));

  let dist_files = dir_files('./dist').filter(f => !f.endsWith('.d.ts'));
  let src_files = dir_files('./src');

  let mtimes = (f) => fs.statSync(f).mtime;

  let dist_mtime = Math.min.apply(null, dist_files.map(mtimes));
  let src_mtime = Math.max.apply(null, src_files.map(mtimes));

  console.log(dist_mtime, src_mtime);

  if (dist_mtime < src_mtime - 100) {
    throw new Error('Dist outdated, run `gulp build`');
  }
  done();
});
<|endoftext|>


<commit_before>import React from 'react';
import TableRow from './TableRow';
import Pagination from './Pagination';
import Button from './Button';
import FilterInput from './FilterInput';
import TableHeaderItem from './TableHeaderItem';

const UNSELECTED = -1;

class Table extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      data: this.props.data,
      currentPage: this.props.page,
      filterValue: this.props.filterValue,
      selectedRowId: UNSELECTED,
      sortDirection: this.props.sortDirection,
      sortColumn: this.props.sortColumn
    };

    this.onAddNewRow = this.onAddNewRow.bind(this);
    this.onDeleteRow = this.onDeleteRow.bind(this);
    this.onEditRow = this.onEditRow.bind(this);
    this.onSelectRow = this.onSelectRow.bind(this);
    this.onChangePageIndex = this.onChangePageIndex.bind(this);
    this.onHandleFilter = this.onHandleFilter.bind(this);
    this.onHandleSortColumn = this.onHandleSortColumn.bind(this);
  }

  onAddNewRow() {
    if (this.props.onAddRow) {
      this.props.onAddRow();
    }
  }

  onDeleteRow(rowId) {
    let unselect = (this.state.selectedRowId === rowId) || this.state.selectedRowId < 0;
    let selectedRowIdAfterDelete = unselect ? UNSELECTED : this.state.selectedRowId;

    this.state.data.splice(rowId, 1);
    this.setState({
      data: this.state.data,
      selectedRowId: selectedRowIdAfterDelete
    });

    if (this.props.onDeleteRow) {
      this.props.onDeleteRow(rowId);
    }
  }

  onEditRow(rowId) {
    if (this.props.onEditRow) {
      this.props.onEditRow(rowId);
    }
  }

  onSelectRow(rowId) {
    let value = (this.state.selectedRowId === rowId) ? UNSELECTED : rowId;
    this.setState({
      selectedRowId: value
    });

    if (this.props.onSelectRow) {
      this.props.onSelectRow(rowId);
    }
  }

  onChangePageIndex(index) {
    if (index < 0) {
      return;
    }

    this.setState({
      currentPage: index
    });
  }

  onHandleFilter(value) {
    this.setState({
      filterValue: value,
      currentPage: 0
    });
  }

  onHandleSortColumn(colId) {
    if (this.props.tools) {
      colId -= 1;
    }

    let sd = this.state.sortDirection;
    if (sd === TableHeaderItem.SORT_NOPE) {
      sd = TableHeaderItem.SORT_ASCENDING;
    }

    let scdv = 1;
    if (this.state.sortColumn === colId) {
      scdv = TableHeaderItem.SORT_CHANGE_DIRECTION;
    }

    function sortFunction(a, b) {
      return sd * a[colId].localeCompare(b[colId]);
    }

    let records = this.state.data;
    records.sort(sortFunction);

    this.setState({
      data: records,
      sortColumn: colId,
      sortDirection: (sd * scdv)
    });
  }

  filterRecords(data) {
    let records = data;

    if (this.state.filterValue !== '') {
      records = data.filter((row) => {
        let value = row.join();
        if (value.indexOf(this.state.filterValue) >= 0) {
          return value;
        }

        return false;
      });
    }

    return records;
  }

  prepRows(records, cp, ps) {
    let rows = [];

    for (let i = 0, cri = cp * ps; cri < records.length && i < ps; i++, cri++) {
      let Row = (
        <TableRow
          data={records[cri]}
          key={`row-${cri}`}
          rowId={cri}
          selected={this.state.selectedRowId === cri}
          tools={this.props.tools}
          onDelete={this.onDeleteRow}
          onEdit={this.onEditRow}
          onSelect={this.onSelectRow}
        />);
      rows.push(Row);
    }

    return rows;
  }

  prepHeader(header, tools) {
    let output = [];

    if (tools && header.length > 0) {
      let th = (<TableHeaderItem key={output.length} colId={output.length} />);
      output.push(th);
    }

    for (let i = 0; i < header.length; i++) {
      let sorted = TableHeaderItem.SORT_NOPE;
      if (i === this.state.sortColumn) {
        sorted = this.state.sortDirection;
      }

      let th = (
        <TableHeaderItem
          sorted={sorted}
          key={output.length}
          colId={output.length}
          title={header[i]}
          onClick={this.onHandleSortColumn}
        />);
      output.push(th);
    }

    return output;
  }

  renderSectionHeader() {
    return (

        <FilterInput onKeyUp={this.onHandleFilter} />

          <Button cn={" btn-primary"} title={"Add new row"} onClick={this.onAddNewRow} />

);
  }

  renderSectionBody(header, rows) {
    return (

              {header}

            {rows}

);
  }

  renderSectionFooter(records, pageCount, pageSize) {
    return (

        {(() => {
          if (records.length > pageSize) {
            return (
              <Pagination
                current={this.state.currentPage}
                pageCount={pageCount}
                onChange={this.onChangePageIndex}
              />);
          }
          return '';
        })()}

    );
  }

  render() {
    let pageSize = this.props.pageSize;
    let cp = this.state.currentPage;

    let records = this.filterRecords(this.state.data);
    let pageCount = Math.ceil(records.length / pageSize);

    let header = this.prepHeader(this.props.header, this.props.tools);
    let rows = this.prepRows(records, cp, pageSize);

    return (

        {this.renderSectionHeader()}
        {this.renderSectionBody(header, rows)}
        {this.renderSectionFooter(records, pageCount, pageSize)}

);
  }
}

Table.defaultProps = {
  page: 0,
  pageSize: 10,
  tools: true,
  sortColumn: 0,
  sortDirection: TableHeaderItem.SORT_NOPE,
  filterValue: ''
};

Table.propTypes = {
  page: React.PropTypes.number,
  data: React.PropTypes.array.isRequired,
  pages: React.PropTypes.number,
  header: React.PropTypes.arrayOf(React.PropTypes.string),
  tools: React.PropTypes.bool,
  sortDirection: React.PropTypes.number,
  filterValue: React.PropTypes.string,

  onDeleteRow: React.PropTypes.func,
  onAddRow: React.PropTypes.func,
  onEditRow: React.PropTypes.func,
  onSelectRow: React.PropTypes.func
};

export default Table;
<commit_msg>selecting row as a redux way<commit_after>import React from 'react';
import { connect } from 'react-redux';
import TableRow from './TableRow';
import Pagination from './Pagination';
import Button from './Button';
import FilterInput from './FilterInput';
import TableHeaderItem from './TableHeaderItem';

import { selectRow } from './../actions/table';

const UNSELECTED = -1;

class Table extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      data: this.props.data,
      currentPage: this.props.page,
      filterValue: this.props.filterValue,
      selectedRowId: UNSELECTED,
      sortDirection: this.props.sortDirection,
      sortColumn: this.props.sortColumn
    };

    this.onAddNewRow = this.onAddNewRow.bind(this);
    this.onDeleteRow = this.onDeleteRow.bind(this);
    this.onEditRow = this.onEditRow.bind(this);
    this.onSelectRow = this.onSelectRow.bind(this);
    this.onChangePageIndex = this.onChangePageIndex.bind(this);
    this.onHandleFilter = this.onHandleFilter.bind(this);
    this.onHandleSortColumn = this.onHandleSortColumn.bind(this);
  }

  onAddNewRow() {
    if (this.props.onAddRow) {
      this.props.onAddRow();
    }
  }

  onDeleteRow(rowId) {
    let unselect = (this.state.selectedRowId === rowId) || this.state.selectedRowId < 0;
    let selectedRowIdAfterDelete = unselect ? UNSELECTED : this.state.selectedRowId;

    this.state.data.splice(rowId, 1);
    this.setState({
      data: this.state.data,
      selectedRowId: selectedRowIdAfterDelete
    });

    if (this.props.onDeleteRow) {
      this.props.onDeleteRow(rowId);
    }
  }

  onEditRow(rowId) {
    if (this.props.onEditRow) {
      this.props.onEditRow(rowId);
    }
  }

  onSelectRow(rowId) {
    let selectedRowId = (this.props.selectedRowId === rowId) ? UNSELECTED : rowId;
    let { dispatch } = this.props;
    dispatch(selectRow(selectedRowId));

    if (this.props.onSelectRow && typeof(this.props.onSelectRow) === 'function') {
      this.props.onSelectRow(rowId);
    }
  }

  onChangePageIndex(index) {
    if (index < 0) {
      return;
    }

    this.setState({
      currentPage: index
    });
  }

  onHandleFilter(value) {
    this.setState({
      filterValue: value,
      currentPage: 0
    });
  }

  onHandleSortColumn(colId) {
    if (this.props.tools) {
      colId -= 1;
    }

    let sd = this.state.sortDirection;
    if (sd === TableHeaderItem.SORT_NOPE) {
      sd = TableHeaderItem.SORT_ASCENDING;
    }

    let scdv = 1;
    if (this.state.sortColumn === colId) {
      scdv = TableHeaderItem.SORT_CHANGE_DIRECTION;
    }

    function sortFunction(a, b) {
      return sd * a[colId].localeCompare(b[colId]);
    }

    let records = this.state.data;
    records.sort(sortFunction);

    this.setState({
      data: records,
      sortColumn: colId,
      sortDirection: (sd * scdv)
    });
  }

  filterRecords(data) {
    let records = data;

    if (this.state.filterValue !== '') {
      records = data.filter((row) => {
        let value = row.join();
        if (value.indexOf(this.state.filterValue) >= 0) {
          return value;
        }

        return false;
      });
    }

    return records;
  }

  prepRows(records, cp, ps) {
    let rows = [];

    for (let i = 0, cri = cp * ps; cri < records.length && i < ps; i++, cri++) {
      let Row = (
        <TableRow
          data={records[cri]}
          key={`row-${cri}`}
          rowId={cri}
          selected={this.props.selectedRowId === cri}
          tools={this.props.tools}
          onDelete={this.onDeleteRow}
          onEdit={this.onEditRow}
          onSelect={this.onSelectRow}
        />);
      rows.push(Row);
    }

    return rows;
  }

  prepHeader(header, tools) {
    let output = [];

    if (tools && header.length > 0) {
      let th = (<TableHeaderItem key={output.length} colId={output.length} />);
      output.push(th);
    }

    for (let i = 0; i < header.length; i++) {
      let sorted = TableHeaderItem.SORT_NOPE;
      if (i === this.state.sortColumn) {
        sorted = this.state.sortDirection;
      }

      let th = (
        <TableHeaderItem
          sorted={sorted}
          key={output.length}
          colId={output.length}
          title={header[i]}
          onClick={this.onHandleSortColumn}
        />);
      output.push(th);
    }

    return output;
  }

  renderSectionHeader() {
    return (

        <FilterInput onKeyUp={this.onHandleFilter} />

          <Button cn={" btn-primary"} title={"Add new row"} onClick={this.onAddNewRow} />

);
  }

  renderSectionBody(header, rows) {
    return (

              {header}

            {rows}

);
  }

  renderSectionFooter(records, pageCount, pageSize) {
    return (

        {(() => {
          if (records.length > pageSize) {
            return (
              <Pagination
                current={this.state.currentPage}
                pageCount={pageCount}
                onChange={this.onChangePageIndex}
              />);
          }
          return '';
        })()}

    );
  }

  render() {
    let pageSize = this.props.pageSize;
    let cp = this.state.currentPage;

    let records = this.filterRecords(this.state.data);
    let pageCount = Math.ceil(records.length / pageSize);

    let header = this.prepHeader(this.props.header, this.props.tools);
    let rows = this.prepRows(records, cp, pageSize);

    return (

        {this.renderSectionHeader()}
        {this.renderSectionBody(header, rows)}
        {this.renderSectionFooter(records, pageCount, pageSize)}

);
  }
}

Table.defaultProps = {
  page: 0,
  pageSize: 10,
  tools: true,
  sortColumn: 0,
  sortDirection: TableHeaderItem.SORT_NOPE,
  filterValue: '',
  selectedRowId: UNSELECTED
};

Table.propTypes = {
  page: React.PropTypes.number,
  data: React.PropTypes.array.isRequired,
  pages: React.PropTypes.number,
  header: React.PropTypes.arrayOf(React.PropTypes.string),
  tools: React.PropTypes.bool,
  sortDirection: React.PropTypes.number,
  filterValue: React.PropTypes.string,
  selectedRowId: React.PropTypes.number,

  onDeleteRow: React.PropTypes.func,
  onAddRow: React.PropTypes.func,
  onEditRow: React.PropTypes.func,
  onSelectRow: React.PropTypes.func
};

function mapStateToProp(state) {
  return {
    selectedRowId: state.table.selectedRowId
  }
}

export default connect(mapStateToProp)(Table);
<|endoftext|>


<commit_before>'use strict';

var config = require('./build/build.config.js');
var karmaConfig = require('./build/karma.config.js');
var protractorConfig = require('./build/protractor.config.js');
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var runSequence = require('run-sequence');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var pkg = require('./package');
var karma = require('karma').server;
var del = require('del');
var _ = require('lodash');
/* jshint camelcase:false*/
var webdriverStandalone = require('gulp-protractor').webdriver_standalone;
var webdriverUpdate = require('gulp-protractor').webdriver_update;

//update webdriver if necessary, this task will be used by e2e task
gulp.task('webdriver:update', webdriverUpdate);

// run unit tests and watch files
gulp.task('tdd', function(cb) {
  karma.start(_.assign({}, karmaConfig, {
    singleRun: false,
    action: 'watch',
    browsers: ['PhantomJS']
  }), cb);
});

// run unit tests with travis CI
gulp.task('travis', ['build'], function(cb) {
  karma.start(_.assign({}, karmaConfig, {
    singleRun: true,
    browsers: ['PhantomJS']
  }), cb);
});

// optimize images and put them in the dist folder
gulp.task('images', function() {
  return gulp.src(config.images)
    .pipe($.imagemin({
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest(config.dist + '/assets/images'))
    .pipe($.size({
      title: 'images'
    }));
});

//generate angular templates using html2js
gulp.task('templates', function() {
  return gulp.src(config.tpl)
    .pipe($.changed(config.tmp))
    .pipe($.html2js({
      outputModuleName: 'templates',
      base: 'client',
      useStrict: true
    }))
    .pipe($.concat('templates.js'))
    .pipe(gulp.dest(config.tmp))
    .pipe($.size({
      title: 'templates'
    }));
});

//generate css files from scss sources
gulp.task('sass', function() {
  return gulp.src(config.mainScss)
    .pipe($.rubySass())
    .on('error', function(err) {
      console.log(err.message);
    })
    .pipe(gulp.dest(config.tmp))
    .pipe($.size({
      title: 'sass'
    }));
});

//build files for creating a dist release
gulp.task('build:dist', ['clean'], function(cb) {
  runSequence(['jshint', 'build', 'copy', 'copy:assets', 'images', 'test:unit'], 'html', cb);
});

//build files for development
gulp.task('build', ['clean'], function(cb) {
  runSequence(['sass', 'templates'], cb);
});

//generate a minified css files, 2 js file, change theirs name to be unique, and generate sourcemaps
gulp.task('html', function() {
  var assets = $.useref.assets({
    searchPath: '{build,client}'
  });

  return gulp.src(config.index)
    .pipe(assets)
    .pipe($.sourcemaps.init())
    .pipe($.if('**/*main.js', $.ngAnnotate()))
    .pipe($.if('*.js', $.uglify({
      mangle: false,
    })))
    .pipe($.if('*.css', $.csso()))
    .pipe($.if(['**/*main.js', '**/*main.css'], $.header(config.banner, {
      pkg: pkg
    })))
    .pipe($.rev())
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe($.revReplace())
    .pipe($.if('*.html', $.minifyHtml({
      empty: true
    })))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest(config.dist))
    .pipe($.size({
      title: 'html'
    }));
});

//copy assets in dist folder
gulp.task('copy:assets', function() {
  return gulp.src(config.assets, {
      dot: true
    }).pipe(gulp.dest(config.dist + '/assets'))
    .pipe($.size({
      title: 'copy:assets'
    }));
});

//copy assets in dist folder
gulp.task('copy', function() {
  return gulp.src([
      config.base + '/*',
      '!' + config.base + '/*.html',
      '!' + config.base + '/src',
      '!' + config.base + '/test'
    ]).pipe(gulp.dest(config.dist))
    .pipe($.size({
      title: 'copy'
    }));
});

//clean temporary directories
gulp.task('clean', del.bind(null, [config.dist, config.tmp]));

//lint files
gulp.task('jshint', function() {
  return gulp.src(config.js)
    .pipe(reload({
      stream: true,
      once: true
    }))
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});

/* tasks supposed to be public */

//default task
gulp.task('default', ['serve']); //

//run unit tests and exit
gulp.task('test:unit', ['build'], function(cb) {
  karma.start(_.assign({}, karmaConfig, {
    singleRun: true
  }), cb);
});

// Run e2e tests using protractor, make sure serve task is running.
gulp.task('test:e2e', ['webdriver:update'], function() {
  return gulp.src(protractorConfig.config.specs)
    .pipe($.protractor.protractor({
      configFile: 'build/protractor.config.js'
    }))
    .on('error', function(e) {
      throw e;
    });
});

//run the server,  watch for file changes and redo tests.
gulp.task('serve:tdd', function(cb) {
  runSequence(['serve', 'tdd'], cb);
});

//run the server after having built generated files, and watch for changes
gulp.task('serve', ['build'], function() {
  browserSync({
    notify: false,
    logPrefix: pkg.name,
    server: ['build', 'client']
  });

  gulp.watch(config.html, reload);
  gulp.watch(config.scss, ['sass', reload]);
  gulp.watch(config.js, ['jshint']);
  gulp.watch(config.tpl, ['templates', reload]);
  gulp.watch(config.assets, reload);
});

//run the app packed in the dist folder
gulp.task('serve:dist', ['build:dist'], function() {
  browserSync({
    notify: false,
    server: [config.dist]
  });
});
<commit_msg>Using new gulp-ruby-sass api in gulpfile<commit_after>'use strict';

var config = require('./build/build.config.js');
var karmaConfig = require('./build/karma.config.js');
var protractorConfig = require('./build/protractor.config.js');
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var runSequence = require('run-sequence');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var pkg = require('./package');
var karma = require('karma').server;
var del = require('del');
var _ = require('lodash');
/* jshint camelcase:false*/
var webdriverStandalone = require('gulp-protractor').webdriver_standalone;
var webdriverUpdate = require('gulp-protractor').webdriver_update;

//update webdriver if necessary, this task will be used by e2e task
gulp.task('webdriver:update', webdriverUpdate);

// run unit tests and watch files
gulp.task('tdd', function(cb) {
  karma.start(_.assign({}, karmaConfig, {
    singleRun: false,
    action: 'watch',
    browsers: ['PhantomJS']
  }), cb);
});

// run unit tests with travis CI
gulp.task('travis', ['build'], function(cb) {
  karma.start(_.assign({}, karmaConfig, {
    singleRun: true,
    browsers: ['PhantomJS']
  }), cb);
});

// optimize images and put them in the dist folder
gulp.task('images', function() {
  return gulp.src(config.images)
    .pipe($.imagemin({
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest(config.dist + '/assets/images'))
    .pipe($.size({
      title: 'images'
    }));
});

//generate angular templates using html2js
gulp.task('templates', function() {
  return gulp.src(config.tpl)
    .pipe($.changed(config.tmp))
    .pipe($.html2js({
      outputModuleName: 'templates',
      base: 'client',
      useStrict: true
    }))
    .pipe($.concat('templates.js'))
    .pipe(gulp.dest(config.tmp))
    .pipe($.size({
      title: 'templates'
    }));
});

//generate css files from scss sources
gulp.task('sass', function() {
  return $.rubySass(config.mainScss)
    .on('error', function(err) {
      console.log(err.message);
    })
    .pipe(gulp.dest(config.tmp))
    .pipe($.size({
      title: 'sass'
    }));
});

//build files for creating a dist release
gulp.task('build:dist', ['clean'], function(cb) {
  runSequence(['jshint', 'build', 'copy', 'copy:assets', 'images', 'test:unit'], 'html', cb);
});

//build files for development
gulp.task('build', ['clean'], function(cb) {
  runSequence(['sass', 'templates'], cb);
});

//generate a minified css files, 2 js file, change theirs name to be unique, and generate sourcemaps
gulp.task('html', function() {
  var assets = $.useref.assets({
    searchPath: '{build,client}'
  });

  return gulp.src(config.index)
    .pipe(assets)
    .pipe($.sourcemaps.init())
    .pipe($.if('**/*main.js', $.ngAnnotate()))
    .pipe($.if('*.js', $.uglify({
      mangle: false,
    })))
    .pipe($.if('*.css', $.csso()))
    .pipe($.if(['**/*main.js', '**/*main.css'], $.header(config.banner, {
      pkg: pkg
    })))
    .pipe($.rev())
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe($.revReplace())
    .pipe($.if('*.html', $.minifyHtml({
      empty: true
    })))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest(config.dist))
    .pipe($.size({
      title: 'html'
    }));
});

//copy assets in dist folder
gulp.task('copy:assets', function() {
  return gulp.src(config.assets, {
      dot: true
    }).pipe(gulp.dest(config.dist + '/assets'))
    .pipe($.size({
      title: 'copy:assets'
    }));
});

//copy assets in dist folder
gulp.task('copy', function() {
  return gulp.src([
      config.base + '/*',
      '!' + config.base + '/*.html',
      '!' + config.base + '/src',
      '!' + config.base + '/test'
    ]).pipe(gulp.dest(config.dist))
    .pipe($.size({
      title: 'copy'
    }));
});

//clean temporary directories
gulp.task('clean', del.bind(null, [config.dist, config.tmp]));

//lint files
gulp.task('jshint', function() {
  return gulp.src(config.js)
    .pipe(reload({
      stream: true,
      once: true
    }))
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});

/* tasks supposed to be public */

//default task
gulp.task('default', ['serve']); //

//run unit tests and exit
gulp.task('test:unit', ['build'], function(cb) {
  karma.start(_.assign({}, karmaConfig, {
    singleRun: true
  }), cb);
});

// Run e2e tests using protractor, make sure serve task is running.
gulp.task('test:e2e', ['webdriver:update'], function() {
  return gulp.src(protractorConfig.config.specs)
    .pipe($.protractor.protractor({
      configFile: 'build/protractor.config.js'
    }))
    .on('error', function(e) {
      throw e;
    });
});

//run the server,  watch for file changes and redo tests.
gulp.task('serve:tdd', function(cb) {
  runSequence(['serve', 'tdd'], cb);
});

//run the server after having built generated files, and watch for changes
gulp.task('serve', ['build'], function() {
  browserSync({
    notify: false,
    logPrefix: pkg.name,
    server: ['build', 'client']
  });

  gulp.watch(config.html, reload);
  gulp.watch(config.scss, ['sass', reload]);
  gulp.watch(config.js, ['jshint']);
  gulp.watch(config.tpl, ['templates', reload]);
  gulp.watch(config.assets, reload);
});

//run the app packed in the dist folder
gulp.task('serve:dist', ['build:dist'], function() {
  browserSync({
    notify: false,
    server: [config.dist]
  });
});
<|endoftext|>


<commit_before>import React from 'react';

const questions = {
  what: {
    question: 'Was ist CosmoWiki.de überhaupt?',
    answer:

          CosmoWiki.de ist ein nichtkommerzielles Projekt zur Verbreitung von Wissen über die Bereiche Astronomie und Raumfahrt.

          Auf Plattformen wie z.B. Wikipedia existiert ein gewaltiger Wissensschatz, der von Enthusiasten mit größter Sorgfalt für jedermann erstellt und gepflegt wird.
          Doch warum sollte dieser phantastische Speicher nicht über seine eigentlichen Grenzen hinaus genutzt werden?

          Wir recherchieren unzählige Informationen aus Wikipedia und anderen Quellen, sammeln, veknüpfen und bereiten sie hier in möglichst übersichtlicher Weise auf.
          Cosmowiki.de ist also im Grunde ein Hybride aus Enzyklopädie und Aggregator - ein zentraler Platz im Netz,
          an dem der Nutzer zwei der faszinierendsten Gebiete aus Wissenschaft und Technik auf neue Weise entdecken kann.

  },
  who: {
    question: 'Wem nützt CosmoWiki.de, für wen wurde es geschaffen?',
    answer:

          CosmoWiki.de dient uns allen - interessierten Laien ebenso wie begeisterten Amateuren und allen anderen Space-Fans.
          Jeder Nutzer kann hier frei das gewaltige Universum der Astronomie und Raumfahrt unter einem Dach entdecken, die Geschichte dieser zwei wohl bedeutendsten Bereiche menschlichen Schaffens
          erkunden und zielgerichtet Informationen über Personen, Orte oder Objekte finden.

          Selbst sind wir natürlich auch fasziniert von allem, was mit dem Weltall zu tun hat. So lautet unser Motto: Nutzer arbeiten für Nutzer!

  },
  license: {
    question: 'Darf ich Inhalte von CosmoWiki.de verwenden? Unter welcher Lizenz steht CosmoWiki.de?',
    answer:

          Alle Inhalte von CosmoWiki.de und die von Wikipedia eingebundenen Inhalte stehen unter der
           Creative-Commons-Lizenz Attribution-ShareAlike 3.0 Unported (CC-by-sa-3.0), wenn nichts anderes ausgewiesen wird.

          Gemäß den Bestimmungen der von Wikipedia verwendeten Lizenz
           Creative-Commons-Lizenz Attribution-ShareAlike 3.0 Unported (CC-by-sa-3.0) weisen wir darauf hin,
          dass CosmoWiki.de Artikel oder Teile von Artikeln von Wikipedia verwendet und einbindet.
          Dadurch steht CosmoWiki.de ebenfalls unter der  Creative Commons Lizenz CC BY-SA 3.0.

          Sie dürfen:
Teilen — das Material in jedwedem Format oder Medium vervielfältigen und weiterverbreiten.
Bearbeiten — das Material remixen, verändern und darauf aufbauen
          und zwar für beliebige Zwecke, sogar kommerziell.

          Weitere Informationen zu der verwendeten Lizenz erhalten sie hier:
          http://creativecommons.org/licenses/by-sa/3.0/de/

  },
  future: {
    question: 'Wie geht es weiter? Wie sieht die Zukunft von CosmoWiki.de aus?',
    answer:

          Dieses Projekt wird nie fertiggestellt sein, da sich auch Astronomie und Raumfahrt permanent weiterentwickeln. Unsere Datenbank wächst ständig um neue Inhalte an,
          bestehende Einträge werden um interessante Fakten ergänzt. Zusätzlich wird auch die Seite selbst weiterentwickelt, neue Funktionen werden das Nutzererlebnis verbessern.
          Wir hoffen auch, CosmoWiki.de bald auch in anderen Sprachen anbieten zu können.

          Die Community ist das Zentrum dieser Seite. Wir setzen auf den Enthusiasmus von Amateuren genauso wie auf die Fachkenntnisse von Naturwissenschaftlern und Historikern um ein Werk zu schaffen,
          das auch kritischen Analysen standhält.

  },
  contribute: {
    question: 'Wie kann ich helfen CosmoWiki.de zu verbessern?',
    answer:

          Wenn Sie etwas zu CosmoWiki.de beitragen und das Projekt unterstützen möchten, lassen Sie es uns wissen.
          Sie sind Hobby-Astronom oder Professor der Astrophysik, Historiker oder interessierter Laie, Raumfahrt-Begeisterter oder Astronaut, dann
          kontaktieren Sie uns bitte hier.

          Für Software-Entwickler und Programmierer ist CosmoWiki.de auch auf Github zu finden.

          Wir sind stets offen für Ihre Anregungen und Ideen, jede Hilfe ist willkommen.

  },
  thx: {
    question: 'Danke!',
    answer:

          An dieser Stelle möchten wir uns ganz herzlich bei Wikimedia,
          der Online-Enzyklopädie Wikipedia.org und seinen vielen freiwilligen Mitarbeitern
          für das größte Lexikon der Welt bedanken! Sie alle haben die Welt der Lexika in das 21. jahrhundert katapultiert und der Menschheit damit einen unschätzbaren Dienst erwiesen.

          Weiterhin bedanken wir uns sehr bei Wolfram Kriesing
          für die Kartenanwendung auf der "Orte"-Seite, unzählige andere Hilfestellungen rund um die Webprogrammierung
          und die generelle Unterstützung des Projektes.

  }
};

export default class AboutComponent extends React.Component {

  constructor() {
    super();
    this.state = {visibleSection: ''};
  }

  toggleCategory(category) {
    const newState = this.state.visibleSection === category ? '' : category;
    this.setState({visibleSection: newState});
  }

  render() {
    const toggleOnClick = category => this.toggleCategory.bind(this, category);
    const categories = Object.keys(questions);
    const isVisible = category => this.state.visibleSection === category;

    return (

Wir über uns

Ohne Idee keine Entwicklung

          {categories.map(category =>
            <Question category={category} toggleOnClick={toggleOnClick(category)} isVisible={isVisible(category)} />)}

    )
  }

  componentWillMount() {
    const category = typeof window !== 'undefined' && window.location.hash.replace(/^#/, '');
    this.toggleCategory(category);
  }
}

class Question {

  render() {
    const {toggleOnClick, category, isVisible} = this.props;
    const {question, answer} = questions[category];
    const classNames = isVisible ? 'answer visible' : 'answer hidden';

    return (

        {' ' + question}

{answer}

    );

  }

}<commit_msg>Better function names.<commit_after>import React from 'react';

const questions = {
  what: {
    question: 'Was ist CosmoWiki.de überhaupt?',
    answer:

          CosmoWiki.de ist ein nichtkommerzielles Projekt zur Verbreitung von Wissen über die Bereiche Astronomie und Raumfahrt.

          Auf Plattformen wie z.B. Wikipedia existiert ein gewaltiger Wissensschatz, der von Enthusiasten mit größter Sorgfalt für jedermann erstellt und gepflegt wird.
          Doch warum sollte dieser phantastische Speicher nicht über seine eigentlichen Grenzen hinaus genutzt werden?

          Wir recherchieren unzählige Informationen aus Wikipedia und anderen Quellen, sammeln, veknüpfen und bereiten sie hier in möglichst übersichtlicher Weise auf.
          Cosmowiki.de ist also im Grunde ein Hybride aus Enzyklopädie und Aggregator - ein zentraler Platz im Netz,
          an dem der Nutzer zwei der faszinierendsten Gebiete aus Wissenschaft und Technik auf neue Weise entdecken kann.

  },
  who: {
    question: 'Wem nützt CosmoWiki.de, für wen wurde es geschaffen?',
    answer:

          CosmoWiki.de dient uns allen - interessierten Laien ebenso wie begeisterten Amateuren und allen anderen Space-Fans.
          Jeder Nutzer kann hier frei das gewaltige Universum der Astronomie und Raumfahrt unter einem Dach entdecken, die Geschichte dieser zwei wohl bedeutendsten Bereiche menschlichen Schaffens
          erkunden und zielgerichtet Informationen über Personen, Orte oder Objekte finden.

          Selbst sind wir natürlich auch fasziniert von allem, was mit dem Weltall zu tun hat. So lautet unser Motto: Nutzer arbeiten für Nutzer!

  },
  license: {
    question: 'Darf ich Inhalte von CosmoWiki.de verwenden? Unter welcher Lizenz steht CosmoWiki.de?',
    answer:

          Alle Inhalte von CosmoWiki.de und die von Wikipedia eingebundenen Inhalte stehen unter der
           Creative-Commons-Lizenz Attribution-ShareAlike 3.0 Unported (CC-by-sa-3.0), wenn nichts anderes ausgewiesen wird.

          Gemäß den Bestimmungen der von Wikipedia verwendeten Lizenz
           Creative-Commons-Lizenz Attribution-ShareAlike 3.0 Unported (CC-by-sa-3.0) weisen wir darauf hin,
          dass CosmoWiki.de Artikel oder Teile von Artikeln von Wikipedia verwendet und einbindet.
          Dadurch steht CosmoWiki.de ebenfalls unter der  Creative Commons Lizenz CC BY-SA 3.0.

          Sie dürfen:
Teilen — das Material in jedwedem Format oder Medium vervielfältigen und weiterverbreiten.
Bearbeiten — das Material remixen, verändern und darauf aufbauen
          und zwar für beliebige Zwecke, sogar kommerziell.

          Weitere Informationen zu der verwendeten Lizenz erhalten sie hier:
          http://creativecommons.org/licenses/by-sa/3.0/de/

  },
  future: {
    question: 'Wie geht es weiter? Wie sieht die Zukunft von CosmoWiki.de aus?',
    answer:

          Dieses Projekt wird nie fertiggestellt sein, da sich auch Astronomie und Raumfahrt permanent weiterentwickeln. Unsere Datenbank wächst ständig um neue Inhalte an,
          bestehende Einträge werden um interessante Fakten ergänzt. Zusätzlich wird auch die Seite selbst weiterentwickelt, neue Funktionen werden das Nutzererlebnis verbessern.
          Wir hoffen auch, CosmoWiki.de bald auch in anderen Sprachen anbieten zu können.

          Die Community ist das Zentrum dieser Seite. Wir setzen auf den Enthusiasmus von Amateuren genauso wie auf die Fachkenntnisse von Naturwissenschaftlern und Historikern um ein Werk zu schaffen,
          das auch kritischen Analysen standhält.

  },
  contribute: {
    question: 'Wie kann ich helfen CosmoWiki.de zu verbessern?',
    answer:

          Wenn Sie etwas zu CosmoWiki.de beitragen und das Projekt unterstützen möchten, lassen Sie es uns wissen.
          Sie sind Hobby-Astronom oder Professor der Astrophysik, Historiker oder interessierter Laie, Raumfahrt-Begeisterter oder Astronaut, dann
          kontaktieren Sie uns bitte hier.

          Für Software-Entwickler und Programmierer ist CosmoWiki.de auch auf Github zu finden.

          Wir sind stets offen für Ihre Anregungen und Ideen, jede Hilfe ist willkommen.

  },
  thx: {
    question: 'Danke!',
    answer:

          An dieser Stelle möchten wir uns ganz herzlich bei Wikimedia,
          der Online-Enzyklopädie Wikipedia.org und seinen vielen freiwilligen Mitarbeitern
          für das größte Lexikon der Welt bedanken! Sie alle haben die Welt der Lexika in das 21. jahrhundert katapultiert und der Menschheit damit einen unschätzbaren Dienst erwiesen.

          Weiterhin bedanken wir uns sehr bei Wolfram Kriesing
          für die Kartenanwendung auf der "Orte"-Seite, unzählige andere Hilfestellungen rund um die Webprogrammierung
          und die generelle Unterstützung des Projektes.

  }
};

export default class AboutComponent extends React.Component {

  constructor() {
    super();
    this.state = {visibleSection: ''};
  }

  toggleCategory(category) {
    const newState = this.state.visibleSection === category ? '' : category;
    this.setState({visibleSection: newState});
  }

  render() {
    const buildToggleFunctionFor = category => this.toggleCategory.bind(this, category);
    const categories = Object.keys(questions);
    const isVisible = category => this.state.visibleSection === category;

    return (

Wir über uns

Ohne Idee keine Entwicklung

          {categories.map(category =>
            <Question category={category} toggleFunction={buildToggleFunctionFor(category)} isVisible={isVisible(category)} />)}

    )
  }

  componentWillMount() {
    const category = typeof window !== 'undefined' && window.location.hash.replace(/^#/, '');
    this.toggleCategory(category);
  }
}

class Question {

  render() {
    const {toggleFunction, category, isVisible} = this.props;
    const {question, answer} = questions[category];
    const classNames = isVisible ? 'answer visible' : 'answer hidden';

    return (

        {' ' + question}

{answer}

    );

  }

}<|endoftext|>


<commit_before>export { default as Button } from './interactive/Button';
export { default as Checkbox } from './interactive/Checkbox';
export { default as Form } from './interactive/Form';
export { default as Input } from './interactive/Input';
export { default as Radio } from './interactive/Radio';

export { default as Aside } from './layout/Aside';
export { default as Footer } from './layout/Footer';
export { default as Header } from './layout/Header';
export { default as Main } from './layout/Main';
export { default as Modal } from './layout/Modal';
export { default as Popup } from './layout/Popup';
export { default as Section } from './layout/Section';
export { default as Table } from './layout/Table';
export { default as Tooltip } from './layout/Tooltip';
export { default as Wrapper } from './layout/Wrapper';

export { default as Link } from './navigation/Link';
export { default as Nav } from './navigation/Nav';

export { default as Alert } from './typography/Alert';
export { default as Article } from './typography/Article';
export { H1, H2, H3 } from './typography/HX';
export { default as Label } from './typography/Label';
export { Ul, Li } from './typography/List';
export { default as P } from './typography/P';
<commit_msg>update components export<commit_after>export { Button } from './interactive/Button';
export { Checkbox } from './interactive/Checkbox';
export { Error } from './interactive/Error';
export { Fieldset } from './interactive/Fieldset';
export { Form } from './interactive/Form';
export { default as Input } from './interactive/Input';
export { default as Link } from './interactive/Link';
export { Radio } from './interactive/Radio';
export { default as TextInput } from './interactive/TextInput';

export { Aside } from './layout/Aside';
export { Footer } from './layout/Footer';
export { Header } from './layout/Header';
export { Main } from './layout/Main';
export { default as Modal } from './layout/Modal';
export { Nav } from './layout/Nav';
export { Section } from './layout/Section';
export { Table } from './layout/Table';
export { Toast } from './layout/Toast';
export { Wrapper } from './layout/Wrapper';

export { Alert } from './text/Alert';
export { Article } from './text/Article';
export { H1, H2, H3 } from './text/HX';
export { Label } from './text/Label';
export { Ul, Li } from './text/List';
export { P } from './text/P';
export { Tooltip } from './text/Tooltip';
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');

var gulp = require('gulp');
var plugins = require('gulp-load-plugins')(); // Load all gulp plugins
                                              // automatically and attach
                                              // them to the `plugins` object

var runSequence = require('run-sequence');    // Temporary solution until gulp 4
                                              // https://github.com/gulpjs/gulp/issues/355

var browserSync = require('browser-sync');
var reload      = browserSync.reload;

var pkg = require('./package.json');
var dirs = pkg['h5bp-configs'].directories;

// ---------------------------------------------------------------------
// | Helper tasks                                                      |
// ---------------------------------------------------------------------

gulp.task('archive:create_archive_dir', function () {
    fs.mkdirSync(path.resolve(dirs.archive), '0755');
});

gulp.task('archive:zip', function (done) {

    var archiveName = path.resolve(dirs.archive, pkg.name + '_v' + pkg.version + '.zip');
    var archiver = require('archiver')('zip');
    var files = require('glob').sync('**/*.*', {
        'cwd': dirs.dist,
        'dot': true // include hidden files
    });
    var output = fs.createWriteStream(archiveName);

    archiver.on('error', function (error) {
        done();
        throw error;
    });

    output.on('close', done);

    files.forEach(function (file) {

        var filePath = path.resolve(dirs.dist, file);

        // `archiver.bulk` does not maintain the file
        // permissions, so we need to add files individually
        archiver.append(fs.createReadStream(filePath), {
            'name': file,
            'mode': fs.statSync(filePath)
        });

    });

    archiver.pipe(output);
    archiver.finalize();

});

gulp.task('clean', function (done) {
    require('del')([
        dirs.archive,
        dirs.dist
    ], done);
});

gulp.task('copy', [
    'copy:.htaccess',
    'copy:index.html',
    'copy:jquery',
    'copy:main.min.css',
    'copy:main.min.js',
    'copy:misc',
    'copy:normalize'
]);

gulp.task('copy:.htaccess', function () {
    return gulp.src('node_modules/apache-server-configs/dist/.htaccess')
               .pipe(plugins.replace(/# ErrorDocument/g, 'ErrorDocument'))
               .pipe(gulp.dest(dirs.dist));
});

gulp.task('copy:index.html', function () {
    return gulp.src(dirs.src + '/index.html')
               .pipe(plugins.replace(/{{JQUERY_VERSION}}/g, pkg.devDependencies.jquery))
               .pipe(gulp.dest(dirs.dist));
});

gulp.task('copy:jquery', function () {
    return gulp.src(['node_modules/jquery/dist/jquery.min.js'])
               .pipe(plugins.rename('jquery-' + pkg.devDependencies.jquery + '.min.js'))
               .pipe(gulp.dest(dirs.dist + '/js/vendor'));
});

gulp.task('copy:main.min.css', function () {
    var banner = '/*! HTML5 Boilerplate v' + pkg.version +
                    ' | ' + pkg.license.type + ' License' +
                    ' | ' + pkg.homepage + ' */\n\n';

    return gulp.src(dirs.src + '/css/main.min.css')
               .pipe(plugins.header(banner))
               .pipe(gulp.dest(dirs.dist + '/css'));
});

gulp.task('copy:main.min.js', function () {
    return gulp.src(dirs.src + '/js/main.min.js')
               .pipe(gulp.dest(dirs.dist + '/js'));
});

gulp.task('copy:misc', function () {
    return gulp.src([

        // Copy all files
        dirs.src + '/**/*',

        // Exclude the following files
        // (other tasks will handle the copying of these files)
        '!' + dirs.src + '/index.html',
        '!' + dirs.src + '/js/main.js',
        '!' + dirs.src + '/js/main.min.js',
        '!' + dirs.src + '/js/main.min.css'

    ], {

        // Include hidden files by default
        dot: true

    }).pipe(gulp.dest(dirs.dist));
});

gulp.task('copy:html', function() {
    return gulp.src([
       // Copy html files
       dirs.src + '/**/*.html'
   ], {
   })
   .pipe(plugins.replace(/{{JQUERY_VERSION}}/g, pkg.devDependencies.jquery))
   .pipe(gulp.dest(dirs.dist));
});

gulp.task('run:html', function(done) {
    runSequence(
        'copy:html',
        'bs-reload',
    done);
});

gulp.task('copy:normalize', function () {
    return gulp.src('node_modules/normalize.css/normalize.css')
        .pipe(plugins.rename({ suffix: '.min' }))
        .pipe(plugins.minifyCss())
        .pipe(gulp.dest(dirs.dist + '/css'));
});

gulp.task('lint:js', function () {
    return gulp.src([
        'gulpfile.js',
        dirs.src + '/js/*.js',
        dirs.test + '/*.js',
        // Exclude the following files
        '!' + dirs.src + '/js/main.min.js'
    ]).pipe(plugins.jscs())
      .pipe(plugins.jshint())
      .pipe(plugins.jshint.reporter('jshint-stylish'))
      .pipe(plugins.jshint.reporter('fail'));
});

// Scripts
gulp.task('scripts', function() {
    return gulp.src(dirs.src + '/js/**/main.js')
        .pipe(plugins.rename({ suffix: '.min' }))
        .pipe(plugins.uglify())
        .pipe(gulp.dest(dirs.src + '/js'))
        .pipe(reload({ stream:true }))
        .pipe(plugins.notify({ message: 'Scripts task completed' }));
});

gulp.task('compile:scripts', function(done) {
    runSequence(
        'scripts',
        'copy:main.min.js',
    done);
});

// Styles
gulp.task('styles', function() {
    return gulp.src(dirs.src + '/less/main.less')
        .pipe(plugins.less())
        .pipe(plugins.autoprefixer())
        // .pipe(gulp.dest(dirs.src + '/css'))
        .pipe(plugins.rename({ suffix: '.min' }))
        .pipe(plugins.minifyCss())
        .pipe(gulp.dest(dirs.src + '/css'))
        .pipe(reload({ stream:true }))
        .pipe(plugins.notify({ message: 'Styles task completed' }));
});

gulp.task('compile:styles', function(done) {
    runSequence(
        'styles',
        'copy:main.min.css',
    done);
});

// BrowserSync task for starting the server.
gulp.task('browser-sync', function() {
    browserSync.init({
        server: {
            baseDir: './' + dirs.dist
        }
    });
});

// Reload all Browsers
gulp.task('bs-reload', function () {
    browserSync.reload();
});

// Remove main.css + min and main.min.js from the src folder
gulp.task('clean:src', function (done) {
    require('del')([
        dirs.src + '/css',
        dirs.src + '/js/main.min.js'
    ], done);
});

// ---------------------------------------------------------------------
// | Main tasks                                                        |
// ---------------------------------------------------------------------

// Watch
gulp.task('watch', function () {
    // Watch .less files
    gulp.watch(dirs.src + '/less/**/*.less', ['compile:styles']);

    // Watch .js files
    gulp.watch(dirs.src + '/js/**/*.js', ['compile:scripts']);

    // Watch .html files
    gulp.watch(dirs.src + '/*.html', ['run:html']);
});

// Archive
gulp.task('archive', function (done) {
    runSequence(
        'build',
        'archive:create_archive_dir',
        'archive:zip',
    done);
});

// Build
gulp.task('build', function (done) {
    runSequence(
        ['clean', 'lint:js', 'styles', 'scripts'],
        'copy', 'clean:src',
    done);
});

// Dev
gulp.task('dev', function (done) {
    runSequence(
        ['clean', 'lint:js', 'styles', 'scripts', 'browser-sync', 'watch'],
        'copy',
    done);
});

// Default
gulp.task('default', ['build']);
<commit_msg>Watch image files inside /img folder when "gulp dev" and copy them from src to dist<commit_after>var fs = require('fs');
var path = require('path');

var gulp = require('gulp');
var plugins = require('gulp-load-plugins')(); // Load all gulp plugins
                                              // automatically and attach
                                              // them to the `plugins` object

var runSequence = require('run-sequence');    // Temporary solution until gulp 4
                                              // https://github.com/gulpjs/gulp/issues/355

var browserSync = require('browser-sync');
var reload      = browserSync.reload;

var pkg = require('./package.json');
var dirs = pkg['h5bp-configs'].directories;

// ---------------------------------------------------------------------
// | Helper tasks                                                      |
// ---------------------------------------------------------------------

gulp.task('archive:create_archive_dir', function () {
    fs.mkdirSync(path.resolve(dirs.archive), '0755');
});

gulp.task('archive:zip', function (done) {

    var archiveName = path.resolve(dirs.archive, pkg.name + '_v' + pkg.version + '.zip');
    var archiver = require('archiver')('zip');
    var files = require('glob').sync('**/*.*', {
        'cwd': dirs.dist,
        'dot': true // include hidden files
    });
    var output = fs.createWriteStream(archiveName);

    archiver.on('error', function (error) {
        done();
        throw error;
    });

    output.on('close', done);

    files.forEach(function (file) {

        var filePath = path.resolve(dirs.dist, file);

        // `archiver.bulk` does not maintain the file
        // permissions, so we need to add files individually
        archiver.append(fs.createReadStream(filePath), {
            'name': file,
            'mode': fs.statSync(filePath)
        });

    });

    archiver.pipe(output);
    archiver.finalize();

});

gulp.task('clean', function (done) {
    require('del')([
        dirs.archive,
        dirs.dist
    ], done);
});

gulp.task('copy', [
    'copy:.htaccess',
    'copy:index.html',
    'copy:jquery',
    'copy:main.min.css',
    'copy:main.min.js',
    'copy:misc',
    'copy:normalize'
]);

gulp.task('copy:.htaccess', function () {
    return gulp.src('node_modules/apache-server-configs/dist/.htaccess')
               .pipe(plugins.replace(/# ErrorDocument/g, 'ErrorDocument'))
               .pipe(gulp.dest(dirs.dist));
});

gulp.task('copy:index.html', function () {
    return gulp.src(dirs.src + '/index.html')
               .pipe(plugins.replace(/{{JQUERY_VERSION}}/g, pkg.devDependencies.jquery))
               .pipe(gulp.dest(dirs.dist));
});

gulp.task('copy:jquery', function () {
    return gulp.src(['node_modules/jquery/dist/jquery.min.js'])
               .pipe(plugins.rename('jquery-' + pkg.devDependencies.jquery + '.min.js'))
               .pipe(gulp.dest(dirs.dist + '/js/vendor'));
});

gulp.task('copy:main.min.css', function () {
    var banner = '/*! HTML5 Boilerplate v' + pkg.version +
                    ' | ' + pkg.license.type + ' License' +
                    ' | ' + pkg.homepage + ' */\n\n';

    return gulp.src(dirs.src + '/css/main.min.css')
               .pipe(plugins.header(banner))
               .pipe(gulp.dest(dirs.dist + '/css'));
});

gulp.task('copy:main.min.js', function () {
    return gulp.src(dirs.src + '/js/main.min.js')
               .pipe(gulp.dest(dirs.dist + '/js'));
});

gulp.task('copy:misc', function () {
    return gulp.src([

        // Copy all files
        dirs.src + '/**/*',

        // Exclude the following files
        // (other tasks will handle the copying of these files)
        '!' + dirs.src + '/index.html',
        '!' + dirs.src + '/js/main.js',
        '!' + dirs.src + '/js/main.min.js',
        '!' + dirs.src + '/js/main.min.css'

    ], {

        // Include hidden files by default
        dot: true

    }).pipe(gulp.dest(dirs.dist));
});

gulp.task('copy:images', function () {
    return gulp.src([
        // Copy all image files
        dirs.src + '/img/**/*'
    ], {
        // Include hidden files by default
        dot: true
    }).pipe(gulp.dest(dirs.dist + '/img'));
});

gulp.task('copy:html', function() {
    return gulp.src([
       // Copy html files
       dirs.src + '/**/*.html'
   ], {
   })
   .pipe(plugins.replace(/{{JQUERY_VERSION}}/g, pkg.devDependencies.jquery))
   .pipe(gulp.dest(dirs.dist));
});

gulp.task('run:html', function(done) {
    runSequence(
        'copy:html',
        'bs-reload',
    done);
});

gulp.task('copy:normalize', function () {
    return gulp.src('node_modules/normalize.css/normalize.css')
        .pipe(plugins.rename({ suffix: '.min' }))
        .pipe(plugins.minifyCss())
        .pipe(gulp.dest(dirs.dist + '/css'));
});

gulp.task('lint:js', function () {
    return gulp.src([
        'gulpfile.js',
        dirs.src + '/js/*.js',
        dirs.test + '/*.js',
        // Exclude the following files
        '!' + dirs.src + '/js/main.min.js'
    ]).pipe(plugins.jscs())
      .pipe(plugins.jshint())
      .pipe(plugins.jshint.reporter('jshint-stylish'))
      .pipe(plugins.jshint.reporter('fail'));
});

// Scripts
gulp.task('scripts', function() {
    return gulp.src(dirs.src + '/js/**/main.js')
        .pipe(plugins.rename({ suffix: '.min' }))
        .pipe(plugins.uglify())
        .pipe(gulp.dest(dirs.src + '/js'))
        .pipe(reload({ stream:true }))
        .pipe(plugins.notify({ message: 'Scripts task completed' }));
});

gulp.task('compile:scripts', function(done) {
    runSequence(
        'scripts',
        'copy:main.min.js',
    done);
});

// Styles
gulp.task('styles', function() {
    return gulp.src(dirs.src + '/less/main.less')
        .pipe(plugins.less())
        .pipe(plugins.autoprefixer())
        // .pipe(gulp.dest(dirs.src + '/css'))
        .pipe(plugins.rename({ suffix: '.min' }))
        .pipe(plugins.minifyCss())
        .pipe(gulp.dest(dirs.src + '/css'))
        .pipe(reload({ stream:true }))
        .pipe(plugins.notify({ message: 'Styles task completed' }));
});

gulp.task('compile:styles', function(done) {
    runSequence(
        'styles',
        'copy:main.min.css',
    done);
});

// BrowserSync task for starting the server.
gulp.task('browser-sync', function() {
    browserSync.init({
        server: {
            baseDir: './' + dirs.dist
        }
    });
});

// Reload all Browsers
gulp.task('bs-reload', function () {
    browserSync.reload();
});

// Remove main.css + min and main.min.js from the src folder
gulp.task('clean:src', function (done) {
    require('del')([
        dirs.src + '/css',
        dirs.src + '/js/main.min.js'
    ], done);
});

// ---------------------------------------------------------------------
// | Main tasks                                                        |
// ---------------------------------------------------------------------

// Watch
gulp.task('watch', function () {
    // Watch .less files
    gulp.watch(dirs.src + '/less/**/*.less', ['compile:styles']);

    // Watch .js files
    gulp.watch(dirs.src + '/js/**/*.js', ['compile:scripts']);

    // Watch .html files
    gulp.watch(dirs.src + '/*.html', ['run:html']);

    // Watch image files
    gulp.watch(dirs.src + '/img/**/*', ['copy:images']);
});

// Archive
gulp.task('archive', function (done) {
    runSequence(
        'build',
        'archive:create_archive_dir',
        'archive:zip',
    done);
});

// Build
gulp.task('build', function (done) {
    runSequence(
        ['clean', 'lint:js', 'styles', 'scripts'],
        'copy', 'clean:src',
    done);
});

// Dev
gulp.task('dev', function (done) {
    runSequence(
        ['clean', 'lint:js', 'styles', 'scripts', 'browser-sync', 'watch'],
        'copy',
    done);
});

// Default
gulp.task('default', ['build']);
<|endoftext|>


<commit_before>var debug = require('../utils/debug');
var diff = require('../utils').diff;
var registerComponent = require('../core/component').registerComponent;
var THREE = require('../lib/three');

var warn = debug('components:sound:warn');

/**
 * Sound component.
 */
module.exports.Component = registerComponent('sound', {
  schema: {
    src: { default: '' },
    on: { default: 'click' },
    autoplay: { default: false },
    loop: { default: false },
    volume: { default: 1 }
  },

  init: function () {
    this.listener = null;
    this.sound = null;
  },

  update: function (oldData) {
    var data = this.data;
    var diffData = diff(oldData || {}, data);
    var el = this.el;
    var sound = this.sound;
    var src = data.src;
    var srcChanged = 'src' in diffData;

    // Create new sound if not yet created or changing `src`.
    if (srcChanged) {
      if (!src) {
        warn('Audio source was not specified with `src`');
        return;
      }
      sound = this.setupSound();
    }

    if (srcChanged || 'autoplay' in diffData) {
      sound.autoplay = data.autoplay;
    }

    if (srcChanged || 'loop' in diffData) {
      sound.setLoop(data.loop);
    }

    if (srcChanged || 'volume' in diffData) {
      sound.setVolume(data.volume);
    }

    if ('on' in diffData) {
      if (oldData && oldData.on) {
        el.removeEventListener(oldData.on);
      }
      el.addEventListener(data.on, this.play.bind(this));
    }

    // All sound values set. Load in `src.
    if (srcChanged) {
      sound.load(src);
    }
  },

  remove: function () {
    this.el.removeObject3D('sound');
    this.sound.disconnect();
  },

  /**
   * Removes current sound object, creates new sound object, adds to entity.
   *
   * @returns {object} sound
   */
  setupSound: function () {
    var el = this.el;
    var sceneEl = el.sceneEl;
    var sound = this.sound;

    if (sound) {
      this.stop();
      el.removeObject3D('sound');
    }

    // Only want one AudioListener. Cache it on the scene.
    var listener = this.listener = sceneEl.audioListener || new THREE.AudioListener();
    sceneEl.audioListener = listener;

    if (sceneEl.camera) {
      sceneEl.camera.add(listener);
    }

    // Wait for camera if necessary.
    sceneEl.addEventListener('camera-set-active', function (evt) {
      evt.detail.cameraEl.getObject3D('camera').add(listener);
    });

    sound = this.sound = new THREE.PositionalAudio(listener);
    el.setObject3D('sound', sound);

    sound.source.onended = function () {
      sound.onEnded();
      el.emit('sound-ended');
    };

    return sound;
  },

  play: function () {
    if (!this.sound.source.buffer) { return; }
    this.sound.play();
  },

  stop: function () {
    if (!this.sound.source.buffer) { return; }
    this.sound.stop();
  },

  pause: function () {
    if (!this.sound.source.buffer) { return; }
    this.sound.pause();
  }
});
<commit_msg>pause sound only if sound is playing<commit_after>var debug = require('../utils/debug');
var diff = require('../utils').diff;
var registerComponent = require('../core/component').registerComponent;
var THREE = require('../lib/three');

var warn = debug('components:sound:warn');

/**
 * Sound component.
 */
module.exports.Component = registerComponent('sound', {
  schema: {
    src: { default: '' },
    on: { default: 'click' },
    autoplay: { default: false },
    loop: { default: false },
    volume: { default: 1 }
  },

  init: function () {
    this.listener = null;
    this.sound = null;
  },

  update: function (oldData) {
    var data = this.data;
    var diffData = diff(oldData || {}, data);
    var el = this.el;
    var sound = this.sound;
    var src = data.src;
    var srcChanged = 'src' in diffData;

    // Create new sound if not yet created or changing `src`.
    if (srcChanged) {
      if (!src) {
        warn('Audio source was not specified with `src`');
        return;
      }
      sound = this.setupSound();
    }

    if (srcChanged || 'autoplay' in diffData) {
      sound.autoplay = data.autoplay;
    }

    if (srcChanged || 'loop' in diffData) {
      sound.setLoop(data.loop);
    }

    if (srcChanged || 'volume' in diffData) {
      sound.setVolume(data.volume);
    }

    if ('on' in diffData) {
      if (oldData && oldData.on) {
        el.removeEventListener(oldData.on);
      }
      el.addEventListener(data.on, this.play.bind(this));
    }

    // All sound values set. Load in `src.
    if (srcChanged) {
      sound.load(src);
    }
  },

  remove: function () {
    this.el.removeObject3D('sound');
    this.sound.disconnect();
  },

  /**
   * Removes current sound object, creates new sound object, adds to entity.
   *
   * @returns {object} sound
   */
  setupSound: function () {
    var el = this.el;
    var sceneEl = el.sceneEl;
    var sound = this.sound;

    if (sound) {
      this.stop();
      el.removeObject3D('sound');
    }

    // Only want one AudioListener. Cache it on the scene.
    var listener = this.listener = sceneEl.audioListener || new THREE.AudioListener();
    sceneEl.audioListener = listener;

    if (sceneEl.camera) {
      sceneEl.camera.add(listener);
    }

    // Wait for camera if necessary.
    sceneEl.addEventListener('camera-set-active', function (evt) {
      evt.detail.cameraEl.getObject3D('camera').add(listener);
    });

    sound = this.sound = new THREE.PositionalAudio(listener);
    el.setObject3D('sound', sound);

    sound.source.onended = function () {
      sound.onEnded();
      el.emit('sound-ended');
    };

    return sound;
  },

  play: function () {
    if (!this.sound.source.buffer) { return; }
    this.sound.play();
  },

  stop: function () {
    if (!this.sound.source.buffer) { return; }
    this.sound.stop();
  },

  pause: function () {
    if (!this.sound.source.buffer || !this.sound.isPlaying) { return; }
    this.sound.pause();
  }
});
<|endoftext|>


<commit_before>/*
 * Minimal Object Storage Library, (C) 2015 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var babel = require('gulp-babel')
var concat = require('gulp-concat')
var exec = require('child_process').exec
var gulp = require('gulp')
var mocha = require('gulp-mocha')
var sourcemaps = require('gulp-sourcemaps')

gulp.task('default', ['test'], function () {
})

gulp.task('compile', function (cb) {
    compile('src/main/**/*.js', 'minio.js', 'dist/main', cb)
})

gulp.task('test:compile', function (cb) {
    compile('src/test/**/*.js', 'minio-test.js', 'dist/test', cb)
})

gulp.task('test', ['compile', 'test:compile'], function () {
    gulp.src('dist/test/*.js', {read: false})
        .pipe(mocha({reporter: 'spec'}))
})

gulp.task('example:compile', function (cb) {
    "use strict";
    compile('src/example/**/*.js', 'example.js', 'dist/example', cb)
})

gulp.task('example', ['compile', 'example:compile'], function (cb) {
    "use strict";
    exec('node dist/example/example.js', function (err, stdout, stderr) {
        console.log(stdout)
        console.log(stderr)
        cb(err)
    })
})

function compile(src, name, dest, cb) {
    gulp.src(src)
        .pipe(sourcemaps.init())
        //.pipe(concat(name))
        .pipe(babel())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(dest))
        .on('end', function () {
            cb()
        })
}
<commit_msg>Changing reporter from spec to min<commit_after>/*
 * Minimal Object Storage Library, (C) 2015 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var babel = require('gulp-babel')
var concat = require('gulp-concat')
var exec = require('child_process').exec
var gulp = require('gulp')
var mocha = require('gulp-mocha')
var sourcemaps = require('gulp-sourcemaps')

gulp.task('default', ['test'], function () {
})

gulp.task('compile', function (cb) {
    compile('src/main/**/*.js', 'minio.js', 'dist/main', cb)
})

gulp.task('test:compile', function (cb) {
    compile('src/test/**/*.js', 'minio-test.js', 'dist/test', cb)
})

gulp.task('test', ['compile', 'test:compile'], function () {
    gulp.src('dist/test/*.js', {read: false})
        .pipe(mocha({reporter: 'min'}))
})

gulp.task('example:compile', function (cb) {
    "use strict";
    compile('src/example/**/*.js', 'example.js', 'dist/example', cb)
})

gulp.task('example', ['compile', 'example:compile'], function (cb) {
    "use strict";
    exec('node dist/example/example.js', function (err, stdout, stderr) {
        console.log(stdout)
        console.log(stderr)
        cb(err)
    })
})

function compile(src, name, dest, cb) {
    gulp.src(src)
        .pipe(sourcemaps.init())
        //.pipe(concat(name))
        .pipe(babel())
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(dest))
        .on('end', function () {
            cb()
        })
}
<|endoftext|>


<commit_before><commit_msg>Removed unused Gulp file.<commit_after><|endoftext|>


<commit_before>/* eslint-env node */
var gulp = require('gulp')
var less = require('gulp-less')
var exec = require('child_process').exec
var sourcemaps = require('gulp-sourcemaps')
var csso = require('gulp-csso')
var rename = require('gulp-rename')
var fs = require('fs')
var hasha = require('hasha')

function run(command) {
  var child = exec(command)
  child.stdout.pipe(process.stdout)
  child.stderr.pipe(process.stderr)
  process.on('exit', function(code) {
    if (child.exit) { child.exit(code) }
  })
  child.on('exit', function(code) {
    process.exit(code)
  })
}

gulp.task('less', function() {
  return gulp.src('public/less/main.less')
    .pipe(sourcemaps.init())
    .pipe(less())
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('public/css'))
})

gulp.task('cssmin', function() {
  return gulp.src('public/css/main.css')
    .pipe(csso())
    .pipe(rename({
      suffix: '.min'
    }))
    .pipe(gulp.dest('public/css'))
})

gulp.task('watch', function() {
  run('npm run watchify')
  run('npm run watchify-test')
  gulp.watch('public/less/**/*.less', ['less'])
})

gulp.task('dev', ['default'], function() {
  run('npm start')
})

gulp.task('hash', function(done) {
  hasha.fromFile('./public/js/main.js', { algorithm: 'md5' }).then(function(hash) {
    fs.readFile('./package.json', 'utf8', function(err, pkg) {
      var json = JSON.parse(pkg)
      json.cache = hash
      fs.writeFile('package.json', JSON.stringify(json, null, 2), done)
    })
  })
})

gulp.task('css', ['less', 'cssmin']);

gulp.task('default', ['less', 'watch'])

<commit_msg>errant semicolon<commit_after>/* eslint-env node */
var gulp = require('gulp')
var less = require('gulp-less')
var exec = require('child_process').exec
var sourcemaps = require('gulp-sourcemaps')
var csso = require('gulp-csso')
var rename = require('gulp-rename')
var fs = require('fs')
var hasha = require('hasha')

function run(command) {
  var child = exec(command)
  child.stdout.pipe(process.stdout)
  child.stderr.pipe(process.stderr)
  process.on('exit', function(code) {
    if (child.exit) { child.exit(code) }
  })
  child.on('exit', function(code) {
    process.exit(code)
  })
}

gulp.task('less', function() {
  return gulp.src('public/less/main.less')
    .pipe(sourcemaps.init())
    .pipe(less())
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('public/css'))
})

gulp.task('cssmin', function() {
  return gulp.src('public/css/main.css')
    .pipe(csso())
    .pipe(rename({
      suffix: '.min'
    }))
    .pipe(gulp.dest('public/css'))
})

gulp.task('watch', function() {
  run('npm run watchify')
  run('npm run watchify-test')
  gulp.watch('public/less/**/*.less', ['less'])
})

gulp.task('dev', ['default'], function() {
  run('npm start')
})

gulp.task('hash', function(done) {
  hasha.fromFile('./public/js/main.js', { algorithm: 'md5' }).then(function(hash) {
    fs.readFile('./package.json', 'utf8', function(err, pkg) {
      var json = JSON.parse(pkg)
      json.cache = hash
      fs.writeFile('package.json', JSON.stringify(json, null, 2), done)
    })
  })
})

gulp.task('css', ['less', 'cssmin'])

gulp.task('default', ['less', 'watch'])

<|endoftext|>


<commit_before>var path = require('path');
var gulp = require('gulp');
var preprocess = require('gulp-preprocess');
gulp.task('dev', function() {
  gulp.src(path.resolve('appsettings.js'))
    .pipe(preprocess({context: { NODE_ENV: 'DEVELOPMENT', DEBUG: true}}))
    .pipe(gulp.dest('client/www/js/'));
});

gulp.task('test_env', function() {
  gulp.src(path.resolve('appsettings.js'))
    .pipe(preprocess({context: { NODE_ENV: 'TEST', DEBUG: true}}))
    .pipe(gulp.dest('client/www/js/'));
});

gulp.task('prod', function() {
  gulp.src(path.resolve('appsettings.js'))
    .pipe(preprocess({context: { NODE_ENV: 'PRODUCTION'}}))
    .pipe(gulp.dest(path.resolve('client/www/js/')));
});<commit_msg>(chore) write out gulp task to utilize android specific api url<commit_after>var path = require('path');
var gulp = require('gulp');
var preprocess = require('gulp-preprocess');
gulp.task('dev', function() {
  gulp.src(path.resolve('appsettings.js'))
    .pipe(preprocess({context: { NODE_ENV: 'DEVELOPMENT', DEBUG: true}}))
    .pipe(gulp.dest('client/www/js/'));
});

gulp.task('test_env', function() {
  gulp.src(path.resolve('appsettings.js'))
    .pipe(preprocess({context: { NODE_ENV: 'TEST', DEBUG: true}}))
    .pipe(gulp.dest('client/www/js/'));
});

gulp.task('prod', function() {
  gulp.src(path.resolve('appsettings.js'))
    .pipe(preprocess({context: { NODE_ENV: 'PRODUCTION'}}))
    .pipe(gulp.dest(path.resolve('client/www/js/')));
});
gulp.task('android', function() {
  gulp.src(path.resolve('appsettings.js'))
    .pipe(preprocess({context: { NODE_ENV: 'ANDROID'}}))
    .pipe(gulp.dest(path.resolve('client/www/js/')));
});<|endoftext|>


<commit_before>/**
 * gulpfile.js for php-library developement
 *
 * 1. install node.js & npm
 * 2. $ npm install
 * 3. $ npm start
 */
var gulp = require('gulp');
var exec = require('child_process').exec;
var bs = require('browser-sync').create();

gulp.task('default', ['test', 'inspect']);

function test(done) {
    var p = exec('composer test');
    p.stdout.pipe(process.stdout);
    p.stderr.pipe(process.stderr);
    p.on('exit', done);
}

function inspect(done) {
    var r = 3;
    function wait() {
        --r || done();
    }
    exec('composer doc', wait);
    exec('composer metrics', wait);
    var lint = exec('composer lint');
    lint.stdout.pipe(process.stdout);
    lint.stderr.pipe(process.stderr);
    lint.on('exit', wait);
}

gulp.task('test', test);
gulp.task('inspect', inspect);

gulp.task('start', function(){
    bs.init({
        server: {
            baseDir: "artifacts/"
        },
        ghostMode: false
    });

    gulp.watch(['src/**/*.php', 'tests/**/*Test.php'], {}, function(ev){
        inspect(function(){
            test(bs.reload);
        });
    });
});

<commit_msg>incremental lint<commit_after>/**
 * gulpfile.js for php-library developement
 *
 * 1. install node.js & npm
 * 2. $ npm install
 * 3. $ npm start
 */
var gulp = require('gulp');
var exec = require('child_process').exec;
var bs = require('browser-sync').create();

gulp.task('default', ['test', 'inspect']);

function test(done) {
    var p = exec('composer test');
    p.stdout.pipe(process.stdout);
    p.stderr.pipe(process.stderr);
    p.on('exit', done);
}

function inspect(done) {
    var r = 3;
    function wait() {
        --r || done();
    }
    exec('composer doc', wait);
    exec('composer metrics', wait);
    var lint = exec('composer lint');
    lint.stdout.pipe(process.stdout);
    lint.stderr.pipe(process.stderr);
    lint.on('exit', wait);
}

function lint(target, done) {
    var p = exec('composer lint -- ' + target);
    p.stdout.pipe(process.stdout);
    p.stderr.pipe(process.stderr);
    p.on('exit', done);
}

gulp.task('test', test);
gulp.task('inspect', inspect);

gulp.task('start', function(){
    bs.init({
        server: {
            baseDir: "artifacts/"
        },
        ghostMode: false
    });

    gulp.watch(['src/**/*.php', 'tests/**/*Test.php'], {}, function(ev){
        switch (ev.type) {
            case "added":
            case "changed":
                lint(ev.path, function(){
                    test(bs.reload);
                });
                break;
            default:
                inspect(function(){
                    test(bs.reload);
                });
        }
    });
});

<|endoftext|>


<commit_before>

if( typeof module !== 'undefined' )
require( '../staging/abase/object/printer/printer/Logger.s' );

var _ = wTools;

var b = new wLogger();
b._prefix = '*'
b.inputFrom( console )
b.log('1');
console.log('2')
console.log( b.inputs[0].input === b.outputs[0].output )
<commit_msg>example update<commit_after>

if( typeof module !== 'undefined' )
require( '../staging/abase/object/printer/printer/Logger.s' );

var _ = wTools;

var b = new wLogger();
b._prefix = '*'
b.inputFrom( console )
b.log('1');
console.log('2')
console.log( b.inputs[0].input === b.outputs[0].output )

// var b = new wLogger();
// b.inputFrom( console ) // no recursion
//
// var l = new wLogger();
// var got = l.outputToUnchain( console ); // cant find default console
<|endoftext|>


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

var concat = require('gulp-concat');
var csso = require('gulp-csso');
var pump = require('pump');
var sass = require('gulp-sass');
var sassGlob = require('gulp-sass-glob');
var uglify = require('gulp-uglify');

/* APP FILES */

gulp.task('app:scripts', function() {
    return gulp.src([
        'babyblotter/static_site/js/babyblotter.js',
        'api/static/js/*.js',
        'core/static/js/*.js',
        'dashboard/static/js/*.js'
    ])
        .pipe(concat('app.js'))
        .pipe(gulp.dest('babyblotter/static/babyblotter/js/'));
});

gulp.task('app:styles', function (cb) {
    pump([
            gulp.src('babyblotter/static_site/scss/babyblotter.scss'),
            sassGlob(),
            sass().on('error', sass.logError),
            concat('app.css'),
            gulp.dest('babyblotter/static/babyblotter/css/')
        ],
        cb
    );
});

gulp.task('app', ['app:scripts', 'app:styles']);

/* VENDOR FILES */

gulp.task('vendor:scripts', function() {
    return gulp.src([
        'node_modules/jquery/dist/jquery.js',
        'node_modules/popper.js/dist/umd/popper.js',
        'node_modules/bootstrap/dist/js/bootstrap.js',
        'node_modules/moment/moment.js',
        'node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.js'
    ])
        .pipe(concat('vendor.js'))
        .pipe(gulp.dest('babyblotter/static/babyblotter/js/'));
});

gulp.task('vendor:styles', function() {
    return gulp.src([
        //'node_modules/bootstrap/dist/css/bootstrap.css',
        'node_modules/tempusdominus-bootstrap-4/build/css/tempusdominus-bootstrap-4.css',
        'node_modules/font-awesome/css/font-awesome.css'
    ])
        .pipe(concat('vendor.css'))
        .pipe(gulp.dest('babyblotter/static/babyblotter/css/'));
});

gulp.task('vendor:fonts', function() {
    return gulp.src([
        'node_modules/font-awesome/fonts/*'
    ])
        .pipe(gulp.dest('babyblotter/static/babyblotter/fonts/'));
});

gulp.task('vendor', ['vendor:styles', 'vendor:scripts', 'vendor:fonts']);

/* COMPRESSION */

gulp.task('compress:app:scripts', function (cb) {
    pump([
            gulp.src('babyblotter/static/babyblotter/js/app.js'),
            concat('app.min.js'),
            uglify(),
            gulp.dest('babyblotter/static/babyblotter/js/')
        ],
        cb
    );
});

gulp.task('compress:app:styles', function (cb) {
    pump([
            gulp.src('babyblotter/static/babyblotter/css/app.css'),
            concat('app.min.css'),
            csso(),
            gulp.dest('babyblotter/static/babyblotter/css/')
        ],
        cb
    );
});

gulp.task('compress:vendor:scripts', function (cb) {
    pump([
            gulp.src('babyblotter/static/babyblotter/js/vendor.js'),
            concat('vendor.min.js'),
            uglify(),
            gulp.dest('babyblotter/static/babyblotter/js/')
        ],
        cb
    );
});

gulp.task('compress:vendor:styles', function (cb) {
    pump([
            gulp.src('babyblotter/static/babyblotter/css/vendor.css'),
            concat('vendor.min.css'),
            csso(),
            gulp.dest('babyblotter/static/babyblotter/css/')
        ],
        cb
    );
});

gulp.task('compress', [
    'compress:app:scripts',
    'compress:app:styles',
    'compress:vendor:scripts',
    'compress:vendor:styles'
]);

/* DEFAULT */

gulp.task('default', ['vendor', 'app']);<commit_msg>Add dependencies for gulp compress tasks.<commit_after>var gulp = require('gulp');

var concat = require('gulp-concat');
var csso = require('gulp-csso');
var pump = require('pump');
var sass = require('gulp-sass');
var sassGlob = require('gulp-sass-glob');
var uglify = require('gulp-uglify');

/* APP FILES */

gulp.task('app:scripts', function() {
    return gulp.src([
        'babyblotter/static_site/js/babyblotter.js',
        'api/static/js/*.js',
        'core/static/js/*.js',
        'dashboard/static/js/*.js'
    ])
        .pipe(concat('app.js'))
        .pipe(gulp.dest('babyblotter/static/babyblotter/js/'));
});

gulp.task('app:styles', function (cb) {
    pump([
            gulp.src('babyblotter/static_site/scss/babyblotter.scss'),
            sassGlob(),
            sass().on('error', sass.logError),
            concat('app.css'),
            gulp.dest('babyblotter/static/babyblotter/css/')
        ],
        cb
    );
});

gulp.task('app', ['app:scripts', 'app:styles']);

/* VENDOR FILES */

gulp.task('vendor:scripts', function() {
    return gulp.src([
        'node_modules/jquery/dist/jquery.js',
        'node_modules/popper.js/dist/umd/popper.js',
        'node_modules/bootstrap/dist/js/bootstrap.js',
        'node_modules/moment/moment.js',
        'node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.js'
    ])
        .pipe(concat('vendor.js'))
        .pipe(gulp.dest('babyblotter/static/babyblotter/js/'));
});

gulp.task('vendor:styles', function() {
    return gulp.src([
        //'node_modules/bootstrap/dist/css/bootstrap.css',
        'node_modules/tempusdominus-bootstrap-4/build/css/tempusdominus-bootstrap-4.css',
        'node_modules/font-awesome/css/font-awesome.css'
    ])
        .pipe(concat('vendor.css'))
        .pipe(gulp.dest('babyblotter/static/babyblotter/css/'));
});

gulp.task('vendor:fonts', function() {
    return gulp.src([
        'node_modules/font-awesome/fonts/*'
    ])
        .pipe(gulp.dest('babyblotter/static/babyblotter/fonts/'));
});

gulp.task('vendor', ['vendor:styles', 'vendor:scripts', 'vendor:fonts']);

/* COMPRESSION */

gulp.task('compress:app:scripts', ['app:scripts'], function (cb) {
    pump([
            gulp.src('babyblotter/static/babyblotter/js/app.js'),
            concat('app.min.js'),
            uglify(),
            gulp.dest('babyblotter/static/babyblotter/js/')
        ],
        cb
    );
});

gulp.task('compress:app:styles', ['app:styles'], function (cb) {
    pump([
            gulp.src('babyblotter/static/babyblotter/css/app.css'),
            concat('app.min.css'),
            csso(),
            gulp.dest('babyblotter/static/babyblotter/css/')
        ],
        cb
    );
});

gulp.task('compress:vendor:scripts', ['vendor:scripts'], function (cb) {
    pump([
            gulp.src('babyblotter/static/babyblotter/js/vendor.js'),
            concat('vendor.min.js'),
            uglify(),
            gulp.dest('babyblotter/static/babyblotter/js/')
        ],
        cb
    );
});

gulp.task('compress:vendor:styles', ['vendor:styles'], function (cb) {
    pump([
            gulp.src('babyblotter/static/babyblotter/css/vendor.css'),
            concat('vendor.min.css'),
            csso(),
            gulp.dest('babyblotter/static/babyblotter/css/')
        ],
        cb
    );
});

gulp.task('compress', [
    'compress:app:scripts',
    'compress:app:styles',
    'compress:vendor:scripts',
    'compress:vendor:styles'
]);

/* DEFAULT */

gulp.task('default', ['vendor', 'app', 'compress']);<|endoftext|>


<commit_before>const {
  overseasAddressForm,
  postcodeLookupForm,
  selectUkAddressForm,
  ukOrOverseasForm,
} = require('../../macros')

module.exports = {
  steps: [
    {
      path: '/create/step-1',
      type: 'form',
      heading: 'Is this a UK or overseas address?',
      breadcrumbs: [
        { name: 'Add an address' },
      ],
      macro: ukOrOverseasForm,
      nextPath: ({ uk_or_overseas: ukOrOverseas }) => {
        const path = {
          uk: '/create/postcode-lookup',
          overseas: '/create/overseas-address',
        }

        return path[ukOrOverseas]
      },
    },
    {
      path: '/create/postcode-lookup',
      type: 'form',
      heading: 'Add a company address',
      breadcrumbs: [
        { name: 'Add an address' },
      ],
      macro: postcodeLookupForm,
      nextPath: '/create/select-uk-address',
    },
    {
      path: '/create/select-uk-address',
      type: 'form',
      heading: 'Add a company address',
      breadcrumbs: [
        { name: 'Add an address' },
      ],
      macro: selectUkAddressForm,
      nextPath: '/',
    },
    {
      path: '/create/overseas-address',
      type: 'form',
      heading: 'Add a company address',
      breadcrumbs: [
        { name: 'Add an address' },
      ],
      macro: overseasAddressForm,
      nextPath: '/',
    },
  ],
}
<commit_msg>Update create address steps<commit_after>const {
  manualUkAddressForm,
  overseasAddressForm,
  postcodeLookupForm,
  selectUkAddressForm,
  ukOrOverseasForm,
} = require('../../macros')
const {
  setAddresses,
  setCountries,
} = require('./middleware')
const api = require('./api')

module.exports = {
  breadcrumbs: [
    { name: 'Add an address', url: '/address-type' },
  ],
  steps: [
    {
      type: 'form',
      path: '/address-type',
      heading: 'Is this a UK or overseas address?',
      macro: ukOrOverseasForm,
      nextPath: ({ uk_or_overseas: ukOrOverseas }) => {
        const path = {
          uk: '/postcode-lookup',
          overseas: '/overseas-address',
        }

        return path[ukOrOverseas]
      },
    },
    {
      type: 'form',
      path: '/postcode-lookup',
      heading: 'Add a company address',
      macro: postcodeLookupForm,
      nextPath: '/select-uk-address',
    },
    {
      type: 'form',
      path: '/select-uk-address',
      heading: 'Add a company address',
      middleware: [
        setAddresses,
      ],
      macro: selectUkAddressForm,
      done: {
        send: api.send,
        message: 'Address has been added',
        nextPath: ({ id }) => `/addresses/${id}`,
      },
    },
    {
      type: 'form',
      path: '/manual-uk-address',
      heading: 'Add a company address',
      macro: manualUkAddressForm,
      validateJourney: false,
      done: {
        send: api.send,
        message: 'Address has been added',
        nextPath: ({ id }) => `/addresses/${id}`,
      },
    },
    {
      type: 'form',
      path: '/overseas-address',
      heading: 'Add a company address',
      middleware: [
        setCountries,
      ],
      macro: overseasAddressForm,
      done: {
        send: api.send,
        message: 'Address has been added',
        nextPath: ({ id }) => `/addresses/${id}`,
      },
    },
  ],
}
<|endoftext|>


<commit_before>// Require
var gulp = require('gulp');

// Include Plugins
var sass             = require('gulp-sass');
var concat           = require('gulp-concat');
var plumber          = require('gulp-plumber');
var sourcemaps       = require('gulp-sourcemaps');
var browserSync      = require('browser-sync');
var uglify           = require('gulp-uglify');
var cleanCSS         = require('gulp-clean-css');
var stripCssComments = require('gulp-strip-css-comments');
var uncss            = require('gulp-uncss');
var rename           = require('gulp-rename');
var autoprefixer     = require('gulp-autoprefixer');
var critical         = require('critical').stream;
var imagemin         = require('gulp-imagemin');
var svgstore         = require('gulp-svgstore');
var svgmin           = require('gulp-svgmin');
var rename           = require('gulp-rename');
var size             = require('gulp-size');
var sassdoc          = require('sassdoc');

// Configuration
var path = {
  sass: './assets/scss/**/*.scss',
  js: [
    './assets/js/vendor/modernizr-2.8.3.min.js',
    './assets/js/vendor/typerendering-1.1.0.min.js',
    './assets/js/main.js'
  ],
  img: './assets/img/*',
  html: './*.html',
  dist: './assets/build/',
  js_dist: './assets/js/build/'
};
var autoprefixerOptions = {
  browsers: ['> 1%', 'last 2 versions', 'Firefox ESR', 'Opera 12.1']
};
var reload = browserSync.reload;
var localConfig = require('./localconfig');

// Static Server + watching scss/html files
gulp.task('serve', function() {
  if(localConfig.enableBrowserSync)
  {
    browserSync({
      proxy: 'http://' + localConfig.serverName + localConfig.subDirectory
    });
  }

  gulp.watch(path.sass, ['sass']);
  gulp.watch(path.html).on('change', reload);
  gulp.watch(path.js, ['js-dev']);
  //.on('change', function(event) {
  //  console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
  //});
});

// Generate SassDoc + Add Sourcemaps + Autoprefixer
// + cache modified files
// + size the final css filereload on change
// + refresh stream
gulp.task('sass', function () {
  return gulp
    .src(path.sass)
    .pipe(plumber({
      errorHandler: function (err) {
        console.log(err);
        this.emit('end');
      }
    }))
    .pipe(sassdoc())
    .pipe(sourcemaps.init())
    .pipe(sass({
      onError: console.error.bind(console, 'SASS error')
    }))
    .pipe(autoprefixer(autoprefixerOptions))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('./assets/css/'))
    .pipe(size())
    .pipe(reload({stream: true}));
});

// Production Sass Task : Compile SASS into CSS + Remove comments
// + Remove unused css + Autoprefixer
// + Rename + Minify + Move to dest folder
gulp.task('sass-prod', function () {
  return gulp
    .src(path.sass)
    .pipe(sass({
      onError: console.error.bind(console, 'SASS error')
    }))
    .pipe(stripCssComments())
    .pipe(uncss({
        html: ['index.html']
    }))
    .pipe(autoprefixer(autoprefixerOptions))
    .pipe(rename({
      suffix: '.min'
    }))
    .pipe(cleanCSS({debug: true}, function(details) {
        console.log(details.name + ' original size : ' + details.stats.originalSize);
        console.log(details.name + ' minified size : ' + details.stats.minifiedSize);
    }))
    .pipe(size())
    .pipe(gulp.dest(path.dist + '/css'));
});

// Concat all the files in js directory to build/all.js
// and reload the page
gulp.task('js-dev', function() {
  return gulp
    .src(path.js)
    .pipe(plumber({
      errorHandler: function (err) {
        console.log(err);
        this.emit('end');
      }
    }))
    .pipe(concat('all.js'))
    .pipe(gulp.dest(path.js_dist))
    .pipe(reload({stream: true}));
});

// JS Prod Task = Minimify JS + Rename it + Move it to build/js
// TODO : Copy vendor minified files in build/js
// + Concat files + Rename final file
gulp.task('js-prod', function() {
  return gulp
  .src(path.js)
  .pipe(uglify())
  .pipe(rename({ suffix: '.min' }))
  .pipe(gulp.dest(path.dist + '/js'));
});

// Compress Images
gulp.task('img', function () {
  return gulp
  .src(path.img)
  .pipe(imagemin({
    progressive: true,
    svgoPlugins: [{removeViewBox: false}],
  }))
  .pipe(gulp.dest(path.dist + '/img'));
});

// Sprite all the SVG inside the 'icons' folder
// into a single SVG file in 'icons/dest'
gulp.task('svgstore', function () {
    return gulp
      .src('assets/icons/*.svg')
      .pipe(svgmin())
      .pipe(svgstore())
      .pipe(rename({baseline: 'sprite'}))
      .pipe(gulp.dest('assets/icons/dest'));
});

// Generate & Inline Critical-path CSS
gulp.task('critical', function () {
  return gulp
    .src(path.html)
    .pipe(critical({
      base: './',
      inline: true,
      minify: true,
      dimensions: [{
        height: 1300,
        width: 900
      }]
    }))
    .pipe(gulp.dest(path.dist));
});

// Run a Google Page Speed Insight Test for mobile
gulp.task('mobile', function () {
    return psi(site, {
        // key: key
        nokey: 'true',
        strategy: 'mobile',
    }, function (err, data) {
        console.log(data.score);
        console.log(data.pageStats);
    });
});

// Run a Google Page Speed Insight Test for desktop
gulp.task('desktop', function () {
    return psi(site, {
        nokey: 'true',
        // key: key,
        strategy: 'desktop',
    }, function (err, data) {
        console.log(data.score);
        console.log(data.pageStats);
    });
});

gulp.task('default', ['sass','serve'], function () {});

gulp.task('prod', ['sass-prod', 'js-prod', 'critical', 'img']);

<commit_msg>Added gulp-plumber & gulp-util For Proper Error Handling<commit_after>// ---------------------------------------------------------------
// Include Plugins
// ---------------------------------------------------------------
var gulp = require('gulp');
var sass             = require('gulp-sass');
var sassdoc          = require('sassdoc');
var plumber          = require('gulp-plumber');
var gutil            = require('gulp-util');
var concat           = require('gulp-concat');
var sourcemaps       = require('gulp-sourcemaps');
var autoprefixer     = require('gulp-autoprefixer');
var cleanCSS         = require('gulp-clean-css');
var stripCssComments = require('gulp-strip-css-comments');
var uncss            = require('gulp-uncss');
var browserSync      = require('browser-sync');
var uglify           = require('gulp-uglify');
var rename           = require('gulp-rename');
var critical         = require('critical').stream;
var imagemin         = require('gulp-imagemin');
var svgstore         = require('gulp-svgstore');
var svgmin           = require('gulp-svgmin');
var rename           = require('gulp-rename');
var size             = require('gulp-size');

// ---------------------------------------------------------------
// Configuration
// ---------------------------------------------------------------
var path = {
  sass: './app/assets/scss/**/*.scss',
  css: './app/assets/css/',
  js: './app/js/**/*.js',
  img: './app/assets/img/*',
  html: './app/*.html',
  dist: './dist/assets/',
  dist_js: './dist/assets/js/',
  dist_css: './dist/assets/css/'
};

var autoprefixerOptions = {
  browsers: ['> 1%', 'last 2 versions', 'Firefox ESR', 'Opera 12.1']
};

var reload = browserSync.reload;
// var localConfig = require('./localconfig');

// gulp-plumber + gulp-util are used for proper error handling and formatting
// see source : https://www.timroes.de/2015/01/06/proper-error-handling-in-gulp-js/
var gulp_src = gulp.src;
gulp.src = function() {
  return gulp_src.apply(gulp, arguments)
    .pipe(plumber(function(error) {
      // Output an error message
      gutil.log(gutil.colors.red('Error (' + error.plugin + '): ' + error.message));
      // emit the end event, to properly end the task
      this.emit('end');
    })
  );
};

// ---------------------------------------------------------------
// MAIN TASKS
// ---------------------------------------------------------------

// Static Server
gulp.task( 'serve', function(){
  browserSync.init( {
    server: {
      baseDir: 'app'
    },
  } )
} );

// Watch task
gulp.task( 'watch', ['serve'], function(){
  gulp.watch( path.sass, ['sass'] );
  gulp.watch( path.html, reload );
  gulp.watch( path.js, reload );
} );

// Generate SassDoc + Add Sourcemaps + Autoprefixer
// + cache modified files
// + size the final css filereload on change
// + refresh stream
gulp.task('sass', function () {
  return gulp
    .src(path.sass)
    .pipe(sassdoc())
    .pipe(sourcemaps.init())
    .pipe(sass())
    .pipe(autoprefixer(autoprefixerOptions))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(path.css))
    .pipe(size())
    .pipe(reload({stream: true}));
});

// Production Sass Task : Compile SASS into CSS + Remove comments
// + Remove unused css + Autoprefixer
// + Rename + Minify + Move to dest folder
gulp.task('sass-prod', function () {
  return gulp
    .src(path.sass)
    .pipe(sass({
      onError: console.error.bind(console, 'SASS error')
    }))
    .pipe(stripCssComments())
    .pipe(uncss({
        html: ['app/index.html']
    }))
    .pipe(autoprefixer(autoprefixerOptions))
    .pipe(rename({
      suffix: '.min'
    }))
    .pipe(cleanCSS({debug: true}, function(details) {
        console.log(details.name + ' original size : ' + details.stats.originalSize);
        console.log(details.name + ' minified size : ' + details.stats.minifiedSize);
    }))
    .pipe(size())
    .pipe(gulp.dest(path.dist + '/css'));
});

// JS Prod Task = Minimify JS + Rename it + Move it to build/js
// TODO : Copy vendor minified files in build/js
// + Concat files + Rename final file
gulp.task('js-prod', function() {
  return gulp
  .src(path.js)
  .pipe(uglify())
  .pipe(rename({ suffix: '.min' }))
  .pipe(gulp.dest(path.dist_js));
});

// Compress Images
gulp.task('img', function () {
  return gulp
  .src(path.img)
  .pipe(imagemin({
    progressive: true,
    svgoPlugins: [{removeViewBox: false}],
  }))
  .pipe(gulp.dest(path.dist + '/img'));
});

// Sprite all the SVG inside the 'icons' folder
// into a single SVG file in 'icons/dest'
gulp.task('svgstore', function () {
    return gulp
      .src('assets/icons/*.svg')
      .pipe(svgmin())
      .pipe(svgstore())
      .pipe(rename({baseline: 'sprite'}))
      .pipe(gulp.dest('assets/icons/dest'));
});

// Generate & Inline Critical-path CSS
gulp.task('critical', function () {
  return gulp
    .src(path.html)
    .pipe(critical({
      base: './',
      inline: true,
      minify: true,
      dimensions: [{
        height: 1300,
        width: 900
      }]
    }))
    .pipe(gulp.dest(path.dist));
});

// Run a Google Page Speed Insight Test for mobile
gulp.task('mobile', function () {
    return psi(site, {
        // key: key
        nokey: 'true',
        strategy: 'mobile',
    }, function (err, data) {
        console.log(data.score);
        console.log(data.pageStats);
    });
});

// Run a Google Page Speed Insight Test for desktop
gulp.task('desktop', function () {
    return psi(site, {
        nokey: 'true',
        // key: key,
        strategy: 'desktop',
    }, function (err, data) {
        console.log(data.score);
        console.log(data.pageStats);
    });
});

gulp.task('default', ['watch'], function () {});

gulp.task('prod', ['sass-prod', 'js-prod', 'critical', 'img']);

<|endoftext|>