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

/**
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // modules
  var assertInstanceOfTypes = require( 'PHET_IO/assertions/assertInstanceOfTypes' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var TNode = require( 'PHET_IO/types/scenery/nodes/TNode' );
  var toEventOnStatic = require( 'PHET_IO/events/toEventOnStatic' );

  var TRadioButton = function( valueType ) {
    return phetioInherit( TNode, 'TRadioButton', function( radioButton, phetioID ) {
      assertInstanceOfTypes( radioButton, [
        phet.sun.RadioButton,
        phet.sun.RadioButtonGroupMember
      ] );
      TNode.call( this, radioButton, phetioID );

      var emitter = radioButton.radioButtonGroupMemberModel || radioButton; //Handle RadioButtonGroupMemberModel or AquaRadioButton
      toEventOnStatic( emitter, 'CallbacksForFired', 'user', phetioID, 'fired', function( value ) {
        return { value: valueType.toStateObject( value ) };
      } );
    }, {}, {
      documentation: 'A traditional radio button',
      events: [ 'fired' ]
    } );
  };

  phetioNamespace.register( 'TRadioButton', TRadioButton );

  return TRadioButton;
} );
<commit_msg>Moved types to sim, see https://github.com/phetsims/phet-io/issues/489<commit_after>// Copyright 2016, University of Colorado Boulder

/**
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // modules
  var assertInstanceOfTypes = require( 'PHET_IO/assertions/assertInstanceOfTypes' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var TNode = require( 'PHET_IO/types/scenery/nodes/TNode' );
  var toEventOnStatic = require( 'PHET_IO/events/toEventOnStatic' );

  var TRadioButton = function( valueType ) {
    assert && assert( !!valueType, 'valueType must be defined' );
    return phetioInherit( TNode, 'TRadioButton', function( radioButton, phetioID ) {
      assertInstanceOfTypes( radioButton, [
        phet.sun.RadioButton,
        phet.sun.RadioButtonGroupMember
      ] );
      TNode.call( this, radioButton, phetioID );

      var emitter = radioButton.radioButtonGroupMemberModel || radioButton; //Handle RadioButtonGroupMemberModel or AquaRadioButton
      toEventOnStatic( emitter, 'CallbacksForFired', 'user', phetioID, 'fired', function( value ) {
        return { value: valueType.toStateObject( value ) };
      } );
    }, {}, {
      documentation: 'A traditional radio button',
      events: [ 'fired' ]
    } );
  };

  phetioNamespace.register( 'TRadioButton', TRadioButton );

  return TRadioButton;
} );
<|endoftext|>


<commit_before>'use strict';
/**
 * mongoose-context-ref plugin
 * --------------------------------------------------------------------------*/

module.exports = function(schema, options) {
  options || (options = {});
  options.required || (options.required = false);
  if(options.virtuals === undefined) options.virtuals = true;

  var ObjectId = schema.constructor.ObjectId;

  // add the context paths
  schema.add({
    context_id:   { type: ObjectId, required: options.required },
    context_type: { type: String, required: options.required }
  });

  // add the validator
  var validator = typeof options.context_types === 'function'?
                                        options.context_types:
                                                 dftValidator;

  schema.path('context_type').validate(validator, 'Invalid context type.');

  // add virtual properties, if the context_types are specified and the user
  // didn't disable this feature
  if(Array.isArray(options.context_types) && options.virtuals) {
    addVirtuals(schema, options.context_types);
  }

  // add the updating hooks
  schema.pre('save', function(next) {
    if(!this.isNew || !this.context_id) return next();
    else refUpdate('save', this, next);
  });

  schema.pre('remove', function(next) {
    if(!this.context_id) return next();
    else refUpdate('remove', this, next);
  });

  // return the schema, for chaining
  return schema;

  // utility functions --
  function dftValidator(value) {
    /* jshint validthis: true */
    var models = options.context_types || getModelNames(this);

    return !!value && (models.indexOf(value) !== -1);
  }
};

function refUpdate(method, doc, cb) {
  var path = doc.constructor.modelName.toLowerCase() + 's',
      action = method === 'save' ? '$push' : '$pull';

  var update = {};
  update[action] = {};
  update[action][path] = doc._id;

  doc.constructor.db.model(doc.context_type)
    .findByIdAndUpdate(doc.context_id, update, function(err, doc) {
      if(err) cb(err);
      else if(!doc && method === 'save') {
        err = new Error(this.context_type + ' not found'); err.status = 400;
        cb(err);
      }
      else cb(null, doc);
    });
}

function addVirtuals(schema, context_types) {
  context_types.forEach(function(context_type) {
    var path = context_type.toLowerCase();

    if(!schema.path(path)) { // don't overwrite existing paths
      schema.virtual(path)
            .get(function() {
              if(this.context_type.toLowerCase() === path)
                return this.context_id;
              else return undefined;
            })
            .set(function(id) {
              this.context_type = (path.charAt(0).toUpperCase() + path.slice(1));
              this.context_id = id;
            });
    }
  });
}

function getModelNames(doc) {
  var model_names = Object.keys(doc.constructor.db.base.models);
  if(model_names.length) return model_names;
  else return doc.constructor.db.modelNames();
}
<commit_msg>Add a `refUpdate` option, as referenced in 089b851.<commit_after>'use strict';
/**
 * mongoose-context-ref plugin
 * --------------------------------------------------------------------------*/

module.exports = function(schema, options) {
  options || (options = {});
  options.required || (options.required = false);
  if(options.virtuals === undefined) options.virtuals = true;
  if(options.refUpdate === undefined) options.refUpdate = true;

  var ObjectId = schema.constructor.ObjectId;

  // add the context paths
  schema.add({
    context_id:   { type: ObjectId, required: options.required },
    context_type: { type: String, required: options.required }
  });

  // add the validator
  var validator = typeof options.context_types === 'function'?
                                        options.context_types:
                                                 dftValidator;

  schema.path('context_type').validate(validator, 'Invalid context type.');

  // add virtual properties, if the context_types are specified and the user
  // didn't disable this feature
  if(Array.isArray(options.context_types) && options.virtuals) {
    addVirtuals(schema, options.context_types);
  }

  // add the updating hooks
  if(options.refUpdate) {
    schema.pre('save', function(next) {
      if(!this.isNew || !this.context_id) return next();
      else refUpdate('save', this, next);
    });

    schema.pre('remove', function(next) {
      if(!this.context_id) return next();
      else refUpdate('remove', this, next);
    });
  }

  // return the schema, for chaining
  return schema;

  // utility functions --
  function dftValidator(value) {
    /* jshint validthis: true */
    var models = options.context_types || getModelNames(this);

    return !!value && (models.indexOf(value) !== -1);
  }
};

function refUpdate(method, doc, cb) {
  var path = doc.constructor.modelName.toLowerCase() + 's',
      action = method === 'save' ? '$push' : '$pull';

  var update = {};
  update[action] = {};
  update[action][path] = doc._id;

  doc.constructor.db.model(doc.context_type)
    .findByIdAndUpdate(doc.context_id, update, function(err, doc) {
      if(err) cb(err);
      else if(!doc && method === 'save') {
        err = new Error(this.context_type + ' not found'); err.status = 400;
        cb(err);
      }
      else cb(null, doc);
    });
}

function addVirtuals(schema, context_types) {
  context_types.forEach(function(context_type) {
    var path = context_type.toLowerCase();

    if(!schema.path(path)) { // don't overwrite existing paths
      schema.virtual(path)
            .get(function() {
              if(this.context_type.toLowerCase() === path)
                return this.context_id;
              else return undefined;
            })
            .set(function(id) {
              this.context_type = (path.charAt(0).toUpperCase() + path.slice(1));
              this.context_id = id;
            });
    }
  });
}

function getModelNames(doc) {
  var model_names = Object.keys(doc.constructor.db.base.models);
  if(model_names.length) return model_names;
  else return doc.constructor.db.modelNames();
}
<|endoftext|>


<commit_before>import Sequelize from 'sequelize';
import parse from './parse';
import {merge} from 'ramda';

const PREBUILT_QUERY = {
    SHOW_DATABASES: 'SHOW_DATABASES',
    SHOW_TABLES: 'SHOW_TABLES',
    SHOW5ROWS: 'SHOW5ROWS'
};

const timestamp = () => (new Date()).toTimeString();
const emptyTableLog = (table) => {
    return `NOTE: table [${table}] seems to be empty`;
};
const emptyTable = {
    columnnames: ['NA'],
    rows: [['empty table']],
    ncols: 1,
    nrows: 1
};
const isEmpty = (table) => {
    return table.length === 0;
};
const intoArray = (objects) => {
    return objects.map(obj => obj[Object.keys(obj)]);
};

export default class SequelizeManager {
    constructor(log) {
        // TODO: can respondEvent be part of the class?
        this.log = log;
    }

    login({username, password, database, portNumber, engine, databasePath, server}, callback) {
        // create new sequelize object
    getDialect() {
        return this.connection.options.dialect;
    }

    setQueryType(type) {
        // type = SELECT for `SELECT` query
        return {type: this.connection.QueryTypes[type]};
    }

    intoTablesArray(results) {
        let tables;
        if (this.getDialect() === 'sqlite') {
            // sqlite returns an array by default
            tables = results;
        } else {
            // others return list of objects
            tables = intoArray(results);
        }
        return tables;
    }

        this.connection = new Sequelize(database, username, password, {
            dialect: engine,
            host: server,
            port: portNumber,
            storage: databasePath
        });

        if (this.connection.config.dialect === 'mssql') {
            this.connection.config.dialectOptions = {encrypt: true};
        }

        // returns a message promise from the database
        return this.connection.authenticate().then((message) => {
            callback(message);
        });
    }

