<commit_before>/* Module contains Cloud Commander SS(Server Side) objects.
 *
 * List of objects:
 * - Cache
 * - Minify
 */

/*
 * Обьект для работы с кэшем
 * аналог клиентского обьекта
 * с тем отличием, что в нём
 * будут храниться серверные
 * данные, такие как файлы
 * отдаваемые клиенту
 * (файлы проэкта по большому
 * счёту, для ускорения
 * первичной загрузки)
 */
exports.Cache={
    /* приватный переключатель возможности работы с кэшем */
    _allowed            :true,
    /* данные в которых храняться файлы
     * в формате <поле> : <значение>
     * _data[name]=pData;
     * одному имени соответствуют
     * одни данные
     */
    _data               :{},

    /* функция говорит можно ли работать с кэшем */
    isAllowed           :(function(){
        return this._allowed;
        }),
    /* функция устанавливает возможность работать с кэшем */
    setAllowed          :(function(pAllowed){
        this._allowed=pAllowed;
    }),
    /* Если доступен кэш
     * сохраняем в него данные
     */
    set                  :(function(pName, pData){
        if(this._allowed && pName && pData){
            this._data[pName]=pData;
        }
    }),
    /* Если доступен Cache принимаем из него данные*/
    get                 :(function(pName){
        if(this._allowed && pName){
            return this._data[pName];
        }
        else return null;
    }),

    /* Функция очищает кэш*/
    clear               :(function(){
        if(this._allowed){
            this._data={};
        }
    })
};

/* Обьект для сжатия скриптов и стилей
 * по умолчанию - сжимаються
 */
exports.Minify={
    /* pathes to directories */
    INDEX           :'index.html',
    LIBDIRCLIENT    : './lib/client',
    /* приватный переключатель минимизации */
    _allowed               :{css:true,js:true,html:true, img: true},

    /* функция разрешает или
     * запрещает минимизировать
     * css/js/html
     * @pAllowed: - структура, в которой
     *              передаються параметры
     *              минификации, вида
     *              {js:true,css:true,html:false; img:true}
     * img отвечает за перевод картинок в base64
     * и сохранение их в css-файл
     */
    setAllowed              :(function(pAllowed){
       if(pAllowed){
           this._allowed=pAllowed;
       }
    }),

    /*
     * Функция минимизирует css/js/html
     * если установлены параметры минимизации
     */
    doit                    :(function(){
        if(this._allowed.css ||
            this._allowed.js ||
            this._allowed.html){
                var lMinify;
                try{
                    lMinify      = require('minify');
                }catch(pError){
                    this._allowed={js:false,css:false,html:false};
                    return console.log('Could not minify '  +
                        'withou minify module\n'            +
                        'npm i minify');
                }
                /*
                 * temporary changed dir path,
                 * becouse directory lib is write
                 * protected by others by default
                 * so if node process is started
                 * from other user (root for example
                 * in nodester) we can not write
                 * minified versions
                 */
                this.MinFolder = '/' + lMinify.MinFolder;
                var lMinFolder=this.MinFolder;

                /* post processing function for file
                 * client.js
                 */

                /* если мы сжимаем client.js -
                 * меняем строку cloudfunc.js на
                 * cloudfunc.min.js и выводим сообщение
                 *
                 * меняем строку keyBinding.js на
                 * keyBinding.min.js
                 * если другой файл - ничего не деалем
                 */
                var lPostProcessing_f = function(pFinalCode){
                    console.log('file name of ' +
                        'cloudfunc.js'          +
                        ' in '                  +
                        'client.js'             +
                        ' changed. size:',
                    (pFinalCode = pFinalCode
                        .replace('editor.js','editor.min.js')
                            .replace('viewer.js','viewer.min.js')
                                .replace('cloudfunc.js','cloudfunc.min.js')
                                    .replace('keyBinding.js','keyBinding.min.js')
                                        .replace('/lib/', lMinFolder)
                                            .replace('/lib/client/',
                                                lMinFolder)).length);
                    return pFinalCode;
                };

                var lOptimizeParams = [];

                if (this._allowed.js) {
                    lOptimizeParams=[{
                        'client.js': lPostProcessing_f},
                        this.LIBDIRCLIENT + '/cloudfunc.js',
                        this.LIBDIRCLIENT + '/keyBinding.js',
                        this.LIBDIRCLIENT + '/editor.js',
                        this.LIBDIRCLIENT + '/viewer.js'];
                }

                if (this._allowed.html)
                    lOptimizeParams[lOptimizeParams.length] = this.INDEX;

                if (this._allowed.css) {
                    lOptimizeParams[lOptimizeParams.length] = {
                        './css/style.css' : this._allowed.img };

                    lOptimizeParams[lOptimizeParams.length] = {
                        './css/reset.css': this._allowed.img};
                }

                if (lOptimizeParams)
                    lMinify.optimize(lOptimizeParams);

                this.Cache = lMinify.Cache;
        }
    }),

    /* minification folder name */
    MinFolder   :'',
    Cache       :{}
};<commit_msg>fixed bug with location of cloudfun.js<commit_after>/* Module contains Cloud Commander SS(Server Side) objects.
 *
 * List of objects:
 * - Cache
 * - Minify
 */

/*
 * Обьект для работы с кэшем
 * аналог клиентского обьекта
 * с тем отличием, что в нём
 * будут храниться серверные
 * данные, такие как файлы
 * отдаваемые клиенту
 * (файлы проэкта по большому
 * счёту, для ускорения
 * первичной загрузки)
 */
exports.Cache={
    /* приватный переключатель возможности работы с кэшем */
    _allowed            :true,
    /* данные в которых храняться файлы
     * в формате <поле> : <значение>
     * _data[name]=pData;
     * одному имени соответствуют
     * одни данные
     */
    _data               :{},

    /* функция говорит можно ли работать с кэшем */
    isAllowed           :(function(){
        return this._allowed;
        }),
    /* функция устанавливает возможность работать с кэшем */
    setAllowed          :(function(pAllowed){
        this._allowed=pAllowed;
    }),
    /* Если доступен кэш
     * сохраняем в него данные
     */
    set                  :(function(pName, pData){
        if(this._allowed && pName && pData){
            this._data[pName]=pData;
        }
    }),
    /* Если доступен Cache принимаем из него данные*/
    get                 :(function(pName){
        if(this._allowed && pName){
            return this._data[pName];
        }
        else return null;
    }),

    /* Функция очищает кэш*/
    clear               :(function(){
        if(this._allowed){
            this._data={};
        }
    })
};

/* Обьект для сжатия скриптов и стилей
 * по умолчанию - сжимаються
 */
exports.Minify={
    /* pathes to directories */
    INDEX           :'index.html',
    LIBDIR          : '/lib/',
    LIBDIRCLIENT    : './lib/client/',
    /* приватный переключатель минимизации */
    _allowed               :{css:true,js:true,html:true, img: true},

    /* функция разрешает или
     * запрещает минимизировать
     * css/js/html
     * @pAllowed: - структура, в которой
     *              передаються параметры
     *              минификации, вида
     *              {js:true,css:true,html:false; img:true}
     * img отвечает за перевод картинок в base64
     * и сохранение их в css-файл
     */
    setAllowed              :(function(pAllowed){
       if(pAllowed){
           this._allowed=pAllowed;
       }
    }),

    /*
     * Функция минимизирует css/js/html
     * если установлены параметры минимизации
     */
    doit                    :(function(){
        if(this._allowed.css ||
            this._allowed.js ||
            this._allowed.html){
                var lMinify;
                try{
                    lMinify      = require('minify');
                }catch(pError){
                    this._allowed={js:false,css:false,html:false};
                    return console.log('Could not minify '  +
                        'withou minify module\n'            +
                        'npm i minify');
                }
                /*
                 * temporary changed dir path,
                 * becouse directory lib is write
                 * protected by others by default
                 * so if node process is started
                 * from other user (root for example
                 * in nodester) we can not write
                 * minified versions
                 */
                this.MinFolder = '/' + lMinify.MinFolder;
                var lMinFolder=this.MinFolder;

                /* post processing function for file
                 * client.js
                 */

                /* если мы сжимаем client.js -
                 * меняем строку cloudfunc.js на
                 * cloudfunc.min.js и выводим сообщение
                 *
                 * меняем строку keyBinding.js на
                 * keyBinding.min.js
                 * если другой файл - ничего не деалем
                 */
                var lPostProcessing_f = function(pFinalCode){
                    console.log('file name of ' +
                        'cloudfunc.js'          +
                        ' in '                  +
                        'client.js'             +
                        ' changed. size:',
                    (pFinalCode = pFinalCode
                        .replace('editor.js','editor.min.js')
                            .replace('viewer.js','viewer.min.js')
                                .replace('cloudfunc.js','cloudfunc.min.js')
                                    .replace('keyBinding.js','keyBinding.min.js')
                                        .replace('/lib/', lMinFolder)
                                            .replace('/lib/client/',
                                                lMinFolder)).length);
                    return pFinalCode;
                };

                var lOptimizeParams = [];

                if (this._allowed.js) {
                    lOptimizeParams=[{
                        'client.js': lPostProcessing_f},
                        this.LIBDIR         + 'cloudfunc.js',
                        this.LIBDIRCLIENT   + 'keyBinding.js',
                        this.LIBDIRCLIENT   + 'editor.js',
                        this.LIBDIRCLIENT   + 'viewer.js'];
                }

                if (this._allowed.html)
                    lOptimizeParams[lOptimizeParams.length] = this.INDEX;

                if (this._allowed.css) {
                    lOptimizeParams[lOptimizeParams.length] = {
                        './css/style.css' : this._allowed.img };

                    lOptimizeParams[lOptimizeParams.length] = {
                        './css/reset.css': this._allowed.img};
                }

                if (lOptimizeParams)
                    lMinify.optimize(lOptimizeParams);

                this.Cache = lMinify.Cache;
        }
    }),

    /* minification folder name */
    MinFolder   :'',
    Cache       :{}
};<|endoftext|>


<commit_before>'use strict';

var connect = require('connect');
var _ = require('underscore');
var EventEmitter = require('events').EventEmitter;
var Converter = require('../converter');
var logger = require('../utils').getLogger();
var mocha = require('mocha');
var util = require('util');

/**
 * The server class
 *
 * @param config {Object} The initial server configuration.
 * @constructor
 */
var TestServer = function (config) {
	_.extend(this, {
		instances: {},
		config: config,
		connect: config.connect || connect(),
		converter: new Converter(),
		hooks: {},
		errorId: 0
	});

	if(mocha.reporters[config.reporter]) {
		this.reporter = new mocha.reporters[config.reporter](this.converter);
	} else {
		// Just in case we got a nonexistent converter, fallback to Spec to report the error
		this.reporter = new mocha.reporters.Spec(this.converter);
		this.error(new Error('Can not find reporter ' + config.reporter + ' falling back to Spec.'), 'Reporter');
	}

	this.on('listening', function (server, port) {
		logger.debug('Listening on port', port);
	});

	this.on('registering', function (token) {
		logger.debug('Registering token', { token: token });
	});
};

util.inherits(TestServer, EventEmitter);

