<commit_before>//Time Merger v1.3
window.ExternalScripts = true;
var Intervalstatistics = setInterval(CellTimer, 1000);

function CellTimer() {
    if (!window.legendmod5.optimizedMass && window.ExternalScripts) {
        myCells = [];
        for (var i = 0; i < window.legendmod.playerCells.length; i++) {
            //legendmod.cells[i].historyMass->window.playerCellsId[legendmod.cells[i].id].historyMass

            if (window.playerCellsId && window.legendmod.playerCells[i] && window.legendmod.playerCells[i].id && window.playerCellsId[legendmod.playerCells[i].id] &&
                window.playerCellsId[legendmod.playerCells[i].id].historyMass &&
                window.playerCellsId[legendmod.playerCells[i].id].historyMass[window.legendmod2.fps] > window.playerCellsId[legendmod.playerCells[i].id].historyMass[0] * 1.4) {
                var j = i;
                var x = 0;

                MergeCells(j, x);

            } else {
                if (window.playerCellsId && window.legendmod.playerCells[i] && window.legendmod.playerCells[i].id && window.playerCellsId[legendmod.playerCells[i].id] &&
                    window.playerCellsId[legendmod.playerCells[i].id].historyMass) {
                    window.playerCellsId[legendmod.playerCells[i].id].mergeTime = null;
                }
            }

        }
    }
}

function MergeCells(j, x) {
    x++;
    if (window.legendmod.playerCells.length > 1 && window.playerCellsId && window.legendmod.playerCells[j] && window.legendmod.playerCells[j].id && window.playerCellsId[legendmod.playerCells[j].id]) {
        window.playerCellsId[legendmod.playerCells[j].id].mergeTime = 29 + (7 / 300) * window.playerCellsId[legendmod.playerCells[j].id].historyMass[0] - x;
        //
        if (window.playerCellsId[legendmod.playerCells[j].id].mergeTime > 0) {
            setTimeout(function() {
                MergeCells(j, x);
				console.log(j,x, window.playerCellsId[legendmod.playerCells[j].id].historyMass[0]);
            }, 1000);
        }

    }
	else {
        window.playerCellsId[legendmod.playerCells[j].id].mergeTime = null;
    }
    return j, x;
}
<commit_msg>Update mergetimer.js<commit_after>//Time Merger v1.4
window.ExternalScripts = true;
var Intervalstatistics = setInterval(CellTimer, 1000);

function CellTimer() {
    if (!window.legendmod5.optimizedMass && window.ExternalScripts) {
        myCells = [];
        for (var i = 0; i < window.legendmod.playerCells.length; i++) {
            //legendmod.cells[i].historyMass->window.playerCellsId[legendmod.cells[i].id].historyMass

            if (window.playerCellsId && window.legendmod.playerCells[i] && window.legendmod.playerCells[i].id && window.playerCellsId[legendmod.playerCells[i].id] &&
                window.playerCellsId[legendmod.playerCells[i].id].historyMass &&
                window.playerCellsId[legendmod.playerCells[i].id].historyMass[window.legendmod2.fps] > window.playerCellsId[legendmod.playerCells[i].id].historyMass[0] * 1.2) {
					console.log("Mass Merge Timer started with mass" + window.playerCellsId[legendmod.playerCells[i].id].historyMass[window.legendmod2.fps]);
                var j = i;
                var x = 0;

                MergeCells(j, x);

            } else {
                if (window.playerCellsId && window.legendmod.playerCells[i] && window.legendmod.playerCells[i].id && window.playerCellsId[legendmod.playerCells[i].id] &&
                    window.playerCellsId[legendmod.playerCells[i].id].historyMass) {
                    window.playerCellsId[legendmod.playerCells[i].id].mergeTime = null;
                }
            }

        }
    }
}

function MergeCells(j, x) {
    x++;
    if (window.legendmod.playerCells.length > 1 && window.playerCellsId && window.legendmod.playerCells[j] && window.legendmod.playerCells[j].id && window.playerCellsId[legendmod.playerCells[j].id]) {
        window.playerCellsId[legendmod.playerCells[j].id].mergeTime = 29 + (7 / 300) * window.playerCellsId[legendmod.playerCells[j].id].historyMass[0] - x;
        //
        if (window.playerCellsId[legendmod.playerCells[j].id].mergeTime > 0) {
            setTimeout(function() {
                MergeCells(j, x);
				console.log(j,x, window.playerCellsId[legendmod.playerCells[j].id].historyMass[0]);
            }, 1000);
        }

    }
	else {
        window.playerCellsId[legendmod.playerCells[j].id].mergeTime = null;
    }
    return j, x;
}
<|endoftext|>


<commit_before>/* Threaded ticket comments
   ========================

   See the #prefs form in ticket.html.

   We have three mutually exclusive orders, 'newest' first, 'oldest'
   first and 'threaded'.  In addition, changes without comments can be
   filtered out.

   When switching to 'threaded', the changes without comments must be
   shown again as they can also have a follow-up. After appending
   eventual children, they must be hidden again and `:has(.comment)`
   will now take into account the threaded comments in
   children. Likewise, when switching away from 'threaded' to a linear
   order, the changes without comments need to be hidden again.
 */