    raiseErrorLog(error) {
        this.log(merge(error, {timestamp: timestamp()}));
    }

    // built-in query to show available databases/schemes
    showDatabases(callback) {
        // constants for cleaner code
        const query = this.getPresetQuery(PREBUILT_QUERY.SHOW_DATABASES);
        const dialect = this.getDialect();

        // deal with sqlite -> has no databases list
        if (dialect === 'sqlite') {
            callback({
                databases: ['SQLITE database accessed'],
                error: null,
                tables: null
            });
            // skip SHOW_DATABASES query and send SHOW_TABLES query right away
            return this.showTables(callback);
        }

        return this.connection.query(query, this.setQueryType('SELECT'))
            .then(results => {
                callback({
                    databases: intoArray(results),
                    error: null,
                    /*
                        if user wants to see all databases/schemes, clear
                        tables from previously selected database/schemes
                    */
                    tables: null
                });
            });
    }

    // built-in query to show available tables in a database/scheme
    showTables(callback) {
        // constants for cleaner code
        const query = this.getPresetQuery(PREBUILT_QUERY.SHOW_TABLES);
        const dialect = this.getDialect();

        return this.connection.query(showtables, this.setQueryType('SELECT'))
            .then(results => {
                const tables = this.intoTablesArray(results);

                const promises = tables.map(table => {
                    const query = this.getPresetQuery(
                        PREBUILT_QUERY.SHOW5ROWS, table
                    );
                    this.log(ipc, query);
                    return this.connection.query(query, {type: noMetaData});
                });

                return Promise.all(promises).then(selectTableResults => {
                    let parsedRows;
                    if (isEmpty(selectTableResults)) {
                        parsedRows = emptyTable;

                        // we will probably keep this log statements in here
                        this.log(respondEvent, emptyTableLog(table));

                    } else {
                        parsedRows = parse(selectTableResults);
                    }
                    callback({
                        error: null,
                        [table]: parsedRows
                    });

                });
            });
    }

    sendQuery(respondEvent, query) {
        // TODO: SQL Injection security hole
        return this.connection.query(query)
            .then((results, metadata) => {
                callback({
                    error: null,
                    rows: parse(results)
                });
            });
    }

    disconnect(respondEvent, callback) {
        /*
            does not return a promise for now. open issue here:
            https://github.com/sequelize/sequelize/pull/5776
        */
        this.connection.close();
        callback({
            databases: null,
            error: null,
            rows: null,
            tables: null
        });
    }

    getPresetQuery(showQuerySelector, table = null) {
        const dialect = this.connection.options.dialect;
        switch (showQuerySelector) {
            case PREBUILT_QUERY.SHOW_DATABASES:
                switch (dialect) {
                    case 'mysql':
                    case 'sqlite':
                    case 'mariadb':
                        return 'SHOW DATABASES';
                    case 'postgres':
                        return 'SELECT datname AS database FROM ' +
                        'pg_database WHERE datistemplate = false;';
                    case 'mssql':
                        return 'SELECT name FROM Sys.Databases';
                    default:
                        throw new Error('could not build a presetQuery');
                }

            case PREBUILT_QUERY.SHOW_TABLES:
                switch (dialect) {
                    case 'mysql':
                    case 'mariadb':
                        return 'SHOW TABLES';
                    case 'postgres':
                        return 'SELECT table_name FROM ' +
                            'information_schema.tables WHERE ' +
                            'table_schema = \'public\'';
                    case 'mssql':
                        return 'SELECT TABLE_NAME FROM ' +
                            'information_schema.tables';
                    case 'sqlite':
                        return 'SELECT name FROM ' +
                        'sqlite_master WHERE type="table"';
                    default:
                        throw new Error('could not build a presetQuery');
                }

            case PREBUILT_QUERY.SHOW5ROWS:
                switch (dialect) {
                    case 'mysql':
                    case 'sqlite':
                    case 'mariadb':
                    case 'postgres':
                        return `SELECT * FROM ${table} LIMIT 5`;
                    case 'mssql':
                        return 'SELECT TOP 5 * FROM ' +
                            `${this.connection.config.database}.dbo.${table}`;
                    default:
                        throw new Error('could not build a presetQuery');
                }
        }
    }
}
<commit_msg>:wrench: rework the table preview, new helper fun<commit_after>import Sequelize from 'sequelize';
import parse from './parse';
import {merge} from 'ramda';

const PREBUILT_QUERY = {
    SHOW_DATABASES: 'SHOW_DATABASES',
    SHOW_TABLES: 'SHOW_TABLES',
    SHOW5ROWS: 'SHOW5ROWS'
};

const timestamp = () => (new Date()).toTimeString();
const emptyTableLog = (table) => {
    return `NOTE: table [${table}] seems to be empty`;
};
const emptyTable = {
    columnnames: ['NA'],
    rows: [['empty table']],
    ncols: 1,
    nrows: 1
};
const isEmpty = (table) => {
    return table.length === 0;
};
const intoArray = (objects) => {
    return objects.map(obj => obj[Object.keys(obj)]);
};

function assembleTablesPreviewMessage(tablePreviews) {
    /*
        topRows is an array of one or many responses of top 5 rows queries
        [ {'table1':[top5rows]}, {'table2': [top5rows]} ...]
    */
    let parsedRows;
    return tablePreviews.map( (tablePreview) => {
        const tableName = Object.keys(tablePreview);
        const rawData = tablePreview[tableName];

        if (isEmpty(rawData)) {
            parsedRows = EMPTY_TABLE;
        } else {
            parsedRows = parse(rawData);
        }
        console.log('tableName: parsedRows');
        console.log({[tableName]: parsedRows});
        return {[tableName]: parsedRows};
    });
}

export default class SequelizeManager {
    constructor(log) {
        // TODO: can respondEvent be part of the class?
        this.log = log;
    }

    login({username, password, database, portNumber, engine, databasePath, server}, callback) {
        // create new sequelize object
    getDialect() {
        return this.connection.options.dialect;
    }

    setQueryType(type) {
        // type = SELECT for `SELECT` query
        return {type: this.connection.QueryTypes[type]};
    }

    intoTablesArray(results) {
        let tables;
        if (this.getDialect() === 'sqlite') {
            // sqlite returns an array by default
            tables = results;
        } else {
            // others return list of objects
            tables = intoArray(results);
        }
        return tables;
    }

        this.connection = new Sequelize(database, username, password, {
            dialect: engine,
            host: server,
            port: portNumber,
            storage: databasePath
        });

        if (this.connection.config.dialect === 'mssql') {
            this.connection.config.dialectOptions = {encrypt: true};
        }

        // returns a message promise from the database
        return this.connection.authenticate().then((message) => {
            callback(message);
        });
    }

    raiseErrorLog(error) {
        this.log(merge(error, {timestamp: timestamp()}));
    }

    // built-in query to show available databases/schemes
    showDatabases(callback) {
        // constants for cleaner code
        const query = this.getPresetQuery(PREBUILT_QUERY.SHOW_DATABASES);
        const dialect = this.getDialect();

        // deal with sqlite -> has no databases list
        if (dialect === 'sqlite') {
            callback({
                databases: ['SQLITE database accessed'],
                error: null,
                tables: null
            });
            // skip SHOW_DATABASES query and send SHOW_TABLES query right away
            return this.showTables(callback);
        }

        return this.connection.query(query, this.setQueryType('SELECT'))
            .then(results => {
                callback({
                    databases: intoArray(results),
                    error: null,
                    /*
                        if user wants to see all databases/schemes, clear
                        tables from previously selected database/schemes
                    */
                    tables: null
                });
            });
    }

    // built-in query to show available tables in a database/scheme
    showTables(callback) {
        // constants for cleaner code
        const query = this.getPresetQuery(PREBUILT_QUERY.SHOW_TABLES);
        const dialect = this.getDialect();

        return this.connection.query(showtables, this.setQueryType('SELECT'))
            .then(results => {
                const tables = this.intoTablesArray(results);

                const promises = tables.map(table => {
                    const query = this.getPresetQuery(
                        PREBUILT_QUERY.SHOW5ROWS, table
                    );
                    this.log(ipc, query);
                    return this.connection.query(query, {type: noMetaData});
                });

                    return this.connection.query(show5rows, this.setQueryType('SELECT'))
                        .then((selectTableResults) => {
                            return {
                                [table]: selectTableResults
                            };
                        });
                });

                return Promise.all(promises)
                    .then(tablePreviews => {
                        callback({
                            error: null,
                            tables: assembleTablesPreviewMessage(tablePreviews)
                        });

                });
            });
    }

    sendQuery(respondEvent, query) {
        // TODO: SQL Injection security hole
        return this.connection.query(query)
            .then((results, metadata) => {
                callback({
                    error: null,
                    rows: parse(results)
                });
            });
    }

    disconnect(respondEvent, callback) {
        /*
            does not return a promise for now. open issue here:
            https://github.com/sequelize/sequelize/pull/5776
        */
        this.connection.close();
        callback({
            databases: null,
            error: null,
            rows: null,
            tables: null
        });
    }

    getPresetQuery(showQuerySelector, table = null) {
        const dialect = this.connection.options.dialect;
        switch (showQuerySelector) {
            case PREBUILT_QUERY.SHOW_DATABASES:
                switch (dialect) {
                    case 'mysql':
                    case 'sqlite':
                    case 'mariadb':
                        return 'SHOW DATABASES';
                    case 'postgres':
                        return 'SELECT datname AS database FROM ' +
                        'pg_database WHERE datistemplate = false;';
                    case 'mssql':
                        return 'SELECT name FROM Sys.Databases';
                    default:
                        throw new Error('could not build a presetQuery');
                }

            case PREBUILT_QUERY.SHOW_TABLES:
                switch (dialect) {
                    case 'mysql':
                    case 'mariadb':
                        return 'SHOW TABLES';
                    case 'postgres':
                        return 'SELECT table_name FROM ' +
                            'information_schema.tables WHERE ' +
                            'table_schema = \'public\'';
                    case 'mssql':
                        return 'SELECT TABLE_NAME FROM ' +
                            'information_schema.tables';
                    case 'sqlite':
                        return 'SELECT name FROM ' +
                        'sqlite_master WHERE type="table"';
                    default:
                        throw new Error('could not build a presetQuery');
                }

            case PREBUILT_QUERY.SHOW5ROWS:
                switch (dialect) {
                    case 'mysql':
                    case 'sqlite':
                    case 'mariadb':
                    case 'postgres':
                        return `SELECT * FROM ${table} LIMIT 5`;
                    case 'mssql':
                        return 'SELECT TOP 5 * FROM ' +
                            `${this.connection.config.database}.dbo.${table}`;
                    default:
                        throw new Error('could not build a presetQuery');
                }
        }
    }
}
<|endoftext|>


