<commit_before>if( typeof XMLHttpRequest == "undefined" ) XMLHttpRequest = function() {
  try { return new ActiveXObject("Msxml2.XMLHTTP.6.0") } catch(e) {}
  try { return new ActiveXObject("Msxml2.XMLHTTP.3.0") } catch(e) {}
  try { return new ActiveXObject("Msxml2.XMLHTTP") } catch(e) {}
  try { return new ActiveXObject("Microsoft.XMLHTTP") } catch(e) {}
  throw new Error( "This browser does not support XMLHttpRequest." )
};
/**
 * @namespace Meteor js connection namespace.
 */
meteor = new Object();
/**
 * Limit for the incoming buffer. When the incoming XMLHttpRequest object buffer grows larger than this, the connection is reinitiated.
 */
meteor.BUFFER_MAX = 1 << 16; // limit for incoming buffer, exceeding this buffer triggers a reconnect
/**
 * Meteor connection class. This is usually used with Atom serialization on top. Use psyc.Client if unsure.
 * @param {String} url URL of the Meteor connection endpoint.
 * @param {Function} callback Function to be called when data has been received.
 * @param {Function} error Function to be called when a fatal error occures.
 * @constructor
 * @example
 * var connection;
 * var incoming = function(data) {
 * 	document.write("Received data: " + data);
 * 	connection.send("Hello World.\n");
 * }
 * connection = new meteor.Connection("http://example.org/meteor/", incoming, alert);
 * connection.init();
 */
meteor.Connection = function(url, callback, error) {
    this.url = url;
    this.buffer = "";
    this.callback = callback;
    this.error = error;
	this.client_id = 0;
	this.new_incoming = 0;
	this.incoming = 0;
	this.outgoing = 0;
	this.init_xhr = 0;
};
meteor.Connection.prototype = {
	new_incoming_state_change : function() {
		var con = this.meteor;
		con.error("new_incoming state is " + this.readyState);
		// we should check here for buffer length. maybe set a max
		// amount to shut down the main one ungracefully
		if (this.readyState >= 3) {
			con.connect_incoming();
		}
	},
	connect_new_incoming : function() {
		if (this.new_incoming) {
			// we already have one new incoming and are waiting for the
			// main one to shut down

			if (this.new_incoming.readyState == 4) {
			// someone is too fast for us.
			// TODO: we have to check for data in new_incoming,
			// not sure what to do with it. we can probably savely
			// parse it in case of atoms.
			} else return this.connect_incoming();
		}

		var xhr = new XMLHttpRequest();
		this.new_incoming = xhr;
		xhr.pos = 0;

		xhr.open("POST", this.url + "?" + this.client_id, true);
		//xhr.overrideMimeType("text/plain; charset=ISO-8859-1");
		xhr.overrideMimeType('text/plain; charset=x-user-defined');
		xhr.onreadystatechange = this.new_incoming_state_change;
		xhr.meteor = this;
		xhr.send("");
	},
	incoming_state_change : function() {
		var con = this.meteor;
		if (this.readyState >= 3) {
			//this.readyState = 2;

			// TODO: this line errors on IE
			if (this.status == 200) {
				var length = this.responseBody ? this.responseBody.length : this.responseText.length;
				var response = this.responseBody ? this.reponseBody : this.responseText;

				if (length <= this.pos) return;
				var str;

				if (this.pos) {
					str = (response.slice(this.pos));
				} else {
					str = response;
				}

				// ifdef firefox or safari
				if (navigator.userAgent.indexOf("Firefox") != -1 || navigator.userAgent.indexOf("Safari") != -1) {
					var t = new Array;
					for (var i = 0; i < str.length; i++) {
						t.push(str.charCodeAt(i) & 0xff);
					}
					str = String.fromCharCode.apply(window, t);
				}
				// endif

				if (con.callback.obj) {
					con.callback.call(con.callback.obj, str);
				} else {
					con.callback(str);
				}

				this.pos = length;

				if (this.readyState == 4 || this.pos >= meteor.BUFFER_MAX) {
					con.connect_new_incoming();
				}
			} else {
			// this throws an exception in firefox. brain
			//	con.error(this.statusText);
				if (meteor.debug) meteor.debug("http status code: "+this.status);
			}
		}
	},
	incoming_on_error : function() {
		this.meteor.connect_new_incoming();
	},
	connect_incoming : function(xhr) {
		if (!xhr) {
			if (this.new_incoming) {
				xhr = this.new_incoming;
			} else throw("you need to call new_incoming() first. no this.new_incoming.");
		}

		if (this.incoming) {
			if (this.incoming.readyState != 4) {
				return;
			}

			try { this.incoming.abort(); } catch (e) {}
		}

		if (this.operatimer) {
			clearTimeout(this.operatimer);
			this.operatimer = null;
		}

		xhr.onreadystatechange = this.incoming_state_change;
		xhr.onerror = this.incoming_on_error;
		this.error("moved new incoming to incoming.\n");
		this.new_incoming = 0;
		this.incoming = xhr;
		meteor.Connection.prototype.incoming_state_change.call(xhr);

		// This code polls the xhr for new data in case opera is used. its necessary
		// because opera does not trigger an event if new data is available in state 3.
		if (window.opera) {
			var fun = function() {
				meteor.Connection.prototype.incoming_state_change.call(xhr);
			};
			this.operatimer = setInterval(fun, 100);
			if (meteor.debug) meteor.debug("timer: "+this.operatimer);
		}
	},
	outgoing_state_change : function() {
		var con = this.meteor;

		if (this.readyState == 4) {

			if (this.status == 200) {

				con.connect_outgoing();
			} else {
				con.error(this.statusText);
			}
		}
	},
	connect_outgoing : function() {
		var xhr;

		if (this.outgoing) {
			this.outgoing.abort();
			xhr = this.outgoing;
		} else {
			xhr = new XMLHttpRequest();
			this.outgoing = xhr;
		}
		//this.error("outgoing state is " + xhr.readyState);

		xhr.open("POST", this.url + "?" + this.client_id, true);
		// we do this charset hackery because we have internal utf8 and plain ascii
		// for the rest of atom. this is supposed to be a binary transport
		xhr.setRequestHeader("Content-Type", "application/binary");
		xhr.onreadystatechange = this.outgoing_state_change;
		xhr.meteor = this;
		this.ready = 1;
	},
	init_state_change : function(change_event) { // fetch the client_id and go
		var con = this.meteor;
		if (this.readyState == 4) {
			if (this.status == 200) {
				con.client_id = this.responseText;
				if (meteor.debug) meteor.debug("got client ID " + con.client_id);
				con.init_xhr = null;
				con.connect_outgoing();
				con.connect_new_incoming();
			} else {
				con.error(this.statusText);
			}
			this.meteor = null;
			//console.debug("not yet in readyState 4\n");
		}
	},
	/**
	 * Initialize the connection. This needs to be called before any data can be sent or received.
	 */
	init : function() { // fetch the client_id and go
		var xhr = new XMLHttpRequest();
		xhr.meteor = this;
		this.init_xhr = xhr;
		//this.error("initialization state is " + xhr.readyState);

		xhr.onreadystatechange = this.init_state_change;
		xhr.meteor = this;
		xhr.open("GET", this.url, true);
		xhr.send("");
	},
	/**
	 * Close incoming connection and clean up cyclic references.
	 */
	destruct : function() {
		var list = [this.init_xhr, this.new_incoming, this.incoming, this.outgoing];
		for (var t in list) {
			t = list[t];
			try {
				if (t) {
					t.abort();
					t.meteor = null;
				}
			} catch(e) { }
		}
		this.init_xhr = null;
		this.incoming = null;
		this.new_incoming = null;
		this.outgoing = null;
		this.callback = null;
		this.error = null;
	},
	/**
	 * Send some data.
	 * @param {String} data String to be sent.
	 */
	send : function(data) {
		// check for status
		this.buffer += data;

		if (this.client_id && this.ready) {
			// ifdef firefox
			//this.outgoing.setRequestHeader("Content-Length", this.buffer.length);
			// endif
			this.outgoing.send(this.buffer);
			this.ready = 0;
			this.buffer = "";
		}
	},
};
// the params handed by the user could be prototyped with a
// msg and something more
meteor.CallbackWrapper = function(params, mapping) {
	this.mapping = mapping;
	this.params = params;
};
meteor.CallbackWrapper.prototype = {
	msg : function(message) {
		if (!this.params.source || this.params.source == message.vars.get("_source")) {
			if (this.params.object) {
				if (this.params.cb) {
					return this.params.cb.call(this.params.object, message, this);
				}

				return this.params.object.msg(message, this);
			} else {
				return this.params.cb(message, this);
			}
		}
	},
	active : function() {
		return this.mapping == 0 ? 0 : 1;
	},
	unregister : function() {
	if (this.mapping == 0) return;

		var list = this.mapping.get(this.params.method);

		for (var i = 0; i < list.length; i++) {
			if (list[i] == this) {
				list.splice(i, 1);
			}
		}

		this.mapping = 0;
	},
};
<commit_msg>fix for IE<commit_after>if( typeof XMLHttpRequest == "undefined" ) XMLHttpRequest = function() {
  try { return new ActiveXObject("Msxml2.XMLHTTP.6.0") } catch(e) {}
  try { return new ActiveXObject("Msxml2.XMLHTTP.3.0") } catch(e) {}
  try { return new ActiveXObject("Msxml2.XMLHTTP") } catch(e) {}
  try { return new ActiveXObject("Microsoft.XMLHTTP") } catch(e) {}
  throw new Error( "This browser does not support XMLHttpRequest." )
};
/**
 * @namespace Meteor js connection namespace.
 */
meteor = new Object();
/**
 * Limit for the incoming buffer. When the incoming XMLHttpRequest object buffer grows larger than this, the connection is reinitiated.
 */
meteor.BUFFER_MAX = 1 << 16; // limit for incoming buffer, exceeding this buffer triggers a reconnect
/**
 * Meteor connection class. This is usually used with Atom serialization on top. Use psyc.Client if unsure.
 * @param {String} url URL of the Meteor connection endpoint.
 * @param {Function} callback Function to be called when data has been received.
 * @param {Function} error Function to be called when a fatal error occures.
 * @constructor
 * @example
 * var connection;
 * var incoming = function(data) {
 * 	document.write("Received data: " + data);
 * 	connection.send("Hello World.\n");
 * }
 * connection = new meteor.Connection("http://example.org/meteor/", incoming, alert);
 * connection.init();
 */