jQuery(document).ready(function($){
  var comments = null;
  var order = null;
  var form = $("#prefs");

  var commentsOnly = $("#trac-comments-only-toggle");
  var applyCommentsOnly = function() {
    if (commentsOnly.attr('checked')) {
      $("div.change ul.changes").hide();
      $("div.change:not(:has(.comment))").hide();
    } else {
      $("div.change ul.changes").show();
      $("div.change:not(:has(.comment))").show();
    }
  };

  var applyOrder = function() {
    var commentsOnlyChecked = commentsOnly.attr('checked');
    if (commentsOnlyChecked) {
      commentsOnly.attr("checked", false);
      applyCommentsOnly();
    }
    order = $("input[name='trac-comments-order']:checked").val();
    if (order == 'newest') {
      $("#changelog").append($("div.change").get().reverse());
    } else if (order == 'threaded') {
      comments = $("div.change");
      comments.each(function() {
        var children = $("a.follow-up", this).map(function() {
          var cnum = $(this).attr("href").replace('#comment:', '');
          return $('[id^="trac-change-' + cnum + '-"]').get(0);
        });
        if (children.length) {
          var ul = $('

').appendTo(this);
          children.appendTo(ul).wrap('
');
        }
      });
    }
    if (commentsOnlyChecked) {
      commentsOnly.attr("checked", true);
      applyCommentsOnly();
    }
  };
  var unapplyOrder = function() {
    if (order == 'newest') {
      $("#changelog").append($("div.change").get().reverse());
    } else if (order == 'threaded') {
      if (comments) {
        $("#changelog").append(comments);
        $("#changelog ul.children").remove();
      }
    }
  };

  if ($("a.follow-up").length)
    $('#trac-threaded-toggle').show();
  else if (comments_prefs.comments_order == 'threaded')
    comments_prefs.comments_order = 'oldest'

  $("input[name='trac-comments-order']")
    .filter("[value=" + comments_prefs.comments_order + "]")
    .attr('checked', 'checked');
  applyOrder();
  $("input[name='trac-comments-order']").change(function() {
    unapplyOrder();
    applyOrder();
    $.ajax({ url: form.attr('action'), type: 'POST', data: {
      save_prefs: true,
      ticket_comments_order: order,
      __FORM_TOKEN: form_token,
    }, dataType: 'text' });
  });

  commentsOnly.attr('checked', comments_prefs.comments_only != 'false');
  applyCommentsOnly();
  commentsOnly.click(function() {
    applyCommentsOnly();
    $.ajax({ url: form.attr('action'), type: 'POST', data: {
      save_prefs: true,
      ticket_comments_only: commentsOnly.attr('checked'),
      __FORM_TOKEN: form_token,
    }, dataType: 'text' });
  });
});
<commit_msg>1.0dev: fix saving //Comments only// pref in ticket view.<commit_after>/* Threaded ticket comments
   ========================

   See the #prefs form in ticket.html.

   We have three mutually exclusive orders, 'newest' first, 'oldest'
   first and 'threaded'.  In addition, changes without comments can be
   filtered out.

   When switching to 'threaded', the changes without comments must be
   shown again as they can also have a follow-up. After appending
   eventual children, they must be hidden again and `:has(.comment)`
   will now take into account the threaded comments in
   children. Likewise, when switching away from 'threaded' to a linear
   order, the changes without comments need to be hidden again.
 */
jQuery(document).ready(function($){
  var comments = null;
  var order = null;
  var form = $("#prefs");

  var commentsOnly = $("#trac-comments-only-toggle");
  var applyCommentsOnly = function() {
    if (commentsOnly.attr('checked')) {
      $("div.change ul.changes").hide();
      $("div.change:not(:has(.comment))").hide();
    } else {
      $("div.change ul.changes").show();
      $("div.change:not(:has(.comment))").show();
    }
  };

  var applyOrder = function() {
    var commentsOnlyChecked = commentsOnly.attr('checked');
    if (commentsOnlyChecked) {
      commentsOnly.attr("checked", false);
      applyCommentsOnly();
    }
    order = $("input[name='trac-comments-order']:checked").val();
    if (order == 'newest') {
      $("#changelog").append($("div.change").get().reverse());
    } else if (order == 'threaded') {
      comments = $("div.change");
      comments.each(function() {
        var children = $("a.follow-up", this).map(function() {
          var cnum = $(this).attr("href").replace('#comment:', '');
          return $('[id^="trac-change-' + cnum + '-"]').get(0);
        });
        if (children.length) {
          var ul = $('

').appendTo(this);
          children.appendTo(ul).wrap('
');
        }
      });
    }
    if (commentsOnlyChecked) {
      commentsOnly.attr("checked", true);
      applyCommentsOnly();
    }
  };
  var unapplyOrder = function() {
    if (order == 'newest') {
      $("#changelog").append($("div.change").get().reverse());
    } else if (order == 'threaded') {
      if (comments) {
        $("#changelog").append(comments);
        $("#changelog ul.children").remove();
      }
    }
  };

  if ($("a.follow-up").length)
    $('#trac-threaded-toggle').show();
  else if (comments_prefs.comments_order == 'threaded')
    comments_prefs.comments_order = 'oldest'

  $("input[name='trac-comments-order']")
    .filter("[value=" + comments_prefs.comments_order + "]")
    .attr('checked', 'checked');
  applyOrder();
  $("input[name='trac-comments-order']").change(function() {
    unapplyOrder();
    applyOrder();
    $.ajax({ url: form.attr('action'), type: 'POST', data: {
      save_prefs: true,
      ticket_comments_order: order,
      __FORM_TOKEN: form_token,
    }, dataType: 'text' });
  });

  commentsOnly.attr('checked', comments_prefs.comments_only != 'false');
  applyCommentsOnly();
  commentsOnly.click(function() {
    applyCommentsOnly();
    $.ajax({ url: form.attr('action'), type: 'POST', data: {
      save_prefs: true,
      ticket_comments_only: !!commentsOnly.attr('checked'),
      __FORM_TOKEN: form_token,
    }, dataType: 'text' });
  });
});
<|endoftext|>


<commit_before>/* global Module */

/* Magic Mirror
 * Module: Calendar
 *
 * By Michael Teeuw http://michaelteeuw.nl
 * MIT Licensed.
 */

Module.register("calendar",{

	// Define module defaults
	defaults: {
		maximumEntries: 10, // Total Maximum Entries
		maximumNumberOfDays: 365,
		displaySymbol: true,
		defaultSymbol: "calendar", // Fontawesome Symbol see http://fontawesome.io/cheatsheet/
		displayRepeatingCountTitle: false,
		defaultRepeatingCountTitle: '',
		maxTitleLength: 25,
		fetchInterval: 5 * 60 * 1000, // Update every 5 minutes.
		animationSpeed: 2000,
		fade: true,
		urgency: 7,
		timeFormat: "relative",
		getRelative: '6',
		fadePoint: 0.25, // Start on 1/4th of the list.
		calendars: [
			{
				symbol: "calendar",
				url: "http://www.calendarlabs.com/templates/ical/US-Holidays.ics",
			},
		],
		titleReplace: {
			"De verjaardag van ": "",
			"'s birthday": ""
		},
	},

	// Define required scripts.
	getStyles: function() {
		return ["calendar.css", "font-awesome.css"];
	},

	// Define required scripts.
	getScripts: function() {
		return ["moment.js"];
	},

	// Define required translations.
	getTranslations: function() {
		// The translations for the defaut modules are defined in the core translation files.
		// Therefor we can just return false. Otherwise we should have returned a dictionairy.
		// If you're trying to build your own module including translations, check out the documentation.
		return false;
	},

	// Override start method.
	start: function() {
		Log.log("Starting module: " + this.name);

		// Set locale.
		moment.locale(config.language);

		for (var c in this.config.calendars) {
			var calendar = this.config.calendars[c];
			calendar.url = calendar.url.replace("webcal://", "http://");
			this.addCalendar(calendar.url);
		}

		this.calendarData = {};
		this.loaded = false;
	},

	// Override socket notification handler.
	socketNotificationReceived: function(notification, payload) {
		if (notification === "CALENDAR_EVENTS") {
			if (this.hasCalendarURL(payload.url)) {
				this.calendarData[payload.url] = payload.events;
				this.loaded = true;
			}
		} else if (notification === "FETCH_ERROR") {
			Log.error("Calendar Error. Could not fetch calendar: " + payload.url);
		} else if (notification === "INCORRECT_URL") {
			Log.error("Calendar Error. Incorrect url: " + payload.url);
		} else {
			Log.log("Calendar received an unknown socket notification: " + notification);
		}

		this.updateDom(this.config.animationSpeed);
	},

	// Override dom generator.
	getDom: function() {

		var events = this.createEventList();
		var wrapper = document.createElement("table");
		wrapper.className = "small";

		if (events.length === 0) {
			wrapper.innerHTML = (this.loaded) ? this.translate("EMPTY") : this.translate("LOADING");
			wrapper.className = "small dimmed";
			return wrapper;
		}

		for (var e in events) {
			var event = events[e];

			var eventWrapper = document.createElement("tr");
			eventWrapper.className = "normal";

			if (this.config.displaySymbol) {
				var symbolWrapper =  document.createElement("td");
				symbolWrapper.className = "symbol";
				var symbol =  document.createElement("span");
				symbol.className = "fa fa-" + this.symbolForUrl(event.url);
				symbolWrapper.appendChild(symbol);
				eventWrapper.appendChild(symbolWrapper);
			}

			var titleWrapper = document.createElement("td"),
				repeatingCountTitle = '';

			if (this.config.displayRepeatingCountTitle) {

				repeatingCountTitle = this.countTitleForUrl(event.url);

				if(repeatingCountTitle !== '') {
					var thisYear = new Date().getFullYear(),
						yearDiff = thisYear - event.firstYear;

					repeatingCountTitle = ', '+ yearDiff + '. ' + repeatingCountTitle;
				}
			}

			titleWrapper.innerHTML = this.titleTransform(event.title) + repeatingCountTitle;
			titleWrapper.className = "title bright";
			eventWrapper.appendChild(titleWrapper);

			var timeWrapper =  document.createElement("td");
			//console.log(event.today);
			var now = new Date();
			// Define second, minute, hour, and day variables
			var one_second = 1000; // 1,000 milliseconds
			var one_minute = one_second * 60;
			var one_hour = one_minute * 60;
			var one_day = one_hour * 24;
			if (event.fullDayEvent) {
				if (event.today) {
					timeWrapper.innerHTML = this.capFirst(this.translate("TODAY"));
				} else if (event.startDate - now < one_day && event.startDate - now > 0) {
					timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW"));
				} else if (event.startDate - now < 2*one_day && event.startDate - now > 0) {
					if (this.translate('DAYAFTERTOMORROW') !== 'DAYAFTERTOMORROW') {
					timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW"));
					} else {
					timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
					}
				} else {
					/* Check to see if the user displays absolute or relative dates with their events
					 * Also check to see if an event is happening within an 'urgency' time frameElement
					 * For example, if the user set an .urgency of 7 days, those events that fall within that
					 * time frame will be displayed with 'in xxx' time format or moment.fromNow()
					 *
					 * Note: this needs to be put in its own function, as the whole thing repeats again verbatim
					 */
					if (this.config.timeFormat === "absolute") {
						if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * one_day))) {
							// This event falls within the config.urgency period that the user has set
							timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
						} else {
							timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format("MMM Do"));
						}
					} else {
						timeWrapper.innerHTML =  this.capFirst(moment(event.startDate, "x").fromNow());
					}
				}
			} else {
				if (event.startDate >= new Date()) {
					if (event.startDate - now < 2 * one_day) {
						// This event is within the next 48 hours (2 days)
						if (event.startDate - now < this.config.getRelative * one_hour) {
							// If event is within 6 hour, display 'in xxx' time format or moment.fromNow()
							timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
						} else {
							// Otherwise just say 'Today/Tomorrow at such-n-such time'
							timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").calendar());
						}
					} else {
						/* Check to see if the user displays absolute or relative dates with their events
						 * Also check to see if an event is happening within an 'urgency' time frameElement
						 * For example, if the user set an .urgency of 7 days, those events that fall within that
						 * time frame will be displayed with 'in xxx' time format or moment.fromNow()
						 *
						 * Note: this needs to be put in its own function, as the whole thing repeats again verbatim
						 */
						if (this.config.timeFormat === "absolute") {
							if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * one_day))) {
								// This event falls within the config.urgency period that the user has set
								timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
							} else {
								timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format("MMM Do"));
							}
						} else {
							timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
						}
					}
				} else {
					timeWrapper.innerHTML =  this.capFirst(this.translate("RUNNING")) + ' ' + this.capFirst(moment(event.endDate,"x").fromNow(true));
				}
			}
			//timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll');
			//console.log(event);
			timeWrapper.className = "time light";
			eventWrapper.appendChild(timeWrapper);

			wrapper.appendChild(eventWrapper);

			// Create fade effect.
			if (this.config.fade && this.config.fadePoint < 1) {
				if (this.config.fadePoint < 0) {
					this.config.fadePoint = 0;
				}
				var startingPoint = events.length * this.config.fadePoint;
				var steps = events.length - startingPoint;
				if (e >= startingPoint) {
					var currentStep = e - startingPoint;
					eventWrapper.style.opacity = 1 - (1 / steps * currentStep);
				}
			}
		}

		return wrapper;
	},

	/* hasCalendarURL(url)
	 * Check if this config contains the calendar url.
	 *
	 * argument url sting - Url to look for.
	 *
	 * return bool - Has calendar url
	 */
	hasCalendarURL: function(url) {
		for (var c in this.config.calendars) {
			var calendar = this.config.calendars[c];
			if (calendar.url === url) {
				return true;
			}
		}

		return false;
	},

	/* createEventList()
	 * Creates the sorted list of all events.
	 *
	 * return array - Array with events.
	 */
	createEventList: function() {
		var events = [];
		var today = moment().startOf("day");
		for (var c in this.calendarData) {
			var calendar = this.calendarData[c];
			for (var e in calendar) {
				var event = calendar[e];
				event.url = c;
				event.today = event.startDate >= today && event.startDate < (today + 24 * 60 * 60 * 1000);
				events.push(event);
			}
		}

		events.sort(function(a, b) {
			return a.startDate - b.startDate;
		});

		return events.slice(0, this.config.maximumEntries);
	},

	/* createEventList(url)
	 * Requests node helper to add calendar url.
	 *
	 * argument url sting - Url to add.
	 */
	addCalendar: function(url) {
		this.sendSocketNotification("ADD_CALENDAR", {
			url: url,
			maximumEntries: this.config.maximumEntries,
			maximumNumberOfDays: this.config.maximumNumberOfDays,
			fetchInterval: this.config.fetchInterval
		});
	},

	/* symbolForUrl(url)
	 * Retrieves the symbol for a specific url.
	 *
	 * argument url sting - Url to look for.
	 *
	 * return string - The Symbol
	 */
	symbolForUrl: function(url) {
		for (var c in this.config.calendars) {
			var calendar = this.config.calendars[c];
			if (calendar.url === url && typeof calendar.symbol === "string")  {
				return calendar.symbol;
			}
		}

		return this.config.defaultSymbol;
	},
	/* countTitleForUrl(url)
	 * Retrieves the name for a specific url.
	 *
	 * argument url sting - Url to look for.
	 *
	 * return string - The Symbol
	 */
	countTitleForUrl: function(url) {
		for (var c in this.config.calendars) {
			var calendar = this.config.calendars[c];
			if (calendar.url === url && typeof calendar.repeatingCountTitle === "string")  {
				return calendar.repeatingCountTitle;
			}
		}

		return this.config.defaultRepeatingCountTitle;
	},

	/* shorten(string, maxLength)
	 * Shortens a sting if it's longer than maxLenthg.
	 * Adds an ellipsis to the end.
	 *
	 * argument string string - The string to shorten.
	 * argument maxLength number - The max lenth of the string.
	 *
	 * return string - The shortened string.
	 */
	shorten: function(string, maxLength) {
		if (string.length > maxLength) {
			return string.slice(0,maxLength) + "…";
		}

		return string;
	},

	/* capFirst(string)
	 * Capitalize the first letter of a string
	 * Eeturn capitalized string
	 */

	capFirst: function(string) {
		return string.charAt(0).toUpperCase() + string.slice(1);
	},

	/* titleTransform(title)
	 * Transforms the title of an event for usage.
	 * Replaces parts of the text as defined in config.titleReplace.
	 * Shortens title based on config.maxTitleLength
	 *
	 * argument title string - The title to transform.
	 *
	 * return string - The transformed title.
	 */
	titleTransform: function(title) {
		for (var needle in this.config.titleReplace) {
			var replacement = this.config.titleReplace[needle];
			title = title.replace(needle, replacement);
		}

		title = this.shorten(title, this.config.maxTitleLength);
		return title;
	}
});
<commit_msg>Added 'getRelative' tag<commit_after>/* global Module */