<commit_before>const isTravis = process.env.TRAVIS;
const isSaucelabs = process.argv.indexOf('--saucelabs') !== -1 || (isTravis && process.env.TRAVIS_PULL_REQUEST === 'false');

if (isSaucelabs && !process.env.SAUCE_USERNAME) {
  try {
    const credentials = require('./saucelabs.json');
    process.env.SAUCE_USERNAME = credentials.username;
    process.env.SAUCE_ACCESS_KEY = credentials.accessKey;
  } catch (err) {
    console.log('Please, create a valid "saucelabs.json" with your credentials.');
    process.exit(1);
  }
}

module.exports = function(config) {
  const cfg = {
    basePath: '',

    frameworks: ['jasmine'],

    files: [
        // Polyfills
        'node_modules/es6-shim/es6-shim.js',
        'node_modules/reflect-metadata/Reflect.js',

        // Intl pollyfill
        'https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en',

        // Typescript helpers polyfill
        'node_modules/ts-helpers/index.js',

        // System.js for module loading
        'node_modules/systemjs/dist/system-polyfills.js',
        'node_modules/systemjs/dist/system.src.js',

        // Zone.js
        'node_modules/zone.js/dist/zone.js',
        'node_modules/zone.js/dist/jasmine-patch.js',
        'node_modules/zone.js/dist/async-test.js',
        'node_modules/zone.js/dist/fake-async-test.js',

        // RxJS
        {pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false},
        {pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false},

        // Angular
        {pattern: 'node_modules/@angular/**/*.js', included: false, watched: true},
        {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: true},

        // Other libraries
        {pattern: 'node_modules/tether/dist/js/tether.min.js', included: true, watched: false},
        {pattern: 'karma-shim.js', included: true, watched: true},

        // Our built application code
        {pattern: 'temp/**/*.js', included: false, watched: true},

        // paths to support debugging with source maps in dev tools
        {pattern: 'src/**/*.ts', included: false, watched: false},
        {pattern: 'temp/**/*.js.map', included: false, watched: false},

        // fixtures
        {pattern: 'test/fixtures/**', watched: false, included: false, served: true},
    ],

    proxies: {
      // Avoid 404 warnings for images during testing
      '/assets/icons/utility-sprite/svg/symbols.svg': '/base/test/fixtures/fake',
      '/mypath/utility-sprite/svg/symbols.svg': '/base/test/fixtures/fake',
      '/mypath/standard-sprite/svg/symbols.svg': '/base/test/fixtures/fake',
      '/mypath/custom-sprite/svg/symbols.svg': '/base/test/fixtures/fake',
      '/image1.jpg': '/base/test/fixtures/fake',

      '/tether': '/base/node_modules/tether/dist/js/tether.min.js'
    },

    preprocessors: {
      'temp/**/*.js': ['sourcemap'],
      'temp/src/**/!(*spec|*mock).js': ['coverage'],
    },

    coverageReporter: {
      dir: 'coverage/',
      reporters: [{type: 'text-summary'}, {type: 'html'}],
    },

    reporters: isTravis ? ['dots'] : ['progress', 'coverage'],
    port: isTravis ? 9876 : 23011,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: [isTravis ? 'Firefox' : 'Chrome'],
    singleRun: false,
  };

  if (isSaucelabs) {
    cfg.customLaunchers =  require('./test/browser-providers');
    cfg.browsers = Object.keys(cfg.customLaunchers);
    cfg.reporters.push('saucelabs');
    cfg.sauceLabs = {
      tunnelIdentifier: isTravis ? process.env.TRAVIS_JOB_NUMBER : 'ng-lightning',
      connectOptions: {
        logfile: './saucelabs.log',
      },
    };
    cfg.captureTimeout = 120000;
    cfg.browserNoActivityTimeout = 120000;
  }

  config.set(cfg);
};
<commit_msg>chore(build): reduce Karma watched files<commit_after>const isTravis = process.env.TRAVIS;
const isSaucelabs = process.argv.indexOf('--saucelabs') !== -1 || (isTravis && process.env.TRAVIS_PULL_REQUEST === 'false');

if (isSaucelabs && !process.env.SAUCE_USERNAME) {
  try {
    const credentials = require('./saucelabs.json');
    process.env.SAUCE_USERNAME = credentials.username;
    process.env.SAUCE_ACCESS_KEY = credentials.accessKey;
  } catch (err) {
    console.log('Please, create a valid "saucelabs.json" with your credentials.');
    process.exit(1);
  }
}

module.exports = function(config) {
  const cfg = {
    basePath: '',

    frameworks: ['jasmine'],

    files: [
        // Polyfills
        {pattern: 'node_modules/es6-shim/es6-shim.js', included: true, watched: false},
        {pattern: 'node_modules/reflect-metadata/Reflect.js', included: true, watched: false},

        // Intl pollyfill
        'https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en',

        // Typescript helpers polyfill
        {pattern: 'node_modules/ts-helpers/index.js', included: true, watched: false},

        // System.js for module loading
        {pattern: 'node_modules/systemjs/dist/system-polyfills.js', included: true, watched: false},
        {pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: false},

        // Zone.js
        {pattern: 'node_modules/zone.js/dist/zone.js', included: true, watched: false},
        {pattern: 'node_modules/zone.js/dist/jasmine-patch.js', included: true, watched: false},
        {pattern: 'node_modules/zone.js/dist/async-test.js', included: true, watched: false},
        {pattern: 'node_modules/zone.js/dist/fake-async-test.js', included: true, watched: false},

        // RxJS
        {pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false},
        {pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false},

        // Angular
        {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false},
        {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false},

        // Other libraries
        {pattern: 'node_modules/tether/dist/js/tether.min.js', included: true, watched: false},
        {pattern: 'karma-shim.js', included: true, watched: true},

        // Our built application code
        {pattern: 'temp/**/*.js', included: false, watched: true},

        // paths to support debugging with source maps in dev tools
        {pattern: 'src/**/*.ts', included: false, watched: false},
        {pattern: 'temp/**/*.js.map', included: false, watched: false},

        // fixtures
        {pattern: 'test/fixtures/**', watched: false, included: false, served: true},
    ],

    proxies: {
      // Avoid 404 warnings for images during testing
      '/assets/icons/utility-sprite/svg/symbols.svg': '/base/test/fixtures/fake',
      '/mypath/utility-sprite/svg/symbols.svg': '/base/test/fixtures/fake',
      '/mypath/standard-sprite/svg/symbols.svg': '/base/test/fixtures/fake',
      '/mypath/custom-sprite/svg/symbols.svg': '/base/test/fixtures/fake',
      '/image1.jpg': '/base/test/fixtures/fake',

      '/tether': '/base/node_modules/tether/dist/js/tether.min.js'
    },

    preprocessors: {
      'temp/**/*.js': ['sourcemap'],
      'temp/src/**/!(*spec|*mock).js': ['coverage'],
    },

    coverageReporter: {
      dir: 'coverage/',
      reporters: [{type: 'text-summary'}, {type: 'html'}],
    },

    reporters: isTravis ? ['dots'] : ['progress', 'coverage'],
    port: isTravis ? 9876 : 23011,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: [isTravis ? 'Firefox' : 'Chrome'],
    singleRun: false,
  };

  if (isSaucelabs) {
    cfg.customLaunchers =  require('./test/browser-providers');
    cfg.browsers = Object.keys(cfg.customLaunchers);
    cfg.reporters.push('saucelabs');
    cfg.sauceLabs = {
      tunnelIdentifier: isTravis ? process.env.TRAVIS_JOB_NUMBER : 'ng-lightning',
      connectOptions: {
        logfile: './saucelabs.log',
      },
    };
    cfg.captureTimeout = 120000;
    cfg.browserNoActivityTimeout = 120000;
  }

  config.set(cfg);
};
<|endoftext|>


<commit_before>function Scene16() {
    this.numParticles = 2048;
    this.maxSpeed = 0.01;
    this.gravityCenter = new THREE.Vector3(0, 0, 0);
    this.lightpos = new THREE.Vector3(0, 0, 0);
    this.gravityConstant = 0.0001;
    this.dx = [];
    this.d2x = [];
    this.m = [];
    this.lastBass = 0;
    for (var i = 0; i < this.numParticles; i++) {
        this.dx.push(new THREE.Vector3(0,0,0));
        this.d2x.push(new THREE.Vector3(0,0,0));
        this.m.push(0.1 + Math.random() * 0.9);
    }
};

