<commit_before>/*
 * Copyright (C) 2017 Steven Soloff
 *
 * This software is licensed under the terms of the GNU Affero General Public
 * License version 3 or later (https://www.gnu.org/licenses/).
 */

import babel from 'gulp-babel'
import coveralls from 'gulp-coveralls'
import del from 'del'
import eslint from 'gulp-eslint'
import excludeGitignore from 'gulp-exclude-gitignore'
import gulp from 'gulp'
import * as isparta from 'isparta'
import istanbul from 'gulp-istanbul'
import jasmine from 'gulp-jasmine'
import nsp from 'gulp-nsp'
import path from 'path'

const dirs = {
  coverage: 'coverage',
  dist: 'dist',
  js: {
    main: 'lib',
    test: 'spec'
  }
}
const paths = {
  js: {
    all: '**/*.js',
    main: `${dirs.js.main}/**/*.js`,
    test: `${dirs.js.test}/**/*.js`
  }
}

export function checkSecurity (done) {
  nsp({package: path.resolve('package.json')}, done)
}

export function clean () {
  return del([dirs.coverage, dirs.dist])
}

export function compile () {
  return gulp.src(paths.js.main)
    .pipe(babel())
    .pipe(gulp.dest(dirs.dist))
}

export function lint () {
  return gulp.src(paths.js.all)
    .pipe(excludeGitignore())
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failAfterError())
}

function pretest () {
  return gulp.src(paths.js.main)
    .pipe(excludeGitignore())
    .pipe(istanbul({
      includeUntested: true,
      instrumenter: isparta.Instrumenter
    }))
    .pipe(istanbul.hookRequire())
}

export function publishCoverage () {
  if (!process.env.CI) {
    return Promise.resolve()
  }

  return gulp.src(path.join(__dirname, `${dirs.coverage}/lcov.info`))
    .pipe(coveralls())
}

function testInternal () {
  return gulp.src(paths.js.test)
    .pipe(jasmine({
      verbose: true
    }))
    .pipe(istanbul.writeReports())
}

export function watch () {
  gulp.watch([paths.js.main, paths.js.test], gulp.parallel(test))
    .on('error', () => {}) // ignore errors during watch so Gulp does not exit
}

export const test = gulp.series(pretest, testInternal)

gulp.task('default', gulp.parallel(lint, test))

gulp.task('prepublish', gulp.series(clean, gulp.parallel(checkSecurity, compile)))
<commit_msg>Rename and restructure test-related tasks<commit_after>/*
 * Copyright (C) 2017 Steven Soloff
 *
 * This software is licensed under the terms of the GNU Affero General Public
 * License version 3 or later (https://www.gnu.org/licenses/).
 */

import babel from 'gulp-babel'
import coveralls from 'gulp-coveralls'
import del from 'del'
import eslint from 'gulp-eslint'
import excludeGitignore from 'gulp-exclude-gitignore'
import gulp from 'gulp'
import * as isparta from 'isparta'
import istanbul from 'gulp-istanbul'
import jasmine from 'gulp-jasmine'
import nsp from 'gulp-nsp'
import path from 'path'

const dirs = {
  coverage: 'coverage',
  dist: 'dist',
  js: {
    main: 'lib',
    test: 'spec'
  }
}
const paths = {
  js: {
    all: '**/*.js',
    main: `${dirs.js.main}/**/*.js`,
    test: `${dirs.js.test}/**/*.js`
  }
}

function beforeTest () {
  return gulp.src(paths.js.main)
    .pipe(excludeGitignore())
    .pipe(istanbul({
      includeUntested: true,
      instrumenter: isparta.Instrumenter
    }))
    .pipe(istanbul.hookRequire())
}

export function checkSecurity (done) {
  nsp({package: path.resolve('package.json')}, done)
}

export function clean () {
  return del([dirs.coverage, dirs.dist])
}

export function compile () {
  return gulp.src(paths.js.main)
    .pipe(babel())
    .pipe(gulp.dest(dirs.dist))
}

function coreTest () {
  return gulp.src(paths.js.test)
    .pipe(jasmine({
      verbose: true
    }))
    .pipe(istanbul.writeReports())
}

export function lint () {
  return gulp.src(paths.js.all)
    .pipe(excludeGitignore())
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failAfterError())
}

export function publishCoverage () {
  if (!process.env.CI) {
    return Promise.resolve()
  }

  return gulp.src(path.join(__dirname, `${dirs.coverage}/lcov.info`))
    .pipe(coveralls())
}

export function test (...args) {
  return gulp.series(beforeTest, coreTest)(...args)
}

export function watch () {
  gulp.watch([paths.js.main, paths.js.test], gulp.parallel(test))
    .on('error', () => {}) // ignore errors during watch so Gulp does not exit
}

gulp.task('default', gulp.parallel(lint, test))

gulp.task('prepublish', gulp.series(clean, gulp.parallel(checkSecurity, compile)))
<|endoftext|>


<commit_before>'use strict';
import babel from 'gulp-babel';
import del from 'del';
import gulp from 'gulp';
import eslint from 'gulp-eslint';
import istanbul from 'gulp-istanbul';
import jscs from 'gulp-jscs';
import jshint from 'gulp-jshint';
import mocha from 'gulp-mocha';

const configFiles = './Gulpfiles.js'
  , srcFiles = 'generator/app/*.js'
  , templateFiles = ['generator/app/*/*', 'generator/app/*/.travis.yml']
  , testFiles = 'test/*.js'

  , destDir = './app';

gulp.task('clean', (cb) => {
  del(destDir, cb);
});

gulp.task('lint', ['clean'], () => {
  return gulp.src([configFiles, srcFiles, testFiles])
    .pipe(eslint())
    .pipe(eslint.formatEach('./node_modules/eslint-path-formatter'))
    .pipe(eslint.failOnError())
    .pipe(jscs({
      esnext: true
    }))
    .pipe(jshint())
    .pipe(jshint.reporter('default'))
    .pipe(jshint.reporter('fail'));
});

gulp.task('compile', ['lint'], () => {
  return gulp.src(srcFiles, {base: './generator/app/'})
    .pipe(babel({
      auxiliaryComment: 'istanbul ignore next',
      modules: 'common'
    }))
    .pipe(gulp.dest(destDir));
});

gulp.task('copy:templates', ['compile'], () => {
  return gulp.src(templateFiles, {base: './generator/app/'})
    .pipe(gulp.dest(destDir));
});

gulp.task('build', ['copy:templates']);

gulp.task('test', ['build'], (cb) => {
  gulp.src([destDir + '*/*.js'])
    .pipe(istanbul())
    .pipe(istanbul.hookRequire())
    .on('finish', () => {
      gulp.src([testFiles])
        .pipe(mocha())
        .pipe(istanbul.writeReports())
        .on('end', cb);
    });
});
<commit_msg>chore(gulp) update from deprecated babel option<commit_after>'use strict';
import babel from 'gulp-babel';
import del from 'del';
import gulp from 'gulp';
import eslint from 'gulp-eslint';
import istanbul from 'gulp-istanbul';
import jscs from 'gulp-jscs';
import jshint from 'gulp-jshint';
import mocha from 'gulp-mocha';

const configFiles = './Gulpfiles.js'
  , srcFiles = 'generator/app/*.js'
  , templateFiles = ['generator/app/*/*', 'generator/app/*/.travis.yml']
  , testFiles = 'test/*.js'

  , destDir = './app';

gulp.task('clean', (cb) => {
  del(destDir, cb);
});

gulp.task('lint', ['clean'], () => {
  return gulp.src([configFiles, srcFiles, testFiles])
    .pipe(eslint())
    .pipe(eslint.formatEach('./node_modules/eslint-path-formatter'))
    .pipe(eslint.failOnError())
    .pipe(jscs({
      esnext: true
    }))
    .pipe(jshint())
    .pipe(jshint.reporter('default'))
    .pipe(jshint.reporter('fail'));
});

gulp.task('compile', ['lint'], () => {
  return gulp.src(srcFiles, {base: './generator/app/'})
    .pipe(babel({
      auxiliaryCommentBefore: 'istanbul ignore next',
      modules: 'common'
    }))
    .pipe(gulp.dest(destDir));
});

gulp.task('copy:templates', ['compile'], () => {
  return gulp.src(templateFiles, {base: './generator/app/'})
    .pipe(gulp.dest(destDir));
});

gulp.task('build', ['copy:templates']);

gulp.task('test', ['build'], (cb) => {
  gulp.src([destDir + '*/*.js'])
    .pipe(istanbul())
    .pipe(istanbul.hookRequire())
    .on('finish', () => {
      gulp.src([testFiles])
        .pipe(mocha())
        .pipe(istanbul.writeReports())
        .on('end', cb);
    });
});
<|endoftext|>


<commit_before>'use strict'

import gulp from 'gulp'
import gutil from 'gulp-util'
import webpack from 'webpack'
import stream from 'webpack-stream'
import webpackConfig from './webpack.config.js'
import DevServer from 'webpack-dev-server'
import Promise from 'es6-promise'
import del from 'del'
import imagemin from 'gulp-imagemin'

gulp.task('build:js', () => {
  const src = './examples/Root.js'
  const dst = './dst'

  return gulp.src(src)
    .pipe(stream(webpackConfig))
    .pipe(gulp.dest(dst))
})

gulp.task('build:stylus', () => {
  const src = './src/**/*.styl'
  const dst = './dst'

  return gulp.src(src)
    .pipe(stream(webpackConfig))
    .pipe(gulp.dest(dst))
})

gulp.task('build:svg', () => {
  const src = './images/**/*.svg'
  const dst = './dst'

  const options = {
    optimizationLevel: 7
  }

  return gulp.src(src)
    .pipe(imagemin(options))
    .pipe(gulp.dest(dst))
})

gulp.task('build', ['build:js', 'build:stylus', 'build:svg'])

gulp.task('clean', () => {
  del(['dst/*'])
})

gulp.task('server', (callback) => {
  const config = Object.create(webpackConfig)

  new DevServer(webpack(config), {
    publicPath: '/' + config.output.publicPath,
    stats: {
      colors: true
    }
  }).listen(8080, 'localhost', (err) => {
    if (err) throw new gutil.PluginError('webpack-dev-server', err)
    gutil.log('[dev-server]', 'http://localhost:8080/index.html')

    callback()
  })
})

gulp.task('watch', () => {
  gulp.watch(['./src/**/*.js', './src/**/*.styl', './images/**/*'], ['build'])
})

gulp.task('default', ['clean', 'build', 'watch', 'server'])
<commit_msg>fix watch path.<commit_after>'use strict'

import gulp from 'gulp'
import gutil from 'gulp-util'
import webpack from 'webpack'
import stream from 'webpack-stream'
import webpackConfig from './webpack.config.js'
import DevServer from 'webpack-dev-server'
import Promise from 'es6-promise'
import del from 'del'
import imagemin from 'gulp-imagemin'

gulp.task('build:js', () => {
  const src = './examples/Root.js'
  const dst = './dst'

  return gulp.src(src)
    .pipe(stream(webpackConfig))
    .pipe(gulp.dest(dst))
})

gulp.task('build:stylus', () => {
  const src = './stylus/**/*.styl'
  const dst = './dst'

  return gulp.src(src)
    .pipe(stream(webpackConfig))
    .pipe(gulp.dest(dst))
})

gulp.task('build:svg', () => {
  const src = './images/**/*.svg'
  const dst = './dst'

  const options = {
    optimizationLevel: 7
  }

  return gulp.src(src)
    .pipe(imagemin(options))
    .pipe(gulp.dest(dst))
})