/* Magic Mirror
 * Module: Calendar
 *
 * By Michael Teeuw http://michaelteeuw.nl
 * MIT Licensed.
 */

Module.register("calendar",{

	// Define module defaults
	defaults: {
		maximumEntries: 10, // Total Maximum Entries
		maximumNumberOfDays: 365,
		displaySymbol: true,
		defaultSymbol: "calendar", // Fontawesome Symbol see http://fontawesome.io/cheatsheet/
		displayRepeatingCountTitle: false,
		defaultRepeatingCountTitle: '',
		maxTitleLength: 25,
		fetchInterval: 5 * 60 * 1000, // Update every 5 minutes.
		animationSpeed: 2000,
		fade: true,
		urgency: 7,
		timeFormat: "relative",
		getRelative: 6,
		fadePoint: 0.25, // Start on 1/4th of the list.
		calendars: [
			{
				symbol: "calendar",
				url: "http://www.calendarlabs.com/templates/ical/US-Holidays.ics",
			},
		],
		titleReplace: {
			"De verjaardag van ": "",
			"'s birthday": ""
		},
	},

	// Define required scripts.
	getStyles: function() {
		return ["calendar.css", "font-awesome.css"];
	},

	// Define required scripts.
	getScripts: function() {
		return ["moment.js"];
	},

	// Define required translations.
	getTranslations: function() {
		// The translations for the defaut modules are defined in the core translation files.
		// Therefor we can just return false. Otherwise we should have returned a dictionairy.
		// If you're trying to build your own module including translations, check out the documentation.
		return false;
	},

	// Override start method.
	start: function() {
		Log.log("Starting module: " + this.name);

		// Set locale.
		moment.locale(config.language);

		for (var c in this.config.calendars) {
			var calendar = this.config.calendars[c];
			calendar.url = calendar.url.replace("webcal://", "http://");
			this.addCalendar(calendar.url);
		}

		this.calendarData = {};
		this.loaded = false;
	},

	// Override socket notification handler.
	socketNotificationReceived: function(notification, payload) {
		if (notification === "CALENDAR_EVENTS") {
			if (this.hasCalendarURL(payload.url)) {
				this.calendarData[payload.url] = payload.events;
				this.loaded = true;
			}
		} else if (notification === "FETCH_ERROR") {
			Log.error("Calendar Error. Could not fetch calendar: " + payload.url);
		} else if (notification === "INCORRECT_URL") {
			Log.error("Calendar Error. Incorrect url: " + payload.url);
		} else {
			Log.log("Calendar received an unknown socket notification: " + notification);
		}

		this.updateDom(this.config.animationSpeed);
	},

	// Override dom generator.
	getDom: function() {

		var events = this.createEventList();
		var wrapper = document.createElement("table");
		wrapper.className = "small";

		if (events.length === 0) {
			wrapper.innerHTML = (this.loaded) ? this.translate("EMPTY") : this.translate("LOADING");
			wrapper.className = "small dimmed";
			return wrapper;
		}

		for (var e in events) {
			var event = events[e];

			var eventWrapper = document.createElement("tr");
			eventWrapper.className = "normal";

			if (this.config.displaySymbol) {
				var symbolWrapper =  document.createElement("td");
				symbolWrapper.className = "symbol";
				var symbol =  document.createElement("span");
				symbol.className = "fa fa-" + this.symbolForUrl(event.url);
				symbolWrapper.appendChild(symbol);
				eventWrapper.appendChild(symbolWrapper);
			}

			var titleWrapper = document.createElement("td"),
				repeatingCountTitle = '';

			if (this.config.displayRepeatingCountTitle) {

				repeatingCountTitle = this.countTitleForUrl(event.url);

				if(repeatingCountTitle !== '') {
					var thisYear = new Date().getFullYear(),
						yearDiff = thisYear - event.firstYear;

					repeatingCountTitle = ', '+ yearDiff + '. ' + repeatingCountTitle;
				}
			}

			titleWrapper.innerHTML = this.titleTransform(event.title) + repeatingCountTitle;
			titleWrapper.className = "title bright";
			eventWrapper.appendChild(titleWrapper);

			var timeWrapper =  document.createElement("td");
			//console.log(event.today);
			var now = new Date();
			// Define second, minute, hour, and day variables
			var one_second = 1000; // 1,000 milliseconds
			var one_minute = one_second * 60;
			var one_hour = one_minute * 60;
			var one_day = one_hour * 24;
			if (event.fullDayEvent) {
				if (event.today) {
					timeWrapper.innerHTML = this.capFirst(this.translate("TODAY"));
				} else if (event.startDate - now < one_day && event.startDate - now > 0) {
					timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW"));
				} else if (event.startDate - now < 2*one_day && event.startDate - now > 0) {
					if (this.translate('DAYAFTERTOMORROW') !== 'DAYAFTERTOMORROW') {
					timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW"));
					} else {
					timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
					}
				} else {
					/* Check to see if the user displays absolute or relative dates with their events
					 * Also check to see if an event is happening within an 'urgency' time frameElement
					 * For example, if the user set an .urgency of 7 days, those events that fall within that
					 * time frame will be displayed with 'in xxx' time format or moment.fromNow()
					 *
					 * Note: this needs to be put in its own function, as the whole thing repeats again verbatim
					 */
					if (this.config.timeFormat === "absolute") {
						if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * one_day))) {
							// This event falls within the config.urgency period that the user has set
							timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
						} else {
							timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format("MMM Do"));
						}
					} else {
						timeWrapper.innerHTML =  this.capFirst(moment(event.startDate, "x").fromNow());
					}
				}
			} else {
				if (event.startDate >= new Date()) {
					if (event.startDate - now < 2 * one_day) {
						// This event is within the next 48 hours (2 days)
						if (event.startDate - now < this.config.getRelative * one_hour) {
							// If event is within 6 hour, display 'in xxx' time format or moment.fromNow()
							timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
						} else {
							// Otherwise just say 'Today/Tomorrow at such-n-such time'
							timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").calendar());
						}
					} else {
						/* Check to see if the user displays absolute or relative dates with their events
						 * Also check to see if an event is happening within an 'urgency' time frameElement
						 * For example, if the user set an .urgency of 7 days, those events that fall within that
						 * time frame will be displayed with 'in xxx' time format or moment.fromNow()
						 *
						 * Note: this needs to be put in its own function, as the whole thing repeats again verbatim
						 */
						if (this.config.timeFormat === "absolute") {
							if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * one_day))) {
								// This event falls within the config.urgency period that the user has set
								timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
							} else {
								timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format("MMM Do"));
							}
						} else {
							timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow());
						}
					}
				} else {
					timeWrapper.innerHTML =  this.capFirst(this.translate("RUNNING")) + ' ' + this.capFirst(moment(event.endDate,"x").fromNow(true));
				}
			}
			//timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll');
			//console.log(event);
			timeWrapper.className = "time light";
			eventWrapper.appendChild(timeWrapper);

			wrapper.appendChild(eventWrapper);

			// Create fade effect.
			if (this.config.fade && this.config.fadePoint < 1) {
				if (this.config.fadePoint < 0) {
					this.config.fadePoint = 0;
				}
				var startingPoint = events.length * this.config.fadePoint;
				var steps = events.length - startingPoint;
				if (e >= startingPoint) {
					var currentStep = e - startingPoint;
					eventWrapper.style.opacity = 1 - (1 / steps * currentStep);
				}
			}
		}

		return wrapper;
	},

	/* hasCalendarURL(url)
	 * Check if this config contains the calendar url.
	 *
	 * argument url sting - Url to look for.
	 *
	 * return bool - Has calendar url
	 */
	hasCalendarURL: function(url) {
		for (var c in this.config.calendars) {
			var calendar = this.config.calendars[c];
			if (calendar.url === url) {
				return true;
			}
		}

		return false;
	},

	/* createEventList()
	 * Creates the sorted list of all events.
	 *
	 * return array - Array with events.
	 */
	createEventList: function() {
		var events = [];
		var today = moment().startOf("day");
		for (var c in this.calendarData) {
			var calendar = this.calendarData[c];
			for (var e in calendar) {
				var event = calendar[e];
				event.url = c;
				event.today = event.startDate >= today && event.startDate < (today + 24 * 60 * 60 * 1000);
				events.push(event);
			}
		}

		events.sort(function(a, b) {
			return a.startDate - b.startDate;
		});

		return events.slice(0, this.config.maximumEntries);
	},

	/* createEventList(url)
	 * Requests node helper to add calendar url.
	 *
	 * argument url sting - Url to add.
	 */
	addCalendar: function(url) {
		this.sendSocketNotification("ADD_CALENDAR", {
			url: url,
			maximumEntries: this.config.maximumEntries,
			maximumNumberOfDays: this.config.maximumNumberOfDays,
			fetchInterval: this.config.fetchInterval
		});
	},

	/* symbolForUrl(url)
	 * Retrieves the symbol for a specific url.
	 *
	 * argument url sting - Url to look for.
	 *
	 * return string - The Symbol
	 */
	symbolForUrl: function(url) {
		for (var c in this.config.calendars) {
			var calendar = this.config.calendars[c];
			if (calendar.url === url && typeof calendar.symbol === "string")  {
				return calendar.symbol;
			}
		}

		return this.config.defaultSymbol;
	},
	/* countTitleForUrl(url)
	 * Retrieves the name for a specific url.
	 *
	 * argument url sting - Url to look for.
	 *
	 * return string - The Symbol
	 */
	countTitleForUrl: function(url) {
		for (var c in this.config.calendars) {
			var calendar = this.config.calendars[c];
			if (calendar.url === url && typeof calendar.repeatingCountTitle === "string")  {
				return calendar.repeatingCountTitle;
			}
		}

		return this.config.defaultRepeatingCountTitle;
	},

	/* shorten(string, maxLength)
	 * Shortens a sting if it's longer than maxLenthg.
	 * Adds an ellipsis to the end.
	 *
	 * argument string string - The string to shorten.
	 * argument maxLength number - The max lenth of the string.
	 *
	 * return string - The shortened string.
	 */
	shorten: function(string, maxLength) {
		if (string.length > maxLength) {
			return string.slice(0,maxLength) + "…";
		}

		return string;
	},

	/* capFirst(string)
	 * Capitalize the first letter of a string
	 * Eeturn capitalized string
	 */

	capFirst: function(string) {
		return string.charAt(0).toUpperCase() + string.slice(1);
	},

	/* titleTransform(title)
	 * Transforms the title of an event for usage.
	 * Replaces parts of the text as defined in config.titleReplace.
	 * Shortens title based on config.maxTitleLength
	 *
	 * argument title string - The title to transform.
	 *
	 * return string - The transformed title.
	 */
	titleTransform: function(title) {
		for (var needle in this.config.titleReplace) {
			var replacement = this.config.titleReplace[needle];
			title = title.replace(needle, replacement);
		}

		title = this.shorten(title, this.config.maxTitleLength);
		return title;
	}
});
<|endoftext|>


