<commit_before>// --------------------
// Sequelize hierarchy
// Shims to model instance methods
// --------------------

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

// exports

module.exports = function(Sequelize) {
	var Promise = Sequelize.Promise;
	var Utils = utils(Sequelize);
	var _ = Utils._;

	// return hooks
	return {
		beforeCreate: function(item, options) {
			var model = item.Model;
			var hierarchy = model.hierarchy;
			var values = item.dataValues;
			var parentId = values[hierarchy.foreignKey];
			var levelFieldName = hierarchy.levelFieldName;

			// if no parent, set level and exit - no ancestor records to create
			if (!parentId) {
				values[levelFieldName] = 1;
				return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned
			}

			// set level based on parent
			var queryOptions = {where: {}, attributes: [levelFieldName]};
			queryOptions.where[model.primaryKeyAttribute] = parentId;

			return model.find(queryOptions, {raw: true, transaction: options.transaction}).then(function(parent) {
				// set hierarchy level
				values[levelFieldName] = parent[levelFieldName] + 1;
			});
		},
		afterCreate: function(item, options) {
			var model = item.Model;
			var hierarchy = model.hierarchy;
			var values = item.dataValues;
			var parentId = values[hierarchy.foreignKey];

			// if no parent, exit - no hierarchy to create
			if (!parentId) return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned

			// create row in hierarchy table for parent
			var itemId = item[model.primaryKeyAttribute];
			var through = hierarchy.through;

			return Promise.try(function() {
				// get ancestors

				// if parent is at top level, has no ancestors
				if (values[hierarchy.levelFieldName] == 2) return [];

				// get parent's ancestors
				var queryOptions = {where: {}, attributes: [hierarchy.throughForeignKey]};
				queryOptions.where[hierarchy.throughKey] = parentId;

				return through.findAll(queryOptions, {raw: true, transaction: options.transaction});
			})
			.then(function(ancestors) {
				// add parent as ancestor
				var parentValues = {};
				parentValues[hierarchy.throughForeignKey] = parentId;
				ancestors.push(parentValues);
				return ancestors;
			})
			.then(function(ancestors) {
				// save ancestors
				ancestors = ancestors.map(function(ancestor) {
					ancestor[hierarchy.throughKey] = itemId;
					return ancestor;
				});

				return through.bulkCreate(ancestors, {transaction: options.transaction});
			})
			.return();
		},

		beforeUpdate: function(item, options) {
			var model = item.Model;
			var sequelize = model.sequelize;
			var hierarchy = model.hierarchy;

			// NB this presumes item has not been updated since it was originally retrieved
			var parentId = item.dataValues[hierarchy.foreignKey];
			var oldParentId = item._previousDataValues[hierarchy.foreignKey];

			// if parent has not changed, exit - no change to make
			if (parentId === oldParentId) return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned

			return Promise.try(function() {
				// check that not trying to make item a child of one of its own children
				if (parentId === null) return;

				var where = {};
				where[hierarchy.throughKey] = parentId;
				where[hierarchy.throughForeignKey] = item[model.primaryKeyAttribute];

				return hierarchy.through.find({where: where}, {transaction: options.transaction}).then(function(illegalItem) {
					if (illegalItem) throw new Error('Parent cannot be a child of itself');
				})
			})
			.then(function() {
				// get parent's level
				if (parentId === null) return 0;

				var where = {};
				where[model.primaryKeyAttribute] = parentId;

				return model.find({where: where, attributes: [hierarchy.levelFieldName]}, {raw: true, transaction: options.transaction}).then(function(parent) {
					if (!parent) throw new Error('Parent does not exist');

					return parent[hierarchy.levelFieldName];
				});
			})
			.then(function(parentLevel) {
				// set hierarchy level
				var newLevel = parentLevel + 1;
				var levelChange = newLevel - item._previousDataValues[hierarchy.levelFieldName];

				item.dataValues[hierarchy.levelFieldName] = newLevel;

				// update level and hierarchy table
				return Promise.try(function() {
					if (!levelChange) return;

					// update hierarchy level for all descendents
					var sql = replaceIdentifiers(
						'UPDATE *Item '
						+ 'SET *level = *level + :levelChange '
						+ 'WHERE *id IN ('
						+ '		SELECT *itemId '
						+ '		FROM *Through AS Ancestors '
						+ '		WHERE Ancestors.*ancestorId = :id'
						+ ')',
						{
							Item: model.tableName,
							Through: hierarchy.through.tableName,
							level: hierarchy.levelFieldName,
							id: model.primaryKeyAttribute,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id, levelChange: levelChange});
				})
				.then(function() {
					// delete ancestors from hierarchy table for item and all descendents
					if (oldParentId === null) return;

					var throughTableName = escapeIdentifier(hierarchy.through.tableName);
					var throughKey = escapeIdentifier(hierarchy.throughKey);
					var throughForeignKey = escapeIdentifier(hierarchy.throughForeignKey);

					var sql = replaceIdentifiers(
						'DELETE Deleters '
						+ 'FROM *Through AS Deleters '
						+ 'INNER JOIN *Through AS Descendents ON Descendents.*itemId = Deleters.*itemId '
						+ 'INNER JOIN *Through AS Ancestors ON Ancestors.*ancestorId = Deleters.*ancestorId '
						+ 'WHERE Ancestors.*itemId = :id '
						+ '		AND ('
						+ '			Descendents.*ancestorId = :id '
						+ '			OR Descendents.*itemId = :id'
						+ '		)',
						{
							Through: hierarchy.through.tableName,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id});
				})
				.then(function() {
					// insert ancestors into hierarchy table for item and all descendents
					if (parentId === null) return;

					var sql = replaceIdentifiers(
						'INSERT INTO *Through (*itemId, *ancestorId) '
						+ 'SELECT Descendents.*itemId, Ancestors.*ancestorId '
						+ 'FROM ( '
						+ '			SELECT *itemId '
						+ '			FROM *Through '
						+ '			WHERE *ancestorId = :id '
						+ '			UNION '
						+ '			SELECT :id '
						+ '		) AS Descendents '
						+ '		INNER JOIN ('
						+ '			SELECT *ancestorId '
						+ '			FROM *Through '
						+ '			WHERE *itemId = :parentId '
						+ '			UNION '
						+ '			SELECT :parentId'
						+ '		) AS Ancestors',
						{
							Through: hierarchy.through.tableName,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id, parentId: parentId});
				});
			})
			.return();
		},

		beforeFind: function(options) {
			// check options do not include illegal hierarchies
			if (options.hierarchy) throw new Error('You cannot get hierarchy of ' + this.name + ' - at top level with find()');
			checkHierarchy(options, this);

			return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned
		},
		afterFind: function(result, options) {
			// convert hierarchies into trees
			convertHierarchies(result, options, this);

			return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned
		},

		beforeFindAll: function(options) {
			// check options do not include illegal hierarchies
			if (options.hierarchy && !this.hierarchy) throw new Error('You cannot get hierarchy of ' + this.name + ' - it is not hierarchical');
			checkHierarchy(options, this);

			return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned
		},
		afterFindAll: function(results, options) {
			// convert hierarchies into trees
			convertHierarchies(results, options, this);

			return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned
		}
	};

	function replaceIdentifiers(sql, identifiers)
	{
		_.forIn(identifiers, function(replacement, identifier) {
			sql = sql.replace(new RegExp('\\*' + identifier, 'g'), escapeIdentifier(replacement));
		});
		return sql.replace(/[ \t\r\n]+/g, ' ');
	}

	function escapeIdentifier(identifier)
	{
		return '`' + identifier.replace(/`/g, '``') + '`';
	}

	function checkHierarchy(options, model)
	{
		// check options do not include illegal hierarchies - throw error if so
		(function traverse(options, model) {
			if (options.include) {
				options.include.forEach(function(include) {
					var includeModel = include.model;
					var accessor = _.uncapitalize(include.as);

					// if hierarchy set, check is legal
					if (include.hierarchy) {
						if (!includeModel.hierarchy) throw new Error('You cannot get hierarchy of ' + includeModel.name + ' - it is not hierarchical');
						if (includeModel !== model) throw new Error('You cannot get a hierarchy of ' + includeModel.name + ' without including it from a parent');
						if (include.as !== model.hierarchy.descendentsAs) throw new Error('You cannot set hierarchy on ' + model.name + ' without using the ' + model.hierarchy.descendentsAs + ' accessor');
					}

					// check includes
					traverse(include, includeModel);
				});
			}
		})(options, model);
	}

	function convertHierarchies(results, options, model)
	{
		// convert hierarchies into trees
		(function traverse(results, options, model, parent) {
			if (options.hierarchy) convertHierarchy(results, model, parent);

			if (options.include) {
				options.include.forEach(function(include) {
					var includeModel = include.model;
					var accessor = _.uncapitalize(include.as);

					if (Array.isArray(results)) {
						results.forEach(function(result) {
							traverse(result[accessor], include, includeModel, result);
						});
					} else {
						traverse(results[accessor], include, includeModel, results);
					}
				});
			}
		})(results, options, model, null);
	}

	function convertHierarchy(results, model, parent)
	{
		var hierarchy = model.hierarchy;
		var primaryKey = model.primaryKeyAttribute;
		var foreignKey = hierarchy.foreignKey;
		var childsAccessor = _.uncapitalize(hierarchy.childsAs);
		var descendentsAccessor = _.uncapitalize(hierarchy.descendentsAs);
		var throughAccessor = _.uncapitalize(Utils.singularize(hierarchy.through.name));

		// get parent id and move results from parent.descendents to parent.childs
		var parentId = null;
		if (parent) {
			parentId = parent[primaryKey];

			parent.dataValues[childsAccessor] = parent[childsAccessor] = results;
			delete parent[descendentsAccessor];
			delete parent.dataValues[descendentsAccessor];
		}

		// run through all results, turning into tree

		// find rows which are not top level and move into references
		var references = {};

		for (var i = 0; i < results.length; i++) {
			var item = results[i];

			// remove reference to through table
			delete item[throughAccessor];
			delete item.dataValues[throughAccessor];

			// add into references
			references[item[primaryKey]] = item;

			// if not a root-level item, remove from results
			if (item[foreignKey] !== parentId) {
				results.splice(i, 1);
				i--;
			}
		}

		// run through references, nesting within parents
		_.forIn(references, function(item) {
			// nest inside parent
			var thisParentId = item[foreignKey];
			if (thisParentId !== parentId) {
				var parent = references[thisParentId];
				if (!parent[childsAccessor]) parent.dataValues[childsAccessor] = parent[childsAccessor] = [];
				parent[childsAccessor].push(item);
			}
		});
	}
};
<commit_msg>process includes before hierarchies<commit_after>// --------------------
// Sequelize hierarchy
// Shims to model instance methods
// --------------------

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

// exports

module.exports = function(Sequelize) {
	var Promise = Sequelize.Promise;
	var Utils = utils(Sequelize);
	var _ = Utils._;

	// return hooks
	return {
		beforeCreate: function(item, options) {
			var model = item.Model;
			var hierarchy = model.hierarchy;
			var values = item.dataValues;
			var parentId = values[hierarchy.foreignKey];
			var levelFieldName = hierarchy.levelFieldName;

			// if no parent, set level and exit - no ancestor records to create
			if (!parentId) {
				values[levelFieldName] = 1;
				return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned
			}

			// set level based on parent
			var queryOptions = {where: {}, attributes: [levelFieldName]};
			queryOptions.where[model.primaryKeyAttribute] = parentId;

			return model.find(queryOptions, {raw: true, transaction: options.transaction}).then(function(parent) {
				// set hierarchy level
				values[levelFieldName] = parent[levelFieldName] + 1;
			});
		},
		afterCreate: function(item, options) {
			var model = item.Model;
			var hierarchy = model.hierarchy;
			var values = item.dataValues;
			var parentId = values[hierarchy.foreignKey];

			// if no parent, exit - no hierarchy to create
			if (!parentId) return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned

			// create row in hierarchy table for parent
			var itemId = item[model.primaryKeyAttribute];
			var through = hierarchy.through;

			return Promise.try(function() {
				// get ancestors

				// if parent is at top level, has no ancestors
				if (values[hierarchy.levelFieldName] == 2) return [];

				// get parent's ancestors
				var queryOptions = {where: {}, attributes: [hierarchy.throughForeignKey]};
				queryOptions.where[hierarchy.throughKey] = parentId;

				return through.findAll(queryOptions, {raw: true, transaction: options.transaction});
			})
			.then(function(ancestors) {
				// add parent as ancestor
				var parentValues = {};
				parentValues[hierarchy.throughForeignKey] = parentId;
				ancestors.push(parentValues);
				return ancestors;
			})
			.then(function(ancestors) {
				// save ancestors
				ancestors = ancestors.map(function(ancestor) {
					ancestor[hierarchy.throughKey] = itemId;
					return ancestor;
				});

				return through.bulkCreate(ancestors, {transaction: options.transaction});
			})
			.return();
		},

		beforeUpdate: function(item, options) {
			var model = item.Model;
			var sequelize = model.sequelize;
			var hierarchy = model.hierarchy;

			// NB this presumes item has not been updated since it was originally retrieved
			var parentId = item.dataValues[hierarchy.foreignKey];
			var oldParentId = item._previousDataValues[hierarchy.foreignKey];

			// if parent has not changed, exit - no change to make
			if (parentId === oldParentId) return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned

			return Promise.try(function() {
				// check that not trying to make item a child of one of its own children
				if (parentId === null) return;

				var where = {};
				where[hierarchy.throughKey] = parentId;
				where[hierarchy.throughForeignKey] = item[model.primaryKeyAttribute];

				return hierarchy.through.find({where: where}, {transaction: options.transaction}).then(function(illegalItem) {
					if (illegalItem) throw new Error('Parent cannot be a child of itself');
				})
			})
			.then(function() {
				// get parent's level
				if (parentId === null) return 0;

				var where = {};
				where[model.primaryKeyAttribute] = parentId;

				return model.find({where: where, attributes: [hierarchy.levelFieldName]}, {raw: true, transaction: options.transaction}).then(function(parent) {
					if (!parent) throw new Error('Parent does not exist');

					return parent[hierarchy.levelFieldName];
				});
			})
			.then(function(parentLevel) {
				// set hierarchy level
				var newLevel = parentLevel + 1;
				var levelChange = newLevel - item._previousDataValues[hierarchy.levelFieldName];

				item.dataValues[hierarchy.levelFieldName] = newLevel;

				// update level and hierarchy table
				return Promise.try(function() {
					if (!levelChange) return;

					// update hierarchy level for all descendents
					var sql = replaceIdentifiers(
						'UPDATE *Item '
						+ 'SET *level = *level + :levelChange '
						+ 'WHERE *id IN ('
						+ '		SELECT *itemId '
						+ '		FROM *Through AS Ancestors '
						+ '		WHERE Ancestors.*ancestorId = :id'
						+ ')',
						{
							Item: model.tableName,
							Through: hierarchy.through.tableName,
							level: hierarchy.levelFieldName,
							id: model.primaryKeyAttribute,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id, levelChange: levelChange});
				})
				.then(function() {
					// delete ancestors from hierarchy table for item and all descendents
					if (oldParentId === null) return;

					var throughTableName = escapeIdentifier(hierarchy.through.tableName);
					var throughKey = escapeIdentifier(hierarchy.throughKey);
					var throughForeignKey = escapeIdentifier(hierarchy.throughForeignKey);

					var sql = replaceIdentifiers(
						'DELETE Deleters '
						+ 'FROM *Through AS Deleters '
						+ 'INNER JOIN *Through AS Descendents ON Descendents.*itemId = Deleters.*itemId '
						+ 'INNER JOIN *Through AS Ancestors ON Ancestors.*ancestorId = Deleters.*ancestorId '
						+ 'WHERE Ancestors.*itemId = :id '
						+ '		AND ('
						+ '			Descendents.*ancestorId = :id '
						+ '			OR Descendents.*itemId = :id'
						+ '		)',
						{
							Through: hierarchy.through.tableName,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id});
				})
				.then(function() {
					// insert ancestors into hierarchy table for item and all descendents
					if (parentId === null) return;

					var sql = replaceIdentifiers(
						'INSERT INTO *Through (*itemId, *ancestorId) '
						+ 'SELECT Descendents.*itemId, Ancestors.*ancestorId '
						+ 'FROM ( '
						+ '			SELECT *itemId '
						+ '			FROM *Through '
						+ '			WHERE *ancestorId = :id '
						+ '			UNION '
						+ '			SELECT :id '
						+ '		) AS Descendents '
						+ '		INNER JOIN ('
						+ '			SELECT *ancestorId '
						+ '			FROM *Through '
						+ '			WHERE *itemId = :parentId '
						+ '			UNION '
						+ '			SELECT :parentId'
						+ '		) AS Ancestors',
						{
							Through: hierarchy.through.tableName,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id, parentId: parentId});
				});
			})
			.return();
		},

		beforeFind: function(options) {
			// check options do not include illegal hierarchies
			if (options.hierarchy) throw new Error('You cannot get hierarchy of ' + this.name + ' - at top level with find()');
			checkHierarchy(options, this);

			return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned
		},
		afterFind: function(result, options) {
			// convert hierarchies into trees
			convertHierarchies(result, options, this);

			return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned
		},

		beforeFindAll: function(options) {
			// check options do not include illegal hierarchies
			if (options.hierarchy && !this.hierarchy) throw new Error('You cannot get hierarchy of ' + this.name + ' - it is not hierarchical');
			checkHierarchy(options, this);

			return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned
		},
		afterFindAll: function(results, options) {
			// convert hierarchies into trees
			convertHierarchies(results, options, this);

			return Promise.resolve(); //xxx this line should not be neccesary but sequelize wants a promise returned
		}
	};

	function replaceIdentifiers(sql, identifiers)
	{
		_.forIn(identifiers, function(replacement, identifier) {
			sql = sql.replace(new RegExp('\\*' + identifier, 'g'), escapeIdentifier(replacement));
		});
		return sql.replace(/[ \t\r\n]+/g, ' ');
	}

	function escapeIdentifier(identifier)
	{
		return '`' + identifier.replace(/`/g, '``') + '`';
	}

	function checkHierarchy(options, model)
	{
		// check options do not include illegal hierarchies - throw error if so
		(function traverse(options, model) {
			if (options.include) {
				options.include.forEach(function(include) {
					var includeModel = include.model;

					// if hierarchy set, check is legal
					if (include.hierarchy) {
						if (!includeModel.hierarchy) throw new Error('You cannot get hierarchy of ' + includeModel.name + ' - it is not hierarchical');
						if (includeModel !== model) throw new Error('You cannot get a hierarchy of ' + includeModel.name + ' without including it from a parent');
						if (include.as !== model.hierarchy.descendentsAs) throw new Error('You cannot set hierarchy on ' + model.name + ' without using the ' + model.hierarchy.descendentsAs + ' accessor');
					}

					// check includes
					traverse(include, includeModel);
				});
			}
		})(options, model);
	}

	function convertHierarchies(results, options, model)
	{
		// convert hierarchies into trees
		(function traverse(results, options, model, parent) {
			if (options.include) {
				options.include.forEach(function(include) {
					var includeModel = include.model;
					var accessor = _.uncapitalize(include.as);

					if (Array.isArray(results)) {
						results.forEach(function(result) {
							traverse(result[accessor], include, includeModel, result);
						});
					} else {
						traverse(results[accessor], include, includeModel, results);
					}
				});
			}

			if (options.hierarchy) convertHierarchy(results, model, parent);
		})(results, options, model, null);
	}

	function convertHierarchy(results, model, parent)
	{
		var hierarchy = model.hierarchy;
		var primaryKey = model.primaryKeyAttribute;
		var foreignKey = hierarchy.foreignKey;
		var childsAccessor = _.uncapitalize(hierarchy.childsAs);
		var descendentsAccessor = _.uncapitalize(hierarchy.descendentsAs);
		var throughAccessor = _.uncapitalize(Utils.singularize(hierarchy.through.name));

		// get parent id and move results from parent.descendents to parent.childs
		var parentId = null;
		if (parent) {
			parentId = parent[primaryKey];

			parent.dataValues[childsAccessor] = parent[childsAccessor] = results;
			delete parent[descendentsAccessor];
			delete parent.dataValues[descendentsAccessor];
		}

		// run through all results, turning into tree

		// find rows which are not top level and move into references
		var references = {};

		for (var i = 0; i < results.length; i++) {
			var item = results[i];

			// remove reference to through table
			delete item[throughAccessor];
			delete item.dataValues[throughAccessor];

			// add into references
			references[item[primaryKey]] = item;

			// if not a root-level item, remove from results
			if (item[foreignKey] !== parentId) {
				results.splice(i, 1);
				i--;
			}
		}

		// run through references, nesting within parents
		_.forIn(references, function(item) {
			// nest inside parent
			var thisParentId = item[foreignKey];
			if (thisParentId !== parentId) {
				var parent = references[thisParentId];
				if (!parent[childsAccessor]) parent.dataValues[childsAccessor] = parent[childsAccessor] = [];
				parent[childsAccessor].push(item);
			}
		});
	}
};
<|endoftext|>


<commit_before>/*
 * It provides a abstraction layer over native javascript Websocket.
 *
 * Provide additional functionality like if connection is close, open
 * it again and process the buffered requests
 *
 *
 * Usage:
 *
 * `BinarySocket.init()` to initiate the connection
 * `BinarySocket.send({contracts_for : 1})` to send message to server
 */
function BinarySocketClass() {
    'use strict';

    var binarySocket,
        bufferedSends = [],
        manualClosed = false,
        events = {},
        authorized = false,
        timeouts = {},
        req_number = 0,
        socketUrl = getSocketURL() + '?app_id=' + getAppId() + (page.language() ? '&l=' + page.language() : '');

    var clearTimeouts = function(){
        for(var k in timeouts){
            if(timeouts.hasOwnProperty(k)){
                clearTimeout(timeouts[k]);
                delete timeouts[k];
            }
        }
    };

    var status = function () {
        return binarySocket && binarySocket.readyState;
    };

    var isReady = function () {
        return binarySocket && binarySocket.readyState === 1;
    };

    var isClose = function () {
        return !binarySocket || binarySocket.readyState === 2 || binarySocket.readyState === 3;
    };

    var sendBufferedSends = function () {
        while (bufferedSends.length > 0) {
            binarySocket.send(JSON.stringify(bufferedSends.shift()));
        }
    };

    var send = function(data) {
        if (isClose()) {
            bufferedSends.push(data);
            init(1);
        } else if (isReady()) {
            if(!data.hasOwnProperty('passthrough') && !data.hasOwnProperty('verify_email')){
                data.passthrough = {};
            }
            // temporary check
            if((data.contracts_for || data.proposal) && !data.passthrough.hasOwnProperty('dispatch_to')){
                data.passthrough.req_number = ++req_number;
                timeouts[req_number] = setTimeout(function(){
                    if(typeof reloadPage === 'function' && data.contracts_for){
                        alert("The server didn't respond to the request:\n\n"+JSON.stringify(data)+"\n\n");
                        reloadPage();
                    }
                    else{
                        $('.price_container').hide();
                    }
                }, 60*1000);
            }

            binarySocket.send(JSON.stringify(data));
        } else {
            bufferedSends.push(data);
        }
    };

    var init = function (es) {
        if(!es){
            events = {};
        }
        if(typeof es === 'object'){
            bufferedSends = [];
            manualClosed = false;
            events = es;
            clearTimeouts();
        }

        if(isClose()){
            binarySocket = new WebSocket(socketUrl);
        }

        binarySocket.onopen = function (){
            var loginToken = getCookieItem('login');
            if(loginToken && !authorized && localStorage.getItem('client.tokens')) {
                binarySocket.send(JSON.stringify({authorize: loginToken}));
            }
            else {
                sendBufferedSends();
            }

            if(typeof events.onopen === 'function'){
                events.onopen();
            }

            if(isReady()=== true){
                if(!Login.is_login_pages()) {
                    page.header.validate_cookies();
                }
                if (clock_started === false) {
                    page.header.start_clock_ws();
                }
            }
        };

        binarySocket.onmessage = function (msg){
            var response = JSON.parse(msg.data);
            if (response) {
                if(response.hasOwnProperty('echo_req') && response.echo_req.hasOwnProperty('passthrough')) {
                    var passthrough = response.echo_req.passthrough;
                    if(passthrough.hasOwnProperty('req_number')) {
                        clearInterval(timeouts[response.echo_req.passthrough.req_number]);
                        delete timeouts[response.echo_req.passthrough.req_number];
                    }
                    else if (passthrough.hasOwnProperty('dispatch_to')) {
                      if (passthrough.dispatch_to === 'ViewPopupWS') {
                        ViewPopupWS.dispatch(response);
                      } else if (passthrough.dispatch_to === 'ViewChartWS') {
                        Highchart.dispatch(response);
                      } else if (passthrough.dispatch_to === 'ViewTickDisplayWS') {
                        WSTickDisplay.dispatch(response);
                      }
                    }
                }
                var type = response.msg_type;
                if (type === 'authorize') {
                    if(response.hasOwnProperty('error')) {
                        var isActiveTab = sessionStorage.getItem('active_tab') === '1';
                        if(response.error.code === 'SelfExclusion' && isActiveTab) {
                            sessionStorage.removeItem('active_tab');
                            alert(response.error.message);
                        }
                        LocalStore.set('reality_check.ack', 0);
                        page.client.send_logout_request(isActiveTab);
                    } else if (response.authorize.loginid !== page.client.loginid) {
                        page.client.send_logout_request(true);
                    } else {
                        authorized = true;
                        if(typeof events.onauth === 'function'){
                            events.onauth();
                        }
                        if(!Login.is_login_pages()) {
                            page.client.response_authorize(response);
                            send({balance:1, subscribe: 1});
                            send({landing_company_details: TUser.get().landing_company_name});
                            send({get_settings: 1});
                            if(!page.client.is_virtual()) {
                                send({get_self_exclusion: 1});
                            }
                        }
                        sendBufferedSends();
                    }
                } else if (type === 'balance') {
                    ViewBalanceUI.updateBalances(response);
                } else if (type === 'time') {
                    page.header.time_counter(response);
                } else if (type === 'logout') {
                    localStorage.removeItem('jp_test_allowed');
                    RealityCheckData.clear();
                    page.header.do_logout(response);
                } else if (type === 'landing_company_details') {
                    page.client.response_landing_company_details(response);
                    BinarySocket.send({reality_check: 1, passthrough: { for: 'init_rc' }});
                } else if (type === 'get_self_exclusion') {
                    SessionDurationLimit.exclusionResponseHandler(response);
                } else if (type === 'payout_currencies' && response.echo_req.hasOwnProperty('passthrough') && response.echo_req.passthrough.handler === 'page.client') {
                    page.client.response_payout_currencies(response);
                } else if (type === 'get_settings') {
                    if(!$.cookie('residence') && response.get_settings.country_code) {
                      page.client.set_cookie('residence', response.get_settings.country_code);
                      page.client.residence = response.get_settings.country_code;
                    }
                    GTM.event_handler(response.get_settings);
                    page.client.set_storage_value('tnc_status', response.get_settings.client_tnc_status || '-');
                    if (!localStorage.getItem('risk_classification')) page.client.check_tnc();
                    var jpStatus = response.get_settings.jp_account_status;
                    if (jpStatus) {
                        switch (jpStatus.status) {
                            case 'jp_knowledge_test_pending': localStorage.setItem('jp_test_allowed', 1);
                                break;
                            case 'jp_knowledge_test_fail':
                                if (Date.now() >= (jpStatus.next_test_epoch * 1000)) {
                                    localStorage.setItem('jp_test_allowed', 1);
                                } else {
                                    localStorage.setItem('jp_test_allowed', 0);
                                }
                                break;
                            default: localStorage.setItem('jp_test_allowed', 0);
                        }

                        KnowledgeTest.showKnowledgeTestTopBarIfValid(jpStatus);
                    } else {
                        localStorage.removeItem('jp_test_allowed');
                    }
                } else if (type === 'website_status') {
                    if(!response.hasOwnProperty('error')) {
                        LocalStore.set('website.tnc_version', response.website_status.terms_conditions_version);
                        if (!localStorage.getItem('risk_classification')) page.client.check_tnc();
                    }
                  if (response.website_status.clients_country) {
                    localStorage.setItem('clients_country', response.website_status.clients_country);
                    if (!$('body').hasClass('BlueTopBack')) {
                      checkClientsCountry();
                    }
                  }
                } else if (type === 'reality_check') {
                    if (response.echo_req.passthrough.for === 'init_rc') {
                        var currentData = TUser.get();
                        var addedLoginTime = Object.assign({logintime: response.reality_check.start_time}, currentData);
                        TUser.set(addedLoginTime);
                        RealityCheck.init();
                    } else {
                        RealityCheck.realityCheckWSHandler(response);
                    }
                } else if (type === 'get_account_status') {
                  if (response.get_account_status.risk_classification === 'high' && page.header.qualify_for_risk_classification()) {
                    send({get_financial_assessment: 1});
                  } else {
                    localStorage.removeItem('risk_classification');
                  }
                  var withdrawal_locked, i;
                  for (i = 0; i < response.get_account_status.status.length; i++) {
                    if (response.get_account_status.status[i] === 'withdrawal_locked') {
                      withdrawal_locked = 'locked';
                      break;
                    }
                  }
                  if (response.echo_req.hasOwnProperty('passthrough') && response.echo_req.passthrough.hasOwnProperty('dispatch_to')) {
                    if (response.echo_req.passthrough.dispatch_to === 'ForwardWS') {
                        ForwardWS.lock_withdrawal(withdrawal_locked || 'unlocked');
                    } else if (response.echo_req.passthrough.dispatch_to === 'Cashier') {
                        Cashier.lock_withdrawal(withdrawal_locked || 'unlocked');
                    } else if (response.echo_req.passthrough.dispatch_to === 'PaymentAgentWithdrawWS') {
                      PaymentAgentWithdrawWS.lock_withdrawal(withdrawal_locked || 'unlocked');
                    }
                  }
                  sessionStorage.setItem('withdrawal_locked', withdrawal_locked || 'unlocked');
                  localStorage.setItem('risk_classification.response', response.get_account_status.risk_classification);
                } else if (type === 'get_financial_assessment' && !response.hasOwnProperty('error')) {
                  if (Object.keys(response.get_financial_assessment).length === 0) {
                    if (page.header.qualify_for_risk_classification() && localStorage.getItem('risk_classification.response') === 'high') {
                      localStorage.setItem('risk_classification', 'high');
                      page.header.check_risk_classification();
                    }
                  } else if ((localStorage.getItem('reality_check.ack') === '1' || !localStorage.getItem('reality_check.interval')) && localStorage.getItem('risk_classification') !== 'high') {
                    localStorage.removeItem('risk_classification');
                    localStorage.removeItem('risk_classification.response');
                    page.client.check_tnc();
                  }
                }
                if (response.hasOwnProperty('error')) {
                    if(response.error && response.error.code) {
                      if (response.error.code === 'RateLimit') {
                        $('#ratelimit-error-message')
                            .css('display', 'block')
                            .on('click', '#ratelimit-refresh-link', function () {
                                window.location.reload();
                            });
                      } else if (response.error.code === 'InvalidToken' &&
                          type !== 'reset_password' &&
                          type !== 'new_account_virtual' &&
                          type !== 'paymentagent_withdraw' &&
                          type !== 'cashier') {
                            page.client.send_logout_request();
                      }
                    }
                }
                if(typeof events.onmessage === 'function'){
                    events.onmessage(msg);
                }
            }
        };

        binarySocket.onclose = function (e) {
            authorized = false;
            clearTimeouts();

            if(!manualClosed){
                init(1);
            }
            if(typeof events.onclose === 'function'){
                events.onclose();
            }
        };

        binarySocket.onerror = function (error) {
            console.log('socket error', error);
        };
    };

    var close = function () {
        manualClosed = true;
        bufferedSends = [];
        events = {};
        if (binarySocket) {
            binarySocket.close();
        }
    };

    var clear = function(){
        bufferedSends = [];
        manualClosed = false;
        events = {};
    };

    return {
        init: init,
        send: send,
        close: close,
        socket: function () { return binarySocket; },
        clear: clear,
        clearTimeouts: clearTimeouts
    };

}

var BinarySocket = new BinarySocketClass();
<commit_msg>Prevent reconnecting forever when app_id is wrong<commit_after>/*
 * It provides a abstraction layer over native javascript Websocket.
 *
 * Provide additional functionality like if connection is close, open
 * it again and process the buffered requests
 *
 *
 * Usage:
 *
 * `BinarySocket.init()` to initiate the connection
 * `BinarySocket.send({contracts_for : 1})` to send message to server
 */
function BinarySocketClass() {
    'use strict';

    var binarySocket,
        bufferedSends = [],
        manualClosed = false,
        events = {},
        authorized = false,
        timeouts = {},
        req_number = 0,
        wrongAppId = 0,
        socketUrl = getSocketURL() + '?app_id=' + getAppId() + (page.language() ? '&l=' + page.language() : '');

    var clearTimeouts = function(){
        for(var k in timeouts){
            if(timeouts.hasOwnProperty(k)){
                clearTimeout(timeouts[k]);
                delete timeouts[k];
            }
        }
    };

    var status = function () {
        return binarySocket && binarySocket.readyState;
    };

    var isReady = function () {
        return binarySocket && binarySocket.readyState === 1;
    };

    var isClose = function () {
        return !binarySocket || binarySocket.readyState === 2 || binarySocket.readyState === 3;
    };

    var sendBufferedSends = function () {
        while (bufferedSends.length > 0) {
            binarySocket.send(JSON.stringify(bufferedSends.shift()));
        }
    };

    var send = function(data) {
        if (isClose()) {
            bufferedSends.push(data);
            init(1);
        } else if (isReady()) {
            if(!data.hasOwnProperty('passthrough') && !data.hasOwnProperty('verify_email')){
                data.passthrough = {};
            }
            // temporary check
            if((data.contracts_for || data.proposal) && !data.passthrough.hasOwnProperty('dispatch_to')){
                data.passthrough.req_number = ++req_number;
                timeouts[req_number] = setTimeout(function(){
                    if(typeof reloadPage === 'function' && data.contracts_for){
                        alert("The server didn't respond to the request:\n\n"+JSON.stringify(data)+"\n\n");
                        reloadPage();
                    }
                    else{
                        $('.price_container').hide();
                    }
                }, 60*1000);
            }

            binarySocket.send(JSON.stringify(data));
        } else {
            bufferedSends.push(data);
        }
    };

    var init = function (es) {
        if(wrongAppId === getAppId()) {
            return;
        }
        if(!es){
            events = {};
        }
        if(typeof es === 'object'){
            bufferedSends = [];
            manualClosed = false;
            events = es;
            clearTimeouts();
        }

        if(isClose()){
            binarySocket = new WebSocket(socketUrl);
        }

        binarySocket.onopen = function (){
            var loginToken = getCookieItem('login');
            if(loginToken && !authorized && localStorage.getItem('client.tokens')) {
                binarySocket.send(JSON.stringify({authorize: loginToken}));
            }
            else {
                sendBufferedSends();
            }

            if(typeof events.onopen === 'function'){
                events.onopen();
            }

            if(isReady()=== true){
                if(!Login.is_login_pages()) {
                    page.header.validate_cookies();
                }
                if (clock_started === false) {
                    page.header.start_clock_ws();
                }
            }
        };

        binarySocket.onmessage = function (msg){
            var response = JSON.parse(msg.data);
            if (response) {
                if(response.hasOwnProperty('echo_req') && response.echo_req.hasOwnProperty('passthrough')) {
                    var passthrough = response.echo_req.passthrough;
                    if(passthrough.hasOwnProperty('req_number')) {
                        clearInterval(timeouts[response.echo_req.passthrough.req_number]);
                        delete timeouts[response.echo_req.passthrough.req_number];
                    }
                    else if (passthrough.hasOwnProperty('dispatch_to')) {
                      if (passthrough.dispatch_to === 'ViewPopupWS') {
                        ViewPopupWS.dispatch(response);
                      } else if (passthrough.dispatch_to === 'ViewChartWS') {
                        Highchart.dispatch(response);
                      } else if (passthrough.dispatch_to === 'ViewTickDisplayWS') {
                        WSTickDisplay.dispatch(response);
                      }
                    }
                }
                var type = response.msg_type;
                if (type === 'authorize') {
                    if(response.hasOwnProperty('error')) {
                        var isActiveTab = sessionStorage.getItem('active_tab') === '1';
                        if(response.error.code === 'SelfExclusion' && isActiveTab) {
                            sessionStorage.removeItem('active_tab');
                            alert(response.error.message);
                        }
                        LocalStore.set('reality_check.ack', 0);
                        page.client.send_logout_request(isActiveTab);
                    } else if (response.authorize.loginid !== page.client.loginid) {
                        page.client.send_logout_request(true);
                    } else {
                        authorized = true;
                        if(typeof events.onauth === 'function'){
                            events.onauth();
                        }
                        if(!Login.is_login_pages()) {
                            page.client.response_authorize(response);
                            send({balance:1, subscribe: 1});
                            send({landing_company_details: TUser.get().landing_company_name});
                            send({get_settings: 1});
                            if(!page.client.is_virtual()) {
                                send({get_self_exclusion: 1});
                            }
                        }
                        sendBufferedSends();
                    }
                } else if (type === 'balance') {
                    ViewBalanceUI.updateBalances(response);
                } else if (type === 'time') {
                    page.header.time_counter(response);
                } else if (type === 'logout') {
                    localStorage.removeItem('jp_test_allowed');
                    RealityCheckData.clear();
                    page.header.do_logout(response);
                } else if (type === 'landing_company_details') {
                    page.client.response_landing_company_details(response);
                    BinarySocket.send({reality_check: 1, passthrough: { for: 'init_rc' }});
                } else if (type === 'get_self_exclusion') {
                    SessionDurationLimit.exclusionResponseHandler(response);
                } else if (type === 'payout_currencies' && response.echo_req.hasOwnProperty('passthrough') && response.echo_req.passthrough.handler === 'page.client') {
                    page.client.response_payout_currencies(response);
                } else if (type === 'get_settings') {
                    if(!$.cookie('residence') && response.get_settings.country_code) {
                      page.client.set_cookie('residence', response.get_settings.country_code);
                      page.client.residence = response.get_settings.country_code;
                    }
                    GTM.event_handler(response.get_settings);
                    page.client.set_storage_value('tnc_status', response.get_settings.client_tnc_status || '-');
                    if (!localStorage.getItem('risk_classification')) page.client.check_tnc();
                    var jpStatus = response.get_settings.jp_account_status;
                    if (jpStatus) {
                        switch (jpStatus.status) {
                            case 'jp_knowledge_test_pending': localStorage.setItem('jp_test_allowed', 1);
                                break;
                            case 'jp_knowledge_test_fail':
                                if (Date.now() >= (jpStatus.next_test_epoch * 1000)) {
                                    localStorage.setItem('jp_test_allowed', 1);
                                } else {
                                    localStorage.setItem('jp_test_allowed', 0);
                                }
                                break;
                            default: localStorage.setItem('jp_test_allowed', 0);
                        }

                        KnowledgeTest.showKnowledgeTestTopBarIfValid(jpStatus);
                    } else {
                        localStorage.removeItem('jp_test_allowed');
                    }
                } else if (type === 'website_status') {
                    if(!response.hasOwnProperty('error')) {
                        LocalStore.set('website.tnc_version', response.website_status.terms_conditions_version);
                        if (!localStorage.getItem('risk_classification')) page.client.check_tnc();
                    }
                  if (response.website_status.clients_country) {
                    localStorage.setItem('clients_country', response.website_status.clients_country);
                    if (!$('body').hasClass('BlueTopBack')) {
                      checkClientsCountry();
                    }
                  }
                } else if (type === 'reality_check') {
                    if (response.echo_req.passthrough.for === 'init_rc') {
                        var currentData = TUser.get();
                        var addedLoginTime = Object.assign({logintime: response.reality_check.start_time}, currentData);
                        TUser.set(addedLoginTime);
                        RealityCheck.init();
                    } else {
                        RealityCheck.realityCheckWSHandler(response);
                    }
                } else if (type === 'get_account_status') {
                  if (response.get_account_status.risk_classification === 'high' && page.header.qualify_for_risk_classification()) {
                    send({get_financial_assessment: 1});
                  } else {
                    localStorage.removeItem('risk_classification');
                  }
                  var withdrawal_locked, i;
                  for (i = 0; i < response.get_account_status.status.length; i++) {
                    if (response.get_account_status.status[i] === 'withdrawal_locked') {
                      withdrawal_locked = 'locked';
                      break;
                    }
                  }
                  if (response.echo_req.hasOwnProperty('passthrough') && response.echo_req.passthrough.hasOwnProperty('dispatch_to')) {
                    if (response.echo_req.passthrough.dispatch_to === 'ForwardWS') {
                        ForwardWS.lock_withdrawal(withdrawal_locked || 'unlocked');
                    } else if (response.echo_req.passthrough.dispatch_to === 'Cashier') {
                        Cashier.lock_withdrawal(withdrawal_locked || 'unlocked');
                    } else if (response.echo_req.passthrough.dispatch_to === 'PaymentAgentWithdrawWS') {
                      PaymentAgentWithdrawWS.lock_withdrawal(withdrawal_locked || 'unlocked');
                    }
                  }
                  sessionStorage.setItem('withdrawal_locked', withdrawal_locked || 'unlocked');
                  localStorage.setItem('risk_classification.response', response.get_account_status.risk_classification);
                } else if (type === 'get_financial_assessment' && !response.hasOwnProperty('error')) {
                  if (Object.keys(response.get_financial_assessment).length === 0) {
                    if (page.header.qualify_for_risk_classification() && localStorage.getItem('risk_classification.response') === 'high') {
                      localStorage.setItem('risk_classification', 'high');
                      page.header.check_risk_classification();
                    }
                  } else if ((localStorage.getItem('reality_check.ack') === '1' || !localStorage.getItem('reality_check.interval')) && localStorage.getItem('risk_classification') !== 'high') {
                    localStorage.removeItem('risk_classification');
                    localStorage.removeItem('risk_classification.response');
                    page.client.check_tnc();
                  }
                }
                if (response.hasOwnProperty('error')) {
                    if(response.error && response.error.code) {
                      if (response.error.code === 'RateLimit') {
                        $('#ratelimit-error-message')
                            .css('display', 'block')
                            .on('click', '#ratelimit-refresh-link', function () {
                                window.location.reload();
                            });
                      } else if (response.error.code === 'InvalidToken' &&
                          type !== 'reset_password' &&
                          type !== 'new_account_virtual' &&
                          type !== 'paymentagent_withdraw' &&
                          type !== 'cashier') {
                            page.client.send_logout_request();
                      } else if (response.error.code === 'InvalidAppID') {
                          wrongAppId = getAppId();
                          alert(response.error.message);
                      }
                    }
                }
                if(typeof events.onmessage === 'function'){
                    events.onmessage(msg);
                }
            }
        };

        binarySocket.onclose = function (e) {
            authorized = false;
            clearTimeouts();

            if(!manualClosed && wrongAppId !== getAppId()) {
                init(1);
            }
            if(typeof events.onclose === 'function'){
                events.onclose();
            }
        };

        binarySocket.onerror = function (error) {
            console.log('socket error', error);
        };
    };

    var close = function () {
        manualClosed = true;
        bufferedSends = [];
        events = {};
        if (binarySocket) {
            binarySocket.close();
        }
    };

    var clear = function(){
        bufferedSends = [];
        manualClosed = false;
        events = {};
    };

    return {
        init: init,
        send: send,
        close: close,
        socket: function () { return binarySocket; },
        clear: clear,
        clearTimeouts: clearTimeouts
    };

}

var BinarySocket = new BinarySocketClass();
<|endoftext|>


<commit_before>//v1.0 as Starting Point
//v2.0 Cleaning up code. Setting up Menu Structure and Initial Settings.

//Declare and Initialize Variables
var AudioAlertsStatus = 3;
var audio_Bell = new Audio("http://xenko.comxa.com/Ship_Bell.mp3");
	audio_Bell.volume = 1;
var audio_Chime = new Audio("http://xenko.comxa.com/Chime.mp3");
	audio_Chime.volume = 1;
var BorderAlertStatus = 1;
var description = "Error";
var i = 0;
var IdleStatus = 0;
var incoming_ONG = 0;
var NinjaAutoClickStatus = 0;
var RKAutoClickStatus = 0;
var RKAlertFrequency = 8;
var Time_to_ONG = 1800000;

//Ninja AutoClicker and Border Warnings
function Ninja() {
    if (Molpy.ninjad == 0) {
        if (Molpy.npbONG == 0 && BorderAlertStatus == 1) {
			$("#beach").css("border","4px solid red");
        }
        else {
            incoming_ONG = 0;
            if (NinjaAutoClickStatus == 1) {
                Molpy.ClickBeach();
				if (BorderAlertStatus == 1) {
					$("#beach").css("border","4px solid white");
				}
            }
            else if (BorderAlertStatus == 1) {
            $("#beach").css("border","4px solid green");
            }

        }
	}
    else if (Time_to_ONG <= 15000) {
		if (BorderAlertStatus == 1) {
			$("#beach").css("border","4px solid yellow");
		}
        if (incoming_ONG == 0 && (AudioAlertsStatus == 3 || AudioAlertsStatus == 4)) {
			audio_Chime.play();
			incoming_ONG = 1;
        }
    }
    else if (BorderAlertStatus == 1) {
        $("#beach").css("border","1px solid white");
	}
}

function RedundaKitty() {
	i = Molpy.redactedToggle - Molpy.redactedCountup;

	if (Molpy.redactedVisible > 0) {
		//Clicks if AutoClicker Enabled
		if (RKAutoClickStatus == 1) {
			Molpy.ClickRedacted();
		}

		else {
			//Redundakitty Notifications (Title Bar and Audio)
			document.title = "! kitten !";
			if (Math.floor(i % RKAlertFrequency) == 0 && (AudioAlertsStatus == 1 || AudioAlertsStatus == 3)) {
				audio_Bell.play();
			}
		}
	}
	else {
		document.title = Molpy.redactedToggle-Molpy.redactedCountup;
		if (i != 0) { i = 0; }
	}
}

function SwitchOption(option) {
	switch (option) {
		case 'RKAutoClick':
			RKAutoClickStatus++;
			if (RKAutoClickStatus > 1) {RKAutoClickStatus = 0};
			status = RKAutoClickStatus;
			break;
		case 'NinjaAutoClick':
			NinjaAutoClickStatus++;
			if (NinjaAutoClickStatus > 1) {NinjaAutoClickStatus = 0};
			status = NinjaAutoClickStatus;
			break;
		case 'BorderAlert':
			BorderAlertStatus++;
			if (BorderAlertStatus > 1) {BorderAlertStatus = 0};
			status = BorderAlertStatus;
			break;
		case 'AudioAlerts':
			AudioAlertsStatus++;
			if (AudioAlertsStatus > 3) {AudioAlertsStatus = 0};
			status = AudioAlertsStatus;
			break;
	}
	DisplayDescription(option, status);
}

function DisplayDescription(option, status) {
	error = 0;
	if (option == 'RKAutoClick' || option == 'NinjaAutoClick' || option == 'BorderAlert') {
		if (status == 0) {description = 'Off';}
		else if (status == 1) {description = 'On';}
		else {Molpy.Notify('Display Description Error',1);}
	}
	else if (option == 'AudioAlerts') {
		//Molpy.Notify(isNaN(status),1);
		if (status == 0) {description = 'Off';}
		else if (status == 1) {description = 'RK Only';}
		else if (status == 2) {description = 'ONG Only';}
		else if (status == 3) {description = 'RK and ONG';}
		else {Molpy.Notify('Display Description Error - Audio Alerts: ' + status,1);}
	}
	else {
		Molpy.Notify(option + ' is not a valid option', 1);
		error = 1;
	}

	if (error == 0) {g(option + 'Desc').innerHTML = '
' + description;}
}

//Beach Ball Startup
//Set Settings
if (Molpy.Got('Kitnip') == 1){RKAlertFrequency = 10;}

//Create Menu
$('#optionsItems').append('

BeachBall Settings

');
$('#optionsItems').append('

RK Auto Click

');
$('#optionsItems').append('

Ninja Auto Click

');
$('#optionsItems').append('

Ninja Visual Alert

');
$('#optionsItems').append('

Audio Alerts

');
DisplayDescription('RKAutoClick', RKAutoClickStatus);
DisplayDescription('NinjaAutoClick', NinjaAutoClickStatus);
DisplayDescription('BorderAlert', BorderAlertStatus);
DisplayDescription('AudioAlerts', AudioAlertsStatus);

//Main Loop
setInterval(function() {
	Time_to_ONG = (Molpy.NPlength * 1000) - Molpy.ONGelapsed;
    RedundaKitty();
    Ninja();
}, 1800);
<commit_msg>Bug Fixing Border Alert Setting<commit_after>//v1.0 as Starting Point
//v2.0 Cleaning up code. Setting up Menu Structure and Initial Settings.

//Declare and Initialize Variables
var AudioAlertsStatus = 3;
var audio_Bell = new Audio("http://xenko.comxa.com/Ship_Bell.mp3");
	audio_Bell.volume = 1;
var audio_Chime = new Audio("http://xenko.comxa.com/Chime.mp3");
	audio_Chime.volume = 1;
var BorderAlertStatus = 1;
var description = "Error";
var i = 0;
var IdleStatus = 0;
var incoming_ONG = 0;
var NinjaAutoClickStatus = 0;
var RKAutoClickStatus = 0;
var RKAlertFrequency = 8;
var Time_to_ONG = 1800000;

//Ninja AutoClicker and Border Warnings
function Ninja() {
    if (Molpy.ninjad == 0) {
        if (Molpy.npbONG == 0 && BorderAlertStatus == 1) {
			$("#beach").css("border","4px solid red");
        }
        else {
            incoming_ONG = 0;
            if (NinjaAutoClickStatus == 1) {
                Molpy.ClickBeach();
				if (BorderAlertStatus == 1) {
					$("#beach").css("border","4px solid white");
				}
            }
            else if (BorderAlertStatus == 1) {
            $("#beach").css("border","4px solid green");
            }

        }
	}
    else if (Time_to_ONG <= 15000) {
		if (BorderAlertStatus == 1) {
			$("#beach").css("border","4px solid yellow");
		}
        if (incoming_ONG == 0 && (AudioAlertsStatus == 3 || AudioAlertsStatus == 4)) {
			audio_Chime.play();
			incoming_ONG = 1;
        }
    }
    else if (BorderAlertStatus == 1) {
        $("#beach").css("border","1px solid white");
	}
}

function RedundaKitty() {
	i = Molpy.redactedToggle - Molpy.redactedCountup;

	if (Molpy.redactedVisible > 0) {
		//Clicks if AutoClicker Enabled
		if (RKAutoClickStatus == 1) {
			Molpy.ClickRedacted();
		}

		else {
			//Redundakitty Notifications (Title Bar and Audio)
			document.title = "! kitten !";
			if (Math.floor(i % RKAlertFrequency) == 0 && (AudioAlertsStatus == 1 || AudioAlertsStatus == 3)) {
				audio_Bell.play();
			}
		}
	}
	else {
		document.title = Molpy.redactedToggle-Molpy.redactedCountup;
		if (i != 0) { i = 0; }
	}
}

function SwitchOption(option) {
	switch (option) {
		case 'RKAutoClick':
			RKAutoClickStatus++;
			if (RKAutoClickStatus > 1) {RKAutoClickStatus = 0;}
			status = RKAutoClickStatus;
			break;
		case 'NinjaAutoClick':
			NinjaAutoClickStatus++;
			if (NinjaAutoClickStatus > 1) {NinjaAutoClickStatus = 0;}
			status = NinjaAutoClickStatus;
			break;
		case 'BorderAlert':
			BorderAlertStatus++;
			if (BorderAlertStatus > 1) {
				BorderAlertStatus = 0;
				$("#beach").css("border","4px solid white");
			}
			status = BorderAlertStatus;
			break;
		case 'AudioAlerts':
			AudioAlertsStatus++;
			if (AudioAlertsStatus > 3) {AudioAlertsStatus = 0;}
			status = AudioAlertsStatus;
			break;
	}
	DisplayDescription(option, status);
}

function DisplayDescription(option, status) {
	error = 0;
	if (option == 'RKAutoClick' || option == 'NinjaAutoClick' || option == 'BorderAlert') {
		if (status == 0) {description = 'Off';}
		else if (status == 1) {description = 'On';}
		else {Molpy.Notify('Display Description Error',1);}
	}
	else if (option == 'AudioAlerts') {
		//Molpy.Notify(isNaN(status),1);
		if (status == 0) {description = 'Off';}
		else if (status == 1) {description = 'RK Only';}
		else if (status == 2) {description = 'ONG Only';}
		else if (status == 3) {description = 'RK and ONG';}
		else {Molpy.Notify('Display Description Error - Audio Alerts: ' + status,1);}
	}
	else {
		Molpy.Notify(option + ' is not a valid option', 1);
		error = 1;
	}

	if (error == 0) {g(option + 'Desc').innerHTML = '
' + description;}
}

//Beach Ball Startup
//Set Settings
if (Molpy.Got('Kitnip') == 1){RKAlertFrequency = 10;}

//Create Menu
$('#optionsItems').append('

BeachBall Settings

');
$('#optionsItems').append('

RK Auto Click

');
$('#optionsItems').append('

Ninja Auto Click

');
$('#optionsItems').append('

Ninja Visual Alert

');
$('#optionsItems').append('

Audio Alerts

');
DisplayDescription('RKAutoClick', RKAutoClickStatus);
DisplayDescription('NinjaAutoClick', NinjaAutoClickStatus);
DisplayDescription('BorderAlert', BorderAlertStatus);
DisplayDescription('AudioAlerts', AudioAlertsStatus);

//Main Loop
setInterval(function() {
	Time_to_ONG = (Molpy.NPlength * 1000) - Molpy.ONGelapsed;
    RedundaKitty();
    Ninja();
}, 1800);
<|endoftext|>


<commit_before>// --------------------
// Sequelize hierarchy
// Shims to model instance methods
// --------------------

// exports

module.exports = function(Sequelize) {
	var Promise = Sequelize.Promise;
	var Utils = Sequelize.Utils;
	var _ = Utils._;

	// return hooks
	return {
		beforeCreate: function(item, options) {
			var model = item.Model,
				hierarchy = model.hierarchy,
				values = item.dataValues,
				parentId = values[hierarchy.foreignKey],
				levelFieldName = hierarchy.levelFieldName;

			// if no parent, set level and exit - no ancestor records to create
			if (!parentId) {
				values[levelFieldName] = 1;
				return;
			}

			// set level based on parent
			var queryOptions = {where: {}, attributes: [levelFieldName]};
			queryOptions.where[model.primaryKeyAttribute] = parentId;

			return model.find(queryOptions, {raw: true, transaction: options.transaction})
			.then(function(parent) {
				// set hierarchy level
				values[levelFieldName] = parent[levelFieldName] + 1;
			});
		},
		afterCreate: function(item, options) {
			var model = item.Model,
				hierarchy = model.hierarchy,
				values = item.dataValues,
				parentId = values[hierarchy.foreignKey];

			// if no parent, exit - no hierarchy to create
			if (!parentId) return;

			// create row in hierarchy table for parent
			var itemId = item[model.primaryKeyAttribute];
			var through = hierarchy.through;

			return Promise.try(function() {
				// get ancestors

				// if parent is at top level, has no ancestors
				if (values[hierarchy.levelFieldName] == 2) return [];

				// get parent's ancestors
				var queryOptions = {where: {}, attributes: [hierarchy.throughForeignKey]};
				queryOptions.where[hierarchy.throughKey] = parentId;

				return through.findAll(queryOptions, {raw: true, transaction: options.transaction});
			})
			.then(function(ancestors) {
				// add parent as ancestor
				var parentValues = {};
				parentValues[hierarchy.throughForeignKey] = parentId;
				ancestors.push(parentValues);
				return ancestors;
			})
			.then(function(ancestors) {
				// save ancestors
				ancestors = ancestors.map(function(ancestor) {
					ancestor[hierarchy.throughKey] = itemId;
					return ancestor;
				});

				return through.bulkCreate(ancestors, {transaction: options.transaction});
			})
			.return();
		},

		beforeUpdate: function(item, options) {
			var model = item.Model,
				sequelize = model.sequelize,
				hierarchy = model.hierarchy;

			// NB this presumes item has not been updated since it was originally retrieved
			var parentId = item.dataValues[hierarchy.foreignKey];
			var oldParentId = item._previousDataValues[hierarchy.foreignKey];

			// if parent has not changed, exit - no change to make
			if (parentId === oldParentId) return;

			return Promise.try(function() {
				// check that not trying to make item a child of one of its own children
				if (parentId === null) return;

				var where = {};
				where[hierarchy.throughKey] = parentId;
				where[hierarchy.throughForeignKey] = item[model.primaryKeyAttribute];

				return hierarchy.through.find({where: where}, {transaction: options.transaction})
				.then(function(illegalItem) {
					if (illegalItem) throw new Error('Parent cannot be a child of itself');
				});
			})
			.then(function() {
				// get parent's level
				if (parentId === null) return 0;

				var where = {};
				where[model.primaryKeyAttribute] = parentId;

				return model.find({where: where, attributes: [hierarchy.levelFieldName]}, {raw: true, transaction: options.transaction})
				.then(function(parent) {
					if (!parent) throw new Error('Parent does not exist');

					return parent[hierarchy.levelFieldName];
				});
			})
			.then(function(parentLevel) {
				// set hierarchy level
				var newLevel = parentLevel + 1;
				var levelChange = newLevel - item._previousDataValues[hierarchy.levelFieldName];

				item.dataValues[hierarchy.levelFieldName] = newLevel;

				// update level and hierarchy table
				return Promise.try(function() {
					if (!levelChange) return;

					// update hierarchy level for all descendents
					var sql = replaceIdentifiers(
						'UPDATE *item '
						+ 'SET *level = *level + :levelChange '
						+ 'WHERE *id IN ('
						+ '		SELECT *itemId '
						+ '		FROM *through AS ancestors '
						+ '		WHERE ancestors.*ancestorId = :id'
						+ ')',
						{
							item: model.tableName,
							through: hierarchy.through.tableName,
							level: hierarchy.levelFieldName,
							id: model.primaryKeyAttribute,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id, levelChange: levelChange});
				})
				.then(function() {
					// delete ancestors from hierarchy table for item and all descendents
					if (oldParentId === null) return;

					var throughTableName = escapeIdentifier(hierarchy.through.tableName);
					var throughKey = escapeIdentifier(hierarchy.throughKey);
					var throughForeignKey = escapeIdentifier(hierarchy.throughForeignKey);

					var sql = replaceIdentifiers(
						'DELETE deleters '
						+ 'FROM *through AS deleters '
						+ 'INNER JOIN *through AS descendents ON descendents.*itemId = deleters.*itemId '
						+ 'INNER JOIN *through AS ancestors ON ancestors.*ancestorId = deleters.*ancestorId '
						+ 'WHERE ancestors.*itemId = :id '
						+ '		AND ('
						+ '			descendents.*ancestorId = :id '
						+ '			OR descendents.*itemId = :id'
						+ '		)',
						{
							through: hierarchy.through.tableName,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id});
				})
				.then(function() {
					// insert ancestors into hierarchy table for item and all descendents
					if (parentId === null) return;

					var sql = replaceIdentifiers(
						'INSERT INTO *through (*itemId, *ancestorId) '
						+ 'SELECT descendents.*itemId, ancestors.*ancestorId '
						+ 'FROM ( '
						+ '			SELECT *itemId '
						+ '			FROM *through '
						+ '			WHERE *ancestorId = :id '
						+ '			UNION '
						+ '			SELECT :id '
						+ '		) AS descendents '
						+ '		INNER JOIN ('
						+ '			SELECT *ancestorId '
						+ '			FROM *through '
						+ '			WHERE *itemId = :parentId '
						+ '			UNION '
						+ '			SELECT :parentId'
						+ '		) AS ancestors',
						{
							through: hierarchy.through.tableName,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id, parentId: parentId});
				});
			})
			.return();
		},

		beforeFind: function(options) {
			// check options do not include illegal hierarchies
			if (options.hierarchy) throw new Error('You cannot get hierarchy of ' + this.name + ' - at top level with find()');
			checkHierarchy(options, this);
		},
		afterFind: function(result, options) {
			// convert hierarchies into trees
			convertHierarchies(result, options, this);
		},

		beforeFindAll: function(options) {
			// check options do not include illegal hierarchies
			if (options.hierarchy && !this.hierarchy) throw new Error('You cannot get hierarchy of ' + this.name + ' - it is not hierarchical');
			checkHierarchy(options, this);
		},
		afterFindAll: function(results, options) {
			// convert hierarchies into trees
			convertHierarchies(results, options, this);
		}
	};

	function replaceIdentifiers(sql, identifiers)
	{
		_.forIn(identifiers, function(replacement, identifier) {
			sql = sql.replace(new RegExp('\\*' + identifier, 'g'), escapeIdentifier(replacement));
		});
		return sql.replace(/[ \t\r\n]+/g, ' ');
	}

	function escapeIdentifier(identifier)
	{
		return '`' + identifier.replace(/`/g, '``') + '`';
	}

	function checkHierarchy(options, model)
	{
		// check options do not include illegal hierarchies - throw error if so
		(function traverse(options, model) {
			if (options.include) {
				options.include.forEach(function(include) {
					var includeModel = include.model;

					// if hierarchy set, check is legal
					if (include.hierarchy) {
						if (!includeModel.hierarchy) throw new Error('You cannot get hierarchy of ' + includeModel.name + ' - it is not hierarchical');
						if (includeModel !== model) throw new Error('You cannot get a hierarchy of ' + includeModel.name + ' without including it from a parent');
						if (include.as !== model.hierarchy.descendentsAs) throw new Error('You cannot set hierarchy on ' + model.name + ' without using the ' + model.hierarchy.descendentsAs + ' accessor');
					}

					// check includes
					traverse(include, includeModel);
				});
			}
		})(options, model);
	}

	function convertHierarchies(results, options, model)
	{
		// convert hierarchies into trees
		(function traverse(results, options, model, parent) {
			if (options.include) {
				options.include.forEach(function(include) {
					var includeModel = include.model,
						accessor = include.as;

					if (Array.isArray(results)) {
						results.forEach(function(result) {
							traverse(result[accessor], include, includeModel, result);
						});
					} else {
						traverse(results[accessor], include, includeModel, results);
					}
				});
			}

			if (options.hierarchy) convertHierarchy(results, model, parent);
		})(results, options, model, null);
	}

	function convertHierarchy(results, model, parent)
	{
		var hierarchy = model.hierarchy,
			primaryKey = model.primaryKeyAttribute,
			foreignKey = hierarchy.foreignKey,
			childrenAccessor = hierarchy.childrenAs,
			descendentsAccessor = hierarchy.descendentsAs,
			throughAccessor = Utils.singularize(hierarchy.through.name);

		// get parent id and move results from parent.descendents to parent.children
		var parentId = null;
		if (parent) {
			parentId = parent[primaryKey];

			parent.dataValues[childrenAccessor] = parent[childrenAccessor] = results;
			delete parent[descendentsAccessor];
			delete parent.dataValues[descendentsAccessor];
		}

		// run through all results, turning into tree

		// find rows which are not top level and move into references
		var references = {};

		for (var i = 0; i < results.length; i++) {
			var item = results[i];

			// remove reference to through table
			delete item[throughAccessor];
			delete item.dataValues[throughAccessor];

			// add into references
			references[item[primaryKey]] = item;

			// if not a root-level item, remove from results
			if (item[foreignKey] !== parentId) {
				results.splice(i, 1);
				i--;
			}
		}

		// run through references, nesting within parents
		_.forIn(references, function(item) {
			// nest inside parent
			var thisParentId = item[foreignKey];
			if (thisParentId !== parentId) {
				var parent = references[thisParentId];
				if (!parent[childrenAccessor]) parent.dataValues[childrenAccessor] = parent[childrenAccessor] = [];
				parent[childrenAccessor].push(item);
			}
		});
	}
};
<commit_msg>Remove unnecessary nested functions<commit_after>// --------------------
// Sequelize hierarchy
// Shims to model instance methods
// --------------------

// exports

module.exports = function(Sequelize) {
	var Promise = Sequelize.Promise;
	var Utils = Sequelize.Utils;
	var _ = Utils._;

	// return hooks
	return {
		beforeCreate: function(item, options) {
			var model = item.Model,
				hierarchy = model.hierarchy,
				values = item.dataValues,
				parentId = values[hierarchy.foreignKey],
				levelFieldName = hierarchy.levelFieldName;

			// if no parent, set level and exit - no ancestor records to create
			if (!parentId) {
				values[levelFieldName] = 1;
				return;
			}

			// set level based on parent
			var queryOptions = {where: {}, attributes: [levelFieldName]};
			queryOptions.where[model.primaryKeyAttribute] = parentId;

			return model.find(queryOptions, {raw: true, transaction: options.transaction})
			.then(function(parent) {
				// set hierarchy level
				values[levelFieldName] = parent[levelFieldName] + 1;
			});
		},
		afterCreate: function(item, options) {
			var model = item.Model,
				hierarchy = model.hierarchy,
				values = item.dataValues,
				parentId = values[hierarchy.foreignKey];

			// if no parent, exit - no hierarchy to create
			if (!parentId) return;

			// create row in hierarchy table for parent
			var itemId = item[model.primaryKeyAttribute];
			var through = hierarchy.through;

			return Promise.try(function() {
				// get ancestors

				// if parent is at top level, has no ancestors
				if (values[hierarchy.levelFieldName] == 2) return [];

				// get parent's ancestors
				var queryOptions = {where: {}, attributes: [hierarchy.throughForeignKey]};
				queryOptions.where[hierarchy.throughKey] = parentId;

				return through.findAll(queryOptions, {raw: true, transaction: options.transaction});
			})
			.then(function(ancestors) {
				// add parent as ancestor
				var parentValues = {};
				parentValues[hierarchy.throughForeignKey] = parentId;
				ancestors.push(parentValues);
				return ancestors;
			})
			.then(function(ancestors) {
				// save ancestors
				ancestors = ancestors.map(function(ancestor) {
					ancestor[hierarchy.throughKey] = itemId;
					return ancestor;
				});

				return through.bulkCreate(ancestors, {transaction: options.transaction});
			})
			.return();
		},

		beforeUpdate: function(item, options) {
			var model = item.Model,
				sequelize = model.sequelize,
				hierarchy = model.hierarchy;

			// NB this presumes item has not been updated since it was originally retrieved
			var parentId = item.dataValues[hierarchy.foreignKey];
			var oldParentId = item._previousDataValues[hierarchy.foreignKey];

			// if parent has not changed, exit - no change to make
			if (parentId === oldParentId) return;

			return Promise.try(function() {
				// check that not trying to make item a child of one of its own children
				if (parentId === null) return;

				var where = {};
				where[hierarchy.throughKey] = parentId;
				where[hierarchy.throughForeignKey] = item[model.primaryKeyAttribute];

				return hierarchy.through.find({where: where}, {transaction: options.transaction})
				.then(function(illegalItem) {
					if (illegalItem) throw new Error('Parent cannot be a child of itself');
				});
			})
			.then(function() {
				// get parent's level
				if (parentId === null) return 0;

				var where = {};
				where[model.primaryKeyAttribute] = parentId;

				return model.find({where: where, attributes: [hierarchy.levelFieldName]}, {raw: true, transaction: options.transaction})
				.then(function(parent) {
					if (!parent) throw new Error('Parent does not exist');

					return parent[hierarchy.levelFieldName];
				});
			})
			.then(function(parentLevel) {
				// set hierarchy level
				var newLevel = parentLevel + 1;
				var levelChange = newLevel - item._previousDataValues[hierarchy.levelFieldName];

				item.dataValues[hierarchy.levelFieldName] = newLevel;

				// update level and hierarchy table
				return Promise.try(function() {
					if (!levelChange) return;

					// update hierarchy level for all descendents
					var sql = replaceIdentifiers(
						'UPDATE *item '
						+ 'SET *level = *level + :levelChange '
						+ 'WHERE *id IN ('
						+ '		SELECT *itemId '
						+ '		FROM *through AS ancestors '
						+ '		WHERE ancestors.*ancestorId = :id'
						+ ')',
						{
							item: model.tableName,
							through: hierarchy.through.tableName,
							level: hierarchy.levelFieldName,
							id: model.primaryKeyAttribute,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id, levelChange: levelChange});
				})
				.then(function() {
					// delete ancestors from hierarchy table for item and all descendents
					if (oldParentId === null) return;

					var throughTableName = escapeIdentifier(hierarchy.through.tableName);
					var throughKey = escapeIdentifier(hierarchy.throughKey);
					var throughForeignKey = escapeIdentifier(hierarchy.throughForeignKey);

					var sql = replaceIdentifiers(
						'DELETE deleters '
						+ 'FROM *through AS deleters '
						+ 'INNER JOIN *through AS descendents ON descendents.*itemId = deleters.*itemId '
						+ 'INNER JOIN *through AS ancestors ON ancestors.*ancestorId = deleters.*ancestorId '
						+ 'WHERE ancestors.*itemId = :id '
						+ '		AND ('
						+ '			descendents.*ancestorId = :id '
						+ '			OR descendents.*itemId = :id'
						+ '		)',
						{
							through: hierarchy.through.tableName,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id});
				})
				.then(function() {
					// insert ancestors into hierarchy table for item and all descendents
					if (parentId === null) return;

					var sql = replaceIdentifiers(
						'INSERT INTO *through (*itemId, *ancestorId) '
						+ 'SELECT descendents.*itemId, ancestors.*ancestorId '
						+ 'FROM ( '
						+ '			SELECT *itemId '
						+ '			FROM *through '
						+ '			WHERE *ancestorId = :id '
						+ '			UNION '
						+ '			SELECT :id '
						+ '		) AS descendents '
						+ '		INNER JOIN ('
						+ '			SELECT *ancestorId '
						+ '			FROM *through '
						+ '			WHERE *itemId = :parentId '
						+ '			UNION '
						+ '			SELECT :parentId'
						+ '		) AS ancestors',
						{
							through: hierarchy.through.tableName,
							itemId: hierarchy.throughKey,
							ancestorId: hierarchy.throughForeignKey
						}
					);

					return sequelize.query(sql, null, {transaction: options.transaction}, {id: item.id, parentId: parentId});
				});
			})
			.return();
		},

		beforeFind: function(options) {
			// check options do not include illegal hierarchies
			if (options.hierarchy) throw new Error('You cannot get hierarchy of ' + this.name + ' - at top level with find()');
			checkHierarchy(options, this);
		},
		afterFind: function(result, options) {
			// convert hierarchies into trees
			convertHierarchies(result, options, this);
		},

		beforeFindAll: function(options) {
			// check options do not include illegal hierarchies
			if (options.hierarchy && !this.hierarchy) throw new Error('You cannot get hierarchy of ' + this.name + ' - it is not hierarchical');
			checkHierarchy(options, this);
		},
		afterFindAll: function(results, options) {
			// convert hierarchies into trees
			convertHierarchies(results, options, this);
		}
	};

	function replaceIdentifiers(sql, identifiers)
	{
		_.forIn(identifiers, function(replacement, identifier) {
			sql = sql.replace(new RegExp('\\*' + identifier, 'g'), escapeIdentifier(replacement));
		});
		return sql.replace(/[ \t\r\n]+/g, ' ');
	}

	function escapeIdentifier(identifier)
	{
		return '`' + identifier.replace(/`/g, '``') + '`';
	}

	function checkHierarchy(options, model)
	{
		// check options do not include illegal hierarchies - throw error if so
		if (!options.include) return;

		options.include.forEach(function(include) {
			var includeModel = include.model;

			// if hierarchy set, check is legal
			if (include.hierarchy) {
				if (!includeModel.hierarchy) throw new Error('You cannot get hierarchy of ' + includeModel.name + ' - it is not hierarchical');
				if (includeModel !== model) throw new Error('You cannot get a hierarchy of ' + includeModel.name + ' without including it from a parent');
				if (include.as !== model.hierarchy.descendentsAs) throw new Error('You cannot set hierarchy on ' + model.name + ' without using the ' + model.hierarchy.descendentsAs + ' accessor');
			}

			// check includes
			checkHierarchy(include, includeModel);
		});
	}

	function convertHierarchies(results, options, model, parent)
	{
		// convert hierarchies into trees
		if (options.include) {
			options.include.forEach(function(include) {
				var includeModel = include.model,
					accessor = include.as;

				if (Array.isArray(results)) {
					results.forEach(function(result) {
						convertHierarchies(result[accessor], include, includeModel, result);
					});
				} else {
					convertHierarchies(results[accessor], include, includeModel, results);
				}
			});
		}

		if (options.hierarchy) convertHierarchy(results, model, parent);
	}

	function convertHierarchy(results, model, parent)
	{
		var hierarchy = model.hierarchy,
			primaryKey = model.primaryKeyAttribute,
			foreignKey = hierarchy.foreignKey,
			childrenAccessor = hierarchy.childrenAs,
			descendentsAccessor = hierarchy.descendentsAs,
			throughAccessor = Utils.singularize(hierarchy.through.name);

		// get parent id and move results from parent.descendents to parent.children
		var parentId = null;
		if (parent) {
			parentId = parent[primaryKey];

			parent.dataValues[childrenAccessor] = parent[childrenAccessor] = results;
			delete parent[descendentsAccessor];
			delete parent.dataValues[descendentsAccessor];
		}

		// run through all results, turning into tree

		// find rows which are not top level and move into references
		var references = {};

		for (var i = 0; i < results.length; i++) {
			var item = results[i];

			// remove reference to through table
			delete item[throughAccessor];
			delete item.dataValues[throughAccessor];

			// add into references
			references[item[primaryKey]] = item;

			// if not a root-level item, remove from results
			if (item[foreignKey] !== parentId) {
				results.splice(i, 1);
				i--;
			}
		}

		// run through references, nesting within parents
		_.forIn(references, function(item) {
			// nest inside parent
			var thisParentId = item[foreignKey];
			if (thisParentId !== parentId) {
				var parent = references[thisParentId];
				if (!parent[childrenAccessor]) parent.dataValues[childrenAccessor] = parent[childrenAccessor] = [];
				parent[childrenAccessor].push(item);
			}
		});
	}
};
<|endoftext|>


<commit_before>import React, { PropTypes } from "react";
import cx from "classNames";
import { InputCore } from "../input";

/**
 * Simple component for a basic checkbox
 */
class Checkbox extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      checked: this.props.checked || false
    };
  }

  // Handles new checkbox clicks and sets value and checked status of hidden input
  _clickHandler = event => {
    if (this.state.checked === true) {
      this.setState({ checked: false });
    } else {
      this.setState({ checked: true });
    }

    /* Check if onClick has been passed, if so call it. */
    if (this.props.onClick) {
      /* Pass the event object, and a data object to the click handler.
       The data object contains a boolean for whether the checkbox was
       clicked or not, plus all the props passed to the object.  */
      this.props.onClick(event, {"checked": this.state.checked, "props": this.props});
    }
  };

  render() {
    const { title, label, disabled, inline, className } = this.props;
    const display = inline ? "inline" : "block";
    const controlStyle = cx("control", "control--checkbox", display);
    const title_label = title ? title : label;
    const labelClasses = this.state.checked
      ? cx("checked", display)
      : cx("not_checked", display);

    return (

        <InputCore
          label={label}
          type="checkbox"
          disabled={disabled}
          checked={this.state.checked}
        />
        {label &&

{label}

}

    );
  }
}

Checkbox.propTypes = {
  /**
   * Text for checkbox label
   * @examples 'Some Label'
   */
  label: PropTypes.string,
  /**
   * A css class name that will be appended to the wrapping  element around the <input> and  elements.
   */
  className: PropTypes.string,
  /**
   * If included, checkbox is disabled
   * @examples <Checkbox disabled />, <Checkbox disabled={true} />
   */
  disabled: PropTypes.bool,
  /**
   * If included, renders the checkbox and it's label inline, so it can be side-by-side to other content.
   */
  inline: PropTypes.bool,
  /**
   * Text for checkbox label title. (i.e. "alt-text" for checkboxes, useful for accessibility). If not provided, will be label text.
   * @examples 'Some Title'
   */
  title: PropTypes.string,
  /**
   * Defines if checkbox should be checked on load.
   */
  checked: PropTypes.bool,
  /**
   * Allows user to pass a callback for click events.
   */
  onClick: PropTypes.func
};

Checkbox.defaultProps = {
  className: "",
  disabled: false,
  inline: false,
  checked: false
};

export default Checkbox;
<commit_msg>Change to onClick to onChange<commit_after>import React, { PropTypes } from "react";
import cx from "classNames";
import { InputCore } from "../input";

/**
 * Simple component for a basic checkbox
 */
class Checkbox extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      checked: this.props.checked || false
    };
  }

  // Handles new checkbox clicks and sets value and checked status of hidden input
  _clickHandler = event => {
    /* Check if onClick has been passed, if so call it. */
    if (this.props.onClick) {
      /* Pass the event object, and a data object to the click handler.
       The data object contains a boolean for whether the checkbox was
       clicked or not, plus all the props passed to the object.  */
      this.props.onClick(event, {"checked": this.state.checked, "props": this.props});
    }

    if (this.state.checked === true) {
      this.setState({ checked: false });
    } else {
      this.setState({ checked: true });
    }

    /* Check if onChange has been passed, if so call it. */
    if (this.props.onChange) {
      /* Pass the event object, and a data object to the click handler.
       The data object contains a boolean for whether the checkbox was
       clicked or not, plus all the props passed to the object.  */
      this.props.onChange(event, {"checked": this.state.checked, "props": this.props});
    }
  };

  render() {
    const { title, label, disabled, inline, className } = this.props;
    const display = inline ? "inline" : "block";
    const controlStyle = cx("control", "control--checkbox", display);
    const title_label = title ? title : label;
    const labelClasses = this.state.checked
      ? cx("checked", display)
      : cx("not_checked", display);

    return (

        <InputCore
          label={label}
          type="checkbox"
          disabled={disabled}
          checked={this.state.checked}
        />
        {label &&

{label}

}

    );
  }
}

Checkbox.propTypes = {
  /**
   * Text for checkbox label
   * @examples 'Some Label'
   */
  label: PropTypes.string,
  /**
   * A css class name that will be appended to the wrapping  element around the <input> and  elements.
   */
  className: PropTypes.string,
  /**
   * If included, checkbox is disabled
   * @examples <Checkbox disabled />, <Checkbox disabled={true} />
   */
  disabled: PropTypes.bool,
  /**
   * If included, renders the checkbox and it's label inline, so it can be side-by-side to other content.
   */
  inline: PropTypes.bool,
  /**
   * Text for checkbox label title. (i.e. "alt-text" for checkboxes, useful for accessibility). If not provided, will be label text.
   * @examples 'Some Title'
   */
  title: PropTypes.string,
  /**
   * Defines if checkbox should be checked on load.
   */
  checked: PropTypes.bool,
  /**
   * Allows user to pass a callback for click events.
   */
  onClick: PropTypes.func
};

Checkbox.defaultProps = {
  className: "",
  disabled: false,
  inline: false,
  checked: false
};

export default Checkbox;
<|endoftext|>


<commit_before>'use strict'

import React, { PropTypes } from 'react'
import FormSelect from '../../components/form-select'
import FormSearch from './form-search'

const HeaderFilter = ({ monthFilter, stateFilter, searchField }) => (
  <nav className='filter'>
    <FormSelect key='months' {...monthFilter} />
    <FormSelect key='states' {...stateFilter} />

    <FormSearch />
  </nav>
)

HeaderFilter.propTypes = {
  monthFilter: PropTypes.object.isRequired,
  stateFilter: PropTypes.object.isRequired,
  searchField: PropTypes.string.isRequired
}

export default HeaderFilter
<commit_msg>pass props to header filter<commit_after>'use strict'

import React, { PropTypes } from 'react'
import FormSelect from '../../components/form-select'
import FormSearch from './form-search'

const HeaderFilter = ({
  monthFilter,
  stateFilter,
  searchField,
  handleChangeMonth,
  handleChangeState
}) => (
  <nav className='filter'>
    <FormSelect
      key='months'
      {...monthFilter}
      handleChange={handleChangeMonth} />

    <FormSelect
      key='states'
      {...stateFilter}
      handleChange={handleChangeState} />

    <FormSearch />
  </nav>
)

HeaderFilter.propTypes = {
  monthFilter: PropTypes.object.isRequired,
  stateFilter: PropTypes.object.isRequired,
  searchField: PropTypes.string.isRequired,
  handleChangeMonth: PropTypes.func.isRequired,
  handleChangeState: PropTypes.func.isRequired
}

export default HeaderFilter
<|endoftext|>