meteor.Connection = function(url, callback, error) {
    this.url = url;
    this.buffer = "";
    this.callback = callback;
    this.error = error;
	this.client_id = 0;
	this.new_incoming = 0;
	this.incoming = 0;
	this.outgoing = 0;
	this.init_xhr = 0;
};
meteor.Connection.prototype = {
	new_incoming_state_change : function() {
		var con = this.meteor;
		con.error("new_incoming state is " + this.readyState);
		// we should check here for buffer length. maybe set a max
		// amount to shut down the main one ungracefully
		if (this.readyState >= 3) {
			con.connect_incoming();
		} else if (window.opera) {
			var xhr = this;
			setTimeout((function() {
				meteor.Connection.prototype.new_incoming_state_change.call(xhr);
			}), 200);
		}
	},
	connect_new_incoming : function() {
		if (this.new_incoming) {
			// we already have one new incoming and are waiting for the
			// main one to shut down

			if (this.new_incoming.readyState == 4) {
			// someone is too fast for us.
			// TODO: we have to check for data in new_incoming,
			// not sure what to do with it. we can probably savely
			// parse it in case of atoms.
			} else return this.connect_incoming();
		}

		if (meteor.debug) meteor.debug("Connecting new incoming.\n");

		var xhr = new XMLHttpRequest();
		this.new_incoming = xhr;
		xhr.pos = 0;

		xhr.open("POST", this.url + "?" + this.client_id, true);
		//xhr.overrideMimeType("text/plain; charset=ISO-8859-1");
		if (xhr.overrideMimeType) xhr.overrideMimeType('text/plain; charset=x-user-defined');
		xhr.onreadystatechange = this.new_incoming_state_change;
		xhr.meteor = this;
		xhr.send("");
	},
	incoming_state_change : function() {
		var con = this.meteor;
		var status;
		if (meteor.debug) meteor.debug("incoming in readyState "+this.readyState);
		if (this.readyState >= 3) {
			//this.readyState = 2;

			// stupid workaround for IE which was written by
			// stupid assholes
			try {
				status = this.status;
			} catch(e) {
				// this is ie country
				// this is ie
				if (meteor.debug) meteor.debug("fucking ie");
			}

			if (status == 200) {
				var length = this.responseBody ? this.responseBody.length : this.responseText.length;
				var response = this.responseBody ? this.reponseBody : this.responseText;

				if (length > this.pos) {
					var str;

					if (this.pos) {
						str = (response.slice(this.pos));
					} else {
						str = response;
					}

					// ifdef firefox or safari
					if (navigator.userAgent.indexOf("Firefox") != -1 || navigator.userAgent.indexOf("Safari") != -1) {
						var t = new Array;
						for (var i = 0; i < str.length; i++) {
							t.push(str.charCodeAt(i) & 0xff);
						}
						str = String.fromCharCode.apply(window, t);
					}
					// endif

					if (con.callback.obj) {
						con.callback.call(con.callback.obj, str);
					} else {
						con.callback(str);
					}

					this.pos = length;
				}

				if (this.readyState == 4 || this.pos >= meteor.BUFFER_MAX) {
					con.connect_new_incoming();
				}
			} else {
			// this throws an exception in firefox. brain
			//	con.error(this.statusText);
				if (meteor.debug) meteor.debug("http status code: "+this.status);
			}
		}
	},
	incoming_on_error : function() {
		this.meteor.connect_new_incoming();
	},
	connect_incoming : function(xhr) {
		if (!xhr) {
			if (this.new_incoming) {
				xhr = this.new_incoming;
			} else throw("you need to call new_incoming() first. no this.new_incoming.");
		}

		if (this.incoming) {
			if (this.incoming.readyState != 4) {
				return;
			}

			try { this.incoming.abort(); } catch (e) {}
		}

		if (this.operatimer) {
			clearTimeout(this.operatimer);
			this.operatimer = null;
		}

		xhr.onreadystatechange = this.incoming_state_change;
		xhr.onerror = this.incoming_on_error;
		this.error("moved new incoming to incoming.\n");
		this.new_incoming = 0;
		this.incoming = xhr;
		meteor.Connection.prototype.incoming_state_change.call(xhr);

		// This code polls the xhr for new data in case opera is used. its necessary
		// because opera does not trigger an event if new data is available in state 3.
		if (window.opera) {
			var fun = function() {
				meteor.Connection.prototype.incoming_state_change.call(xhr);
			};
			this.operatimer = setInterval(fun, 100);
			if (meteor.debug) meteor.debug("timer: "+this.operatimer);
		}
	},
	outgoing_state_change : function() {
		var con = this.meteor;

		if (this.readyState == 4) {

			if (this.status == 200) {

				con.connect_outgoing();
			} else {
				con.error(this.statusText);
			}
		}
	},
	connect_outgoing : function() {
		var xhr;

		if (this.outgoing) {
			this.outgoing.abort();
			xhr = this.outgoing;
		} else {
			xhr = new XMLHttpRequest();
			this.outgoing = xhr;
		}
		//this.error("outgoing state is " + xhr.readyState);

		xhr.open("POST", this.url + "?" + this.client_id, true);
		// we do this charset hackery because we have internal utf8 and plain ascii
		// for the rest of atom. this is supposed to be a binary transport
		xhr.setRequestHeader("Content-Type", "application/binary");
		xhr.onreadystatechange = this.outgoing_state_change;
		xhr.meteor = this;
		this.ready = 1;
	},
	init_state_change : function(change_event) { // fetch the client_id and go
		var con = this.meteor;
		if (this.readyState == 4) {
			if (this.status == 200) {
				con.client_id = this.responseText;
				if (meteor.debug) meteor.debug("got client ID " + con.client_id);
				con.init_xhr = null;
				con.connect_outgoing();
				con.connect_new_incoming();
			} else {
				con.error(this.statusText);
			}
			this.meteor = null;
			//console.debug("not yet in readyState 4\n");
		}
	},
	/**
	 * Initialize the connection. This needs to be called before any data can be sent or received.
	 */
	init : function() { // fetch the client_id and go
		var xhr = new XMLHttpRequest();
		xhr.meteor = this;
		this.init_xhr = xhr;
		//this.error("initialization state is " + xhr.readyState);

		xhr.onreadystatechange = this.init_state_change;
		xhr.meteor = this;
		xhr.open("GET", this.url, true);
		xhr.send("");
	},
	/**
	 * Close incoming connection and clean up cyclic references.
	 */
	destruct : function() {
		var list = [this.init_xhr, this.new_incoming, this.incoming, this.outgoing];
		for (var t in list) {
			t = list[t];
			try {
				if (t) {
					t.abort();
					t.meteor = null;
				}
			} catch(e) { }
		}
		this.init_xhr = null;
		this.incoming = null;
		this.new_incoming = null;
		this.outgoing = null;
		this.callback = null;
		this.error = null;
	},
	/**
	 * Send some data.
	 * @param {String} data String to be sent.
	 */
	send : function(data) {
		// check for status
		this.buffer += data;

		if (this.client_id && this.ready) {
			// ifdef firefox
			//this.outgoing.setRequestHeader("Content-Length", this.buffer.length);
			// endif
			this.outgoing.send(this.buffer);
			this.ready = 0;
			this.buffer = "";
		}
	},
};
// the params handed by the user could be prototyped with a
// msg and something more
meteor.CallbackWrapper = function(params, mapping) {
	this.mapping = mapping;
	this.params = params;
};
meteor.CallbackWrapper.prototype = {
	msg : function(message) {
		if (!this.params.source || this.params.source == message.vars.get("_source")) {
			if (this.params.object) {
				if (this.params.cb) {
					return this.params.cb.call(this.params.object, message, this);
				}

				return this.params.object.msg(message, this);
			} else {
				return this.params.cb(message, this);
			}
		}
	},
	active : function() {
		return this.mapping == 0 ? 0 : 1;
	},
	unregister : function() {
	if (this.mapping == 0) return;

		var list = this.mapping.get(this.params.method);

		for (var i = 0; i < list.length; i++) {
			if (list[i] == this) {
				list.splice(i, 1);
			}
		}

		this.mapping = 0;
	},
};
<|endoftext|>