<commit_before><commit_msg>Update ogario2.v4.js<commit_after><|endoftext|>


<commit_before>describe('uiJq', function () {
  var scope, compile;
  scope = null;
  beforeEach(module('ui.directives'));
  beforeEach(function () {
    jQuery.fn.foo = function () {};
    module(function ($provide) {
      $provide.value('ui.config', {
        jq: {foo: {}}
      });
    });
  });
  beforeEach(inject(function ($rootScope, $compile) {
    scope = $rootScope.$new();
    compile = $compile;
  }));
  describe('function or plugin isn\'t found', function () {
    it('should throw an error', function () {
      expect(function () {
        compile("

")(scope);
      }).toThrow();
    });
  });
  describe('calling a jQuery element function', function () {
    it('should just like, sort of work and junk', function () {
      spyOn(jQuery.fn, 'foo');
      compile("

")(scope);
      waits(100);
      runs(function(){
        expect(jQuery.fn.foo).toHaveBeenCalled();
      });
    });
    it('should fire after the view has rendered', function() {
      var length;
      jQuery.fn.bar = function() {
        length = $(this).children().length;
        console.log(length);
      };
      scope.$apply('items=[1, 2]');
      compile("

")(scope);
      waits(100);
      runs(function(){
        expect(length).toBe(2);
      });
    });
  });
  describe('calling a jQuery element function with options', function() {
    it('should not copy options.pizza to global', function() {
      spyOn(jQuery.fn, 'foo');
      compile('

')(scope);
      expect(jQuery.fn.foo.calls[0].args).toEqual([{pizza: true}]);
      expect(jQuery.fn.foo.calls[1].args).toEqual([{}]);
    });
  });
  describe('using ui-refresh', function() {
    it('should execute exactly once if the expression is never set', function() {
      spyOn(jQuery.fn, 'foo');
      compile('

')(scope);
      expect(jQuery.fn.foo.callCount).toBe(1);
    });
    it('should execute exactly once if the expression is set at initialization', function() {
      spyOn(jQuery.fn, 'foo');
      scope.$apply('bar = true');
      compile('

')(scope);
      expect(jQuery.fn.foo.callCount).toBe(1);
    });
    it('should execute once for each time the expression changes', function() {
      spyOn(jQuery.fn, 'foo');
      scope.$apply('bar = 1');
      compile('

')(scope);
      expect(jQuery.fn.foo.callCount).toBe(1);
      scope.$apply('bar = bar+1');
      expect(jQuery.fn.foo.callCount).toBe(2);
      scope.$apply('bar = bar+1');
      expect(jQuery.fn.foo.callCount).toBe(3);
    });
  });
  describe('change events', function() {
    it('should trigger an `input` event', function() {
      var bar = false;
      var element = compile('<input ui-jq="foo" ng-model="foobar">')(scope);
      element.bind('input', function(){
        bar = true;
      });
      element.trigger('change');
      expect(bar).toBe(true);
    });
    it('should ignore controls without ngModel attribute', function() {
      var bar = false;
      var element = compile('<input ui-jq="foo">')(scope);
      element.bind('input', function(){
        bar = true;
      });
      element.trigger('change');
      expect(bar).toBe(false);
    });
    it('should ignore non-form controls', function() {
      var bar = false;
      var element = compile('

')(scope);
      element.bind('input', function(){
        bar = true;
      });
      element.trigger('change');
      expect(bar).toBe(false);
    });
  });
});
<commit_msg>fix(jq-test) Trying to get the passthru tests working<commit_after>describe('uiJq', function () {
  var scope, compile, timeout;
  scope = null;
  beforeEach(module('ui.directives'));
  beforeEach(function () {
    jQuery.fn.foo = function () {};
    module(function ($provide) {
      $provide.value('ui.config', {
        jq: {foo: {}}
      });
    });
  });
  beforeEach(inject(function ($rootScope, $compile, $timeout) {
    scope = $rootScope.$new();
    compile = $compile;
    timeout = $timeout;
  }));
  describe('function or plugin isn\'t found', function () {
    it('should throw an error', function () {
      expect(function () {
        compile("

")(scope);
      }).toThrow();
    });
  });
  describe('calling a jQuery element function', function () {
    it('should just like, sort of work and junk', function () {
      spyOn(jQuery.fn, 'foo');
      compile("

")(scope);
      timeout.flush();
      expect(jQuery.fn.foo).toHaveBeenCalled();
    });
    it('should fire after the view has rendered', function() {
      var length;
      jQuery.fn.bar = function() {
        length = $(this).children().length;
        console.log(length);
      };
      scope.$apply('items=[1, 2]');
      compile("

")(scope);
      timeout.flush();
      expect(length).toBe(2);
    });
  });
  describe('calling a jQuery element function with options', function() {
    it('should not copy options.pizza to global', function() {
      spyOn(jQuery.fn, 'foo');
      compile('

')(scope);
      timeout.flush();
      expect(jQuery.fn.foo.calls[0].args).toEqual([{pizza: true}]);
      expect(jQuery.fn.foo.calls[1].args).toEqual([{}]);
    });
  });
  describe('using ui-refresh', function() {
    it('should execute exactly once if the expression is never set', function() {
      spyOn(jQuery.fn, 'foo');
      compile('

')(scope);
      timeout.flush();
      expect(jQuery.fn.foo.callCount).toBe(1);
    });
    it('should execute exactly once if the expression is set at initialization', function() {
      spyOn(jQuery.fn, 'foo');
      scope.$apply('bar = true');
      compile('

')(scope);
      timeout.flush();
      expect(jQuery.fn.foo.callCount).toBe(1);
    });
    it('should execute once for each time the expression changes', function() {
      spyOn(jQuery.fn, 'foo');
      scope.$apply('bar = 1');
      compile('

')(scope);
      timeout.flush();
      expect(jQuery.fn.foo.callCount).toBe(1);
      scope.$apply('bar = bar+1');
      timeout.flush();
      expect(jQuery.fn.foo.callCount).toBe(2);
      scope.$apply('bar = bar+1');
      timeout.flush();
      expect(jQuery.fn.foo.callCount).toBe(3);
    });
  });
  describe('change events', function() {
    it('should trigger an `input` event', function() {
      var bar = false;
      var element = compile('<input ui-jq="foo" ng-model="foobar">')(scope);
      element.bind('input', function(){
        bar = true;
      });
      element.trigger('change');
      expect(bar).toBe(true);
    });
    it('should ignore controls without ngModel attribute', function() {
      var bar = false;
      var element = compile('<input ui-jq="foo">')(scope);
      element.bind('input', function(){
        bar = true;
      });
      element.trigger('change');
      expect(bar).toBe(false);
    });
    it('should ignore non-form controls', function() {
      var bar = false;
      var element = compile('

')(scope);
      element.bind('input', function(){
        bar = true;
      });
      element.trigger('change');
      expect(bar).toBe(false);
    });
  });
});
<|endoftext|>


<commit_before>var Configuration = require('integra').Configuration
  , Runner = require('integra').Runner
  , ParallelRunner = require('integra').ParallelRunner
  , mongodb = require('../')
  , Db = mongodb.Db
  , Server = mongodb.Server
  , ReplSet = mongodb.ReplSet
  , ServerManager = require('../test/tools/server_manager').ServerManager
  , ReplicaSetManager = require('../test/tools/replica_set_manager').ReplicaSetManager;

// Server manager
var startPort = 30000;

//
//  Configurations
//
var configurations = Configuration

  // Single server configuration
  .add('single_server', function() {
    var serverManager = new ServerManager();
    var db = new Db('integration_tests', new Server("127.0.0.1", 27017,
     {auto_reconnect: false, poolSize: 4}), {w:0, native_parser: false});

    // Test suite start
    this.start = function(callback) {
      serverManager.start(true, {purgedirectories:true}, function(err) {
        if(err) throw err;

        db.open(function(err, result) {
          if(err) throw err;
          callback();
        })
      });
    }

    // Test suite stop
    this.stop = function(callback) {
      serverManager.stop(9, function(err) {
        callback();
      });
    };

    // Pr test functions
    this.setup = function(callback) { callback(); }
    this.teardown = function(callback) { callback(); };

    // Returns a db
    this.db = function() {
      return db;
    }

    // Used in tests
    this.db_name = "integration_tests";
  })

  // Simple Replicaset Configuration
  .add('replica_set', function() {
    var self = this;
    var replicasetManager = new ReplicaSetManager(
      {
          retries:120, secondary_count:2
        , passive_count:0, arbiter_count:1
        , start_port: startPort
        , tags:[{"dc1":"ny"}, {"dc1":"ny"}, {"dc2":"sf"}]
      }
    );

    // Adjust startPort
    startPort = startPort + 10;

    // Test suite start
    this.start = function(callback) {
      replicasetManager.startSet(true, function(err, result) {
        if(err) throw err;

        // Set up the replicaset
        var replSet = new ReplSet( [
                new Server( replicasetManager.host, replicasetManager.ports[1]),
                new Server( replicasetManager.host, replicasetManager.ports[0]),
                new Server( replicasetManager.host, replicasetManager.ports[2])
              ],
              {rs_name:replicasetManager.name}
            );

        self._db = new Db('integration_tests', replSet, {w:0, native_parser: false});
        self._db.open(function(err, result) {
          if(err) throw err;
          callback();
        })
      });
    }

    // Test suite stop
    this.stop = function(callback) {
      replicasetManager.killAll(function(err) {
        callback();
      });
    };

    // Allow us to kill the primary
    this.killPrimary = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.killPrimary.apply(replicasetManager, args);
    }

    // Restart killed nodes
    this.restartKilledNodes = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.restartKilledNodes.apply(replicasetManager, args);
    }

    // Stepdown primary
    this.stepDownPrimary = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.stepDownPrimary.apply(replicasetManager, args);
    }

    // Get node
    this.getNodeFromPort = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.getNodeFromPort.apply(replicasetManager, args);
    }

    // kill
    this.kill = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.kill.apply(replicasetManager, args);
    }

    // kill secondary
    this.killSecondary = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.killSecondary.apply(replicasetManager, args);
    }

    // primary
    this.primary = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.primary.apply(replicasetManager, args);
    }

    // secondaries
    this.secondaries = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.secondaries.apply(replicasetManager, args);
    }

    // arbiters
    this.arbiters = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.arbiters.apply(replicasetManager, args);
    }

    // Pr test functions
    this.setup = function(callback) {
      callback();
    }

    this.teardown = function(callback) {
      replicasetManager.restartKilledNodes(function() {
        callback();
      });
    };

    // Returns the package for using Mongo driver classes
    this.getMongoPackage = function() {
      return mongodb;
    }

    // Get the star port
    this.getReplicasetManager = function() {
      return replicasetManager;
    }

    // Returns a db
    this.db = function() {
      return self._db;
    }

    // Used in tests
    this.db_name = "integration_tests";
  })

//
//  Runners
//
// Configure a Run of tests
var functional_tests_runner = Runner
  // Add configurations to the test runner
  .configurations(configurations)
  // First parameter is test suite name
  // Second parameter is the configuration used
  // Third parameter is the list of files to execute
  .add("functional_tests",
    ['/new_tests/functional/insert_tests.js']
  );

// Configure a Run of tests
var repl_set_tests_runner = Runner
  // Add configurations to the test runner
  .configurations(configurations)
  .exeuteSerially(true)
  // First parameter is test suite name
  // Second parameter is the configuration used
  // Third parameter is the list of files to execute
  .add("replica_set",
    [
        '/new_tests/repl_set/reconnect_tests.js'
      // , '/new_tests/repl_set/reconnect_tests.js'
    ]
  );

// Configure a Run of tests
var repl_set_parallel_tests_runner = ParallelRunner
  // Add configurations to the test runner
  .configurations(configurations)
  // .parallelContexts(2)
  .parallelContexts(4)
  .parallelizeAtLevel(ParallelRunner.TEST)
  .exeuteSerially(true)
  // First parameter is test suite name
  // Second parameter is the configuration used
  // Third parameter is the list of files to execute
  .add("replica_set",
    [
        '/new_tests/repl_set/reconnect_tests.js'
      , '/new_tests/repl_set/connecting_tests.js'
      , '/new_tests/repl_set/secondary_queries_tests.js'
      , '/new_tests/repl_set/mongoclient_tests.js'
      , '/new_tests/repl_set/read_preferences_tests.js'
      , '/new_tests/repl_set/read_preferences_spec_tests.js'
      , '/new_tests/repl_set/failover_query_tests.js'
    ]
  );

// // Run the tests against configuration 'single_server'
// functional_tests_runner.run("single_server");
// repl_set_tests_runner.run("replica_set");
repl_set_parallel_tests_runner.run("replica_set");

<commit_msg>Added more to runner<commit_after>var Configuration = require('integra').Configuration
  , Runner = require('integra').Runner
  , ParallelRunner = require('integra').ParallelRunner
  , mongodb = require('../')
  , Db = mongodb.Db
  , Server = mongodb.Server
  , ReplSet = mongodb.ReplSet
  , ServerManager = require('../test/tools/server_manager').ServerManager
  , ReplicaSetManager = require('../test/tools/replica_set_manager').ReplicaSetManager;

// Server manager
var startPort = 30000;

//
//  Configurations
//
var configurations = Configuration

  // Single server configuration
  .add('single_server', function() {
    var serverManager = new ServerManager();
    var db = new Db('integration_tests', new Server("127.0.0.1", 27017,
     {auto_reconnect: false, poolSize: 4}), {w:0, native_parser: false});

    // Test suite start
    this.start = function(callback) {
      serverManager.start(true, {purgedirectories:true}, function(err) {
        if(err) throw err;

        db.open(function(err, result) {
          if(err) throw err;
          callback();
        })
      });
    }

    // Test suite stop
    this.stop = function(callback) {
      serverManager.stop(9, function(err) {
        callback();
      });
    };

    // Pr test functions
    this.setup = function(callback) { callback(); }
    this.teardown = function(callback) { callback(); };

    // Returns a db
    this.db = function() {
      return db;
    }

    // Used in tests
    this.db_name = "integration_tests";
  })

  // Simple Replicaset Configuration
  .add('replica_set', function() {
    var self = this;
    // Save the startPort
    this.startPort = startPort;
    // Set up replicaset manager
    var replicasetManager = new ReplicaSetManager(
      {
          retries:120, secondary_count:2
        , passive_count:0, arbiter_count:1
        , start_port: startPort
        , tags:[{"dc1":"ny"}, {"dc1":"ny"}, {"dc2":"sf"}]
      }
    );

    // Adjust startPort
    startPort = startPort + 10;

    // Test suite start
    this.start = function(callback) {
      replicasetManager.startSet(true, function(err, result) {
        if(err) throw err;

        // Set up the replicaset
        var replSet = new ReplSet( [
                new Server( replicasetManager.host, replicasetManager.ports[1]),
                new Server( replicasetManager.host, replicasetManager.ports[0]),
                new Server( replicasetManager.host, replicasetManager.ports[2])
              ],
              {rs_name:replicasetManager.name}
            );

        self._db = new Db('integration_tests', replSet, {w:0, native_parser: false});
        self._db.open(function(err, result) {
          if(err) throw err;
          callback();
        })
      });
    }

    // Test suite stop
    this.stop = function(callback) {
      replicasetManager.killAll(function(err) {
        callback();
      });
    };

    // Allow us to kill the primary
    this.killPrimary = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.killPrimary.apply(replicasetManager, args);
    }

    // Restart killed nodes
    this.restartKilledNodes = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.restartKilledNodes.apply(replicasetManager, args);
    }

    // Stepdown primary
    this.stepDownPrimary = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.stepDownPrimary.apply(replicasetManager, args);
    }

    // Get node
    this.getNodeFromPort = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.getNodeFromPort.apply(replicasetManager, args);
    }

    // kill
    this.kill = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.kill.apply(replicasetManager, args);
    }

    // kill secondary
    this.killSecondary = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.killSecondary.apply(replicasetManager, args);
    }

    // primary
    this.primary = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.primary.apply(replicasetManager, args);
    }

    // secondaries
    this.secondaries = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.secondaries.apply(replicasetManager, args);
    }

    // arbiters
    this.arbiters = function() {
      var args = Array.prototype.slice.call(arguments, 0);
      replicasetManager.arbiters.apply(replicasetManager, args);
    }

    // Pr test functions
    this.setup = function(callback) {
      callback();
    }

    this.teardown = function(callback) {
      replicasetManager.restartKilledNodes(function() {
        callback();
      });
    };

    // Returns the package for using Mongo driver classes
    this.getMongoPackage = function() {
      return mongodb;
    }

    // Get the star port
    this.getReplicasetManager = function() {
      return replicasetManager;
    }

    // Returns a db
    this.db = function() {
      return self._db;
    }

    // Used in tests
    this.db_name = "integration_tests";
  })