gulp.task('build', ['build:js', 'build:stylus', 'build:svg'])

gulp.task('clean', () => {
  del(['dst/*'])
})

gulp.task('server', (callback) => {
  const config = Object.create(webpackConfig)

  new DevServer(webpack(config), {
    publicPath: '/' + config.output.publicPath,
    stats: {
      colors: true
    }
  }).listen(8080, 'localhost', (err) => {
    if (err) throw new gutil.PluginError('webpack-dev-server', err)
    gutil.log('[dev-server]', 'http://localhost:8080/index.html')

    callback()
  })
})

gulp.task('watch', () => {
  gulp.watch([
    './lib/**/*.js', '/examples/**/*.js',
    './stylus/**/*.styl', './images/**/*'
  ], ['build'])
})

gulp.task('default', ['clean', 'build', 'watch', 'server'])
<|endoftext|>


<commit_before>import gulp from 'gulp'
import uglify from 'gulp-uglify'
import identity from 'gulp-identity'
import source from 'vinyl-source-stream'
import buffer from 'vinyl-buffer'
import browserify from 'browserify'
import watchify from 'watchify'
import babelify from 'babelify'
import envify from 'loose-envify/custom'
import eslint from 'gulp-eslint'
import uglifyify from 'uglifyify'
import path from 'path'
import cssModulesify from 'css-modulesify'
import cssnext from 'postcss-cssnext'

const staticFiles = {
    'node_modules/webextension-polyfill/dist/browser-polyfill.js': 'extension/lib',
    'node_modules/pdfjs-dist/build/pdf.worker.min.js': 'extension/lib',
}

const sourceFiles = [
    {
        entries: ['./src/background.js'],
        output: 'background.js',
        destination: './extension',
    },
    {
        entries: ['./src/content_script.js'],
        output: 'content_script.js',
        destination: './extension',
    },
    {
        entries: ['./src/overview/main.jsx'],
        output: 'overview.js',
        destination: './extension/overview',
        cssOutput: 'style.css',
    },
    {
        entries: ['./src/options/main.jsx'],
        output: 'options.js',
        destination: './extension/options',
        cssOutput: 'style.css',
    },
]

const browserifySettings = {
    debug: true,
    extensions: ['.jsx', '.css'],
    paths: ['.'],
}

function createBundle({entries, output, destination, cssOutput},
                      {watch = false, production = false}) {
    let b = watch
        ? watchify(browserify({...watchify.args, ...browserifySettings, entries}))
            .on('update', bundle)
        : browserify({...browserifySettings, entries})
    b.transform(babelify)
    b.transform(envify({
        NODE_ENV: production ? 'production' : 'development',
    }), {global: true})

    if (cssOutput) {
        b.plugin(cssModulesify, {
            global: true,
            output: path.join(destination, cssOutput),
            postcssBefore: [
                cssnext,
            ],
        })
    }

    if (production) {
        b.transform(uglifyify, {global: true})
    }

    function bundle() {
        let startTime = Date.now()
        b.bundle()
            .on('error', error => console.error(error.message))
            .pipe(source(output))
            .pipe(buffer())
            .pipe(production ? uglify({output: {ascii_only: true}}) : identity())
            .pipe(gulp.dest(destination))
            .on('end', () => {
                let time = (Date.now() - startTime) / 1000
                console.log(`Bundled ${output} in ${time}s.`)
            })
    }

    bundle()
}

gulp.task('copyStaticFiles', () => {
    for (let filename in staticFiles) {
        console.log(`Copying '${filename}' to '${staticFiles[filename]}'..`)
        gulp.src(filename)
            .pipe(gulp.dest(staticFiles[filename]))
    }
})

gulp.task('lint', () => {
    return gulp.src(['src/**/*.js', 'src/**/*.jsx'])
        .pipe(eslint())
        .pipe(eslint.format())
        .pipe(eslint.results(results => {
            console.log(`Total Errors: ${results.errorCount}`)
        }))
})

gulp.task('build-prod', ['copyStaticFiles', 'lint'], () => {
    sourceFiles.forEach(bundle => createBundle(bundle, {watch: false, production: true}))
})

gulp.task('build', ['copyStaticFiles', 'lint'], () => {
    sourceFiles.forEach(bundle => createBundle(bundle, {watch: false}))
})

gulp.task('build-watch', ['copyStaticFiles'], () => {
    sourceFiles.forEach(bundle => createBundle(bundle, {watch: true}))
})

gulp.task('lint-watch', () => {
    gulp.watch(['src/**/*.js', 'src/**/*.jsx'])
    .on('change', (file) => {
        return gulp.src(file.path)
        .pipe(eslint())
        .pipe(eslint.format())
    })
})

gulp.task('watch', ['lint', 'build-watch', 'lint-watch'])
gulp.task('default', ['watch'])
<commit_msg>Run lint before lint-watch.<commit_after>import gulp from 'gulp'
import uglify from 'gulp-uglify'
import identity from 'gulp-identity'
import source from 'vinyl-source-stream'
import buffer from 'vinyl-buffer'
import browserify from 'browserify'
import watchify from 'watchify'
import babelify from 'babelify'
import envify from 'loose-envify/custom'
import eslint from 'gulp-eslint'
import uglifyify from 'uglifyify'
import path from 'path'
import cssModulesify from 'css-modulesify'
import cssnext from 'postcss-cssnext'

const staticFiles = {
    'node_modules/webextension-polyfill/dist/browser-polyfill.js': 'extension/lib',
    'node_modules/pdfjs-dist/build/pdf.worker.min.js': 'extension/lib',
}

const sourceFiles = [
    {
        entries: ['./src/background.js'],
        output: 'background.js',
        destination: './extension',
    },
    {
        entries: ['./src/content_script.js'],
        output: 'content_script.js',
        destination: './extension',
    },
    {
        entries: ['./src/overview/main.jsx'],
        output: 'overview.js',
        destination: './extension/overview',
        cssOutput: 'style.css',
    },
    {
        entries: ['./src/options/main.jsx'],
        output: 'options.js',
        destination: './extension/options',
        cssOutput: 'style.css',
    },
]

const browserifySettings = {
    debug: true,
    extensions: ['.jsx', '.css'],
    paths: ['.'],
}

function createBundle({entries, output, destination, cssOutput},
                      {watch = false, production = false}) {
    let b = watch
        ? watchify(browserify({...watchify.args, ...browserifySettings, entries}))
            .on('update', bundle)
        : browserify({...browserifySettings, entries})
    b.transform(babelify)
    b.transform(envify({
        NODE_ENV: production ? 'production' : 'development',
    }), {global: true})

    if (cssOutput) {
        b.plugin(cssModulesify, {
            global: true,
            output: path.join(destination, cssOutput),
            postcssBefore: [
                cssnext,
            ],
        })
    }

    if (production) {
        b.transform(uglifyify, {global: true})
    }

    function bundle() {
        let startTime = Date.now()
        b.bundle()
            .on('error', error => console.error(error.message))
            .pipe(source(output))
            .pipe(buffer())
            .pipe(production ? uglify({output: {ascii_only: true}}) : identity())
            .pipe(gulp.dest(destination))
            .on('end', () => {
                let time = (Date.now() - startTime) / 1000
                console.log(`Bundled ${output} in ${time}s.`)
            })
    }

    bundle()
}

gulp.task('copyStaticFiles', () => {
    for (let filename in staticFiles) {
        console.log(`Copying '${filename}' to '${staticFiles[filename]}'..`)
        gulp.src(filename)
            .pipe(gulp.dest(staticFiles[filename]))
    }
})

gulp.task('lint', () => {
    return gulp.src(['src/**/*.js', 'src/**/*.jsx'])
        .pipe(eslint())
        .pipe(eslint.format())
        .pipe(eslint.results(results => {
            console.log(`Total Errors: ${results.errorCount}`)
        }))
})

gulp.task('build-prod', ['copyStaticFiles', 'lint'], () => {
    sourceFiles.forEach(bundle => createBundle(bundle, {watch: false, production: true}))
})

gulp.task('build', ['copyStaticFiles', 'lint'], () => {
    sourceFiles.forEach(bundle => createBundle(bundle, {watch: false}))
})

gulp.task('build-watch', ['copyStaticFiles'], () => {
    sourceFiles.forEach(bundle => createBundle(bundle, {watch: true}))
})

gulp.task('lint-watch', ['lint'], () => {
    gulp.watch(['src/**/*.js', 'src/**/*.jsx'])
    .on('change', (file) => {
        return gulp.src(file.path)
        .pipe(eslint())
        .pipe(eslint.format())
    })
})

gulp.task('watch', ['build-watch', 'lint-watch'])
gulp.task('default', ['watch'])
<|endoftext|>


<commit_before>import {guid} from './utils'
import {config} from '../config'
const {map} = config

export default class Layer {
  constructor() {
    this.rows = map.rows
	  this.cols = map.cols
    this.refSize = config.map.squareSize
    // create the matrix
    this.matrix = []
    // default matrix value
    for(var y = 0; y < this.cols; y++) {
        this.matrix[y] = []
        for(var x = 0; x < this.rows; x++) {
          this.matrix[y][x] = {
  					id : guid(),
  					val : 0
  				}
        }
    }
  }
  setVal (col, row, val) {
    this.matrix[row][col].val = val
  }
  getVal (col, row) {
    return this.matrix[row][col].val
  }
  replaceObject (col, row, object) {
    this.matrix[row][col] = object
  }
}
<commit_msg>rename layer file<commit_after>import {guid} from './utils'
import {config} from '../config'
const {map} = config

export default class Layer {
  constructor() {
    this.rows = map.rows
	  this.cols = map.cols
    this.refSize = config.map.squareSize
    // create the matrix
    this.matrix = []
    // default matrix value
    for(var y = 0; y < this.cols; y++) {
        this.matrix[y] = []
        for(var x = 0; x < this.rows; x++) {
          this.matrix[y][x] = {
  					id : guid(),
  					val : 0
  				}
        }
    }
  }
  setVal (col, row, val) {
    this.matrix[row][col].val = val
  }
  getVal (col, row) {
    return this.matrix[row][col].val
  }
  replaceObject (col, row, object) {
    this.matrix[row][col] = object
  }
}
<|endoftext|>


<commit_before>/*
 * This file is part of Search NEU and licensed under AGPL3.
 * See the license file in the root folder for details.
 */

import Request from './scrapers/request';

import macros from './macros';

const request = new Request('notifyer', {
  cache: false,

  // Try each request up to three times in production,
  // but fail on the first try in development.
  retryCount: macros.DEV ? 1 : 3,
});

class Notifyer {
  // Webhook to respond to Facebook messages.
  async sendFBNotification(sender, text) {
    const token = await macros.getEnvVariable('fbToken');

    if (!token) {
      macros.warn("Don't have fbToken, not sending FB notification to", sender, text);
      return {
        error: 'true',
      };
    }

    const config = {
      method: 'POST',
      url: 'https://graph.facebook.com/v2.6/me/messages',
      qs: {
        access_token: token,
      },
      json: {
        recipient: {
          id: sender,
        },
        message: {
          text: text,
        },
      },
    };

    try {
      const response = await request.post(config);

      if (response.body.message_id) {
        macros.log('Sent a fb message to ', sender, text, response.body.message_id);
        return {
          status: 'success',
        };
      }

      macros.error('Could not send fb message', sender, text, response.body);
      return {
        error: 'true',
      };
    } catch (e) {
      macros.error('Could not send fb message', sender, text, e.message || e.error || e);
      return {
        error: 'true',
      };
    }
  }