_.extend(TestServer.prototype, {
	/**
	 * Use a Middleware on this server
	 * @return {Server} The server instance
	 */
	use: function () {
		this.connect.use.apply(this.connect, arguments);
		return this;
	},
	/**
	 * Add a handler function. A handler will be called right
	 * away with the server instance as the single parameter.
	 *
	 * @param {Function} callback The handler function taking
	 * the server instance as the single parameter.
	 * @return {Server}
	 */
	handle: function (callback) {
		callback(this);
		return this;
	},
	/**
	 * Checks if a given token has a registered instance.
	 *
	 * @param {String} token The token to check for
	 * @return {Boolean} Whether there is an instance or now.
	 */
	isValid: function (token) {
		return this.instances[token] !== undefined;
	},
	/**
	 * Start the server on a given port.
	 *
	 * @param port {Integer} The port to listen on
	 * @return {*}
	 */
	listen: function (port) {
		var self = this;
		var server = this.connect.listen(port);
		server.on('listening', function () {
			self.emit('listening', server, port);
		});
		this.on('close', function () {
			server.close();
		});
		return server;
	},
	close: function () {
		this.emit('close');
	},
	hook: function (event, handler) {
		if (!this.hooks[event]) {
			this.hooks[event] = [];
		}
		this.hooks[event].push(handler);
		this.emit('hook', event, this.hooks[event]);
		return this.hooks[event];
	},
	/**
	 * Register a new instance for a given token. An instance is
	 * an event emitter expected to emit the `testing` event with
	 * the remote reporter (EventEmitter) when a test is started.
	 *
	 * @param token
	 * @param instance
	 * @return {*}
	 */
	register: function (token, instance) {
		var self = this;
		var timeout = setTimeout(function() {
			self.error(new Error('No test started within the timeout of ' + self.config.timeout + ' seconds.'),
				'Server', false);
		}, self.config.timeout * 1000);

		self.emit('registering', token, instance);
		self.instances[token] = instance;

		instance.on('testing', function (testReporter) {
			self.converter.run(testReporter);
			self.emit('testing', testReporter, self);

			// Once the test reporter officially starts
			// remove this emitter from the list so that it can't authenticate again
			testReporter.once(self.config.startEvent, function () {
				logger.debug('Removing token ' + token);
				delete self.instances[token];
				clearTimeout(timeout);
			});

			testReporter.once(self.config.exitEvent, function () {
				self.emit('done', instance, testReporter, self);
			});

			// Add hooks
			_.each(self.hooks, function (handlers, event) {
				_.each(handlers, function (handler) {
					testReporter.on(event, function () {
						var args = _.toArray(arguments);
						args.unshift(self);
						handler.apply(this, args);
					});
				});
			});
		});

		return this;
	},
	/**
	 * Report an error on this server.
	 *
	 * @param {Error} error The error that happened
	 * @param {String} [context] A description of the context the error happened in
	 * @param {Boolean} [critical] If this is a critial error
	 */
	error: function(error, context, critical) {
		var self = this.converter;
		var events = self.config.events;
		var reporter = new EventEmitter();
		var suiteId = --self.errorId;
		var testId = --self.errorId;

		this.converter.run(reporter);

		reporter.emit(events.suite, {
			id: suiteId,
			title: 'Testee Error',
			root: true
		});

		reporter.emit(events.test, {
			id: testId,
			title: context || 'General Error'
		});

		reporter.emit(events.fail, {
			id: testId,
			err: error
		});

		reporter.emit(events.testEnd, {
			id: testId
		});

		reporter.emit(events.suiteEnd, {
			id: suiteId
		});

		if(critical) {
			this.converter.end({});
		}

		this.emit('serverError', error, critical);
	},
	emitter: function (token) {
		return this.instances[token];
	}
});

module.exports = TestServer;
<commit_msg>Log error.<commit_after>'use strict';

var connect = require('connect');
var _ = require('underscore');
var EventEmitter = require('events').EventEmitter;
var Converter = require('../converter');
var logger = require('../utils').getLogger();
var mocha = require('mocha');
var util = require('util');

/**
 * The server class
 *
 * @param config {Object} The initial server configuration.
 * @constructor
 */
var TestServer = function (config) {
	_.extend(this, {
		instances: {},
		config: config,
		connect: config.connect || connect(),
		converter: new Converter(),
		hooks: {},
		errorId: 0
	});

	if(mocha.reporters[config.reporter]) {
		this.reporter = new mocha.reporters[config.reporter](this.converter);
	} else {
		// Just in case we got a nonexistent converter, fallback to Spec to report the error
		this.reporter = new mocha.reporters.Spec(this.converter);
		this.error(new Error('Can not find reporter ' + config.reporter + ' falling back to Spec.'), 'Reporter');
	}

	this.on('listening', function (server, port) {
		logger.debug('Listening on port', port);
	});

	this.on('registering', function (token) {
		logger.debug('Registering token', { token: token });
	});
};

util.inherits(TestServer, EventEmitter);

_.extend(TestServer.prototype, {
	/**
	 * Use a Middleware on this server
	 * @return {Server} The server instance
	 */
	use: function () {
		this.connect.use.apply(this.connect, arguments);
		return this;
	},
	/**
	 * Add a handler function. A handler will be called right
	 * away with the server instance as the single parameter.
	 *
	 * @param {Function} callback The handler function taking
	 * the server instance as the single parameter.
	 * @return {Server}
	 */
	handle: function (callback) {
		callback(this);
		return this;
	},
	/**
	 * Checks if a given token has a registered instance.
	 *
	 * @param {String} token The token to check for
	 * @return {Boolean} Whether there is an instance or now.
	 */
	isValid: function (token) {
		return this.instances[token] !== undefined;
	},
	/**
	 * Start the server on a given port.
	 *
	 * @param port {Integer} The port to listen on
	 * @return {*}
	 */
	listen: function (port) {
		var self = this;
		var server = this.connect.listen(port);
		server.on('listening', function () {
			self.emit('listening', server, port);
		});
		this.on('close', function () {
			server.close();
		});
		return server;
	},
	close: function () {
		this.emit('close');
	},
	hook: function (event, handler) {
		if (!this.hooks[event]) {
			this.hooks[event] = [];
		}
		this.hooks[event].push(handler);
		this.emit('hook', event, this.hooks[event]);
		return this.hooks[event];
	},
	/**
	 * Register a new instance for a given token. An instance is
	 * an event emitter expected to emit the `testing` event with
	 * the remote reporter (EventEmitter) when a test is started.
	 *
	 * @param token
	 * @param instance
	 * @return {*}
	 */
	register: function (token, instance) {
		var self = this;
		var timeout = setTimeout(function() {
			self.error(new Error('No test started within the timeout of ' + self.config.timeout + ' seconds.'),
				'Server', false);
		}, self.config.timeout * 1000);

		self.emit('registering', token, instance);
		self.instances[token] = instance;

		instance.on('testing', function (testReporter) {
			self.converter.run(testReporter);
			self.emit('testing', testReporter, self);

			// Once the test reporter officially starts
			// remove this emitter from the list so that it can't authenticate again
			testReporter.once(self.config.startEvent, function () {
				logger.debug('Removing token ' + token);
				delete self.instances[token];
				clearTimeout(timeout);
			});

			testReporter.once(self.config.exitEvent, function () {
				self.emit('done', instance, testReporter, self);
			});

			// Add hooks
			_.each(self.hooks, function (handlers, event) {
				_.each(handlers, function (handler) {
					testReporter.on(event, function () {
						var args = _.toArray(arguments);
						args.unshift(self);
						handler.apply(this, args);
					});
				});
			});
		});

		return this;
	},
	/**
	 * Report an error on this server.
	 *
	 * @param {Error} error The error that happened
	 * @param {String} [context] A description of the context the error happened in
	 * @param {Boolean} [critical] If this is a critial error
	 */
	error: function(error, context, critical) {
		var self = this.converter;
		var events = self.config.events;
		var reporter = new EventEmitter();
		var suiteId = --self.errorId;
		var testId = --self.errorId;

    console.dir(error);

		this.converter.run(reporter);

		reporter.emit(events.suite, {
			id: suiteId,
			title: 'Testee Error',
			root: true
		});

		reporter.emit(events.test, {
			id: testId,
			title: context || 'General Error'
		});

		reporter.emit(events.fail, {
			id: testId,
			err: error
		});

		reporter.emit(events.testEnd, {
			id: testId
		});

		reporter.emit(events.suiteEnd, {
			id: suiteId
		});

		if(critical) {
			this.converter.end({});
		}

		this.emit('serverError', error, critical);
	},
	emitter: function (token) {
		return this.instances[token];
	}
});

module.exports = TestServer;
<|endoftext|>


<commit_before>'use strict';

var EngineIOClient = require('engine.io-client');

var DubAPIRequestError = require('./errors/requestError.js');

var utils = require('./utils.js');

var endpoints = require('./data/endpoints.js');

function SocketHandler(dubAPI) {
    this._ = {};
    this._.dubAPI = dubAPI;
    this._.socket = undefined;
    this._.channels = {};
    this._.reconnect = true;

    this.connectBind = utils.bind(this.connect, this);

    this.onOpenBind = utils.bind(this.onOpen, this);
    this.onMessageBind = utils.bind(this.onMessage, this);
    this.onErrorBind = utils.bind(this.onError, this);
    this.onCloseBind = utils.bind(this.onClose, this);
}

SocketHandler.prototype.connect = function() {
    if (this._.socket) return;

    this._.reconnect = true;

    var that = this;

    this._.dubAPI._.reqHandler.queue({method: 'GET', url: endpoints.authToken}, function(code, body) {
        if (code !== 200) {
            that._.dubAPI.emit('error', new DubAPIRequestError(code, that._.dubAPI._.reqHandler.endpoint(endpoints.authToken)));
            setTimeout(that.connectBind, 5000);
            return;
        }

        that._.socket = new EngineIOClient({
            hostname: 'ws.dubtrack.fm',
            secure: true,
            path: '/ws',
            query: {access_token: body.data.token}, //eslint-disable-line camelcase
            transports: ['websocket']
        });

        that._.socket.on('open', that.onOpenBind);
        that._.socket.on('message', that.onMessageBind);
        that._.socket.on('error', that.onErrorBind);
        that._.socket.on('close', that.onCloseBind);
    });
};

SocketHandler.prototype.onOpen = function() {
    var channels = Object.keys(this._.channels);

    for (var i = 0; i < channels.length; i++) {
        this._.socket.send(JSON.stringify({action: 10, channel: channels[i]}));
    }

    this._.dubAPI.emit('socket:open');
};

SocketHandler.prototype.onMessage = function(data) {
    try {
        data = JSON.parse(data);
    } catch (err) {
        this._.dubAPI.emit('error', err);
        return;
    }

    this._.dubAPI.emit('socket:message', data);

    if (data.action === 15 && this._.channels[data.channel]) {
        try {
            data.message.data = JSON.parse(data.message.data);
        } catch (err) {
            this._.dubAPI.emit('error', err);
            return;
        }

        this._.channels[data.channel](data.message.data);
    }
};

SocketHandler.prototype.onError = function(err) {
    this._.dubAPI.emit('error', err);
};

SocketHandler.prototype.onClose = function() {
    this._.socket = undefined;

    if (this._.reconnect) setTimeout(this.connectBind, 5000);

    this._.dubAPI.emit('socket:close');
};