//
//  Runners
//
// Configure a Run of tests
var functional_tests_runner = Runner
  // Add configurations to the test runner
  .configurations(configurations)
  // First parameter is test suite name
  // Second parameter is the configuration used
  // Third parameter is the list of files to execute
  .add("functional_tests",
    ['/new_tests/functional/insert_tests.js']
  );

// Configure a Run of tests
var repl_set_tests_runner = Runner
  // Add configurations to the test runner
  .configurations(configurations)
  .exeuteSerially(true)
  // First parameter is test suite name
  // Second parameter is the configuration used
  // Third parameter is the list of files to execute
  .add("replica_set",
    [
        '/new_tests/repl_set/reconnect_tests.js'
      // , '/new_tests/repl_set/reconnect_tests.js'
    ]
  );

var buckets = {};

// Configure a Run of tests
var repl_set_parallel_tests_runner = ParallelRunner
  // Add configurations to the test runner
  .configurations(configurations)
  // The number of parallel contexts we are running with
  .parallelContexts(4)
  // Parallelize at test or file level
  .parallelizeAtLevel(ParallelRunner.TEST)
  // Execute all tests serially in each context
  .exeuteSerially(true)
  // Callback for each test run including time to execute and env
  .testStatistics(function(event_type, test_statistics) {
    // Unpack statistics
    var time_spent = test_statistics.end_time.getTime() - test_statistics.start_time.getTime();
    var test = test_statistics.name;
    var file = test_statistics.file_name;
    var config = test_statistics.config_name;

    // Add to bucket
    if(!Array.isArray(buckets[test_statistics.configuration.startPort])) {
      buckets[test_statistics.configuration.startPort] = [];
    }

    // Stat object
    var stat = {
        port: test_statistics.configuration.startPort
      , time: time_spent
      , test: test
      , file: file
      , config: config
    };

    // Save statistics about test to it's bucket
    buckets[test_statistics.configuration.startPort].push(stat);

    console.log("---------------------------- stat recorded")
    console.dir(stat)
  })
  // First parameter is test suite name
  // Second parameter is the configuration used
  // Third parameter is the list of files to execute
  .add("replica_set",
    [
        '/new_tests/repl_set/reconnect_tests.js'
      , '/new_tests/repl_set/connecting_tests.js'
      // , '/new_tests/repl_set/secondary_queries_tests.js'
      // , '/new_tests/repl_set/mongoclient_tests.js'
      // , '/new_tests/repl_set/read_preferences_tests.js'
      // , '/new_tests/repl_set/read_preferences_spec_tests.js'
      // , '/new_tests/repl_set/failover_query_tests.js'
    ]
  );