<commit_before>'use strict';
(function (angular) {
  angular
    .module('eventsManualPluginContent')
    .controller('ContentEventCtrl', ['$scope', '$routeParams', 'Buildfire', 'DataStore', 'TAG_NAMES', 'ADDRESS_TYPE', '$location', 'Utils', '$timeout',
      function ($scope, $routeParams, Buildfire, DataStore, TAG_NAMES, ADDRESS_TYPE, $location, Utils, $timeout) {
        var ContentEvent = this;
        var _data = {
          "title": "",
          "listImage": "",
          "deepLinkUrl": "",
          "carouselImages": [],
          "startDate": "",
          "endDate": "",
          "isAllDay": "",
          "timezone": "",
          "timeDisplay": {},
          "repeat": {},
          "addressTitle": "",
          "address": {},
          "description": "",
          "links": []

        };

        ContentEvent.event = {
          data: angular.copy(_data)
        };
        ContentEvent.isUpdating = false;
        ContentEvent.isNewEventInserted = false;
        ContentEvent.unchangedData = true;
        ContentEvent.displayTiming = "SELECTED";

        function isValidEvent(event) {
          return event.startDate || event.title;
        }

        updateMasterEvent(ContentEvent.event);

        function updateMasterEvent(event) {
          ContentEvent.masterEvent = angular.copy(event);
        }

        function isUnchanged(event) {
          return angular.equals(event, ContentEvent.masterEvent);
        }

        ContentEvent.getItem = function (id) {
          var successEvents = function (result) {
            ContentEvent.event = result;
            _data.dateCreated = result.data.dateCreated;
            updateMasterEvent(ContentEvent.event);
          }, errorEvents = function () {
            throw console.error('There was a problem fetching your data', err);
          };
          DataStore.getById(id, TAG_NAMES.EVENTS_MANUAL).then(successEvents, errorEvents);
        };

        if ($routeParams.id) {
          ContentEvent.getItem($routeParams.id);
        }

        ContentEvent.TimeZoneDropdownOptions = [
          {name: "(GMT -12:00) Eniwetok, Kwajalein", value: "-12.0"},
          {name: "(GMT -11:00) Midway Island, Samoa", value: "-11.0"},
          {name: "(GMT -10:00) Hawaii", value: "-10.0"},
          {name: "(GMT -9:00) Alaska", value: "-9.0"},
          {name: "(GMT -8:00) Pacific Time (US & Canada)", value: "-8.0"},
          {name: "(GMT -7:00) Mountain Time (US & Canada)", value: "-7:00"},
          {
            name: "(GMT -6:00) Central Time (US & Canada), Mexico City",
            value: "-6:00"
          },
          {
            name: "(GMT -5:00) Eastern Time (US & Canada), Bogota, Lima",
            value: "-5:00"
          },
          {
            name: "(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz",
            value: "-4:00"
          },
          {name: "(GMT -3:30) Newfoundland", value: "-3:30"},
          {
            name: "(GMT -3:00) Brazil, Buenos Aires, Georgetown",
            value: "-3:00"
          },
          {name: "(GMT -2:00) Mid-Atlantic", value: "-2:00"},
          {name: "(GMT -1:00) Azores, Cape Verde Islands", value: "-1:00"},
          {
            name: "(GMT) Western Europe Time, London, Lisbon, Casablanca",
            value: "0.0"
          },
          {
            name: "(GMT +1:00 hour) Brussels, Copenhagen, Madrid, Paris",
            value: "1.0"
          },
          {name: "(GMT +2:00) Kaliningrad, South Africa", value: "2:00"},
          {
            name: "(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg",
            value: "3:00"
          },
          {name: "(GMT +3:30) Tehran", value: "3:30"},
          {name: "(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi", value: "4:00"},
          {name: "(GMT +4:30) Kabul", value: "4:30"},
          {
            name: "(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent",
            value: "5:00"
          },
          {
            name: "(GMT +5:30) Bombay, Calcutta, Madras, New Delhi",
            value: '5:30'
          },
          {name: "(GMT +5:45) Kathmandu", value: "5:45"},
          {name: "(GMT +6:00) Almaty, Dhaka, Colombo", value: '6:00'},
          {name: "(GMT +7:00) Bangkok, Hanoi, Jakarta", value: "7:00"},
          {
            name: "(GMT +8:00) Beijing, Perth, Singapore, Hong Kong",
            value: "8:00"
          },
          {
            name: "(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk",
            value: "9:00"
          },
          {name: "(GMT +9:30) Adelaide, Darwin", value: "9:30"},
          {
            name: "(GMT +10:00) Eastern Australia, Guam, Vladivostok",
            value: "10:00"
          },
          {
            name: "(GMT +11:00) Magadan, Solomon Islands, New Caledonia",
            value: "11:00"
          },
          {
            name: "(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka",
            value: "12:00"
          }

        ];

        ContentEvent.descriptionWYSIWYGOptions = {
          plugins: 'advlist autolink link image lists charmap print preview',
          skin: 'lightgray',
          trusted: true,
          theme: 'modern'
        };

        /**
         * link and sortable options
         */
        var linkOptions = {"icon": "true"};
        ContentEvent.linksSortableOptions = {
          handle: '> .cursor-grab'
        };

        ContentEvent.validCoordinatesFailure = false;

        // create a new instance of the buildfire carousel editor
        var editor = new Buildfire.components.carousel.editor("#carousel");
        // this method will be called when a new item added to the list
        editor.onAddItems = function (items) {
          if (!ContentEvent.event.carouselImages)
            ContentEvent.event.carouselImages = [];
          ContentEvent.event.carouselImages.push.apply(ContentEvent.event.carouselImages, items);
          $scope.$digest();
        };
        // this method will be called when an item deleted from the list
        editor.onDeleteItem = function (item, index) {
          ContentEvent.event.carouselImages.splice(index, 1);
          $scope.$digest();
        };
        // this method will be called when you edit item details
        editor.onItemChange = function (item, index) {
          ContentEvent.event.carouselImages.splice(index, 1, item);
          $scope.$digest();
        };
        // this method will be called when you change the order of items
        editor.onOrderChange = function (item, oldIndex, newIndex) {
          var temp = ContentEvent.event.carouselImages[oldIndex];
          ContentEvent.event.carouselImages[oldIndex] = ContentEvent.event.carouselImages[newIndex];
          ContentEvent.event.carouselImages[newIndex] = temp;
          $scope.$digest();
        };

        ContentEvent.addNewEvent = function () {
          ContentEvent.isNewEventInserted = true;
          ContentEvent.event.data.dateCreated = +new Date();
          var successEvents = function (result) {
            console.log("Inserted", result.id);
            ContentEvent.isUpdating = false;
            ContentEvent.event.id = result.id;
            _data.dateCreated = ContentEvent.event.data.dateCreated;
            updateMasterEvent(ContentEvent.event);
            ContentEvent.event.data.deepLinkUrl = Buildfire.deeplink.createLink({id: result.id});
          }, errorEvents = function () {
            ContentEvent.isNewEventInserted = false;
            return console.error('There was a problem saving your data');
          };
          DataStore.insert(ContentEvent.event.data, TAG_NAMES.EVENTS_MANUAL).then(successEvents, errorEvents);
        };

        ContentEvent.updateEventData = function () {
          DataStore.update(ContentEvent.event.id, ContentEvent.event.data, TAG_NAMES.EVENTS_MANUAL, function (err) {
            ContentEvent.isUpdating = false;
            if (err)
              return console.error('There was a problem saving your data');
          })
        };

        var tmrDelayForEvent = null;

        var updateItemsWithDelay = function (event) {
          clearTimeout(tmrDelayForEvent);
          ContentEvent.isUpdating = false;
          ContentEvent.unchangedData = angular.equals(_data, ContentEvent.event.data);

          ContentEvent.isEventValid = isValidEvent(ContentEvent.event.data);
          if (!ContentEvent.isUpdating && !isUnchanged(ContentEvent.event) && ContentEvent.isEventValid) {
            tmrDelayForEvent = setTimeout(function () {
              if (event.id) {
                ContentEvent.updateEventData();
              } else if (!ContentEvent.isNewEventInserted) {
                ContentEvent.addNewEvent();
              }
            }, 300);
          }
        };

        ContentEvent.changeTimeZone = function (timezone) {
          ContentEvent.event.timezone = timezone;
        };

        ContentEvent.changeRepeatType = function (type) {
          ContentEvent.event.repeat = {};
          ContentEvent.event.repeat.isRepeating = true;
          ContentEvent.event.repeat.repeatType = type;
        };

        /**
         * Add dynamic link
         */

        ContentEvent.addLink = function () {
          var options = {showIcons: false};
          var callback = function (error, result) {
            if (error) {
              return console.error('Error:', error);
            }
            if (!ContentEvent.event.links)
              ContentEvent.event.links = [];
            ContentEvent.event.links.push(result);
            $scope.$digest();
          };
          Buildfire.actionItems.showDialog(null, options, callback);
        };

        /**
         * Remove dynamic link
         */

        ContentEvent.removeLink = function (index) {
          if (ContentEvent.event && ContentEvent.event.links) {
            ContentEvent.event.links.splice(index, 1);
          }
        };

        /**
         * Edit dynamic link
         */

        ContentEvent.editLink = function (link, index) {
          Buildfire.actionItems.showDialog(link, linkOptions, function editLinkCallback(error, result) {
            if (error) {
              return console.error('Error:', error);
            }
            if (!ContentEvent.event.links) {
              ContentEvent.event.links = [];
            }
            if (result === null) {
              return console.error('Error:Can not save data, Null record found.');
            }
            ContentEvent.event.links.splice(index, 1, result);
            $scope.$digest();
          });
        };

        /**
         * Save selected place from google autocomplete as address
         */

        ContentEvent.setLocation = function (data) {
          ContentEvent.event.address = {
            type: ADDRESS_TYPE.LOCATION,
            location: data.location,
            location_coordinates: data.coordinates
          };
          ContentEvent.currentAddress = ContentEvent.event.address.location;
          ContentEvent.currentCoordinates = ContentEvent.event.address.location_coordinates;
          $scope.$digest();
        };

        /**
         * Change the address and map to dragged marker location
         */

        ContentEvent.setDraggedLocation = function (data) {
          ContentEvent.event.address = {
            type: ADDRESS_TYPE.LOCATION,
            location: data.location,
            location_coordinates: data.coordinates
          };
          ContentEvent.currentAddress = ContentEvent.event.address.location;
          ContentEvent.currentCoordinates = ContentEvent.event.address.location_coordinates;
          $scope.$digest();
        };

        /* Build fire thumbnail component to add thumbnail image*/
        var listImage = new Buildfire.components.images.thumbnail("#listImage", {title: "List Image"});

        listImage.onChange = function (url) {
          ContentEvent.event.listImage = url;
          if (!$scope.$$phase && !$scope.$root.$$phase) {
            $scope.$apply();
          }
        };

        listImage.onDelete = function (url) {
          ContentEvent.event.listImage = "";
          if (!$scope.$$phase && !$scope.$root.$$phase) {
            $scope.$apply();
          }
        };

        ContentEvent.deleteEvent = function () {
          var event = ContentEvent.event;
          if (event.id) {
            Buildfire.datastore.delete(event.id, TAG_NAMES.EVENTS_MANUAL, function (err, result) {
              if (err)
                return;
              $location.path('/');
            });
          }
        };

        ContentEvent.clearAddress = function () {
          if (!ContentEvent.currentAddress) {
            ContentEvent.event.address = null;
            ContentEvent.currentCoordinates = null;
          }
        };

        ContentEvent.setCoordinates = function () {
          function successCallback(resp) {
            if (resp) {
              ContentEvent.event.address = {
                type: ADDRESS_TYPE.COORDINATES,
                location: resp.formatted_address || ContentEvent.currentAddress,
                location_coordinates: [ContentEvent.currentAddress.split(",")[0].trim(), ContentEvent.currentAddress.split(",")[1].trim()]
              };
              ContentEvent.currentAddress = ContentEvent.event.address.location;
              ContentEvent.currentCoordinates = ContentEvent.event.address.location_coordinates;
            } else {
              errorCallback();
            }
          }

          function errorCallback(err) {
            ContentEvent.validCoordinatesFailure = true;
            $timeout(function () {
              ContentEvent.validCoordinatesFailure = false;
            }, 5000);
          }

          Utils.validLongLats(ContentEvent.currentAddress).then(successCallback, errorCallback);
        };

        $scope.$watch(function () {
          return ContentEvent.event;
        }, updateItemsWithDelay, true);

      }]);
})(window.angular);
<commit_msg>added delete event on content event list<commit_after>'use strict';
(function (angular) {
  angular
    .module('eventsManualPluginContent')
    .controller('ContentEventCtrl', ['$scope', '$routeParams', 'Buildfire', 'DataStore', 'TAG_NAMES', 'ADDRESS_TYPE', '$location', 'Utils', '$timeout',
      function ($scope, $routeParams, Buildfire, DataStore, TAG_NAMES, ADDRESS_TYPE, $location, Utils, $timeout) {
        var ContentEvent = this;
        var _data = {
          "title": "",
          "listImage": "",
          "deepLinkUrl": "",
          "carouselImages": [],
          "startDate": "",
          "endDate": "",
          "isAllDay": "",
          "timezone": "",
          "timeDisplay": {},
          "repeat": {},
          "addressTitle": "",
          "address": {},
          "description": "",
          "links": []

        };

        ContentEvent.event = {
          data: angular.copy(_data)
        };
        ContentEvent.isUpdating = false;
        ContentEvent.isNewEventInserted = false;
        ContentEvent.unchangedData = true;
        ContentEvent.displayTiming = "SELECTED";

        function isValidEvent(event) {
          return event.startDate || event.title;
        }

        updateMasterEvent(ContentEvent.event);

        function updateMasterEvent(event) {
          ContentEvent.masterEvent = angular.copy(event);
        }

        function isUnchanged(event) {
          return angular.equals(event, ContentEvent.masterEvent);
        }

        ContentEvent.getItem = function (id) {
          var successEvents = function (result) {
            ContentEvent.event = result;
            if (ContentEvent.event.data.startDate)
              ContentEvent.event.data.startDate = new Date(result.data.startDate);
            if (ContentEvent.event.data.endDate)
              ContentEvent.event.data.endDate = new Date(result.data.endDate);
            if (ContentEvent.event.data.startTime)
              ContentEvent.event.data.startTime = new Date(result.data.startTime);
            if (ContentEvent.event.data.endTime)
              ContentEvent.event.data.endTime = new Date(result.data.endTime);
            if (ContentEvent.event.data.address && ContentEvent.event.data.address.location) {
              ContentEvent.currentAddress = ContentEvent.event.data.address.location;
              ContentEvent.currentCoordinates = ContentEvent.event.data.address.location_coordinates;
            }
            _data.dateCreated = result.data.dateCreated;
            updateMasterEvent(ContentEvent.event);
          }, errorEvents = function () {
            throw console.error('There was a problem fetching your data', err);
          };
          DataStore.getById(id, TAG_NAMES.EVENTS_MANUAL).then(successEvents, errorEvents);
        };

        if ($routeParams.id) {
          ContentEvent.getItem($routeParams.id);
        }

        ContentEvent.TimeZoneDropdownOptions = [
          {name: "(GMT -12:00) Eniwetok, Kwajalein", value: "-12.0"},
          {name: "(GMT -11:00) Midway Island, Samoa", value: "-11.0"},
          {name: "(GMT -10:00) Hawaii", value: "-10.0"},
          {name: "(GMT -9:00) Alaska", value: "-9.0"},
          {name: "(GMT -8:00) Pacific Time (US & Canada)", value: "-8.0"},
          {name: "(GMT -7:00) Mountain Time (US & Canada)", value: "-7:00"},
          {
            name: "(GMT -6:00) Central Time (US & Canada), Mexico City",
            value: "-6:00"
          },
          {
            name: "(GMT -5:00) Eastern Time (US & Canada), Bogota, Lima",
            value: "-5:00"
          },
          {
            name: "(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz",
            value: "-4:00"
          },
          {name: "(GMT -3:30) Newfoundland", value: "-3:30"},
          {
            name: "(GMT -3:00) Brazil, Buenos Aires, Georgetown",
            value: "-3:00"
          },
          {name: "(GMT -2:00) Mid-Atlantic", value: "-2:00"},
          {name: "(GMT -1:00) Azores, Cape Verde Islands", value: "-1:00"},
          {
            name: "(GMT) Western Europe Time, London, Lisbon, Casablanca",
            value: "0.0"
          },
          {
            name: "(GMT +1:00 hour) Brussels, Copenhagen, Madrid, Paris",
            value: "1.0"
          },
          {name: "(GMT +2:00) Kaliningrad, South Africa", value: "2:00"},
          {
            name: "(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg",
            value: "3:00"
          },
          {name: "(GMT +3:30) Tehran", value: "3:30"},
          {name: "(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi", value: "4:00"},
          {name: "(GMT +4:30) Kabul", value: "4:30"},
          {
            name: "(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent",
            value: "5:00"
          },
          {
            name: "(GMT +5:30) Bombay, Calcutta, Madras, New Delhi",
            value: '5:30'
          },
          {name: "(GMT +5:45) Kathmandu", value: "5:45"},
          {name: "(GMT +6:00) Almaty, Dhaka, Colombo", value: '6:00'},
          {name: "(GMT +7:00) Bangkok, Hanoi, Jakarta", value: "7:00"},
          {
            name: "(GMT +8:00) Beijing, Perth, Singapore, Hong Kong",
            value: "8:00"
          },
          {
            name: "(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk",
            value: "9:00"
          },
          {name: "(GMT +9:30) Adelaide, Darwin", value: "9:30"},
          {
            name: "(GMT +10:00) Eastern Australia, Guam, Vladivostok",
            value: "10:00"
          },
          {
            name: "(GMT +11:00) Magadan, Solomon Islands, New Caledonia",
            value: "11:00"
          },
          {
            name: "(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka",
            value: "12:00"
          }

        ];

        ContentEvent.descriptionWYSIWYGOptions = {
          plugins: 'advlist autolink link image lists charmap print preview',
          skin: 'lightgray',
          trusted: true,
          theme: 'modern'
        };

        /**
         * link and sortable options
         */
        var linkOptions = {"icon": "true"};
        ContentEvent.linksSortableOptions = {
          handle: '> .cursor-grab'
        };

        ContentEvent.validCoordinatesFailure = false;

        // create a new instance of the buildfire carousel editor
        var editor = new Buildfire.components.carousel.editor("#carousel");
        // this method will be called when a new item added to the list
        editor.onAddItems = function (items) {
          if (!ContentEvent.event.carouselImages)
            ContentEvent.event.carouselImages = [];
          ContentEvent.event.carouselImages.push.apply(ContentEvent.event.carouselImages, items);
          $scope.$digest();
        };
        // this method will be called when an item deleted from the list
        editor.onDeleteItem = function (item, index) {
          ContentEvent.event.carouselImages.splice(index, 1);
          $scope.$digest();
        };
        // this method will be called when you edit item details
        editor.onItemChange = function (item, index) {
          ContentEvent.event.carouselImages.splice(index, 1, item);
          $scope.$digest();
        };
        // this method will be called when you change the order of items
        editor.onOrderChange = function (item, oldIndex, newIndex) {
          var temp = ContentEvent.event.carouselImages[oldIndex];
          ContentEvent.event.carouselImages[oldIndex] = ContentEvent.event.carouselImages[newIndex];
          ContentEvent.event.carouselImages[newIndex] = temp;
          $scope.$digest();
        };

        ContentEvent.addNewEvent = function () {
          ContentEvent.isNewEventInserted = true;
          ContentEvent.event.data.dateCreated = +new Date();
          var successEvents = function (result) {
            console.log("Inserted", result.id);
            ContentEvent.isUpdating = false;
            ContentEvent.event.id = result.id;
            _data.dateCreated = ContentEvent.event.data.dateCreated;
            updateMasterEvent(ContentEvent.event);
            ContentEvent.event.data.deepLinkUrl = Buildfire.deeplink.createLink({id: result.id});
          }, errorEvents = function () {
            ContentEvent.isNewEventInserted = false;
            return console.error('There was a problem saving your data');
          };
          DataStore.insert(ContentEvent.event.data, TAG_NAMES.EVENTS_MANUAL).then(successEvents, errorEvents);
        };

        ContentEvent.updateEventData = function () {
          DataStore.update(ContentEvent.event.id, ContentEvent.event.data, TAG_NAMES.EVENTS_MANUAL, function (err) {
            ContentEvent.isUpdating = false;
            if (err)
              return console.error('There was a problem saving your data');
          })
        };

        var tmrDelayForEvent = null;

        var updateItemsWithDelay = function (event) {
          clearTimeout(tmrDelayForEvent);
          ContentEvent.isUpdating = false;
          ContentEvent.unchangedData = angular.equals(_data, ContentEvent.event.data);

          ContentEvent.isEventValid = isValidEvent(ContentEvent.event.data);
          if (!ContentEvent.isUpdating && !isUnchanged(ContentEvent.event) && ContentEvent.isEventValid) {
            tmrDelayForEvent = setTimeout(function () {
              if (event.id) {
                ContentEvent.updateEventData();
              } else if (!ContentEvent.isNewEventInserted) {
                ContentEvent.addNewEvent();
              }
            }, 300);
          }
        };

        ContentEvent.changeTimeZone = function (timezone) {
          ContentEvent.event.timezone = timezone;
        };

        ContentEvent.changeRepeatType = function (type) {
          ContentEvent.event.repeat = {};
          ContentEvent.event.repeat.isRepeating = true;
          ContentEvent.event.repeat.repeatType = type;
        };

        /**
         * Add dynamic link
         */

        ContentEvent.addLink = function () {
          var options = {showIcons: false};
          var callback = function (error, result) {
            if (error) {
              return console.error('Error:', error);
            }
            if (!ContentEvent.event.links)
              ContentEvent.event.links = [];
            ContentEvent.event.links.push(result);
            $scope.$digest();
          };
          Buildfire.actionItems.showDialog(null, options, callback);
        };

        /**
         * Remove dynamic link
         */

        ContentEvent.removeLink = function (index) {
          if (ContentEvent.event && ContentEvent.event.links) {
            ContentEvent.event.links.splice(index, 1);
          }
        };

        /**
         * Edit dynamic link
         */

        ContentEvent.editLink = function (link, index) {
          Buildfire.actionItems.showDialog(link, linkOptions, function editLinkCallback(error, result) {
            if (error) {
              return console.error('Error:', error);
            }
            if (!ContentEvent.event.links) {
              ContentEvent.event.links = [];
            }
            if (result === null) {
              return console.error('Error:Can not save data, Null record found.');
            }
            ContentEvent.event.links.splice(index, 1, result);
            $scope.$digest();
          });
        };

        /**
         * Save selected place from google autocomplete as address
         */

        ContentEvent.setLocation = function (data) {
          ContentEvent.event.data.address = {
            type: ADDRESS_TYPE.LOCATION,
            location: data.location,
            location_coordinates: data.coordinates
          };
          ContentEvent.currentAddress = ContentEvent.event.data.address.location;
          ContentEvent.currentCoordinates = ContentEvent.event.data.address.location_coordinates;
          $scope.$digest();
        };

        /**
         * Change the address and map to dragged marker location
         */

        ContentEvent.setDraggedLocation = function (data) {
          ContentEvent.event.data.address = {
            type: ADDRESS_TYPE.LOCATION,
            location: data.location,
            location_coordinates: data.coordinates
          };
          ContentEvent.currentAddress = ContentEvent.event.data.address.location;
          ContentEvent.currentCoordinates = ContentEvent.event.data.address.location_coordinates;
          $scope.$digest();
        };

        /* Build fire thumbnail component to add thumbnail image*/
        var listImage = new Buildfire.components.images.thumbnail("#listImage", {title: "List Image"});

        listImage.onChange = function (url) {
          ContentEvent.event.listImage = url;
          if (!$scope.$$phase && !$scope.$root.$$phase) {
            $scope.$apply();
          }
        };

        listImage.onDelete = function (url) {
          ContentEvent.event.listImage = "";
          if (!$scope.$$phase && !$scope.$root.$$phase) {
            $scope.$apply();
          }
        };

        ContentEvent.deleteEvent = function () {
          var event = ContentEvent.event;
          if (event.id) {
            Buildfire.datastore.delete(event.id, TAG_NAMES.EVENTS_MANUAL, function (err, result) {
              if (err)
                return;
              $location.path('/');
            });
          }
        };

        ContentEvent.clearAddress = function () {
          if (!ContentEvent.currentAddress) {
            ContentEvent.event.data.address = null;
            ContentEvent.currentCoordinates = null;
          }
        };

        ContentEvent.setCoordinates = function () {
          function successCallback(resp) {
            if (resp) {
              ContentEvent.event.data.address = {
                type: ADDRESS_TYPE.COORDINATES,
                location: resp.formatted_address || ContentEvent.currentAddress,
                location_coordinates: [ContentEvent.currentAddress.split(",")[0].trim(), ContentEvent.currentAddress.split(",")[1].trim()]
              };
              ContentEvent.currentAddress = ContentEvent.event.data.address.location;
              ContentEvent.currentCoordinates = ContentEvent.event.data.address.location_coordinates;
            } else {
              errorCallback();
            }
          }

          function errorCallback(err) {
            ContentEvent.validCoordinatesFailure = true;
            $timeout(function () {
              ContentEvent.validCoordinatesFailure = false;
            }, 5000);
          }

          Utils.validLongLats(ContentEvent.currentAddress).then(successCallback, errorCallback);
        };

        $scope.$watch(function () {
          return ContentEvent.event;
        }, updateItemsWithDelay, true);

      }]);
})(window.angular);
<|endoftext|>