SocketHandler.prototype.attachChannel = function(channel, callback) {
    if (this._.socket && !this._.channels[channel]) {
        this._.socket.send(JSON.stringify({action: 10, channel: channel}));

        if (/^room:/.test(channel)) {
            this._.socket.send(JSON.stringify({action: 14, channel: channel, presence: {action: 0, data: {}}}));
        }
    }

    this._.channels[channel] = callback;
};

SocketHandler.prototype.detachChannel = function(channel) {
    if (this._.socket && this._.channels[channel]) this._.socket.send(JSON.stringify({action: 12, channel: channel}));

    delete this._.channels[channel];
};

SocketHandler.prototype.disconnect = function() {
    if (!this._.socket) return;

    this._.reconnect = false;
    this._.socket.close();
};

module.exports = SocketHandler;
<commit_msg>Send presence enter on socket reconnect too<commit_after>'use strict';

var EngineIOClient = require('engine.io-client');

var DubAPIRequestError = require('./errors/requestError.js');

var utils = require('./utils.js');

var endpoints = require('./data/endpoints.js');

function SocketHandler(dubAPI) {
    this._ = {};
    this._.dubAPI = dubAPI;
    this._.socket = undefined;
    this._.channels = {};
    this._.reconnect = true;

    this.connectBind = utils.bind(this.connect, this);

    this.onOpenBind = utils.bind(this.onOpen, this);
    this.onMessageBind = utils.bind(this.onMessage, this);
    this.onErrorBind = utils.bind(this.onError, this);
    this.onCloseBind = utils.bind(this.onClose, this);
}

SocketHandler.prototype.connect = function() {
    if (this._.socket) return;

    this._.reconnect = true;

    var that = this;

    this._.dubAPI._.reqHandler.queue({method: 'GET', url: endpoints.authToken}, function(code, body) {
        if (code !== 200) {
            that._.dubAPI.emit('error', new DubAPIRequestError(code, that._.dubAPI._.reqHandler.endpoint(endpoints.authToken)));
            setTimeout(that.connectBind, 5000);
            return;
        }

        that._.socket = new EngineIOClient({
            hostname: 'ws.dubtrack.fm',
            secure: true,
            path: '/ws',
            query: {access_token: body.data.token}, //eslint-disable-line camelcase
            transports: ['websocket']
        });

        that._.socket.on('open', that.onOpenBind);
        that._.socket.on('message', that.onMessageBind);
        that._.socket.on('error', that.onErrorBind);
        that._.socket.on('close', that.onCloseBind);
    });
};

SocketHandler.prototype.onOpen = function() {
    var channels = Object.keys(this._.channels);

    for (var i = 0; i < channels.length; i++) {
        this._.socket.send(JSON.stringify({action: 10, channel: channels[i]}));

        if (/^room:/.test(channels[i])) {
            this._.socket.send(JSON.stringify({action: 14, channel: channels[i], presence: {action: 0, data: {}}}));
        }
    }

    this._.dubAPI.emit('socket:open');
};

SocketHandler.prototype.onMessage = function(data) {
    try {
        data = JSON.parse(data);
    } catch (err) {
        this._.dubAPI.emit('error', err);
        return;
    }

    this._.dubAPI.emit('socket:message', data);

    if (data.action === 15 && this._.channels[data.channel]) {
        try {
            data.message.data = JSON.parse(data.message.data);
        } catch (err) {
            this._.dubAPI.emit('error', err);
            return;
        }

        this._.channels[data.channel](data.message.data);
    }
};

SocketHandler.prototype.onError = function(err) {
    this._.dubAPI.emit('error', err);
};

SocketHandler.prototype.onClose = function() {
    this._.socket = undefined;

    if (this._.reconnect) setTimeout(this.connectBind, 5000);

    this._.dubAPI.emit('socket:close');
};

SocketHandler.prototype.attachChannel = function(channel, callback) {
    if (this._.socket && !this._.channels[channel]) {
        this._.socket.send(JSON.stringify({action: 10, channel: channel}));

        if (/^room:/.test(channel)) {
            this._.socket.send(JSON.stringify({action: 14, channel: channel, presence: {action: 0, data: {}}}));
        }
    }

    this._.channels[channel] = callback;
};

SocketHandler.prototype.detachChannel = function(channel) {
    if (this._.socket && this._.channels[channel]) this._.socket.send(JSON.stringify({action: 12, channel: channel}));

    delete this._.channels[channel];
};

SocketHandler.prototype.disconnect = function() {
    if (!this._.socket) return;

    this._.reconnect = false;
    this._.socket.close();
};

module.exports = SocketHandler;
<|endoftext|>


<commit_before>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2016 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 *
 */
var TouchID = require('ti.touchid');
var win = Ti.UI.createWindow({
    backgroundColor: '#fff',
    layout: 'vertical'
});

// -- IMPORTANT --
// This prefix is required for device and production builds
// and will be ignored for simulator builds. It is the Team-ID
// of your provisioning profile.
var appIdentifierPrefix = '<YOU-APP-IDENTIFIER-PREFIX>';

var keychainItem = TouchID.createKeychainItem({
    identifier: 'mypassword',
    accessGroup: appIdentifierPrefix + '.' + Ti.App.getId(),
    accessibilityMode: TouchID.ACCESSIBLE_WHEN_PASSCODE_SET_THIS_DEVICE_ONLY,
    accessControlMode: TouchID.ACCESS_CONTROL_TOUCH_ID_ANY,
    // Pass more native options to the keychain. Since there are hundrets of them,
    // look up the value of the constant and pass it here. Example:
    options: {
        // It's the value of kSecUseOperationPrompt
        'u_OpPrompt': 'Please authenticate yourself before'
    }
});

keychainItem.addEventListener('save', function(e) {
    if (!e.success) {
        Ti.API.error('Error saving to the keychain: ' + e.error);
        return;
    }

    Ti.API.info('Successfully saved!');
    Ti.API.info(e);
});

keychainItem.addEventListener('read', function(e) {
    if (!e.success) {
        Ti.API.error('Error reading the keychain: ' + e.error);
        return;
    }

    Ti.API.info('Successfully read!');
    Ti.API.info(e);
});

keychainItem.addEventListener('reset', function(e) {
    if (!e.success) {
        Ti.API.error('Error resetting the keychain: ' + e.error);
        return;
    }

    Ti.API.info('Successfully resetted!');
});

var btnExists = Ti.UI.createButton({
    title: 'Exists?',
    top: 40
});

btnExists.addEventListener('click', function() {
    Ti.API.info('Exists? ' + keychainItem.exists());
});

var btnSave = Ti.UI.createButton({
    title: 'Save password to keychain!',
    top: 40
});

btnSave.addEventListener('click', function() {
    keychainItem.save('s3cr3t_p4$$w0rd');
});

var btnRead = Ti.UI.createButton({
    title: 'Read password from keychain',
    top: 40
});

btnRead.addEventListener('click', function() {
    keychainItem.read();
});

var btnDelete = Ti.UI.createButton({
    title: 'Delete password from keychain',
    top: 40
});

btnDelete.addEventListener('click', function() {
    keychainItem.reset();
});

win.add(btnExists);
win.add(btnSave);
win.add(btnRead);
win.add(btnDelete);

win.open();
<commit_msg>Fix existence-check in example<commit_after>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2016 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 *
 */
var TouchID = require('ti.touchid');
var win = Ti.UI.createWindow({
    backgroundColor: '#fff',
    layout: 'vertical'
});

// -- IMPORTANT --
// This prefix is required for device and production builds
// and will be ignored for simulator builds. It is the Team-ID
// of your provisioning profile.
var appIdentifierPrefix = '<YOU-APP-IDENTIFIER-PREFIX>';

var keychainItem = TouchID.createKeychainItem({
    identifier: 'mypassword',
    accessGroup: appIdentifierPrefix + '.' + Ti.App.getId(),
    accessibilityMode: TouchID.ACCESSIBLE_WHEN_PASSCODE_SET_THIS_DEVICE_ONLY,
    accessControlMode: TouchID.ACCESS_CONTROL_TOUCH_ID_ANY,
    // Pass more native options to the keychain. Since there are hundrets of them,
    // look up the value of the constant and pass it here. Example:
    options: {
        // It's the value of kSecUseOperationPrompt
        'u_OpPrompt': 'Please authenticate yourself before'
    }
});

keychainItem.addEventListener('save', function(e) {
    if (!e.success) {
        Ti.API.error('Error saving to the keychain: ' + e.error);
        return;
    }

    Ti.API.info('Successfully saved!');
    Ti.API.info(e);
});

keychainItem.addEventListener('read', function(e) {
    if (!e.success) {
        Ti.API.error('Error reading the keychain: ' + e.error);
        return;
    }

    Ti.API.info('Successfully read!');
    Ti.API.info(e);
});

keychainItem.addEventListener('reset', function(e) {
    if (!e.success) {
        Ti.API.error('Error resetting the keychain: ' + e.error);
        return;
    }

    Ti.API.info('Successfully resetted!');
});

var btnExists = Ti.UI.createButton({
    title: 'Exists?',
    top: 40
});

btnExists.addEventListener('click', function() {
    keychainItem.fetchExistence(function(e) {
        alert("Exists? " + e.exists);
    });
});

var btnSave = Ti.UI.createButton({
    title: 'Save password to keychain!',
    top: 40
});

btnSave.addEventListener('click', function() {
    keychainItem.save('s3cr3t_p4$$w0rd');
});

var btnRead = Ti.UI.createButton({
    title: 'Read password from keychain',
    top: 40
});

btnRead.addEventListener('click', function() {
    keychainItem.read();
});

var btnDelete = Ti.UI.createButton({
    title: 'Delete password from keychain',
    top: 40
});

btnDelete.addEventListener('click', function() {
    keychainItem.reset();
});

win.add(btnExists);
win.add(btnSave);
win.add(btnRead);
win.add(btnDelete);

win.open();
<|endoftext|>


<commit_before>$(function () {
        // Автообновляемые элементы
        $('.autoload').each(function () {
            $(this).load($(this).attr('data-url'));
        });

        setInterval(function () {
            $('.autoload').each(function () {
                $(this).load($(this).attr('data-url'))
            });
        }, 3000);

        // Отклики на лайки
        $(this).on('click', 'a.ajaxlike', function () {
            var data = $(this).data();

            var likesSpan = $('#likes-' + data.postId);
            var likeHeart = $(this);

            $.ajax({url: data.url, method: 'post'}).done(function (data, status, response) {
                    var responseData = $.parseJSON(response.responseText);

                    if (responseData.is_liked) {
                        $(likeHeart).removeClass("text-muted");
                        $(likeHeart).addClass("text-danger");
                    } else {
                        $(likeHeart).removeClass("text-danger");
                        $(likeHeart).addClass("text-muted");
                    }

                    $(likesSpan).html(responseData.n_likes);
                }
            );

            return false;
        });

        // Настройка автокомплита в select'ах
        $('select').select2();

        // Настраиваем django-fm
        $.fm({debug: false});
        $('body').on("fm.ready", function () {
            $('select').select2();
        });

        function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }

        $.ajaxSetup({
            beforeSend: function (xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", $('meta[name=csrf]').attr("content"));
                }
            }
        });
    }
);<commit_msg>Update js after code review.<commit_after>$(function () {
        // Автообновляемые элементы
        function loadItems() {
            $('.autoload').each(function () {
                $(this).load($(this).attr('data-url'));
            });
        }

        loadItems();
        setInterval(loadItems, 3000);

        // Отклики на лайки
        $(this).on('click', 'a.ajaxlike', function () {
            var likeHeart = $(this);

            var data = likeHeart.data();

            var likesSpan = $('#likes-' + data.postId);

            $.ajax({url: data.url, method: 'post'}).done(function (data, status, response) {
                var responseData = $.parseJSON(response.responseText);

                // \todo Переписать на toggleClass
                if (responseData.is_liked) {
                    likeHeart.removeClass("text-muted").addClass("text-danger");
                } else {
                    likeHeart.removeClass("text-danger").addClass("text-muted");
                }

                likesSpan.html(responseData.n_likes);
            });

            return false;
        });

        // Настраиваем django-fm
        $.fm({debug: false});

        // Настройка автокомплита в select'ах
        $('select').select2();
        $('body').on("fm.ready", function () {
            $('select', this).select2();
        });

        function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }

        $.ajaxSetup({
            beforeSend: function (xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", $('meta[name=csrf]').attr("content"));
                }
            }
        });
    }
);<|endoftext|>