// // Run the tests against configuration 'single_server'
// functional_tests_runner.run("single_server");
// repl_set_tests_runner.run("replica_set");

// // After each test is done
// repl_set_parallel_tests_runner.on('test_done', function(test_statistics) {
// })

// // After test suite is finished
// repl_set_parallel_tests_runner.on('end', function() {
// });

// Parallel runner
repl_set_parallel_tests_runner.run("replica_set");

<|endoftext|>


<commit_before>// ==========================================================================
// SC.Logger
// ==========================================================================

/**
  If {@link SC.Logger.format} is true, this delimiter will be put between arguments.

  @property {String}
*/
SC.LOGGER_LOG_DELIMITER = ", ";

/**
  If {@link SC.Logger.error} falls back onto {@link SC.Logger.log}, this will be
  prepended to the output.

  @property {String}
*/
SC.LOGGER_LOG_ERROR = "ERROR: ";

/**
  If {@link SC.Logger.info} falls back onto {@link SC.Logger.log}, this will be
  prepended to the output.

  @property {String}
*/
SC.LOGGER_LOG_INFO = "INFO: ";

/**
  If {@link SC.Logger.warn} falls back onto {@link SC.Logger.log}, this will be
  prepended to the output.

  @property {String}
*/
SC.LOGGER_LOG_WARN = "WARNING: ";

/**
  If {@link SC.Logger.debug} falls back onto {@link SC.Logger.log}, this will be
  prepended to the output.

  @property {String}
*/
SC.LOGGER_LOG_DEBUG = "DEBUG: ";