Scene16.prototype.init = function() {
    this.hue1 = 0;
    this.hue2 = 180;
    camera = new THREE.PerspectiveCamera( 85, window.innerWidth/window.innerHeight, 0.1, 1000 );

    this.map = THREE.ImageUtils.loadTexture('isoparticle.png');
    //this.map.minFilter = THREE.NearestFilter;

    // Add objects
    curThreeScene = new THREE.Scene();
    camera.position.z = 14;

    var particleGeometry = new THREE.Geometry();
    for (var i = 0; i < this.numParticles; i++) {
        particleGeometry.vertices.push(new THREE.Vector3((Math.random() - 0.5)*100, (Math.random()-0.5)*100, (Math.random()-0.5)*100));
        particleGeometry.colors.push(new THREE.Color(0xFFFFFF * Math.random()));// * Math.random());
    }
    var particleMaterial = new THREE.PointCloudMaterial({
        size: 0.5,
        map: this.map,
        transparent: true,
        vertexColors:THREE.VertexColors
    });

    this.particles = new THREE.PointCloud(particleGeometry, particleMaterial);

    var planeGeom = new THREE.PlaneBufferGeometry(1000, 1000);
    //var planeMaterial = new THREE.MeshBasicMaterial();
    this.uniforms = {
        bass: {type: "f", value: bass},
        lightPos: {type: "v3", value: new THREE.Vector3(0,0,0)},
        resolution: { type: "v2", value: new THREE.Vector2(window.innerWidth, window.innerHeight) }
    };
    this.attributes = {
        vertexPosition: {type: "v3", values: particleGeometry.vertices},
    }
    var unif = this.uniforms;
    var attrib = this.attributes;
    var planeMaterial = new THREE.ShaderMaterial({
        uniforms: unif,
        attributes: attrib,
        vertexShader: document.getElementById("scene3vs").textContent,
        fragmentShader: document.getElementById("scene3fs").textContent,
    });
    this.plane = new THREE.Mesh(planeGeom, planeMaterial);

    curThreeScene.add(this.particles);
    curThreeScene.add(this.plane);

    // postprocessing
    composer = new THREE.EffectComposer( renderer );
    composer.addPass( new THREE.RenderPass( curThreeScene, camera ) );

    this.hblur = new THREE.ShaderPass(THREE.HorizontalBlurShader);
    composer.addPass(this.hblur);
    this.hblur.renderToScreen = true;
};

Scene16.prototype.deinit = function() {
    renderer.shadowMapEnabled = false;
};

Scene16.prototype.update = function(dt, t) {
    //this.particles.rotateOnAxis(new THREE.Vector3(1, 1, 0), 0.01);
    dt = dt;
    this.hue1 = (this.hue1 + bass * 1) % 360;
    this.hue2 = (this.hue2 + bass * 1) % 360;
    this.lightness = 7* bass;

    var cycle = barCycle / 2;

    var lightness1 = 5;

    var color_s1 = 'hsl(' + this.hue1 + '%, 100%, ' + lightness1 + '%)';
    var color1 = tinycolor(color_s1).toRgb();

    var color_s2 = 'hsl(' + this.hue2 + '%, 100%, ' + this.lightness + '%)';
    var color2 = tinycolor(color_s2).toRgb();

    var time = audio.currentTime * 1000;
    //console.log(dt);
    var is_bass = (bass > 0.90) && ((time - this.lastBass) > 200);
    if (is_bass) {
        this.lastBass = time;
    }
    for (var i = 0; i < this.numParticles; i++) {
        this.particles.geometry.vertices[i].add(this.dx[i].clone().multiplyScalar(dt));

        this.dx[i].add(this.d2x[i].clone().multiplyScalar(dt));
        if (this.dx[i].length() > this.maxSpeed){
            this.dx[i].normalize().multiplyScalar(this.maxSpeed);
        }
        if (i == 0) {
            //console.log(this.d2x[i]);
        }
        var diff = this.gravityCenter.clone().sub(this.particles.geometry.vertices[i]);
        var dir = diff.clone().normalize();
        var str = diff.length() - 1;
        if (diff.length > 40) {
            this.dx[i] = 0;
        }
        this.d2x[i] = dir.clone().multiplyScalar(this.m[i] * str * this.gravityConstant * (1- Math.random() * 0.1));
        this.d2x[i].add(new THREE.Vector3(Math.random()-0.5, Math.random()-0.99, Math.random()-0.99).multiplyScalar(0.000001));

        if (is_bass) {
            this.dx[i].add(dir.clone().multiplyScalar(-(0.1 + Math.random()*0.2) * (1/(diff.length()))));
            this.dx[i].add(dir.clone().cross(new THREE.Vector3(0, Math.sin(time*0.1), Math.cos(time*0.2)).multiplyScalar(0.1)));
        }
        this.dx[i].multiplyScalar(0.99);
        var lightstr2 = is_bass ? 0.3 : 1;
        var lightstr = 1 / Math.pow((this.lightpos.clone().sub(this.particles.geometry.vertices[i]).length() * lightstr2 * 0.05), 2);
        //console.log(lightstr);
        this.particles.geometry.colors[i] = new THREE.Color(color1.r / 255, color1.g / 255, color1.b / 255).multiplyScalar(lightstr);
        //console.log(color1.r);
        this.particles.geometry.verticesNeedUpdate = true;
        this.particles.geometry.colorsNeedUpdate = true;
    }

    //this.gravityCenter.x = Math.sin(time*0.001) * 15;
    //this.gravityCenter.y = Math.cos(time*0.001) * 15;
    //this.particles.material.size = snare;
    this.lightpos.x = Math.sin(time*0.003) * 15;
    this.lightpos.z = Math.cos(time*0.003) * 15;
    this.uniforms.bass.value = bass;
    this.uniforms.lightPos.value = new THREE.Vector3(color2.r / 255, color2.g / 255, color2.b / 255);
    var timeMod = time % 2000;

    this.hblur.uniforms[ 'h' ].value = Math.max(0, (snare - 0.5)) * 3 / 360;
};
<commit_msg>post processin<commit_after>function Scene16() {
    this.numParticles = 2048;
    this.maxSpeed = 0.01;
    this.gravityCenter = new THREE.Vector3(0, 0, 0);
    this.lightpos = new THREE.Vector3(0, 0, 0);
    this.gravityConstant = 0.0001;
    this.dx = [];
    this.d2x = [];
    this.m = [];
    this.lastBass = 0;
    for (var i = 0; i < this.numParticles; i++) {
        this.dx.push(new THREE.Vector3(0,0,0));
        this.d2x.push(new THREE.Vector3(0,0,0));
        this.m.push(0.1 + Math.random() * 0.9);
    }
};

Scene16.prototype.init = function() {
    this.hue1 = 0;
    this.hue2 = 0;
    camera = new THREE.PerspectiveCamera( 85, window.innerWidth/window.innerHeight, 0.1, 1000 );

    this.map = THREE.ImageUtils.loadTexture('isoparticle.png');
    //this.map.minFilter = THREE.NearestFilter;

    // Add objects
    curThreeScene = new THREE.Scene();
    camera.position.z = 14;

    var particleGeometry = new THREE.Geometry();
    for (var i = 0; i < this.numParticles; i++) {
        particleGeometry.vertices.push(new THREE.Vector3((Math.random() - 0.5)*100, (Math.random()-0.5)*100, (Math.random()-0.5)*100));
        particleGeometry.colors.push(new THREE.Color(0xFFFFFF * Math.random()));// * Math.random());
    }
    var particleMaterial = new THREE.PointCloudMaterial({
        size: 0.5,
        map: this.map,
        transparent: true,
        vertexColors:THREE.VertexColors
    });

    this.particles = new THREE.PointCloud(particleGeometry, particleMaterial);

    var planeGeom = new THREE.PlaneBufferGeometry(1000, 1000);
    //var planeMaterial = new THREE.MeshBasicMaterial();
    this.uniforms = {
        bass: {type: "f", value: bass},
        lightPos: {type: "v3", value: new THREE.Vector3(0,0,0)},
        resolution: { type: "v2", value: new THREE.Vector2(window.innerWidth, window.innerHeight) }
    };
    this.attributes = {
        vertexPosition: {type: "v3", values: particleGeometry.vertices},
    }
    var unif = this.uniforms;
    var attrib = this.attributes;
    var planeMaterial = new THREE.ShaderMaterial({
        uniforms: unif,
        attributes: attrib,
        vertexShader: document.getElementById("scene3vs").textContent,
        fragmentShader: document.getElementById("scene3fs").textContent,
    });
    this.plane = new THREE.Mesh(planeGeom, planeMaterial);

    curThreeScene.add(this.particles);
    curThreeScene.add(this.plane);

    // postprocessing
    composer = new THREE.EffectComposer( renderer );
    composer.addPass( new THREE.RenderPass( curThreeScene, camera ) );

    this.rgbeffect = new THREE.ShaderPass( THREE.RGBShiftShader );
    this.rgbeffect.uniforms[ 'amount' ].value = 0.002;
    composer.addPass( this.rgbeffect );

    this.hblur = new THREE.ShaderPass(THREE.HorizontalBlurShader);
    composer.addPass(this.hblur);
    this.hblur.renderToScreen = true;
};

Scene16.prototype.deinit = function() {
    renderer.shadowMapEnabled = false;
};