<commit_before>var words = [];

var exclam = /\b!\b/g;
var exclamrepl = [", verily!", ", verily I say!", ", verily I sayeth!", ", I say!", ", I sayeth!", "! Huzzah!", "! Hear Hear!", "! What-ho!", "! Ho!", "! Fie!", ", indeed!"];

var questi = /\b\?\b/g;
var questirepl = [", I say?", ", I wonder?", ", wonder I?", ", what say thee?", ", what sayeth thee?", ", what say thou?", ", what sayeth thou?", ", I ponder?", ", I pondereth?", ", pray tell?", ", ho?", ", do tell?"];

var insults = /\bidiot\b|\bfool\b|\bbastard\b/gi;

var insultnoun = ["mongrel", "codpiece", "jackanape", "ape", "coxcomb", "harlot", "hussy", "strumpet", "cur", "clot", "fool", "barnacle", "harpy", "wench", "churl", "pleb", "taffer", "scoundrel", "scalliwag", "mooncalf", "rapscallion", "doxy", "bawd", "tosspot", "cupshot", "recreant", "fustalarion", "scullion", "rampallion", "knave", "barbermonger", "boil", "plague-sore", "carbuncle", "whoreson", "clotpole", "lout", "gudgeon", "puttock", "skainsmate", "varlet", "bladder"];

var insultadj = ["artless", "droning", "fawning", "warped", "paunchy", "puny", "spongy", "ruttish", "vain", "lumpish", "craven", "witless", "pustulent", "infested", "ill-bred", "blind", "scurvy", "puny", "fetid", "vile", "gibbering", "mewling", "rank", "fawning", "moonish", "brutish", "malapert", "curst", "lack-linen", "bottle-ailed", "lyingest", "embossed", "cheating", "crook-pated", "base-court", "hasty-witted", "two-faced", "pox-marked", "toad-brained", "errant", "idle-headed", "quailing", "flap-mouthed", "puking", "fly-bitten", "surly", "tottering", "villainous", "rump-fed", "bootless", "churlish", "tickle-brained", "froward"];

var startmsgs = ["Forsooth,", "I say,", "I sayeth,", "Forsooth, I say,", "Forsooth, say I,", "Forsooth, sayeth I,", "Hark!", "Harketh!", "By <god>,", "By the Will of <god adjective> <god>,", "By the <body part adjective> <body part> of the <god adjective> <god>,", "By <god adjective> <god>'s <body part adjective> <body part>,", "Avast,", "Zounds,", "Perchance,", "Pray tell,", "Prithee,", "What hey,", "What ho,", "Pray,", "Surely", "Pray pardon,", "Alas,", "In short,", "My Lord,", "My Lady,", "By my faith,", "If it pleases you,", "I pray you,", "In truth,", "By my trowth,", "In sooth,", "By my word,", "S'wounds,", "Z'wounds,", "<god>'s wounds,", "<god>'s <body part>,", "Heigh-ho,", "Ah,", "Quoth I,", "Listen,", "Listen thee,", "Hear me,", "Now hear me,", "I warrant", "Come,", "Kind sire,", "Sire,", "There is much in what you say, and yet,"];
var endmsgs = ["Anon!", "Hum.", "Good sir!", "Good sire!", "Milady!", "My Liege!", "Guvnor!"];

var gods = ["Odin", "Bob", "Zeus", "Hera", "Thor", "Crom", "Mad-poet Navarth", "Cugel", "Wotsit", "Baron Boddisey", "Poseidon", "Saint Mary", "Pallus Athena", "Loki", "Erlik", "Shoggoth", "Omm", "Vishnu", "Azazoth", "Father Odin", "Allfather Odin", "Cthulhu", "Buddha", "Aphrodite", "Isis", "Kali", "Dionysus", "Zarathustra", "Croesus", "Hermes", "Venus", "Montezuma", "Popacatapetl", "Hephaestus", "Bubastes", "Bacchus", "Nebuchadnezzar", "Assurbanipal", "Sargon", "Xerxes", "Mulwatallish", "Labarna", "Hammurabi", "Rameses", "Minos", "Tilgath-Pileser", "Vercingetorix", "Mithradites", "Pericles", "Belasarius", "Archaemides", "Heraclius", "Imhotep", "Artemis", "Orthia", "Phoebe", "Hestia", "Eros", "Persephone", "Minerva", "Mercury", "Aesculapius", "Discordia", "Hecate", "Hespera"];

var godadjs = ["Almighty", "Unthinkable", "Unknowable", "All-knowing", "All-seeing", "Lecherous", "Scandalous", "Merciful", "Ravaging", "Thunderous", "Wrathful", "Distant", "Vengeful", "Supreme", "Wise", "Warlike", "Jealous", "Vindictive", "Powerful", "Adulterous", "Licentious", "Crafty", "Benefical", "Virtuous", "Protective", "Prophetic", "Bloodthirsty", "Murderous", "Ruinous", "Militant", "Invisible", "Omnipotent", "Forgotten", "Enlightened", "Tempestuous", "Destructive", "Grim"];

var bodyparts = ["Beard", "Third Leg", "Scalp", "Eye", "Thigh", "Arm", "Sword", "Heel", "Gaze", "Tongue", "Hammer", "Toenail", "Nether Regions", "Liver", "Lights", "Spleen", "Gall", "Liver and Lights"];

var bodypartadjs = ["Unknowable", "Unescapable", "Unfathomable", "Unthinkable", "Righteous", "Hairy", "Hairless", "Wandering", "Blistered", "Awe-inspiring", "Toothy", "Ravaged", "Aged", "Endless", "Wondrous", "Unavoidable", "Pestilent", "Forgotten", "Beautiful", "Fertile", "Prophetic", "Musical", "Helpful", "Virginal", "Curative", "Bleak", "Incessant", "Sagely", "Unfashionable", "Unfaltering", "Unfamiliar", "Abysmal", "Boundless", "Eternal", "Immeasurable", "Infinite", "Unending", "Soundless", "Incomprehensible", "Inexplicable", "Profound", "Unintelligible", "Unbelievable", "Impenetrable", "Indecipherable", "Esoteric", "Enigmatic", "Ancient", "Venerable", "Baneful", "Contagious", "Corrupting", "Deadly", "Deleterious", "Evil", "Noxious", "Diseased", "Pernicious", "Pestiferous", "Pestilential", "Tainted", "Contaminated", "Pulchritudinous", "Odoriferous", "Misbegotten", "Sacriligio"];

function arrRandom(arr) {
    return arr[sys.rand(0, arr.length)];
}

function word(original, replacement) {
    var len, i;

    if (!Array.isArray(original)) {
        original = [original];
    }
    if (!Array.isArray(replacement)) {
        replacement = [replacement];
    }

    for (i = 0, len = original.length; i < len; i += 1) {
        words.push({regex: new RegExp("\\b" + original[i] + "\\b", "gi"), replacements: replacement});
    }
}

// http://wiki.teamfortress.com/wiki/Medieval_Mode#Chat_parser
function addWords() {
    words = [];

    // 1
    word(["it is", "it's"], "tis");
    word("it was", "'twas");
    word("it would", "'twould");
    word("it will", "'twill");
    word("it were", "'twere");
    word(["shall not", "will not"], "shan't");
    word("over there", "yonder");
    word("in the", "i' the");
    word("thank you", ["many good thanks to you", "thankee", "kindly thanks to you", "grammercy to you"]);
    word(["you", "u"], ["thou", "thee", "ye"]);
    word("are", "art");
    word("lol", ["lolleth", "lollery"]);
    word(["killed", "beaten"], ["slain", "vanquished", "brung low", "conquered", "fleeced", "humbled", "subjugated", "bested", "foiled"]);
    word(["goodbye", "bye", "seeya", "goodnight"], ["farewell", "fare thee well", "good morrow", "by your leave", "godspeed", "begone", "good day", "good day, sirrah", "good day, sire", "good day, master", "adieu", "cheerio", "pleasant journey", "I bid thee good day", "I bid thee farewell"]);
    word("yes", ["aye", "yea", "yea verily"]);
    word("no", ["nay", "nayeth"]);
    word(["hello", "hi"], ["good day", "well met", "well meteth", "tally ho", "ave"]);
    word("does", ["doeseth", "dost", "doth"]);
    word(["kill", "gank"], ["slay", "vanquish", "bring low", "conquer", "fleece", "humble", "subjugate", "best", "foil"]);
    word("your", ["thy", "thine", "thyne"]);
    word("my", "mine");
    word("in", "within");
    word("flag", ["pennant", "banner", "colors", "heraldry"]);

    // 2
    word("walking", "a-walkin'");
    word("bet", "warrant");
    word("the", "ye");
    word("joke", ["jest", "jape"]);
    word(["balls", "groin"], ["leathers", "beans", "poundables", "nethers", "nadchakles", "buis", "fellahs", "coin purse"]);
    word("afk", ["away, fighting kobolds", "away, fruity knights", "aft, frisking knickers", "abaft, flailing knouts"]);
    word("map", "chart");
    word("please", ["I pray you", "prithee", "pray"]);
    word("ok", ["as you will", "agreed", "well said", "just so"]);
    word("is", "be");
    word("never", "ne'er");
    word(["haha", "hehe", "heh", "hah"], ["guffaw!", "cackle!", "oh, 'tis to laugh!", "zounds!", "chuckle!", "snigger!", "snort!", "snicker!", "cachinnate!", "titter!", "and there was much tittering!", "and there was much guffawing!", "and there was much chuckling!", "and there was much snorting!", "and there was much snickering!", "and there was much mirth!"]);
    word("assist", ["aid", "aideth", "saveth", "assistance", "succor"]);
    word("could", "couldst");
    word("would", "wouldst");
    word("sure", "shore");
    word("maybe", ["mayhaps", "perchance"]);
    word(["girl", "woman"], ["madame", "waif", "mistress", "lass", "lady", "goodwife", "maid", "maiden"]);
    word("later", "anon");
    word("often", "oft");
    word("really", ["indeed", "in truth"]);
    word("those", "yon");
    word("here", "hither");
    word("enough", "enow");
    word("child", "poppet");
    word("why", "wherefore");
    word("away", "aroint");
    word("being", "bein'");
    word("of", "o'");
    word("fucker", "swiver");
    word("shit", "nightsoil");
}

