<commit_before>/**
 * @preserve EventEmitter v3.0.0
 *
 * Copyright 2011, Oliver Caldwell (olivercaldwell.co.uk)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * https://github.com/Wolfy87/EventEmitter
 */

(function(exports) {
	'use strict';

	/**
	 * EventEmitter class
	 * Creates an object with event registering and firing methods
	 */
	function EventEmitter() {
		// Initialise required storage variables
		this._events = {};
		this._maxListeners = 10;
	}

	/**
	 * Event class
	 * Contains Event methods and property storage
	 *
	 * @param {String} type Event type name
	 * @param {Function} listener Function to be called when the event is fired
	 * @param {Object} scope Object that this should be set to when the listener is called
	 * @param {Boolean} once If true then the listener will be removed after the first call
	 * @param {Object} instance The parent EventEmitter instance
	 */
	function Event(type, listener, scope, once, instance) {
		// Store arguments
		this.type = type;
		this.listener = listener;
		this.scope = scope;
		this.once = once;
		this.instance = instance;
	}

	/**
	 * Executes the listener
	 *
	 * @param {Array} args List of arguments to pass to the listener
	 * @return {Boolean} If false then it was a once event
	 */
	Event.prototype.fire = function(args) {
		this.listener.apply(this.scope || this, args);

		// Remove the listener if this is a once only listener
		if(this.once) {
			this.instance.removeListener(this.type, this.listener);
			return false;
		}
	};

	/**
	 * Passes every listener for a specified event to a function one at a time
	 *
	 * @param {String} type Event type name
	 * @param {Function} callback Function to pass each listener to
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.eachListener = function(type, callback) {
		// Initialise variables
		var i = null,
			possibleListeners = null,
			result = null;

		// Only loop if the type exists
		if(this._events.hasOwnProperty(type)) {
			possibleListeners = this._events[type];

			for(i = 0; i < possibleListeners.length; i += 1) {
				result = callback.call(this, possibleListeners[i], i);

				if(result === false) {
					i -= 1;
				}
				else if(result === true) {
					break;
				}
			}
		}

		// Return the instance to allow chaining
		return this;
	};

	/**
	 * Adds an event listener for the specified event
	 *
	 * @param {String} type Event type name
	 * @param {Function} listener Function to be called when the event is fired
	 * @param {Object} scope Object that this should be set to when the listener is called
	 * @param {Boolean} once If true then the listener will be removed after the first call
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.addListener = function(type, listener, scope, once) {
		// Create the listener array if it does not exist yet
		if(!this._events.hasOwnProperty(type)) {
			this._events[type] = [];
		}

		// Push the new event to the array
		this._events[type].push(new Event(type, listener, scope, once, this));

		// Emit the new listener event
		this.emit('newListener', type, listener, scope, once);

		// Check if we have exceeded the maxListener count
		// Ignore this check if the count is 0
		// Also don't check if we have already fired a warning
		if(this._maxListeners && !this._events[type].warned && this._events[type].length > this._maxListeners) {
			// The max listener count has been exceeded!
			// My god, we have a mother flipping memory leak on our hands!
			// Beter let the big developer in the sky know
			console.warn('Possible EventEmitter memory leak detected. ' + this._events[type].length + ' listeners added. Use emitter.setMaxListeners() to increase limit.');

			// Set the flag so it doesn't fire again
			this._events[type].warned = true;
		}

		// Return the instance to allow chaining
		return this;
	};

	/**
	 * Alias of the addListener method
	 *
	 * @param {String} type Event type name
	 * @param {Function} listener Function to be called when the event is fired
	 * @param {Object} scope Object that this should be set to when the listener is called
	 * @param {Boolean} once If true then the listener will be removed after the first call
	 */
	EventEmitter.prototype.on = EventEmitter.prototype.addListener;

	/**
	 * Alias of the addListener method but will remove the event after the first use
	 *
	 * @param {String} type Event type name
	 * @param {Function} listener Function to be called when the event is fired
	 * @param {Object} scope Object that this should be set to when the listener is called
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.once = function(type, listener, scope) {
		return this.addListener(type, listener, scope, true);
	};

	/**
	 * Removes the a listener for the specified event
	 *
	 * @param {String} type Event type name the listener must have for the event to be removed
	 * @param {Function} listener Listener the event must have to be removed
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.removeListener = function(type, listener) {
		this.eachListener(type, function(currentListener, index) {
			// If this is the listener remove it from the array
			if(currentListener.listener === listener) {
				this._events[type].splice(index, 1);
			}
		});

		// Remove the property if there are no more listeners
		if(this._events[type] && this._events[type].length === 0) {
			delete this._events[type];
		}

		// Return the instance to allow chaining
		return this;
	};

	/**
	 * Removes all listeners for a specified event
	 * If no event type is passed it will remove every listener
	 *
	 * @param {String} type Event type name to remove all listeners from
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.removeAllListeners = function(type) {
		// Check for a type, if there is none remove all listeners
		// If there is a type however, just remove the listeners for that type
		if(type && this._events.hasOwnProperty(type)) {
			delete this._events[type];
		}
		else if(!type) {
			this._events = {};
		}

		// Return the instance to allow chaining
		return this;
	};

	/**
	 * Retrieves the array of listeners for a specified event
	 *
	 * @param {String} type Event type name to return all listeners from
	 * @return {Array | Boolean} Will return either an array of listeners or false if there are none
	 */
	EventEmitter.prototype.listeners = function(type) {
		// Return the array of listeners of false if it does not exist
		if(this._events.hasOwnProperty(type)) {
			return this._events[type];
		}

		return false;
	};

	/**
	 * Emits an event executing all appropriate listeners
	 * All values passed after the type will be passed as arguments to the listeners
	 *
	 * @param {String} type Event type name to run all listeners from
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.emit = function(type) {
		// Calculate the arguments
		var args = [].slice.call(arguments).splice(1);

		this.eachListener(type, function(currentListener) {
			return currentListener.fire(args);
		});

		// Return the instance to allow chaining
		return this;
	};

	/**
	 * Sets the max listener count for the EventEmitter
	 * When the count of listeners for an event exceeds this limit a warning will be printed
	 * Set to 0 for no limit
	 *
	 * @param {Number} maxListeners The new max listener limit
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.setMaxListeners = function(maxListeners) {
		this._maxListeners = maxListeners;

		// Return the instance to allow chaining
		return this;
	};

	// Export the class
	exports.EventEmitter = EventEmitter;
}(this));<commit_msg>Improved the header comment with a new licence stratagy. Only GPL<commit_after>/**
 * @preserve EventEmitter v3.0.0
 * https://github.com/Wolfy87/EventEmitter
 *
 * Licenced under GPL v3 http://www.gnu.org/licenses/gpl.html
 * Oliver Caldwell (olivercaldwell.co.uk)
 */

(function(exports) {
	'use strict';

	/**
	 * EventEmitter class
	 * Creates an object with event registering and firing methods
	 */
	function EventEmitter() {
		// Initialise required storage variables
		this._events = {};
		this._maxListeners = 10;
	}

	/**
	 * Event class
	 * Contains Event methods and property storage
	 *
	 * @param {String} type Event type name
	 * @param {Function} listener Function to be called when the event is fired
	 * @param {Object} scope Object that this should be set to when the listener is called
	 * @param {Boolean} once If true then the listener will be removed after the first call
	 * @param {Object} instance The parent EventEmitter instance
	 */
	function Event(type, listener, scope, once, instance) {
		// Store arguments
		this.type = type;
		this.listener = listener;
		this.scope = scope;
		this.once = once;
		this.instance = instance;
	}

	/**
	 * Executes the listener
	 *
	 * @param {Array} args List of arguments to pass to the listener
	 * @return {Boolean} If false then it was a once event
	 */
	Event.prototype.fire = function(args) {
		this.listener.apply(this.scope || this, args);

		// Remove the listener if this is a once only listener
		if(this.once) {
			this.instance.removeListener(this.type, this.listener);
			return false;
		}
	};

	/**
	 * Passes every listener for a specified event to a function one at a time
	 *
	 * @param {String} type Event type name
	 * @param {Function} callback Function to pass each listener to
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.eachListener = function(type, callback) {
		// Initialise variables
		var i = null,
			possibleListeners = null,
			result = null;

		// Only loop if the type exists
		if(this._events.hasOwnProperty(type)) {
			possibleListeners = this._events[type];

			for(i = 0; i < possibleListeners.length; i += 1) {
				result = callback.call(this, possibleListeners[i], i);

				if(result === false) {
					i -= 1;
				}
				else if(result === true) {
					break;
				}
			}
		}

		// Return the instance to allow chaining
		return this;
	};

	/**
	 * Adds an event listener for the specified event
	 *
	 * @param {String} type Event type name
	 * @param {Function} listener Function to be called when the event is fired
	 * @param {Object} scope Object that this should be set to when the listener is called
	 * @param {Boolean} once If true then the listener will be removed after the first call
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.addListener = function(type, listener, scope, once) {
		// Create the listener array if it does not exist yet
		if(!this._events.hasOwnProperty(type)) {
			this._events[type] = [];
		}

		// Push the new event to the array
		this._events[type].push(new Event(type, listener, scope, once, this));

		// Emit the new listener event
		this.emit('newListener', type, listener, scope, once);

		// Check if we have exceeded the maxListener count
		// Ignore this check if the count is 0
		// Also don't check if we have already fired a warning
		if(this._maxListeners && !this._events[type].warned && this._events[type].length > this._maxListeners) {
			// The max listener count has been exceeded!
			// My god, we have a mother flipping memory leak on our hands!
			// Beter let the big developer in the sky know
			console.warn('Possible EventEmitter memory leak detected. ' + this._events[type].length + ' listeners added. Use emitter.setMaxListeners() to increase limit.');

			// Set the flag so it doesn't fire again
			this._events[type].warned = true;
		}

		// Return the instance to allow chaining
		return this;
	};

	/**
	 * Alias of the addListener method
	 *
	 * @param {String} type Event type name
	 * @param {Function} listener Function to be called when the event is fired
	 * @param {Object} scope Object that this should be set to when the listener is called
	 * @param {Boolean} once If true then the listener will be removed after the first call
	 */
	EventEmitter.prototype.on = EventEmitter.prototype.addListener;

	/**
	 * Alias of the addListener method but will remove the event after the first use
	 *
	 * @param {String} type Event type name
	 * @param {Function} listener Function to be called when the event is fired
	 * @param {Object} scope Object that this should be set to when the listener is called
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.once = function(type, listener, scope) {
		return this.addListener(type, listener, scope, true);
	};

	/**
	 * Removes the a listener for the specified event
	 *
	 * @param {String} type Event type name the listener must have for the event to be removed
	 * @param {Function} listener Listener the event must have to be removed
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.removeListener = function(type, listener) {
		this.eachListener(type, function(currentListener, index) {
			// If this is the listener remove it from the array
			if(currentListener.listener === listener) {
				this._events[type].splice(index, 1);
			}
		});

		// Remove the property if there are no more listeners
		if(this._events[type] && this._events[type].length === 0) {
			delete this._events[type];
		}

		// Return the instance to allow chaining
		return this;
	};

	/**
	 * Removes all listeners for a specified event
	 * If no event type is passed it will remove every listener
	 *
	 * @param {String} type Event type name to remove all listeners from
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.removeAllListeners = function(type) {
		// Check for a type, if there is none remove all listeners
		// If there is a type however, just remove the listeners for that type
		if(type && this._events.hasOwnProperty(type)) {
			delete this._events[type];
		}
		else if(!type) {
			this._events = {};
		}

		// Return the instance to allow chaining
		return this;
	};

	/**
	 * Retrieves the array of listeners for a specified event
	 *
	 * @param {String} type Event type name to return all listeners from
	 * @return {Array | Boolean} Will return either an array of listeners or false if there are none
	 */
	EventEmitter.prototype.listeners = function(type) {
		// Return the array of listeners of false if it does not exist
		if(this._events.hasOwnProperty(type)) {
			return this._events[type];
		}

		return false;
	};

	/**
	 * Emits an event executing all appropriate listeners
	 * All values passed after the type will be passed as arguments to the listeners
	 *
	 * @param {String} type Event type name to run all listeners from
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.emit = function(type) {
		// Calculate the arguments
		var args = [].slice.call(arguments).splice(1);

		this.eachListener(type, function(currentListener) {
			return currentListener.fire(args);
		});

		// Return the instance to allow chaining
		return this;
	};

	/**
	 * Sets the max listener count for the EventEmitter
	 * When the count of listeners for an event exceeds this limit a warning will be printed
	 * Set to 0 for no limit
	 *
	 * @param {Number} maxListeners The new max listener limit
	 * @return {Object} The current EventEmitter instance to allow chaining
	 */
	EventEmitter.prototype.setMaxListeners = function(maxListeners) {
		this._maxListeners = maxListeners;

		// Return the instance to allow chaining
		return this;
	};

	// Export the class
	exports.EventEmitter = EventEmitter;
}(this));<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;
var pg = require('pg');
var Q = require("q");
var request = require("request");
var db = require("./db");

const scriptRules = require('./script.json');

function wait(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

//move to separeate file
var promises = [];
function nlp(query,sessionId){
	var deferred = Q.defer();
	var options = {
		"method" : "POST",
		"url" : "https://api.api.ai/v1/query?v=20150910",
		"json" : {
			"query" : query,
			"lang" : "en",
			"sessionId" : sessionId
		},
		"headers" : {
			"Authorization" : "Bearer " + process.env.API_AI_TOKEN,
			"Content-Type" : "application/json"
		}
	};

	console.log("===nlp");
	console.log("===query: ",query);
	console.log("===sessionId",sessionId);
	request(options,function(err,response,body){
		if(err){
			console.log("===nlp failed because: ",err.message);
			deferred.reject(err);
		}else{
			body.sessionId = sessionId;
			if(response.statusCode == 200){
				console.log("===nlp succeeded ");
				deferred.resolve(body);
			}else{
				deferred.reject(body);
			}
		}
	});
	return deferred.promise;
}

module.exports = new Script({
    processing: {
        //prompt: (bot) => bot.say('Beep boop...'),
        receive: () => 'processing'
    },

    start: {
        receive: (bot) => {
            return bot.say('Get started by saying BOT.')
                .then(() => 'speak');
        }
    },

    speak: {
        receive: (bot, message) => {
            console.log("===bot user ",bot.userId);
            let upperText = message.text.trim().toUpperCase();

            console.log("===before db");
            promises.push(newUser(bot));
            console.log("===after db");

            function updateSilent() {
                switch (upperText) {
                    case "CONNECT ME":
                        return bot.setProp("silent", true);
                    case "DISCONNECT":
                        return bot.setProp("silent", false);
                    default:
                        return Promise.resolve();
                }
            }

            function getSilent() {
                return bot.getProp("silent");
            }

            function processMessage(isSilent) {
                if (isSilent) {
                    return Promise.resolve("speak");
                }

                var source;
                var fulfillmentSpeech;
                var simplified;
                promises.push(nlp(upperText, bot.userId));

                Q.all(promises)
                .then(function(responses) {
                    // response is the JSON from API.ai
                    responses.forEach(function(response) {
                        console.log("===in Q.all");
                        console.log("===received result from API.ai",response);
                        source = response.result.source;
                        if (source && source !== 'agent')
                        {
                            fulfillmentSpeech = response.result.fulfillment.speech;
                            simplified = response.result.parameters.simplified;
                        }
                        console.log("source: ", source);
                        console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                        console.log("simplified: ", simplified);

                        respondMessage(source, fulfillmentSpeech, simplified);
                    });
                }, function(error) {
                    console.log("[webhook_post.js]", error);
                });
                //return next();

            }

            function respondMessage(source, fulfillmentSpeech, simplified)
            {
                console.log("source: ", source);
                console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                console.log("simplified: ", simplified);
                if (source != 'agent')
                {
                    console.log("===source is ", source);
                    if (fulfillmentSpeech)
                    {
                        console.log("fulfillmentSpeech is: ", fulfillmentSpeech);
                        return bot.say(fulfillmentSpeech).then(() => 'speak');
                    }
                    else if (simplified)
                    {
                        console.log("simplified is: ", simplified);
                        upperText = simplified.toUpperCase();
                    }
                }

                if (!_.has(scriptRules, upperText)) {
                    return bot.say(`So, I'm good at structured conversations but stickers, emoji and sentences still confuse me. Say 'more' to chat about something else.`).then(() => 'speak');
                }

                var response = scriptRules[upperText];
                var lines = response.split('\n');

                var p = Promise.resolve();
                _.each(lines, function(line) {
                    line = line.trim();
                    p = p.then(function() {
                        console.log(line);
                        return wait(50).then(function() {
                            return bot.say(line);
                        });
                    });
                });

                return p.then(() => 'speak');
            }

            return updateSilent()
                .then(getSilent)
                .then(processMessage);
        }
    }
});
<commit_msg>grasping<commit_after>'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;
var pg = require('pg');
var Q = require("q");
var request = require("request");
var newUser = require("./db");

const scriptRules = require('./script.json');

function wait(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

//move to separeate file
var promises = [];
function nlp(query,sessionId){
	var deferred = Q.defer();
	var options = {
		"method" : "POST",
		"url" : "https://api.api.ai/v1/query?v=20150910",
		"json" : {
			"query" : query,
			"lang" : "en",
			"sessionId" : sessionId
		},
		"headers" : {
			"Authorization" : "Bearer " + process.env.API_AI_TOKEN,
			"Content-Type" : "application/json"
		}
	};

	console.log("===nlp");
	console.log("===query: ",query);
	console.log("===sessionId",sessionId);
	request(options,function(err,response,body){
		if(err){
			console.log("===nlp failed because: ",err.message);
			deferred.reject(err);
		}else{
			body.sessionId = sessionId;
			if(response.statusCode == 200){
				console.log("===nlp succeeded ");
				deferred.resolve(body);
			}else{
				deferred.reject(body);
			}
		}
	});
	return deferred.promise;
}

module.exports = new Script({
    processing: {
        //prompt: (bot) => bot.say('Beep boop...'),
        receive: () => 'processing'
    },

    start: {
        receive: (bot) => {
            return bot.say('Get started by saying BOT.')
                .then(() => 'speak');
        }
    },

    speak: {
        receive: (bot, message) => {
            console.log("===bot user ",bot.userId);
            let upperText = message.text.trim().toUpperCase();

            console.log("===before db");
            promises.push(newUser(bot));
            console.log("===after db");

            function updateSilent() {
                switch (upperText) {
                    case "CONNECT ME":
                        return bot.setProp("silent", true);
                    case "DISCONNECT":
                        return bot.setProp("silent", false);
                    default:
                        return Promise.resolve();
                }
            }

            function getSilent() {
                return bot.getProp("silent");
            }

            function processMessage(isSilent) {
                if (isSilent) {
                    return Promise.resolve("speak");
                }

                var source;
                var fulfillmentSpeech;
                var simplified;
                promises.push(nlp(upperText, bot.userId));

                Q.all(promises)
                .then(function(responses) {
                    // response is the JSON from API.ai
                    responses.forEach(function(response) {
                        console.log("===in Q.all");
                        console.log("===received result from API.ai",response);
                        source = response.result.source;
                        if (source && source !== 'agent')
                        {
                            fulfillmentSpeech = response.result.fulfillment.speech;
                            simplified = response.result.parameters.simplified;
                        }
                        console.log("source: ", source);
                        console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                        console.log("simplified: ", simplified);

                        respondMessage(source, fulfillmentSpeech, simplified);
                    });
                }, function(error) {
                    console.log("[webhook_post.js]", error);
                });
                //return next();

            }

            function respondMessage(source, fulfillmentSpeech, simplified)
            {
                console.log("source: ", source);
                console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                console.log("simplified: ", simplified);
                if (source != 'agent')
                {
                    console.log("===source is ", source);
                    if (fulfillmentSpeech)
                    {
                        console.log("fulfillmentSpeech is: ", fulfillmentSpeech);
                        return bot.say(fulfillmentSpeech).then(() => 'speak');
                    }
                    else if (simplified)
                    {
                        console.log("simplified is: ", simplified);
                        upperText = simplified.toUpperCase();
                    }
                }

                if (!_.has(scriptRules, upperText)) {
                    return bot.say(`So, I'm good at structured conversations but stickers, emoji and sentences still confuse me. Say 'more' to chat about something else.`).then(() => 'speak');
                }

                var response = scriptRules[upperText];
                var lines = response.split('\n');

                var p = Promise.resolve();
                _.each(lines, function(line) {
                    line = line.trim();
                    p = p.then(function() {
                        console.log(line);
                        return wait(50).then(function() {
                            return bot.say(line);
                        });
                    });
                });

                return p.then(() => 'speak');
            }

            return updateSilent()
                .then(getSilent)
                .then(processMessage);
        }
    }
});
<|endoftext|>


<commit_before>/* global hasOwn, slice */

( function () {

	/**
	 * @class
	 */
	OO.EventEmitter = function OoEventEmitter() {
		// Properties

		/**
		 * Storage of bound event handlers by event name.
		 *
		 * @private
		 * @property {Object} bindings
		 */
		this.bindings = {};
	};

	OO.initClass( OO.EventEmitter );

	/* Private helper functions */

	/**
	 * Validate a function or method call in a context
	 *
	 * For a method name, check that it names a function in the context object
	 *
	 * @private
	 * @param {Function|string} method Function or method name
	 * @param {any} context The context of the call
	 * @throws {Error} A method name is given but there is no context
	 * @throws {Error} In the context object, no property exists with the given name
	 * @throws {Error} In the context object, the named property is not a function
	 */
	function validateMethod( method, context ) {
		// Validate method and context
		if ( typeof method === 'string' ) {
			// Validate method
			if ( context === undefined || context === null ) {
				throw new Error( 'Method name "' + method + '" has no context.' );
			}
			if ( typeof context[ method ] !== 'function' ) {
				// Technically the property could be replaced by a function before
				// call time. But this probably signals a typo.
				throw new Error( 'Property "' + method + '" is not a function' );
			}
		} else if ( typeof method !== 'function' ) {
			throw new Error( 'Invalid callback. Function or method name expected.' );
		}
	}

	/**
	 * @private
	 * @param {OO.EventEmitter} eventEmitter Event emitter
	 * @param {string} event Event name
	 * @param {Object} binding
	 */
	function addBinding( eventEmitter, event, binding ) {
		var bindings;
		// Auto-initialize bindings list
		if ( hasOwn.call( eventEmitter.bindings, event ) ) {
			bindings = eventEmitter.bindings[ event ];
		} else {
			bindings = eventEmitter.bindings[ event ] = [];
		}
		// Add binding
		bindings.push( binding );
	}

	/* Methods */

	/**
	 * Add a listener to events of a specific event.
	 *
	 * The listener can be a function or the string name of a method; if the latter, then the
	 * name lookup happens at the time the listener is called.
	 *
	 * @param {string} event Type of event to listen to
	 * @param {Function|string} method Function or method name to call when event occurs
	 * @param {Array} [args] Arguments to pass to listener, will be prepended to emitted arguments
	 * @param {Object} [context=null] Context object for function or method call
	 * @return {OO.EventEmitter}
	 * @throws {Error} Listener argument is not a function or a valid method name
	 */
	OO.EventEmitter.prototype.on = function ( event, method, args, context ) {
		validateMethod( method, context );

		// Ensure consistent object shape (optimisation)
		addBinding( this, event, {
			method: method,
			args: args,
			context: ( arguments.length < 4 ) ? null : context,
			once: false
		} );
		return this;
	};

	/**
	 * Add a one-time listener to a specific event.
	 *
	 * @param {string} event Type of event to listen to
	 * @param {Function} listener Listener to call when event occurs
	 * @return {OO.EventEmitter}
	 */
	OO.EventEmitter.prototype.once = function ( event, listener ) {
		validateMethod( listener );

		// Ensure consistent object shape (optimisation)
		addBinding( this, event, {
			method: listener,
			args: undefined,
			context: null,
			once: true
		} );
		return this;
	};

	/**
	 * Remove a specific listener from a specific event.
	 *
	 * @param {string} event Type of event to remove listener from
	 * @param {Function|string} [method] Listener to remove. Must be in the same form as was passed
	 * to "on". Omit to remove all listeners.
	 * @param {Object} [context=null] Context object function or method call
	 * @return {OO.EventEmitter}
	 * @throws {Error} Listener argument is not a function or a valid method name
	 */
	OO.EventEmitter.prototype.off = function ( event, method, context ) {
		var i, bindings;

		if ( arguments.length === 1 ) {
			// Remove all bindings for event
			delete this.bindings[ event ];
			return this;
		}

		validateMethod( method, context );

		if ( !hasOwn.call( this.bindings, event ) || !this.bindings[ event ].length ) {
			// No matching bindings
			return this;
		}

		// Default to null context
		if ( arguments.length < 3 ) {
			context = null;
		}

		// Remove matching handlers
		bindings = this.bindings[ event ];
		i = bindings.length;
		while ( i-- ) {
			if ( bindings[ i ].method === method && bindings[ i ].context === context ) {
				bindings.splice( i, 1 );
			}
		}

		// Cleanup if now empty
		if ( bindings.length === 0 ) {
			delete this.bindings[ event ];
		}
		return this;
	};

	/**
	 * Emit an event.
	 *
	 * All listeners for the event will be called synchronously, in an
	 * unspecified order. If any listeners throw an exception, this won't
	 * disrupt the calls to the remaining listeners; however, the exception
	 * won't be thrown until the next tick.
	 *
	 * Listeners should avoid mutating the emitting object, as this is
	 * something of an anti-pattern which can easily result in
	 * hard-to-understand code with hidden side-effects and dependencies.
	 *
	 * @param {string} event Type of event
	 * @param {...any} [args] Arguments passed to the event handler
	 * @return {boolean} Whether the event was handled by at least one listener
	 */
	OO.EventEmitter.prototype.emit = function ( event ) {
		var bindings, args, i, binding, method;

		if ( !hasOwn.call( this.bindings, event ) ) {
			return false;
		}

		// Slicing ensures that we don't get tripped up by event
		// handlers that add/remove bindings
		bindings = this.bindings[ event ].slice();
		args = slice.call( arguments, 1 );
		for ( i = 0; i < bindings.length; i++ ) {
			binding = bindings[ i ];
			if ( typeof binding.method === 'string' ) {
				// Lookup method by name (late binding)
				method = binding.context[ binding.method ];
			} else {
				method = binding.method;
			}
			if ( binding.once ) {
				// Unbind before calling, to avoid any nested triggers.
				this.off( event, method );
			}
			try {
				method.apply(
					binding.context,
					binding.args ? binding.args.concat( args ) : args
				);
			} catch ( e ) {
				// If one listener has an unhandled error, don't have it
				// take down the emitter. But rethrow asynchronously so
				// debuggers can break with a full async stack trace.
				setTimeout( ( function ( error ) {
					throw error;
				} ).bind( null, e ) );
			}

		}
		return true;
	};

	/**
	 * Emit an event, propagating the first exception some listener throws
	 *
	 * All listeners for the event will be called synchronously, in an
	 * unspecified order. If any listener throws an exception, this won't
	 * disrupt the calls to the remaining listeners. The first exception
	 * thrown will be propagated back to the caller; any others won't be
	 * thrown until the next tick.
	 *
	 * Listeners should avoid mutating the emitting object, as this is
	 * something of an anti-pattern which can easily result in
	 * hard-to-understand code with hidden side-effects and dependencies.
	 *
	 * @param {string} event Type of event
	 * @param {...any} [args] Arguments passed to the event handler
	 * @return {boolean} Whether the event was handled by at least one listener
	 */
	OO.EventEmitter.prototype.emitThrow = function ( event ) {
		// We tolerate code duplication with #emit, because the
		// alternative is an extra level of indirection which will
		// appear in very many stack traces.
		var bindings, args, i, binding, method, firstError;

		if ( !hasOwn.call( this.bindings, event ) ) {
			return false;
		}

		// Slicing ensures that we don't get tripped up by event
		// handlers that add/remove bindings
		bindings = this.bindings[ event ].slice();
		args = slice.call( arguments, 1 );
		for ( i = 0; i < bindings.length; i++ ) {
			binding = bindings[ i ];
			if ( typeof binding.method === 'string' ) {
				// Lookup method by name (late binding)
				method = binding.context[ binding.method ];
			} else {
				method = binding.method;
			}
			if ( binding.once ) {
				// Unbind before calling, to avoid any nested triggers.
				this.off( event, method );
			}
			try {
				method.apply(
					binding.context,
					binding.args ? binding.args.concat( args ) : args
				);
			} catch ( e ) {
				if ( firstError === undefined ) {
					firstError = e;
				} else {
					// If one listener has an unhandled error, don't have it
					// take down the emitter. But rethrow asynchronously so
					// debuggers can break with a full async stack trace.
					setTimeout( ( function ( error ) {
						throw error;
					} ).bind( null, e ) );
				}
			}

		}
		if ( firstError !== undefined ) {
			throw firstError;
		}
		return true;
	};

	/**
	 * Connect event handlers to an object.
	 *
	 * @param {Object} context Object to call methods on when events occur
	 * @param {Object.<string,string>|Object.<string,Function>|Object.<string,Array>} methods
	 *  List of event bindings keyed by event name containing either method names, functions or
	 *  arrays containing method name or function followed by a list of arguments to be passed to
	 *  callback before emitted arguments.
	 * @return {OO.EventEmitter}
	 */
	OO.EventEmitter.prototype.connect = function ( context, methods ) {
		var method, args, event;

		for ( event in methods ) {
			method = methods[ event ];
			// Allow providing additional args
			if ( Array.isArray( method ) ) {
				args = method.slice( 1 );
				method = method[ 0 ];
			} else {
				args = [];
			}
			// Add binding
			this.on( event, method, args, context );
		}
		return this;
	};

	/**
	 * Disconnect event handlers from an object.
	 *
	 * @param {Object} context Object to disconnect methods from
	 * @param {Object.<string,string>|Object.<string,Function>|Object.<string,Array>} [methods]
	 *  List of event bindings keyed by event name. Values can be either method names, functions or
	 *  arrays containing a method name.
	 *  NOTE: To allow matching call sites with connect(), array values are allowed to contain the
	 *  parameters as well, but only the method name is used to find bindings. Tt is discouraged to
	 *  have multiple bindings for the same event to the same listener, but if used (and only the
	 *  parameters vary), disconnecting one variation of (event name, event listener, parameters)
	 *  will disconnect other variations as well.
	 * @return {OO.EventEmitter}
	 */
	OO.EventEmitter.prototype.disconnect = function ( context, methods ) {
		var i, event, method, bindings;

		if ( methods ) {
			// Remove specific connections to the context
			for ( event in methods ) {
				method = methods[ event ];
				if ( Array.isArray( method ) ) {
					method = method[ 0 ];
				}
				this.off( event, method, context );
			}
		} else {
			// Remove all connections to the context
			for ( event in this.bindings ) {
				bindings = this.bindings[ event ];
				i = bindings.length;
				while ( i-- ) {
					// bindings[i] may have been removed by the previous step's
					// this.off so check it still exists
					if ( bindings[ i ] && bindings[ i ].context === context ) {
						this.off( event, bindings[ i ].method, context );
					}
				}
			}
		}

		return this;
	};

}() );
<commit_msg>doc: Fix typo in EventEmitter documentation<commit_after>/* global hasOwn, slice */

( function () {

	/**
	 * @class
	 */
	OO.EventEmitter = function OoEventEmitter() {
		// Properties

		/**
		 * Storage of bound event handlers by event name.
		 *
		 * @private
		 * @property {Object} bindings
		 */
		this.bindings = {};
	};

	OO.initClass( OO.EventEmitter );

	/* Private helper functions */

	/**
	 * Validate a function or method call in a context
	 *
	 * For a method name, check that it names a function in the context object
	 *
	 * @private
	 * @param {Function|string} method Function or method name
	 * @param {any} context The context of the call
	 * @throws {Error} A method name is given but there is no context
	 * @throws {Error} In the context object, no property exists with the given name
	 * @throws {Error} In the context object, the named property is not a function
	 */
	function validateMethod( method, context ) {
		// Validate method and context
		if ( typeof method === 'string' ) {
			// Validate method
			if ( context === undefined || context === null ) {
				throw new Error( 'Method name "' + method + '" has no context.' );
			}
			if ( typeof context[ method ] !== 'function' ) {
				// Technically the property could be replaced by a function before
				// call time. But this probably signals a typo.
				throw new Error( 'Property "' + method + '" is not a function' );
			}
		} else if ( typeof method !== 'function' ) {
			throw new Error( 'Invalid callback. Function or method name expected.' );
		}
	}

	/**
	 * @private
	 * @param {OO.EventEmitter} eventEmitter Event emitter
	 * @param {string} event Event name
	 * @param {Object} binding
	 */
	function addBinding( eventEmitter, event, binding ) {
		var bindings;
		// Auto-initialize bindings list
		if ( hasOwn.call( eventEmitter.bindings, event ) ) {
			bindings = eventEmitter.bindings[ event ];
		} else {
			bindings = eventEmitter.bindings[ event ] = [];
		}
		// Add binding
		bindings.push( binding );
	}

	/* Methods */

	/**
	 * Add a listener to events of a specific event.
	 *
	 * The listener can be a function or the string name of a method; if the latter, then the
	 * name lookup happens at the time the listener is called.
	 *
	 * @param {string} event Type of event to listen to
	 * @param {Function|string} method Function or method name to call when event occurs
	 * @param {Array} [args] Arguments to pass to listener, will be prepended to emitted arguments
	 * @param {Object} [context=null] Context object for function or method call
	 * @return {OO.EventEmitter}
	 * @throws {Error} Listener argument is not a function or a valid method name
	 */
	OO.EventEmitter.prototype.on = function ( event, method, args, context ) {
		validateMethod( method, context );

		// Ensure consistent object shape (optimisation)
		addBinding( this, event, {
			method: method,
			args: args,
			context: ( arguments.length < 4 ) ? null : context,
			once: false
		} );
		return this;
	};

	/**
	 * Add a one-time listener to a specific event.
	 *
	 * @param {string} event Type of event to listen to
	 * @param {Function} listener Listener to call when event occurs
	 * @return {OO.EventEmitter}
	 */
	OO.EventEmitter.prototype.once = function ( event, listener ) {
		validateMethod( listener );

		// Ensure consistent object shape (optimisation)
		addBinding( this, event, {
			method: listener,
			args: undefined,
			context: null,
			once: true
		} );
		return this;
	};

	/**
	 * Remove a specific listener from a specific event.
	 *
	 * @param {string} event Type of event to remove listener from
	 * @param {Function|string} [method] Listener to remove. Must be in the same form as was passed
	 * to "on". Omit to remove all listeners.
	 * @param {Object} [context=null] Context object function or method call
	 * @return {OO.EventEmitter}
	 * @throws {Error} Listener argument is not a function or a valid method name
	 */
	OO.EventEmitter.prototype.off = function ( event, method, context ) {
		var i, bindings;

		if ( arguments.length === 1 ) {
			// Remove all bindings for event
			delete this.bindings[ event ];
			return this;
		}

		validateMethod( method, context );

		if ( !hasOwn.call( this.bindings, event ) || !this.bindings[ event ].length ) {
			// No matching bindings
			return this;
		}

		// Default to null context
		if ( arguments.length < 3 ) {
			context = null;
		}

		// Remove matching handlers
		bindings = this.bindings[ event ];
		i = bindings.length;
		while ( i-- ) {
			if ( bindings[ i ].method === method && bindings[ i ].context === context ) {
				bindings.splice( i, 1 );
			}
		}

		// Cleanup if now empty
		if ( bindings.length === 0 ) {
			delete this.bindings[ event ];
		}
		return this;
	};

	/**
	 * Emit an event.
	 *
	 * All listeners for the event will be called synchronously, in an
	 * unspecified order. If any listeners throw an exception, this won't
	 * disrupt the calls to the remaining listeners; however, the exception
	 * won't be thrown until the next tick.
	 *
	 * Listeners should avoid mutating the emitting object, as this is
	 * something of an anti-pattern which can easily result in
	 * hard-to-understand code with hidden side-effects and dependencies.
	 *
	 * @param {string} event Type of event
	 * @param {...any} [args] Arguments passed to the event handler
	 * @return {boolean} Whether the event was handled by at least one listener
	 */
	OO.EventEmitter.prototype.emit = function ( event ) {
		var bindings, args, i, binding, method;

		if ( !hasOwn.call( this.bindings, event ) ) {
			return false;
		}

		// Slicing ensures that we don't get tripped up by event
		// handlers that add/remove bindings
		bindings = this.bindings[ event ].slice();
		args = slice.call( arguments, 1 );
		for ( i = 0; i < bindings.length; i++ ) {
			binding = bindings[ i ];
			if ( typeof binding.method === 'string' ) {
				// Lookup method by name (late binding)
				method = binding.context[ binding.method ];
			} else {
				method = binding.method;
			}
			if ( binding.once ) {
				// Unbind before calling, to avoid any nested triggers.
				this.off( event, method );
			}
			try {
				method.apply(
					binding.context,
					binding.args ? binding.args.concat( args ) : args
				);
			} catch ( e ) {
				// If one listener has an unhandled error, don't have it
				// take down the emitter. But rethrow asynchronously so
				// debuggers can break with a full async stack trace.
				setTimeout( ( function ( error ) {
					throw error;
				} ).bind( null, e ) );
			}

		}
		return true;
	};

	/**
	 * Emit an event, propagating the first exception some listener throws
	 *
	 * All listeners for the event will be called synchronously, in an
	 * unspecified order. If any listener throws an exception, this won't
	 * disrupt the calls to the remaining listeners. The first exception
	 * thrown will be propagated back to the caller; any others won't be
	 * thrown until the next tick.
	 *
	 * Listeners should avoid mutating the emitting object, as this is
	 * something of an anti-pattern which can easily result in
	 * hard-to-understand code with hidden side-effects and dependencies.
	 *
	 * @param {string} event Type of event
	 * @param {...any} [args] Arguments passed to the event handler
	 * @return {boolean} Whether the event was handled by at least one listener
	 */
	OO.EventEmitter.prototype.emitThrow = function ( event ) {
		// We tolerate code duplication with #emit, because the
		// alternative is an extra level of indirection which will
		// appear in very many stack traces.
		var bindings, args, i, binding, method, firstError;

		if ( !hasOwn.call( this.bindings, event ) ) {
			return false;
		}

		// Slicing ensures that we don't get tripped up by event
		// handlers that add/remove bindings
		bindings = this.bindings[ event ].slice();
		args = slice.call( arguments, 1 );
		for ( i = 0; i < bindings.length; i++ ) {
			binding = bindings[ i ];
			if ( typeof binding.method === 'string' ) {
				// Lookup method by name (late binding)
				method = binding.context[ binding.method ];
			} else {
				method = binding.method;
			}
			if ( binding.once ) {
				// Unbind before calling, to avoid any nested triggers.
				this.off( event, method );
			}
			try {
				method.apply(
					binding.context,
					binding.args ? binding.args.concat( args ) : args
				);
			} catch ( e ) {
				if ( firstError === undefined ) {
					firstError = e;
				} else {
					// If one listener has an unhandled error, don't have it
					// take down the emitter. But rethrow asynchronously so
					// debuggers can break with a full async stack trace.
					setTimeout( ( function ( error ) {
						throw error;
					} ).bind( null, e ) );
				}
			}

		}
		if ( firstError !== undefined ) {
			throw firstError;
		}
		return true;
	};

	/**
	 * Connect event handlers to an object.
	 *
	 * @param {Object} context Object to call methods on when events occur
	 * @param {Object.<string,string>|Object.<string,Function>|Object.<string,Array>} methods
	 *  List of event bindings keyed by event name containing either method names, functions or
	 *  arrays containing method name or function followed by a list of arguments to be passed to
	 *  callback before emitted arguments.
	 * @return {OO.EventEmitter}
	 */
	OO.EventEmitter.prototype.connect = function ( context, methods ) {
		var method, args, event;

		for ( event in methods ) {
			method = methods[ event ];
			// Allow providing additional args
			if ( Array.isArray( method ) ) {
				args = method.slice( 1 );
				method = method[ 0 ];
			} else {
				args = [];
			}
			// Add binding
			this.on( event, method, args, context );
		}
		return this;
	};

	/**
	 * Disconnect event handlers from an object.
	 *
	 * @param {Object} context Object to disconnect methods from
	 * @param {Object.<string,string>|Object.<string,Function>|Object.<string,Array>} [methods]
	 *  List of event bindings keyed by event name. Values can be either method names, functions or
	 *  arrays containing a method name.
	 *  NOTE: To allow matching call sites with connect(), array values are allowed to contain the
	 *  parameters as well, but only the method name is used to find bindings. It is discouraged to
	 *  have multiple bindings for the same event to the same listener, but if used (and only the
	 *  parameters vary), disconnecting one variation of (event name, event listener, parameters)
	 *  will disconnect other variations as well.
	 * @return {OO.EventEmitter}
	 */
	OO.EventEmitter.prototype.disconnect = function ( context, methods ) {
		var i, event, method, bindings;

		if ( methods ) {
			// Remove specific connections to the context
			for ( event in methods ) {
				method = methods[ event ];
				if ( Array.isArray( method ) ) {
					method = method[ 0 ];
				}
				this.off( event, method, context );
			}
		} else {
			// Remove all connections to the context
			for ( event in this.bindings ) {
				bindings = this.bindings[ event ];
				i = bindings.length;
				while ( i-- ) {
					// bindings[i] may have been removed by the previous step's
					// this.off so check it still exists
					if ( bindings[ i ] && bindings[ i ].context === context ) {
						this.off( event, bindings[ i ].method, context );
					}
				}
			}
		}

		return this;
	};

}() );
<|endoftext|>


<commit_before>/**
 * Helper library for building mobile ArcGIS mapping applications with jQuery mobile.
 * Specifically designed for use in multiple view applications.
 * Requires: jQuery Mobile 1.3+ and ArcGIS API for JavaScript v3.5+
 * @author Andy Gup
 * @param map esri.Map
 */
var jQueryHelper = function(/* Map */ map){
    this.map = map;
    this.mapId = map.id;
    this.mapDiv = document.getElementById(map.id);
    this.basemap = map._basemap;
    this.currentPageID = null;
    this.slider = this.map._slider;

    /**
     * By default the library will automatically recenter the map
     * after an orientation event in a child view.
     * Override this if you wish to handle your own recentering
     * when the view is returned to home.
     * If you override, then listen for the jquery "helper-map-loaded" event.
     * @type {boolean}
     */
    this.autoCenter = true;

    /**
     * Map debounce delay in milliseconds
     * @type {number}
     */
    this.DEBOUNCE_DELAY = 250;

    /**
     * Constant variables
     * @type {Object}
     */
    this.localEnum = (function(){
        var values = {
            PORTRAIT:"portrait",
            LANDSCAPE:"landscape",
            DELAY: 400  //Delay in ms to wait for view to settle.
                        //You might have to experiment with this to get max performance.
        }

        return values;
    });

    this.setZoom = function(/* int */ zoom){
        localStorage.setItem("_zoomLevel",zoom);
    }

    this.getZoom = function(){
        var value = null;

        try{
            value = localStorage.getItem("_zoomLevel");
        }
        catch(err)
        {
            console.log("getZoom: " + err.message);
        }

        return value;
    }

    this.setWidth = function(/* int */ value){
        localStorage.setItem("_width",value);
    }

    this.getWidth = function(){
        var value = null;

        try{
            value = localStorage.getItem("_width");
        }
        catch(err)
        {
            console.log("getZoom: " + err.message);
        }

        return value;
    }

    this.setHeight = function(/* int */ value){
        localStorage.setItem("_height",value);
    }

    this.getHeight = function(){
        var value = null;

        try{
            value = localStorage.getItem("_height");
        }
        catch(err)
        {
            console.log("getZoom: " + err.message);
        }

        return value;
    }

    /**
     * Determines if phone is in PORTRAIT or LANDSCAPE mode
     * See localEnum() for constant values
     * @returns {string}
     */
    this.getOrientation = function(){

        if(typeof window.orientation != "undefined"){
            if(window.orientation == 0 || window.orientation == 180) return this.localEnum().PORTRAIT;
            if(window.orientation == 90 || window.orientation == 270) return this.localEnum().LANDSCAPE;
        }
        else{
            return  window.innerHeight > window.innerWidth ?
                this.localEnum().PORTRAIT :
                this.localEnum().LANDSCAPE;
        }
    }

    /**
     * Uses localStorage to save a location.
     * @param lat
     * @param lon
     * @param spatialReference
     */
    this.setCenterPt = function(lat,lon,spatialReference){
        localStorage.setItem("_centerPtX", lat);
        localStorage.setItem("_centerPtY", lon);
        localStorage.setItem("_spatialReference", spatialReference);
    }

    /**
     * Pulls a saved location from localStorage
     * Requires that setCenterPt() has been set.
     * @returns String x,y,spatialReference
     */
    this.getCenterPt = function(){
        var value = null;

        try{
            value = localStorage.getItem("_centerPtX") + "," + localStorage.getItem("_centerPtY") + "," +
                localStorage.getItem("_spatialReference");
        }
        catch(err)
        {
            console.log("getCenterFromLocalStorage: " + err.message);
        }

        return value;
    }

    /**
     * Activates the orientation listener and listens for native events.
     * Handle orientation events to allow for resizing the map and working around
     * jQuery mobile bugs related to how and when the view settles after such an event
     */
    this.setOrientationListener = function(){
        var supportsOrientationChange = "onorientationchange" in window,
            orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";

        window.addEventListener(orientationEvent, this.debounceMap(function(){
            if(this._getActivePage() == this.currentPageID){
                this.recenterOnRotate(400);
            }
        },this.DEBOUNCE_DELAY).bind(this), false);
    }

    /**
     * Minimize the number of times window readjustment fires a function
     * http://davidwalsh.name/javascript-debounce-function
     * @param func
     * @param wait
     * @param immediate
     * @returns {Function}
     */
    this.debounceMap = function (func, wait, immediate) {
        var timeout;
        return function() {
            var context = this, args = arguments;
            clearTimeout(timeout);
            timeout = setTimeout(function() {
                timeout = null;
                if (!immediate) func.apply(context, args);
            }, wait);
            if (immediate && !timeout) func.apply(context, args);
        };
    };

    /**
     * Automatically sets new center point in local storage.
     */
    this.setPanListener = function(){
        this.map.on("pan-end",function(){
            var center = this.map.extent.getCenter();
            this.setCenterPt(center.x,center.y,this.map.spatialReference);
        }.bind(this))
    }

    /**
     * Automatically sets new center point and zoom level in
     * local storage.
     */
    this.setZoomListener = function(){
        this.map.on("zoom-end",function(){
            var center = this.map.extent.getCenter();
            this.setCenterPt(center.x,center.y,this.map.spatialReference);
            this.setZoom(this.map.getZoom());
        }.bind(this))
    }

    /**
     * Sets internal page listeners
     * @param pageId
     */
    this.setPageChangeListeners = function(pageId){
        $('#' + pageId).on("pageshow",function(){
            console.log("home pageshow event");
            var currentOrientation = this.getOrientation();
            this._reinflatMap(currentOrientation);
        }.bind(this))
    }

    this.recenterOnRotate = function(/* int */ timerDelay){

        if(this.map.height == 0 || this.map.width == 0){
            var currentOrientation = this.getOrientation();
            this._reinflatMap(currentOrientation);
        }
        else{
            var timeout = null;
            timerDelay != "undefined" ? timeout = timerDelay : timeout = 500;
            setTimeout((function(){
                console.log("rotate timer complete");

                var locationStr = this.getCenterPt().split(",");
                this._centerMap(locationStr[0],locationStr[1],locationStr[2])

            }).bind(this),timeout);
        }
    }

    this._getMapDivVisibility = function(){
        var id = this.map.id;
        return $("#" + id).is(":visible");
    }

    this._debounceMapReinflate = function(callback){
        console.log("get vis " + this._getMapDivVisibility())
        if(this._getMapDivVisibility() == false){
            this.debounceMap(function(){
                console.log("debounced: " + this._getMapDivVisibility());
                callback();
            }.bind(this),this.DEBOUNCE_DELAY)()
        }
        else{
            console.log("visible!")
        }
    }

    this.resetMap = function(height,width,zoom){
        if(this.getOrientation() == this.localEnum().PORTRAIT){
            //adjust map height/width
            this.map.height = height;
            this.map.width = width;

            //adjust map div height/width
            this.mapDiv.style.height = height;
            this.mapDiv.style.width = width;

        }
        else{
            //adjust map height/width
            this.map.width = height;
            this.map.height = width;

            //adjust map div height/width
            this.mapDiv.style.width = height;
            this.mapDiv.style.height = width;
        }
    }

    /**
     * Reinflate map based on specific conditions
     * @param currentOrientation
     * @private
     */
    this._reinflatMap = function(currentOrientation){
        if(this.map.height == 0 || this.map.width ==0){
            this.debounceMap(function(){
                this.resetMap(this.getHeight(),this.getWidth(),this.getZoom());
                this.map.resize();
                this.map.reposition();
                setTimeout(function(){
                    this.map.setZoom(this.getZoom());
                    var locationStr = this.getCenterPt().split(",");
                    this._centerMap(locationStr[0],locationStr[1],locationStr[2])
                }.bind(this),350) //resize and reposition need to settle before this fires!
            }.bind(this),this.DEBOUNCE_DELAY)()
        }
        else{
            this.map.resize();
            this.map.reposition();
        }
    }

    /**
     * Deprecated Mar 4, 2014
     */
    this.destroyMap = function(){
        this.map.destroy();
    }

    /**
     * Deprecated Mar 4, 2014
     * @param autoCenter
     * @private
     */
    this._createNewMap = function(/* boolean */ autoCenter){
        var locationStr = this.getCenterPt().split(",");
        if(locationStr instanceof Array){
            var slider = this.slider != null ? "small" : false;
            this.map = new esri.Map(this.mapId, {
                basemap: this.basemap,
                center: [locationStr[1],locationStr[0]], // long, lat
                zoom: this.getZoom(),
                sliderStyle: slider
            });

            this.map.on("load",function(){
                this.map.resize();
                this.map.reposition();
                this._centerMap(locationStr[0],locationStr[1],locationStr[2])
                $.event.trigger({
                    type: "helper-map-loaded",
                    message: "jQueryHelper map loaded",
                    time: new Date()
                })
            }.bind(this));
        }
    }

    this._centerMap = function(/* number */ x, /* number */ y, /* int */ wkid){
        if(!isNaN(x) && !isNaN(y) && !isNaN(wkid)){
            var wgsPt = null;
            if(wkid == 4326){
                wgsPt = new esri.geometry.Point(y,x);
            }
            else if(wkid = 102100){
                wgsPt = new esri.geometry.Point(x,y, new esri.SpatialReference({ wkid: wkid }));
            }

            this.map.centerAt(wgsPt);
            console.log("map centered");
        }
        else{
            console.log("Null value detected. Is setCenterPt() set?");
        }
    }

    this._getActivePage = function(){
        return $.mobile.activePage[0].id;
    }

    this._init = function(){
        this.currentPageID = this._getActivePage();

        this.setOrientationListener();
        this.setPageChangeListeners(this.currentPageID);

//        Set these listeners from within your application!
//        this.setPanListener();
//        this.setZoomListener();

        this.setWidth((this.map).width);
        this.setHeight((this.map).height);

        var center = this.map.extent.getCenter();
        this.setCenterPt(center.x,center.y,this.map.spatialReference.wkid);
        this.setZoom(this.map.getZoom());

    }.bind(this)()
}<commit_msg>removed _debounceMapReinflate()<commit_after>/**
 * Helper library for building mobile ArcGIS mapping applications with jQuery mobile.
 * Specifically designed for use in multiple view applications.
 * Requires: jQuery Mobile 1.3+ and ArcGIS API for JavaScript v3.5+
 * @author Andy Gup
 * @param map esri.Map
 */
var jQueryHelper = function(/* Map */ map){
    this.map = map;
    this.mapId = map.id;
    this.mapDiv = document.getElementById(map.id);
    this.basemap = map._basemap;
    this.currentPageID = null;
    this.slider = this.map._slider;

    /**
     * By default the library will automatically recenter the map
     * after an orientation event in a child view.
     * Override this if you wish to handle your own recentering
     * when the view is returned to home.
     * If you override, then listen for the jquery "helper-map-loaded" event.
     * @type {boolean}
     */
    this.autoCenter = true;

    /**
     * Map debounce delay in milliseconds
     * @type {number}
     */
    this.DEBOUNCE_DELAY = 250;

    /**
     * Constant variables
     * @type {Object}
     */
    this.localEnum = (function(){
        var values = {
            PORTRAIT:"portrait",
            LANDSCAPE:"landscape",
            DELAY: 400  //Delay in ms to wait for view to settle.
                        //You might have to experiment with this to get max performance.
        }

        return values;
    });

    this.setZoom = function(/* int */ zoom){
        localStorage.setItem("_zoomLevel",zoom);
    }

    this.getZoom = function(){
        var value = null;

        try{
            value = localStorage.getItem("_zoomLevel");
        }
        catch(err)
        {
            console.log("getZoom: " + err.message);
        }

        return value;
    }

    this.setWidth = function(/* int */ value){
        localStorage.setItem("_width",value);
    }

    this.getWidth = function(){
        var value = null;

        try{
            value = localStorage.getItem("_width");
        }
        catch(err)
        {
            console.log("getZoom: " + err.message);
        }

        return value;
    }

    this.setHeight = function(/* int */ value){
        localStorage.setItem("_height",value);
    }

    this.getHeight = function(){
        var value = null;

        try{
            value = localStorage.getItem("_height");
        }
        catch(err)
        {
            console.log("getZoom: " + err.message);
        }

        return value;
    }

    /**
     * Determines if phone is in PORTRAIT or LANDSCAPE mode
     * See localEnum() for constant values
     * @returns {string}
     */
    this.getOrientation = function(){

        if(typeof window.orientation != "undefined"){
            if(window.orientation == 0 || window.orientation == 180) return this.localEnum().PORTRAIT;
            if(window.orientation == 90 || window.orientation == 270) return this.localEnum().LANDSCAPE;
        }
        else{
            return  window.innerHeight > window.innerWidth ?
                this.localEnum().PORTRAIT :
                this.localEnum().LANDSCAPE;
        }
    }

    /**
     * Uses localStorage to save a location.
     * @param lat
     * @param lon
     * @param spatialReference
     */
    this.setCenterPt = function(lat,lon,spatialReference){
        localStorage.setItem("_centerPtX", lat);
        localStorage.setItem("_centerPtY", lon);
        localStorage.setItem("_spatialReference", spatialReference);
    }

    /**
     * Pulls a saved location from localStorage
     * Requires that setCenterPt() has been set.
     * @returns String x,y,spatialReference
     */
    this.getCenterPt = function(){
        var value = null;

        try{
            value = localStorage.getItem("_centerPtX") + "," + localStorage.getItem("_centerPtY") + "," +
                localStorage.getItem("_spatialReference");
        }
        catch(err)
        {
            console.log("getCenterFromLocalStorage: " + err.message);
        }

        return value;
    }

    /**
     * Activates the orientation listener and listens for native events.
     * Handle orientation events to allow for resizing the map and working around
     * jQuery mobile bugs related to how and when the view settles after such an event
     */
    this.setOrientationListener = function(){
        var supportsOrientationChange = "onorientationchange" in window,
            orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";

        window.addEventListener(orientationEvent, this.debounceMap(function(){
            if(this._getActivePage() == this.currentPageID){
                this.recenterOnRotate(400);
            }
        },this.DEBOUNCE_DELAY).bind(this), false);
    }

    /**
     * Minimize the number of times window readjustment fires a function
     * http://davidwalsh.name/javascript-debounce-function
     * @param func
     * @param wait
     * @param immediate
     * @returns {Function}
     */
    this.debounceMap = function (func, wait, immediate) {
        var timeout;
        return function() {
            var context = this, args = arguments;
            clearTimeout(timeout);
            timeout = setTimeout(function() {
                timeout = null;
                if (!immediate) func.apply(context, args);
            }, wait);
            if (immediate && !timeout) func.apply(context, args);
        };
    };

    /**
     * Automatically sets new center point in local storage.
     */
    this.setPanListener = function(){
        this.map.on("pan-end",function(){
            var center = this.map.extent.getCenter();
            this.setCenterPt(center.x,center.y,this.map.spatialReference);
        }.bind(this))
    }

    /**
     * Automatically sets new center point and zoom level in
     * local storage.
     */
    this.setZoomListener = function(){
        this.map.on("zoom-end",function(){
            var center = this.map.extent.getCenter();
            this.setCenterPt(center.x,center.y,this.map.spatialReference);
            this.setZoom(this.map.getZoom());
        }.bind(this))
    }

    /**
     * Sets internal page listeners
     * @param pageId
     */
    this.setPageChangeListeners = function(pageId){
        $('#' + pageId).on("pageshow",function(){
            console.log("home pageshow event");
            var currentOrientation = this.getOrientation();
            this._reinflatMap(currentOrientation);
        }.bind(this))
    }

    this.recenterOnRotate = function(/* int */ timerDelay){

        if(this.map.height == 0 || this.map.width == 0){
            var currentOrientation = this.getOrientation();
            this._reinflatMap(currentOrientation);
        }
        else{
            var timeout = null;
            timerDelay != "undefined" ? timeout = timerDelay : timeout = 500;
            setTimeout((function(){
                console.log("rotate timer complete");

                var locationStr = this.getCenterPt().split(",");
                this._centerMap(locationStr[0],locationStr[1],locationStr[2])

            }).bind(this),timeout);
        }
    }

    this._getMapDivVisibility = function(){
        var id = this.map.id;
        return $("#" + id).is(":visible");
    }

    this.resetMap = function(height,width,zoom){
        if(this.getOrientation() == this.localEnum().PORTRAIT){
            //adjust map height/width
            this.map.height = height;
            this.map.width = width;

            //adjust map div height/width
            this.mapDiv.style.height = height;
            this.mapDiv.style.width = width;

        }
        else{
            //adjust map height/width
            this.map.width = height;
            this.map.height = width;

            //adjust map div height/width
            this.mapDiv.style.width = height;
            this.mapDiv.style.height = width;
        }
    }

    /**
     * Reinflate map based on specific conditions
     * @param currentOrientation
     * @private
     */
    this._reinflatMap = function(currentOrientation){
        if(this.map.height == 0 || this.map.width ==0){
            this.debounceMap(function(){
                this.resetMap(this.getHeight(),this.getWidth(),this.getZoom());
                this.map.resize();
                this.map.reposition();
                setTimeout(function(){
                    this.map.setZoom(this.getZoom());
                    var locationStr = this.getCenterPt().split(",");
                    this._centerMap(locationStr[0],locationStr[1],locationStr[2])
                }.bind(this),350) //resize and reposition need to settle before this fires!
            }.bind(this),this.DEBOUNCE_DELAY)()
        }
        else{
            this.map.resize();
            this.map.reposition();
        }
    }

    /**
     * Deprecated Mar 4, 2014
     */
    this.destroyMap = function(){
        this.map.destroy();
    }

    /**
     * Deprecated Mar 4, 2014
     * @param autoCenter
     * @private
     */
    this._createNewMap = function(/* boolean */ autoCenter){
        var locationStr = this.getCenterPt().split(",");
        if(locationStr instanceof Array){
            var slider = this.slider != null ? "small" : false;
            this.map = new esri.Map(this.mapId, {
                basemap: this.basemap,
                center: [locationStr[1],locationStr[0]], // long, lat
                zoom: this.getZoom(),
                sliderStyle: slider
            });

            this.map.on("load",function(){
                this.map.resize();
                this.map.reposition();
                this._centerMap(locationStr[0],locationStr[1],locationStr[2])
                $.event.trigger({
                    type: "helper-map-loaded",
                    message: "jQueryHelper map loaded",
                    time: new Date()
                })
            }.bind(this));
        }
    }

    this._centerMap = function(/* number */ x, /* number */ y, /* int */ wkid){
        if(!isNaN(x) && !isNaN(y) && !isNaN(wkid)){
            var wgsPt = null;
            if(wkid == 4326){
                wgsPt = new esri.geometry.Point(y,x);
            }
            else if(wkid = 102100){
                wgsPt = new esri.geometry.Point(x,y, new esri.SpatialReference({ wkid: wkid }));
            }

            this.map.centerAt(wgsPt);
            console.log("map centered");
        }
        else{
            console.log("Null value detected. Is setCenterPt() set?");
        }
    }

    this._getActivePage = function(){
        return $.mobile.activePage[0].id;
    }

    this._init = function(){
        this.currentPageID = this._getActivePage();

        this.setOrientationListener();
        this.setPageChangeListeners(this.currentPageID);

//        Set these listeners from within your application!
//        this.setPanListener();
//        this.setZoomListener();

        this.setWidth((this.map).width);
        this.setHeight((this.map).height);

        var center = this.map.extent.getCenter();
        this.setCenterPt(center.x,center.y,this.map.spatialReference.wkid);
        this.setZoom(this.map.getZoom());

    }.bind(this)()
}<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var configure = require('gulp-ccr');

var recipes = configure({
	src: 'app',
	dest: 'dist',
	clean: {
	},
	make: {
		scripts: {
			browserify: {
				options: {
					development: {
						sourcemap: 'internal'
					},
					production: {
						sourcemap: 'external'
					}
				},
				bundle: {
					entry: 'main.js'
				}
			}
		},
		markups: {
			src: '**/*.html'
		},
		resources: {
			src: '**/*.{png,jpeg,gif,webp}'
		}
	},
	watch: ['scripts', 'markups', 'resources'],
	build: ['clean', 'make'],
	default: 'build'
});

gulp.registry(recipes);
<commit_msg>examples/browserify-demo: update gulpfile.js<commit_after>'use strict';

var gulp = require('gulp');
var configure = require('gulp-ccr');

var recipes = configure({
	src: 'app',
	dest: 'dist',
	clean: {
	},
	make: {
		scripts: {
			browserify: {
				options: {
					development: {
						sourcemap: 'internal'
					},
					production: {
						sourcemap: 'external'
					}
				},
				bundle: {
					entry: 'main.js',
					file: 'bundle.js'
				}
			}
		},
		markups: {
			src: '**/*.html'
		},
		resources: {
			src: '**/*.{png,jpeg,gif,webp}'
		}
	},
	watch: ['scripts', 'markups', 'resources'],
	build: ['clean', 'make'],
	default: 'build'
});

gulp.registry(recipes);
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;
var pg = require('pg');
var Q = require("q");
var request = require("request");
var newUser = require("./db");
var logConversation = require("./conversation");
var nlp = require("./nlp");
var pushConv = require("./push");

const scriptRules = require('./script.json');

var msgLog = {
    smoochId: '',
    received: '',
    usermessage: '',
    role: '',
    message_id: '',
    sourcetype: '',
    receivedtime: '',
    responsemessage: '',
    responsetype: '',
    responsetime: ''
  };

function wait(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

module.exports = new Script({
    processing: {
        //prompt: (bot) => bot.say('Beep boop...'),
        receive: () => 'processing'
    },

    start: {
        receive: (bot) => {
            return bot.say('Hello!  I\'m A16, the Agile2016 EventBot Concierge.  To find out what I can help you with type MENU for options or KEY for Keywords.')
                .then(() => 'speak');
        }
    },

    speakers: {
      prompt: (bot) => bot.say('What speaker are you searching for?'),
      receive: (bot, message) => {
        const name = message.text;
        return bot.setProp('name', name)
          .then(() => bot.say("I will search for ${name} is that OK? %[Yes](postback:hello) %[No](postback:hello)"))
          .then(() => 'finish');
      }
    },

    finish {
      receive: (bot, message) => {
        return bot.getProp('name')
          .then((name) => bot.say('That is all!'))
          .then(() => 'finish');
      }
    },

    speak: {
        receive: (bot, message) => {
            console.log("===bot user ");
            console.log("===receive step 1",message);
            let upperText = message.text.trim().toUpperCase();

            if (message.text = 'speakers') {
              .then(() => 'speakers');
            }

            msgLog.smoochId = bot.userId;
            msgLog.received = message.received;
            msgLog.usermessage = message.text;
            msgLog.role = message.role;
            msgLog.message_id = message.message_id;
            msgLog.sourcetype = message.source.type;
            msgLog.receivedtime = new Date();

            var botUser = bot.userId;
            var authUsers = ['a30fa820d0a0f0216fa26070'];

            //Undone - currently only creates new user
            //needs to create conversation record and update it throughout the prcoess
            //console.log("===before db");
            newUser(bot)
            //  .then (console.log("===after db", bot.userId))

              //undone - test for userid and or message
              //look at stacking messages in DB and looking them up
              //end conversation and do not send a response to the user that kicked things off
              //
              if (authUsers.indexOf(bot.userId) !== -1) {
                if (message.text.substr(0,5) == '/msg ') {
                  upperText = upperText.substr(0,4);
                  pushConv(bot, message.text.substr(5));
                  console.log("****after push msg:  ",message.text);
                }
              }

            function updateSilent() {
                switch (upperText) {
                    case "CONNECT ME":
                        return bot.setProp("silent", true);
                    case "/SUPPORT":
                        return bot.setProp("silent", true);
                    case "DISCONNECT":
                        return bot.setProp("silent", false);
                    case "/A16":
                        console.log("*** ",upperText," ***");
                        processMessage(false);
                        return bot.setProp("silent", false);
                    default:
                        return Promise.resolve();
                }
            }

            console.log("===receive step 2",upperText);

            function getSilent() {
                return bot.getProp("silent");
            }

            function processMessage(isSilent) {
                if (isSilent) {
                    return Promise.resolve("speak");
                }

                var promises = [];
                var source;
                var fulfillmentSpeech;
                var simplified;
                promises.push(nlp(upperText, bot.userId));

                Q.all(promises).then(function(responses) {
                    // response is the JSON from API.ai
                    responses.forEach(function(response) {
                        //console.log("===in Q.all");
                        console.log("===received result from API.ai",response);
                        source = response.result.source;
                        if (source && source !== 'agent')
                        {
                            fulfillmentSpeech = response.result.fulfillment.speech;
                            simplified = response.result.parameters.simplified;
                        }
                        console.log("source: ", source);
                        console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                        console.log("simplified: ", simplified);

                        respondMessage(source, fulfillmentSpeech, simplified);
                    });
                }, function(error) {
                    console.log("===Q all error ", error);
                });
                //return next();

            }

            function respondMessage(source, fulfillmentSpeech, simplified)
            {
                console.log("source: ", source);
                console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                console.log("simplified: ", simplified);
                console.log("===receive step 3",upperText);

              if (source != 'agent')
                {
                    console.log("===source is ", source);
                    if (fulfillmentSpeech)
                    {
                      switch (simplified) {
                        case "hello":
                          console.log("===in hello");
                          upperText = simplified.trim().toUpperCase();
                          break;
                        case "what do you know":
                          console.log("===in what do you know");
                          upperText = simplified.trim().toUpperCase();
                          break;
                        case "can you talk":
                          console.log("===can you talk");
                          upperText = simplified.trim().toUpperCase();
                          break;
                        default:
                          console.log("===in switch default");
                          msgLog.responsemessage = fulfillmentSpeech;
                          msgLog.responsetime = new Date;
                          msgLog.responsetype = 'API.AI';
                          return bot.say(fulfillmentSpeech).then(() => 'speak');
                      }
                    }
                    else if (simplified)
                    {
                        console.log("simplified is: ", simplified);
                        upperText = simplified.toUpperCase();
                    }
                }
                if (!_.has(scriptRules, upperText)) {
                    console.log("===no rule", upperText);
                    return bot.say(`I'm sorry that is not something I know.  Type MENU or KEY for a list of things I can help you with.`).then(() => 'speak');
                }

                console.log("===receive step 3",upperText);

                var response = scriptRules[upperText];
                var lines = response.split('\n');

                bot.userId = botUser;

                var p = Promise.resolve();
                _.each(lines, function(line) {
                    line = line.trim();
                    p = p.then(function() {
                        console.log("=== p line",line);
                        return wait(5).then(function() {
                            msgLog.responsemessage = line;
                            //var senttime = new new Date( new Date().getTime() -6 * 3600 * 1000).toUTCString().replace( / GMT$/, "" );
                            msgLog.responsetime = new Date;
                            msgLog.responsetype = 'JSON';
                            console.log("=== msgLog  obj",msgLog);
                            logConversation(msgLog);
                            return bot.say(line);
                        });
                    });
                });
                return p.then(() => 'speak');
            }

            return updateSilent()
                .then(getSilent)
                .then(processMessage);
        }
    }
});
<commit_msg>missing :<commit_after>'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;
var pg = require('pg');
var Q = require("q");
var request = require("request");
var newUser = require("./db");
var logConversation = require("./conversation");
var nlp = require("./nlp");
var pushConv = require("./push");

const scriptRules = require('./script.json');

var msgLog = {
    smoochId: '',
    received: '',
    usermessage: '',
    role: '',
    message_id: '',
    sourcetype: '',
    receivedtime: '',
    responsemessage: '',
    responsetype: '',
    responsetime: ''
  };

function wait(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

module.exports = new Script({
    processing: {
        //prompt: (bot) => bot.say('Beep boop...'),
        receive: () => 'processing'
    },

    start: {
        receive: (bot) => {
            return bot.say('Hello!  I\'m A16, the Agile2016 EventBot Concierge.  To find out what I can help you with type MENU for options or KEY for Keywords.')
                .then(() => 'speak');
        }
    },

    speakers: {
      prompt: (bot) => bot.say('What speaker are you searching for?'),
      receive: (bot, message) => {
        const name = message.text;
        return bot.setProp('name', name)
          .then(() => bot.say("I will search for ${name} is that OK? %[Yes](postback:hello) %[No](postback:hello)"))
          .then(() => 'finish');
      }
    },

    finish: {
      receive: (bot, message) => {
        return bot.getProp('name')
          .then((name) => bot.say('That is all!'))
          .then(() => 'finish');
      }
    },

    speak: {
        receive: (bot, message) => {
            console.log("===bot user ");
            console.log("===receive step 1",message);
            let upperText = message.text.trim().toUpperCase();

            if (message.text = 'speakers') {
              .then(() => 'speakers');
            }

            msgLog.smoochId = bot.userId;
            msgLog.received = message.received;
            msgLog.usermessage = message.text;
            msgLog.role = message.role;
            msgLog.message_id = message.message_id;
            msgLog.sourcetype = message.source.type;
            msgLog.receivedtime = new Date();

            var botUser = bot.userId;
            var authUsers = ['a30fa820d0a0f0216fa26070'];

            //Undone - currently only creates new user
            //needs to create conversation record and update it throughout the prcoess
            //console.log("===before db");
            newUser(bot)
            //  .then (console.log("===after db", bot.userId))

              //undone - test for userid and or message
              //look at stacking messages in DB and looking them up
              //end conversation and do not send a response to the user that kicked things off
              //
              if (authUsers.indexOf(bot.userId) !== -1) {
                if (message.text.substr(0,5) == '/msg ') {
                  upperText = upperText.substr(0,4);
                  pushConv(bot, message.text.substr(5));
                  console.log("****after push msg:  ",message.text);
                }
              }

            function updateSilent() {
                switch (upperText) {
                    case "CONNECT ME":
                        return bot.setProp("silent", true);
                    case "/SUPPORT":
                        return bot.setProp("silent", true);
                    case "DISCONNECT":
                        return bot.setProp("silent", false);
                    case "/A16":
                        console.log("*** ",upperText," ***");
                        processMessage(false);
                        return bot.setProp("silent", false);
                    default:
                        return Promise.resolve();
                }
            }

            console.log("===receive step 2",upperText);

            function getSilent() {
                return bot.getProp("silent");
            }

            function processMessage(isSilent) {
                if (isSilent) {
                    return Promise.resolve("speak");
                }

                var promises = [];
                var source;
                var fulfillmentSpeech;
                var simplified;
                promises.push(nlp(upperText, bot.userId));

                Q.all(promises).then(function(responses) {
                    // response is the JSON from API.ai
                    responses.forEach(function(response) {
                        //console.log("===in Q.all");
                        console.log("===received result from API.ai",response);
                        source = response.result.source;
                        if (source && source !== 'agent')
                        {
                            fulfillmentSpeech = response.result.fulfillment.speech;
                            simplified = response.result.parameters.simplified;
                        }
                        console.log("source: ", source);
                        console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                        console.log("simplified: ", simplified);

                        respondMessage(source, fulfillmentSpeech, simplified);
                    });
                }, function(error) {
                    console.log("===Q all error ", error);
                });
                //return next();

            }

            function respondMessage(source, fulfillmentSpeech, simplified)
            {
                console.log("source: ", source);
                console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                console.log("simplified: ", simplified);
                console.log("===receive step 3",upperText);

              if (source != 'agent')
                {
                    console.log("===source is ", source);
                    if (fulfillmentSpeech)
                    {
                      switch (simplified) {
                        case "hello":
                          console.log("===in hello");
                          upperText = simplified.trim().toUpperCase();
                          break;
                        case "what do you know":
                          console.log("===in what do you know");
                          upperText = simplified.trim().toUpperCase();
                          break;
                        case "can you talk":
                          console.log("===can you talk");
                          upperText = simplified.trim().toUpperCase();
                          break;
                        default:
                          console.log("===in switch default");
                          msgLog.responsemessage = fulfillmentSpeech;
                          msgLog.responsetime = new Date;
                          msgLog.responsetype = 'API.AI';
                          return bot.say(fulfillmentSpeech).then(() => 'speak');
                      }
                    }
                    else if (simplified)
                    {
                        console.log("simplified is: ", simplified);
                        upperText = simplified.toUpperCase();
                    }
                }
                if (!_.has(scriptRules, upperText)) {
                    console.log("===no rule", upperText);
                    return bot.say(`I'm sorry that is not something I know.  Type MENU or KEY for a list of things I can help you with.`).then(() => 'speak');
                }

                console.log("===receive step 3",upperText);

                var response = scriptRules[upperText];
                var lines = response.split('\n');

                bot.userId = botUser;

                var p = Promise.resolve();
                _.each(lines, function(line) {
                    line = line.trim();
                    p = p.then(function() {
                        console.log("=== p line",line);
                        return wait(5).then(function() {
                            msgLog.responsemessage = line;
                            //var senttime = new new Date( new Date().getTime() -6 * 3600 * 1000).toUTCString().replace( / GMT$/, "" );
                            msgLog.responsetime = new Date;
                            msgLog.responsetype = 'JSON';
                            console.log("=== msgLog  obj",msgLog);
                            logConversation(msgLog);
                            return bot.say(line);
                        });
                    });
                });
                return p.then(() => 'speak');
            }

            return updateSilent()
                .then(getSilent)
                .then(processMessage);
        }
    }
});
<|endoftext|>


<commit_before>function fun1() {
	var rtl=document.getElementBYId('rtl').value;
	var rtr=document.getElementBYId('rtr').value;
	var rbl=document.getElementBYId('rbl').value;
	var ttl=document.getElementBYId('ttl').value;
	var ttr=document.getElementBYId('ttr').value;
	var tbr=document.getElementBYId('tbr').value;
	var tbl=document.getElementBYId('tbl').value;
	var rbr=document.getElementBYId('rbr').value;
}<commit_msg>получаем блок по идентификатору<commit_after>function fun1() {
	var rtl=document.getElementBYId('rtl').value;
	var rtr=document.getElementBYId('rtr').value;
	var rbl=document.getElementBYId('rbl').value;
	var ttl=document.getElementBYId('ttl').value;
	var ttr=document.getElementBYId('ttr').value;
	var tbr=document.getElementBYId('tbr').value;
	var tbl=document.getElementBYId('tbl').value;
	var rbr=document.getElementBYId('rbr').value;

	var block=document.getElementById('block') ;
}<|endoftext|>


<commit_before>$(document).ready(function() {
var sections = $('section')
  , nav = $('nav')
  , nav_height = 50;
 //nav.outerHeight()

$(window).on('scroll', function () {
  var cur_pos = $(this).scrollTop();

 console.log(cur_pos);

  sections.each(function() {

    var top = $(this).offset().top - nav_height,
        bottom = top + $(this).outerHeight();
    if (cur_pos >= top && cur_pos <= bottom) {
      nav.find('a').parent().removeClass('active');
      sections.removeClass('active');
      $(this).addClass('active');
      nav.find('a[href="#'+$(this).attr('id')+'"]').parent().addClass('active');

	  scrollToID($(this).attr('id'), 500);

    }
  });
});

	nav.find('a').on("click", function(){
		event.preventDefault();
		id = $(this).attr("href");
		scrollToID(id, 800);
	});

});

function scrollToID(id, speed){
	var targetOffset = $(id).offset().top;
	$('html,body').animate({scrollTop:targetOffset}, speed);
}<commit_msg>startactive<commit_after>$(document).ready(function() {
var sections = $('section')
  , nav = $('nav')
  , nav_height = 500;
 //nav.outerHeight()

$(window).on('scroll', function () {
  var cur_pos = $(this).scrollTop();

 console.log(cur_pos);

  sections.each(function() {

    var top = $(this).offset().top - nav_height,
        bottom = top + $(this).outerHeight();
    if (cur_pos >= top && cur_pos <= bottom) {
      nav.find('a').parent().removeClass('active');
      sections.removeClass('active');
      $(this).addClass('active');
      nav.find('a[href="#'+$(this).attr('id')+'"]').parent().addClass('active');

	  scrollToID($(this).attr('id'), 500);

    }
  });
});

	nav.find('a').on("click", function(){
		event.preventDefault();
		id = $(this).attr("href");
		scrollToID(id, 800);
	});

});

function scrollToID(id, speed){
	var targetOffset = $(id).offset().top;
	$('html,body').animate({scrollTop:targetOffset}, speed);
}<|endoftext|>