<commit_before>'use strict';

/**
 * Convert a list of strings to a list of objects with a name and value
 * @param {String[]} choices - list in the format of 'name:value' or 'name'
 * @return {Object[]} - choices with name and value properties
 */
function convertToNameValue(choices) {
  return choices.map(choice => {
    const name = choice.split(':')[0]
      , value = choice.split(':')[1] || name.toLowerCase();

    return {name, value};
  });
}

/**
 * Returns supported Angular versions
 * @return {Object[]} - list of supported Angular versions with name and value
 */
exports.getAngularVersions = function () {
  return ['1.4.*', '1.3.*', '1.2.*'].map(version => ({name: version, value: version}));
};

/**
 * Returns available Bower component choices for a given Angular version
 * @param {String} [angularVersion=1.2.*] - version of Angular being used in the format of '1.X.*'
 * @return {Object[]} - list of bower components with a name and value property
 */
exports.getBowerComponents = function (angularVersion = '1.2.*') {
  let bowerComponents = [
    'Angular Animate:animate',
    'Angular Cookies:cookies',
    'Angular Resource:resource',
    'Angular Sanitize:sanitize',
    'Angular Touch:touch',
    'Font Awesome:fontawesome',
    'Lo-Dash:lodash',
    'Restangular (installs Lo-Dash):restangular'
  ];

  if (angularVersion !== '1.2.*') {
    bowerComponents.splice(1, 0, 'Angular Aria:aria');
    bowerComponents.splice(3, 0, 'Angular Messages:messages');
  }

  return convertToNameValue(bowerComponents);
};

/**
 * Returns supported markup languages
 * @return {Object[]} - list of markup languages with name and value properties
 */
exports.getMarkupLanguages = function () {
  return convertToNameValue(['HAML', 'HTML', 'Jade']);
};

/**
 * Returns supported module structures
 * @return {Object[]} - list of module structures with name and value properties
 */
exports.getModuleStructures = function () {
  return convertToNameValue([
    ['app/',
    '├── module1/',
    '│   ├── module2/',
    '│   ├── module1-module.js',
    '│   └── module1-controller.js',
    '└── app.js'].join('\n') + ':module-only',

    ['app/',
    '├── module1/',
    '│   ├── controllers/',
    '│   │   └── module1-controller.js',
    '│   ├── module2/',
    '│   └── module1-module.js',
    '└── app.js'].join('\n') + ':module-type'
  ]);
};

/**
 * Returns supported script languages
 * @return {Object[]} - list of script languages with name and value properties
 */
exports.getScriptLanguages = function () {
  return convertToNameValue([
    'CoffeeScript:coffee',
    'EcmaScript2015 (ES6) using Babel:es6',
    'JavaScript (ES5):js',
    'TypeScript:ts'
  ]);
};

/**
 * Returns supported style langauges
 * @return {Object[]} - list of style languages with a name and value property
 */
exports.getStyleLanguages = function () {
  return convertToNameValue(['CSS', 'LESS', 'SCSS', 'Stylus:styl']);
};

/**
 * Returns supported test frameworks
 * @return {Object[]} - list of test frameworks with a name and value property
 */
exports.getTestFrameworks = function () {
  return convertToNameValue(['Jasmine', 'Mocha with Chai:mocha']);
};

/**
 * Returns available frameworks for a given Angular version
 * @param {String} [angularVersion=1.2.*] - version of Angular being used in the format of '1.X.*'
 * @return {Object[]} - list of frameworks with a name and value property
 */
exports.getUIFrameworks = function (angularVersion = '1.2.*') {
  let frameworks;

  frameworks = [
    'none',
    'Bootstrap with AngularStrap:angularstrap',
    'Bootstrap with UI Bootstrap:uibootstrap',
    'Foundation with Angular Foundation:foundation'
  ];

  if (angularVersion !== '1.2.*') {
    frameworks.splice(1, 0, 'Angular Material:material');
  }

  return convertToNameValue(frameworks);
};
<commit_msg>style(utils-prompts): switch to export default object<commit_after>'use strict';

/**
 * Convert a list of strings to a list of objects with a name and value
 * @param {String[]} choices - list in the format of 'name:value' or 'name'
 * @return {Object[]} - choices with name and value properties
 */
function convertToNameValue(choices) {
  return choices.map(choice => {
    const name = choice.split(':')[0]
      , value = choice.split(':')[1] || name.toLowerCase();

    return {name, value};
  });
}

export default {
  /**
   * Returns supported Angular versions
   * @return {Object[]} - list of supported Angular versions with name and value
   */
  getAngularVersions() {
    return ['1.4.*', '1.3.*', '1.2.*'].map(version => ({name: version, value: version}));
  },

  /**
   * Returns available Bower component choices for a given Angular version
   * @param {String} [angularVersion=1.2.*] - version of Angular being used in the format of '1.X.*'
   * @return {Object[]} - list of bower components with a name and value property
   */
  getBowerComponents(angularVersion = '1.2.*') {
    let bowerComponents = [
      'Angular Animate:animate',
      'Angular Cookies:cookies',
      'Angular Resource:resource',
      'Angular Sanitize:sanitize',
      'Angular Touch:touch',
      'Font Awesome:fontawesome',
      'Lo-Dash:lodash',
      'Restangular (installs Lo-Dash):restangular'
    ];

    if (angularVersion !== '1.2.*') {
      bowerComponents.splice(1, 0, 'Angular Aria:aria');
      bowerComponents.splice(3, 0, 'Angular Messages:messages');
    }

    return convertToNameValue(bowerComponents);
  },

  /**
   * Returns supported markup languages
   * @return {Object[]} - list of markup languages with name and value properties
   */
  getMarkupLanguages() {
    return convertToNameValue(['HAML', 'HTML', 'Jade']);
  },

  /**
   * Returns supported module structures
   * @return {Object[]} - list of module structures with name and value properties
   */
  getModuleStructures() {
    return convertToNameValue([
      ['app/',
      '├── module1/',
      '│   ├── module2/',
      '│   ├── module1-module.js',
      '│   └── module1-controller.js',
      '└── app.js'].join('\n') + ':module-only',

      ['app/',
      '├── module1/',
      '│   ├── controllers/',
      '│   │   └── module1-controller.js',
      '│   ├── module2/',
      '│   └── module1-module.js',
      '└── app.js'].join('\n') + ':module-type'
    ]);
  },

  /**
   * Returns supported script languages
   * @return {Object[]} - list of script languages with name and value properties
   */
  getScriptLanguages() {
    return convertToNameValue([
      'CoffeeScript:coffee',
      'EcmaScript2015 (ES6) using Babel:es6',
      'JavaScript (ES5):js',
      'TypeScript:ts'
    ]);
  },

  /**
   * Returns supported style langauges
   * @return {Object[]} - list of style languages with a name and value property
   */
  getStyleLanguages() {
    return convertToNameValue(['CSS', 'LESS', 'SCSS', 'Stylus:styl']);
  },

  /**
   * Returns supported test frameworks
   * @return {Object[]} - list of test frameworks with a name and value property
   */
  getTestFrameworks() {
    return convertToNameValue(['Jasmine', 'Mocha with Chai:mocha']);
  },

  /**
   * Returns available frameworks for a given Angular version
   * @param {String} [angularVersion=1.2.*] - version of Angular being used in the format of '1.X.*'
   * @return {Object[]} - list of frameworks with a name and value property
   */
  getUIFrameworks(angularVersion = '1.2.*') {
    let frameworks;

    frameworks = [
      'none',
      'Bootstrap with AngularStrap:angularstrap',
      'Bootstrap with UI Bootstrap:uibootstrap',
      'Foundation with Angular Foundation:foundation'
    ];

    if (angularVersion !== '1.2.*') {
      frameworks.splice(1, 0, 'Angular Material:material');
    }

    return convertToNameValue(frameworks);
  }
};
<|endoftext|>


<commit_before>var env = process.env;
var fs = require('fs');
var cache = require(env.Z_PATH_CACHE + 'cache');
var fingerprint = require(env.Z_PATH_UTILS + 'fingerprint');
var compViews = cache.comp('views');
var snippetCache = cache.file('snippets', {wd: env.Z_PATH_PROCESS_MARKUP, noCompression: true});

module.exports = factoryService;