  // Get some info about the user
  // Docs here: https://developers.facebook.com/docs/messenger-platform/identity/user-profile
  async getUserProfileInfo(sender) {
    const token = await macros.getEnvVariable('fbToken');

    if (!token) {
      macros.warn("Don't have fbToken, not getting user info for", sender);
      return {};
    }

    // Example:
    // {
    //   "first_name": "Ryan",
    //   "last_name": "Hughes",
    //   "id": "..."
    // }
    const response = await request.get(`https://graph.facebook.com/v2.6/${sender}?fields=first_name,last_name&access_token=${token}`);

    return JSON.parse(response.body);
  }

  main() {
    this.sendFBNotification('1397905100304615', 'test notification');
  }
}

const instance = new Notifyer();
export default instance;

if (require.main === module) {
  instance.main();
}
<commit_msg>changed error if fb message fails to send to warning, so server dosent loose data if message dropped<commit_after>/*
 * This file is part of Search NEU and licensed under AGPL3.
 * See the license file in the root folder for details.
 */

import Request from './scrapers/request';

import macros from './macros';

const request = new Request('notifyer', {
  cache: false,

  // Try each request up to three times in production,
  // but fail on the first try in development.
  retryCount: macros.DEV ? 1 : 3,
});

class Notifyer {
  // Webhook to respond to Facebook messages.
  async sendFBNotification(sender, text) {
    const token = await macros.getEnvVariable('fbToken');

    if (!token) {
      macros.warn("Don't have fbToken, not sending FB notification to", sender, text);
      return {
        error: 'true',
      };
    }

    const config = {
      method: 'POST',
      url: 'https://graph.facebook.com/v2.6/me/messages',
      qs: {
        access_token: token,
      },
      json: {
        recipient: {
          id: sender,
        },
        message: {
          text: text,
        },
      },
    };

    try {
      const response = await request.post(config);

      if (response.body.message_id) {
        macros.log('Sent a fb message to ', sender, text, response.body.message_id);
        return {
          status: 'success',
        };
      }

      macros.warn('Could not send fb message', sender, text, response.body);
      return {
        error: 'true',
      };
    } catch (e) {
      macros.warn('Could not send fb message', sender, text, e.message || e.error || e);
      return {
        error: 'true',
      };
    }
  }

  // Get some info about the user
  // Docs here: https://developers.facebook.com/docs/messenger-platform/identity/user-profile
  async getUserProfileInfo(sender) {
    const token = await macros.getEnvVariable('fbToken');

    if (!token) {
      macros.warn("Don't have fbToken, not getting user info for", sender);
      return {};
    }

    // Example:
    // {
    //   "first_name": "Ryan",
    //   "last_name": "Hughes",
    //   "id": "..."
    // }
    const response = await request.get(`https://graph.facebook.com/v2.6/${sender}?fields=first_name,last_name&access_token=${token}`);

    return JSON.parse(response.body);
  }

  main() {
    this.sendFBNotification('1397905100304615', 'test notification');
  }
}

const instance = new Notifyer();
export default instance;

if (require.main === module) {
  instance.main();
}
<|endoftext|>


<commit_before>
/**
 * Unit tests for checking that the game engine works. This includes things like
 * ECS system ordering and actor scheduling.
 */

const expect = require('chai').expect;
const RG = require('../../../client/src/battles');

const Game = require('../../../client/src/game.js');
const Actor = require('../../../client/src/actor');

/* Creates a game engine with 2 actors scheduled for actions.*/
const setupEngineWithActors = function() {
    this.engine = new Game.Engine();
    this.actor = new Actor.Rogue('TestActor');
    this.actor2 = new Actor.Rogue('TestActor2');

    const level = RG.FACT.createLevel('arena', 30, 30);
    level.addActor(this.actor, 1, 1);
    level.addActor(this.actor2, 2, 2);
    this.actor.get('Action').enable();
    this.actor2.get('Action').enable();
    this.level = level;
};

describe('Game.Engine', () => {
    let eng = null;
    let engine = null;

    beforeEach( () => {
        eng = new setupEngineWithActors();
        engine = eng.engine;
    });

    it('has game messages', () => {
        const pool = RG.POOL;
        let msg = engine.getMessages();
        expect(msg).to.have.length(0);

        const testMsg = 'A test message';
        pool.emitEvent(RG.EVT_MSG, {msg: testMsg});
        expect(engine.hasNewMessages()).to.be.true;
        msg = engine.getMessages();
        expect(engine.hasNewMessages()).to.be.false;
        expect(msg).to.have.length(1);
        expect(msg[0].msg).to.equal(testMsg);

        engine.clearMessages();
        msg = engine.getMessages();
        expect(msg).to.have.length(1);
    });

    it('Executes scheduled actors one by one', () => {
        const actor = eng.actor;
        const action = actor.nextAction({});
        engine.simulateGame();
        engine.simulateGame();
    });

    it('manages a list of active levels', () => {
        const actor = eng.actor;
        expect(engine.nextActor).to.be.null;
        engine.addActiveLevel(eng.level);
        engine.simulateGame();
        expect(engine.nextActor).to.not.be.null;

        const hunger = new RG.Component.Hunger(1000);
        actor.add('Hunger', hunger);
        actor.getBrain().energy = 10; // Add energy artificially
        const energyBefore = hunger.getEnergy();
        for (let i = 0; i < 10; i++) {
            engine.simulateGame();
            engine.updateLoopSystems();
        }
        const energyAfter = hunger.getEnergy();
        expect(energyAfter).to.be.below(energyBefore);

    });

    // This a bit too thorough test for Engine
    it('Uses Systems to manage entity behaviour', () => {
        const timeSystem = engine.timeSystems.TimeEffects;

        const poison = new RG.Component.Poison();
        const expiration = new RG.Component.Expiration();
        expiration.addEffect(poison, 20);
        expect(expiration.hasEffects()).to.equal(true);
        expect(expiration.hasEffect(poison)).to.equal(true);
        // poison.setDuration(20);
        poison.setProb(1.0);
        poison.setDamageDie(new RG.Die(1, 1, 10));
        poison.setSource(eng.actor2);

        const currHP = eng.actor.get('Health').getHP();

        eng.actor.add('Expiration', expiration);
        eng.actor.add('Poison', poison);
        expect(timeSystem.entities).to.have.property(eng.actor.getID());

        engine.simulateGame();
        const remHP = eng.actor.get('Health').getHP();
        expect(remHP < currHP).to.equal(true);

        const expActor2 = eng.actor2.get('Experience').getExp();
        while (eng.actor.get('Health').isAlive()) {
            engine.simulateGame();
        }

        for (let i = 0; i < 10; i++) {engine.simulateGame();}

        expect(eng.actor.has('Poison')).to.equal(false);
        expect(expiration.hasEffect(poison)).to.equal(false);
        expect(expiration.hasEffects()).to.equal(false);

        expect(timeSystem.entities).to.not.have.property(eng.actor.getID());

        // Check that actor2 was given exp for using poison to kill actor2
        const newExpActor2 = eng.actor2.get('Experience').getExp();
        expect(newExpActor2 > expActor2).to.equal(true);

    });

    it('has high-level update() function for GUI', () => {
        const player = new RG.Actor.Rogue('player');
        player.setIsPlayer(true);
        engine.playerCommandCallback = () => true;

        eng.level.addActorToFreeCell(player);
        engine.addActiveLevel(eng.level);
        engine.simulateGame();
        expect(engine.nextActor).to.not.be.null;
        engine.nextActor = player;
        engine.update({code: RG.KEY.REST});
        expect(engine.nextActor).to.not.be.null;
    });
});
<commit_msg>Fixed tests because Engine does not use the global event pool.<commit_after>
/**
 * Unit tests for checking that the game engine works. This includes things like
 * ECS system ordering and actor scheduling.
 */

const expect = require('chai').expect;
const RG = require('../../../client/src/battles');

const Game = require('../../../client/src/game.js');
const Actor = require('../../../client/src/actor');

/* Creates a game engine with 2 actors scheduled for actions.*/
const setupEngineWithActors = function(pool) {
    this.engine = new Game.Engine(pool);
    this.actor = new Actor.Rogue('TestActor');
    this.actor2 = new Actor.Rogue('TestActor2');

    const level = RG.FACT.createLevel('arena', 30, 30);
    level.addActor(this.actor, 1, 1);
    level.addActor(this.actor2, 2, 2);
    this.actor.get('Action').enable();
    this.actor2.get('Action').enable();
    this.level = level;
};

describe('Game.Engine', () => {
    let eng = null;
    let engine = null;
    let pool = null;

    beforeEach( () => {
        pool = new RG.EventPool();
        RG.resetEventPools();
        RG.pushEventPool(pool);
        eng = new setupEngineWithActors(pool);
        engine = eng.engine;
    });

    it('has game messages', () => {
        let msg = engine.getMessages();
        expect(msg).to.have.length(0);

        const testMsg = 'A test message';
        pool.emitEvent(RG.EVT_MSG, {msg: testMsg});
        expect(engine.hasNewMessages()).to.be.true;
        msg = engine.getMessages();
        expect(engine.hasNewMessages()).to.be.false;
        expect(msg).to.have.length(1);
        expect(msg[0].msg).to.equal(testMsg);

        engine.clearMessages();
        msg = engine.getMessages();
        expect(msg).to.have.length(1);
    });

    it('Executes scheduled actors one by one', () => {
        const actor = eng.actor;
        const action = actor.nextAction({});
        engine.simulateGame();
        engine.simulateGame();
    });

    it('manages a list of active levels', () => {
        const actor = eng.actor;
        expect(engine.nextActor).to.be.null;
        engine.addActiveLevel(eng.level);
        engine.simulateGame();
        expect(engine.nextActor).to.not.be.null;

        const hunger = new RG.Component.Hunger(1000);
        actor.add('Hunger', hunger);
        actor.getBrain().energy = 10; // Add energy artificially
        const energyBefore = hunger.getEnergy();
        for (let i = 0; i < 10; i++) {
            engine.simulateGame();
            engine.updateLoopSystems();
        }
        const energyAfter = hunger.getEnergy();
        expect(energyAfter).to.be.below(energyBefore);

    });

    // This a bit too thorough test for Engine
    it('Uses Systems to manage entity behaviour', () => {
        const timeSystem = engine.timeSystems.TimeEffects;

        const poison = new RG.Component.Poison();
        const expiration = new RG.Component.Expiration();
        expiration.addEffect(poison, 20);
        expect(expiration.hasEffects()).to.equal(true);
        expect(expiration.hasEffect(poison)).to.equal(true);
        // poison.setDuration(20);
        poison.setProb(1.0);
        poison.setDamageDie(new RG.Die(1, 1, 10));
        poison.setSource(eng.actor2);

        const currHP = eng.actor.get('Health').getHP();

        eng.actor.add('Expiration', expiration);
        eng.actor.add('Poison', poison);
        expect(timeSystem.entities).to.have.property(eng.actor.getID());

        engine.simulateGame();
        const remHP = eng.actor.get('Health').getHP();
        expect(remHP < currHP).to.equal(true);

        const expActor2 = eng.actor2.get('Experience').getExp();
        while (eng.actor.get('Health').isAlive()) {
            engine.simulateGame();
        }

        for (let i = 0; i < 10; i++) {engine.simulateGame();}

        expect(eng.actor.has('Poison')).to.equal(false);
        expect(expiration.hasEffect(poison)).to.equal(false);
        expect(expiration.hasEffects()).to.equal(false);

        expect(timeSystem.entities).to.not.have.property(eng.actor.getID());

        // Check that actor2 was given exp for using poison to kill actor2
        const newExpActor2 = eng.actor2.get('Experience').getExp();
        expect(newExpActor2 > expActor2).to.equal(true);

    });

    it('has high-level update() function for GUI', () => {
        const player = new RG.Actor.Rogue('player');
        player.setIsPlayer(true);
        engine.playerCommandCallback = () => true;

        eng.level.addActorToFreeCell(player);
        engine.addActiveLevel(eng.level);
        engine.simulateGame();
        expect(engine.nextActor).to.not.be.null;
        engine.nextActor = player;
        engine.update({code: RG.KEY.REST});
        expect(engine.nextActor).to.not.be.null;
    });
});
<|endoftext|>


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