function yeolde(message) {
    var startmsg = arrRandom(startmsgs),
        endmsg = arrRandom(endmsgs),
        wrd, len, i;

    startmsg = startmsg
        .replace("<god>", arrRandom(gods))
        .replace("<god adjective>", arrRandom(godadjs))
        .replace("<body part>", arrRandom(bodyparts))
        .replace("<body part adjective>", arrRandom(bodypartadjs));

    message = message.replace(exclam, arrRandom(exclamrepl));
    message = message.replace(questi, arrRandom(questirepl));

    message = message.replace(insults, function () {
        var adjs = insultadj.slice(),
            adj1 = arrRandom(adjs),
            noun = arrRandom(insultnoun);

        adjs.splice(adjs.indexOf(adj1), 1);
        return adj1 + ", " + arrRandom(adjs) + ", " + noun;
    });

    for (i = 0, len = words.length; i < len; i += 1) {
        wrd = words[i];
        message = message.replace(wrd.regex, arrRandom(wrd.replacements));
    }

    if (["!", "?", ";", ",", "."].indexOf(message[message.length - 1]) === -1) {
        message += ".";
    }

    return startmsg + " " + message + " " + endmsg;
}

module.exports = {
    yeolde: yeolde,
    addWords: addWords,
    word: word,
    words: words
};

module.reload = function () {
    addWords();
    return true;
};
<commit_msg>Let's try a closure<commit_after>(function () {
    var words = [];

    var exclam = /\b!\b/g;
    var exclamrepl = [", verily!", ", verily I say!", ", verily I sayeth!", ", I say!", ", I sayeth!", "! Huzzah!", "! Hear Hear!", "! What-ho!", "! Ho!", "! Fie!", ", indeed!"];

    var questi = /\b\?\b/g;
    var questirepl = [", I say?", ", I wonder?", ", wonder I?", ", what say thee?", ", what sayeth thee?", ", what say thou?", ", what sayeth thou?", ", I ponder?", ", I pondereth?", ", pray tell?", ", ho?", ", do tell?"];

    var insults = /\bidiot\b|\bfool\b|\bbastard\b/gi;

    var insultnoun = ["mongrel", "codpiece", "jackanape", "ape", "coxcomb", "harlot", "hussy", "strumpet", "cur", "clot", "fool", "barnacle", "harpy", "wench", "churl", "pleb", "taffer", "scoundrel", "scalliwag", "mooncalf", "rapscallion", "doxy", "bawd", "tosspot", "cupshot", "recreant", "fustalarion", "scullion", "rampallion", "knave", "barbermonger", "boil", "plague-sore", "carbuncle", "whoreson", "clotpole", "lout", "gudgeon", "puttock", "skainsmate", "varlet", "bladder"];

    var insultadj = ["artless", "droning", "fawning", "warped", "paunchy", "puny", "spongy", "ruttish", "vain", "lumpish", "craven", "witless", "pustulent", "infested", "ill-bred", "blind", "scurvy", "puny", "fetid", "vile", "gibbering", "mewling", "rank", "fawning", "moonish", "brutish", "malapert", "curst", "lack-linen", "bottle-ailed", "lyingest", "embossed", "cheating", "crook-pated", "base-court", "hasty-witted", "two-faced", "pox-marked", "toad-brained", "errant", "idle-headed", "quailing", "flap-mouthed", "puking", "fly-bitten", "surly", "tottering", "villainous", "rump-fed", "bootless", "churlish", "tickle-brained", "froward"];

    var startmsgs = ["Forsooth,", "I say,", "I sayeth,", "Forsooth, I say,", "Forsooth, say I,", "Forsooth, sayeth I,", "Hark!", "Harketh!", "By <god>,", "By the Will of <god adjective> <god>,", "By the <body part adjective> <body part> of the <god adjective> <god>,", "By <god adjective> <god>'s <body part adjective> <body part>,", "Avast,", "Zounds,", "Perchance,", "Pray tell,", "Prithee,", "What hey,", "What ho,", "Pray,", "Surely", "Pray pardon,", "Alas,", "In short,", "My Lord,", "My Lady,", "By my faith,", "If it pleases you,", "I pray you,", "In truth,", "By my trowth,", "In sooth,", "By my word,", "S'wounds,", "Z'wounds,", "<god>'s wounds,", "<god>'s <body part>,", "Heigh-ho,", "Ah,", "Quoth I,", "Listen,", "Listen thee,", "Hear me,", "Now hear me,", "I warrant", "Come,", "Kind sire,", "Sire,", "There is much in what you say, and yet,"];
    var endmsgs = ["Anon!", "Hum.", "Good sir!", "Good sire!", "Milady!", "My Liege!", "Guvnor!"];

    var gods = ["Odin", "Bob", "Zeus", "Hera", "Thor", "Crom", "Mad-poet Navarth", "Cugel", "Wotsit", "Baron Boddisey", "Poseidon", "Saint Mary", "Pallus Athena", "Loki", "Erlik", "Shoggoth", "Omm", "Vishnu", "Azazoth", "Father Odin", "Allfather Odin", "Cthulhu", "Buddha", "Aphrodite", "Isis", "Kali", "Dionysus", "Zarathustra", "Croesus", "Hermes", "Venus", "Montezuma", "Popacatapetl", "Hephaestus", "Bubastes", "Bacchus", "Nebuchadnezzar", "Assurbanipal", "Sargon", "Xerxes", "Mulwatallish", "Labarna", "Hammurabi", "Rameses", "Minos", "Tilgath-Pileser", "Vercingetorix", "Mithradites", "Pericles", "Belasarius", "Archaemides", "Heraclius", "Imhotep", "Artemis", "Orthia", "Phoebe", "Hestia", "Eros", "Persephone", "Minerva", "Mercury", "Aesculapius", "Discordia", "Hecate", "Hespera"];

    var godadjs = ["Almighty", "Unthinkable", "Unknowable", "All-knowing", "All-seeing", "Lecherous", "Scandalous", "Merciful", "Ravaging", "Thunderous", "Wrathful", "Distant", "Vengeful", "Supreme", "Wise", "Warlike", "Jealous", "Vindictive", "Powerful", "Adulterous", "Licentious", "Crafty", "Benefical", "Virtuous", "Protective", "Prophetic", "Bloodthirsty", "Murderous", "Ruinous", "Militant", "Invisible", "Omnipotent", "Forgotten", "Enlightened", "Tempestuous", "Destructive", "Grim"];

    var bodyparts = ["Beard", "Third Leg", "Scalp", "Eye", "Thigh", "Arm", "Sword", "Heel", "Gaze", "Tongue", "Hammer", "Toenail", "Nether Regions", "Liver", "Lights", "Spleen", "Gall", "Liver and Lights"];

    var bodypartadjs = ["Unknowable", "Unescapable", "Unfathomable", "Unthinkable", "Righteous", "Hairy", "Hairless", "Wandering", "Blistered", "Awe-inspiring", "Toothy", "Ravaged", "Aged", "Endless", "Wondrous", "Unavoidable", "Pestilent", "Forgotten", "Beautiful", "Fertile", "Prophetic", "Musical", "Helpful", "Virginal", "Curative", "Bleak", "Incessant", "Sagely", "Unfashionable", "Unfaltering", "Unfamiliar", "Abysmal", "Boundless", "Eternal", "Immeasurable", "Infinite", "Unending", "Soundless", "Incomprehensible", "Inexplicable", "Profound", "Unintelligible", "Unbelievable", "Impenetrable", "Indecipherable", "Esoteric", "Enigmatic", "Ancient", "Venerable", "Baneful", "Contagious", "Corrupting", "Deadly", "Deleterious", "Evil", "Noxious", "Diseased", "Pernicious", "Pestiferous", "Pestilential", "Tainted", "Contaminated", "Pulchritudinous", "Odoriferous", "Misbegotten", "Sacriligio"];

    function arrRandom(arr) {
        return arr[sys.rand(0, arr.length)];
    }

    function word(original, replacement) {
        var len, i;

        if (!Array.isArray(original)) {
            original = [original];
        }
        if (!Array.isArray(replacement)) {
            replacement = [replacement];
        }

        for (i = 0, len = original.length; i < len; i += 1) {
            words.push({regex: new RegExp("\\b" + original[i] + "\\b", "gi"), replacements: replacement});
        }
    }

    // http://wiki.teamfortress.com/wiki/Medieval_Mode#Chat_parser
    function addWords() {
        words = [];

        // 1
        word(["it is", "it's"], "tis");
        word("it was", "'twas");
        word("it would", "'twould");
        word("it will", "'twill");
        word("it were", "'twere");
        word(["shall not", "will not"], "shan't");
        word("over there", "yonder");
        word("in the", "i' the");
        word("thank you", ["many good thanks to you", "thankee", "kindly thanks to you", "grammercy to you"]);
        word(["you", "u"], ["thou", "thee", "ye"]);
        word("are", "art");
        word("lol", ["lolleth", "lollery"]);
        word(["killed", "beaten"], ["slain", "vanquished", "brung low", "conquered", "fleeced", "humbled", "subjugated", "bested", "foiled"]);
        word(["goodbye", "bye", "seeya", "goodnight"], ["farewell", "fare thee well", "good morrow", "by your leave", "godspeed", "begone", "good day", "good day, sirrah", "good day, sire", "good day, master", "adieu", "cheerio", "pleasant journey", "I bid thee good day", "I bid thee farewell"]);
        word("yes", ["aye", "yea", "yea verily"]);
        word("no", ["nay", "nayeth"]);
        word(["hello", "hi"], ["good day", "well met", "well meteth", "tally ho", "ave"]);
        word("does", ["doeseth", "dost", "doth"]);
        word(["kill", "gank"], ["slay", "vanquish", "bring low", "conquer", "fleece", "humble", "subjugate", "best", "foil"]);
        word("your", ["thy", "thine", "thyne"]);
        word("my", "mine");
        word("in", "within");
        word("flag", ["pennant", "banner", "colors", "heraldry"]);

        // 2
        word("walking", "a-walkin'");
        word("bet", "warrant");
        word("the", "ye");
        word("joke", ["jest", "jape"]);
        word(["balls", "groin"], ["leathers", "beans", "poundables", "nethers", "nadchakles", "buis", "fellahs", "coin purse"]);
        word("afk", ["away, fighting kobolds", "away, fruity knights", "aft, frisking knickers", "abaft, flailing knouts"]);
        word("map", "chart");
        word("please", ["I pray you", "prithee", "pray"]);
        word("ok", ["as you will", "agreed", "well said", "just so"]);
        word("is", "be");
        word("never", "ne'er");
        word(["haha", "hehe", "heh", "hah"], ["guffaw!", "cackle!", "oh, 'tis to laugh!", "zounds!", "chuckle!", "snigger!", "snort!", "snicker!", "cachinnate!", "titter!", "and there was much tittering!", "and there was much guffawing!", "and there was much chuckling!", "and there was much snorting!", "and there was much snickering!", "and there was much mirth!"]);
        word("assist", ["aid", "aideth", "saveth", "assistance", "succor"]);
        word("could", "couldst");
        word("would", "wouldst");
        word("sure", "shore");
        word("maybe", ["mayhaps", "perchance"]);
        word(["girl", "woman"], ["madame", "waif", "mistress", "lass", "lady", "goodwife", "maid", "maiden"]);
        word("later", "anon");
        word("often", "oft");
        word("really", ["indeed", "in truth"]);
        word("those", "yon");
        word("here", "hither");
        word("enough", "enow");
        word("child", "poppet");
        word("why", "wherefore");
        word("away", "aroint");
        word("being", "bein'");
        word("of", "o'");
        word("fucker", "swiver");
        word("shit", "nightsoil");
    }

    function yeolde(message) {
        var startmsg = arrRandom(startmsgs),
            endmsg = arrRandom(endmsgs),
            wrd, len, i;

        startmsg = startmsg
            .replace("<god>", arrRandom(gods))
            .replace("<god adjective>", arrRandom(godadjs))
            .replace("<body part>", arrRandom(bodyparts))
            .replace("<body part adjective>", arrRandom(bodypartadjs));

        message = message.replace(exclam, arrRandom(exclamrepl));
        message = message.replace(questi, arrRandom(questirepl));

        message = message.replace(insults, function () {
            var adjs = insultadj.slice(),
                adj1 = arrRandom(adjs),
                noun = arrRandom(insultnoun);

            adjs.splice(adjs.indexOf(adj1), 1);
            return adj1 + ", " + arrRandom(adjs) + ", " + noun;
        });

        for (i = 0, len = words.length; i < len; i += 1) {
            wrd = words[i];
            message = message.replace(wrd.regex, arrRandom(wrd.replacements));
        }

        if (["!", "?", ";", ",", "."].indexOf(message[message.length - 1]) === -1) {
            message += ".";
        }

        return startmsg + " " + message + " " + endmsg;
    }

    module.exports = {
        yeolde: yeolde,
        addWords: addWords,
        word: word,
        words: words
    };

    module.reload = function () {
        addWords();
        return true;
    };
}());
<|endoftext|>