Scene16.prototype.update = function(dt, t) {
    //this.particles.rotateOnAxis(new THREE.Vector3(1, 1, 0), 0.01);
    dt = dt;
    this.hue1 = (this.hue1 + bass * 1) % 360;
    this.hue2 = (this.hue2 + bass * 1) % 360;
    this.lightness = 7* bass;

    var cycle = barCycle / 2;

    var lightness1 = 5;

    var color_s1 = 'hsl(' + this.hue1 + '%, 100%, ' + lightness1 + '%)';
    var color1 = tinycolor(color_s1).toRgb();

    var color_s2 = 'hsl(' + this.hue2 + '%, 100%, ' + this.lightness + '%)';
    var color2 = tinycolor(color_s2).toRgb();

    var time = audio.currentTime * 1000;
    //console.log(dt);
    var is_bass = (bass > 0.90) && ((time - this.lastBass) > 200);
    if (is_bass) {
        this.lastBass = time;
    }
    for (var i = 0; i < this.numParticles; i++) {
        this.particles.geometry.vertices[i].add(this.dx[i].clone().multiplyScalar(dt));

        this.dx[i].add(this.d2x[i].clone().multiplyScalar(dt));
        if (this.dx[i].length() > this.maxSpeed){
            this.dx[i].normalize().multiplyScalar(this.maxSpeed);
        }
        if (i == 0) {
            //console.log(this.d2x[i]);
        }
        var diff = this.gravityCenter.clone().sub(this.particles.geometry.vertices[i]);
        var dir = diff.clone().normalize();
        var str = diff.length() - 1;
        if (diff.length > 40) {
            this.dx[i] = 0;
        }
        this.d2x[i] = dir.clone().multiplyScalar(this.m[i] * str * this.gravityConstant * (1- Math.random() * 0.1));
        this.d2x[i].add(new THREE.Vector3(Math.random()-0.5, Math.random()-0.99, Math.random()-0.99).multiplyScalar(0.000001));

        if (is_bass) {
            this.dx[i].add(dir.clone().multiplyScalar(-(0.1 + Math.random()*0.2) * (1/(diff.length()))));
            this.dx[i].add(dir.clone().cross(new THREE.Vector3(0, Math.sin(time*0.1), Math.cos(time*0.2)).multiplyScalar(0.1)));
        }
        this.dx[i].multiplyScalar(0.99);
        var lightstr2 = is_bass ? 0.3 : 1;
        var lightstr = 1 / Math.pow((this.lightpos.clone().sub(this.particles.geometry.vertices[i]).length() * lightstr2 * 0.05), 2);
        //console.log(lightstr);
        this.particles.geometry.colors[i] = new THREE.Color(color1.r / 255, color1.g / 255, color1.b / 255).multiplyScalar(lightstr);
        //console.log(color1.r);
        this.particles.geometry.verticesNeedUpdate = true;
        this.particles.geometry.colorsNeedUpdate = true;
    }

    //this.gravityCenter.x = Math.sin(time*0.001) * 15;
    //this.gravityCenter.y = Math.cos(time*0.001) * 15;
    //this.particles.material.size = snare;
    this.lightpos.x = Math.sin(time*0.003) * 15;
    this.lightpos.z = Math.cos(time*0.003) * 15;
    this.uniforms.bass.value = bass;
    this.uniforms.lightPos.value = new THREE.Vector3(color2.r / 255, color2.g / 255, color2.b / 255);
    var timeMod = time % 2000;

    this.hblur.uniforms[ 'h' ].value = Math.max(0, (snare - 0.5)) * 3 / 512;
};
<|endoftext|>


<commit_before>"use strict";
/**
 * @module BrowserSync.options
 */
module.exports = {

    /**
     * BrowserSync includes a user-interface that is accessed via a separate port.
     * The UI allows to controls all devices, push sync updates and much more.
     * @property ui
     * @type Object
     * @param {Number} [port=3001]
     * @param {Number} [weinre.port=8080]
     * @since 2.0.0
     * @default false
     */
    ui: {
        port: 3001,
        weinre: {
            port: 8080
        }
    },

    /**
     * BrowserSync can watch your files as you work. Changes you make will either
     * be injected into the page (CSS & images) or will cause all browsers to do
     * a full-page refresh. See [anymatch](https://github.com/es128/anymatch) for more information on glob patterns.
     * @property files
     * @type Array|String
     * @default false
     */
    files: false,

    /**
     * File watching options that get passed along to [Chokidar](https://github.com/paulmillr/chokidar).
     * Check their docs for available options
     * @property watchOptions
     * @type Object
     * @default undefined
     * @since 2.6.0
     */
    watchOptions: {
        /*
         persistent: true,

         ignored: '*.txt',
         ignoreInitial: false,
         followSymlinks: true,
         cwd: '.',

         usePolling: true,
         alwaysStat: false,
         depth: undefined,
         interval: 100,

         ignorePermissionErrors: false,
         atomic: true
         */
    },

    /**
     * Use the built-in static server for basic HTML/JS/CSS websites.
     * @property server
     * @type Object|Boolean
     * @default false
     */
    server: false,

    /**
     * Proxy an EXISTING vhost. BrowserSync will wrap your vhost with a proxy URL to view your site.
     * @property proxy
     * @type String|Object|Boolean
     * @param {String} [target]
     * @param {Function|Array} [middleware]
     * @param {Function} [reqHeaders]
     * @default false
     */
    proxy: false,

    /**
     * @property port
     * @type Number
     * @default 3000
     */
    port: 3000,

    middleware: false,

    /**
     * Enable https for localhost development. **Note:** Proxy and Tunnel not currently supported.
     * @property https
     * @type Boolean
     * @default undefined
     * @since 1.3.0
     */

    /**
     * Clicks, Scrolls & Form inputs on any device will be mirrored to all others.
     * @property ghostMode
     * @param {Boolean} [clicks=true]
     * @param {Boolean} [scroll=true]
     * @param {Boolean} [forms=true]
     * @param {Boolean} [forms.submit=true]
     * @param {Boolean} [forms.inputs=true]
     * @param {Boolean} [forms.toggles=true]
     * @type Object
     */
    ghostMode: {
        clicks: true,
        scroll: true,
        forms: {
            submit: true,
            inputs: true,
            toggles: true
        }
    },

    /**
     * Can be either "info", "debug", "warn", or "silent"
     * @property logLevel
     * @type String
     * @default info
     */
    logLevel: "info",

    /**
     * Change the console logging prefix. Useful if you're creating your
     * own project based on BrowserSync
     * @property logPrefix
     * @type String
     * @default BS
     * @since 1.5.1
     */
    logPrefix: "BS",

    /**
     * @property logConnections
     * @type Boolean
     * @default false
     */
    logConnections: false,

    /**
     * @property logFileChanges
     * @type Boolean
     * @default true
     */
    logFileChanges: true,

    /**
     * Log the snippet to the console when you're in snippet mode (no proxy/server)
     * @property logSnippet
     * @type: Boolean
     * @default true
     * @since 1.5.2
     */
    logSnippet: true,

    /**
     * SINCE 1.7.0! You can control how the snippet is injected
     * onto each page via a custom regex + function.
     * You can also provide patterns for certain urls
     * that should be ignored from the snippet injection.
     * @property snippetOptions
     * @since 2.0.0
     * @param {Array} [blacklist]
     * @param {Array} [whitelist]
     * @param {RegExp} [rule.match=/<body[^>]*>/i]
     * @param {Function} [rule.fn=Function]
     * @type Object
     */
    snippetOptions: {
        whitelist: [],
        blacklist: [],
        rule: {
            match: /<body[^>]*>/i,
            fn: function (snippet, match) {
                return match + snippet;
            }
        }
    },

    /**
     * Add additional HTML rewriting rules.
     * @property rewriteRules
     * @since 2.4.0
     * @type Array|Boolean
     * @default false
     */
    rewriteRules: false,

    /**
     * @property tunnel
     * @type String|Boolean
     * @default null
     */

    /**
     * Some features of BrowserSync (such as `xip` & `tunnel`) require an internet connection, but if you're
     * working offline, you can reduce start-up time by setting this option to `false`
     * @property online
     * @type Boolean
     * @default undefined
     */

    /**
     * Decide which URL to open automatically when BrowserSync starts. Defaults to "local" if none set.
     * Can be true, "local", "external", "ui", "ui-external" or "tunnel"
     * @property open
     * @type Boolean|String
     * @default true
     */
    open: "local",

    /**
     * @property browser
     * @type String|Array
     * @default default
     */
    browser: "default",

    /**
     * Requires an internet connection - useful for services such as [Typekit](https://typekit.com/)
     * as it allows you to configure domains such as `*.xip.io` in your kit settings
     * @property xip
     * @type Boolean
     * @default false
     */
    xip: false,

    hostnameSuffix: false,

    /**
     * Reload each browser when BrowserSync is restarted.
     * @property reloadOnRestart
     * @type Boolean
     * @default true
     */
    reloadOnRestart: true,

    /**
     * The small pop-over notifications in the browser are not always needed/wanted.
     * @property notify
     * @type Boolean
     * @default true
     */
    notify: true,

    /**
     * @property scrollProportionally
     * @type Boolean
     * @default true
     */
    scrollProportionally: true,

    /**
     * @property scrollThrottle
     * @type Number
     * @default 0
     */
    scrollThrottle: 0,

    /**
     * Time, in milliseconds, to wait before
     * instruction browser to reload/inject following a
     * file change event
     * @property reloadDelay
     * @type Number
     * @default 0
     */
    reloadDelay: 0,

    /**
     * Restrict the frequency in which browser:reload events
     * can be emitted to connected clients
     * @property reloadDebounce
     * @type Number
     * @default 0
     * @since 2.6.0
     */
    reloadDebounce: 0,

    /**
     * User provided plugins
     * @property plugins
     * @type Array
     * @default []
     * @since 2.6.0
     */
    plugins: [],

    /**
     * @property injectChanges
     * @type Boolean
     * @default true
     */
    injectChanges: true,

    /**
     * @property startPath
     * @type String|Null
     * @default null
     */
    startPath: null,

    /**
     * Whether to minify client script, or not.
     * @property minify
     * @type Boolean
     * @default true
     */
    minify: true,

    /**
     * @property host
     * @type String
     * @default null
     */
    host: null,

    /**
     * @property codeSync
     * @type Boolean
     * @default true
     */
    codeSync: true,

    /**
     * @property timestamps
     * @type Boolean
     * @default true
     */
    timestamps: true,

    clientEvents: [
        "scroll",
        "input:text",
        "input:toggles",
        "form:submit",
        "form:reset",
        "click"
    ],

    /**
     * Alter the script path for complete control over where the BrowserSync
     * Javascript is served from. Whatever you return from this function
     * will be used as the script path.
     * @property scriptPath
     * @default undefined
     * @since 1.5.0
     * @type Function
     */

    /**
     * Configure the Socket.IO path and namespace to avoid collisions. Note: `namespace` can also be a function
     * @property socket
     * @param {String} [path="/browser-sync/socket.io"]
     * @param {String} [clientPath="/browser-sync"]
     * @param {String|Function} [namespace="/browser-sync"]
     * @param {Object} [clients.heartbeatTimeout=5000]
     * @since 1.6.2
     * @type Object
     */
    socket: {
        path: "/browser-sync/socket.io",
        clientPath: "/browser-sync",
        namespace: "/browser-sync",
        clients: {
            heartbeatTimeout: 5000
        }
    },

    /**
     * A map of file-extensions -> dom element.
     * Useful if you're serving files with unusual file extensions
     * @property tagNames
     */
    tagNames: {
        "less": "link",
        "scss": "link",
        "css":  "link",
        "jpg":  "img",
        "jpeg": "img",
        "png":  "img",
        "svg":  "img",
        "gif":  "img",
        "js":   "script"
    },

    injectFileTypes: ["css", "png", "jpg", "jpeg", "svg", "gif", "webp"],
    excludedFileTypes: [
        "js",
        "css",
        "pdf",
        "map",
        "svg",
        "ico",
        "woff",
        "json",
        "eot",
        "ttf",
        "png",
        "jpg",
        "jpeg",
        "webp",
        "gif",
        "mp4",
        "mp3",
        "3gp",
        "ogg",
        "ogv",
        "webm",
        "m4a",
        "flv",
        "wmv",
        "avi",
        "swf",
        "scss"
    ]
};
<commit_msg>Docs: update for auto-website build<commit_after>"use strict";
/**
 * @module BrowserSync.options
 */