/** @class

  Object to allow for safe logging actions, such as using the browser console.

  The FireFox plugin Firebug was used as a function reference. Please see
  {@link Firebug Logging Reference}
  for further information.

  @author Colin Campbell
  @author Benedikt Böhm
  @extends SC.Object
  @since Sproutcore 1.0
  @see Firebug Logging Reference
*/
SC.Logger = SC.Object.create({

  // ..........................................................
  // PROPERTIES
  //

  /**
    Whether or not to enable debug logging.

    @property: {Boolean}
  */
  debugEnabled: NO,

  /**
    Computed property that checks for the existence of the reporter object.

    @property {Boolean}
  */
  exists: function() {
    return typeof(this.get('reporter')) !== 'undefined' && this.get('reporter') != null;
  }.property('reporter').cacheable(),

  /**
    If console.log does not exist, SC.Logger will use window.alert instead.

    This property is only used inside {@link SC.Logger.log}. If fallBackOnLog is
    false and you call a different function, an alert will not be opened.

    @property {Boolean}
  */
  fallBackOnAlert: NO,

  /**
    If some function, such as console.dir, does not exist,
    SC.Logger will try console.log if this is true.

    @property {Boolean}
  */
  fallBackOnLog: YES,

  /**
    Whether or not to format multiple arguments together
    or let the browser deal with that.

    @property {Boolean}
  */
  format: YES,

  /**
    The reporter is the object which implements the actual logging functions.

    @default The browser's console
    @property {Object}
  */
  reporter: console,

  // ..........................................................
  // METHODS
  //

  /**
    Log output to the console, but only if it exists.

    @param {String|Array|Function|Object}
    @returns {Boolean} true if reporter.log exists, false otherwise
  */
  log: function() {
    var reporter = this.get('reporter');

    // log through the reporter
    if (this.get('exists') && typeof(reporter.log) === "function") {
      if (this.get('format')) {
        reporter.log(this._argumentsToString.apply(this, arguments));
      }
      else {
        reporter.log.apply(reporter, arguments);
      }
      return true;
    }

    // log through alert
    else if (this.fallBackOnAlert) {
      var s = this.get('format') ? this._argumentsToString.apply(this, arguments) : arguments;
      // include support for overriding the alert through the reporter
      // if it has come this far, it's likely this will fail
      if (this.get('exists') && typeof(reporter.alert) === "function") {
        reporter.alert(s);
      }
      else {
        alert(s);
      }
      return true;
    }
    return false;
  },

  /**
    Log a debug message to the console.

    Logs the response using {@link SC.Logger.log} if reporter.debug does not exist and
    {@link SC.Logger.fallBackOnLog} is true.

    @param {String|Array|Function|Object}
    @returns {Boolean} true if logged to reporter, false if not
  */
  debug: function() {
    var reporter = this.get('reporter');

    if (this.get('debugEnabled') !== YES) {
      return false;
    }

    if (this.get('exists') && (typeof reporter.debug === "function")) {
      reporter.debug.apply(reporter, arguments);
      return true;
    }
    else if (this.fallBackOnLog) {
      var a = this._argumentsToArray(arguments);
      if (typeof(a.unshift) === "function") a.unshift(SC.LOGGER_LOG_DEBUG);
      return this.log.apply(this, a);
    }
    return false;
  },

  /**
    Prints the properties of an object.

    Logs the object using {@link SC.Logger.log} if the reporter.dir function does not exist and
    {@link SC.Logger.fallBackOnLog} is true.

    @param {Object}
    @returns {Boolean} true if logged to console, false if not
  */
  dir: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.dir) === "function") {
      // Firebug's console.dir doesn't support multiple objects here
      // but maybe custom reporters will
      reporter.dir.apply(reporter, arguments);
      return true;
    }
    return (this.fallBackOnLog) ? this.log.apply(this, arguments) : false;
  },

  /**
    Prints an XML outline for any HTML or XML object.

    Logs the object using {@link SC.Logger.log} if reporter.dirxml function does not exist and
    {@lnk SC.Logger.fallBackOnLog} is true.

    @param {Object}
    @returns {Boolean} true if logged to reporter, false if not
  */
  dirxml: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.dirxml) === "function") {
      // Firebug's console.dirxml doesn't support multiple objects here
      // but maybe custom reporters will
      reporter.dirxml.apply(reporter, arguments);
      return true;
    }
    return (this.fallBackOnLog) ? this.log.apply(this, arguments) : false;
  },

  /**
    Log an error to the console

    Logs the error using {@link SC.Logger.log} if reporter.error does not exist and
    {@link SC.Logger.fallBackOnLog} is true.

    @param {String|Array|Function|Object}
    @returns {Boolean} true if logged to reporter, false if not
  */
  error: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.error) === "function") {
      reporter.error.apply(reporter, arguments);
      return true;
    }
    else if (this.fallBackOnLog) {
      var a = this._argumentsToArray(arguments);
      if (typeof(a.unshift) === "function") a.unshift(SC.LOGGER_LOG_ERROR);
      return this.log.apply(this, a);
    }
    return false;
  },

  /**
    Every log after this call until {@link SC.Logger.groupEnd} is called
    will be indented for readability. You can create as many levels
    as you want.

    @param {String} [title] An optional title to display above the group
    @returns {Boolean} true if reporter.group exists, false otherwise
  */
  group: function(s) {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.group) === "function") {
      reporter.group(s);
      return true;
    }
    return false;
  },

  /**
    Ends a group declared with {@link SC.Logger.group}.

    @returns {Boolean} true if the reporter.groupEnd exists, false otherwise
    @see SC.Logger.group
  */
  groupEnd: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.groupEnd) === "function") {
      reporter.groupEnd();
      return true;
    }
    return false;
  },

  /**
    Log an information response to the reporter.

    Logs the response using {@link SC.Logger.log} if reporter.info does not exist and
    {@link SC.Logger.fallBackOnLog} is true.

    @param {String|Array|Function|Object}
    @returns {Boolean} true if logged to reporter, false if not
  */
  info: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.info) === "function") {
      reporter.info.apply(reporter, arguments);
      return true;
    }
    else if (this.fallBackOnLog) {
      var a = this._argumentsToArray(arguments);
      if (typeof(a.unshift) === "function") a.unshift(SC.LOGGER_LOG_INFO);
      return this.log.apply(this, a);
    }
    return false;
  },

  /**
    Begins the JavaScript profiler, if it exists. Call {@link SC.Logger.profileEnd}
    to end the profiling process and receive a report.

    @returns {Boolean} true if reporter.profile exists, false otherwise
  */
  profile: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.profile) === "function") {
      reporter.profile();
      return true;
    }
    return false;
  },

  /**
    Ends the JavaScript profiler, if it exists.

    @returns {Boolean} true if reporter.profileEnd exists, false otherwise
    @see SC.Logger.profile
  */
  profileEnd: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.profileEnd) === "function") {
      reporter.profileEnd();
      return true;
    }
    return false;
  },

  /**
    Measure the time between when this function is called and
    {@link SC.Logger.timeEnd} is called.

    @param {String} name The name of the profile to begin
    @returns {Boolean} true if reporter.time exists, false otherwise
    @see SC.Logger.timeEnd
  */
  time: function(name) {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.time) === "function") {
      reporter.time(name);
      return true;
    }
    return false;
  },

  /**
    Ends the profile specified.

    @param {String} name The name of the profile to end
    @returns {Boolean} true if reporter.timeEnd exists, false otherwise
    @see SC.Logger.time
  */
  timeEnd: function(name) {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.timeEnd) === "function") {
      reporter.timeEnd(name);
      return true;
    }
    return false;
  },

  /**
    Prints a stack-trace.

    @returns {Boolean} true if reporter.trace exists, false otherwise
  */
  trace: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.trace) === "function") {
      reporter.trace();
      return true;
    }
    return false;
  },

  /**
    Log a warning to the console.

    Logs the warning using {@link SC.Logger.log} if reporter.warning does not exist and
    {@link SC.Logger.fallBackOnLog} is true.

    @param {String|Array|Function|Object}
    @returns {Boolean} true if logged to reporter, false if not
  */
  warn: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.warn) === "function") {
      reporter.warn.apply(reporter, arguments);
      return true;
    }
    else if (this.fallBackOnLog) {
      var a = this._argumentsToArray(arguments);
      if (typeof(a.unshift) === "function") a.unshift(SC.LOGGER_LOG_WARN);
      return this.log.apply(this, a);
    }
    return false;
  },

  // ..........................................................
  // INTERNAL SUPPORT
  //

  /**
    @private

    The arguments function property doesn't support Array#unshift. This helper
    copies the elements of arguments to a blank array.

    @param {Array} arguments The arguments property of a function
    @returns {Array} An array containing the elements of arguments parameter
  */
  _argumentsToArray: function(arguments) {
    if (!arguments) return [];
    var a = [];
    for (var i = 0; i < arguments.length; i++) {
      a[i] = arguments[i];
    }
    return a;
  },

  /**
    @private

    Formats the arguments array of a function by creating a string
    with SC.LOGGER_LOG_DELIMITER between the elements.

    @returns {String} A string of formatted arguments
  */
  _argumentsToString: function() {
    var s = "";
    for (var i = 0; i<arguments.length - 1; i++) {
      s += arguments[i] + SC.LOGGER_LOG_DELIMITER;
    }
    s += arguments[arguments.length-1];
    return s;
  }

});
<commit_msg>add debug() support to SC.Logger<commit_after>// ==========================================================================
// SC.Logger
// ==========================================================================

/**
  If {@link SC.Logger.format} is true, this delimiter will be put between arguments.

  @property {String}
*/
SC.LOGGER_LOG_DELIMITER = ", ";

/**
  If {@link SC.Logger.error} falls back onto {@link SC.Logger.log}, this will be
  prepended to the output.

  @property {String}
*/
SC.LOGGER_LOG_ERROR = "ERROR: ";

/**
  If {@link SC.Logger.info} falls back onto {@link SC.Logger.log}, this will be
  prepended to the output.

  @property {String}
*/
SC.LOGGER_LOG_INFO = "INFO: ";

/**
  If {@link SC.Logger.warn} falls back onto {@link SC.Logger.log}, this will be
  prepended to the output.

  @property {String}
*/
SC.LOGGER_LOG_WARN = "WARNING: ";

/**
  If {@link SC.Logger.debug} falls back onto {@link SC.Logger.log}, this will be
  prepended to the output.

  @property {String}
*/
SC.LOGGER_LOG_DEBUG = "DEBUG: ";