<commit_before>/* global $ */
function process_btn_press(element, state) {
    var popover = element.parents('.popover');
    var taskid = popover.prev().data('taskid');
    var data = {id: taskid, state: state};
    // send actual HTTP POST request to app
    // TODO: this is bad but whatever...
    $.post('/set_task_state', data, location.reload());
    // TODO error handling
    //popover.popover('hide');
}

// Init popovers
var popovers = $('[data-toggle="popover"]');
popovers.popover({
    placement: 'bottom',
    html: true,
    content: '
' +
             '<button type="button" class="btn btn-warning btn-backlog">Backlog</button>' +
             '<button type="button" class="btn btn-danger btn-todo">ToDo</button>' +
             '<button type="button" class="btn btn-success btn-done">Done</button>' +
             '
'
});
// Only one popover at a time
popovers.click(function(){
    popovers.not(this).popover('hide');
});
// Button events
$(document).on('click', '.popover .close', function(){
    $(this).parents('.popover').popover('hide');
});
$(document).on('click', '.btn-backlog', function(){
    process_btn_press($(this), 0);
});
$(document).on('click', '.btn-todo', function(){
    process_btn_press($(this), 1);
});
$(document).on('click', '.btn-done', function(){
    process_btn_press($(this), 2);
});
<commit_msg>Minor improvement for popover placement<commit_after>/* global $ */
function process_btn_press(element, state) {
    var popover = element.parents('.popover');
    var taskid = popover.prev().data('taskid');
    var data = {id: taskid, state: state};
    // send actual HTTP POST request to app
    // TODO: this is bad but whatever...
    $.post('/set_task_state', data, location.reload());
    // TODO error handling
    //popover.popover('hide');
}

// Init popovers
var popovers = $('[data-toggle="popover"]');
popovers.popover({
    placement: 'bottom auto',
    html: true,
    content: '
' +
             '<button type="button" class="btn btn-warning btn-backlog">Backlog</button>' +
             '<button type="button" class="btn btn-danger btn-todo">ToDo</button>' +
             '<button type="button" class="btn btn-success btn-done">Done</button>' +
             '
'
});
// Only one popover at a time
popovers.click(function(){
    popovers.not(this).popover('hide');
});
// Button events
$(document).on('click', '.popover .close', function(){
    $(this).parents('.popover').popover('hide');
});
$(document).on('click', '.btn-backlog', function(){
    process_btn_press($(this), 0);
});
$(document).on('click', '.btn-todo', function(){
    process_btn_press($(this), 1);
});
$(document).on('click', '.btn-done', function(){
    process_btn_press($(this), 2);
});
<|endoftext|>


<commit_before>
import "./saga"

// Constants
// taken from https://github.com/reactjs/react-router-redux/blob/master/src/index.js
const TRANSITION = "@@router/TRANSITION"
const UPDATE_LOCATION = "@@router/UPDATE_LOCATION"

const SELECT_LOCATION = state => state.routing.location

function transition(method) {
  return (...args) => ({
    type: TRANSITION,
    payload: { method, args }
  })
}

export const push = transition("push")
export const replace = transition("replace")
export const go = transition("go")
export const goBack = transition("goBack")
export const goForward = transition("goForward")

export const routeActions = { push, replace, go, goBack, goForward }

function updateLocation(location) {
  return {
    type: UPDATE_LOCATION,
    payload: location
  }
}

// Reducer

const initialState = {
  location: undefined
}

export function routeReducer(state = initialState, { type, payload: location }) {
  if (type !== UPDATE_LOCATION) {
    return state
  }

  return { ...state, location }
}

// Syncing

export function syncHistory(history) {
  let unsubscribeHistory, currentKey, unsubscribeStore
  let connected = false, syncing = false

  history.listen(location => { initialState.location = location })()

  function middleware(store) {
    unsubscribeHistory = history.listen(location => {
      currentKey = location.key
      if (syncing) {
        // Don't dispatch a new action if we're replaying location.
        return
      }
      let { routing } = store.getState()
      location.previous = routing.location.pathname
      store.dispatch(updateLocation(location))
    })

    connected = true

    return next => action => {
      if (action.type !== TRANSITION || !connected) {
        return next(action)
      }

      let { routing } = store.getState()

      let { payload: { method, args } } = action
      if (method === "goBack") {
        method = "push"
        args = [routing.location.previous]
      }

      history[method](...args)
    }
  }

  middleware.listenForReplays =
    (store, selectLocationState = SELECT_LOCATION) => {
      const getLocationState = () => selectLocationState(store.getState())
      const initialLocation = getLocationState()

      unsubscribeStore = store.subscribe(() => {
        const location = getLocationState()

        // If we're resetting to the beginning, use the saved initial value. We
        // need to dispatch a new action at this point to populate the store
        // appropriately.
        if (location.key === initialLocation.key) {
          history.replace(initialLocation)
          return
        }

        // Otherwise, if we need to update the history location, do so without
        // dispatching a new action, as we're just bringing history in sync
        // with the store.
        if (location.key !== currentKey) {
          syncing = true
          history.transitionTo(location)
          syncing = false
        }
      })
    }

  middleware.unsubscribe = () => {
    unsubscribeHistory()
    if (unsubscribeStore) {
      unsubscribeStore()
    }

    connected = false
  }

  return middleware
}
<commit_msg>proper back button support<commit_after>
import "./saga"

// Constants
// taken from https://github.com/reactjs/react-router-redux/blob/master/src/index.js
const TRANSITION = "@@router/TRANSITION"
const UPDATE_LOCATION = "@@router/UPDATE_LOCATION"

const SELECT_LOCATION = state => state.routing.location

function transition(method) {
  return (...args) => ({
    type: TRANSITION,
    payload: { method, args }
  })
}

export const push = transition("push")
export const replace = transition("replace")
export const go = transition("go")
export const goBack = transition("goBack")
export const goForward = transition("goForward")

export const routeActions = { push, replace, go, goBack, goForward }

function updateLocation(location) {
  return {
    type: UPDATE_LOCATION,
    payload: location
  }
}

// Reducer

const initialState = {
  location: undefined
}

export function routeReducer(state = initialState, { type, payload: location }) {
  if (type !== UPDATE_LOCATION) {
    return state
  }

  return { ...state, location }
}

// Syncing

export function syncHistory(history) {
  let unsubscribeHistory, currentKey, unsubscribeStore
  let connected = false, syncing = false

  history.listen(location => { initialState.location = location })()

  function middleware(store) {
    unsubscribeHistory = history.listen(location => {
      currentKey = location.key
      if (syncing) {
        // Don't dispatch a new action if we're replaying location.
        return
      }
      let { routing } = store.getState()
      location.previous || (location.previous = [])
      routing.location.previous || (routing.location.previous = [])

      if (routing.location.previous[routing.location.previous.length - 1] === location.pathname) {
        routing.location.previous.splice(-1)
        location.previous = routing.location.previous
      } else {
        location.previous = [...routing.location.previous, ...[routing.location.pathname]]
      }

      store.dispatch(updateLocation(location))
    })

    connected = true

    return next => action => {
      if (action.type !== TRANSITION || !connected) {
        return next(action)
      }

      let { routing } = store.getState()

      let { payload: { method, args } } = action
      if (method === "goBack") {
        method = "push"
        length  = routing.location.previous.length
        args = [routing.location.previous[length - 1]]
      }

      history[method](...args)
    }
  }

  middleware.listenForReplays =
    (store, selectLocationState = SELECT_LOCATION) => {
      const getLocationState = () => selectLocationState(store.getState())
      const initialLocation = getLocationState()

      unsubscribeStore = store.subscribe(() => {
        const location = getLocationState()

        // If we're resetting to the beginning, use the saved initial value. We
        // need to dispatch a new action at this point to populate the store
        // appropriately.
        if (location.key === initialLocation.key) {
          history.replace(initialLocation)
          return
        }

        // Otherwise, if we need to update the history location, do so without
        // dispatching a new action, as we're just bringing history in sync
        // with the store.
        if (location.key !== currentKey) {
          syncing = true
          history.transitionTo(location)
          syncing = false
        }
      })
    }

  middleware.unsubscribe = () => {
    unsubscribeHistory()
    if (unsubscribeStore) {
      unsubscribeStore()
    }

    connected = false
  }

  return middleware
}
<|endoftext|>