module.exports = {

    /**
     * BrowserSync includes a user-interface that is accessed via a separate port.
     * The UI allows to controls all devices, push sync updates and much more.
     * @property ui
     * @type Object
     * @param {Number} [port=3001]
     * @param {Number} [weinre.port=8080]
     * @since 2.0.0
     * @default false
     */
    ui: {
        port: 3001,
        weinre: {
            port: 8080
        }
    },

    /**
     * BrowserSync can watch your files as you work. Changes you make will either
     * be injected into the page (CSS & images) or will cause all browsers to do
     * a full-page refresh. See [anymatch](https://github.com/es128/anymatch) for more information on glob patterns.
     * @property files
     * @type Array|String
     * @default false
     */
    files: false,

    /**
     * File watching options that get passed along to [Chokidar](https://github.com/paulmillr/chokidar).
     * Check their docs for available options
     * @property watchOptions
     * @type Object
     * @default undefined
     * @since 2.6.0
     */
    watchOptions: {
        /*
         persistent: true,

         ignored: '*.txt',
         ignoreInitial: false,
         followSymlinks: true,
         cwd: '.',

         usePolling: true,
         alwaysStat: false,
         depth: undefined,
         interval: 100,

         ignorePermissionErrors: false,
         atomic: true
         */
    },

    /**
     * Use the built-in static server for basic HTML/JS/CSS websites.
     * @property server
     * @type Object|Boolean
     * @default false
     */
    server: false,

    /**
     * Proxy an EXISTING vhost. BrowserSync will wrap your vhost with a proxy URL to view your site.
     * @property proxy
     * @type String|Object|Boolean
     * @param {String} [target]
     * @param {Function|Array} [middleware]
     * @param {Function} [reqHeaders]
     * @default false
     */
    proxy: false,

    /**
     * @property port
     * @type Number
     * @default 3000
     */
    port: 3000,

    middleware: false,

    /**
     * Enable https for localhost development. **Note** - this is not needed for proxy
     * option as it will be inferred from your target url.
     * @property https
     * @type Boolean
     * @default undefined
     * @since 1.3.0
     */

    /**
     * Clicks, Scrolls & Form inputs on any device will be mirrored to all others.
     * @property ghostMode
     * @param {Boolean} [clicks=true]
     * @param {Boolean} [scroll=true]
     * @param {Boolean} [forms=true]
     * @param {Boolean} [forms.submit=true]
     * @param {Boolean} [forms.inputs=true]
     * @param {Boolean} [forms.toggles=true]
     * @type Object
     */
    ghostMode: {
        clicks: true,
        scroll: true,
        forms: {
            submit: true,
            inputs: true,
            toggles: true
        }
    },

    /**
     * Can be either "info", "debug", "warn", or "silent"
     * @property logLevel
     * @type String
     * @default info
     */
    logLevel: "info",

    /**
     * Change the console logging prefix. Useful if you're creating your
     * own project based on BrowserSync
     * @property logPrefix
     * @type String
     * @default BS
     * @since 1.5.1
     */
    logPrefix: "BS",

    /**
     * @property logConnections
     * @type Boolean
     * @default false
     */
    logConnections: false,

    /**
     * @property logFileChanges
     * @type Boolean
     * @default true
     */
    logFileChanges: true,

    /**
     * Log the snippet to the console when you're in snippet mode (no proxy/server)
     * @property logSnippet
     * @type: Boolean
     * @default true
     * @since 1.5.2
     */
    logSnippet: true,

    /**
     * SINCE 1.7.0! You can control how the snippet is injected
     * onto each page via a custom regex + function.
     * You can also provide patterns for certain urls
     * that should be ignored from the snippet injection.
     * @property snippetOptions
     * @since 2.0.0
     * @param {Array} [blacklist]
     * @param {Array} [whitelist]
     * @param {RegExp} [rule.match=/<body[^>]*>/i]
     * @param {Function} [rule.fn=Function]
     * @type Object
     */
    snippetOptions: {
        whitelist: [],
        blacklist: [],
        rule: {
            match: /<body[^>]*>/i,
            fn: function (snippet, match) {
                return match + snippet;
            }
        }
    },

    /**
     * Add additional HTML rewriting rules.
     * @property rewriteRules
     * @since 2.4.0
     * @type Array|Boolean
     * @default false
     */
    rewriteRules: false,

    /**
     * @property tunnel
     * @type String|Boolean
     * @default null
     */

    /**
     * Some features of BrowserSync (such as `xip` & `tunnel`) require an internet connection, but if you're
     * working offline, you can reduce start-up time by setting this option to `false`
     * @property online
     * @type Boolean
     * @default undefined
     */

    /**
     * Decide which URL to open automatically when BrowserSync starts. Defaults to "local" if none set.
     * Can be true, `local`, `external`, `ui`, `ui-external`, `tunnel` or `false`
     * @property open
     * @type Boolean|String
     * @default true
     */
    open: "local",

    /**
     * @property browser
     * @type String|Array
     * @default default
     */
    browser: "default",

    /**
     * Requires an internet connection - useful for services such as [Typekit](https://typekit.com/)
     * as it allows you to configure domains such as `*.xip.io` in your kit settings
     * @property xip
     * @type Boolean
     * @default false
     */
    xip: false,

    hostnameSuffix: false,

    /**
     * Reload each browser when BrowserSync is restarted.
     * @property reloadOnRestart
     * @type Boolean
     * @default true
     */
    reloadOnRestart: true,

    /**
     * The small pop-over notifications in the browser are not always needed/wanted.
     * @property notify
     * @type Boolean
     * @default true
     */
    notify: true,

    /**
     * @property scrollProportionally
     * @type Boolean
     * @default true
     */
    scrollProportionally: true,

    /**
     * @property scrollThrottle
     * @type Number
     * @default 0
     */
    scrollThrottle: 0,

    /**
     * Time, in milliseconds, to wait before
     * instruction browser to reload/inject following a
     * file change event
     * @property reloadDelay
     * @type Number
     * @default 0
     */
    reloadDelay: 0,

    /**
     * Restrict the frequency in which browser:reload events
     * can be emitted to connected clients
     * @property reloadDebounce
     * @type Number
     * @default 0
     * @since 2.6.0
     */
    reloadDebounce: 0,

    /**
     * User provided plugins
     * @property plugins
     * @type Array
     * @default []
     * @since 2.6.0
     */
    plugins: [],

    /**
     * @property injectChanges
     * @type Boolean
     * @default true
     */
    injectChanges: true,

    /**
     * @property startPath
     * @type String|Null
     * @default null
     */
    startPath: null,

    /**
     * Whether to minify client script, or not.
     * @property minify
     * @type Boolean
     * @default true
     */
    minify: true,

    /**
     * @property host
     * @type String
     * @default null
     */
    host: null,

    /**
     * @property codeSync
     * @type Boolean
     * @default true
     */
    codeSync: true,

    /**
     * @property timestamps
     * @type Boolean
     * @default true
     */
    timestamps: true,

    clientEvents: [
        "scroll",
        "input:text",
        "input:toggles",
        "form:submit",
        "form:reset",
        "click"
    ],

    /**
     * Alter the script path for complete control over where the BrowserSync
     * Javascript is served from. Whatever you return from this function
     * will be used as the script path.
     * @property scriptPath
     * @default undefined
     * @since 1.5.0
     * @type Function
     */

    /**
     * Configure the Socket.IO path and namespace to avoid collisions. Note: `namespace` can also be a function
     * @property socket
     * @param {String} [path="/browser-sync/socket.io"]
     * @param {String} [clientPath="/browser-sync"]
     * @param {String|Function} [namespace="/browser-sync"]
     * @param {Object} [clients.heartbeatTimeout=5000]
     * @since 1.6.2
     * @type Object
     */
    socket: {
        path: "/browser-sync/socket.io",
        clientPath: "/browser-sync",
        namespace: "/browser-sync",
        clients: {
            heartbeatTimeout: 5000
        }
    },

    tagNames: {
        "less": "link",
        "scss": "link",
        "css":  "link",
        "jpg":  "img",
        "jpeg": "img",
        "png":  "img",
        "svg":  "img",
        "gif":  "img",
        "js":   "script"
    },

    injectFileTypes: ["css", "png", "jpg", "jpeg", "svg", "gif", "webp"],
    excludedFileTypes: [
        "js",
        "css",
        "pdf",
        "map",
        "svg",
        "ico",
        "woff",
        "json",
        "eot",
        "ttf",
        "png",
        "jpg",
        "jpeg",
        "webp",
        "gif",
        "mp4",
        "mp3",
        "3gp",
        "ogg",
        "ogv",
        "webm",
        "m4a",
        "flv",
        "wmv",
        "avi",
        "swf",
        "scss"
    ]
};
<|endoftext|>