function factory (name, role, callback) {
    var self = this;

    // check cache
    var view = compViews.pojo.get(name, role);

    // handle no access
    if (view === 0) {
        return callback(new Error('View ' + name + ' not found.'));
    }

    // return view from cache
    if (view) {
        return callback(null, view);
    }

    // get system store to fetch models
    compViews.get(name, role, function (err, view, viewChanged) {

        if (err || !view) {
            return callback(err || new Error('View ' + name + ' not found.'));
        }

        // save roles in view
        view._roles = view.roles;

        // add commit ids to css files
        fingerprint.addToFiles(null, view.css || [], function (err, css) {

            if (err) {
                return callback(err);
            }

            // update css
            if (css) {
                view.css = css;
            }

            if (!view.html) {

                // save view in cache
                compViews.pojo.set(name, view);

                return callback(null, view);
            }

            var path = view.html.replace(/[^a-z0-9\/\.\-_]|\.\.\//gi, '');
            snippetCache.set(path, function (err, snipped) {

                if (err) {
                    return callback(err);
                }

                // add snipped to view
                view.html = snipped.data.toString('utf8');

                // remove view on snippet change
                if (!viewChanged) {
                    snippetCache.obs.once('change:' + path, function () {
                        compViews.rm(name, role);
                    });
                }

                // save view in cache
                compViews.pojo.set(name, view);

                callback(null, view);
            });
        });
    });
}

function factoryService (event, name, callback) {
    var self = this;

    // check message
    if (!name) {
        return callback('Bad message');
    }

    // create model
    factory.call(self, name, event.role, function (err, view) {

        if (err) {
            return callback(err);
        }

        // create client view
        var clientView = {
            name: view.name
        };

        // add client config
        if (view.config && view.config.client) {
            clientView.config = view.config.client;
        }

        if (view.flow) {
            clientView.flow = view.flow;
        }

        if (view.html) {
            clientView.html = view.html;
        }

        if (view.to) {
            clientView.to = view.to;
        }

        if (view.css) {
            clientView.css = view.css;
        }

        if (view.dontEscape) {
            clientView.dontEscape = view.dontEscape;
        }

        if (view.leaveKeys) {
            clientView.leaveKeys = view.leaveKeys;
        }

        callback(null, clientView);
    });
}
<commit_msg>send config for "nested" views<commit_after>var env = process.env;
var fs = require('fs');
var cache = require(env.Z_PATH_CACHE + 'cache');
var fingerprint = require(env.Z_PATH_UTILS + 'fingerprint');
var compViews = cache.comp('views');
var snippetCache = cache.file('snippets', {wd: env.Z_PATH_PROCESS_MARKUP, noCompression: true});

module.exports = factoryService;

function factory (name, role, callback) {
    var self = this;

    // check cache
    var view = compViews.pojo.get(name, role);

    // handle no access
    if (view === 0) {
        return callback(new Error('View ' + name + ' not found.'));
    }

    // return view from cache
    if (view) {
        return callback(null, view);
    }

    // get system store to fetch models
    compViews.get(name, role, function (err, view, viewChanged) {

        if (err || !view) {
            return callback(err || new Error('View ' + name + ' not found.'));
        }

        // save roles in view
        view._roles = view.roles;

        // add commit ids to css files
        fingerprint.addToFiles(null, view.css || [], function (err, css) {

            if (err) {
                return callback(err);
            }

            // update css
            if (css) {
                view.css = css;
            }

            if (!view.html) {

                // save view in cache
                compViews.pojo.set(name, view);

                return callback(null, view);
            }

            var path = view.html.replace(/[^a-z0-9\/\.\-_]|\.\.\//gi, '');
            snippetCache.set(path, function (err, snipped) {

                if (err) {
                    return callback(err);
                }

                // add snipped to view
                view.html = snipped.data.toString('utf8');

                // remove view on snippet change
                if (!viewChanged) {
                    snippetCache.obs.once('change:' + path, function () {
                        compViews.rm(name, role);
                    });
                }

                // save view in cache
                compViews.pojo.set(name, view);

                callback(null, view);
            });
        });
    });
}

function factoryService (event, name, callback) {
    var self = this;

    // check message
    if (!name) {
        return callback('Bad message');
    }

    // create model
    factory.call(self, name, event.role, function (err, view) {

        if (err) {
            return callback(err);
        }

        // create client view
        var clientView = {
            name: view.name
        };

        // add client config
        if (view.config && view.config.client) {
            clientView.config = view.config.client;
        }

        if (view.nested) {
            clientView.nested = view.nested;
        }

        if (view.flow) {
            clientView.flow = view.flow;
        }

        if (view.html) {
            clientView.html = view.html;
        }

        if (view.to) {
            clientView.to = view.to;
        }

        if (view.css) {
            clientView.css = view.css;
        }

        if (view.dontEscape) {
            clientView.dontEscape = view.dontEscape;
        }

        if (view.leaveKeys) {
            clientView.leaveKeys = view.leaveKeys;
        }

        callback(null, clientView);
    });
}
<|endoftext|>


<commit_before>'use strict';
const qGram = require('./QGram');
const keyBar = require('./KeyBar');
const util = require('../util');

const CLI = require('clui');
const Line = CLI.Line;
const LineBuffer = CLI.LineBuffer;

function flattenQGram(qgram) {
	// replace qgram with just its value
	const flattened = qgram.map(qgram => qgram.y);
	if (flattened.length < 5) {
		while (flattened.length < 5) {
			flattened.push(0);
		}
	}
	return flattened;
}
module.exports = function (report) {
	const blankLine = new Line().fill().output();
	const base = new LineBuffer();
	base.addLine(blankLine);
	base.addLine(qGram(flattenQGram(report.users.qgram)));
	base.addLine(blankLine);
	const labels = new Line()
	.padding(2)
	.column('Key', 20)
	.column('Holding %', 27)
	.column('Releasing %', 27);
	base.addLine(labels);
	util.convertToArray(report.tactile).forEach(tactile => {
		base.addLine(keyBar(tactile, 100));
	});
	const now = new Date().toLocaleString();
	base.addLine(new Line().padding(2).column(`Last Control Update:${now}`, 50).fill());
	base.addLine(blankLine);
	base.output();
};
<commit_msg>Sort tactile output by id<commit_after>'use strict';
const qGram = require('./QGram');
const keyBar = require('./KeyBar');
const util = require('../util');

const CLI = require('clui');
const Line = CLI.Line;
const LineBuffer = CLI.LineBuffer;

function flattenQGram(qgram) {
	// replace qgram with just its value
	const flattened = qgram.map(qgram => qgram.y);
	if (flattened.length < 5) {
		while (flattened.length < 5) {
			flattened.push(0);
		}
	}
	return flattened;
}
module.exports = function (report) {
	const tactileArray = util.convertToArray(report.tactile);
	const maxIdLength = Math.floor(Math.log10(Math.abs(tactileArray.length))) + 1;
	const blankLine = new Line().fill().output();
	const base = new LineBuffer();
	base.addLine(blankLine);
	base.addLine(qGram(flattenQGram(report.users.qgram)));
	base.addLine(blankLine);
	const labels = new Line()
	.padding(2)
	.column('ID', maxIdLength + 3)
	.column('Key', 20)
	.column('Holding %', 25)
	.column('Releasing %', 27);
	base.addLine(labels);
	tactileArray.sort(function(a, b) { return a.id - b.id; }).forEach(tactile => {
		base.addLine(keyBar(tactile, maxIdLength, 100));
	});
	const now = new Date().toLocaleString();
	base.addLine(new Line().padding(2).column(`Last Control Update:${now}`, 50).fill());
	base.addLine(blankLine);
	base.output();
};
<|endoftext|>


<commit_before>import { combineReducers } from 'redux';

import { CONFERENCE_FAILED, CONFERENCE_LEFT } from '../conference';
import { ReducerRegistry } from '../redux';
import { TRACK_REMOVED } from '../tracks';

import {
    SET_AUDIO_AVAILABLE,
    SET_AUDIO_MUTED,
    SET_CAMERA_FACING_MODE,
    SET_VIDEO_AVAILABLE,
    SET_VIDEO_MUTED,
    STORE_VIDEO_TRANSFORM,
    TOGGLE_CAMERA_FACING_MODE
} from './actionTypes';
import { CAMERA_FACING_MODE } from './constants';

/**
 * Media state object for local audio.
 *
 * @typedef {Object} AudioMediaState
 * @property {boolean} muted=false - Audio muted state.
 */

// FIXME Technically, _AUDIO_INITIAL_MEDIA_STATE is a constant internal to the
// feature base/media and used in multiple files so it should be in
// constants.js. Practically though, AudioMediaState would then be used in
// multiple files as well so I don't know where and how to move it.
/**
 * Initial state for local audio.
 *
 * @type {AudioMediaState}
 */
export const _AUDIO_INITIAL_MEDIA_STATE = {
    available: true,
    muted: false
};

/**
 * Reducer for audio media state.
 *
 * @param {AudioMediaState} state - Media state of local audio.
 * @param {Object} action - Action object.
 * @param {string} action.type - Type of action.
 * @private
 * @returns {AudioMediaState}
 */
function _audio(state = _AUDIO_INITIAL_MEDIA_STATE, action) {
    switch (action.type) {
    case SET_AUDIO_AVAILABLE:
        return {
            ...state,
            available: action.available
        };

    case SET_AUDIO_MUTED:
        return {
            ...state,
            muted: action.muted
        };

    default:
        return state;
    }
}

/**
 * Media state object for local video.
 *
 * @typedef {Object} VideoMediaState
 * @property {CAMERA_FACING_MODE} facingMode='user' - Camera facing mode.
 * @property {boolean} muted=false - Video muted state.
 */

// FIXME Technically, _VIDEO_INITIAL_MEDIA_STATE is a constant internal to the
// feature base/media and used in multiple files so it should be in
// constants.js. Practically though, VideoMediaState would then be used in
// multiple files as well so I don't know where and how to move it.
/**
 * Initial state for video.
 *
 * @type {VideoMediaState}
 */
export const _VIDEO_INITIAL_MEDIA_STATE = {
    available: true,
    facingMode: CAMERA_FACING_MODE.USER,
    muted: 0,

    /**
     * The video {@link Transform}s applied to {@code MediaStream}s by
     * {@code id} i.e. "pinch to zoom".
     */
    transforms: {}
};

/**
 * Reducer for camera media state.
 *
 * @param {VideoMediaState} state - Media state of local video.
 * @param {Object} action - Action object.
 * @param {string} action.type - Type of action.
 * @private
 * @returns {VideoMediaState}
 */
function _video(state = _VIDEO_INITIAL_MEDIA_STATE, action) {
    switch (action.type) {
    case CONFERENCE_FAILED:
    case CONFERENCE_LEFT:
        return _clearAllVideoTransforms(state);

    case SET_CAMERA_FACING_MODE:
        return {
            ...state,
            facingMode: action.cameraFacingMode
        };

    case SET_VIDEO_AVAILABLE:
        return {
            ...state,
            available: action.available
        };

    case SET_VIDEO_MUTED:
        return {
            ...state,
            muted: action.muted
        };

    case STORE_VIDEO_TRANSFORM:
        return _storeVideoTransform(state, action);

    case TOGGLE_CAMERA_FACING_MODE: {
        let cameraFacingMode = state.facingMode;

        cameraFacingMode
            = cameraFacingMode === CAMERA_FACING_MODE.USER
                ? CAMERA_FACING_MODE.ENVIRONMENT
                : CAMERA_FACING_MODE.USER;

        return {
            ...state,
            facingMode: cameraFacingMode
        };
    }

    case TRACK_REMOVED:
        return _trackRemoved(state, action);

    default:
        return state;
    }
}

/**
 * Listen for various actions related to media devices.
 *
 * @param {Object} state - State of media devices.
 * @param {Object} action - Action object.
 * @param {string} action.type - Type of action.
 * @param {Object} action.media - Information about media devices to be
 * modified.
 * @returns {Object}
 */
ReducerRegistry.register('features/base/media', combineReducers({
    audio: _audio,
    video: _video
}));

/**
 * Removes all stored video {@link Transform}s.
 *
 * @param {Object} state - The {@code video} state of the feature base/media.
 * @private
 * @returns {Object}
 */
function _clearAllVideoTransforms(state) {
    return {
        ...state,
        transforms: _VIDEO_INITIAL_MEDIA_STATE.transforms
    };
}

/**
 * Stores the last applied transform to a stream.
 *
 * @param {Object} state - The {@code video} state of the feature base/media.
 * @param {Object} action - The redux action {@link STORE_VIDEO_TRANSFORM}.
 * @private
 * @returns {Object}
 */
function _storeVideoTransform(state, { streamId, transform }) {
    return {
        ...state,
        transforms: {
            ...state.transforms,
            [streamId]: transform
        }
    };
}

/**
 * Removes the stored video {@link Transform} associated with a
 * {@code MediaStream} when its respective track is removed.
 *
 * @param {Object} state - The {@code video} state of the feature base/media.
 * @param {Object} action - The redux action {@link TRACK_REMOVED}.
 * @private
 * @returns {Object}
 */
function _trackRemoved(state, { track: { jitsiTrack } }) {
    if (jitsiTrack) {
        const streamId = jitsiTrack.getStreamId();

        if (streamId && streamId in state.transforms) {
            const nextTransforms = {
                ...state.transforms
            };

            delete nextTransforms[streamId];

            return {
                ...state,
                transforms: nextTransforms
            };
        }
    }

    return state;
}
<commit_msg>misc: break import cycle<commit_after>import { combineReducers } from 'redux';

import { CONFERENCE_FAILED, CONFERENCE_LEFT } from '../conference/actionTypes';
import { ReducerRegistry } from '../redux';
import { TRACK_REMOVED } from '../tracks/actionTypes';

import {
    SET_AUDIO_AVAILABLE,
    SET_AUDIO_MUTED,
    SET_CAMERA_FACING_MODE,
    SET_VIDEO_AVAILABLE,
    SET_VIDEO_MUTED,
    STORE_VIDEO_TRANSFORM,
    TOGGLE_CAMERA_FACING_MODE
} from './actionTypes';
import { CAMERA_FACING_MODE } from './constants';

/**
 * Media state object for local audio.
 *
 * @typedef {Object} AudioMediaState
 * @property {boolean} muted=false - Audio muted state.
 */

// FIXME Technically, _AUDIO_INITIAL_MEDIA_STATE is a constant internal to the
// feature base/media and used in multiple files so it should be in
// constants.js. Practically though, AudioMediaState would then be used in
// multiple files as well so I don't know where and how to move it.
/**
 * Initial state for local audio.
 *
 * @type {AudioMediaState}
 */
export const _AUDIO_INITIAL_MEDIA_STATE = {
    available: true,
    muted: false
};

/**
 * Reducer for audio media state.
 *
 * @param {AudioMediaState} state - Media state of local audio.
 * @param {Object} action - Action object.
 * @param {string} action.type - Type of action.
 * @private
 * @returns {AudioMediaState}
 */
function _audio(state = _AUDIO_INITIAL_MEDIA_STATE, action) {
    switch (action.type) {
    case SET_AUDIO_AVAILABLE:
        return {
            ...state,
            available: action.available
        };

    case SET_AUDIO_MUTED:
        return {
            ...state,
            muted: action.muted
        };

    default:
        return state;
    }
}

/**
 * Media state object for local video.
 *
 * @typedef {Object} VideoMediaState
 * @property {CAMERA_FACING_MODE} facingMode='user' - Camera facing mode.
 * @property {boolean} muted=false - Video muted state.
 */

// FIXME Technically, _VIDEO_INITIAL_MEDIA_STATE is a constant internal to the
// feature base/media and used in multiple files so it should be in
// constants.js. Practically though, VideoMediaState would then be used in
// multiple files as well so I don't know where and how to move it.
/**
 * Initial state for video.
 *
 * @type {VideoMediaState}
 */
export const _VIDEO_INITIAL_MEDIA_STATE = {
    available: true,
    facingMode: CAMERA_FACING_MODE.USER,
    muted: 0,

    /**
     * The video {@link Transform}s applied to {@code MediaStream}s by
     * {@code id} i.e. "pinch to zoom".
     */
    transforms: {}
};

/**
 * Reducer for camera media state.
 *
 * @param {VideoMediaState} state - Media state of local video.
 * @param {Object} action - Action object.
 * @param {string} action.type - Type of action.
 * @private
 * @returns {VideoMediaState}
 */
function _video(state = _VIDEO_INITIAL_MEDIA_STATE, action) {
    switch (action.type) {
    case CONFERENCE_FAILED:
    case CONFERENCE_LEFT:
        return _clearAllVideoTransforms(state);

    case SET_CAMERA_FACING_MODE:
        return {
            ...state,
            facingMode: action.cameraFacingMode
        };

    case SET_VIDEO_AVAILABLE:
        return {
            ...state,
            available: action.available
        };

    case SET_VIDEO_MUTED:
        return {
            ...state,
            muted: action.muted
        };

    case STORE_VIDEO_TRANSFORM:
        return _storeVideoTransform(state, action);

    case TOGGLE_CAMERA_FACING_MODE: {
        let cameraFacingMode = state.facingMode;

        cameraFacingMode
            = cameraFacingMode === CAMERA_FACING_MODE.USER
                ? CAMERA_FACING_MODE.ENVIRONMENT
                : CAMERA_FACING_MODE.USER;

        return {
            ...state,
            facingMode: cameraFacingMode
        };
    }

    case TRACK_REMOVED:
        return _trackRemoved(state, action);

    default:
        return state;
    }
}

/**
 * Listen for various actions related to media devices.
 *
 * @param {Object} state - State of media devices.
 * @param {Object} action - Action object.
 * @param {string} action.type - Type of action.
 * @param {Object} action.media - Information about media devices to be
 * modified.
 * @returns {Object}
 */
ReducerRegistry.register('features/base/media', combineReducers({
    audio: _audio,
    video: _video
}));

/**
 * Removes all stored video {@link Transform}s.
 *
 * @param {Object} state - The {@code video} state of the feature base/media.
 * @private
 * @returns {Object}
 */
function _clearAllVideoTransforms(state) {
    return {
        ...state,
        transforms: _VIDEO_INITIAL_MEDIA_STATE.transforms
    };
}

/**
 * Stores the last applied transform to a stream.
 *
 * @param {Object} state - The {@code video} state of the feature base/media.
 * @param {Object} action - The redux action {@link STORE_VIDEO_TRANSFORM}.
 * @private
 * @returns {Object}
 */
function _storeVideoTransform(state, { streamId, transform }) {
    return {
        ...state,
        transforms: {
            ...state.transforms,
            [streamId]: transform
        }
    };
}

/**
 * Removes the stored video {@link Transform} associated with a
 * {@code MediaStream} when its respective track is removed.
 *
 * @param {Object} state - The {@code video} state of the feature base/media.
 * @param {Object} action - The redux action {@link TRACK_REMOVED}.
 * @private
 * @returns {Object}
 */
function _trackRemoved(state, { track: { jitsiTrack } }) {
    if (jitsiTrack) {
        const streamId = jitsiTrack.getStreamId();

        if (streamId && streamId in state.transforms) {
            const nextTransforms = {
                ...state.transforms
            };

            delete nextTransforms[streamId];

            return {
                ...state,
                transforms: nextTransforms
            };
        }
    }

    return state;
}
<|endoftext|>


<commit_before>'use strict';

var browserify = require('browserify'),
    watchify   = require('watchify'),
    exorcist   = require('exorcist'),
    uglifyify  = require('uglifyify'),
    istanbul   = require('browserify-istanbul'),
    fs         = require('fs'),
    path       = require('path'),
    FileSet    = require('./file-set'),
    util       = require('./util');

module.exports = writeBundles;

/**
 * Writes Browserify bundles for the given entry file.
 * At least one bundle is created (the outputFile), but additional ones may be
 * created, depending on {@link Options.debug}, {@link Options.minify}, and {@link Options.test}.
 *
 * @param {FileSet} mainFiles - The main input & output files (not the minified or test files)
 * @param {EventEmitter} events - Browserify events will be propagated to this EventEmitter
 * @param {Options} options - Bundling options
 */
function writeBundles(mainFiles, events, options) {
  var bundles = [];
  var bundleFiles = [];

  // Create the main bundle
  var mainBundle = newify(mainFiles, events, options);
  bundles.push(mainBundle);
  bundleFiles.push(mainFiles);

  if (options.minify) {
    // The files for the minified bundle
    var minifiedFiles = new FileSet();
    minifiedFiles.entryFile = mainFiles.entryFile;
    minifiedFiles.outputFile = util.appendToFileName(mainFiles.outputFile, '.min');
    if (options.debug) {
      minifiedFiles.mapFile = minifiedFiles.outputFile + '.map';
    }
    bundleFiles.push(minifiedFiles);

    // Create the minified bundle
    var minifiedBundle = newify(minifiedFiles, events, options);
    addMinifyTransform(minifiedBundle);
    bundles.push(minifiedBundle);
  }

  if (options.test) {
    // The files for the test bundle
    var testFiles = new FileSet();
    testFiles.entryFile = mainFiles.entryFile;
    testFiles.outputFile = util.appendToFileName(mainFiles.outputFile, '.test');
    bundleFiles.push(testFiles);

    // Create the test bundle
    var testBundle = newify(testFiles, events, options);
    addCoverageTransform(testBundle);
    addMinifyTransform(testBundle);
    bundles.push(testBundle);
  }

  /**
   * Build each bundle one-at-a-time, rather than all of them simultaneously.
   * This dramatically lowers the total build time, especially on large apps.
   *
   * @param {number} index - The bundle to build (from the {@link bundles} array)
   **/
  function writeBundle(index) {
    if (bundles[index]) {
      // Write this bundle
      bundle(bundles[index], bundleFiles[index]);

      // Write the next bundle when this one finishes
      bundles[index].once('end', function() {
        writeBundle(index + 1);
      });
    }
  }

  writeBundle(0);
}

/**
 * Creates a new Browserify or Watchify instance
 *
 * @param {FileSet} fileSet - The input & output files for this bundle
 * @param {EventEmitter} events - Browserify events will be propagated to this EventEmitter
 * @param {Options} options - Bundling options
 * @returns {Browserify}
 */
function newify(fileSet, events, options) {
  var b = browserify({
    entries: fileSet.entryFile,
    standalone: options.standalone || undefined,
    debug: !!fileSet.mapFile,
    cache: {},
    packageCache: {}
  });

  // Propagate events
  b.on('error', function(err) {
    events.emit('error', err, fileSet);
  });
  b.on('end', function() {
    events.emit('end', fileSet);
  });
  b.on('log', function(msg) {
    events.emit('log', msg, fileSet);
  });
  b.on('update', function(file) {
    events.emit('update', file.toString(), fileSet);
  });

  if (options.watch) {
    // Enable Watchify
    b = watchify(b);

    // Re-bundle when a file changes
    b.on('update', function() {
      bundle(b, fileSet);
    });
  }

  return b;
}

/**
 * Uses the Uglifyify transform to minify the given Browserify bundle
 *
 * @param {Browserify} b - The Browserify object to transform
 */
function addMinifyTransform(b) {
  b.transform(uglifyify, {
    global: true,
    exts: ['.js', '.json'],
    output: {
      // Keep important comments when minifying
      comments: /^!|^\*!|@preserve|@license|@cc_on/
    }
  });
}

/**
 * Uses the Istanbul transform to add code-coverage instrumentation the given Browserify bundle
 *
 * @param {Browserify} b - The Browserify object to transform
 */
function addCoverageTransform(b) {
  b.transform(istanbul({
    ignore: ['**/*.html', '**/*.md', '**/*.txt'],
    defaultIgnore: true
  }));
}

/**
 * Writes the output file (and possibly its .map file) for the given Browserify object
 *
 * @param {Browserify} b - The Browserify object to bundle
 * @param {FileSet} fileSet - The input & output files for this bundle
 */
function bundle(b, fileSet) {
  var stream = b.bundle();
  stream.on('end', b.emit.bind(b, 'end'));
  stream.on('error', b.emit.bind(b, 'error'));

  if (fileSet.mapFile) {
    util.ensureFileExists(fileSet.mapFile);
    var dirname = path.dirname(fileSet.mapFile);
    stream = stream.pipe(exorcist(fileSet.mapFile, null, null, dirname));
  }

  util.ensureFileExists(fileSet.outputFile);
  stream.pipe(fs.createWriteStream(fileSet.outputFile));
}
<commit_msg>Excluded the default Istanbul ignore list, since it includes folders such as "tests" and "bower_components", which can cause confusion<commit_after>'use strict';

var browserify = require('browserify'),
    watchify   = require('watchify'),
    exorcist   = require('exorcist'),
    uglifyify  = require('uglifyify'),
    istanbul   = require('browserify-istanbul'),
    fs         = require('fs'),
    path       = require('path'),
    FileSet    = require('./file-set'),
    util       = require('./util');

module.exports = writeBundles;

/**
 * Writes Browserify bundles for the given entry file.
 * At least one bundle is created (the outputFile), but additional ones may be
 * created, depending on {@link Options.debug}, {@link Options.minify}, and {@link Options.test}.
 *
 * @param {FileSet} mainFiles - The main input & output files (not the minified or test files)
 * @param {EventEmitter} events - Browserify events will be propagated to this EventEmitter
 * @param {Options} options - Bundling options
 */
function writeBundles(mainFiles, events, options) {
  var bundles = [];
  var bundleFiles = [];

  // Create the main bundle
  var mainBundle = newify(mainFiles, events, options);
  bundles.push(mainBundle);
  bundleFiles.push(mainFiles);

  if (options.minify) {
    // The files for the minified bundle
    var minifiedFiles = new FileSet();
    minifiedFiles.entryFile = mainFiles.entryFile;
    minifiedFiles.outputFile = util.appendToFileName(mainFiles.outputFile, '.min');
    if (options.debug) {
      minifiedFiles.mapFile = minifiedFiles.outputFile + '.map';
    }
    bundleFiles.push(minifiedFiles);

    // Create the minified bundle
    var minifiedBundle = newify(minifiedFiles, events, options);
    addMinifyTransform(minifiedBundle);
    bundles.push(minifiedBundle);
  }

  if (options.test) {
    // The files for the test bundle
    var testFiles = new FileSet();
    testFiles.entryFile = mainFiles.entryFile;
    testFiles.outputFile = util.appendToFileName(mainFiles.outputFile, '.test');
    bundleFiles.push(testFiles);

    // Create the test bundle
    var testBundle = newify(testFiles, events, options);
    addCoverageTransform(testBundle);
    addMinifyTransform(testBundle);
    bundles.push(testBundle);
  }

  /**
   * Build each bundle one-at-a-time, rather than all of them simultaneously.
   * This dramatically lowers the total build time, especially on large apps.
   *
   * @param {number} index - The bundle to build (from the {@link bundles} array)
   **/
  function writeBundle(index) {
    if (bundles[index]) {
      // Write this bundle
      bundle(bundles[index], bundleFiles[index]);

      // Write the next bundle when this one finishes
      bundles[index].once('end', function() {
        writeBundle(index + 1);
      });
    }
  }

  writeBundle(0);
}

/**
 * Creates a new Browserify or Watchify instance
 *
 * @param {FileSet} fileSet - The input & output files for this bundle
 * @param {EventEmitter} events - Browserify events will be propagated to this EventEmitter
 * @param {Options} options - Bundling options
 * @returns {Browserify}
 */
function newify(fileSet, events, options) {
  var b = browserify({
    entries: fileSet.entryFile,
    standalone: options.standalone || undefined,
    debug: !!fileSet.mapFile,
    cache: {},
    packageCache: {}
  });

  // Propagate events
  b.on('error', function(err) {
    events.emit('error', err, fileSet);
  });
  b.on('end', function() {
    events.emit('end', fileSet);
  });
  b.on('log', function(msg) {
    events.emit('log', msg, fileSet);
  });
  b.on('update', function(file) {
    events.emit('update', file.toString(), fileSet);
  });

  if (options.watch) {
    // Enable Watchify
    b = watchify(b);

    // Re-bundle when a file changes
    b.on('update', function() {
      bundle(b, fileSet);
    });
  }

  return b;
}

/**
 * Uses the Uglifyify transform to minify the given Browserify bundle
 *
 * @param {Browserify} b - The Browserify object to transform
 */
function addMinifyTransform(b) {
  b.transform(uglifyify, {
    global: true,
    exts: ['.js', '.json'],
    output: {
      // Keep important comments when minifying
      comments: /^!|^\*!|@preserve|@license|@cc_on/
    }
  });
}

/**
 * Uses the Istanbul transform to add code-coverage instrumentation the given Browserify bundle
 *
 * @param {Browserify} b - The Browserify object to transform
 */
function addCoverageTransform(b) {
  b.transform(istanbul({
    ignore: ['**/*.json', '**/*.html', '**/*.md', '**/*.txt'],
    defaultIgnore: false
  }));
}

/**
 * Writes the output file (and possibly its .map file) for the given Browserify object
 *
 * @param {Browserify} b - The Browserify object to bundle
 * @param {FileSet} fileSet - The input & output files for this bundle
 */
function bundle(b, fileSet) {
  var stream = b.bundle();
  stream.on('end', b.emit.bind(b, 'end'));
  stream.on('error', b.emit.bind(b, 'error'));

  if (fileSet.mapFile) {
    util.ensureFileExists(fileSet.mapFile);
    var dirname = path.dirname(fileSet.mapFile);
    stream = stream.pipe(exorcist(fileSet.mapFile, null, null, dirname));
  }

  util.ensureFileExists(fileSet.outputFile);
  stream.pipe(fs.createWriteStream(fileSet.outputFile));
}
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import keycode from 'keycode';

import icBEM from '../utils/icBEM';
import prefixClass from '../utils/prefixClass';
import getComponentName from '../utils/getComponentName';

import '../styles/Closable.scss';

export const COMPONENT_NAME = prefixClass('closable');
const ROOT_BEM = icBEM(COMPONENT_NAME);

const ESCAPE = 'Escape';

/**
 * `closable()` HOC mixin
 * ====================
 * Provide various of ways to determine when to “close” a component by
 * binding event listeners on `document`.
 *
 * Formerlly `escapable()`.
 */
const closable = ({
    onEscape = true,
    onClickOutside = false,
    onClickInside = false,
    stopEventPropagation = true,
} = {}) => (WrappedComponent) => {
    const componentName = getComponentName(WrappedComponent);

    const mixinConfigs = {
        onEscape,
        onClickOutside,
        onClickInside,
        stopEventPropagation,
    };

    class Closable extends PureComponent {
        static displayName = `closable(${componentName})`;

        static propTypes = {
            onClose: PropTypes.func,
            closable: PropTypes.shape({
                onEscape: PropTypes.bool,
                onClickOutside: PropTypes.bool,
                onClickInside: PropTypes.bool,
                stopEventPropagation: PropTypes.bool,
            }),
        };

        static defaultProps = {
            onClose: () => {},
            closable: mixinConfigs,
        };

        constructor(props) {
            super(props);
            this.clickedInside = false;
        }

        componentDidMount() {
            document.addEventListener('keyup', this.handleDocumentKeyup);
        }

        componentWillUnmount() {
            document.removeEventListener('keyup', this.handleDocumentKeyup);
        }

        getOptions() {
            const { closable: runtimeOptions } = this.props;

            /** @type {typeof mixinDefaults} */
            const actualOptions = {
                ...mixinConfigs,
                ...runtimeOptions,
            };

            return actualOptions;
        }

        /**
         * @param {KeyboardEvent} event
         */
        handleDocumentKeyup = (event) => {
            const options = this.getOptions();

            if (options.onEscape && event.keyCode === keycode(ESCAPE)) {
                this.props.onClose(event);
            }
        }

        /**
         * @param {React.MouseEvent} event
         */
        handleOuterLayerClick = (event) => {
            const options = this.getOptions();

            if (options.stopEventPropagation) {
                event.stopPropagation();
            }

            if (this.clickedInside) {
                // ignoring click events bubbling up from inside
                this.clickedInside = false;
                return;
            }

            if (options.onClickOutside) {
                this.props.onClose(event);
            }
        }

        /**
         * @param {React.MouseEvent} event
         */
        handleInsideClick = (event) => {
            const options = this.getOptions();
            this.clickedInside = true;

            if (options.onClickInside) {
                this.props.onClose(event);
            }
        }

        render() {
            const {
                onClose,
                closable: runtimeOptions,
                ...otherProps
            } = this.props;

            return (
                <div
                    role="presentation"
                    className={ROOT_BEM.toString()}
                    onClick={this.handleOuterLayerClick}>
                    <WrappedComponent
                        onInsideClick={this.handleInsideClick}
                        {...otherProps} />
                </div>
            );
        }
    }

    return Closable;
};

export default closable;
<commit_msg>Fix anchored popover top position when document is scrollable<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import keycode from 'keycode';

import icBEM from '../utils/icBEM';
import prefixClass from '../utils/prefixClass';
import getComponentName from '../utils/getComponentName';

import '../styles/Closable.scss';

export const COMPONENT_NAME = prefixClass('closable');
const ROOT_BEM = icBEM(COMPONENT_NAME);

const ESCAPE = 'Escape';

/**
 * `closable()` HOC mixin
 * ====================
 * Provide various of ways to determine when to “close” a component by
 * binding event listeners on `document`.
 *
 * Formerlly `escapable()`.
 */
const closable = ({
    onEscape = true,
    onClickOutside = false,
    onClickInside = false,
    stopEventPropagation = true,
} = {}) => (WrappedComponent) => {
    const componentName = getComponentName(WrappedComponent);

    const mixinConfigs = {
        onEscape,
        onClickOutside,
        onClickInside,
        stopEventPropagation,
    };

    class Closable extends PureComponent {
        static displayName = `closable(${componentName})`;

        static propTypes = {
            onClose: PropTypes.func,
            closable: PropTypes.shape({
                onEscape: PropTypes.bool,
                onClickOutside: PropTypes.bool,
                onClickInside: PropTypes.bool,
                stopEventPropagation: PropTypes.bool,
            }),
        };

        static defaultProps = {
            onClose: () => {},
            closable: mixinConfigs,
        };

        constructor(props) {
            super(props);
            this.clickedInside = false;
        }

        componentDidMount() {
            document.addEventListener('keyup', this.handleDocumentKeyup);
        }

        componentWillUnmount() {
            document.removeEventListener('keyup', this.handleDocumentKeyup);
        }

        getOptions() {
            const { closable: runtimeOptions } = this.props;

            /** @type {typeof mixinDefaults} */
            const actualOptions = {
                ...mixinConfigs,
                ...runtimeOptions,
            };

            return actualOptions;
        }

        /**
         * @param {KeyboardEvent} event
         */
        handleDocumentKeyup = (event) => {
            const options = this.getOptions();

            if (options.onEscape && event.keyCode === keycode(ESCAPE)) {
                this.props.onClose(event);
            }
        }

        /**
         * @param {React.MouseEvent} event
         */
        handleOuterLayerClick = (event) => {
            const options = this.getOptions();

            if (options.stopEventPropagation) {
                event.stopPropagation();
            }

            if (this.clickedInside) {
                // ignoring click events bubbling up from inside
                this.clickedInside = false;
                return;
            }

            if (options.onClickOutside) {
                this.props.onClose(event);
            }
        }

        /**
         * @param {React.MouseEvent} event
         */
        handleInsideClick = (event) => {
            const options = this.getOptions();
            this.clickedInside = true;

            if (options.onClickInside) {
                this.props.onClose(event);
            }
        }

        render() {
            const {
                onClose,
                closable: runtimeOptions,
                ...otherProps
            } = this.props;

            return (
                <>
                    <div
                        role="presentation"
                        className={ROOT_BEM.toString()}
                        onClick={this.handleOuterLayerClick}
                    />
                    <WrappedComponent
                        onInsideClick={this.handleInsideClick}
                        {...otherProps}
                    />
                </>
            );
        }
    }

    return Closable;
};

export default closable;
<|endoftext|>


<commit_before>var request = require('request');
// request.debug=true;
var urls = require("./urls");
var fs = require("fs");
var authentication = require("./authentication");
var randomip = require("random-ip");

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

// Schemas
var Account = require("../db/schemas/account").Account;
var Skin = require("../db/schemas/skin").Skin;
var Traffic = require("../db/schemas/traffic").Traffic;

module.exports = {};

module.exports.findExistingSkin = function (hash, name, model, visibility, cb) {
    Skin.findOne({hash: hash, name: name, model: model, visibility: visibility}).exec(function (err, skin) {
        if (err) return console.log(err);
        if (skin) {
            console.log("Found existing skin with same hash");
            skin.duplicate += 1;
            skin.save(function (err, skin) {
                if (err) return console.log(err);
                cb(skin);
            })
        } else {
            cb();
        }
    })
};

module.exports.findExistingSkinForTextureUrl = function (url, name, model, visibility, cb) {
    Skin.findOne({url:url, name: name, model: model, visibility: visibility}).exec(function (err, skin) {
        if (err) return console.log(err);
        if (skin) {
            console.log("Found existing skin with same texture url");
            skin.duplicate += 1;
            skin.save(function (err, skin) {
                if (err) return console.log(err);
                cb(skin);
            })
        } else {
            cb();
        }
    })
};

module.exports.getAvailableAccount = function (req, res, cb) {
    var time = Date.now() / 1000;
    Account.findOne({enabled: true, requestServer: {$in: [null, "default", config.server]}, lastUsed: {'$lt': (time - 60)}, forcedTimeoutAt: {'$lt': (time - 120)}, errorCounter: {'$lt': (config.errorThreshold||10)}}).sort({lastUsed: 1, lastSelected: 1}).exec(function (err, account) {
        if (err) return console.log(err);
        if (!account) {
            console.log(("[SkinChanger] There are no accounts available!").error);
            res.status(500).json({error: "No accounts available"});
        } else {
            // if (time - account.lastUsed > 3600) {// Reset tokens after 30 minutes
            //     account.accessToken = null;
            //     // account.clientToken = null;
            // }
            console.log("Account #"+account.id+" last used "+Math.round(time-account.lastUsed)+"s ago, last selected "+Math.round(time-account.lastSelected)+"s ago")
            account.lastUsed = account.lastSelected = time;
            account.save(function (err, account) {
                cb(account);
            });
        }
    })
}

module.exports.generateUrl = function (account, url, model, cb) {
    console.log(("[SkinChanger] Generating Skin from URL").info);
    console.log(("" + url).debug);

    if (!account.requestIp)
        account.requestIp = randomip('0.0.0.0', 0);
    console.log(("Using ip " + account.requestIp).debug);

    authentication.authenticate(account, function (authErr, authResult) {
        if (!authErr && authResult) {
            authentication.completeChallenges(account, function (result, errorBody) {
                if (result) {
                    account.lastUsed = account.lastSelected;// account *should* be saved in the following code, so there shouldn't be any need to make another call here

                    request({
                        method: "POST",
                        url: urls.skin.replace(":uuid", account.uuid),
                        headers: {
                            "User-Agent": "MineSkin.org",
                            "Content-Type": "application/x-www-form-urlencoded",
                            "Authorization": "Bearer " + account.accessToken,
                            "X-Forwarded-For": account.requestIp,
                            "REMOTE_ADDR": account.requestIp
                        },
                        form: {
                            model: model,
                            url: url
                        }
                    }, function (err, response, body) {
                        if (err) return console.log(err);
                        console.log(("" + body).debug);
                        if (response.statusCode >= 200 && response.statusCode < 300) {
                            cb(true);
                        } else {
                            cb(response.statusCode, "generate_rescode_" + response.statusCode);
                            console.log(("Got response " + response.statusCode + " for generateUrl").warn);
                        }
                    })
                } else {
                    account.successCounter = 0;
                    account.errorCounter++;
                    account.save(function (err, account) {
                        cb("Challenges failed", authErrorCauseFromMessage(errorBody.errorMessage || errorBody) || "challenges_failed");
                    });
                }
            })
        } else {
            account.successCounter = 0;
            account.errorCounter++;
            account.forcedTimeoutAt = Date.now() / 1000;
            account.save(function (err, account) {
                cb("Authentication failed - " + (authErr.errorMessage || "unknown error"), authErrorCauseFromMessage(authErr.errorMessage || authErr));
            });
        }
    })
};

// 'fileBuf' must be a buffer
module.exports.generateUpload = function (account, fileBuf, model, cb) {
    console.log(("[SkinChanger] Generating Skin from Upload").info);

    if (!account.requestIp)
        account.requestIp = randomip('0.0.0.0', 0);
    console.log(("Using ip " + account.requestIp).debug);

    authentication.authenticate(account, function (authErr, authResult) {
        if (!authErr && authResult) {
            authentication.completeChallenges(account, function (result, errorBody) {
                if (result) {
                    account.lastUsed = account.lastSelected;// account *should* be saved in the following code, so there shouldn't be any need to make another call here

                    request({
                        method: "PUT",
                        url: urls.skin.replace(":uuid", account.uuid),
                        headers: {
                            "User-Agent": "MineSkin.org",
                            "Content-Type": "multipart/form-data",
                            "Authorization": "Bearer " + account.accessToken,
                            "X-Forwarded-For": account.requestIp,
                            "REMOTE_ADDR": account.requestIp
                        },
                        formData: {
                            model: model,
                            file: {
                                value: fileBuf,
                                options: {
                                    filename: "skin.png",
                                    contentType: "image/png"
                                }
                            }
                        }
                    }, function (err, response, body) {
                        if (err) return console.log(err);
                        console.log(("" + body).debug);
                        if (response.statusCode >= 200 && response.statusCode < 300) {
                            cb(true);
                        } else {
                            cb(response.statusCode, "generate_rescode_" + response.statusCode);
                            console.log(("Got response " + response.statusCode + " for generateUpload").warn);
                        }
                    });
                } else {
                    account.successCounter = 0;
                    account.errorCounter++;
                    account.save(function (err, account) {
                        console.log(("Challenges failed").warn);
                        cb("Challenges failed", authErrorCauseFromMessage(errorBody.errorMessage || errorBody)||"challenges_failed");
                    });
                }
            })
        } else {
            account.successCounter = 0;
            account.errorCounter++;
            account.forcedTimeoutAt = Date.now() / 1000;
            account.save(function (err, account) {
                cb("Authentication failed - " + (authErr.errorMessage || "unknown error"), authErrorCauseFromMessage(authErr.errorMessage || authErr));
            });
        }
    })
};

function authErrorCauseFromMessage(msg) {
    if (msg && msg.length > 0) {
        if (msg.indexOf("Invalid credentials") !== -1) {
            return "invalid_credentials";
        }
        if (msg.indexOf("answer was incorrect") !== -1) {
            return "wrong_security_answers";
        }
        if (msg.indexOf("cloudfront") !== -1) {
            if (msg.indexOf("403 ERROR") !== -1) {
                return "cloudfront_unauthorized";
            }
            return "cloudfront_error";
        }
    }
}

<commit_msg>log responses<commit_after>var request = require('request');
// request.debug=true;
var urls = require("./urls");
var fs = require("fs");
var authentication = require("./authentication");
var randomip = require("random-ip");

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

// Schemas
var Account = require("../db/schemas/account").Account;
var Skin = require("../db/schemas/skin").Skin;
var Traffic = require("../db/schemas/traffic").Traffic;

module.exports = {};

module.exports.findExistingSkin = function (hash, name, model, visibility, cb) {
    Skin.findOne({hash: hash, name: name, model: model, visibility: visibility}).exec(function (err, skin) {
        if (err) return console.log(err);
        if (skin) {
            console.log("Found existing skin with same hash");
            skin.duplicate += 1;
            skin.save(function (err, skin) {
                if (err) return console.log(err);
                cb(skin);
            })
        } else {
            cb();
        }
    })
};

module.exports.findExistingSkinForTextureUrl = function (url, name, model, visibility, cb) {
    Skin.findOne({url:url, name: name, model: model, visibility: visibility}).exec(function (err, skin) {
        if (err) return console.log(err);
        if (skin) {
            console.log("Found existing skin with same texture url");
            skin.duplicate += 1;
            skin.save(function (err, skin) {
                if (err) return console.log(err);
                cb(skin);
            })
        } else {
            cb();
        }
    })
};

module.exports.getAvailableAccount = function (req, res, cb) {
    var time = Date.now() / 1000;
    Account.findOne({enabled: true, requestServer: {$in: [null, "default", config.server]}, lastUsed: {'$lt': (time - 60)}, forcedTimeoutAt: {'$lt': (time - 120)}, errorCounter: {'$lt': (config.errorThreshold||10)}}).sort({lastUsed: 1, lastSelected: 1}).exec(function (err, account) {
        if (err) return console.log(err);
        if (!account) {
            console.log(("[SkinChanger] There are no accounts available!").error);
            res.status(500).json({error: "No accounts available"});
        } else {
            // if (time - account.lastUsed > 3600) {// Reset tokens after 30 minutes
            //     account.accessToken = null;
            //     // account.clientToken = null;
            // }
            console.log("Account #"+account.id+" last used "+Math.round(time-account.lastUsed)+"s ago, last selected "+Math.round(time-account.lastSelected)+"s ago")
            account.lastUsed = account.lastSelected = time;
            account.save(function (err, account) {
                cb(account);
            });
        }
    })
}

module.exports.generateUrl = function (account, url, model, cb) {
    console.log(("[SkinChanger] Generating Skin from URL").info);
    console.log(("" + url).debug);

    if (!account.requestIp)
        account.requestIp = randomip('0.0.0.0', 0);
    console.log(("Using ip " + account.requestIp).debug);

    authentication.authenticate(account, function (authErr, authResult) {
        if (!authErr && authResult) {
            authentication.completeChallenges(account, function (result, errorBody) {
                if (result) {
                    account.lastUsed = account.lastSelected;// account *should* be saved in the following code, so there shouldn't be any need to make another call here

                    request({
                        method: "POST",
                        url: urls.skin.replace(":uuid", account.uuid),
                        headers: {
                            "User-Agent": "MineSkin.org",
                            "Content-Type": "application/x-www-form-urlencoded",
                            "Authorization": "Bearer " + account.accessToken,
                            "X-Forwarded-For": account.requestIp,
                            "REMOTE_ADDR": account.requestIp
                        },
                        form: {
                            model: model,
                            url: url
                        }
                    }, function (err, response, body) {
                        if (err) return console.log(err);
                        console.log(("Url response (acc#"+account.id+"): "+response.statusCode+" " + body).debug);
                        if (response.statusCode >= 200 && response.statusCode < 300) {
                            cb(true);
                        } else {
                            cb(response.statusCode, "generate_rescode_" + response.statusCode);
                            console.log(("Got response " + response.statusCode + " for generateUrl").warn);
                        }
                    })
                } else {
                    account.successCounter = 0;
                    account.errorCounter++;
                    account.save(function (err, account) {
                        cb("Challenges failed", authErrorCauseFromMessage(errorBody.errorMessage || errorBody) || "challenges_failed");
                    });
                }
            })
        } else {
            account.successCounter = 0;
            account.errorCounter++;
            account.forcedTimeoutAt = Date.now() / 1000;
            account.save(function (err, account) {
                cb("Authentication failed - " + (authErr.errorMessage || "unknown error"), authErrorCauseFromMessage(authErr.errorMessage || authErr));
            });
        }
    })
};

// 'fileBuf' must be a buffer
module.exports.generateUpload = function (account, fileBuf, model, cb) {
    console.log(("[SkinChanger] Generating Skin from Upload").info);

    if (!account.requestIp)
        account.requestIp = randomip('0.0.0.0', 0);
    console.log(("Using ip " + account.requestIp).debug);

    authentication.authenticate(account, function (authErr, authResult) {
        if (!authErr && authResult) {
            authentication.completeChallenges(account, function (result, errorBody) {
                if (result) {
                    account.lastUsed = account.lastSelected;// account *should* be saved in the following code, so there shouldn't be any need to make another call here

                    request({
                        method: "PUT",
                        url: urls.skin.replace(":uuid", account.uuid),
                        headers: {
                            "User-Agent": "MineSkin.org",
                            "Content-Type": "multipart/form-data",
                            "Authorization": "Bearer " + account.accessToken,
                            "X-Forwarded-For": account.requestIp,
                            "REMOTE_ADDR": account.requestIp
                        },
                        formData: {
                            model: model,
                            file: {
                                value: fileBuf,
                                options: {
                                    filename: "skin.png",
                                    contentType: "image/png"
                                }
                            }
                        }
                    }, function (err, response, body) {
                        if (err) return console.log(err);
                        console.log(("Upload response (acc#"+account.id+"): "+response.statusCode+" " + body).debug);
                        if (response.statusCode >= 200 && response.statusCode < 300) {
                            cb(true);
                        } else {
                            cb(response.statusCode, "generate_rescode_" + response.statusCode);
                            console.log(("Got response " + response.statusCode + " for generateUpload").warn);
                        }
                    });
                } else {
                    account.successCounter = 0;
                    account.errorCounter++;
                    account.save(function (err, account) {
                        console.log(("Challenges failed").warn);
                        cb("Challenges failed", authErrorCauseFromMessage(errorBody.errorMessage || errorBody)||"challenges_failed");
                    });
                }
            })
        } else {
            account.successCounter = 0;
            account.errorCounter++;
            account.forcedTimeoutAt = Date.now() / 1000;
            account.save(function (err, account) {
                cb("Authentication failed - " + (authErr.errorMessage || "unknown error"), authErrorCauseFromMessage(authErr.errorMessage || authErr));
            });
        }
    })
};

function authErrorCauseFromMessage(msg) {
    if (msg && msg.length > 0) {
        if (msg.indexOf("Invalid credentials") !== -1) {
            return "invalid_credentials";
        }
        if (msg.indexOf("answer was incorrect") !== -1) {
            return "wrong_security_answers";
        }
        if (msg.indexOf("cloudfront") !== -1) {
            if (msg.indexOf("403 ERROR") !== -1) {
                return "cloudfront_unauthorized";
            }
            return "cloudfront_error";
        }
    }
}

<|endoftext|>


<commit_before>'use strict';
var generators = require('yeoman-generator');
var path = require('path');
var _ = require('lodash');
var extend = _.merge;
var message = require('../message');

module.exports = generators.Base.extend({
  constructor: function () {
    generators.Base.apply(this, arguments);

    this.option('generateInto', {
      type: String,
      required: false,
      defaults: '',
      desc: message.generateInto
    });

    this.option('name', {
      type: String,
      required: true,
      desc: message.name
    });

    this.option('browser', {
      type: Boolean,
      required: true,
      defaults: true,
      desc: message.browser
    });

    this.option('styles', {
      type: Boolean,
      required: true,
      defaults: false,
      desc: message.styles
    });

    this.option('scss', {
      type: Boolean,
      required: true,
      defaults: true,
      desc: message.scss
    });

    this.option('bower', {
      type: Boolean,
      required: true,
      defaults: true,
      desc: message.browser
    });

    this.option('testFramework', {
      type: String,
      required: true,
      defaults: 'jasmine',
      desc: message.testFramework
    });
  },

  writing: {
    package: function () {
      var pkg = this.fs.readJSON(this.destinationPath(this.options.generateInto, 'package.json'), {});

      extend(pkg, {
        dependencies: {
          'lodash': '4.8.2'
        },
        devDependencies: {
          'del': '2.0.2',
          'gulp': '3.9.1',
          'gulp-bump': '2.1.0',
          'gulp-concat': '2.6.0',
          'gulp-filter': '4.0.0',
          'gulp-git': '1.7.1',
          'gulp-help': '1.6.0',
          'gulp-jshint': '2.0.0',
          'gulp-load-plugins': '1.0.0-rc.1',
          "gulp-nsp": "2.4.0",
          'gulp-sourcemaps': '1.6.0',
          'gulp-streamify': '1.0.2',
          'gulp-tag-version': '1.3.0',
          'gulp-tsc': '1.1.5',
          'gulp-tsconfig-files': '0.0.2',
          'gulp-tslint': '3.1',
          'gulp-typedoc': '1.2.1',
          'gulp-typescript': '2.12.2',
          'gulp-typings': '1.3.4',
          'gulp-uglify': '1.2.0',
          'gulp-util': '3.0.7',
          'jshint': '2.9.1',
          'jshint-stylish': '2.1.0',
          'path': '0.12.7',
          'remap-istanbul': '0.5.1',
          'require-dir': '0.3.0',
          'run-sequence': '1.1.5',
          'tsify': '0.14.1',
          'typescript': '1.8.7',
          'vinyl-source-stream': '1.1.0',
          'watchify': '3.7.0'
        },
        scripts: {
          'typings-install': 'gulp typings-install',
          'test': 'gulp test',
          'watch': 'gulp watch',
          'clean': 'gulp clean-build',
          'build': 'gulp build',
          'coverage': 'gulp coverage',
          'doc': 'gulp typedoc',
          'patch': 'gulp build && gulp patch',
          'feature': 'gulp build && gulp feature',
          'release': 'gulp build && gulp release',
          'prepublish': 'npm run build'
        }
      });

      if (this.options.browser) {
        pkg.devDependencies['browserify'] = '13.0.0';
        pkg.devDependencies['browserify-istanbul'] = '2.0.0';
        pkg.devDependencies['karma'] = '0.13.22';
        pkg.devDependencies['karma-browserify'] = '5.0.3';
        pkg.devDependencies['karma-chrome-launcher'] = '0.2.2';
        pkg.devDependencies['karma-coverage'] = '0.5.5';
        pkg.devDependencies['karma-phantomjs-launcher'] = '1.0.0';
        pkg.devDependencies['karma-remap-istanbul'] = '0.0.5';
        pkg.devDependencies['phantomjs-prebuilt'] = '2.1.7';

        pkg.scripts['dev-test'] = 'gulp dev-test';

        switch (this.options.testFramework) {
          case 'jasmine':
            pkg.devDependencies['jasmine'] = '2.3.1';
            pkg.devDependencies['jasmine-ajax'] = '3.2.0';
            pkg.devDependencies['jasmine-core'] = '2.4.1';
            pkg.devDependencies['karma-jasmine'] = '0.3.7';
            break;
          case 'mocha':
            pkg.devDependencies['chai'] = '3.5.0';
            pkg.devDependencies['karma-mocha'] = '0.2.2';
            pkg.devDependencies['mocha'] = '2.4.5';
            break;
        }

        if (this.options.styles) {
          pkg.devDependencies['gulp-concat'] = '2.6.0';
          pkg.devDependencies['gulp-cssmin'] = '0.1.7';
        }

        if (this.options.browser) {
          pkg.devDependencies['gulp-inject'] = '4.0.0';
          pkg.devDependencies['gulp-notify'] = '2.2.0';
          pkg.devDependencies['gulp-size'] = '2.1.0';
          pkg.devDependencies['gulp-rename'] = '1.2.2';
        }

        if (this.options.styles && this.options.scss) {
          pkg.devDependencies['gulp-scss'] = '1.3.17';
          pkg.devDependencies['gulp-scss-lint'] = '0.3.9';
          pkg.devDependencies['gulp-scss-lint-stylish'] = '1.0.1';
        }

        if (this.options.styles && !this.options.scss) {
          pkg.devDependencies['gulp-csslint'] = '0.3.0';
        }
      } else {
        pkg.devDependencies['chai'] = '3.5.0';
        pkg.devDependencies['karma-mocha'] = '0.2.2';
        pkg.devDependencies['mocha'] = '2.4.5';
        pkg.devDependencies['gulp-istanbul'] = '0.10.3';
        pkg.devDependencies['gulp-mocha'] = '2.2.0';
        pkg.devDependencies['gulp-plumber'] = '1.0.0';
      }

      this.fs.writeJSON(this.destinationPath(this.options.generateInto, 'package.json'), pkg);
    },

    gulpfile: function () {
      this.fs.copy(
        this.templatePath('gulpfile.js'),
        this.destinationPath(this.options.generateInto, 'gulpfile.js')
      );

      this.fs.copy(
        this.templatePath('build.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'build.js')
      );

      this.fs.copyTpl(
        this.templatePath('clean.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'clean.js'),
        {
          bower: this.options.browser && this.options.bower,
          styles: this.options.browser && this.options.styles
        }
      );

      this.fs.copyTpl(
        this.templatePath('conf.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'conf.js'),
        {
          projectName: this.options.name,
          bower: this.options.browser && this.options.bower,
          styles: this.options.browser && this.options.styles,
          scss: this.options.browser && this.options.styles && this.options.scss,
          browser: this.options.browser
        }
      );

      if (this.options.styles) {
        this.fs.copyTpl(
          this.templatePath('copy.js'),
          this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'copy.js'),
          {
            bower: this.options.browser && this.options.bower
          }
        );
      }

      if (this.options.browser && (this.options.styles || this.options.bower)) {
        this.fs.copyTpl(
          this.templatePath('inject.js'),
          this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'inject.js'),
          {
            bower: this.options.browser && this.options.bower,
            styles: this.options.browser && this.options.styles && this.options.styles
          }
        );
      }

      this.fs.copyTpl(
        this.templatePath('lint.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'lint.js'),
        {
          browser: this.options.browser
        }
      );

      if (this.options.browser && this.options.styles && this.options.scss) {
        this.fs.copy(
          this.templatePath('scss.js'),
          this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'scss.js')
        );
      }

      if (this.options.browser && this.options.styles && !this.options.scss) {
        this.fs.copy(
          this.templatePath('css.js'),
          this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'css.js')
        );
      }

      this.fs.copyTpl(
        this.templatePath('scripts.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'scripts.js'),
        {
          bower: this.options.browser && this.options.bower,
          styles: this.options.browser && this.options.styles,
          scss: this.options.browser && this.options.styles && this.options.scss
        }
      );

      this.fs.copyTpl(
        this.templatePath('tests.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'tests.js'),
        {
          browser: this.options.browser
        }
      );

      this.fs.copy(
        this.templatePath('tsconfig.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'tsconfig.js')
      );

      this.fs.copy(
        this.templatePath('tsdocs.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'tsdocs.js')
      );

      this.fs.copyTpl(
        this.templatePath('version.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'version.js'),
        {
          bower: this.options.browser && this.options.bower
        }
      );

      this.fs.copyTpl(
        this.templatePath('watch.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'watch.js'),
        {
          styles: this.options.browser && this.options.styles,
          scss: this.options.browser && this.options.scss,
          browser: this.options.browser
        }
      );
    }
  }
});
<commit_msg>Added tsconfig.json update command to index.js in gulp folder.<commit_after>'use strict';
var generators = require('yeoman-generator');
var path = require('path');
var _ = require('lodash');
var extend = _.merge;
var message = require('../message');

module.exports = generators.Base.extend({
  constructor: function () {
    generators.Base.apply(this, arguments);

    this.option('generateInto', {
      type: String,
      required: false,
      defaults: '',
      desc: message.generateInto
    });

    this.option('name', {
      type: String,
      required: true,
      desc: message.name
    });

    this.option('browser', {
      type: Boolean,
      required: true,
      defaults: true,
      desc: message.browser
    });

    this.option('styles', {
      type: Boolean,
      required: true,
      defaults: false,
      desc: message.styles
    });

    this.option('scss', {
      type: Boolean,
      required: true,
      defaults: true,
      desc: message.scss
    });

    this.option('bower', {
      type: Boolean,
      required: true,
      defaults: true,
      desc: message.browser
    });

    this.option('testFramework', {
      type: String,
      required: true,
      defaults: 'jasmine',
      desc: message.testFramework
    });
  },

  writing: {
    package: function () {
      var pkg = this.fs.readJSON(this.destinationPath(this.options.generateInto, 'package.json'), {});

      extend(pkg, {
        dependencies: {
          'lodash': '4.8.2'
        },
        devDependencies: {
          'del': '2.0.2',
          'gulp': '3.9.1',
          'gulp-bump': '2.1.0',
          'gulp-concat': '2.6.0',
          'gulp-filter': '4.0.0',
          'gulp-git': '1.7.1',
          'gulp-help': '1.6.0',
          'gulp-jshint': '2.0.0',
          'gulp-load-plugins': '1.0.0-rc.1',
          "gulp-nsp": "2.4.0",
          'gulp-sourcemaps': '1.6.0',
          'gulp-streamify': '1.0.2',
          'gulp-tag-version': '1.3.0',
          'gulp-tsc': '1.1.5',
          'gulp-tsconfig-files': '0.0.2',
          'gulp-tslint': '3.1',
          'gulp-typedoc': '1.2.1',
          'gulp-typescript': '2.12.2',
          'gulp-typings': '1.3.4',
          'gulp-uglify': '1.2.0',
          'gulp-util': '3.0.7',
          'jshint': '2.9.1',
          'jshint-stylish': '2.1.0',
          'path': '0.12.7',
          'remap-istanbul': '0.5.1',
          'require-dir': '0.3.0',
          'run-sequence': '1.1.5',
          'tsify': '0.14.1',
          'typescript': '1.8.7',
          'vinyl-source-stream': '1.1.0',
          'watchify': '3.7.0'
        },
        scripts: {
          'typings-install': 'gulp typings-install',
          'test': 'gulp test',
          'watch': 'gulp watch',
          'clean': 'gulp clean-build',
          'build': 'gulp build',
          'coverage': 'gulp coverage',
          'doc': 'gulp typedoc',
          'tsconfig-update':'gulp tsconfig-update',
          'patch': 'gulp build && gulp patch',
          'feature': 'gulp build && gulp feature',
          'release': 'gulp build && gulp release',
          'prepublish': 'npm run build'
        }
      });

      if (this.options.browser) {
        pkg.devDependencies['browserify'] = '13.0.0';
        pkg.devDependencies['browserify-istanbul'] = '2.0.0';
        pkg.devDependencies['karma'] = '0.13.22';
        pkg.devDependencies['karma-browserify'] = '5.0.3';
        pkg.devDependencies['karma-chrome-launcher'] = '0.2.2';
        pkg.devDependencies['karma-coverage'] = '0.5.5';
        pkg.devDependencies['karma-phantomjs-launcher'] = '1.0.0';
        pkg.devDependencies['karma-remap-istanbul'] = '0.0.5';
        pkg.devDependencies['phantomjs-prebuilt'] = '2.1.7';

        pkg.scripts['dev-test'] = 'gulp dev-test';

        switch (this.options.testFramework) {
          case 'jasmine':
            pkg.devDependencies['jasmine'] = '2.3.1';
            pkg.devDependencies['jasmine-ajax'] = '3.2.0';
            pkg.devDependencies['jasmine-core'] = '2.4.1';
            pkg.devDependencies['karma-jasmine'] = '0.3.7';
            break;
          case 'mocha':
            pkg.devDependencies['chai'] = '3.5.0';
            pkg.devDependencies['karma-mocha'] = '0.2.2';
            pkg.devDependencies['mocha'] = '2.4.5';
            break;
        }

        if (this.options.styles) {
          pkg.devDependencies['gulp-concat'] = '2.6.0';
          pkg.devDependencies['gulp-cssmin'] = '0.1.7';
        }

        if (this.options.browser) {
          pkg.devDependencies['gulp-inject'] = '4.0.0';
          pkg.devDependencies['gulp-notify'] = '2.2.0';
          pkg.devDependencies['gulp-size'] = '2.1.0';
          pkg.devDependencies['gulp-rename'] = '1.2.2';
        }

        if (this.options.styles && this.options.scss) {
          pkg.devDependencies['gulp-scss'] = '1.3.17';
          pkg.devDependencies['gulp-scss-lint'] = '0.3.9';
          pkg.devDependencies['gulp-scss-lint-stylish'] = '1.0.1';
        }

        if (this.options.styles && !this.options.scss) {
          pkg.devDependencies['gulp-csslint'] = '0.3.0';
        }
      } else {
        pkg.devDependencies['chai'] = '3.5.0';
        pkg.devDependencies['karma-mocha'] = '0.2.2';
        pkg.devDependencies['mocha'] = '2.4.5';
        pkg.devDependencies['gulp-istanbul'] = '0.10.3';
        pkg.devDependencies['gulp-mocha'] = '2.2.0';
        pkg.devDependencies['gulp-plumber'] = '1.0.0';
      }

      this.fs.writeJSON(this.destinationPath(this.options.generateInto, 'package.json'), pkg);
    },

    gulpfile: function () {
      this.fs.copy(
        this.templatePath('gulpfile.js'),
        this.destinationPath(this.options.generateInto, 'gulpfile.js')
      );

      this.fs.copy(
        this.templatePath('build.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'build.js')
      );

      this.fs.copyTpl(
        this.templatePath('clean.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'clean.js'),
        {
          bower: this.options.browser && this.options.bower,
          styles: this.options.browser && this.options.styles
        }
      );

      this.fs.copyTpl(
        this.templatePath('conf.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'conf.js'),
        {
          projectName: this.options.name,
          bower: this.options.browser && this.options.bower,
          styles: this.options.browser && this.options.styles,
          scss: this.options.browser && this.options.styles && this.options.scss,
          browser: this.options.browser
        }
      );

      if (this.options.styles) {
        this.fs.copyTpl(
          this.templatePath('copy.js'),
          this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'copy.js'),
          {
            bower: this.options.browser && this.options.bower
          }
        );
      }

      if (this.options.browser && (this.options.styles || this.options.bower)) {
        this.fs.copyTpl(
          this.templatePath('inject.js'),
          this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'inject.js'),
          {
            bower: this.options.browser && this.options.bower,
            styles: this.options.browser && this.options.styles && this.options.styles
          }
        );
      }

      this.fs.copyTpl(
        this.templatePath('lint.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'lint.js'),
        {
          browser: this.options.browser
        }
      );

      if (this.options.browser && this.options.styles && this.options.scss) {
        this.fs.copy(
          this.templatePath('scss.js'),
          this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'scss.js')
        );
      }

      if (this.options.browser && this.options.styles && !this.options.scss) {
        this.fs.copy(
          this.templatePath('css.js'),
          this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'css.js')
        );
      }

      this.fs.copyTpl(
        this.templatePath('scripts.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'scripts.js'),
        {
          bower: this.options.browser && this.options.bower,
          styles: this.options.browser && this.options.styles,
          scss: this.options.browser && this.options.styles && this.options.scss
        }
      );

      this.fs.copyTpl(
        this.templatePath('tests.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'tests.js'),
        {
          browser: this.options.browser
        }
      );

      this.fs.copy(
        this.templatePath('tsconfig.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'tsconfig.js')
      );

      this.fs.copy(
        this.templatePath('tsdocs.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'tsdocs.js')
      );

      this.fs.copyTpl(
        this.templatePath('version.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'version.js'),
        {
          bower: this.options.browser && this.options.bower
        }
      );

      this.fs.copyTpl(
        this.templatePath('watch.js'),
        this.destinationPath(path.join(this.options.generateInto, 'gulp'), 'watch.js'),
        {
          styles: this.options.browser && this.options.styles,
          scss: this.options.browser && this.options.scss,
          browser: this.options.browser
        }
      );
    }
  }
});
<|endoftext|>


<commit_before>var webdriver = require('selenium-webdriver'),
    By = webdriver.By;
var webdriverRemote = require('selenium-webdriver/remote');
var sprintf = require('sprintf-js').sprintf;
var config = require('./config.js');

var seleniumServerUrl = 'http://%s:%s/wd/hub';

const PLATFORM  = {
    CHROME: 'CHROME',
    FIREFOX: 'FIREFOX'
};

var buildDriver = function(platform) {
    var capabilities;

    if(platform === PLATFORM.CHROME) {
        capabilities = webdriver.Capabilities.chrome();
    } else if(platform === PLATFORM.FIREFOX) {
        capabilities = webdriver.Capabilities.firefox();
    }

    var logPreferences = new webdriver.logging.Preferences();
    logPreferences.setLevel('driver', config.seleniumDriverLogLevel);
    logPreferences.setLevel('browser', config.seleniumBrowserLogLevel);

    var seleniumProxy = require('selenium-webdriver/proxy');
    var proxyUrl = config.proxyHost + ':' + config.proxyHttpPort;

    return new webdriver.Builder()
    .usingServer(sprintf(seleniumServerUrl, config.seleniumServerHost, config.seleniumServerPort))
    .withCapabilities(capabilities)
    .setLoggingPrefs(logPreferences)
    .setProxy(seleniumProxy.manual({
        http: proxyUrl
    }))
    .build();
};

var loadDriverOptions = function(driver) {
    if(config.runMaximized) {
    driver.manage().window().maximize();
    }

    if(config.xvfbMode) {
    driver.manage().window().setSize(config.xvfbSettings.windowWidth, config.xvfbSettings.windowHeight);
    }

    driver.setFileDetector(new webdriverRemote.FileDetector);
};

//building driver
var driver = buildDriver(config.platform);
loadDriverOptions(driver);

//methods
var loadPage = function(page) {
    return driver.get(page);
};

var getDocumentReatyState = function() {
    return driver.executeScript(
        'return document.readyState === \'complete\'',
        ''
    ).then(function(result) {
        return result;
    });
};

var validatePageReadyState = function() {
    //TODO: code style
    return driver.wait(function() {
        return getDocumentReatyState()
            .then(function(value) {
                return value;
            },
            function() {
                return getDocumentReatyState()
                    .then(function(value) {
                        return value;
                    });
            });
    }, defaultTimeout);
};

var waitForElement = function(xpath, customTimeout) {
    var waitTimeout = timeout || defaultTimeout;

    return driver.wait(until.elementLocated(By.xpath(xpath)), waitTimeout);
};

var findElement = function(xpath, customTimeout) {
    return waitForElement(xpath, customTimeout)
        .then(function() {
            return driver.findElement(By.xpath(xpath));
        });
};

var findElements = function(xpath, customTimeout) {
    return waitForElement(xpath, customTimeout)
        .then(function() {
            return driver.findElements(By.xpath(xpath));
        });
};

var jsBasedClick = function(xpath) {
    return findElement(xpath, 0)
        .then(function() {
            return driver.executeScript(
                'document.evaluate(\''+ xpath +'\', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click();'
            ).then(function() {
                return true;
            });
        });
};

var click = function(xpath, customTimeout) {
    return validatePageReadyState()
        .then(function() {
            return findElement(xpath, customTimeout)
                .then(function(el) {
                    el.click().catch(function(e) {
                        console.log('Standard click failed.');
                        return jsBasedClick(xpath);
                    });
                });
        });
};

var hover = function(xpath, customTimeout) {
    return validatePageReadyState()
        .then(function() {
            return findElement(xpath, customTimeout).then(function(el) {
                return driver.actions().mouseMove(el).perform();
            });
        });
};

fillInInput = function(xpath, value, blur, customTimeout) {
    return findElement(xpath, customTimeout)
        .clear()
        .sendKeys(typeof blur !== 'undefined' && blur ? value  + '\t': value);
};

selectImage(imageInputXP, imageName, customTimeout) {
    return waitForElement(imageInputXP, customTimeout)
        .then(function() {
            return findElement(xpath, 0)
                .then(function(el) {
                    var imageDir = config.baseDirectory + 'testImages/' + imageName;
                    return el.sendKeys(imageDir);
                });
        });
};

var sleep = function(sleepTime) {
    return new Promise((resolve) => setTimeout(resolve, sleepTime));
};

var World = function() {
};

module.exports = {
    loadPage: loadPage,
    findElement: findElement,
    findElements: findElements,
    click: click,
    hover: hover,
    sleep: sleep
};
<commit_msg>Missing var added<commit_after>var webdriver = require('selenium-webdriver'),
    By = webdriver.By;
var webdriverRemote = require('selenium-webdriver/remote');
var sprintf = require('sprintf-js').sprintf;
var config = require('./config.js');

var seleniumServerUrl = 'http://%s:%s/wd/hub';

const PLATFORM  = {
    CHROME: 'CHROME',
    FIREFOX: 'FIREFOX'
};

var buildDriver = function(platform) {
    var capabilities;

    if(platform === PLATFORM.CHROME) {
        capabilities = webdriver.Capabilities.chrome();
    } else if(platform === PLATFORM.FIREFOX) {
        capabilities = webdriver.Capabilities.firefox();
    }

    var logPreferences = new webdriver.logging.Preferences();
    logPreferences.setLevel('driver', config.seleniumDriverLogLevel);
    logPreferences.setLevel('browser', config.seleniumBrowserLogLevel);

    var seleniumProxy = require('selenium-webdriver/proxy');
    var proxyUrl = config.proxyHost + ':' + config.proxyHttpPort;

    return new webdriver.Builder()
    .usingServer(sprintf(seleniumServerUrl, config.seleniumServerHost, config.seleniumServerPort))
    .withCapabilities(capabilities)
    .setLoggingPrefs(logPreferences)
    .setProxy(seleniumProxy.manual({
        http: proxyUrl
    }))
    .build();
};

var loadDriverOptions = function(driver) {
    if(config.runMaximized) {
    driver.manage().window().maximize();
    }

    if(config.xvfbMode) {
    driver.manage().window().setSize(config.xvfbSettings.windowWidth, config.xvfbSettings.windowHeight);
    }

    driver.setFileDetector(new webdriverRemote.FileDetector);
};

//building driver
var driver = buildDriver(config.platform);
loadDriverOptions(driver);

//methods
var loadPage = function(page) {
    return driver.get(page);
};

var getDocumentReatyState = function() {
    return driver.executeScript(
        'return document.readyState === \'complete\'',
        ''
    ).then(function(result) {
        return result;
    });
};

var validatePageReadyState = function() {
    //TODO: code style
    return driver.wait(function() {
        return getDocumentReatyState()
            .then(function(value) {
                return value;
            },
            function() {
                return getDocumentReatyState()
                    .then(function(value) {
                        return value;
                    });
            });
    }, defaultTimeout);
};

var waitForElement = function(xpath, customTimeout) {
    var waitTimeout = timeout || defaultTimeout;

    return driver.wait(until.elementLocated(By.xpath(xpath)), waitTimeout);
};

var findElement = function(xpath, customTimeout) {
    return waitForElement(xpath, customTimeout)
        .then(function() {
            return driver.findElement(By.xpath(xpath));
        });
};

var findElements = function(xpath, customTimeout) {
    return waitForElement(xpath, customTimeout)
        .then(function() {
            return driver.findElements(By.xpath(xpath));
        });
};

var jsBasedClick = function(xpath) {
    return findElement(xpath, 0)
        .then(function() {
            return driver.executeScript(
                'document.evaluate(\''+ xpath +'\', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click();'
            ).then(function() {
                return true;
            });
        });
};

var click = function(xpath, customTimeout) {
    return validatePageReadyState()
        .then(function() {
            return findElement(xpath, customTimeout)
                .then(function(el) {
                    el.click().catch(function(e) {
                        console.log('Standard click failed.');
                        return jsBasedClick(xpath);
                    });
                });
        });
};

var hover = function(xpath, customTimeout) {
    return validatePageReadyState()
        .then(function() {
            return findElement(xpath, customTimeout).then(function(el) {
                return driver.actions().mouseMove(el).perform();
            });
        });
};

var fillInInput = function(xpath, value, blur, customTimeout) {
    return findElement(xpath, customTimeout)
        .clear()
        .sendKeys(typeof blur !== 'undefined' && blur ? value  + '\t': value);
};

var selectImage(imageInputXP, imageName, customTimeout) {
    return waitForElement(imageInputXP, customTimeout)
        .then(function() {
            return findElement(xpath, 0)
                .then(function(el) {
                    var imageDir = config.baseDirectory + 'testImages/' + imageName;
                    return el.sendKeys(imageDir);
                });
        });
};

var sleep = function(sleepTime) {
    return new Promise((resolve) => setTimeout(resolve, sleepTime));
};

var World = function() {
};

module.exports = {
    loadPage: loadPage,
    findElement: findElement,
    findElements: findElements,
    click: click,
    hover: hover,
    sleep: sleep
};
<|endoftext|>