/**
  #### leave

  ```
  /leave|{"id":"..."}
  ```

  When a leave message is received from a peer, we check to see if that is
  a peer that we are managing state information for and if we are then the
  peer state is removed.

  ##### Events triggered in response to `/leave` messages

  The following event(s) are triggered when a `/leave` action is received
  from a peer signaller:

  - `peer:leave`

    The `peer:leave` event is emitted once a `/leave` message is captured
    from a peer.  Prior to the event being dispatched, the internal peers
    data in the signaller is removed but can be accessed in 2nd argument
    of the event handler.

**/
module.exports = function(signaller) {
  return function(args) {
    var data = args[0];
    var peer = signaller.peers.get(data && data.id);

    // if we know about the peer, mark it as inactive
    if (peer) {
      peer.inactive = true;
    }

    // emit the event
    signaller.emit('peer:leave', data.id, peer);
  };
};<commit_msg>Generate a peer:disconnected event rather than peer:leave for /leave messages sent by the signaller<commit_after>/* jshint node: true */
'use strict';

/**
  #### leave

  ```
  /leave|{"id":"..."}
  ```

  When a leave message is received from a peer, we check to see if that is
  a peer that we are managing state information for and if we are then the
  peer state is removed.

**/
module.exports = function(signaller) {
  return function(args) {
    var data = args[0];
    var peer = signaller.peers.get(data && data.id);

    // if we know about the peer, mark it as inactive
    if (peer) {
      peer.inactive = true;
    }

    // emit the event
    signaller.emit('peer:disconnected', data.id, peer);
  };
};<|endoftext|>


<commit_before>/*jshint node:true */
/*
 * DevGuide Utils
 */
'use strict';
var http = require('http');
var https = require('https');
var utils = require('./utils');
var util = require('util');
var shortid = require('shortid');
var authRequest = require('./authrequest');

exports.doGet = function (options, callback, res, useHttps) {
  var protocol = http;
  if (useHttps) {
    protocol = https;
  }

  var request = protocol.get(options, function (response) {
    // data is streamed in chunks from the server
    // so we have to handle the "data" event
    var buffer = '',
      data;

    response.on('data', function (chunk) {
      buffer += chunk;
    });

    response.on('end', function () {
      var msg = '';
      try {
        data = JSON.parse(buffer);
        // console.log(data);
      } catch (err) {
        console.log('Can\'t decode JSON response.');
        console.log(err);
        msg = 'Can\'t decode JSON response.';
      }
      if (data === undefined) {
        msg = 'Error processing JSON response';
      } else {
        msg = buffer;
      }
      callback(res, msg);
    });
  });
  request.on('error', function (err) {
    console.log('FAILED GET REQUEST');
    err = new Error();
    err.status = 502; // Bad gateway
    callback(res, err);
    console.log(err);
  });
};

exports.doPost = function (options, data, callback, res, useHttps) {

  try {
    var protocol = http;
    if (useHttps) {
      protocol = https;
    }

    var postReq = protocol.request(options, function (response) {
      // console.log("DOING POST");

      response.setEncoding('utf8');

      var buffer = '';

      response.on('data', function (chunk) {
        buffer += chunk;

      });

      response.on('end', function () {
        // console.log(buffer);
        callback(res, buffer, response.headers);
      });
    });

    // console.log("POST Request created");

    postReq.on('error', function (e) {
      // TODO: handle error.
      callback(res, e);
      console.log(e);
    });

    // post the data
    postReq.write(data);
    postReq.end();

  } catch (error) {
    callback(res, error);
    console.log(error);
  }
};