<commit_before>/**
 * Created by timadamson on 8/22/17.
 */

/**
 * An App self adds 3 camera streams, and the controlers to move the robot
 */

function init() {
    var arm_div = document.querySelectorAll('.js_arm_div');
    this.app = new App();
    var self = this;

    app.ros.on('connection', function () {
        console.log("We are connected!");
    });

    var elmnt = document.getElementById("camera1");

    var cameraWidth = "342";
    var cameraHeight = "342";

    var upBTN1 = document.createElement("button");
    upBTN1.innerHTML="";
    upBTN1.id='up';
    upBTN1.title='\u2191Up\u2191';
    upBTN1.style.left=(cameraWidth - 95)/2 + "px";
    upBTN1.style.top= cameraHeight/4  + 10 + "px";
    var body = document.getElementsByTagName("body")[0];
    body.appendChild(upBTN1);

    var downBTN1 = document.createElement("button");
    downBTN1.innerHTML = "";
    downBTN1.id='down';
    downBTN1.title='\u2191Down\u2191';
    downBTN1.className = "button";
    downBTN1.style.left=(cameraWidth - 95)/2 + "px";
    downBTN1.style.top= (cameraHeight- (-50))+ "px";
    body.appendChild(downBTN1);

    var leftBTN1 = document.createElement("button");
    leftBTN1.innerHTML = "";
    leftBTN1.id='left';
    leftBTN1.title='\u2190Left\u2190[';
    leftBTN1.className = "button";
    leftBTN1.style.left=0 + "px";
    leftBTN1.style.top=(cameraHeight- (-90))/2 + "px";
    body.appendChild(leftBTN1);

    var rightBTN1 = document.createElement("button");
    rightBTN1.innerHTML = "";
    rightBTN1.id='right';
    rightBTN1.title='\u2192Right\u2192';
    rightBTN1.className = "button";
    rightBTN1.style.left=(cameraWidth -52)+ "px";
    rightBTN1.style.top= (cameraHeight- (-90))/2 + "px";
    body.appendChild(rightBTN1);

    var rotaterightBTN1 = document.createElement("button");
    rotaterightBTN1.innerHTML = "";
    rotaterightBTN1.id = 'rotateRight';
    rotaterightBTN1.title = '\u21BBRotate Right\u21BB';
    rotaterightBTN1.className = "button";
    rotaterightBTN1.style.left =(cameraWidth -118)+ "px";
    rotaterightBTN1.style.top =(cameraHeight- (-90))/2 + "px";
    rotaterightBTN1.style.height = 80 + "px";
    body.appendChild(rotaterightBTN1);

    var rotateleftBTN1 = document.createElement("button");
    rotateleftBTN1.innerHTML = "";
    rotateleftBTN1.id = 'rotateLeft';
    rotateleftBTN1.title = '\u21BARotate Left\u21BA';
    rotateleftBTN1.className = "button";
    rotateleftBTN1.style.width = 65 + "px";
    rotateleftBTN1.style.height = 80 + "px";
    rotateleftBTN1.style.left =  55 + "px";
    rotateleftBTN1.style.top = (cameraHeight- (-90))/2 + "px";
    rotateleftBTN1.style.height = 80 + "px";
    body.appendChild(rotateleftBTN1);

    var upBTN2 = document.createElement("button");
    upBTN2.innerHTML="";
    upBTN2.id='up2';
    upBTN2.title='\u2191Up\u2191';
    upBTN2.style.left=(cameraWidth - 100)*2 + "px";
    upBTN2.style.top= cameraHeight/4  + 10 + "px";
    body.appendChild(upBTN2);

    var downBTN2 = document.createElement("button");
    downBTN2.innerHTML = "";
    downBTN2.id='down2';
    downBTN2.title='\u2191Down\u2191';
    downBTN2.className = "button";
    downBTN2.style.left=(cameraWidth - 100)*2 + "px";
    downBTN2.style.top= (cameraHeight- (-50))+ "px";
    body.appendChild(downBTN2);

    var leftBTN2 = document.createElement("button");
    leftBTN2.innerHTML = "";
    leftBTN2.id='left2';
    leftBTN2.title='\u2191Left\u2191';
    leftBTN2.className = "button";
    leftBTN2.style.left=(cameraWidth- (-10)) + "px";
    leftBTN2.style.top=(cameraHeight- (-90))/2 + "px";
    body.appendChild(leftBTN2);

    var rightBTN2 = document.createElement("button");
    rightBTN2.innerHTML = "";
    rightBTN2.id='right2';
    rightBTN2.title='\u2191Right\u2191';
    rightBTN2.className = "button";
    rightBTN2.style.left=(cameraWidth*2 - (48)) + "px";
    rightBTN2.style.top= (cameraHeight- (-90))/2 + "px";
    body.appendChild(rightBTN2);

    var rotaterightBTN2 = document.createElement("button");
    rotaterightBTN2.innerHTML = "";
    rotaterightBTN2.id = 'rotateRight2';
    rotaterightBTN2.title = '\u21BBRotate Right\u21BB';
    rotaterightBTN2.className = "button";
    rotaterightBTN2.style.left =(cameraWidth*2- (120)) + "px";
    rotaterightBTN2.style.top =(cameraHeight- (-90))/2 + "px";
    rotaterightBTN2.style.height = 80 + "px";
    body.appendChild(rotaterightBTN2);

    var rotateleftBTN2 = document.createElement("button");
    rotateleftBTN2.innerHTML = "";
    rotateleftBTN2.id = 'rotateLeft2';
    rotateleftBTN2.title = '\u21BARotate Left\u21BA';
    rotateleftBTN2.className = "button";
    rotateleftBTN2.style.left =  (cameraWidth- (-65)) + "px";
    rotateleftBTN2.style.top = (cameraHeight- (-90))/2 + "px";
    body.appendChild(rotateleftBTN2);

    upBTN1.addEventListener ("click", pubMoveMsg);
    downBTN1.addEventListener ("click", pubMoveMsg);
    leftBTN1.addEventListener ("click", pubMoveMsg);
    rightBTN1.addEventListener ("click", pubMoveMsg);
    rotaterightBTN1.addEventListener ("click", pubMoveMsg);
    rotateleftBTN1.addEventListener ("click", pubMoveMsg);
    upBTN2.addEventListener ("click", pubMoveMsg);
    downBTN2.addEventListener ("click", pubMoveMsg);
    leftBTN2.addEventListener ("click", pubMoveMsg);
    rightBTN2.addEventListener ("click", pubMoveMsg);
    rotaterightBTN2.addEventListener ("click", pubMoveMsg);
    rotateleftBTN2.addEventListener ("click", pubMoveMsg);

function pubMoveMsg() {
    var comSel;
    var expr = this.id;
    switch (expr) {
      case 'up':
        comSel="Go Up 1";
        break;
      case 'up2':
        comSel="Go Up 2";
        break;
      case 'down':
        comSel="Go Down 1";
        break;
      case 'down2':
        comSel="Go Down 2";
        break;
      case 'left':
        comSel="Go Left 1";
        break;
      case 'left2':
        comSel="Go Left 2";
        break;
      case 'right':
        comSel="Go Right 1";
        break;
      case 'right2':
        comSel="Go Right 2";
        break;
      case 'rotateRight':
        comSel="Go Rotate Right 1";
        break;
      case 'rotateRight2':
        comSel="Go Rotate Right 2";
        break;
      case 'rotateLeft':
        comSel="Go Rotate Left";
        break;
      case 'rotateLeft2':
        comSel="Go Rotate Left 2";
        break;
    }

    document.getElementById("cmdReceived").innerHTML = comSel;
}
}<commit_msg>keyboard tooltips<commit_after>/**
 * Created by timadamson on 8/22/17.
 */

/**
 * An App self adds 3 camera streams, and the controlers to move the robot
 */