<commit_before>define([
  'intern!object',
  'intern/chai!expect',
  '../helper/fixtures/shadow-input.fixture',
  '../helper/dispatch-event',
  'ally/style/focus-source',
], function(registerSuite, expect, shadowInputFixture, dispatchEvent, styleFocusSource) {

  registerSuite(function() {
    var fixture;
    var handle;

    return {
      name: 'style/focus-source',

      beforeEach: function() {
        fixture = shadowInputFixture();
      },
      afterEach: function() {
        // make sure a failed test cannot leave listeners behind
        handle && handle.disengage({ force: true });
        fixture.remove();
        fixture = null;
      },

      lifecycle: function() {
        var deferred = this.async(1000);
        expect(document.documentElement.hasAttribute('data-focus-source')).to.equal(false, 'before engage');

        // initiate with delay because of IE10's async focus event from previous test
        setTimeout(deferred.callback(function() {
          handle = styleFocusSource();
          expect(handle.disengage).to.be.a('function');
          expect(handle.lock).to.be.a('function');
          expect(handle.current).to.be.a('function');
          expect(handle.used).to.be.a('function');

          expect(document.documentElement.getAttribute('data-focus-source')).to.equal('initial', 'attribute after engage');
          expect(handle.current()).to.equal('initial', 'current after engage');

          fixture.input.outer.focus();
          expect(document.activeElement).to.equal(fixture.input.outer, 'focus shift');
          expect(document.documentElement.getAttribute('data-focus-source')).to.equal('script', 'attribute focus shift');
          expect(handle.current()).to.equal('script', 'current focus shift');
          expect(handle.used('initial')).to.equal(true, 'used(initial) focus shift');
          expect(handle.used('script')).to.equal(true, 'used(script) focus shift');
          expect(handle.used('key')).to.equal(false, 'used(key) focus shift');
          expect(handle.used('pointer')).to.equal(false, 'used(pointer) focus shift');

          handle.disengage();
          handle = null;
          expect(document.documentElement.hasAttribute('data-focus-source')).to.equal(false, 'after disengage');
        }), 20);
      },
      key: function() {
        var deferred = this.async(1000);
        // initiate with delay because of IE10's async focus event from previous test
        setTimeout(deferred.rejectOnError(function() {
          handle = styleFocusSource();
          expect(handle.used('initial')).to.equal(true, 'used focus shift');

          dispatchEvent.key(document.documentElement, 'keydown', {
            key: 'Tab',
            keyCode: 9,
          });
          fixture.input.outer.focus();
          dispatchEvent.key(document.documentElement, 'keyup', {
            key: 'Tab',
            keyCode: 9,
          });

          expect(document.documentElement.getAttribute('data-focus-source')).to.equal('key', 'attribute after focus shift');
          expect(handle.current()).to.equal('key', 'current() after focus shift');
          expect(document.documentElement.classList.contains('focus-source-key')).to.equal(true, 'class after focus shift');
          expect(handle.used('key')).to.equal(true, 'used(key) after focus shift');
          expect(handle.used('pointer')).to.equal(false, 'used(pointer) after focus shift');

          // allow for observe/interaction-type disengaging async
          setTimeout(deferred.callback(function() {
            fixture.input.after.focus();
            expect(handle.current()).to.equal('script', 'current() after second focus shift');
          }), 20);
        }), 20);
      },
      pointer: function() {
        var deferred = this.async(1000);
        // initiate with delay because of IE10's async focus event from previous test
        setTimeout(deferred.rejectOnError(function() {
          handle = styleFocusSource();

          dispatchEvent.mouse(document.documentElement, 'mousedown', {});
          fixture.input.outer.focus();
          dispatchEvent.mouse(document.documentElement, 'mouseup', {});

          expect(document.documentElement.getAttribute('data-focus-source')).to.equal('pointer', 'attribute after focus shift');
          expect(handle.current()).to.equal('pointer', 'current() after focus shift');
          expect(document.documentElement.classList.contains('focus-source-pointer')).to.equal(true, 'class after focus shift');
          expect(handle.used('key')).to.equal(false, 'used(key) after focus shift');
          expect(handle.used('pointer')).to.equal(true, 'used(pointer) after focus shift');

          // allow for observe/interaction-type disengaging async
          setTimeout(deferred.callback(function() {
            fixture.input.after.focus();
            expect(handle.current()).to.equal('script', 'current() after second focus shift');
          }), 20);
        }), 20);
      },
      'lock()': function() {
        handle = styleFocusSource();

        dispatchEvent.mouse(document.documentElement, 'mousedown', {});
        fixture.input.outer.focus();
        dispatchEvent.mouse(document.documentElement, 'mouseup', {});

        expect(handle.current()).to.equal('pointer', 'current() after focus shift');

        handle.lock('key');
        fixture.input.after.focus();
        expect(handle.current()).to.equal('key', 'current() after second focus shift');

        fixture.input.outer.focus();
        expect(handle.current()).to.equal('key', 'current() after third focus shift');
      },
    };
  });
});
<commit_msg>chore(tests): bumping async timeouts, because WebDriver<commit_after>define([
  'intern!object',
  'intern/chai!expect',
  '../helper/fixtures/shadow-input.fixture',
  '../helper/dispatch-event',
  'ally/style/focus-source',
], function(registerSuite, expect, shadowInputFixture, dispatchEvent, styleFocusSource) {

  registerSuite(function() {
    var fixture;
    var handle;

    return {
      name: 'style/focus-source',

      beforeEach: function() {
        fixture = shadowInputFixture();
      },
      afterEach: function() {
        // make sure a failed test cannot leave listeners behind
        handle && handle.disengage({ force: true });
        fixture.remove();
        fixture = null;
      },

      lifecycle: function() {
        var deferred = this.async(1000);
        expect(document.documentElement.hasAttribute('data-focus-source')).to.equal(false, 'before engage');

        // initiate with delay because of IE10's async focus event from previous test
        setTimeout(deferred.callback(function() {
          handle = styleFocusSource();
          expect(handle.disengage).to.be.a('function');
          expect(handle.lock).to.be.a('function');
          expect(handle.current).to.be.a('function');
          expect(handle.used).to.be.a('function');

          expect(document.documentElement.getAttribute('data-focus-source')).to.equal('initial', 'attribute after engage');
          expect(handle.current()).to.equal('initial', 'current after engage');

          fixture.input.outer.focus();
          expect(document.activeElement).to.equal(fixture.input.outer, 'focus shift');
          expect(document.documentElement.getAttribute('data-focus-source')).to.equal('script', 'attribute focus shift');
          expect(handle.current()).to.equal('script', 'current focus shift');
          expect(handle.used('initial')).to.equal(true, 'used(initial) focus shift');
          expect(handle.used('script')).to.equal(true, 'used(script) focus shift');
          expect(handle.used('key')).to.equal(false, 'used(key) focus shift');
          expect(handle.used('pointer')).to.equal(false, 'used(pointer) focus shift');

          handle.disengage();
          handle = null;
          expect(document.documentElement.hasAttribute('data-focus-source')).to.equal(false, 'after disengage');
        }), 100);
      },
      key: function() {
        var deferred = this.async(1000);
        // initiate with delay because of IE10's async focus event from previous test
        setTimeout(deferred.rejectOnError(function() {
          handle = styleFocusSource();
          expect(handle.used('initial')).to.equal(true, 'used focus shift');

          dispatchEvent.key(document.documentElement, 'keydown', {
            key: 'Tab',
            keyCode: 9,
          });
          fixture.input.outer.focus();
          dispatchEvent.key(document.documentElement, 'keyup', {
            key: 'Tab',
            keyCode: 9,
          });

          expect(document.documentElement.getAttribute('data-focus-source')).to.equal('key', 'attribute after focus shift');
          expect(handle.current()).to.equal('key', 'current() after focus shift');
          expect(document.documentElement.classList.contains('focus-source-key')).to.equal(true, 'class after focus shift');
          expect(handle.used('key')).to.equal(true, 'used(key) after focus shift');
          expect(handle.used('pointer')).to.equal(false, 'used(pointer) after focus shift');

          // allow for observe/interaction-type disengaging async
          setTimeout(deferred.callback(function() {
            fixture.input.after.focus();
            expect(handle.current()).to.equal('script', 'current() after second focus shift');
          }), 100);
        }), 100);
      },
      pointer: function() {
        var deferred = this.async(1000);
        // initiate with delay because of IE10's async focus event from previous test
        setTimeout(deferred.rejectOnError(function() {
          handle = styleFocusSource();

          dispatchEvent.mouse(document.documentElement, 'mousedown', {});
          fixture.input.outer.focus();
          dispatchEvent.mouse(document.documentElement, 'mouseup', {});

          expect(document.documentElement.getAttribute('data-focus-source')).to.equal('pointer', 'attribute after focus shift');
          expect(handle.current()).to.equal('pointer', 'current() after focus shift');
          expect(document.documentElement.classList.contains('focus-source-pointer')).to.equal(true, 'class after focus shift');
          expect(handle.used('key')).to.equal(false, 'used(key) after focus shift');
          expect(handle.used('pointer')).to.equal(true, 'used(pointer) after focus shift');

          // allow for observe/interaction-type disengaging async
          setTimeout(deferred.callback(function() {
            fixture.input.after.focus();
            expect(handle.current()).to.equal('script', 'current() after second focus shift');
          }), 100);
        }), 100);
      },
      'lock()': function() {
        handle = styleFocusSource();

        dispatchEvent.mouse(document.documentElement, 'mousedown', {});
        fixture.input.outer.focus();
        dispatchEvent.mouse(document.documentElement, 'mouseup', {});

        expect(handle.current()).to.equal('pointer', 'current() after focus shift');

        handle.lock('key');
        fixture.input.after.focus();
        expect(handle.current()).to.equal('key', 'current() after second focus shift');

        fixture.input.outer.focus();
        expect(handle.current()).to.equal('key', 'current() after third focus shift');
      },
    };
  });
});
<|endoftext|>


<commit_before>'use strict'

const
  co = require('co'),
  path = require('path'),
  log = require('loglevel'),
  cpy = require('cpy'),
  del = require('del'),
  refresh = require('./refresh'),
  watch = require('./watch'),
  mkdirs = require('./mkdirs')

module.exports = co.wrap(function* (opts) {
  const
    loglevel = opts.debug ? log.levels.DEBUG : log.levels.ERROR,
    src = path.join(opts.root, opts.src),
    dest = path.join(opts.root, opts.cache)

  log.setLevel(loglevel, false)
  const
    patterns = opts.patterns.map(entry => `!${ entry.pattern }`),
    globs = ['**', '!**/.*'].concat(patterns)

  yield mkdirs(dest)
  yield del('**', { cwd: dest })
  log.debug('All files cleared')
  yield cpy(globs, dest, { cwd: src, nodir: true, ignore: opts.excludes })
  log.debug('All files copied except the files handled by Felt')
  yield refresh(opts)
  log.debug(`Exporting completed: ${ opts.cache }`)

  if (opts.watch) {
    watch(opts)
    log.debug('Watching started!')
  }
})
<commit_msg>fix static file directory on export.<commit_after>'use strict'

const
  co = require('co'),
  path = require('path'),
  log = require('loglevel'),
  cpy = require('cpy'),
  del = require('del'),
  refresh = require('./refresh'),
  watch = require('./watch'),
  mkdirs = require('./mkdirs')

module.exports = co.wrap(function* (opts) {
  const
    loglevel = opts.debug ? log.levels.DEBUG : log.levels.ERROR,
    src = path.join(opts.root, opts.src),
    dest = path.join(opts.root, opts.cache)

  log.setLevel(loglevel, false)
  const
    patterns = opts.patterns.map(entry => `!${ entry.pattern }`),
    globs = ['**', '!**/.*'].concat(patterns)

  yield mkdirs(dest)
  yield del('**', { cwd: dest })
  log.debug('All files cleared')
  yield cpy(globs, dest, { cwd: src, parents: true, nodir: true, ignore: opts.excludes })
  log.debug('All files copied except the files handled by Felt')
  yield refresh(opts)
  log.debug(`Exporting completed: ${ opts.cache }`)

  if (opts.watch) {
    watch(opts)
    log.debug('Watching started!')
  }
})
<|endoftext|>


<commit_before>// creating a TCP server

var net = require('net');