exports.replaceOnceUsingDictionary = function (dictionary, content,
  replacehandler) {
  if (typeof replacehandler !== 'function') {
    // Default replacehandler function.
    replacehandler = function (key, dictionary) {
      return dictionary[key];
    };
  }

  var patterns = [], // \b is used to mark boundaries "foo" doesn't match food
    patternHash = {},
    oldkey, key, index = 0,
    output = [];
  for (key in dictionary) {
    // Case-insensitivity:
    key = (oldkey = key).toLowerCase();
    dictionary[key] = dictionary[oldkey];

    // Sanitize the key, and push it in the list
    patterns.push('\\b(?:' + key.replace(/([[^$.|?*+(){}])/g,
        '\\$1') +
      ')\\b');

    // Add entry to hash variable,
    // for an optimized backtracking at the next loop
    patternHash[key] = index++;
  }
  var pattern = new RegExp(patterns.join('|'), 'gi'),
    lastIndex = 0;

  // We should actually test using !== null, but for foolproofness,
  //  we also reject empty strings

  while (!!(key = pattern.exec(content))) {
    // Case-insensitivity
    key = key[0].toLowerCase();

    // Add to output buffer
    output.push(content.substring(lastIndex, pattern.lastIndex -
      key.length));
    // The next line is the actual replacement method
    output.push(replacehandler(key, dictionary));

    // Update lastIndex variable
    lastIndex = pattern.lastIndex;

    // Don't match again by removing the matched word, create new pattern
    patterns[patternHash[key]] = '^';
    pattern = new RegExp(patterns.join('|'), 'gi');

    // IMPORTANT: Update lastIndex property. Otherwise, enjoy an infinite loop
    pattern.lastIndex = lastIndex;
  }
  output.push(content.substring(lastIndex, content.length));
  return output.join('');
};

exports.randomIntInc = function (low, high) {
  return Math.floor(Math.random() * (high - low + 1) + low);
};

exports.randomElement = function (elements) {
  return elements[Math.floor(Math.random() * elements.length)];
};

exports.fixedEncodeURIComponent = function (str) {
  str = str.replace(/["]/g, '\\"');
  str = str.replace(/\n/g, '\\n');
  return str.replace(/[<>"'=;()\n\\]/g, function (c) {
    var hex;
    hex = c.charCodeAt(0).toString(16);
    return '%' + ((hex.length === 2) ? hex : '0' + hex);
  });
};

exports.getRandomDate = function (from, to) {
  if (!from) {
    from = new Date(2015, 10, 1).getTime();
  } else {
    from = from.getTime();
  }
  if (!to) {
    to = new Date(2015, 10, 25).getTime();
  } else {
    to = to.getTime();
  }
  return new Date(from + Math.random() * (to - from));
};

exports.convertHtmlToText = function (str) {

  //-- remove BR tags and replace them with line break
  str = str.replace(/
/gi, '\n');
  str = str.replace(/
/gi, '\n');
  str = str.replace(/
/gi, '\n');

  //-- remove P and A tags but preserve what's inside of them
  str = str.replace(/
/gi, '\n');
  str = str.replace(/(.*?)<\/a>/gi, ' $2 ($1)');

  //-- remove all inside SCRIPT and STYLE tags
  str = str.replace(
    /


<commit_before>/**
 * Watching for changes
 */
'use strict';

var config = require('../config');

module.exports = {
  scss: {
    files: config.sass.files,
    tasks: 'sass:dev',
    atBegin: true
  },

  js: {
    files: [config.jsHintFiles, config.tests.src],
    tasks: ['jshint', 'karma:unit']
  }
};
<commit_msg>Add livereload to watch task<commit_after>/**
 * Watching for changes
 */
'use strict';

var config = require('../config');

module.exports = {
  scss: {
    files: config.sass.files,
    tasks: 'sass:dev',
    atBegin: true
  },

  js: {
    files: [config.jsHintFiles, config.tests.src],
    tasks: ['jshint', 'karma:unit']
  },

  livereload: {
    options: {
      livereload: true
    },
    files: ['src/css/**/*']
  }
};
<|endoftext|>


<commit_before>import Route from '@ember/routing/route';
import { inject } from '@ember/service';
import Ember from 'ember';

export default Route.extend({
  fastboot: inject(),

  beforeModel() {
    if (!Ember.testing && !this.get('fastboot.isFastBoot')) {
      this.router.on('didTransition', () => {
        window.scrollTo(0,0);
      });
    }
  }
});
<commit_msg>Fix missing router in docs application route<commit_after>import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import Ember from 'ember';

export default Route.extend({
  fastboot: service(),
  router: service(),

  beforeModel() {
    if (!Ember.testing && !this.get('fastboot.isFastBoot')) {
      this.router.on('didTransition', () => {
        window.scrollTo(0,0);
      });
    }
  }
});
<|endoftext|>


<commit_before>'use strict';
// sample tree object {name: "tree", qspecies: "Maytenus boaria :: Mayten", picture: "nameless", plantdate: "1969-12-31T06:00:00.000Z", latitude: -122.431434474484…}

angular.module('mean.articles')
.controller('ArticlesController', ['$scope', '$http','$resource','$stateParams', '$location', 'Global', 'GetMessages', 'Messages', 'Articles', 'treeData',
  function($scope, $http, $stateParams, $resource, $location, Global, GetMessages, Messages, Articles, treeData) {
    $scope.global = Global;
    $scope.hasAuthorization = function(article) {
      if (!article || !article.user) return false;
      return $scope.global.isAdmin || article.user._id === $scope.global.user._id;
    };

    $scope.find = function() {
      console.log('find has been called.');
      Articles.query(function(trees) {
        $scope.trees = trees;
      });
    };

    $scope.findOne = function() {
      treeData.getTree().$promise.then(function(tree){
        $scope.tree = tree;
        console.log($scope.tree);
      })
      .then(function() {
        $scope.getMessages();
      });
    };
    //Post message to database from single tree (profile) view
    //to be able to access tree.treeid, added data-treeid to h3 tag in profile.html
    $scope.submitMessage = function() {
      var message = $scope.message;
      var username = $scope.tree.name;
      var treeid = $scope.tree.treeid;
      var body = {
        message: message,
        username: username,
        treeid: treeid
      };
      Messages.save(body, function(data) {
        //async load new message to DOM. Loads to end of message list
        $scope.messages.push(data[0]);
        //reset message form to empty
        $scope.message = '';
      });
    };

    //get All messages for a Tree and display on tree profile page
    $scope.getMessages = function($stateParams) {
      //console.log("getMessages $scopr.tree.treeid ", $scope.tree.treeid);
       GetMessages.get({ treeid: $scope.tree.treeid }, function(messages) {
        console.log("$scope.messages is ", messages);
        $scope.messages = messages;
      });

    };
  }
])

.service('treeData', ['Articles', '$stateParams', function(Articles, $stateParams){
  var tree = null;
  var promise = Articles.get({
      treeId: $stateParams.treeId
    }, function(t) {
      tree = t;
    });
  return {
    promise: promise,
    getTree: function(){
      return tree;
    }
  };
}
]);

<commit_msg>implement message posting on tree profile page<commit_after>'use strict';
// sample tree object {name: "tree", qspecies: "Maytenus boaria :: Mayten", picture: "nameless", plantdate: "1969-12-31T06:00:00.000Z", latitude: -122.431434474484…}

angular.module('mean.articles')
.controller('ArticlesController', ['$scope', '$http','$resource','$stateParams', '$location', 'Global', 'GetMessages', 'Messages', 'Articles', 'treeData',
  function($scope, $http, $stateParams, $resource, $location, Global, GetMessages, Messages, Articles, treeData) {
    $scope.global = Global;
    $scope.hasAuthorization = function(article) {
      if (!article || !article.user) return false;
      return $scope.global.isAdmin || article.user._id === $scope.global.user._id;
    };

    $scope.find = function() {
      console.log('find has been called.');
      Articles.query(function(trees) {
        $scope.trees = trees;
      });
    };

    $scope.findOne = function() {
      treeData.getTree().$promise.then(function(tree){
        $scope.tree = tree;
        console.log($scope.tree);
      })
      .then(function() {
        $scope.getMessages();
      });
    };
    //Post message to database from single tree (profile) view
    //to be able to access tree.treeid, added data-treeid to h3 tag in profile.html
    $scope.submitMessage = function() {
      var message = $scope.message;
      var username = $scope.tree.name;
      var treeid = $scope.tree.treeid;
      var body = {
        message: message,
        username: username,
        treeid: treeid
      };
      Messages.save(body, function(data) {
        //async load new message to DOM. Loads to end of message list
        $scope.messages.push(data[0]);
        //reset message form to empty
        $scope.message = '';
      });

    };

    //get All messages for a Tree and display on tree profile page
    $scope.getMessages = function($stateParams) {
      //console.log("getMessages $scopr.tree.treeid ", $scope.tree.treeid);
       GetMessages.get({ treeid: $scope.tree.treeid }, function(messages) {
        console.log("$scope.messages is ", messages);
        $scope.messages = messages;
      });

    };
  }
])

.service('treeData', ['Articles', '$stateParams', function(Articles, $stateParams){
  var tree = null;
  var promise = Articles.get({
      treeId: $stateParams.treeId
    }, function(t) {
      tree = t;
    });
  return {
    promise: promise,
    getTree: function(){
      return tree;
    }
  };
}
]);

<|endoftext|>


<commit_before>let fs = null;
let path = null;
let tpl = null;
let inquirer = null;
let ora = null;
let shelljs = null;
let fse = null;
let chalk = null;
let glob = null;
const platformMap = require('./platform.json');
const platformTotal = 5;

exports.name = 'init';
exports.usage = '[command] [options]';
exports.desc = 'initialize template for chameleon project';
const cmdOptions = {
  lang: 'cml',
  tpl: 'html',
  demo: 'blank'
}
exports.register = function (commander) {
  commander
    .option('-r, --root [root]', 'specify project root')
    .option('-g, --lang [cml|vue]', 'specify project template default language, example: cml init project -g vue ')
    .option('-t, --tpl [html|smarty]', 'specify project templateType, example: cml init project -t html')
    .option('-d, --demo [blank|todo]', 'specify init project demo, example: cml init project -d todo ')
  commander
    .action(function (...args) {
      /* eslint-disable */
      fs = require('fs');
      path = require('path');
      tpl = require('chameleon-templates');
      inquirer = require('inquirer');
      ora = require('ora');
      shelljs = require('shelljs');
      fse = require('fs-extra');
      glob = require('glob');
      chalk = require('chalk');
      /* eslint-disable */

      // 不能删除
      var options = args.pop(); // eslint-disable-line
      if (options.lang === 'vue') {
        cmdOptions.lang = options.lang;
      }
      if (options.tpl === 'smarty') {
        cmdOptions.tpl = options.tpl;
      }
      if (~['todo'].indexOf(options.demo)) {
        cmdOptions.demo = options.demo;
      }
      var type = args.shift();
      if (type) {
        initMethod(type);
      } else {
        let questions = [{
          type: 'list',
          name: 'type',
          message: 'Which do you want to init?',
          choices: [
            'project',
            'page',
            'component'
          ]
        }]
        inquirer.prompt(questions).then(answers => {
          initMethod(answers.type)
        })

      }
    })

  commander.on('--help', function() {
    var cmd = `
  Commands:
    project   initialize a chameleon project
    page      initialize a chameleon page in project
    component initialize a chameleon component in project
    server    initialize the php server for dev
  Examples:
    cml init project
    cml init page
    cml init component
  `
    console.log(cmd)
  })

  function initMethod(type) {
    if (!~['project', 'page', 'component'].indexOf(type)) {
      cml.log.error(`init type must in ['project', 'page', 'component']`);
      return;
    }
    if (type !== 'project') {
      cml.utils.checkProjectConfig();
    }
    switch (type) {
      case 'project':
        initProject();
        break;
      case 'page':
        initPage();
        break;
      case 'component':
        initComponent();
        break;
      default: break;
    }
  }

  function initProject() {
    let questions = [
      // {
      //   type: 'checkbox',
      //   name: 'platforms',
      //   message: '请选择项目需要支持的平台，默认已全选',
      //   choices: [
      //     'h5',
      //     'weex',
      //     '微信小程序'
      //   ],
      //   validate: function(value) {
      //     value = value || [];
      //     if (value.length === 0) {
      //       return '至少选择一个平台'
      //     }
      //     return true;
      //   },
      //   default: ['h5', 'weex', '微信小程序']
      // },
      {
        type: 'input',
        name: 'projectName',
        message: '请输入项目名称',
        validate: function (value) {
          if (!value) {
            return 'project name can not be empty'
          }
          let nameReg = /^[0-9a-zA-Z_\-\.]+$/;
          if (!nameReg.test(value)) {
            return `project name characters must only in [0-9a-zA-Z_\-\.]`
          }

          if (fs.existsSync(value)) {
            return 'There is already a project with the same name in the current directory,please change one'
          }

          return true;
        }
      }
    ]

    inquirer.prompt(questions).then(answers => {
      let {projectName } = answers;
      let platforms = ['h5', 'weex', '微信小程序','支付宝小程序','百度小程序'];
      let templateType = cmdOptions.tpl;
      let templateLang = cmdOptions.lang;
      platforms = platforms.map(item => platformMap[item]);
      let pagedir = path.join(cml.projectRoot, projectName);
      let projectMap = {
        blank: tpl.blankDemoTpl,
        todo: tpl.todoDemoTpl
      }
      let projectTpl = projectMap[cmdOptions.demo];

      fse.copySync(projectTpl, pagedir);
      // package.json文件中的name需要更改
      var packagePath = path.join(pagedir, 'package.json');
      let packageContent = JSON.parse(fs.readFileSync(packagePath, 'utf-8'));
      packageContent.name = projectName;
      fs.writeFileSync(packagePath, JSON.stringify(packageContent, '', 2))

      // 修改配置文件
      let configFile = path.join(pagedir, 'chameleon.config.js');
      let content = fs.readFileSync(configFile, {encoding: 'utf-8'}).replace(/templateLang\s*:\s*["'](cml|vue)["']/g, function() {
        return `templateLang: "${templateLang}"`
      })
        .replace(/templateType\s*:\s*["'](smarty|html)["']/g, function() {
          return `templateType: "${templateType}"`
        })
        .replace(/platforms\s*:\s*\[(.+?)\]/g, function() {
          return `platforms: ${JSON.stringify(platforms)}`
        })
      fs.writeFileSync(configFile, content);

      var npmignore = path.join(pagedir, '.npmignore');

      // npm包中的.gitignore变成了.npmignore
      if (cml.utils.isFile(npmignore)) {
        fse.moveSync(npmignore, path.join(pagedir, '.gitignore'));
      }
      // 处理平台文件
      if (platforms.length < platformTotal) {
        let { ignorePlatform, ignoreReg } = getIgnorePlatform(platforms);
        let currentPlatforms = platforms;
        let currentReg = new RegExp(`\\.(${currentPlatforms.join('|')})\\.cml$`);
        // 处理.cml文件
        let cmlFilePath = path.join(pagedir, '**/*.cml');
        glob.sync(cmlFilePath).forEach(cfp => {
          // 删除忽略平台的文件
          if (ignoreReg.test(cfp)) {
            fse.removeSync(cfp);
          } else {
            if (cfp.endsWith('.cml') && !currentReg.test(cfp)) {
              let content = fs.readFileSync(cfp, {encoding: 'utf-8'});
              let splitContent = cml.utils.getScriptPart({content, cmlType: 'json'});
              let jsonObj = JSON.parse(splitContent.content);
              ignorePlatform.forEach(item => {
                delete jsonObj[item];
              });
              content = content.replace(splitContent.content, `\n${JSON.stringify(jsonObj, null, 2)}\n`);
              fs.writeFileSync(cfp, content);
            }
          }
        })
        // 处理 .interface文件
        let interfaceFilePath = path.join(pagedir, '**/*.interface');
        glob.sync(interfaceFilePath).forEach(ifp => {
          content = fs.readFileSync(ifp, {encoding: 'utf-8'});
          ignorePlatform.forEach(item => {
            content = cml.utils.deleteScript({
              content,
              cmlType: item
            });
          });

          fs.writeFileSync(ifp, content);
        })

      }

      const installSpinner = ora('npm installing...').start()
      const install = shelljs.exec(`cd ${projectName} && npm install`, {
        silent: true
      })
      if (install.code === 0) {
        installSpinner.color = 'green'
        installSpinner.succeed('install success')
        console.log(chalk.yellow('To get started:\n'))
        console.log(chalk.yellow(`cd ${projectName}\n`))
        console.log(chalk.yellow(`cml dev\n`))
        // installSpinner.succeed(`Please exec: cd ${projectName}; cml dev`)
        // console.log(`${install.stderr}${install.stdout}`)
      } else {
        installSpinner.color = 'red'
        installSpinner.fail(chalk.red('install fail, please exec npm install youself'))
        console.log(`${install.stderr}${install.stdout}`)
      }
    })

  }

  function initPage() {
    let questions = [{
      type: 'input',
      name: 'pageName',
      message: 'please input page name:',
      validate: function (value) {
        if (!value) {
          return 'page name can not be empty'
        }

        if (fs.existsSync(path.join(cml.projectRoot, `src/pages/${value}`))) {
          return 'There is already a page with the same name in the current project, please change one'
        }
        return true;
      }
    }]

    inquirer.prompt(questions).then(answers => {
      let {pageName} = answers;
      let pagedir = path.join(cml.projectRoot, `src/pages/${pageName}`)
      let UpperName = toUpperCase(pageName);
      fs.readdirSync(tpl.pageTpl).forEach(fileName => {
        let filePath = path.join(tpl.pageTpl, fileName);
        let newFilePath = path.join(pagedir, fileName.replace('index', pageName));
        let content = fs.readFileSync(filePath, {encoding: 'utf-8'}).replace(/Replace/ig, UpperName);
        if (cml.config.get().templateLang === 'vue') {
          content = content.replace(/<template>/, '<template lang="vue">')
        }
        content = contentIgnoreHanle(content, 'cml');
        fse.outputFile(newFilePath, content);

      })
      cml.log.notice(`init page ${pageName} success!`)
    })
  }

  function initComponent() {
    let questions = [{
      type: 'list',
      name: 'componentType',
      message: '请选择组件类型',
      choices: [
        '普通组件',
        '多态组件',
        '多态接口'
      ]
    }, {
      type: 'input',
      name: 'componentName',
      message: 'please input component name:',
      validate: function (value) {
        if (!value) {
          return 'component name can not be empty'
        }

        if (fs.existsSync(path.join(cml.projectRoot, `src/components/${value}`))) {
          return 'There is already a component with the same name in the current project, please change one'
        }

        return true;
      }
    }]

    inquirer.prompt(questions).then(answers => {
      let {componentName, componentType} = answers;
      let comdir = path.join(cml.projectRoot, `src/components/${componentName}`);
      let comPathMap = {
        '普通组件': 'component',
        '多态组件': 'interface-component',
        '多态接口': 'interface-js'
      }
      let tplPath = path.join(tpl.componentTpl, comPathMap[componentType]);
      let UpperName = toUpperCase(componentName);
      let { ignoreReg } = getIgnorePlatform();
      fs.readdirSync(tplPath).forEach(fileName => {
        if (ignoreReg.test(fileName)) {
          return;
        }
        let filePath = path.join(tplPath, fileName);
        let newFilePath = path.join(comdir, fileName.replace('index', componentName));
        let content = fs.readFileSync(filePath, {encoding: 'utf-8'}).replace(/Replace/ig, UpperName);
        if (cml.config.get().templateLang === 'vue') {
          content = content.replace(/<template>/, '<template lang="vue">')
        }
        if (newFilePath.endsWith('.cml')) {
          content = contentIgnoreHanle(content, 'cml');
        }
        if (newFilePath.endsWith('.interface')) {
          content = contentIgnoreHanle(content, 'interface');
        }
        fse.outputFile(newFilePath, content);
      })
      cml.log.notice(`init component ${componentName} success!`)
    })
  }

  function toUpperCase(content) {
    content = content[0].toUpperCase() + content.slice(1);
    return content.replace(/-(\w)/ig, function(m, s1) {
      return s1.toUpperCase()
    })
  }

  function getIgnorePlatform(platforms) {
    platforms = platforms || cml.config.get().platforms.map(item => item.trim());
    let platformValues = Object.values(platformMap);
    let ignorePlatform = platformValues.filter(item => platforms.indexOf(item) === -1);
    let ignoreReg = new RegExp(`\\.(${ignorePlatform.join('|')})\\.cml$`);
    return {
      ignorePlatform,
      ignoreReg
    }
  }
  // 处理文件
  function contentIgnoreHanle(content, type) {
    let { ignorePlatform } = getIgnorePlatform();
    if (type === 'interface') {
      ignorePlatform.forEach(item => {
        content = cml.utils.deleteScript({
          content,
          cmlType: item
        });
      });
    } else if (type === 'cml') {
      let splitContent = cml.utils.getScriptPart({content, cmlType: 'json'});
      if (splitContent) {
        let jsonObj = JSON.parse(splitContent.content);
        ignorePlatform.forEach(item => {
          delete jsonObj[item];
        });
        content = content.replace(splitContent.content, `\n${JSON.stringify(jsonObj, null, 2)}\n`);
      }
    }
    return content;
  }

}
<commit_msg>cli命令行英文化<commit_after>let fs = null;
let path = null;
let tpl = null;
let inquirer = null;
let ora = null;
let shelljs = null;
let fse = null;
let chalk = null;
let glob = null;
const platformMap = require('./platform.json');
const platformTotal = 5;

exports.name = 'init';
exports.usage = '[command] [options]';
exports.desc = 'initialize template for chameleon project';
const cmdOptions = {
  lang: 'cml',
  tpl: 'html',
  demo: 'blank'
}
exports.register = function (commander) {
  commander
    .option('-r, --root [root]', 'specify project root')
    .option('-g, --lang [cml|vue]', 'specify project template default language, example: cml init project -g vue ')
    .option('-t, --tpl [html|smarty]', 'specify project templateType, example: cml init project -t html')
    .option('-d, --demo [blank|todo]', 'specify init project demo, example: cml init project -d todo ')
  commander
    .action(function (...args) {
      /* eslint-disable */
      fs = require('fs');
      path = require('path');
      tpl = require('chameleon-templates');
      inquirer = require('inquirer');
      ora = require('ora');
      shelljs = require('shelljs');
      fse = require('fs-extra');
      glob = require('glob');
      chalk = require('chalk');
      /* eslint-disable */

      // 不能删除
      var options = args.pop(); // eslint-disable-line
      if (options.lang === 'vue') {
        cmdOptions.lang = options.lang;
      }
      if (options.tpl === 'smarty') {
        cmdOptions.tpl = options.tpl;
      }
      if (~['todo'].indexOf(options.demo)) {
        cmdOptions.demo = options.demo;
      }
      var type = args.shift();
      if (type) {
        initMethod(type);
      } else {
        let questions = [{
          type: 'list',
          name: 'type',
          message: 'Which do you want to init?',
          choices: [
            'project',
            'page',
            'component'
          ]
        }]
        inquirer.prompt(questions).then(answers => {
          initMethod(answers.type)
        })

      }
    })

  commander.on('--help', function() {
    var cmd = `
  Commands:
    project   initialize a chameleon project
    page      initialize a chameleon page in project
    component initialize a chameleon component in project
    server    initialize the php server for dev
  Examples:
    cml init project
    cml init page
    cml init component
  `
    console.log(cmd)
  })

  function initMethod(type) {
    if (!~['project', 'page', 'component'].indexOf(type)) {
      cml.log.error(`init type must in ['project', 'page', 'component']`);
      return;
    }
    if (type !== 'project') {
      cml.utils.checkProjectConfig();
    }
    switch (type) {
      case 'project':
        initProject();
        break;
      case 'page':
        initPage();
        break;
      case 'component':
        initComponent();
        break;
      default: break;
    }
  }

  function initProject() {
    let questions = [
      // {
      //   type: 'checkbox',
      //   name: 'platforms',
      //   message: '请选择项目需要支持的平台，默认已全选',
      //   choices: [
      //     'h5',
      //     'weex',
      //     '微信小程序'
      //   ],
      //   validate: function(value) {
      //     value = value || [];
      //     if (value.length === 0) {
      //       return '至少选择一个平台'
      //     }
      //     return true;
      //   },
      //   default: ['h5', 'weex', '微信小程序']
      // },
      {
        type: 'input',
        name: 'projectName',
        message: '请输入项目名称',
        validate: function (value) {
          if (!value) {
            return 'project name can not be empty'
          }
          let nameReg = /^[0-9a-zA-Z_\-\.]+$/;
          if (!nameReg.test(value)) {
            return `project name characters must only in [0-9a-zA-Z_\-\.]`
          }

          if (fs.existsSync(value)) {
            return 'There is already a project with the same name in the current directory,please change one'
          }

          return true;
        }
      }
    ]

    inquirer.prompt(questions).then(answers => {
      let {projectName } = answers;
      let platforms = ['h5', 'weex', '微信小程序','支付宝小程序','百度小程序'];
      let templateType = cmdOptions.tpl;
      let templateLang = cmdOptions.lang;
      platforms = platforms.map(item => platformMap[item]);
      let pagedir = path.join(cml.projectRoot, projectName);
      let projectMap = {
        blank: tpl.blankDemoTpl,
        todo: tpl.todoDemoTpl
      }
      let projectTpl = projectMap[cmdOptions.demo];

      fse.copySync(projectTpl, pagedir);
      // package.json文件中的name需要更改
      var packagePath = path.join(pagedir, 'package.json');
      let packageContent = JSON.parse(fs.readFileSync(packagePath, 'utf-8'));
      packageContent.name = projectName;
      fs.writeFileSync(packagePath, JSON.stringify(packageContent, '', 2))

      // 修改配置文件
      let configFile = path.join(pagedir, 'chameleon.config.js');
      let content = fs.readFileSync(configFile, {encoding: 'utf-8'}).replace(/templateLang\s*:\s*["'](cml|vue)["']/g, function() {
        return `templateLang: "${templateLang}"`
      })
        .replace(/templateType\s*:\s*["'](smarty|html)["']/g, function() {
          return `templateType: "${templateType}"`
        })
        .replace(/platforms\s*:\s*\[(.+?)\]/g, function() {
          return `platforms: ${JSON.stringify(platforms)}`
        })
      fs.writeFileSync(configFile, content);

      var npmignore = path.join(pagedir, '.npmignore');

      // npm包中的.gitignore变成了.npmignore
      if (cml.utils.isFile(npmignore)) {
        fse.moveSync(npmignore, path.join(pagedir, '.gitignore'));
      }
      // 处理平台文件
      if (platforms.length < platformTotal) {
        let { ignorePlatform, ignoreReg } = getIgnorePlatform(platforms);
        let currentPlatforms = platforms;
        let currentReg = new RegExp(`\\.(${currentPlatforms.join('|')})\\.cml$`);
        // 处理.cml文件
        let cmlFilePath = path.join(pagedir, '**/*.cml');
        glob.sync(cmlFilePath).forEach(cfp => {
          // 删除忽略平台的文件
          if (ignoreReg.test(cfp)) {
            fse.removeSync(cfp);
          } else {
            if (cfp.endsWith('.cml') && !currentReg.test(cfp)) {
              let content = fs.readFileSync(cfp, {encoding: 'utf-8'});
              let splitContent = cml.utils.getScriptPart({content, cmlType: 'json'});
              let jsonObj = JSON.parse(splitContent.content);
              ignorePlatform.forEach(item => {
                delete jsonObj[item];
              });
              content = content.replace(splitContent.content, `\n${JSON.stringify(jsonObj, null, 2)}\n`);
              fs.writeFileSync(cfp, content);
            }
          }
        })
        // 处理 .interface文件
        let interfaceFilePath = path.join(pagedir, '**/*.interface');
        glob.sync(interfaceFilePath).forEach(ifp => {
          content = fs.readFileSync(ifp, {encoding: 'utf-8'});
          ignorePlatform.forEach(item => {
            content = cml.utils.deleteScript({
              content,
              cmlType: item
            });
          });

          fs.writeFileSync(ifp, content);
        })

      }

      const installSpinner = ora('npm installing...').start()
      const install = shelljs.exec(`cd ${projectName} && npm install`, {
        silent: true
      })
      if (install.code === 0) {
        installSpinner.color = 'green'
        installSpinner.succeed('install success')
        console.log(chalk.yellow('To get started:\n'))
        console.log(chalk.yellow(`cd ${projectName}\n`))
        console.log(chalk.yellow(`cml dev\n`))
        // installSpinner.succeed(`Please exec: cd ${projectName}; cml dev`)
        // console.log(`${install.stderr}${install.stdout}`)
      } else {
        installSpinner.color = 'red'
        installSpinner.fail(chalk.red('install fail, please exec npm install youself'))
        console.log(`${install.stderr}${install.stdout}`)
      }
    })

  }

  function initPage() {
    let questions = [{
      type: 'input',
      name: 'pageName',
      message: 'please input page name:',
      validate: function (value) {
        if (!value) {
          return 'page name can not be empty'
        }

        if (fs.existsSync(path.join(cml.projectRoot, `src/pages/${value}`))) {
          return 'There is already a page with the same name in the current project, please change one'
        }
        return true;
      }
    }]

    inquirer.prompt(questions).then(answers => {
      let {pageName} = answers;
      let pagedir = path.join(cml.projectRoot, `src/pages/${pageName}`)
      let UpperName = toUpperCase(pageName);
      fs.readdirSync(tpl.pageTpl).forEach(fileName => {
        let filePath = path.join(tpl.pageTpl, fileName);
        let newFilePath = path.join(pagedir, fileName.replace('index', pageName));
        let content = fs.readFileSync(filePath, {encoding: 'utf-8'}).replace(/Replace/ig, UpperName);
        if (cml.config.get().templateLang === 'vue') {
          content = content.replace(/<template>/, '<template lang="vue">')
        }
        content = contentIgnoreHanle(content, 'cml');
        fse.outputFile(newFilePath, content);

      })
      cml.log.notice(`init page ${pageName} success!`)
    })
  }

  function initComponent() {
    let questions = [{
      type: 'list',
      name: 'componentType',
      message: 'please select the type of component',
      choices: [
        'normal-component',
        'multimode-component',
        'multimode-interface'
      ]
    }, {
      type: 'input',
      name: 'componentName',
      message: 'please input component name:',
      validate: function (value) {
        if (!value) {
          return 'component name can not be empty'
        }

        if (fs.existsSync(path.join(cml.projectRoot, `src/components/${value}`))) {
          return 'There is already a component with the same name in the current project, please change one'
        }

        return true;
      }
    }]

    inquirer.prompt(questions).then(answers => {
      let {componentName, componentType} = answers;
      let comdir = path.join(cml.projectRoot, `src/components/${componentName}`);
      let comPathMap = {
        'normal-component': 'component',
        'multimode-component': 'interface-component',
        'multimode-interface': 'interface-js'
      }
      let tplPath = path.join(tpl.componentTpl, comPathMap[componentType]);
      let UpperName = toUpperCase(componentName);
      let { ignoreReg } = getIgnorePlatform();
      fs.readdirSync(tplPath).forEach(fileName => {
        if (ignoreReg.test(fileName)) {
          return;
        }
        let filePath = path.join(tplPath, fileName);
        let newFilePath = path.join(comdir, fileName.replace('index', componentName));
        let content = fs.readFileSync(filePath, {encoding: 'utf-8'}).replace(/Replace/ig, UpperName);
        if (cml.config.get().templateLang === 'vue') {
          content = content.replace(/<template>/, '<template lang="vue">')
        }
        if (newFilePath.endsWith('.cml')) {
          content = contentIgnoreHanle(content, 'cml');
        }
        if (newFilePath.endsWith('.interface')) {
          content = contentIgnoreHanle(content, 'interface');
        }
        fse.outputFile(newFilePath, content);
      })
      cml.log.notice(`init component ${componentName} success!`)
    })
  }

  function toUpperCase(content) {
    content = content[0].toUpperCase() + content.slice(1);
    return content.replace(/-(\w)/ig, function(m, s1) {
      return s1.toUpperCase()
    })
  }

  function getIgnorePlatform(platforms) {
    platforms = platforms || cml.config.get().platforms.map(item => item.trim());
    let platformValues = Object.values(platformMap);
    let ignorePlatform = platformValues.filter(item => platforms.indexOf(item) === -1);
    let ignoreReg = new RegExp(`\\.(${ignorePlatform.join('|')})\\.cml$`);
    return {
      ignorePlatform,
      ignoreReg
    }
  }
  // 处理文件
  function contentIgnoreHanle(content, type) {
    let { ignorePlatform } = getIgnorePlatform();
    if (type === 'interface') {
      ignorePlatform.forEach(item => {
        content = cml.utils.deleteScript({
          content,
          cmlType: item
        });
      });
    } else if (type === 'cml') {
      let splitContent = cml.utils.getScriptPart({content, cmlType: 'json'});
      if (splitContent) {
        let jsonObj = JSON.parse(splitContent.content);
        ignorePlatform.forEach(item => {
          delete jsonObj[item];
        });
        content = content.replace(splitContent.content, `\n${JSON.stringify(jsonObj, null, 2)}\n`);
      }
    }
    return content;
  }

}
<|endoftext|>


<commit_before>// Function to validate the E-Mail input in the DonationForm

function validateEmail(email) {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
}

var userInput = [];
var DonationForm = document.getElementById("donationForm");

//Function to clear form after valid input

function ClearFields (validateArray, formData){
  if (validateArray.indexOf(false) < 0){ //makes sure input is valid
    var formUrl = DonationForm.action;
    var formType = DonationForm.method;

    $.ajax({
      url: formUrl,
      data: formData,
      type: formType,
      dataType: 'xml',
      statusCode: {
        0: function () {
          DonationForm.reset(); // clears form
          localStorage.removeItem('DonationsForm'); // clears local storage
          var div = document.createElement("div"); // build DOM tree and new elements
          div.setAttribute("role", "alert");
          div.className = "alert alert-success alert-dismissible";
          var button = document.createElement("button");
          button.setAttribute("type", "button");
          button.setAttribute("data-dismiss", "alert");
          button.setAttribute("aria-label", "Close");
          button.className = "close";
          var span = document.createElement("span");
          span.setAttribute("aria-hidden", "true");
          span.innerHTML = "×";
          var spanText = document.createElement("span");
          spanText.textContent = "Thank you for your comment. You rock!";
          button.appendChild(span);
          div.appendChild(button);
          div.appendChild(spanText);
          var parent = DonationForm.parentNode;
          parent.insertBefore(div, DonationForm);
        }
      }
    });
  }
}

//Local Storage

function saveStorage(key, UserData) {
  var temp = JSON.stringify(UserData);
  localStorage.setItem(key, temp);
}

function getStorage(key){
  var temp = localStorage.getItem(key);
  return JSON.parse(temp);
}

//Event Listeners for Submit Button

DonationForm.addEventListener("submit", validateDonationForm);
DonationForm.addEventListener("keyup", storeFormValues);

// Function to validate the Name input in the DonationForm

function validateDonationForm(e) {
    e.preventDefault();
    var validateArray = [];
    var formData = {};
    for (var i = 0; i < e.target.length; i++) {
      var el = e.target[i];
      var InputName = el.name;
      var InputValue = el.value;
      var InputID = el.id;
      var ElP = el.nextElementSibling;
      var checkEmail = false;
      if (InputID != "SubmitButton" && InputID !=  "DonationAmount" &&  InputID != "DonationPreference") { //don't include the button
        userInput.push(InputValue);
        // console.log(InputValue);
        if (InputValue == null || InputValue == ""){ //checks if something is written in box
          ElP.setAttribute('style', 'visibility:visible');
          validateArray.push(false);
        } else {
          ElP.setAttribute('style', 'visibility:hidden')
          checkEmail = true;
          validateArray.push(true);
        }
        if (checkEmail && InputID == 'DonationEmail') { //checks if something is a valid email
          var validEmail = validateEmail(InputValue);
            if (validEmail) { //checks if input is true or false (and email is valid)
              ElP.setAttribute('style', 'visibility:hidden');
              validateArray.push(true);
            } else {
              ElP.setAttribute('style', 'visibility:visible');
              validateArray.push(false);
            }
        }
      }
      formData[InputName] = InputValue;
    }
    ClearFields(validateArray, formData); //clearing fields after valid input
  }

//Local Storage

function storeFormValues (e) {
  console.log(e);
  var elForm = e.target.form;
  var localStorageArray = [];
  for (var i = 0; i < elForm.length; i++) {
    var el = elForm[i];
    var InputValue = el.value;
    var InputID = el.id;
    var InputObject = {};
    InputObject.InputValue = InputValue;
    InputObject.InputID = InputID;
    localStorageArray.push(InputObject);
  }
  saveStorage('DonationsForm', localStorageArray);
}

function populateForm (){ //puts saved data into form
  var DonationFormStorage = getStorage('DonationsForm');
  if (DonationFormStorage !== null) { //if there's something inside storage use it populate form
    for (var i = 0; i < DonationFormStorage.length; i++) {
      var inputId = DonationFormStorage[i].InputID;
      var inputValue = DonationFormStorage[i].InputValue;
      var elInput = document.getElementById(inputId);
      elInput.value = inputValue;
    }
  }
}

populateForm();
<commit_msg>cleaned up my code a bit and added comments<commit_after>//*************************************************//
//               VARIABLES                        //
//************************************************//

//Global Variables
var userInput = [];
var DonationForm = document.getElementById("donationForm");

//*************************************************//
//               FUNCTIONS                        //
//************************************************//

// Function to validate the E-Mail input in the DonationForm - regular expression found on web
function validateEmail(email) {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
}

//Function to clear form after valid input
function ClearFields (validateArray, formData){
  if (validateArray.indexOf(false) < 0){ //makes sure input is valid
    var formUrl = DonationForm.action;
    var formType = DonationForm.method;

    $.ajax({         //google forms
      url: formUrl,
      data: formData,
      type: formType,
      dataType: 'xml',
      statusCode: {
        0: function () {
          DonationForm.reset(); // clears form
          localStorage.removeItem('DonationsForm'); // clears local storage
          var div = document.createElement("div"); // build DOM tree and new elements for message box
          div.setAttribute("role", "alert");
          div.className = "alert alert-success alert-dismissible";
          var button = document.createElement("button");
          button.setAttribute("type", "button");
          button.setAttribute("data-dismiss", "alert");
          button.setAttribute("aria-label", "Close");
          button.className = "close";
          var span = document.createElement("span");
          span.setAttribute("aria-hidden", "true");
          span.innerHTML = "×";
          var spanText = document.createElement("span");
          spanText.textContent = "Thank you for your donation! We appreciate your help";
          button.appendChild(span);
          div.appendChild(button);
          div.appendChild(spanText);
          var parent = DonationForm.parentNode;
          parent.insertBefore(div, DonationForm);
        }
      }
    });
  }
}

// Function to validate the Name input in the DonationForm

function validateDonationForm(e) {
    e.preventDefault();
    var validateArray = [];
    var formData = {};
    for (var i = 0; i < e.target.length; i++) {
      var el = e.target[i];
      var InputName = el.name;
      var InputValue = el.value;
      var InputID = el.id;
      var ElP = el.nextElementSibling;
      var checkEmail = false;
      if (InputID != "SubmitButton" && InputID !=  "DonationAmount" &&  InputID != "DonationPreference") { //don't include the button
        userInput.push(InputValue);
        // console.log(InputValue);
        if (InputValue == null || InputValue == ""){ //checks if something is written in box
          ElP.setAttribute('style', 'visibility:visible');
          validateArray.push(false);
        } else {
          ElP.setAttribute('style', 'visibility:hidden')
          checkEmail = true;
          validateArray.push(true);
        }
        if (checkEmail && InputID == 'DonationEmail') { //checks if something is a valid email
          var validEmail = validateEmail(InputValue);
            if (validEmail) { //checks if input is true or false (and email is valid)
              ElP.setAttribute('style', 'visibility:hidden');
              validateArray.push(true);
            } else {
              ElP.setAttribute('style', 'visibility:visible');
              validateArray.push(false);
            }
        }
      }
      formData[InputName] = InputValue;
    }
    ClearFields(validateArray, formData); //clearing fields after valid input
  }

  //*************************************************//
  //          FUNCTIONS FOR LOCAL STORAGE            //
  //************************************************//

//Local Storage Basics - get it and save it

function saveStorage(key, UserData) {
  var temp = JSON.stringify(UserData);
  localStorage.setItem(key, temp);
}

function getStorage(key){
  var temp = localStorage.getItem(key);
  return JSON.parse(temp);
}

//Function to store Info

function storeFormValues (e) {
  console.log(e);
  var elForm = e.target.form;
  var localStorageArray = [];
  for (var i = 0; i < elForm.length; i++) {
    var el = elForm[i];
    var InputValue = el.value;
    var InputID = el.id;
    var InputObject = {};
    InputObject.InputValue = InputValue;
    InputObject.InputID = InputID;
    localStorageArray.push(InputObject);
  }
  saveStorage('DonationsForm', localStorageArray);
}

//Function to populate the Form if Local Storage exists

function populateForm (){ //puts saved data into form
  var DonationFormStorage = getStorage('DonationsForm');
  if (DonationFormStorage !== null) { //if there's something inside storage use it populate form
    for (var i = 0; i < DonationFormStorage.length; i++) {
      var inputId = DonationFormStorage[i].InputID;
      var inputValue = DonationFormStorage[i].InputValue;
      var elInput = document.getElementById(inputId);
      elInput.value = inputValue;
    }
  }
}

populateForm();

//*************************************************//
//         EVENT LISTENERS                        //
//************************************************//

//Event Listeners for Submit Button

DonationForm.addEventListener("submit", validateDonationForm);
DonationForm.addEventListener("keyup", storeFormValues);
<|endoftext|>


<commit_before>"use strict";

window.gswaSynth = function() {
	this.nodeStack = {};
	this.nodeStackLength = 0;
	this.osc = {};
	this._currId = 0;
};

gswaSynth.prototype = {
	setContext( ctx ) {
		this.ctx = ctx;
	},
	connect( node ) {
		this.connectedTo = node;
		for ( var id in this.nodeStack ) {
			this.nodeStack[ id ].connect( node );
		}
	},
	disconnect() {
		this.connectedTo = null;
		for ( var id in this.nodeStack ) {
			this.nodeStack[ id ].disconnect();
		}
	},
	simpleStart( key ) {
		var oscNode = this._newOscNode( key );

		if ( oscNode ) {
			this._oscNode = oscNode;
			return ( this._promise = new Promise( function( resolve ) {
				oscNode.onended = resolve;
				oscNode.start();
			} ) );
		}
	},
	start( key, when, offset, duration ) {
		var oscNode = this._newOscNode();

		if ( oscNode ) {
			oscNode.onended = this._removeSource.bind( this, this._currId );
			this.nodeStack[ this._currId++ ] = oscNode;
			++this.nodeStackLength;
			oscNode.start( when || 0, offset || 0,
				arguments.length > 2 ? duration : this.duration );
			return oscNode;
		}
	},
	stop() {
		if ( this._oscNode ) {
			this._oscNode.stop();
		}
		for ( var id in this.nodeStack ) {
			this.nodeStack[ id ].stop();
		}
	},
	change( obj ) {
		var id, newOsc,
			data = this.data;

		for ( id in obj.oscillators ) {
			newOsc = obj.oscillators[ id ];
			newOsc ? data.oscillators[ id ]
				? _updateOscStack(newOsc, data.oscillators[ id ])
				: _createOscStack(newOsc, data.oscillators[ id ])
				: 2; // delete
		}
		gswaSynth.assignDeep( data, obj );
	},

	// private:
	_newOscNode( key ) {
		var oscNode,
			ctx = this.ctx;

		if ( ctx ) {
			oscNode = ctx.createOscillator();
			oscNode.connect( this.connectedTo );
			oscNode.frequency.value = gswaSynth.keyToHz[ key ];
		}
		return oscNode;
	},
	_updateOscStack( newOsc, osc ) {
		var oscNode;

		for ( oscNode in this.nodeStack ) {
			if ( "type" in newOsc )
				oscNode.type = newOsc.type;
			if ( "detune" in newOsc )
				oscNode.detune.value = newOsc.detune;
		}
	},
	_removeSource( id ) {
		delete this.nodeStack[ id ];
		--this.nodeStackLength;
	}
};

gswaSynth.keyToHz = {
	"A0":    27.5,
	"A#0":   29.1353,
	"B0":    30.8677,
	"C1":    32.7032,
	"C#1":   34.6479,
	"D1":    36.7081,
	"D#1":   38.8909,
	"E1":    41.2035,
	"F1":    43.6536,
	"F#1":   46.2493,
	"G1":    48.9995,
	"G#1":   51.9130,
	"A1":    55,
	"A#1":   58.2705,
	"B1":    61.7354,
	"C2":    65.4064,
	"C#2":   69.2957,
	"D2":    73.4162,
	"D#2":   77.7817,
	"E2":    82.4069,
	"F2":    87.3071,
	"F#2":   92.4986,
	"G2":    97.9989,
	"G#2":  103.826,
	"A2":   110,
	"A#2":  116.541,
	"B2":   123.471,
	"C3":   130.813,
	"C#3":  138.591,
	"D3":   146.832,
	"D#3":  155.563,
	"E3":   164.814,
	"F3":   174.614,
	"F#3":  184.997,
	"G3":   195.998,
	"G#3":  207.652,
	"A3":   220,
	"A#3":  233.082,
	"B3":   246.942,
	"C4":   261.626,
	"C#4":  277.183,
	"D4":   293.665,
	"D#4":  311.127,
	"E4":   329.628,
	"F4":   349.228,
	"F#4":  369.994,
	"G4":   391.995,
	"G#4":  415.305,
	"A4":   440,
	"A#4":  466.164,
	"B4":   493.883,
	"C5":   523.251,
	"C#5":  554.365,
	"D5":   587.33,
	"D#5":  622.254,
	"F#5":  739.989,
	"E5":   659.255,
	"F5":   698.456,
	"G5":   783.991,
	"G#5":  830.609,
	"A5":   880,
	"A#5":  932.328,
	"B5":   987.767,
	"C6":  1046.5,
	"C#6": 1108.73,
	"D6":  1174.66,
	"D#6": 1244.51,
	"E6":  1318.51,
	"F6":  1396.91,
	"F#6": 1479.98,
	"G6":  1567.98,
	"G#6": 1661.22,
	"A6":  1760,
	"A#6": 1864.66,
	"B6":  1975.53,
	"C7":  2093,
	"C#7": 2217.46,
	"D7":  2349.32,
	"D#7": 2489.02,
	"E7":  2637.02,
	"F7":  2793.83,
	"F#7": 2959.96,
	"G7":  3135.96,
	"G#7": 3322.44,
	"A7":  3520,
	"A#7": 3729.31,
	"B7":  3951.07,
	"C8":  4186.01
};
<commit_msg>gswaSynth : first sound :)<commit_after>"use strict";

window.gswaSynth = function() {
	this.data = {};
	this.simplePlayStack = [];
	this._currId = 0;
};

gswaSynth.prototype = {
	setContext( ctx ) {
		this.ctx = ctx;
	},
	connect( node ) {
		this.connectedTo = node;
		for ( var id in this.nodeStack ) {
			this.nodeStack[ id ].connect( node );
		}
	},
	disconnect() {
		this.connectedTo = null;
		for ( var id in this.nodeStack ) {
			this.nodeStack[ id ].disconnect();
		}
	},
	simpleStart( key ) {
		var oscObj, oscId, oscNode;
		for ( oscId in this.data.oscillators ) {
			oscObj = this.data.oscillators[ oscId ];
			oscNode = this._newOscNode( key, oscObj.type, oscObj.detune );
			if ( oscNode ) {
				this.simplePlayStack.push( oscNode );
				oscNode.start( 0 );
			}
		}
	},
	start( key, when, offset, duration ) {
		var oscObj, oscId, oscNode;

		for ( oscId in this.data.oscillators ) {
			oscObj = this.data.oscillators[ oscId ];
			oscNode = this._newOscNode( key, oscObj.type, oscObj.detune );
			if ( oscNode ) {
				oscObj.nodeStack[ this._currId ] = oscNode;
				oscNode.onended = this._removeOscNode.bind( this, oscObj, this._currId );
				++this._currId;
				++oscObj.nodeStackLength;
				oscNode.start( when || 0 ); // ?
				if ( arguments.length > 3 ) {
					oscNode.stop( when + duration );
				}
			}
		}
	},
	stop() {
		var oscObj, oscId, oscNode, oscNodeId;

		this.simplePlayStack.forEach( function( oscNode ) {
			oscNode.stop();
		});
		this.simplePlayStack.length = 0;

		for ( oscId in this.data.oscillators ) {
			oscObj = this.data.oscillators[ oscId ];
			for ( oscNodeId in oscObj.nodeStack ) {
				oscNode = oscObj.nodeStack[ oscNodeId ];
				oscNode.stop();
			}
		}
	},
	change( obj ) {
		var data = this.data;

		gswaSynth.assignDeep( data, obj );
	},

	// private:
	_newOscNode( key, type, detune ) {
		var oscNode,
			ctx = this.ctx;
		if ( ctx ) {
			oscNode = ctx.createOscillator();
			oscNode.connect( this.connectedTo );
			oscNode.frequency.value = gswaSynth.keyToHz[ key ];
			oscNode.type = type;
			oscNode.detune.value = detune;
		}
		return oscNode;
	},
	_removeOscNode( oscObj, id ) {
		delete oscObj.nodeStack[ id ];
		--oscObj.nodeStackLength;
	}
};

gswaSynth.keyToHz = {
	"A0":    27.5,
	"A#0":   29.1353,
	"B0":    30.8677,
	"C1":    32.7032,
	"C#1":   34.6479,
	"D1":    36.7081,
	"D#1":   38.8909,
	"E1":    41.2035,
	"F1":    43.6536,
	"F#1":   46.2493,
	"G1":    48.9995,
	"G#1":   51.9130,
	"A1":    55,
	"A#1":   58.2705,
	"B1":    61.7354,
	"C2":    65.4064,
	"C#2":   69.2957,
	"D2":    73.4162,
	"D#2":   77.7817,
	"E2":    82.4069,
	"F2":    87.3071,
	"F#2":   92.4986,
	"G2":    97.9989,
	"G#2":  103.826,
	"A2":   110,
	"A#2":  116.541,
	"B2":   123.471,
	"C3":   130.813,
	"C#3":  138.591,
	"D3":   146.832,
	"D#3":  155.563,
	"E3":   164.814,
	"F3":   174.614,
	"F#3":  184.997,
	"G3":   195.998,
	"G#3":  207.652,
	"A3":   220,
	"A#3":  233.082,
	"B3":   246.942,
	"C4":   261.626,
	"C#4":  277.183,
	"D4":   293.665,
	"D#4":  311.127,
	"E4":   329.628,
	"F4":   349.228,
	"F#4":  369.994,
	"G4":   391.995,
	"G#4":  415.305,
	"A4":   440,
	"A#4":  466.164,
	"B4":   493.883,
	"C5":   523.251,
	"C#5":  554.365,
	"D5":   587.33,
	"D#5":  622.254,
	"F#5":  739.989,
	"E5":   659.255,
	"F5":   698.456,
	"G5":   783.991,
	"G#5":  830.609,
	"A5":   880,
	"A#5":  932.328,
	"B5":   987.767,
	"C6":  1046.5,
	"C#6": 1108.73,
	"D6":  1174.66,
	"D#6": 1244.51,
	"E6":  1318.51,
	"F6":  1396.91,
	"F#6": 1479.98,
	"G6":  1567.98,
	"G#6": 1661.22,
	"A6":  1760,
	"A#6": 1864.66,
	"B6":  1975.53,
	"C7":  2093,
	"C#7": 2217.46,
	"D7":  2349.32,
	"D#7": 2489.02,
	"E7":  2637.02,
	"F7":  2793.83,
	"F#7": 2959.96,
	"G7":  3135.96,
	"G#7": 3322.44,
	"A7":  3520,
	"A#7": 3729.31,
	"B7":  3951.07,
	"C8":  4186.01
};
<|endoftext|>