function init() {
    var arm_div = document.querySelectorAll('.js_arm_div');
    this.app = new App();
    var self = this;

    app.ros.on('connection', function () {
        console.log("We are connected!");
    });

    var elmnt = document.getElementById("camera1");

    var cameraWidth = "342";
    var cameraHeight = "342";

    var upBTN1 = document.createElement("button");
    upBTN1.innerHTML="";
    upBTN1.id='up';
    upBTN1.title='\u2191Up\u2191';
    upBTN1.style.left=(cameraWidth - 95)/2 + "px";
    upBTN1.style.top= cameraHeight/4  + 10 + "px";
    var body = document.getElementsByTagName("body")[0];
    body.appendChild(upBTN1);

    var downBTN1 = document.createElement("button");
    downBTN1.innerHTML = "";
    downBTN1.id='down';
    downBTN1.title='\u2193Down\u2193';
    downBTN1.className = "button";
    downBTN1.style.left=(cameraWidth - 95)/2 + "px";
    downBTN1.style.top= (cameraHeight- (-50))+ "px";
    body.appendChild(downBTN1);

    var leftBTN1 = document.createElement("button");
    leftBTN1.innerHTML = "";
    leftBTN1.id='left';
    leftBTN1.title='\u2190Left\u2190';
    leftBTN1.className = "button";
    leftBTN1.style.left=0 + "px";
    leftBTN1.style.top=(cameraHeight- (-90))/2 + "px";
    body.appendChild(leftBTN1);

    var rightBTN1 = document.createElement("button");
    rightBTN1.innerHTML = "";
    rightBTN1.id='right';
    rightBTN1.title='\u2192Right\u2192';
    rightBTN1.className = "button";
    rightBTN1.style.left=(cameraWidth -52)+ "px";
    rightBTN1.style.top= (cameraHeight- (-90))/2 + "px";
    body.appendChild(rightBTN1);

    var rotaterightBTN1 = document.createElement("button");
    rotaterightBTN1.innerHTML = "";
    rotaterightBTN1.id = 'rotateRight';
    rotaterightBTN1.title = '\u21B6Rotate Right\u21B6';
    rotaterightBTN1.className = "button";
    rotaterightBTN1.style.left =(cameraWidth -118)+ "px";
    rotaterightBTN1.style.top =(cameraHeight- (-90))/2 + "px";
    rotaterightBTN1.style.height = 80 + "px";
    body.appendChild(rotaterightBTN1);

    var rotateleftBTN1 = document.createElement("button");
    rotateleftBTN1.innerHTML = "";
    rotateleftBTN1.id = 'rotateLeft';
    rotateleftBTN1.title = '\u21BARotate Left\u21BA';
    rotateleftBTN1.className = "button";
    rotateleftBTN1.style.width = 65 + "px";
    rotateleftBTN1.style.height = 80 + "px";
    rotateleftBTN1.style.left =  55 + "px";
    rotateleftBTN1.style.top = (cameraHeight- (-90))/2 + "px";
    rotateleftBTN1.style.height = 80 + "px";
    body.appendChild(rotateleftBTN1);

    var upBTN2 = document.createElement("button");
    upBTN2.innerHTML="";
    upBTN2.id='up2';
    upBTN2.title='\u2191Up\u2191';
    upBTN2.style.left=(cameraWidth - 100)*2 + "px";
    upBTN2.style.top= cameraHeight/4  + 10 + "px";
    body.appendChild(upBTN2);

    var downBTN2 = document.createElement("button");
    downBTN2.innerHTML = "";
    downBTN2.id='down2';
    downBTN2.title='\u2193Down\u2193';
    downBTN2.className = "button";
    downBTN2.style.left=(cameraWidth - 100)*2 + "px";
    downBTN2.style.top= (cameraHeight- (-50))+ "px";
    body.appendChild(downBTN2);

    var leftBTN2 = document.createElement("button");
    leftBTN2.innerHTML = "";
    leftBTN2.id='left2';
    leftBTN2.title='\u2190Left\u2190';
    leftBTN2.className = "button";
    leftBTN2.style.left=(cameraWidth- (-10)) + "px";
    leftBTN2.style.top=(cameraHeight- (-90))/2 + "px";
    body.appendChild(leftBTN2);

    var rightBTN2 = document.createElement("button");
    rightBTN2.innerHTML = "";
    rightBTN2.id='right2';
    rightBTN2.title='\u2192Right\u2192';
    rightBTN2.className = "button";
    rightBTN2.style.left=(cameraWidth*2 - (48)) + "px";
    rightBTN2.style.top= (cameraHeight- (-90))/2 + "px";
    body.appendChild(rightBTN2);

    var rotaterightBTN2 = document.createElement("button");
    rotaterightBTN2.innerHTML = "";
    rotaterightBTN2.id = 'rotateRight2';
    rotaterightBTN2.title = '\u21B6Rotate Right\u21B6';
    rotaterightBTN2.className = "button";
    rotaterightBTN2.style.left =(cameraWidth*2- (120)) + "px";
    rotaterightBTN2.style.top =(cameraHeight- (-90))/2 + "px";
    rotaterightBTN2.style.height = 80 + "px";
    body.appendChild(rotaterightBTN2);

    var rotateleftBTN2 = document.createElement("button");
    rotateleftBTN2.innerHTML = "";
    rotateleftBTN2.id = 'rotateLeft2';
    rotateleftBTN2.title = '\u21BARotate Left\u21BA';
    rotateleftBTN2.className = "button";
    rotateleftBTN2.style.left =  (cameraWidth- (-65)) + "px";
    rotateleftBTN2.style.top = (cameraHeight- (-90))/2 + "px";
    body.appendChild(rotateleftBTN2);

    upBTN1.addEventListener ("click", pubMoveMsg);
    downBTN1.addEventListener ("click", pubMoveMsg);
    leftBTN1.addEventListener ("click", pubMoveMsg);
    rightBTN1.addEventListener ("click", pubMoveMsg);
    rotaterightBTN1.addEventListener ("click", pubMoveMsg);
    rotateleftBTN1.addEventListener ("click", pubMoveMsg);
    upBTN2.addEventListener ("click", pubMoveMsg);
    downBTN2.addEventListener ("click", pubMoveMsg);
    leftBTN2.addEventListener ("click", pubMoveMsg);
    rightBTN2.addEventListener ("click", pubMoveMsg);
    rotaterightBTN2.addEventListener ("click", pubMoveMsg);
    rotateleftBTN2.addEventListener ("click", pubMoveMsg);

function pubMoveMsg() {
    var comSel;
    var expr = this.id;
    switch (expr) {
      case 'up':
        comSel="Go Up 1";
        break;
      case 'up2':
        comSel="Go Up 2";
        break;
      case 'down':
        comSel="Go Down 1";
        break;
      case 'down2':
        comSel="Go Down 2";
        break;
      case 'left':
        comSel="Go Left 1";
        break;
      case 'left2':
        comSel="Go Left 2";
        break;
      case 'right':
        comSel="Go Right 1";
        break;
      case 'right2':
        comSel="Go Right 2";
        break;
      case 'rotateRight':
        comSel="Go Rotate Right 1";
        break;
      case 'rotateRight2':
        comSel="Go Rotate Right 2";
        break;
      case 'rotateLeft':
        comSel="Go Rotate Left";
        break;
      case 'rotateLeft2':
        comSel="Go Rotate Left 2";
        break;
    }

    document.getElementById("cmdReceived").innerHTML = comSel;
}
}<|endoftext|>


<commit_before>function traverseDOM(node){
  var childLen=node.childNodes.length;
  if(childLen==0){
  }else{
    for(var i=0;i<childLen;i++){
      var childTmp=node.childNodes[i];
      if(childTmp.nodeName=="DIV"){
        if(childTmp.id=="tanx-popwin-outermm_51073678_5024723_15460009"){
          var obj=window.getComputedStyle(childTmp);
          console.log(obj);
        }
        var obj=window.getComputedStyle(childTmp);
        if(obj.hasOwnProperty("position")){
          if(obj.position=="fixed"){
            console.log("the fixed element");
            console.log(childTmp);
            childTmp.style.display="none";
             return;
          }
        }
      }
      traverseDOM(childTmp);
    }
  }
}

setTimeout(function(){
  traverseDOM(document.body);
},500);

<commit_msg>Update test.js<commit_after>function traverseDOM(node){
  var childLen=node.childNodes.length;
  if(childLen==0){
  }else{
    for(var i=0;i<childLen;i++){
      var childTmp=node.childNodes[i];
      if(childTmp.nodeName=="DIV"){
        var obj=window.getComputedStyle(childTmp);
        if(obj.hasOwnProperty("position")){
          if(obj.position=="fixed"){
            console.log("the fixed element");
            console.log(childTmp);
            childTmp.style.display="none";
             return;
          }
        }
      }
      traverseDOM(childTmp);
    }
  }
}

setTimeout(function(){
  traverseDOM(document.body);
},0);

<|endoftext|>


<commit_before>'use strict';

const hash = require('./hash');

exports.Color = require('./color');
exports.escapeDiacritic = require('./escape_diacritic');
exports.escapeHTML = require('./escape_html');
exports.escapeRegExp = require('./escape_regexp');
exports.highlight = require('./highlight');
exports.htmlTag = require('./html_tag');
exports.Pattern = require('./pattern');
exports.Permalink = require('./permalink');
exports.slugize = require('./slugize');
exports.spawn = require('./spawn');
exports.stripHTML = require('./strip_html');
exports.truncate = require('./truncate');
exports.wordWrap = require('./word_wrap');
exports.hash = hash.hash;
exports.HashStream = hash.HashStream;
exports.createSha1Hash = hash.createSha1Hash;
exports.CacheStream = require('./cache_stream');
exports.camelCaseKeys = require('./camel_case_keys');
<commit_msg>style: sort functions in alphabetical order<commit_after>'use strict';

const hash = require('./hash');

exports.CacheStream = require('./cache_stream');
exports.camelCaseKeys = require('./camel_case_keys');
exports.Color = require('./color');
exports.createSha1Hash = hash.createSha1Hash;
exports.escapeDiacritic = require('./escape_diacritic');
exports.escapeHTML = require('./escape_html');
exports.escapeRegExp = require('./escape_regexp');
exports.hash = hash.hash;
exports.HashStream = hash.HashStream;
exports.highlight = require('./highlight');
exports.htmlTag = require('./html_tag');
exports.Pattern = require('./pattern');
exports.Permalink = require('./permalink');
exports.slugize = require('./slugize');
exports.spawn = require('./spawn');
exports.stripHTML = require('./strip_html');
exports.truncate = require('./truncate');
exports.wordWrap = require('./word_wrap');
<|endoftext|>