var server = net.createServer(function(socket) {
    // the socket has end method
    socket.end('Hello World');// Socket is a Duplex stream (those streams which are both readable and as well as writable)
});

server.listen(3000, function() {
    console.log("Server is listening on Port 3000");
});
<commit_msg>tcp server removed<commit_after><|endoftext|>


<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import onClickOutside from "react-onclickoutside"
import isEqual from 'lodash/isequal'

import { getStreams } from '../api'

require('./StreamSelector.less')

class StreamSelector extends Component {

    constructor(props) {
        super(props)
        this.state = {
            loadingStreams: false,
            streams: [],
            selectedStream: null,
            open: false,
            searchText: '',
        }
    }

    componentWillMount() {
        this.setState({ selectedStream: kango.storage.getItem('stream'),
                        streams: kango.storage.getItem('streams')
                      }, () => {
                            this.props.onStreamChange(this.state.selectedStream)
                      })
    }

    componentDidMount() {
        this.setState({ loadingStreams: true })
        this.updateStreams()
    }

    updateStreams = () => {
        getStreams()
            .then(data => {
                const streams = data.streams
                let { selectedStream } = this.state
                // if user selects new stream before updated streams load
                // users selection will be changed to most recently updated
                debugger
                let mostRecentStream = streams[0]

                kango.storage.setItem("stream", mostRecentStream)
                kango.storage.setItem("streams", streams)

                this.setState({ streams: streams, loadingStreams: false, selectedStream: mostRecentStream })
            })
            .catch(actualError => {
                this.setState({ loadingStreams: false })
                this.props.onError({
                    actualError,
                    message: "Could not load your streams.
Please try again later.",
                    closeBtn: true,
                })
            })
    }

    toggleDropDown = () => {
        this.setState({ open: !this.state.open })
    }

    handleStreamItemClick = (stream) => {
        this.setState({ selectedStream: stream }, () => {
            this.props.onStreamChange(stream)
        })
    }

    stopPropagation = (e) => {
        e.stopPropagation()
    }

    handleClickOutside = (e) => {
        this.setState({ open: false })
    }

    truncateName = (name) => {
        if (name.length > 30) {
            return `${name.slice(0, 30)}...`
        } else {
            return name
        }
    }

    handleSearch = (e) => {
        this.setState({ searchText: e.target.value })
    }

    findRecentStreams = () => {
        const { streams } = this.state
        let recentlyPostedStreams = []
        let remainingStreams = []

        for(let i = 0; i < streams.length; i++) {
            if (streams[i].content_added && i < 5) {
                recentlyPostedStreams.push(streams[i])
            } else {
                remainingStreams.push(streams[i])
            }
        }

        return { recentlyPostedStreams, remainingStreams }
    }

    renderStreamItem = (stream) => {
        return (

 this.handleStreamItemClick(stream)}
                className="stream-list-item"
            >
                {stream.name}

                {stream.owner.name}

        )
    }

    renderStreamsList(streams) {
        return (

              {
                  streams.map( stream => this.renderStreamItem(stream) )
              }

        )
    }

    renderSearchBar = () => {
        const { searchText } = this.state
        return (

                <input
                    onChange={this.handleSearch}
                    value={searchText}
                    type="text"
                    placeholder="Search streams..."
                />
                {
                    searchText !== '' &&
                     this.setState({ searchText: '' })}
                    />
                }

        )
    }

    renderDivider = (label, position) => {
        return (
            <div className={`divider-${position}`} onClick={this.stopPropagation}>
                {label}

        )
    }

    renderStreams = () => {
        const { recentlyPostedStreams, remainingStreams } = this.findRecentStreams()
        if (this.state.searchText === '') {
            return (

                  {
                      this.renderDivider('RECENT', 'top')
                  }
                  {
                      this.renderStreamsList(recentlyPostedStreams)
                  }
                  {
                      this.renderDivider('YOUR STREAMS', 'top')
                  }
                  {
                      this.renderStreamsList(remainingStreams)
                  }

            )
        } else {
            const { searchText, streams } = this.state

            const filteredStreams = streams.filter( stream => stream.name.toLowerCase().includes(searchText.toLowerCase()))

            return (

                    {
                        this.renderStreamsList(filteredStreams)
                    }

            )
        }
    }

    buildDropDown = () => {
        return (

                {
                    this.renderSearchBar()
                }
                {
                    this.renderDivider('', 'bottom')
                }
                {
                    this.renderStreams()
                }

        )
    }

    render() {
        const { selectedStream, open } = this.state

        return (

                {
                    selectedStream &&
                    {this.truncateName(selectedStream.name)}
                }
                {
                    open &&
                    this.buildDropDown()
                }

        )
    }
}

export default onClickOutside(StreamSelector)
<commit_msg>Display all streams, not remaining ones<commit_after>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import onClickOutside from "react-onclickoutside"
import isEqual from 'lodash/isequal'

import { getStreams } from '../api'

require('./StreamSelector.less')

class StreamSelector extends Component {

    constructor(props) {
        super(props)
        this.state = {
            loadingStreams: false,
            streams: [],
            selectedStream: null,
            open: false,
            searchText: '',
        }
    }

    componentWillMount() {
        this.setState({ selectedStream: kango.storage.getItem('stream'),
                        streams: kango.storage.getItem('streams')
                      }, () => {
                            this.props.onStreamChange(this.state.selectedStream)
                      })
    }

    componentDidMount() {
        this.setState({ loadingStreams: true })
        this.updateStreams()
    }

    updateStreams = () => {
        getStreams()
            .then(data => {
                const streams = data.streams
                let { selectedStream } = this.state
                // if user selects new stream before updated streams load
                // users selection will be changed to most recently updated
                let mostRecentStream = streams[0]

                kango.storage.setItem("stream", mostRecentStream)
                kango.storage.setItem("streams", streams)

                this.setState({ streams: streams, loadingStreams: false, selectedStream: mostRecentStream })
            })
            .catch(actualError => {
                this.setState({ loadingStreams: false })
                this.props.onError({
                    actualError,
                    message: "Could not load your streams.
Please try again later.",
                    closeBtn: true,
                })
            })
    }

    toggleDropDown = () => {
        this.setState({ open: !this.state.open })
    }

    handleStreamItemClick = (stream) => {
        this.setState({ selectedStream: stream }, () => {
            this.props.onStreamChange(stream)
        })
    }

    stopPropagation = (e) => {
        e.stopPropagation()
    }

    handleClickOutside = (e) => {
        this.setState({ open: false })
    }

    truncateName = (name) => {
        if (name.length > 30) {
            return `${name.slice(0, 30)}...`
        } else {
            return name
        }
    }

    handleSearch = (e) => {
        this.setState({ searchText: e.target.value })
    }

    findRecentStreams = () => {
        const { streams } = this.state
        let recentlyPostedStreams = []

        for(let i = 0; i < streams.length; i++) {
            if (streams[i].content_added && i < 5) {
                recentlyPostedStreams.push(streams[i])
            }
        }

        return { recentlyPostedStreams, streams }
    }

    renderStreamItem = (stream) => {
        return (

 this.handleStreamItemClick(stream)}
                className="stream-list-item"
            >
                {stream.name}

                {stream.owner.name}

        )
    }

    renderStreamsList(streams) {
        return (

              {
                  streams.map( stream => this.renderStreamItem(stream) )
              }

        )
    }

    renderSearchBar = () => {
        const { searchText } = this.state
        return (

                <input
                    onChange={this.handleSearch}
                    value={searchText}
                    type="text"
                    placeholder="Search streams..."
                />
                {
                    searchText !== '' &&
                     this.setState({ searchText: '' })}
                    />
                }

        )
    }

    renderDivider = (label, position) => {
        return (
            <div className={`divider-${position}`} onClick={this.stopPropagation}>
                {label}

        )
    }

    renderStreams = () => {
        const { recentlyPostedStreams, streams } = this.findRecentStreams()
        if (this.state.searchText === '') {
            return (

                  {
                      this.renderDivider('RECENT', 'top')
                  }
                  {
                      this.renderStreamsList(recentlyPostedStreams)
                  }
                  {
                      this.renderDivider('YOUR STREAMS', 'top')
                  }
                  {
                      this.renderStreamsList(streams)
                  }

            )
        } else {
            const { searchText, streams } = this.state

            const filteredStreams = streams.filter( stream => stream.name.toLowerCase().includes(searchText.toLowerCase()))

            return (

                    {
                        this.renderStreamsList(filteredStreams)
                    }

            )
        }
    }

    buildDropDown = () => {
        return (

                {
                    this.renderSearchBar()
                }
                {
                    this.renderDivider('', 'bottom')
                }
                {
                    this.renderStreams()
                }

        )
    }

    render() {
        const { selectedStream, open } = this.state

        return (

                {
                    selectedStream &&
                    {this.truncateName(selectedStream.name)}
                }
                {
                    open &&
                    this.buildDropDown()
                }

        )
    }
}

export default onClickOutside(StreamSelector)
<|endoftext|>


<commit_before>'use strict';
var AV = require('leancloud-storage/live-query');

AV._config.disableCurrentUser = true;

if (process.env.LEANCLOUD_REGION) {
  AV._config.region = process.env.LEANCLOUD_REGION;
}

if (process.env.LEANCLOUD_APP_ANDX_KEY) {
  AV._config.androidxKey = process.env.LEANCLOUD_APP_ANDX_KEY;
}

if (process.env.LC_API_SERVER) {
  AV.setServerURLs(process.env.LC_API_SERVER);
}

if (process.env.LEANCLOUD_API_SERVER) {
  AV.setServerURLs(process.env.LEANCLOUD_API_SERVER);
}

AV._sharedConfig.userAgent = 'AVOS Cloud Code Node ' + require('../package').version;
AV.Cloud.__prod = process.env.NODE_ENV === 'production' ? 1 : 0;
AV.setProduction(AV.Cloud.__prod);

module.exports = AV;
<commit_msg>:twisted_rightwards_arrows: Merge pull request #148 from leancloud/init<commit_after>'use strict';
var AV = require('leancloud-storage/live-query');

AV._config.disableCurrentUser = true;

if (process.env.LEANCLOUD_REGION) {
  AV._config.region = process.env.LEANCLOUD_REGION;
}

if (process.env.LEANCLOUD_APP_ANDX_KEY) {
  AV._config.androidxKey = process.env.LEANCLOUD_APP_ANDX_KEY;
}

if (process.env.LC_API_SERVER) {
  AV.setServerURLs(process.env.LC_API_SERVER);
}

if (process.env.LEANCLOUD_API_SERVER) {
  AV.setServerURLs(process.env.LEANCLOUD_API_SERVER);
}

if (AV.version && !AV.version.match(/^[0123]\./)) {
  AV._config.applicationId = process.env.LEANCLOUD_APP_ID;
  AV._config.applicationKey = process.env.LEANCLOUD_APP_KEY;
  AV._config.masterKey = process.env.LEANCLOUD_APP_MASTER_KEY;
  AV._config.hookKey = process.env.LEANCLOUD_APP_HOOK_KEY;
}

AV._sharedConfig.userAgent = 'AVOS Cloud Code Node ' + require('../package').version;
AV.Cloud.__prod = process.env.NODE_ENV === 'production' ? 1 : 0;
AV.setProduction(AV.Cloud.__prod);

module.exports = AV;
<|endoftext|>