/** @class

  Object to allow for safe logging actions, such as using the browser console.

  The FireFox plugin Firebug was used as a function reference. Please see
  {@link Firebug Logging Reference}
  for further information.

  @author Colin Campbell
  @author Benedikt Böhm
  @extends SC.Object
  @since Sproutcore 1.0
  @see Firebug Logging Reference
*/
SC.Logger = SC.Object.create({

  // ..........................................................
  // PROPERTIES
  //

  /**
    Whether or not to enable debug logging.

    @property: {Boolean}
  */
  debugEnabled: NO,

  /**
    Computed property that checks for the existence of the reporter object.

    @property {Boolean}
  */
  exists: function() {
    return typeof(this.get('reporter')) !== 'undefined' && this.get('reporter') != null;
  }.property('reporter').cacheable(),

  /**
    If console.log does not exist, SC.Logger will use window.alert instead.

    This property is only used inside {@link SC.Logger.log}. If fallBackOnLog is
    false and you call a different function, an alert will not be opened.

    @property {Boolean}
  */
  fallBackOnAlert: NO,

  /**
    If some function, such as console.dir, does not exist,
    SC.Logger will try console.log if this is true.

    @property {Boolean}
  */
  fallBackOnLog: YES,

  /**
    Whether or not to format multiple arguments together
    or let the browser deal with that.

    @property {Boolean}
  */
  format: YES,

  /**
    The reporter is the object which implements the actual logging functions.

    @default The browser's console
    @property {Object}
  */
  reporter: console,

  // ..........................................................
  // METHODS
  //

  /**
    Log output to the console, but only if it exists.

    @param {String|Array|Function|Object}
    @returns {Boolean} true if reporter.log exists, false otherwise
  */
  log: function() {
    var reporter = this.get('reporter');

    // log through the reporter
    if (this.get('exists') && typeof(reporter.log) === "function") {
      if (this.get('format')) {
        reporter.log(this._argumentsToString.apply(this, arguments));
      }
      else {
        reporter.log.apply(reporter, arguments);
      }
      return true;
    }

    // log through alert
    else if (this.fallBackOnAlert) {
      var s = this.get('format') ? this._argumentsToString.apply(this, arguments) : arguments;
      // include support for overriding the alert through the reporter
      // if it has come this far, it's likely this will fail
      if (this.get('exists') && typeof(reporter.alert) === "function") {
        reporter.alert(s);
      }
      else {
        alert(s);
      }
      return true;
    }
    return false;
  },

  /**
    Log a debug message to the console.

    Logs the response using {@link SC.Logger.log} if reporter.debug does not exist and
    {@link SC.Logger.fallBackOnLog} is true.

    @param {String|Array|Function|Object}
    @returns {Boolean} true if logged to reporter, false if not
  */
  debug: function() {
    var reporter = this.get('reporter');

    if (this.get('debugEnabled') !== YES) {
      return false;
    }

    if (this.get('exists') && typeof(reporter.debug) === "function") {
      reporter.debug.apply(reporter, arguments);
      return true;
    }
    else if (this.fallBackOnLog) {
      var a = this._argumentsToArray(arguments);
      if (typeof(a.unshift) === "function") a.unshift(SC.LOGGER_LOG_DEBUG);
      return this.log.apply(this, a);
    }
    return false;
  },

  /**
    Prints the properties of an object.

    Logs the object using {@link SC.Logger.log} if the reporter.dir function does not exist and
    {@link SC.Logger.fallBackOnLog} is true.

    @param {Object}
    @returns {Boolean} true if logged to console, false if not
  */
  dir: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.dir) === "function") {
      // Firebug's console.dir doesn't support multiple objects here
      // but maybe custom reporters will
      reporter.dir.apply(reporter, arguments);
      return true;
    }
    return (this.fallBackOnLog) ? this.log.apply(this, arguments) : false;
  },

  /**
    Prints an XML outline for any HTML or XML object.

    Logs the object using {@link SC.Logger.log} if reporter.dirxml function does not exist and
    {@lnk SC.Logger.fallBackOnLog} is true.

    @param {Object}
    @returns {Boolean} true if logged to reporter, false if not
  */
  dirxml: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.dirxml) === "function") {
      // Firebug's console.dirxml doesn't support multiple objects here
      // but maybe custom reporters will
      reporter.dirxml.apply(reporter, arguments);
      return true;
    }
    return (this.fallBackOnLog) ? this.log.apply(this, arguments) : false;
  },

  /**
    Log an error to the console

    Logs the error using {@link SC.Logger.log} if reporter.error does not exist and
    {@link SC.Logger.fallBackOnLog} is true.

    @param {String|Array|Function|Object}
    @returns {Boolean} true if logged to reporter, false if not
  */
  error: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.error) === "function") {
      reporter.error.apply(reporter, arguments);
      return true;
    }
    else if (this.fallBackOnLog) {
      var a = this._argumentsToArray(arguments);
      if (typeof(a.unshift) === "function") a.unshift(SC.LOGGER_LOG_ERROR);
      return this.log.apply(this, a);
    }
    return false;
  },

  /**
    Every log after this call until {@link SC.Logger.groupEnd} is called
    will be indented for readability. You can create as many levels
    as you want.

    @param {String} [title] An optional title to display above the group
    @returns {Boolean} true if reporter.group exists, false otherwise
  */
  group: function(s) {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.group) === "function") {
      reporter.group(s);
      return true;
    }
    return false;
  },

  /**
    Ends a group declared with {@link SC.Logger.group}.

    @returns {Boolean} true if the reporter.groupEnd exists, false otherwise
    @see SC.Logger.group
  */
  groupEnd: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.groupEnd) === "function") {
      reporter.groupEnd();
      return true;
    }
    return false;
  },

  /**
    Log an information response to the reporter.

    Logs the response using {@link SC.Logger.log} if reporter.info does not exist and
    {@link SC.Logger.fallBackOnLog} is true.

    @param {String|Array|Function|Object}
    @returns {Boolean} true if logged to reporter, false if not
  */
  info: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.info) === "function") {
      reporter.info.apply(reporter, arguments);
      return true;
    }
    else if (this.fallBackOnLog) {
      var a = this._argumentsToArray(arguments);
      if (typeof(a.unshift) === "function") a.unshift(SC.LOGGER_LOG_INFO);
      return this.log.apply(this, a);
    }
    return false;
  },

  /**
    Begins the JavaScript profiler, if it exists. Call {@link SC.Logger.profileEnd}
    to end the profiling process and receive a report.

    @returns {Boolean} true if reporter.profile exists, false otherwise
  */
  profile: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.profile) === "function") {
      reporter.profile();
      return true;
    }
    return false;
  },

  /**
    Ends the JavaScript profiler, if it exists.

    @returns {Boolean} true if reporter.profileEnd exists, false otherwise
    @see SC.Logger.profile
  */
  profileEnd: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.profileEnd) === "function") {
      reporter.profileEnd();
      return true;
    }
    return false;
  },

  /**
    Measure the time between when this function is called and
    {@link SC.Logger.timeEnd} is called.

    @param {String} name The name of the profile to begin
    @returns {Boolean} true if reporter.time exists, false otherwise
    @see SC.Logger.timeEnd
  */
  time: function(name) {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.time) === "function") {
      reporter.time(name);
      return true;
    }
    return false;
  },

  /**
    Ends the profile specified.

    @param {String} name The name of the profile to end
    @returns {Boolean} true if reporter.timeEnd exists, false otherwise
    @see SC.Logger.time
  */
  timeEnd: function(name) {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.timeEnd) === "function") {
      reporter.timeEnd(name);
      return true;
    }
    return false;
  },

  /**
    Prints a stack-trace.

    @returns {Boolean} true if reporter.trace exists, false otherwise
  */
  trace: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.trace) === "function") {
      reporter.trace();
      return true;
    }
    return false;
  },

  /**
    Log a warning to the console.

    Logs the warning using {@link SC.Logger.log} if reporter.warning does not exist and
    {@link SC.Logger.fallBackOnLog} is true.

    @param {String|Array|Function|Object}
    @returns {Boolean} true if logged to reporter, false if not
  */
  warn: function() {
    var reporter = this.get('reporter');

    if (this.get('exists') && typeof(reporter.warn) === "function") {
      reporter.warn.apply(reporter, arguments);
      return true;
    }
    else if (this.fallBackOnLog) {
      var a = this._argumentsToArray(arguments);
      if (typeof(a.unshift) === "function") a.unshift(SC.LOGGER_LOG_WARN);
      return this.log.apply(this, a);
    }
    return false;
  },

  // ..........................................................
  // INTERNAL SUPPORT
  //

  /**
    @private

    The arguments function property doesn't support Array#unshift. This helper
    copies the elements of arguments to a blank array.

    @param {Array} arguments The arguments property of a function
    @returns {Array} An array containing the elements of arguments parameter
  */
  _argumentsToArray: function(arguments) {
    if (!arguments) return [];
    var a = [];
    for (var i = 0; i < arguments.length; i++) {
      a[i] = arguments[i];
    }
    return a;
  },

  /**
    @private

    Formats the arguments array of a function by creating a string
    with SC.LOGGER_LOG_DELIMITER between the elements.

    @returns {String} A string of formatted arguments
  */
  _argumentsToString: function() {
    var s = "";
    for (var i = 0; i<arguments.length - 1; i++) {
      s += arguments[i] + SC.LOGGER_LOG_DELIMITER;
    }
    s += arguments[arguments.length-1];
    return s;
  }

});
<|endoftext|>