<commit_before>/*!
 * Carousel.js v1.0.0 ~ Copyright (c) 2013 Nino D'Aversa, http://ndaversa.com
 * Released under MIT license
 */

;(function (global) { function moduleDefinition(_, $) {
'use strict';

// ---------------------------------------------------------------------------
// Browser and Feature Detection

var dummyStyle = document.createElement('div').style,
  hasTouch = 'ontouchstart' in window,

  // Events
  resizeEvent = 'onorientationchange' in window ? 'orientationchange' : 'resize',
  startEvent = hasTouch ? 'touchstart' : 'mousedown',
  moveEvent = hasTouch ? 'touchmove' : 'mousemove',
  endEvent = hasTouch ? 'touchend' : 'mouseup',
  cancelEvent = hasTouch ? 'touchcancel' : 'mouseup';

// ---------------------------------------------------------------------------
// Carousel.js

function Carousel(options) {
  options || (options = {});

  this.start = {x: 0, page:0};
  this.move = {x: 0, page: 0};
  this.delta = {x: 0, page: 0};
  this.next = {x: 0, page:0};
  this.current = {x: 0, page:0};
  this.limit = {left: {x: 0}, right: {x:0}};

  this._configure(options);
  this.$el = $(this.el);
  this.el = this.$el[0];
}

var carouselOptions = [
  'bufferPages',
  'data',
  'el',
  'loop',
  'pageTemplate',
  'pageWidth',
  'template',
];

_.extend(Carousel.prototype, {

  _configure: function (options) {
    var carouselDefaults = {
      loop: true,
      data: [],
      bufferPages: 2,
      pageWidth: 256
    };
    _.extend(this, carouselDefaults, _.pick(options, carouselOptions));
    if (!this.loop) {
      this.limit.left.x = 0;
      this.limit.right.x = (this.data.length - 1) * -this.pageWidth;
    }
    else {
      this.limit.left.x = Infinity;
      this.limit.right.x = -Infinity;
    }
    this.current.page = this.bufferPages;
  },

  pageTemplate: function (data) {
    data = data || { content: '' };
    return '
' + this.template(data) + '
';
  },

  template: function (data) {
    data = data || { content: '' };
    return '' + data.content;
  },

  initPages: function () {
    var dataIndex = this.data.length - 1;

    this.page = new Array(this.bufferPages * 2 + 1);

    // Build left buffer pages
    for (var i=this.current.page-1; i>=0; i--) {
      var data = this.loop ? this.data[dataIndex-- % this.data.length] : undefined,
        x = (i - this.bufferPages) * this.pageWidth;

      this.page[i] = {
        x: x,
        dataIndex: dataIndex + 1,
        data: data,
        $el: $(this.pageTemplate(data)).css({
          position: 'absolute',
          left: x + 'px'
        })
      };
    }

    dataIndex = 0;
    for (var i=this.current.page; i<this.page.length; i++) {
      var data,
        x = (i - this.bufferPages) * this.pageWidth;

      if (!this.loop && dataIndex > this.data.length - 1) {
        data = undefined;
      }
      else {
        data = this.data[dataIndex++ % this.data.length];
      }

      this.page[i] = {
        x: x,
        dataIndex: dataIndex - 1,
        data: data,
        $el: $(this.pageTemplate(data)).css({
          position: 'absolute',
          left: x + 'px'
        })
      };
    }
  },

  initSlider: function () {
    this.slider = $('
');
    this.slider.css({
      position: 'relative',
      top: '0px',
      height: '100%',
      width: '100%',
      transitionDuration: '0s',
      transitionTimingFunction: 'ease-out',
      transform: 'translate3d(0px, 0px, 0px)'
    })
    .on('touchstart', _.bind(this._start, this))
    .on('touchmove', _.bind(this._move, this))
    .on('touchend', _.bind(this._end, this))
    .on('touchcancel', _.bind(this._cancel, this));
  },

  appendPages: function () {
    for (var i=0; i<this.page.length; i++) {
      this.slider.append(this.page[i].$el);
    }
  },

  render: function () {
    this.initPages();
    this.initSlider();
    this.appendPages();

    this.$el.css({
      position: 'relative',
      overflow: 'hidden'
    }).html(this.slider);

    return this;
  },

  indexShift: function (current, amt, size) {
    return (size + ((current + amt) % size)) % size;
  },

  crossBoundary: function (previous, current) {
    var rightMostPage = _.max(this.page, function(page) { return page.x; }),
        leftMostPage  = _.min(this.page, function(page) { return page.x; }),
        nextRightData = this.indexShift(rightMostPage.dataIndex, 1, this.data.length),
        nextLeftData  = this.indexShift(leftMostPage.dataIndex, -1, this.data.length);

    if (previous < current) { //swiped to the left (show more on right)
      if (this.loop || nextRightData !== 0) {
        leftMostPage.data = this.data[nextRightData];
        leftMostPage.dataIndex = nextRightData;
        leftMostPage.x = rightMostPage.x + this.pageWidth;
        leftMostPage.$el
          .css('left', leftMostPage.x + 'px')
          .html(this.template(leftMostPage.data));
      }
    }
    else { //swiped to the right (show more on left)
      if (this.loop || nextLeftData !== this.data.length - 1) {
        rightMostPage.data = this.data[nextLeftData];
        rightMostPage.dataIndex = nextLeftData;
        rightMostPage.x = leftMostPage.x - this.pageWidth;
        rightMostPage.$el
          .css('left', rightMostPage.x + 'px')
          .html(this.template(rightMostPage.data));
      }
    }
    this.current.page = current;
  },

  _start: function (evt) {
    this.start.x = evt.originalEvent.touches[0].pageX;
    this.touches = [];
    this.touches.push(this.start.x);
  },

  _move: function (evt) {
    evt.preventDefault(); //needed for Android 2.3

    this.move.x = evt.originalEvent.touches[0].pageX;
    this.touches.push(this.move.x);
    this.delta.x = this.move.x - this.start.x;
    this.next.x = this.current.x + this.delta.x;

    if (this.next.x > this.limit.left.x) { //left-most limit
      this.next.x -= Math.round(this.delta.x/2);
    }
    else if (this.next.x < this.limit.right.x) { //right-most limit
      this.delta.bounce = this.limit.right.x - this.next.x;
      this.next.x = this.limit.right.x - Math.round(this.delta.bounce/2);
    }

    this.slider.css({
      transform: 'translate3d(' + this.next.x + 'px, 0, 0)',
      transition: '0s'
    });
  },

  _end: function (evt) {
    var animateBack = false;

    // console.log('_end, touches', this.touches);
    this.touches = [];

    if (this.next.x > this.limit.left.x) { //left-most limit
      this.next.x = this.limit.left.x;
      animateBack = true;
    }
    else if (this.next.x < this.limit.right.x) { //right-most limit
      this.next.x = this.limit.right.x;
      animateBack = true;
    }

    if (animateBack) {
      this.slider.css({
        transform: 'translate3d(' + this.next.x + 'px, 0, 0)',
        transition: '300ms'
      });
    }

    this.current.x = this.next.x;
    this.next.page = Math.floor(-this.current.x / this.pageWidth) + this.bufferPages;
    if (this.current.page !== this.next.page) {
      this.crossBoundary(this.current.page, this.next.page);
    }
  },

  _cancel: function (evt) {
    this._end(evt);
  }

});
return Carousel;

// ---------------------------------------------------------------------------
// Module Definition

} if (typeof exports === 'object') {
    module.exports = moduleDefinition(require('lodash'), require('jquery'));
} else if (typeof define === 'function' && define.amd) {
    define([require('lodash'), require('jquery')], moduleDefinition);
} else {
    global.Carousel = moduleDefinition(global._, global.$);
}}(this));
<commit_msg>Only preventDefault when gesture is in the horizontal direction<commit_after>/*!
 * Carousel.js v1.0.0 ~ Copyright (c) 2013 Nino D'Aversa, http://ndaversa.com
 * Released under MIT license
 */

;(function (global) { function moduleDefinition(_, $) {
'use strict';

// ---------------------------------------------------------------------------
// Browser and Feature Detection

var dummyStyle = document.createElement('div').style,
  hasTouch = 'ontouchstart' in window,

  // Events
  resizeEvent = 'onorientationchange' in window ? 'orientationchange' : 'resize',
  startEvent = hasTouch ? 'touchstart' : 'mousedown',
  moveEvent = hasTouch ? 'touchmove' : 'mousemove',
  endEvent = hasTouch ? 'touchend' : 'mouseup',
  cancelEvent = hasTouch ? 'touchcancel' : 'mouseup';

// ---------------------------------------------------------------------------
// Carousel.js

function Carousel(options) {
  options || (options = {});

  this.start = {x: 0, page:0};
  this.move = {x: 0, page: 0};
  this.delta = {x: 0, page: 0};
  this.next = {x: 0, page:0};
  this.current = {x: 0, page:0};
  this.limit = {left: {x: 0}, right: {x:0}};

  this._configure(options);
  this.$el = $(this.el);
  this.el = this.$el[0];
}

var carouselOptions = [
  'bufferPages',
  'data',
  'el',
  'loop',
  'pageTemplate',
  'pageWidth',
  'template',
];

_.extend(Carousel.prototype, {

  _configure: function (options) {
    var carouselDefaults = {
      loop: true,
      data: [],
      bufferPages: 2,
      pageWidth: 256
    };
    _.extend(this, carouselDefaults, _.pick(options, carouselOptions));
    if (!this.loop) {
      this.limit.left.x = 0;
      this.limit.right.x = (this.data.length - 1) * -this.pageWidth;
    }
    else {
      this.limit.left.x = Infinity;
      this.limit.right.x = -Infinity;
    }
    this.current.page = this.bufferPages;
  },

  pageTemplate: function (data) {
    data = data || { content: '' };
    return '
' + this.template(data) + '
';
  },

  template: function (data) {
    data = data || { content: '' };
    return '' + data.content;
  },

  initPages: function () {
    var dataIndex = this.data.length - 1;

    this.page = new Array(this.bufferPages * 2 + 1);

    // Build left buffer pages
    for (var i=this.current.page-1; i>=0; i--) {
      var data = this.loop ? this.data[dataIndex-- % this.data.length] : undefined,
        x = (i - this.bufferPages) * this.pageWidth;

      this.page[i] = {
        x: x,
        dataIndex: dataIndex + 1,
        data: data,
        $el: $(this.pageTemplate(data)).css({
          position: 'absolute',
          left: x + 'px'
        })
      };
    }

    dataIndex = 0;
    for (var i=this.current.page; i<this.page.length; i++) {
      var data,
        x = (i - this.bufferPages) * this.pageWidth;

      if (!this.loop && dataIndex > this.data.length - 1) {
        data = undefined;
      }
      else {
        data = this.data[dataIndex++ % this.data.length];
      }

      this.page[i] = {
        x: x,
        dataIndex: dataIndex - 1,
        data: data,
        $el: $(this.pageTemplate(data)).css({
          position: 'absolute',
          left: x + 'px'
        })
      };
    }
  },

  initSlider: function () {
    this.slider = $('
');
    this.slider.css({
      position: 'relative',
      top: '0px',
      height: '100%',
      width: '100%',
      transitionDuration: '0s',
      transitionTimingFunction: 'ease-out',
      transform: 'translate3d(0px, 0px, 0px)'
    })
    .on('touchstart', _.bind(this._start, this))
    .on('touchmove', _.bind(this._move, this))
    .on('touchend', _.bind(this._end, this))
    .on('touchcancel', _.bind(this._cancel, this));
  },

  appendPages: function () {
    for (var i=0; i<this.page.length; i++) {
      this.slider.append(this.page[i].$el);
    }
  },

  render: function () {
    this.initPages();
    this.initSlider();
    this.appendPages();

    this.$el.css({
      position: 'relative',
      overflow: 'hidden'
    }).html(this.slider);

    return this;
  },

  indexShift: function (current, amt, size) {
    return (size + ((current + amt) % size)) % size;
  },

  crossBoundary: function (previous, current) {
    var rightMostPage = _.max(this.page, function(page) { return page.x; }),
        leftMostPage  = _.min(this.page, function(page) { return page.x; }),
        nextRightData = this.indexShift(rightMostPage.dataIndex, 1, this.data.length),
        nextLeftData  = this.indexShift(leftMostPage.dataIndex, -1, this.data.length);

    if (previous < current) { //swiped to the left (show more on right)
      if (this.loop || nextRightData !== 0) {
        leftMostPage.data = this.data[nextRightData];
        leftMostPage.dataIndex = nextRightData;
        leftMostPage.x = rightMostPage.x + this.pageWidth;
        leftMostPage.$el
          .css('left', leftMostPage.x + 'px')
          .html(this.template(leftMostPage.data));
      }
    }
    else { //swiped to the right (show more on left)
      if (this.loop || nextLeftData !== this.data.length - 1) {
        rightMostPage.data = this.data[nextLeftData];
        rightMostPage.dataIndex = nextLeftData;
        rightMostPage.x = leftMostPage.x - this.pageWidth;
        rightMostPage.$el
          .css('left', rightMostPage.x + 'px')
          .html(this.template(rightMostPage.data));
      }
    }
    this.current.page = current;
  },

  _start: function (evt) {
    this.start.x = evt.originalEvent.touches[0].pageX;
    this.start.y = evt.originalEvent.touches[0].pageY;
    this.touches = [];
    this.touches.push(this.start.x);
  },

  _move: function (evt) {
    this.move.x = evt.originalEvent.touches[0].pageX;
    this.move.y = evt.originalEvent.touches[0].pageY;
    this.delta.x = this.move.x - this.start.x;
    this.delta.y = this.move.y - this.start.y;

    if (this.delta.y > this.delta.x) return;

    evt.preventDefault(); //needed for Android 2.3
    this.touches.push(this.move.x);
    this.next.x = this.current.x + this.delta.x;

    if (this.next.x > this.limit.left.x) { //left-most limit
      this.next.x -= Math.round(this.delta.x/2);
    }
    else if (this.next.x < this.limit.right.x) { //right-most limit
      this.delta.bounce = this.limit.right.x - this.next.x;
      this.next.x = this.limit.right.x - Math.round(this.delta.bounce/2);
    }

    this.slider.css({
      transform: 'translate3d(' + this.next.x + 'px, 0, 0)',
      transition: '0s'
    });
  },

  _end: function (evt) {
    var animateBack = false;

    // console.log('_end, touches', this.touches);
    this.touches = [];

    if (this.next.x > this.limit.left.x) { //left-most limit
      this.next.x = this.limit.left.x;
      animateBack = true;
    }
    else if (this.next.x < this.limit.right.x) { //right-most limit
      this.next.x = this.limit.right.x;
      animateBack = true;
    }

    if (animateBack) {
      this.slider.css({
        transform: 'translate3d(' + this.next.x + 'px, 0, 0)',
        transition: '300ms'
      });
    }

    this.current.x = this.next.x;
    this.next.page = Math.floor(-this.current.x / this.pageWidth) + this.bufferPages;
    if (this.current.page !== this.next.page) {
      this.crossBoundary(this.current.page, this.next.page);
    }
  },

  _cancel: function (evt) {
    this._end(evt);
  }

});
return Carousel;

// ---------------------------------------------------------------------------
// Module Definition

} if (typeof exports === 'object') {
    module.exports = moduleDefinition(require('lodash'), require('jquery'));
} else if (typeof define === 'function' && define.amd) {
    define([require('lodash'), require('jquery')], moduleDefinition);
} else {
    global.Carousel = moduleDefinition(global._, global.$);
}}(this));
<|endoftext|>


<commit_before>module.exports = [
  {
    _id: Math.round(Math.random() * 1000000),
    text:
      "It uses the same design as React, letting you compose a rich mobile UI from declarative components https://facebook.github.io/react-native/",
    createdAt: new Date(Date.UTC(2016, 7, 30, 17, 20, 0)),
    user: {
      _id: 1,
      name: "Developer"
    }
  },
  {
    _id: Math.round(Math.random() * 1000000),
    text: "React Native lets you build mobile apps using only JavaScript",
    createdAt: new Date(Date.UTC(2016, 7, 30, 17, 20, 0)),
    user: {
      _id: 1,
      name: "Developer"
    }
  },
  {
    _id: Math.round(Math.random() * 1000000),
    text: "This is a system message.",
    createdAt: new Date(Date.UTC(2016, 7, 30, 17, 20, 0)),
    system: true
  }
];;
<commit_msg>Unnecessary semicolon removed (#677)<commit_after>module.exports = [
  {
    _id: Math.round(Math.random() * 1000000),
    text:
      "It uses the same design as React, letting you compose a rich mobile UI from declarative components https://facebook.github.io/react-native/",
    createdAt: new Date(Date.UTC(2016, 7, 30, 17, 20, 0)),
    user: {
      _id: 1,
      name: "Developer"
    }
  },
  {
    _id: Math.round(Math.random() * 1000000),
    text: "React Native lets you build mobile apps using only JavaScript",
    createdAt: new Date(Date.UTC(2016, 7, 30, 17, 20, 0)),
    user: {
      _id: 1,
      name: "Developer"
    }
  },
  {
    _id: Math.round(Math.random() * 1000000),
    text: "This is a system message.",
    createdAt: new Date(Date.UTC(2016, 7, 30, 17, 20, 0)),
    system: true
  }
];
<|endoftext|>


<commit_before>TileMill.popup = {};

TileMill.popup.show = function(options) {
  if ($('body #popup').size()) {
    TileMill.popup.hide();
  }
  var popup = $(TileMill.template('popup', {
    'title': options.title,
    'content': TileMill.template('popup-' + (options.type ? options.type : 'standard'), options),
  }));
  popup.find('a.popup-close').bind('click', TileMill.popup.hide);
  $('body').append(popup);
};

TileMill.popup.hide = function() {
  if ($('body #popup').size()) {
    $('body #popup').remove();
  }
};
<commit_msg>Return false on popup close.<commit_after>TileMill.popup = {};

TileMill.popup.show = function(options) {
  if ($('body #popup').size()) {
    TileMill.popup.hide();
  }
  var popup = $(TileMill.template('popup', {
    'title': options.title,
    'content': TileMill.template('popup-' + (options.type ? options.type : 'standard'), options),
  }));
  popup.find('a.popup-close').bind('click', TileMill.popup.hide);
  $('body').append(popup);
};

TileMill.popup.hide = function() {
  if ($('body #popup').size()) {
    $('body #popup').remove();
  }
  return false;
};
<|endoftext|>


<commit_before>/*
 * Copyright [1999-2014] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

(function($) {
  var elements = [];
  var coords = [];

  var wiggle = 1000;
  var miles_away = 50000;

  function still_alive(el) {
    var p = el.parents();
    if(!p.length) { return false; }
    if($(p[p.length-1]).prop("tagName") != "HTML") { return false; }
    return true;
  }

  function refresh_element(i,el) {
    var etop = el.offset().top;
    var ebot = etop +el.outerHeight(true);
    coords[i] = [etop-wiggle,ebot+wiggle];
  }

  function refresh() {
    for(var i=0;i<elements.length;i++) {
      refresh_element(i,elements[i]);
      if(!still_alive(elements[i])) {
        elements.splice(i,1);
        coords.splice(i,1);
        i--;
      }
    }
  }

  function awaken(el) {
    el.trigger('awaken');
    el.addClass('__awake');
    refresh();
  }

  function sleepen(el) {
    el.trigger('sleepen');
    el.removeClass('__awake');
    refresh();
  }

  function check() {
    var wtop = $(window).scrollTop();
    var wbot = wtop + $(window).height();
    var height = $(document).height();
    var i;
    // Awaken some elements?
    while(true) {
      for(i=0;i<elements.length;i++) {
        if(elements[i].hasClass('__awake')) { continue; }
        if(wbot>coords[i][0] && wtop<coords[i][1]) {
          awaken(elements[i]);
          break; // from the top
        }
      }
      break; // all done
    }
    // Send some to sleep?
    for(i=0;i<elements.length;i++) {
      if(coords[i][0] < miles_away/2 ||
         coords[i][1] > height - miles_away/2) {
        elements[i].removeClass('__miles_away');
      } else if(coords[i][0]-wtop > miles_away ||
                wbot-coords[i][1] > miles_away) {
        if(!elements[i].hasClass('__miles_away')) {
          elements[i].addClass('__miles_away');
          if(elements[i].hasClass('__awake')) {
            sleepen(elements[i]);
          }
        }
      } else {
        elements[i].removeClass('__miles_away');
      }
    }
  }

  function eager() {
    var i;
    refresh();
    check();
    var wtop = $(window).scrollTop();
    var wbot = wtop + $(window).height();
    var height = $(document).height();
    var targets = [null,null,null,null];
    for(i=0;i<elements.length;i++) {
      var prio = 3;
      if(coords[i][1] > height - miles_away/2) { prio = 2; }
      if(coords[i][0] < miles_away && !targets[1]) { prio = 1; }
      if(wbot>coords[i][0] && wtop<coords[i][1]) { prio = 0; }
      if(elements[i].hasClass('__awake')) { continue; }
      if(elements[i].hasClass('__miles_away')) { continue; }
      targets[prio] = elements[i];
    }
    for(i=0;i<targets.length;i++) {
      if(targets[i]) { awaken(targets[i]); break; }
    }
  }

  var check_soon = $.debounce(check,500);
  $(window).scroll(function() { check_soon(); });

  $.fn.lazy = function(arg) {
    this.each(function(i,el) {
      var $this = $(this);
      if(!$this.hasClass('__lazy')) {
        elements.push($this);
        refresh_element(elements.length-1,$this);
        $this.addClass('__lazy');
      } else {
        $this.removeClass('__awake');
      }
    });
  };

  var refresh_soon = $.debounce(refresh,500);
  $.lazy = function(arg,val) {
    if(arg == 'refresh') {
      refresh_soon();
    } else if(arg == 'periodic') {
      setInterval(function() { refresh_soon(); check_soon(); },5000);
    } else if(arg == 'eager') {
      eager();
    }
  };

})(jQuery);
<commit_msg>Less lazy laziness.<commit_after>/*
 * Copyright [1999-2014] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

(function($) {
  var elements = [];
  var coords = [];

  var wiggle = 10000;
  var miles_away = 100000;

  function still_alive(el) {
    var p = el.parents();
    if(!p.length) { return false; }
    if($(p[p.length-1]).prop("tagName") != "HTML") { return false; }
    return true;
  }

  function refresh_element(i,el) {
    var etop = el.offset().top;
    var ebot = etop +el.outerHeight(true);
    coords[i] = [etop-wiggle,ebot+wiggle];
  }

  function refresh() {
    for(var i=0;i<elements.length;i++) {
      refresh_element(i,elements[i]);
      if(!still_alive(elements[i])) {
        elements.splice(i,1);
        coords.splice(i,1);
        i--;
      }
    }
  }

  function awaken(el) {
    el.trigger('awaken');
    el.addClass('__awake');
    refresh();
  }

  function sleepen(el) {
    el.trigger('sleepen');
    el.removeClass('__awake');
    refresh();
  }

  function check() {
    var wtop = $(window).scrollTop();
    var wbot = wtop + $(window).height();
    var height = $(document).height();
    var i;
    // Awaken some elements?
    while(true) {
      for(i=0;i<elements.length;i++) {
        if(elements[i].hasClass('__awake')) { continue; }
        if(wbot>coords[i][0] && wtop<coords[i][1]) {
          awaken(elements[i]);
          break; // from the top
        }
      }
      break; // all done
    }
    // Send some to sleep?
    for(i=0;i<elements.length;i++) {
      if(coords[i][0] < miles_away/2 ||
         coords[i][1] > height - miles_away/2) {
        elements[i].removeClass('__miles_away');
      } else if(coords[i][0]-wtop > miles_away ||
                wbot-coords[i][1] > miles_away) {
        if(!elements[i].hasClass('__miles_away')) {
          elements[i].addClass('__miles_away');
          if(elements[i].hasClass('__awake')) {
            sleepen(elements[i]);
          }
        }
      } else {
        elements[i].removeClass('__miles_away');
      }
    }
  }

  function eager() {
    var i;
    refresh();
    check();
    var wtop = $(window).scrollTop();
    var wbot = wtop + $(window).height();
    var height = $(document).height();
    var targets = [null,null,null,null];
    for(i=0;i<elements.length;i++) {
      var prio = 3;
      if(coords[i][1] > height - miles_away/2) { prio = 2; }
      if(coords[i][0] < miles_away && !targets[1]) { prio = 1; }
      if(wbot>coords[i][0] && wtop<coords[i][1]) { prio = 0; }
      if(elements[i].hasClass('__awake')) { continue; }
      if(elements[i].hasClass('__miles_away')) { continue; }
      targets[prio] = elements[i];
    }
    for(i=0;i<targets.length;i++) {
      if(targets[i]) { awaken(targets[i]); break; }
    }
  }

  var check_soon = $.debounce(check,500);
  $(window).scroll(function() { check_soon(); });

  $.fn.lazy = function(arg) {
    this.each(function(i,el) {
      var $this = $(this);
      if(!$this.hasClass('__lazy')) {
        elements.push($this);
        refresh_element(elements.length-1,$this);
        $this.addClass('__lazy');
      } else {
        $this.removeClass('__awake');
      }
    });
  };

  var refresh_soon = $.debounce(refresh,500);
  $.lazy = function(arg,val) {
    if(arg == 'refresh') {
      refresh_soon();
    } else if(arg == 'periodic') {
      setInterval(function() { refresh_soon(); check_soon(); },5000);
    } else if(arg == 'eager') {
      eager();
    }
  };

})(jQuery);
<|endoftext|>


<commit_before>// Entity mixins

Game.Mixins = {};

//Movement

//Entity can move to unblocked squares
//Takes argument in absolute coordinates to current position
Game.Mixins.AbsMoveable = {
	name : 'AbsMoveable',
	groupName : 'Moveable',
	tryMove: function(x,y,map) {
		var tile = map.getTile(x,y);
		if (tile.isWalkable() && !this._map.getEntityAt(x,y)) {
			this._x = x;
			this._y = y;

			if (this._playercontrolled) {
				this._map.getEngine().unlock();
			}

			return true;
		}
		else { return false;}
	}
}

//Has balance statistic that governs whether various actions can be used
Game.Mixins.Balanced = {
	name : 'Balanced',
	groupName : 'Balanced',
	init : function(properties) {
		this._mbal = properties['mbal'] || 5; //Max balance
		this._cbal = properties['cbal'] || 5; //Current balance
	},
	getBalance : function() {
		return this._cbal;
	},
	setBalance : function(balance) {
		this._cbal = balance;
	},
	reduceBalance : function(reduction) {
		this._cbal = Math.max(0,this._cbal-reduction);
		if (this._cbal == 1) {
			Game.sendMessage(this, "Your intricate dance is getting your legs into quite a tangle");
		}
		if (this._cbal == 0) {
			Game.sendMessage(this, "You fall over");
		}
	},
	increaseBalance : function(increase) {
		this._cbal = Math.min(this._mbal,this._cbal+increase);
	}
}

//Coordinates are relative to current position and direction
//'Fpsmove' direction is relative to current directin
//'RogueMove' direction is absolute
Game.Mixins.DirectionMoveable = {
	name : 'DirectionMoveable',
	groupName : 'Moveable',
	init : function(properties) {
		var x = properties['x_dir'] || 1;
		var y = properties['y_dir'] || -1;

		this._direction = v2d(x,-y);
		this._olddirection = this._direction;
		this._chararray = properties['chararray'] || Game.Chars.SingleArrows;
		this._char = this._chararray[this._direction];
	},
	getChar : function() {
		return this._chararray[this._direction];
	},
	turn : function(x,y) {
		if (this.getBalance()) {
			this._direction = v2d(x,-y);
			return 1;
		} else {
			return 0;
		}
	},

	fpsMove : function(dx,dy,map) {

		if (dx == 0 && dy == 0) {
			this.increaseBalance(2);
			this._olddirection = this._direction;
			return true;
		}

		var movedir = v2d(dx,dy);
		var absdir = mod(this._direction-movedir,8);
		var movevec = d2v(absdir);
		var x = movevec[0]+this.getX();
		var y = movevec[1]+this.getY();
		var tile = map.getTile(x,y);
		var target = this._map.getEntityAt(x,y);

		if (tile.isWalkable() && (!target || target == this)) {

			this._olddirection = this._direction;

			if (!this.getBalance()) {
				Game.sendMessage(this,'You stand on shaking legs, steadying yourself to step once more.');
				this.setBalance(2);
				return true;
			} else {
				var bal_loss = Math.min(1,movedir);
				this.reduceBalance(bal_loss);
				this._x = x;
				this._y = y;
			}

		} else {
			return false;
		}
	},

	kbMove: function(dx,dy,noturn,map) {
		var x = this.getX() + dx;
		var y = this.getY() + dy;
		var tile = map.getTile(x,y);
		var target = this._map.getEntityAt(x,y);

		if (tile.isWalkable() && (!target || target == this)) {

			if (!this.getBalance()) {
				Game.sendMessage(this,'You stand on shaking legs, steadying yourself to step once more.');
				this.setBalance(2);
				return true;
			} else {

				this._x = x;
				this._y = y;
				if (!noturn) {
					this.turn(dx,dy);
				} else {
					var movedir = v2d(dx,dy);
					var absdir = mod(this._direction-movedir,8);
					var bal_loss = Math.min(1,absdir);
					this.reduceBalance(bal_loss);
			}
				return true;
			}
		} else { return false;}
	}
}

//Actor

//Player version of the Actor mixin
Game.Mixins.PlayerActor = {
	name : 'PlayerActor',
	groupName : 'Actor',
	act : function() {
		Game.refresh();
		this.getMap().getEngine().lock();
		console.log("Player moving");
	},
	getControl : function(ch) {
		return this.controls[ch];
	},
	setControls : function(controls) {
		this.controls = controls;
	}
}

//Combat

//Use attacking abilities
Game.Mixins.Attacker = {
	name : 'Attacker',
	init : function(properties) {
		this._dmg = properties['dmg'] || 1; //Attack damage
		var abilities = properties['abilities'] || [Game.Attacks.AttackForward];

		this._abilities = {};
		this._currentability = properties['currentability'] || ['Basic Attack'];
		for (var i=0; i<abilities.length; i++) {
			this.addAbility(abilities[i]);
		}
	},
	setDamage : function(damage) {
		this._dmg = damage;
	},
	getDamage : function() {
		if (this.getBalance() + 0.5 > Math.random()) {
			return this._dmg;
		} else {
			return 0;
		}
	},
	addAbility : function(ability) {
		this._abilities[ability.name] = ability;
	},
	hasAbility : function(obj) {
		if (typeof obj === 'object' && this._abilities[obj.name]) {
			return true;
		}
		else if (this._abilities[obj]) {
			return true;
		}
		else {
			return false;
		}
	},
	useCurrentAbility : function() {
		var ability = this._abilities[this._currentability];
		var targets = ability.getTargets(this);
		var hit = false;

		var damage = this.getDamage();
		var bal_damage = damage;
		if (damage) {
			var doMessage = ability.doHitMessage;
			var takeMessage = ability.takeHitMessage;
			var missMessage = ability.missMessage;
		} else {
			var doMessage = ability.doWeakHitMessage;
			var takeMessage = ability.takeWeakHitMessage;
			var missMessage = ability.weakMissMessage;
		}

		this.reduceBalance(ability.balance_cost);

		for (i=0; i<targets.length; i++) {
			target = this.getMap().getEntityAt(targets[i][0],targets[i][1]);
			if (target && target.hasMixin('Destructible')) {
				Game.sendMessage(this, doMessage, [target.getName()]);
				Game.sendMessage(target, takeMessage, [this.getName()]);
				target.takeDamage(damage);
				if (target.hasMixin('Balanced')) {
					target.reduceBalance(bal_damage);
				}
				hit = true;
				}
			}

		if (!hit) {
			Game.sendMessage(this, missMessage);
		}

	},
	readyNextAbility : function() {
		var abilities = Object.keys(this._abilities);
		var idx = abilities.indexOf(this._currentability);
		this._currentability = abilities[mod(idx+1,abilities.length)];
	},
}

//Take damage
Game.Mixins.Destructible = {
	name : 'Destructible',

	init : function(properties) {
		this._mhp = properties['mhp'] || 1; //Max hitpoints
		this._chp = properties['chp'] || this._mhp; //Current hitpoints
	},
	takeDamage : function(damage) {
		this._chp -= damage;
		if (this._chp <= 0) {
			this.die();
		}

	},
	die : function() {
		this.getMap().removeEntity(this);
	}
}

//Messaging

Game.Mixins.MessageRecipient = {
	name : "MessageRecipient",
	groupName : "MessageRecipient",

	init : function(properites) {
		this._messages = [];
	},
	receiveMessage : function(message) {
		this._messages.push(message);
	},
	getMessages : function() {
		return(this._messages);
	},
	clearMessages : function() {
		this._messages = [];
	}
}

//Previews

Game.Mixins.PreviewSpawner = {
	name : "PreviewSpawner",
	groupName : "PreviewSpawner",

	init : function() {
		this._previews = [];
	},
	spawnPreview : function(x,y,ch) {
		var prev = new Game.Entity(Game.PreviewTemplate);
		prev.setChar(ch);
		prev.setX(x);
		prev.setY(y);
		this.getMap().addEntity(prev);
		this._previews.push(prev);
	},
	clearPreviews : function() {
		for (var i=0; i<this._previews.length; i++) {
			this.getMap().removeEntity(this._previews[i]);
		}
		this._previews=[];
	},
	previewCurrentAbility : function() {
		var ability = this._abilities[this._currentability];
		var targets = ability.getTargets(this);
		for (var i=0; i<targets.length; i++) {
			var ent = this.getMap().getEntityAt(targets[i][0],targets[i][1]);
			if (ent) {
				var ch = ent.getChar();
				this.spawnPreview(targets[i][0],targets[i][1],ch);
			} else {
				this.spawnPreview(targets[i][0],targets[i][1],'.');
			}
		}
	}
}
<commit_msg>regain balance on forward move<commit_after>// Entity mixins

Game.Mixins = {};

//Movement

//Entity can move to unblocked squares
//Takes argument in absolute coordinates to current position
Game.Mixins.AbsMoveable = {
	name : 'AbsMoveable',
	groupName : 'Moveable',
	tryMove: function(x,y,map) {
		var tile = map.getTile(x,y);
		if (tile.isWalkable() && !this._map.getEntityAt(x,y)) {
			this._x = x;
			this._y = y;

			if (this._playercontrolled) {
				this._map.getEngine().unlock();
			}

			return true;
		}
		else { return false;}
	}
}

//Has balance statistic that governs whether various actions can be used
Game.Mixins.Balanced = {
	name : 'Balanced',
	groupName : 'Balanced',
	init : function(properties) {
		this._mbal = properties['mbal'] || 5; //Max balance
		this._cbal = properties['cbal'] || 5; //Current balance
	},
	getBalance : function() {
		return this._cbal;
	},
	setBalance : function(balance) {
		this._cbal = balance;
	},
	reduceBalance : function(reduction) {
		var bal = Math.max(0,this._cbal-reduction);
		this._cbal = Math.min(this._mbal, bal);
		if (this._cbal == 1) {
			Game.sendMessage(this, "Your intricate dance is getting your legs into quite a tangle");
		}
		if (this._cbal == 0) {
			Game.sendMessage(this, "You fall over");
		}
	},
	increaseBalance : function(increase) {
		var bal = Math.min(this._mbal,this._cbal+increase);
		this._cbal = Math.max(bal,0);
	}
}

//Coordinates are relative to current position and direction
//'Fpsmove' direction is relative to current directin
//'RogueMove' direction is absolute
Game.Mixins.DirectionMoveable = {
	name : 'DirectionMoveable',
	groupName : 'Moveable',
	init : function(properties) {
		var x = properties['x_dir'] || 1;
		var y = properties['y_dir'] || -1;

		this._direction = v2d(x,-y);
		this._olddirection = this._direction;
		this._chararray = properties['chararray'] || Game.Chars.SingleArrows;
		this._char = this._chararray[this._direction];
	},
	getChar : function() {
		return this._chararray[this._direction];
	},
	turn : function(x,y) {
		if (this.getBalance()) {
			this._direction = v2d(x,-y);
			return 1;
		} else {
			return 0;
		}
	},

	fpsMove : function(dx,dy,map) {

		if (dx == 0 && dy == 0) {
			this.increaseBalance(2);
			this._olddirection = this._direction;
			return true;
		}

		var movedir = v2d(dx,dy);
		var absdir = mod(this._direction-movedir,8);
		var movevec = d2v(absdir);
		var x = movevec[0]+this.getX();
		var y = movevec[1]+this.getY();
		var tile = map.getTile(x,y);
		var target = this._map.getEntityAt(x,y);

		if (tile.isWalkable() && (!target || target == this)) {

			this._olddirection = this._direction;

			if (!this.getBalance()) {
				Game.sendMessage(this,'You stand on shaking legs, steadying yourself to step once more.');
				this.setBalance(2);
				return true;
			} else {
				var bal_loss = Math.min(1,movedir-1);
				this.reduceBalance(bal_loss);
				this._x = x;
				this._y = y;
			}

		} else {
			return false;
		}
	},

	kbMove: function(dx,dy,noturn,map) {
		var x = this.getX() + dx;
		var y = this.getY() + dy;
		var tile = map.getTile(x,y);
		var target = this._map.getEntityAt(x,y);

		if (tile.isWalkable() && (!target || target == this)) {

			if (!this.getBalance()) {
				Game.sendMessage(this,'You stand on shaking legs, steadying yourself to step once more.');
				this.setBalance(2);
				return true;
			} else {

				this._x = x;
				this._y = y;
				if (!noturn) {
					this.turn(dx,dy);
				} else {
					var movedir = v2d(dx,dy);
					var absdir = mod(this._direction-movedir,8);
					var bal_loss = Math.min(1,absdir-1);
					this.reduceBalance(bal_loss);
			}
				return true;
			}
		} else { return false;}
	}
}

//Actor

//Player version of the Actor mixin
Game.Mixins.PlayerActor = {
	name : 'PlayerActor',
	groupName : 'Actor',
	act : function() {
		Game.refresh();
		this.getMap().getEngine().lock();
		console.log("Player moving");
	},
	getControl : function(ch) {
		return this.controls[ch];
	},
	setControls : function(controls) {
		this.controls = controls;
	}
}

//Combat

//Use attacking abilities
Game.Mixins.Attacker = {
	name : 'Attacker',
	init : function(properties) {
		this._dmg = properties['dmg'] || 1; //Attack damage
		var abilities = properties['abilities'] || [Game.Attacks.AttackForward];

		this._abilities = {};
		this._currentability = properties['currentability'] || ['Basic Attack'];
		for (var i=0; i<abilities.length; i++) {
			this.addAbility(abilities[i]);
		}
	},
	setDamage : function(damage) {
		this._dmg = damage;
	},
	getDamage : function() {
		if (this.getBalance() + 0.5 > Math.random()) {
			return this._dmg;
		} else {
			return 0;
		}
	},
	addAbility : function(ability) {
		this._abilities[ability.name] = ability;
	},
	hasAbility : function(obj) {
		if (typeof obj === 'object' && this._abilities[obj.name]) {
			return true;
		}
		else if (this._abilities[obj]) {
			return true;
		}
		else {
			return false;
		}
	},
	useCurrentAbility : function() {
		var ability = this._abilities[this._currentability];
		var targets = ability.getTargets(this);
		var hit = false;

		var damage = this.getDamage();
		var bal_damage = damage;
		if (damage) {
			var doMessage = ability.doHitMessage;
			var takeMessage = ability.takeHitMessage;
			var missMessage = ability.missMessage;
		} else {
			var doMessage = ability.doWeakHitMessage;
			var takeMessage = ability.takeWeakHitMessage;
			var missMessage = ability.weakMissMessage;
		}

		this.reduceBalance(ability.balance_cost);

		for (i=0; i<targets.length; i++) {
			target = this.getMap().getEntityAt(targets[i][0],targets[i][1]);
			if (target && target.hasMixin('Destructible')) {
				Game.sendMessage(this, doMessage, [target.getName()]);
				Game.sendMessage(target, takeMessage, [this.getName()]);
				target.takeDamage(damage);
				if (target.hasMixin('Balanced')) {
					target.reduceBalance(bal_damage);
				}
				hit = true;
				}
			}

		if (!hit) {
			Game.sendMessage(this, missMessage);
		}

	},
	readyNextAbility : function() {
		var abilities = Object.keys(this._abilities);
		var idx = abilities.indexOf(this._currentability);
		this._currentability = abilities[mod(idx+1,abilities.length)];
	},
}

//Take damage
Game.Mixins.Destructible = {
	name : 'Destructible',

	init : function(properties) {
		this._mhp = properties['mhp'] || 1; //Max hitpoints
		this._chp = properties['chp'] || this._mhp; //Current hitpoints
	},
	takeDamage : function(damage) {
		this._chp -= damage;
		if (this._chp <= 0) {
			this.die();
		}

	},
	die : function() {
		this.getMap().removeEntity(this);
	}
}

//Messaging

Game.Mixins.MessageRecipient = {
	name : "MessageRecipient",
	groupName : "MessageRecipient",

	init : function(properites) {
		this._messages = [];
	},
	receiveMessage : function(message) {
		this._messages.push(message);
	},
	getMessages : function() {
		return(this._messages);
	},
	clearMessages : function() {
		this._messages = [];
	}
}

//Previews

Game.Mixins.PreviewSpawner = {
	name : "PreviewSpawner",
	groupName : "PreviewSpawner",

	init : function() {
		this._previews = [];
	},
	spawnPreview : function(x,y,ch) {
		var prev = new Game.Entity(Game.PreviewTemplate);
		prev.setChar(ch);
		prev.setX(x);
		prev.setY(y);
		this.getMap().addEntity(prev);
		this._previews.push(prev);
	},
	clearPreviews : function() {
		for (var i=0; i<this._previews.length; i++) {
			this.getMap().removeEntity(this._previews[i]);
		}
		this._previews=[];
	},
	previewCurrentAbility : function() {
		var ability = this._abilities[this._currentability];
		var targets = ability.getTargets(this);
		for (var i=0; i<targets.length; i++) {
			var ent = this.getMap().getEntityAt(targets[i][0],targets[i][1]);
			if (ent) {
				var ch = ent.getChar();
				this.spawnPreview(targets[i][0],targets[i][1],ch);
			} else {
				this.spawnPreview(targets[i][0],targets[i][1],'.');
			}
		}
	}
}
<|endoftext|>