Bug 883629 - remove test pilot from thunderbird. r=standard8
authorMagnus Melin <mkmelin+mozilla@iki.fi>
Sun, 23 Jun 2013 12:21:40 +0300
changeset 15787 374d30ca7c599aae5c72dec2cfcb63fe49b3a6d9
parent 15786 89ca38497a74fa4e060e24e81e863fd31609520f
child 15788 4a17c2c1bb24a7fe5916bdbab66934bcb3946b21
push id942
push userbugzilla@standard8.plus.com
push dateMon, 05 Aug 2013 19:15:38 +0000
treeherdercomm-beta@0e1a1c4a9f0c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstandard8
bugs883629
Bug 883629 - remove test pilot from thunderbird. r=standard8
mail/app/profile/extensions/Makefile.in
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/chrome.manifest
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/components/TestPilot.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/all-studies-window.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/all-studies-window.xul
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/all-studies.html
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/all-studies.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/browser.css
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/browser.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/browser.xul
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/debug.html
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/experiment-page.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/feedback-browser.xul
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/fennec-options.xul
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.colorhelpers.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.crosshair.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.image.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.navigate.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.selection.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.stack.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.threshold.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/notificationBindings.xml
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/raw-data-dialog.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/raw-data-dialog.xul
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/raw-data.html
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/screen.css
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/status-quit.html
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/status.html
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/survey-generator.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/take-survey.html
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/tp-browser-customNotifications.xul
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/tp-browser-popupNotifications.xul
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/welcome-page.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/welcome.html
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/window-utils.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/defaults/preferences/preferences.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/install.rdf.in
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/instrument/chrome.manifest
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/instrument/install.rdf
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/instrument/instrument.jsm
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/instrument/instrument.xul
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/Observers.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/dbutils.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/experiment_data_store.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/feedback.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/interface.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/jar-code-store.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/cuddlefish.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/file.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/memory.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/observer-service.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/plain-text-console.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/preferences-service.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/securable-module.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/timer.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/traceback.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/unit-test.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/unload.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/url.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/lib/xhr.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/log4moz.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/metadata.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/notifications.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/remote-experiment-loader.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/setup.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/string_sanitizer.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/modules/tasks.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/badge-default.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/bg.jpg
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/css/screen-standalone-mobile.css
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/css/screen-standalone.css
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/dino_32x32.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/bg-status.jpg
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/callout.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/callout_continue.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/data1.jpg
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/data2.jpg
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/home_comments.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/home_computer.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/home_continue.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/home_quit.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/home_results.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/home_twitter.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/images/home_upcoming.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/logo.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/mozilla-logo.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/notification-tail-down.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/status-completed.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/status-ejected.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/status-missed.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/testPilot_200x200.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/testpilot_16x16.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/testpilot_32x32.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/tp-completedstudies-32x32.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/tp-currentstudies-32x32.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/tp-generic-32x32.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/tp-learned-32x32.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/tp-results-48x48.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/tp-settings-32x32.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/tp-study-48x48.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/all/tp-submit-48x48.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/linux/close_button.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/linux/feedback-broken-website.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/linux/feedback-frown-16x16.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/linux/feedback-idea.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/linux/feedback-rate.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/linux/feedback-smile-16x16.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/linux/feedback.css
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/mac/close_button.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/mac/feedback-broken-website.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/mac/feedback-frown-16x16.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/mac/feedback-idea.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/mac/feedback-rate.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/mac/feedback-smile-16x16.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/mac/feedback.css
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/mac/notification-tail-down.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/mac/notification-tail-up.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/win/close_button.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/win/feedback-broken-website.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/win/feedback-frown-16x16.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/win/feedback-idea.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/win/feedback-rate.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/win/feedback-smile-16x16.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/win/feedback.css
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/win/notification-tail-down.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/skin/win/notification-tail-up.png
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/tests/foo.jar
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/tests/foo.js
mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/tests/test_data_store.js
mail/installer/package-manifest.in
mail/installer/removed-files.in
mail/locales/en-US/feedback/main.dtd
mail/locales/en-US/feedback/main.properties
mail/locales/jar.mn
mail/test/mozmill/runtest.py
--- a/mail/app/profile/extensions/Makefile.in
+++ b/mail/app/profile/extensions/Makefile.in
@@ -12,17 +12,16 @@ DISTROEXT = $(call core_abspath,$(DIST))
 
 include $(DEPTH)/config/autoconf.mk
 
 include $(topsrcdir)/config/rules.mk
 
 # If adding extra extensions here, check that EXTRA_ARGS defined below won't
 # affect them unintentionally.
 EXTENSIONS = \
-  tbtestpilot@labs.mozilla.com \
   $(NULL)
 
 # We are in release mode, we don't want to ship the debug file.
 ifndef MOZ_DEBUG
 EXTRA_ARGS = -x content/debug.html
 endif
 
 DEFINES += \
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/chrome.manifest
+++ /dev/null
@@ -1,28 +0,0 @@
-resource testpilot ./
-content testpilot content/
-skin testpilot skin skin/all/
-skin testpilot-os skin skin/linux/ os=Linux
-skin testpilot-os skin skin/linux/ os=SunOS
-skin testpilot-os skin skin/mac/ os=Darwin
-skin testpilot-os skin skin/win/ os=WINNT
-
-# firefox
-overlay chrome://browser/content/macBrowserOverlay.xul chrome://testpilot/content/browser.xul   application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
-
-# firefox
-overlay chrome://browser/content/browser.xul chrome://testpilot/content/browser.xul   application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
-
-# thunderbird
-overlay chrome://messenger/content/mailWindowOverlay.xul chrome://testpilot/content/browser.xul   application={3550f703-e582-4d05-9a08-453d09bdfdc6}
-
-style	chrome://global/content/customizeToolbar.xul	chrome://testpilot/content/browser.css
-# For the menubar on Mac
-overlay chrome://testpilot/content/all-studies-window.xul chrome://browser/content/macBrowserOverlay.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} os=Darwin
-
-
-component {e6e5e58f-7977-485a-b076-2f74bee2677b} components/TestPilot.js
-contract @mozilla.org/testpilot/service;1 {e6e5e58f-7977-485a-b076-2f74bee2677b}
-category profile-after-change testpilot @mozilla.org/testpilot/service;1
-
-# For the options on Fennec
-override chrome://testpilot/content/options.xul chrome://testpilot/content/fennec-options.xul application={a23983c0-fd0e-11dc-95ff-0800200c9a66}
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/components/TestPilot.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-function TestPilotComponent() {}
-TestPilotComponent.prototype = {
-  classDescription: "Test Pilot Component",
-  contractID: "@mozilla.org/testpilot/service;1",
-  classID: Components.ID("{e6e5e58f-7977-485a-b076-2f74bee2677b}"),
-  _xpcom_categories: [{ category: "profile-after-change" }],
-  _startupTimer: null,
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
-                                         Ci.nsISupportsWeakReference]),
-
-  observe: function TPC__observe(subject, topic, data) {
-    let os = Cc["@mozilla.org/observer-service;1"].
-        getService(Ci.nsIObserverService);
-    switch (topic) {
-    case "profile-after-change":
-      //Services.console.logStringMessage("Test Pilot Component Sessionstore\n");
-      os.addObserver(this, "mail-startup-done", true);
-      os.addObserver(this, "sessionstore-windows-restored", true);
-      break;
-    case "sessionstore-windows-restored":
-    case "mail-startup-done":
-      /* Stop oberver, to ensure that globalStartup doesn't get
-       * called more than once. */
-      os.removeObserver(this, topic, false);
-      /* Call global startup on a timer so that it's off of the main
-       * thread... delay a few seconds to give firefox time to finish
-       * starting up.
-       */
-      this._startupTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-      this._startupTimer.initWithCallback(
-        {notify: function(timer) {
-           Cu.import("resource://testpilot/modules/setup.js");
-           TestPilotSetup.globalStartup();
-         }}, 3000, Ci.nsITimer.TYPE_ONE_SHOT);
-      break;
-    }
-  }
-};
-
-const components = [TestPilotComponent];
-var NSGetFactory, NSGetModule;
-if (XPCOMUtils.generateNSGetFactory)
-  NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
-else
-  NSGetModule = XPCOMUtils.generateNSGetModule(components);
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/all-studies-window.js
+++ /dev/null
@@ -1,439 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// TODO Show individual status page in new chromeless window as html with
-// background color set to "moz-dialog".
-
-const NO_STUDIES_IMG = "chrome://testpilot/skin/testPilot_200x200.png";
-const PROPOSE_STUDY_URL =
-  "https://wiki.mozilla.org/Labs/Test_Pilot#For_researchers";
-
-var TestPilotXulWindow = {
-  _stringBundle : null,
-
-  onSubmitButton: function(experimentId) {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    let task = TestPilotSetup.getTaskById(experimentId);
-    let button = document.getElementById("submit-button-" + task.id);
-
-    // Hide the upload button so it doesn't get clicked again...
-    let parent = button.parentNode;
-    while (parent.firstChild) {
-      parent.removeChild(parent.firstChild);
-    }
-    // Replace it with a message:
-    this.addLabel(
-      parent,
-      this._stringBundle.getString("testpilot.studiesWindow.uploading"));
-    let self = this;
-
-    task.upload( function(success) {
-      while (parent.firstChild) {
-        parent.removeChild(parent.firstChild);
-      }
-      if (success) {
-        self.addThanksMessage(parent);
-        // TODO or should we move it to 'finished studies' immediately?
-      } else {
-        // TODO a better error message?
-        self.addLabel(
-          parent,
-          self._stringBundle.getString(
-            "testpilot.studiesWindow.unableToReachServer"));
-      }
-    });
-
-  },
-
-  addThanksMessage: function(container) {
-    // Fill in status box with icon and message to show success
-    let hbox = document.createElement("hbox");
-    container.appendChild(this.makeSpacer());
-    container.appendChild(hbox);
-    this.addLabel(
-      container,
-      this._stringBundle.getString(
-        "testpilot.studiesWindow.thanksForContributing"));
-    container.appendChild(this.makeSpacer());
-    hbox.appendChild(this.makeSpacer());
-    this.addImg(hbox, "study-submitted");
-    hbox.appendChild(this.makeSpacer());
-  },
-
-  addXulLink: function (container, text, url, openInTab) {
-    let linkContainer = document.createElement("hbox");
-    let link = document.createElement("label");
-    let spacer = document.createElement("spacer");
-    link.setAttribute("value", text);
-    link.setAttribute("class", "text-link");
-    if (openInTab) {
-      link.addEventListener("click",
-        function(event) {
-          if (event.button == 0) {
-            TestPilotWindowUtils.openInTab(url);
-          }
-        }, false);
-    } else {
-      link.addEventListener("click",
-        function(event) {
-          if (event.button == 0) {
-            TestPilotWindowUtils.openChromeless(url);
-          }
-        }, false);
-    }
-    linkContainer.appendChild(link);
-    spacer.setAttribute("flex", "1");
-    linkContainer.appendChild(spacer);
-    container.appendChild(linkContainer);
-  },
-
-  addLabel: function(container, text, styleClass) {
-    let label = document.createElement("label");
-    label.setAttribute("value", text);
-    if (styleClass) {
-      label.setAttribute("class", styleClass);
-    }
-    container.appendChild(label);
-  },
-
-  addImg: function(container, iconClass) {
-    let newImg = document.createElement("image");
-    newImg.setAttribute("class", iconClass);
-    container.appendChild(newImg);
-  },
-
-  makeSpacer: function() {
-    let spacer = document.createElement("spacer");
-    spacer.setAttribute("flex", "1");
-    return spacer;
-  },
-
-  addThumbnail: function(container, imgUrl) {
-    let boundingBox = document.createElement("vbox");
-    boundingBox.setAttribute("class", "results-thumbnail");
-    let bBox2 = document.createElement("hbox");
-
-    boundingBox.appendChild(this.makeSpacer());
-    boundingBox.appendChild(bBox2);
-    boundingBox.appendChild(this.makeSpacer());
-
-    bBox2.appendChild(this.makeSpacer());
-    let newImg = document.createElement("image");
-    newImg.setAttribute("src", imgUrl);
-    newImg.setAttribute("class", "results-thumbnail");
-    bBox2.appendChild(newImg);
-    bBox2.appendChild(this.makeSpacer());
-
-    container.appendChild(boundingBox);
-  },
-
-  addProgressBar: function(container, percent) {
-    let progBar = document.createElement("progressmeter");
-    progBar.setAttribute("mode", "determined");
-    progBar.setAttribute("value", Math.ceil(percent).toString());
-    container.appendChild(progBar);
-  },
-
-  addDescription: function(container, title, paragraph) {
-    let desc = document.createElement("description");
-    desc.setAttribute("class", "study-title");
-    let txtNode = document.createTextNode(title);
-    desc.appendChild(txtNode);
-    container.appendChild(desc);
-
-    desc = document.createElement("description");
-    desc.setAttribute("class", "study-description");
-    desc.setAttribute("crop", "none");
-    txtNode = document.createTextNode(paragraph);
-    desc.appendChild(txtNode);
-    container.appendChild(desc);
-  },
-
-  addButton: function(container, label, id, onClickHandler) {
-    let button = document.createElement("button");
-    button.setAttribute("label", this._stringBundle.getString(label));
-    button.setAttribute("id", id);
-    button.addEventListener("command", onClickHandler, false);
-    container.appendChild(button);
-  },
-
-  _sortNewestFirst: function(experiments) {
-    experiments.sort(
-      function sortFunc(a, b) {
-        if (a.endDate && b.endDate) {
-          return b.endDate - a.endDate;
-        }
-        if (a.publishDate && b.publishDate) {
-          if (isNaN(a.publishDate) || isNaN(b.publishDate)) {
-            return 0;
-          }
-          return b.publishDate - a.publishDate;
-        }
-        return 0;
-      });
-    return experiments;
-  },
-
-  onLoad: function () {
-    Components.utils.import("resource://testpilot/modules/Observers.js");
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    Components.utils.import("resource://testpilot/modules/tasks.js");
-
-    this._stringBundle = document.getElementById("testpilot-stringbundle");
-    this.sizeWindow();
-    this._init(false);
-    Observers.add("testpilot:task:changed", this._onTaskStatusChanged, this);
-  },
-
-  onUnload: function() {
-    document.getElementById("settings-pane").writePreferences(true);
-    Observers.remove("testpilot:task:changed", this._onTaskStatusChanged, this);
-  },
-
-  _onTaskStatusChanged : function() {
-    this._init(true);
-  },
-
-  onTakeSurveyButton: function(taskId) {
-    let task = TestPilotSetup.getTaskById(taskId);
-    TestPilotWindowUtils.openChromeless(task.defaultUrl);
-    task.onDetailPageOpened();
-  },
-
-  _init: function(aReload) {
-    if (!TestPilotSetup.startupComplete) {
-      // If you opened the window before tasks are done loading, exit now
-      // but try again in a few seconds.
-      window.setTimeout(
-        function() { TestPilotXulWindow._init(aReload); }, 2000);
-      return;
-    }
-
-    let numFinishedStudies = 0;
-    let numCurrentStudies = 0;
-
-    /* Remove 'loading' message */
-    let msg = window.document.getElementById("still-loading-msg");
-    msg.setAttribute("hidden", "true");
-
-    if (aReload) {
-      /* If we're reloading, start by clearing out any old stuff already
-       * present in the listboxes. */
-      let listboxIds =
-        ["current-studies-listbox", "finished-studies-listbox",
-         "study-results-listbox"];
-      for (let i = 0; i < listboxIds.length; i++) {
-        let listbox = document.getElementById(listboxIds[i]);
-
-        while (listbox.lastChild) {
-          listbox.removeChild(listbox.lastChild);
-        }
-      }
-    }
-
-    let experiments = TestPilotSetup.getAllTasks();
-    experiments = this._sortNewestFirst(experiments);
-
-    for (let i = 0; i < experiments.length; i++) {
-      let task = experiments[i];
-      let newRow = document.createElement("richlistitem");
-      newRow.setAttribute("class", "tp-study-list");
-
-      this.addThumbnail(newRow, task.thumbnail);
-
-      let textVbox = document.createElement("vbox");
-      newRow.appendChild(textVbox);
-
-      let openInTab = (task.taskType == TaskConstants.TYPE_LEGACY);
-
-      this.addDescription(textVbox, task.title, task.summary);
-      this.addXulLink(
-        textVbox, this._stringBundle.getString("testpilot.moreInfo"),
-        task.defaultUrl, openInTab);
-
-      // Create the rightmost status area, depending on status:
-      let statusVbox = document.createElement("vbox");
-      if (task.status == TaskConstants.STATUS_FINISHED) {
-        this.addLabel(
-          statusVbox,
-          this._stringBundle.getFormattedString(
-            "testpilot.studiesWindow.finishedOn",
-            [(new Date(task.endDate)).toLocaleDateString()]));
-        this.addButton(statusVbox,
-          "testpilot.submit",
-          "submit-button-" + task.id,
-          function() {TestPilotXulWindow.onSubmitButton(task.id)});
-      }
-      if (task.status == TaskConstants.STATUS_CANCELLED) {
-        let hbox = document.createElement("hbox");
-        newRow.setAttribute("class", "tp-opted-out");
-        statusVbox.appendChild(this.makeSpacer());
-        statusVbox.appendChild(hbox);
-        this.addLabel(
-          statusVbox,
-          this._stringBundle.getString("testpilot.studiesWindow.canceledStudy"));
-        statusVbox.appendChild(this.makeSpacer());
-        hbox.appendChild(this.makeSpacer());
-        this.addImg(hbox, "study-canceled");
-        hbox.appendChild(this.makeSpacer());
-      }
-      if (task.status == TaskConstants.STATUS_NEW ||
-          task.status == TaskConstants.STATUS_PENDING ) {
-        newRow.setAttribute("class", "tp-new-results");
-
-        if (task.taskType == TaskConstants.TYPE_SURVEY) {
-          this.addButton(
-            statusVbox,
-            "testpilot.takeSurvey",
-            "survey-button",
-            function(){TestPilotXulWindow.onTakeSurveyButton(task.id)});
-        } else if (task.taskType == TaskConstants.TYPE_EXPERIMENT) {
-          if (task.startDate) {
-            this.addLabel(
-              statusVbox,
-              this._stringBundle.getFormattedString(
-                "testpilot.studiesWindow.willStart",
-                [(new Date(task.startDate)).toLocaleDateString()]));
-          }
-        }
-      }
-      if (task.status == TaskConstants.STATUS_IN_PROGRESS ||
-          task.status == TaskConstants.STATUS_STARTING) {
-
-        if (task.taskType == TaskConstants.TYPE_SURVEY) {
-          this.addButton(
-            statusVbox,
-            "testpilot.takeSurvey",
-            "survey-button",
-            function(){TestPilotXulWindow.onTakeSurveyButton(task.id)});
-        } else if (task.taskType == TaskConstants.TYPE_EXPERIMENT) {
-          this.addLabel(
-            statusVbox,
-            this._stringBundle.getString(
-             "testpilot.studiesWindow.gatheringData"));
-             let now = (new Date()).getTime();
-          let progress =
-            100 * (now - task.startDate) / (task.endDate - task.startDate);
-          this.addProgressBar(statusVbox, progress);
-          this.addLabel(
-            statusVbox,
-            this._stringBundle.getFormattedString(
-              "testpilot.studiesWindow.willFinish",
-              [(new Date(task.endDate)).toLocaleDateString()]));
-        }
-      }
-      if (task.status >= TaskConstants.STATUS_SUBMITTED) {
-        if (task.taskType == TaskConstants.TYPE_RESULTS) {
-          let maintask = TestPilotSetup.getTaskById(task.relatedStudyId);
-          if (maintask && maintask.status >= TaskConstants.STATUS_SUBMITTED) {
-            this.addThanksMessage(statusVbox);
-          }
-        } else {
-          if (task.status == TaskConstants.STATUS_MISSED) {
-            // Icon for missed studies
-            let hbox = document.createElement("hbox");
-            newRow.setAttribute("class", "tp-opted-out");
-            statusVbox.appendChild(this.makeSpacer());
-            statusVbox.appendChild(hbox);
-            this.addLabel(
-              statusVbox,
-              this._stringBundle.getString("testpilot.studiesWindow.missedStudy"));
-            statusVbox.appendChild(this.makeSpacer());
-            hbox.appendChild(this.makeSpacer());
-            this.addImg(hbox, "study-missed");
-            hbox.appendChild(this.makeSpacer());
-          } else {
-            this.addThanksMessage(statusVbox);
-            numFinishedStudies ++;
-          }
-        }
-      }
-      let spacer = document.createElement("spacer");
-      spacer.setAttribute("flex", "1");
-      newRow.appendChild(spacer);
-      newRow.appendChild(statusVbox);
-
-      // Use status to decide which panel to add this to:
-      let rowset;
-      if (task.taskType == TaskConstants.TYPE_RESULTS) {
-        rowset = document.getElementById("study-results-listbox");
-      } else if (task.status > TaskConstants.STATUS_FINISHED) {
-        rowset = document.getElementById("finished-studies-listbox");
-      } else {
-        rowset = document.getElementById("current-studies-listbox");
-        numCurrentStudies++;
-      }
-
-      // TODO further distinguish by background colors.
-      rowset.appendChild(newRow);
-    }
-
-    // If there are no current studies, show a message about upcoming
-    // studies:
-    if (numCurrentStudies == 0) {
-      let newRow = document.createElement("richlistitem");
-      newRow.setAttribute("class", "tp-study-list");
-      this.addThumbnail(newRow, NO_STUDIES_IMG);
-      let textVbox = document.createElement("vbox");
-      textVbox.setAttribute("class", "pilot-largetext");
-      newRow.appendChild(textVbox);
-      this.addDescription(
-        textVbox, "",
-        this._stringBundle.getString("testpilot.studiesWindow.noStudies"));
-      this.addXulLink(
-        textVbox,
-        this._stringBundle.getString("testpilot.studiesWindow.proposeStudy"),
-        PROPOSE_STUDY_URL, true);
-      document.getElementById("current-studies-listbox").appendChild(newRow);
-    }
-
-    // Show number of studies the user finished on badge:
-    document.getElementById("num-finished-badge").setAttribute(
-      "value", numFinishedStudies);
-  },
-
-  sizeWindow: function() {
-    // Size listboxes based on available screen size, then size window to fit
-    // list boxes.
-    let currList = document.getElementById("current-studies-listbox");
-    let finList = document.getElementById("finished-studies-listbox");
-    let resultsList = document.getElementById("study-results-listbox");
-
-    let screenWidth = window.screen.availWidth;
-    let screenHeight = window.screen.availHeight;
-    let width = screenWidth >= 800 ? 700 : screenWidth - 100;
-    let height = screenHeight >= 800 ? 700 : screenHeight - 100;
-
-    height -= 130; // Or whatever is height of title bar plus windowdragbox
-
-    currList.width = width;
-    currList.height = height;
-    finList.width = width;
-    finList.height = height;
-    resultsList.width = width;
-    resultsList.height = height;
-    window.sizeToContent();
-  },
-
-  focusPane: function(paneIndex) {
-    document.getElementById("tp-xulwindow-deck").selectedIndex = paneIndex;
-
-    // When you focus the 'study findings' tab, any results there which
-    // are still marked "new" should have their status changed as the user
-    // is considered to have seen them.
-    if (paneIndex == 2) {
-      Components.utils.import("resource://testpilot/modules/setup.js");
-      Components.utils.import("resource://testpilot/modules/tasks.js");
-
-      let experiments = TestPilotSetup.getAllTasks();
-      for each (let experiment in experiments) {
-        if (experiment.taskType == TaskConstants.TYPE_RESULTS) {
-          if (experiment.status == TaskConstants.STATUS_NEW) {
-            experiment.changeStatus(TaskConstants.STATUS_ARCHIVED, true);
-          }
-        }
-      }
-    }
-  }
-};
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/all-studies-window.xul
+++ /dev/null
@@ -1,144 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
-<?xml-stylesheet href="chrome://global/skin/preferences.css" type="text/css"?>
-<?xml-stylesheet href="chrome://mozapps/content/extensions/extensions.css"
-  type="text/css"?>
-<?xml-stylesheet href="chrome://testpilot/content/browser.css" type="text/css"?>
-
-
-<!DOCTYPE prefwindow [
-  <!ENTITY % testpilotDTD SYSTEM "chrome://testpilot/locale/main.dtd">
-    %testpilotDTD;
-]>
-
-<prefwindow id="test-pilot-all-studies-window"
-  title="&testpilot.studiesWindow.title;"
-  windowtype="extensions:testpilot:all_studies_window"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="TestPilotXulWindow.onLoad();"
-  onunload="TestPilotXulWindow.onUnload();">
-
-  <script src="chrome://testpilot/content/window-utils.js"
-    type="application/javascript;version=1.8"/>
-  <script src="chrome://testpilot/content/all-studies-window.js"
-    type="application/javascript;version=1.8"/>
-  <script src="chrome://communicator/content/utilityOverlay.js"
-    type="application/javascript;version=1.8"/>
-
-  <stringbundleset id="stringbundleset">
-    <stringbundle id="testpilot-stringbundle"
-      src="chrome://testpilot/locale/main.properties" />
-  </stringbundleset>
-
-  <vbox flex="1">
-    <windowdragbox orient="vertical">
-      <radiogroup id="tp-radiogroup" orient="horizontal" role="listbox"
-        class="paneSelector"
-        onselect="TestPilotXulWindow.focusPane(this.selectedIndex);">
-        <radio pane="current-studies-pane-button" orient="vertical">
-          <image class="paneButtonIcon" />
-          <label class="paneButtonLabel"
-            value="&testpilot.studiesWindow.currentStudies.label;"/>
-        </radio>
-        <radio pane="finished-studies-pane-button" orient="vertical">
-          <stack align="center" pack="center">
-            <hbox align="center" pack="center">
-             <image class="paneButtonIcon" />
-            </hbox>
-            <label id="num-finished-badge" class="pane-button-badge"/>
-          </stack>
-          <label class="paneButtonLabel"
-            value="&testpilot.studiesWindow.finishedStudies.label;"/>
-        </radio>
-        <radio pane="study-results-pane-button" orient="vertical">
-          <image class="paneButtonIcon" />
-          <label class="paneButtonLabel"
-            value="&testpilot.studiesWindow.studyFindings.label;"/>
-        </radio>
-        <radio pane="settings-pane-button" orient="vertical">
-          <image class="paneButtonIcon" />
-          <label class="paneButtonLabel"
-            value="&testpilot.studiesWindow.settings.label;"/>
-        </radio>
-      </radiogroup>
-    </windowdragbox>
-
-    <deck id="tp-xulwindow-deck" flex="1">
-      <prefpane id="current-studies-pane" class="tp-tab-panel">
-        <richlistbox id="current-studies-listbox" class="tp-study-list"
-          disabled="true">
-          <richlistitem id="still-loading-msg" class="tp-study-list">
-            <description class="pilot-largetext">
-              &testpilot.studiesWindow.stillLoadingMessage;
-            </description>
-          </richlistitem>
-        </richlistbox>
-      </prefpane>
-
-      <prefpane id="finished-studies-pane" class="tp-tab-panel">
-        <richlistbox id="finished-studies-listbox" class="tp-study-list"
-          disabled="true"/>
-      </prefpane>
-
-      <prefpane id="study-results-pane" class="tp-tab-panel">
-        <richlistbox id="study-results-listbox" class="tp-study-list"
-          disabled="true"/>
-      </prefpane>
-
-      <prefpane id="settings-pane" class="tp-tab-panel">
-        <preferences>
-          <preference id="notify-finished" type="bool"
-                      name="extensions.testpilot.popup.showOnStudyFinished"/>
-          <preference id="notify-new" type="bool"
-                      name="extensions.testpilot.popup.showOnNewStudy"/>
-          <preference id="notify-results" type="bool"
-                      name="extensions.testpilot.popup.showOnNewResults"/>
-          <preference id="always-submit-data" type="bool"
-                      name="extensions.testpilot.alwaysSubmitData"/>
-        </preferences>
-        <vbox style="padding: 12px;">
-          <groupbox>
-            <caption label="&testpilot.settings.dataSubmission.label;" />
-            <checkbox label="&testpilot.settings.alwaysSubmitData.shortLabel;"
-                      preference="always-submit-data"/>
-          </groupbox>
-          <groupbox>
-            <caption label="&testpilot.settings.notifications.label;" />
-            <label value="&testpilot.settings.notifyWhen.label;"/>
-            <hbox>
-              <separator orient="vertical" />
-              <vbox>
-                <checkbox label="&testpilot.settings.readyToSubmit.label;"
-                          preference="notify-finished"/>
-                <checkbox label="&testpilot.settings.newStudy.label;"
-                          preference="notify-new"/>
-                <checkbox label="&testpilot.settings.hasNewResults.label;"
-                          preference="notify-results"/>
-              </vbox>
-            </hbox>
-          </groupbox>
-        </vbox>
-      </prefpane>
-    </deck>
-  </vbox>
-
-  <!-- For the menubar on mac, the below elements are needed for
-       macBrowserOverlay.xul to overlay this window. -->
-  <stringbundleset id="stringbundleset"/>
-
-  <commandset id="mainCommandSet"/>
-  <commandset id="baseMenuCommandSet"/>
-  <commandset id="placesCommands"/>
-
-  <broadcasterset id="mainBroadcasterSet"/>
-
-  <keyset id="mainKeyset"/>
-  <keyset id="baseMenuKeyset"/>
-
-  <menubar id="main-menubar" style="border:none !important;margin:0;padding:0;"/>
-
-</prefwindow>
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/all-studies.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-  <head>
-    <title>All Test Pilot Studies</title>
-    <script src="chrome://testpilot/content/all-studies.js"
-             type="application/javascript;version=1.8">
-    </script>
-  </head>
-  <body onload="fillAllStudiesPage();">
-    <h1>All Test Pilot Studies</h1>
-    <p id="still-loading-msg">Loading, please wait...</p>
-    <table id="studies-list"></table>
-  </body>
-</html>
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/all-studies.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// for the HTML version
-
-function _sortNewestFirst(experiments) {
-    experiments.sort(
-      function sortFunc(a, b) {
-        if (a.endDate && b.endDate) {
-          return b.endDate - a.endDate;
-        }
-        if (a.publishDate && b.publishDate) {
-          if (isNaN(a.publishDate) || isNaN(b.publishDate)) {
-            return 0;
-          }
-          return b.publishDate - a.publishDate;
-        }
-        return 0;
-      });
-    return experiments;
-}
-
-
-function fillAllStudiesPage() {
-  Components.utils.import("resource://testpilot/modules/Observers.js");
-  Components.utils.import("resource://testpilot/modules/setup.js");
-  Components.utils.import("resource://testpilot/modules/tasks.js");
-  //this._stringBundle = document.getElementById("testpilot-stringbundle");
-
-
-  // Are we done loading tasks?
-  if (!TestPilotSetup.startupComplete || TestPilotSetup.getAllTasks().length == 0) {
-    // If you opened the window before tasks are done loading, exit now
-    // but try again in a few seconds.
-    window.setTimeout(fillAllStudiesPage, 2000);
-    return;
-  }
-
-  // hide the 'loading' msg
-  window.document.getElementById("still-loading-msg").innerHTML = "";
-
-  // clear the table
-  let table = window.document.getElementById("studies-list");
-  table.innerHTML = "";
-
-  let experiments = _sortNewestFirst(TestPilotSetup.getAllTasks());
-
-  for (let i = 0; i < experiments.length; i++) {
-    let task = experiments[i];
-    let newRow = document.createElement("tr");
-
-    let newCell = document.createElement("td");
-    newCell.textContent = task.title;
-    newRow.appendChild(newCell);
-    newCell = document.createElement("td");
-    newCell.textContent = task.summary;
-    newRow.appendChild(newCell);
-
-    let link = document.createElement("a");
-    link.setAttribute("href", task.defaultUrl);
-    link.textContent = "More Info";
-
-    newCell = document.createElement("td");
-    newCell.appendChild(link);
-    newRow.appendChild(newCell);
-
-    table.appendChild(newRow);
-  }
-}
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/browser.css
+++ /dev/null
@@ -1,299 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Toolbar Button */
-
-#feedback-menu-button {
-  -moz-box-orient: horizontal;
-}
-
-#feedback-menu-button .toolbarbutton-icon {
-  display: none;
-}
-
-#feedback-menu-button .toolbarbutton-menu-dropmarker {
-  -moz-padding-start: 5px;
-}
-
-#pilot-notifications-button {
-  margin-right: 10px;
-}
-
-/* For Firefox 4 built-in popup notification system */
-#tp-notification-popup-icon {
-  list-style-image: url("chrome://testpilot/skin/testpilot_16x16.png");
-}
-
-#tp-notification-popup-box[anchorid="tp-notification-popup-icon"] > #tp-notification-popup-icon {
-  display: -moz-box;
-}
-
-#testpilot-notification {
-  -moz-binding: url("chrome://testpilot/content/notificationBindings.xml#testpilot-notification");
-}
-
-/* hide menu separator and "not now" item: */
-#testpilot-notification menuseparator { display: none }
-#testpilot-notification .popup-notification-closeitem { display: none }
-
-.testpilot-notification-title {
-    text-align: center;
-    font-size: large;
-}
-
-/* .popup-notification-icon[popupid="study-finished"] {
-  list-style-image: url("chrome://testpilot/skin/tp-submit-48x48.png");
-  height: 48px;
-  width: 48px;
-}
-.popup-notification-icon[popupid="new-study"] {
-  list-style-image: url("chrome://testpilot/skin/tp-study-48x48.png");
-  height: 48px;
-  width: 48px;
-}
-.popup-notification-icon[popupid="new-results"] {
-  list-style-image: url("chrome://testpilot/skin/tp-results-48x48.png");
-  height: 48px;
-  width: 48px;
-}
-.popup-notification-icon[popupid="study-submitted"] {
-  list-style-image: url("chrome://testpilot/skin/status-completed.png");
-  height: 32px;
-  width: 64px;
-}*/
-
-/* For older notification system */
-
-/* Popup Bounding Box */
-#pilot-notification-popup {
-  -moz-appearance: none;
-  -moz-window-shadow: none;
-  background-color: transparent;
-  margin-top: -6px;
-  margin-right: -3px;
-  width: 480px;
-}
-
-.tail-up {
- /* Needed whilst we support Gecko < 13 */
- -moz-border-image: url(chrome://testpilot-os/skin/notification-tail-up.png) 26 56 22 18 / 26px 56px 22px 18px round stretch;
- /* Supported in Gecko >= 13 */
- -moz-border-image: url(chrome://testpilot-os/skin/notification-tail-up.png) 26 50 22 18 fill repeat;
- border-width: 26px 56px 22px 18px;
- border-style: solid;
-}
-
-/* tail-down uses the old styling; it doesn't look as good as the new styling,
-   but the new styling doesn't work on 3.6.
-   TODO: If someone is using 3.7.* or 4.* but is NOT on the beta channel and
-   installed Test Pilot from AMO, they should get the new styling, similar
-   to .tail-up! */
-.tail-down {
- /* Needed whilst we support Gecko < 13 */
- -moz-border-image: url(chrome://testpilot/skin/notification-tail-down.png) 26 50 22 18 / 26px 50px 22px 18px repeat;
- /* Supported in Gecko >= 13 */
- -moz-border-image: url(chrome://testpilot/skin/notification-tail-down.png) 26 50 22 18 fill repeat;
- border-width: 26px 56px 22px 18px;
- border-style: solid;
- color: white;
-}
-
-.pilot-notification-popup-container {
-  -moz-appearance: none;
-  margin-right: -42px;
-  padding: 0px 5px 5px 5px;
-  font-size: 14px;
-}
-
-.pilot-notification-toprow {
-  margin-bottom: 12px;
-}
-
-#pilot-notification-text,
-#pilot-notification-link {
-  margin-bottom: 5px;
-}
-
-#pilot-notification-close {
-  list-style-image: url("chrome://testpilot-os/skin/close_button.png");
-  -moz-image-region: rect(0px, 14px, 14px, 0px);
-  width: 14px;
-  height: 14px;
-}
-
-#pilot-notification-close:hover {
-  -moz-image-region: rect(0px, 28px, 14px, 14px);
-}
-
-#pilot-notification-close:hover:active {
-  -moz-image-region: rect(0px, 42px, 14px, 28px);
-}
-
-.pilot-notify-me-when[disabled="true"] {
-  color: MenuText;
-}
-.pilot-title {
-  font-size: 25px;
-}
-
-image.study-finished {
-  list-style-image: url("chrome://testpilot/skin/tp-submit-48x48.png");
-  height: 48px;
-  width: 48px;
-  margin-right: 8px;
-}
-
-image.study-submitted {
-  list-style-image: url("chrome://testpilot/skin/status-completed.png");
-  height: 32px;
-  width: 64px;
-  margin-right: 8px;
-}
-
-image.study-canceled {
-  list-style-image: url("chrome://testpilot/skin/status-ejected.png");
-  height: 32px;
-  width: 64px;
-  margin-right: 8px;
-}
-
-image.study-missed {
-  list-style-image: url("chrome://testpilot/skin/status-missed.png");
-  height: 32px;
-  width: 64px;
-  margin-right: 8px;
-}
-
-image.new-study {
-  list-style-image: url("chrome://testpilot/skin/tp-study-48x48.png");
-  height: 48px;
-  width: 48px;
-  margin-right: 8px;
-}
-
-image.new-results {
-  list-style-image: url("chrome://testpilot/skin/tp-results-48x48.png");
-  height: 48px;
-  width: 48px;
-  margin-right: 8px;
-}
-
-image.update-extension {
-  list-style-image: url("chrome://testpilot/skin/testpilot_32x32.png");
-  height: 48px;
-  width: 48px;
-  margin-right: 8px;
-}
-
-image.study-result {
-  list-style-image: url("chrome://testpilot/skin/badge-default.png");
-  height: 96px;
-  width: 96px;
-  margin-right: 8px;
-}
-
-/* All studies window */
-.pilot-largetext {
-  font-size: 16px;
-}
-
-#test-pilot-all-studies-window > .prefWindow-dlgbuttons {
-    display: none;
-}
-
-.paneSelector {
-    margin: 0 !important;
-}
-
-.paneSelector radio[pane="current-studies-pane-button"] .paneButtonIcon {
-    list-style-image: url("chrome://testpilot/skin/tp-currentstudies-32x32.png");
-    padding-top: 3px;
-}
-.paneSelector radio[pane="finished-studies-pane-button"] .paneButtonIcon {
-    list-style-image: url("chrome://testpilot/skin/tp-completedstudies-32x32.png");
-    padding-top: 3px;
-}
-.paneSelector radio[pane="study-results-pane-button"] .paneButtonIcon {
-    list-style-image: url("chrome://testpilot/skin/tp-learned-32x32.png");
-    padding-top: 3px;
-}
-.paneSelector radio[pane="settings-pane-button"] .paneButtonIcon {
-    list-style-image: url("chrome://testpilot/skin/tp-settings-32x32.png");
-    padding-top: 3px;
-}
-
-.pane-button-badge {
-    background-color: green;
-    color: white;
-    font-weight: bold;
-    padding: 2px;
-    border-radius: 100%;
-    margin-right: 25px;
-    margin-bottom: 13px;
-}
-
-richlistbox.tp-study-list {
-    overflow: auto;
-    margin: 0px;
-}
-
-.tp-tab-panel {
-    background-color: -moz-dialog;
-    padding: 0px;
-}
-
-description.study-description {
-    width: 350px;
-}
-
-description.study-title {
-    width: 350px;
-    font-size: 20px;
-    text-align: left;
-    margin-top: 10px;
-}
-
-richlistitem.tp-study-list {
-    min-height: 120px;
-    color: black;
-    background-color: -moz-dialog;
-}
-
-richlistitem.tp-new-results {
-    min-height: 120px;
-    color: black;
-    background-color: LemonChiffon;
-}
-
-richlistitem.tp-opted-out {
-    min-height: 120px;
-    color: grey;
-    background-color: -moz-dialog;
-}
-
-vbox.results-thumbnail {
-    height: 120px;
-    width: 120px;
-}
-
-image.results-thumbnail {
-    max-height: 90px;
-    max-width:  90px;
-    margin: 10px;
-}
-
-.notification-link {
-    text-decoration: underline;
-    cursor: pointer;
-}
-
-prefpane .groupbox-body {
-  -moz-appearance: none;
-  padding: 8px 4px 4px 4px;
-}
-
-prefpane .groupbox-title {
-  background: url("chrome://global/skin/50pct_transparent_grey.png") repeat-x bottom left;
-  margin-bottom: 4px;
-}
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/browser.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var TestPilotMenuUtils;
-
-(function() {
-  var Cc = Components.classes;
-  var Cu = Components.utils;
-  var Ci = Components.interfaces;
-
-  Cu.import("resource://testpilot/modules/setup.js");
-
-  TestPilotMenuUtils = {
-    __prefs: null,
-    get _prefs() {
-      this.__prefs = Cc["@mozilla.org/preferences-service;1"]
-        .getService(Ci.nsIPrefBranch);
-      return this.__prefs;
-    },
-
-    updateSubmenu: function() {
-      let ntfyMenuFinished =
-        document.getElementById("pilot-menu-notify-finished");
-      let ntfyMenuNew = document.getElementById("pilot-menu-notify-new");
-      let ntfyMenuResults = document.getElementById("pilot-menu-notify-results");
-      let alwaysSubmitData =
-        document.getElementById("pilot-menu-always-submit-data");
-      ntfyMenuFinished.setAttribute("checked",
-                                    this._prefs.getBoolPref(POPUP_SHOW_ON_FINISH));
-      ntfyMenuNew.setAttribute("checked",
-                                 this._prefs.getBoolPref(POPUP_SHOW_ON_NEW));
-      ntfyMenuResults.setAttribute("checked",
-                                   this._prefs.getBoolPref(POPUP_SHOW_ON_RESULTS));
-      alwaysSubmitData.setAttribute("checked",
-                                    this._prefs.getBoolPref(ALWAYS_SUBMIT_DATA));
-    },
-
-    togglePref: function(id) {
-      let prefName = "extensions.testpilot." + id;
-      let oldVal = false;
-      if (this._prefs.prefHasUserValue(prefName)) {
-        oldVal = this._prefs.getBoolPref(prefName);
-      }
-      this._prefs.setBoolPref(prefName, !oldVal);
-
-      // If you turn on or off the global pref, startup or shutdown test pilot
-      // accordingly:
-      if (prefName == RUN_AT_ALL_PREF) {
-        if (oldVal == true) {
-          TestPilotSetup.globalShutdown();
-        }
-        if (oldVal == false) {
-          TestPilotSetup.globalStartup();
-        }
-      }
-    },
-
-    onPopupShowing: function(event) {
-      this._setMenuLabels();
-    },
-
-    onPopupHiding: function(event) {
-      let target = event.target;
-      if (target.id == "pilot-menu-popup") {
-        let menu = document.getElementById("pilot-menu");
-        if (target.parentNode != menu) {
-          menu.appendChild(target);
-        }
-      }
-    },
-
-    _setMenuLabels: function() {
-      // Make the enable/disable User Studies menu item show the right label
-      // for the current status...
-      let runStudiesToggle = document.getElementById("feedback-menu-enable-studies");
-      if (runStudiesToggle) {
-        let currSetting = this._prefs.getBoolPref(RUN_AT_ALL_PREF);
-
-        let stringBundle = Cc["@mozilla.org/intl/stringbundle;1"].
-          getService(Ci.nsIStringBundleService).
-          createBundle("chrome://testpilot/locale/main.properties");
-
-        if (currSetting) {
-          runStudiesToggle.setAttribute("label",
-            stringBundle.GetStringFromName("testpilot.turnOff"));
-        } else {
-          runStudiesToggle.setAttribute("label",
-            stringBundle.GetStringFromName("testpilot.turnOn"));
-        }
-      }
-
-      let studiesMenuItem = document.getElementById("feedback-menu-show-studies");
-      studiesMenuItem.setAttribute("disabled",
-                                   !this._prefs.getBoolPref(RUN_AT_ALL_PREF));
-    },
-
-    onMenuButtonMouseDown: function(attachPointId) {
-      if (!attachPointId) {
-        attachPointId = "pilot-notifications-button";
-      }
-      let menuPopup = document.getElementById("pilot-menu-popup");
-      let menuButton = document.getElementById(attachPointId);
-
-      // TODO failing here with "menuPopup is null" for Tracy
-      if (menuPopup.parentNode != menuButton)
-        menuButton.appendChild(menuPopup);
-
-      let alignment;
-      // Menu should appear above status bar icon, but below Feedback button
-      if (attachPointId == "pilot-notifications-button") {
-        alignment = "before_start";
-      } else {
-        alignment = "after_end";
-      }
-
-      menuPopup.openPopup(menuButton, alignment, 0, 0, true);
-    }
-  };
-
-
-  var TestPilotWindowHandlers = {
-    initialized: false,
-    onWindowLoad: function() {
-      try {
-      // Customize the interface of the newly opened window.
-      Cu.import("resource://testpilot/modules/interface.js");
-      TestPilotUIBuilder.buildCorrectInterface(window);
-
-      /* "Hold" window load events for TestPilotSetup, passing them along only
-       * after startup is complete.  It's hacky, but the benefit is that
-       * TestPilotSetup.onWindowLoad can treat all windows the same no matter
-       * whether they opened with Firefox on startup or were opened later. */
-
-      if (("TestPilotSetup" in window) && TestPilotSetup.startupComplete) {
-        TestPilotSetup.onWindowLoad(window);
-      } else {
-        let observerSvc = Cc["@mozilla.org/observer-service;1"]
-                             .getService(Ci.nsIObserverService);
-        let observer = {
-          observe: function(subject, topic, data) {
-            observerSvc.removeObserver(this, "testpilot:startup:complete");
-            TestPilotSetup.onWindowLoad(window);
-          }
-        };
-        observerSvc.addObserver(observer, "testpilot:startup:complete", false);
-      }
-
-      } catch (e) {
-        Cu.reportError(e);
-      }
-    },
-
-    onWindowUnload: function() {
-      TestPilotSetup.onWindowUnload(window);
-    }
-  };
-
-  window.addEventListener("load", TestPilotWindowHandlers.onWindowLoad, false);
-  window.addEventListener("unload", TestPilotWindowHandlers.onWindowUnload, false);
-}());
-
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/browser.xul
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<?xml-stylesheet href="chrome://testpilot/content/browser.css" type="text/css"?>
-
-<!DOCTYPE overlay [
-  <!ENTITY % testpilotDTD SYSTEM "chrome://testpilot/locale/main.dtd">
-    %testpilotDTD;
-]>
-
-<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-<script src="chrome://testpilot/content/browser.js"
-  type="application/x-javascript" />
-<script src="chrome://testpilot/content/window-utils.js"
-  type="application/x-javascript" />
-
-<toolbarpalette id="MailToolbarPalette">
-  <toolbarbutton id="feedback-menu-button"
-    type="menu" class="toolbarbutton-1" label="&testpilot.feedbackbutton.label;"
-    onmousedown="event.preventDefault();
-    TestPilotMenuUtils.onMenuButtonMouseDown('feedback-menu-button');"/>
-
-</toolbarpalette>
-
-</overlay>
\ No newline at end of file
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/debug.html
+++ /dev/null
@@ -1,303 +0,0 @@
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html> <head>
-<title>Test Pilot Debug Page</title>
-<script src="experiment-page.js" type="application/javascript;version=1.8"></script>
-<script type="application/javascript;version=1.8">
-
-  function getEid() {
-    var selector = document.getElementById("task-selector");
-    var i = selector.selectedIndex;
-    return selector.options[i].getAttribute("value");
-  }
-
-  function setTaskStatus() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    var newStatus = document.getElementById("status-code").value;
-    newStatus = parseInt(newStatus);
-    var task = TestPilotSetup.getTaskById(getEid());
-    task.changeStatus(newStatus, false);
-  }
-
-  function reloadAllExperiments() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    TestPilotSetup.reloadRemoteExperiments(function(success) {
-      let errors = TestPilotSetup._remoteExperimentLoader.getLoadErrors();
-      let str;
-      if (errors.length > 0) {
-        str = "<ul>";
-        for each (let errStr in errors) {
-          str += "<li>" + errStr + "</li>";          
-        }
-        str += "</ul>";
-      } else {
-        str = "All experiments reloaded, no errors.";
-      }
-      document.getElementById("debug").innerHTML = str;
-    });
-  }
-
-  function runUnitTests() {
-   Components.utils.import("resource://testpilot/tests/test_data_store.js");
-   runAllTests();
-  }
-
-  function testJarStore() {
-    var Cuddlefish = {};
-    Components.utils.import("resource://testpilot/modules/lib/cuddlefish.js",
-                        Cuddlefish);
-    var loader = new Cuddlefish.Loader(
-      {rootPaths: ["resource://testpilot/modules/",
-                   "resource://testpilot/modules/lib/"]});
-    var jarStoreModule = loader.require("jar-code-store");
-    var SecurableModule = loader.require("securable-module");
-    var jarStore = new jarStoreModule.JarStore();
-
-    // OK now watch this!  It's gonna be awesome!
-    var clientLoader = Cuddlefish.Loader(
-      {fs: new SecurableModule.CompositeFileSystem(
-         [jarStore, loader.fs])});
-    dump("Debug page Requiring toolbar study.\n");
-    var toolbarStudy = clientLoader.require("toolbar-study");
-    
-  }
-
-  function remindMe() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    TestPilotSetup._notifyUserOfTasks();
-    //TestPilotSetup._doHousekeeping();
-  }
-
-  function getCodeStorage() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    var loader = TestPilotSetup._remoteExperimentLoader;
-    return loader._jarStore;
-  }
-
-  function getSelectedFilename() {
-    var selector = document.getElementById("file-selector");
-    var i = selector.selectedIndex;
-    return selector.options[i].text;
-  }
-
-  function loadExperimentCode() {
-    var filename = getSelectedFilename();
-    var codeStore = getCodeStorage();
-    var textArea = document.getElementById("experiment-code-area");
-    var path = codeStore.resolveModule(null, filename);
-    code = codeStore.getFile(path).contents;
-    textArea.value = code;
-  }
-
-  function saveAndRun() {
-    var filename = getSelectedFilename();
-    var codeStore = getCodeStorage();
-    var path = codeStore.resolveModule(null, filename);
-    var textArea = document.getElementById("experiment-code-area");
-    codeStore.setLocalOverride(path, textArea.value);
-    reloadAllExperiments();
-  }
-
-  function showMetaData() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    let task = TestPilotSetup.getTaskById(getEid());
-    let json = task._prependMetadataToJSON(function(json) {
-      document.getElementById("debug").innerHTML = json;
-    });
-  }
-
-  function makeThereBeAPopup() {
-    document.getElementById("debug").innerHTML = "Making popup...";
-    Components.utils.import("resource://testpilot/modules/interface.js");
-    var notifier = TestPilotUIBuilder.getNotificationManager();
-    document.getElementById("debug").innerHTML = "Got Notfn Manager";
-    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].
-               getService(Components.interfaces.nsIWindowMediator);
-    var window = wm.getMostRecentWindow("navigator:browser") ||
-                 wm.getMostRecentWindow("mail:3pane");
-    document.getElementById("debug").innerHTML = "Got Window.";
-    try {
-    notifier.showNotification(window, { title: "This is title",
-                                        text: "This is text",
-                                        iconClass: "study-submitted",
-                                        moreInfoLabel: "This is a link",
-                                        moreInfoCallback: function() {dump("You picked More Info\n");},
-                                        closeCallback: function() {dump("You closed the notfn\n");},
-                                        fragile: true
-     });
-    } catch(e) {
-      document.getElementById("debug").innerHTML = "Error: " + e;
-    }
-  }
-
-  function wipeDb() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    var task = TestPilotSetup.getTaskById(getEid());
-    task.dataStore.wipeAllData();
-    var debug = document.getElementById("debug");
-    debug.innerHTML = "Wiped!";
-  }
-
-  function nukeDb() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    var task = TestPilotSetup.getTaskById(getEid());
-    task.dataStore.nukeTable();
-    var debug = document.getElementById("debug");
-    debug.innerHTML = "Nuked!";
-  }
-
-  function populateFileDropdown() {
-    var codeStore = getCodeStorage();
-    var files = codeStore.listAllFiles();
-    var selector = document.getElementById("file-selector");
-    var opt, i;
-    for (var i = 0; i < files.length; i++) {
-      opt = document.createElement("option");
-      opt.innerHTML = files[i];
-      selector.appendChild(opt);
-    }
-
-    selector = document.getElementById("task-selector");
-    var tasks = TestPilotSetup.getAllTasks();
-    var title;
-    for (i = 0; i < tasks.length; i++) {
-      opt = document.createElement("option");
-      title = tasks[i].title;
-      opt.innerHTML = title;
-      opt.setAttribute("value", tasks[i].id);
-      selector.appendChild(opt);
-    }
-  }
-
-  function showSelectedTaskStatus() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    var task = TestPilotSetup.getTaskById(getEid());
-    document.getElementById("show-status-span").innerHTML = task.status;
-    var selector = document.getElementById("status-selector");
-    selector.selectedIndex = task.status;
-  }
-
-  function resetSelectedTask() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    var task = TestPilotSetup.getTaskById(getEid());
-    task.changeStatus(0, true);
-    var prefService  = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-    var prefName= "extensions.testpilot.startDate." + task.id;
-    if (prefService.prefHasUserValue(prefName)) {
-      prefService.clearUserPref(prefName);
-    }
-  }
-
-  function setSelectedTaskStatus() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    var task = TestPilotSetup.getTaskById(getEid());
-
-    var selector = document.getElementById("status-selector");
-    var i = selector.selectedIndex;
-    var newStatus = parseInt( selector.options[i].value );
-    task.changeStatus(newStatus, false);
-  }
-
-  function showIndexFileDropdown() {
-    var prefService  = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-    var prefName = "extensions.testpilot.indexFileName";
-    var selector = document.getElementById("index-file-selector");
-    switch (prefService.getCharPref(prefName)) {
-      case "index.json":
-        selector.selectedIndex = 0;
-      break;
-      case "index-dev.json":
-        selector.selectedIndex = 1;
-      break;
-      case "index-mobile.json":
-        selector.selectedIndex = 2;
-      break;
-      case "index-tb-dev.json":
-        selector.selectedIndex = 3;
-      break;
-    }
-  }
-
-  function setSelectedIndexFile() {
-    document.getElementById("debug").innerHTML = "Setting index file";
-    try {
-    var prefService  = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
-    var prefName = "extensions.testpilot.indexFileName";
-    var selector = document.getElementById("index-file-selector");
-    var i = selector.selectedIndex;
-    document.getElementById("debug").innerHTML = "Setting index file to " + selector.options[i].value;
-    prefService.setCharPref( prefName, selector.options[i].value );
-
-    // DELETE CACHED INDEX FILE
-    var file = Components.classes["@mozilla.org/file/directory_service;1"].
-                     getService(Components.interfaces.nsIProperties).
-                     get("ProfD", Components.interfaces.nsIFile);
-    file.append("TestPilotExperimentFiles");
-    file.append("index.json");
-    if (file.exists()) {
-      file.remove(false);
-    }
-    } catch(e) {
-       document.getElementById("debug").innerHTML = "Error: " + e;
-    }
-  }
-
-</script>
-
-<style type="text/css">
-      canvas { border: 1px solid black; }
-    </style>
-
-</head>
-
-<body onload="populateFileDropdown();showSelectedTaskStatus();showIndexFileDropdown();">
-
-<fieldset>
-<p><select id="task-selector" onchange="showSelectedTaskStatus();"></select> Current Status = <span id="show-status-span"></span>.
-<button onclick="resetSelectedTask();showSelectedTaskStatus();">Reset Task</button>
-or set it to
-<select id="status-selector" onchange="setSelectedTaskStatus(); showSelectedTaskStatus();">
-  <option value="0">0 (New)</option>
-  <option value="1">1 (Pending)</option>
-  <option value="2">2 (Starting)</option>
-  <option value="3">3 (In Progress)</option>
-  <option value="4">4 (Finished)</option>
-  <option value="5">5 (Cancelled)</option>
-  <option value="6">6 (Submitted)</option>
-  <option value="7">7 (Results)</option>
-  <option value="8">8 (Archived)</option>
-</select>
-<button onclick="wipeDb();">Wipe My Data</button>
-<button onclick="nukeDb();">NUKE</button>
-<button onclick="uploadData();">Upload My Data</button>
-<button onclick="showMetaData();">Show Metadata</button>
-<button onclick="runUnitTests();">Run Tests</button>
-</fieldset>
-<fieldset>
-<p><button onclick="makeThereBeAPopup();">Show Dummy Popup</button>
-<button onclick="reloadAllExperiments();">Reload All Experiments</button>
-<button onclick="remindMe();">Notify Me</button>
-<button onclick="testJarStore();">Test Jar Store</button>
-Index file: 
-<select id="index-file-selector" onchange="setSelectedIndexFile();">
-  <option value="index.json">index.json</option>
-  <option value="index-dev.json">index-dev.json</option>
-  <option value="index-mobile.json">index-mobile.json</option>
-  <option value="index-tb-dev.json">index-tb-dev.json</option>
-</select>
-</p>
-</fieldset>
-<p><span id="debug"></span></p>
-
-
-<textarea id="experiment-code-area" rows="40" cols="80">
-</textarea>
-<select id="file-selector"></select>
-<button onclick="loadExperimentCode();">Load Ye Code</button>
-<button onclick="saveAndRun();">Save And Run Ye Code</button>
-
-
-</body> </html>
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/experiment-page.js
+++ /dev/null
@@ -1,491 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const PAGE_TYPE_STATUS = 0;
-const PAGE_TYPE_QUIT = 1;
-var stringBundle;
-
-  function showRawData(experimentId) {
-    window.openDialog(
-      "chrome://testpilot/content/raw-data-dialog.xul",
-      "TestPilotRawDataDialog", "chrome,centerscreen,resizable,scrollbars",
-      experimentId);
-  }
-
-  function getUrlParam(name) {
-    // from http://www.netlobo.com/url_query_string_javascript.html
-    name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
-    var regexS = "[\\?&]"+name+"=([^&#]*)";
-    var regex = new RegExp(regexS);
-    var results = regex.exec(window.location.href);
-    if( results == null )
-      return "";
-    else
-      return results[1];
-  }
-
-  function uploadData() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    let eid = getUrlParam("eid");
-    let task = TestPilotSetup.getTaskById(eid);
-
-    // If always-submit-checkbox is checked, set the pref
-    if (task._recursAutomatically) {
-      let checkBox = document.getElementById("always-submit-checkbox");
-      if (checkBox && checkBox.checked) {
-        task.setRecurPref(TaskConstants.ALWAYS_SUBMIT);
-      }
-    }
-
-    // Study web content must provide an element with id 'upload-status'.
-    // Fill it first with a message about data being uploaded; if there's
-    // an error, replace it with the error message.
-    let uploadStatus = document.getElementById("upload-status");
-    uploadStatus.textContent =
-      stringBundle.GetStringFromName("testpilot.statusPage.uploadingData");
-    task.upload( function(success) {
-      if (success) {
-        onStatusPageLoad();
-      } else {
-        // Replace 'now uploading' message
-        let errorParagraph = document.createElement("p");
-        errorParagraph.textContent = stringBundle.GetStringFromName("testpilot.statusPage.uploadErrorMsg");
-        let willRetryParagraph = document.createElement("p");
-        willRetryParagraph.textContent = stringBundle.GetStringFromName("testpilot.statusPage.willRetry");
-        uploadStatus.innerHTML = "";
-        uploadStatus.appendChild(errorParagraph);
-        uploadStatus.appendChild(willRetryParagraph);
-      }
-    });
-  }
-
-  function deleteData() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    Components.utils.import("resource://testpilot/modules/tasks.js");
-    let eid = getUrlParam("eid");
-    let task = TestPilotSetup.getTaskById(eid);
-    task.dataStore.wipeAllData();
-    // reload the URL after wiping all data.
-    window.location = "chrome://testpilot/content/status.html?eid=" + eid;
-  }
-
-  function saveCanvas(canvas) {
-    const nsIFilePicker = Components.interfaces.nsIFilePicker;
-    let filePicker = Components.classes["@mozilla.org/filepicker;1"].
-      createInstance(nsIFilePicker);
-    filePicker.init(window, null, nsIFilePicker.modeSave);
-    filePicker.appendFilters(
-	nsIFilePicker.filterImages | nsIFilePicker.filterAll);
-    filePicker.defaultString = "canvas.png";
-
-    let response = filePicker.show();
-    if (response == nsIFilePicker.returnOK ||
-	response == nsIFilePicker.returnReplace) {
-      const nsIWebBrowserPersist = Components.interfaces.nsIWebBrowserPersist;
-      let file = filePicker.file;
-
-      // create a data url from the canvas and then create URIs of the source
-      // and targets
-      let io = Components.classes["@mozilla.org/network/io-service;1"].
-	getService(Components.interfaces.nsIIOService);
-      let source = io.newURI(canvas.toDataURL("image/png", ""), "UTF8", null);
-      let target = io.newFileURI(file);
-
-      // prepare to save the canvas data
-      let persist = Components.classes[
-	"@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].
-	  createInstance(nsIWebBrowserPersist);
-      persist.persistFlags = nsIWebBrowserPersist.
-	PERSIST_FLAGS_REPLACE_EXISTING_FILES;
-      persist.persistFlags |= nsIWebBrowserPersist.
-        PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
-
-      // displays a download dialog (remove these 3 lines for silent download)
-      let xfer = Components.classes["@mozilla.org/transfer;1"].
-	createInstance(Components.interfaces.nsITransfer);
-      xfer.init(source, target, "", null, null, null, persist);
-      persist.progressListener = xfer;
-
-      // save the canvas data to the file
-      persist.saveURI(source, null, null, null, null, file);
-    }
-  }
-
-  function exportData() {
-    const nsIFilePicker = Components.interfaces.nsIFilePicker;
-    let filePicker = Components.classes["@mozilla.org/filepicker;1"].
-      createInstance(nsIFilePicker);
-    let eid = getUrlParam("eid");
-    let task = TestPilotSetup.getTaskById(eid);
-
-    filePicker.init(window, null, nsIFilePicker.modeSave);
-    filePicker.appendFilters(
-	nsIFilePicker.filterImages | nsIFilePicker.filterAll);
-    filePicker.defaultString = task.title + ".csv";
-
-    let response = filePicker.show();
-    if (response == nsIFilePicker.returnOK ||
-	response == nsIFilePicker.returnReplace) {
-      const nsIWebBrowserPersist = Components.interfaces.nsIWebBrowserPersist;
-      let foStream =
-        Components.classes["@mozilla.org/network/file-output-stream;1"].
-	  createInstance(Components.interfaces.nsIFileOutputStream);
-      let converter =
-        Components.classes["@mozilla.org/intl/converter-output-stream;1"].
-	  createInstance(Components.interfaces.nsIConverterOutputStream);
-      let file = filePicker.file;
-      let dataStore = task.dataStore;
-      let columnNames = dataStore.getHumanReadableColumnNames();
-      let propertyNames = dataStore.getPropertyNames();
-      let csvString = "";
-
-      // titles
-      for (let i = 0; i < columnNames.length; i++) {
-	csvString += "\"" + columnNames[i] + "\",";
-      }
-      if (csvString.length > 0) {
-	csvString = csvString.substring(0, (csvString.length - 1));
-        csvString += "\n";
-      }
-
-      dataStore.getAllDataAsJSON(true, function(rawData) {
-        // data
-        for (let i = 0; i < rawData.length; i++) {
-          for (let j = 0; j < columnNames.length; j++) {
-	    csvString += "\"" + rawData[i][propertyNames[j]] + "\",";
-          }
-	  csvString = csvString.substring(0, (csvString.length - 1));
-          csvString += "\n";
-        }
-
-        // write, create, truncate
-        foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0);
-        converter.init(foStream, "UTF-8", 0, 0);
-        converter.writeString(csvString);
-        converter.close();
-      });
-    }
-  }
-
-  function openLink(url) {
-    const THUNDERBIRD_APP_ID = "{3550f703-e582-4d05-9a08-453d09bdfdc6}";
-
-    if (Application.id == THUNDERBIRD_APP_ID) {
-      Components.classes["@mozilla.org/messenger;1"]
-                .createInstance(Components.interfaces.nsIMessenger)
-                .launchExternalURL(url);
-    }
-    else {
-      // open the link in the chromeless window
-      let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-                         .getService(Components.interfaces.nsIWindowMediator);
-      let recentWindow = wm.getMostRecentWindow("navigator:browser");
-
-      if (recentWindow) {
-        recentWindow.TestPilotWindowUtils.openInTab(url);
-      } else {
-        window.open(url);
-      } 
-    }
-  }
-
-  function getTestEndingDate(experimentId) {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    var task = TestPilotSetup.getTaskById(experimentId);
-    var endDate = new Date(task.endDate);
-    var diff = (endDate - Date.now());
-    var span = document.getElementById("test-end-time");
-    if (!span) {
-      return;
-    }
-    if (diff < 0) {
-      span.textContent =
-        stringBundle.GetStringFromName("testpilot.statusPage.endedAlready");
-      return;
-    }
-    var hours = diff / (60 * 60 * 1000);
-    if (hours < 24) {
-      span.textContent =
-        stringBundle.formatStringFromName(
-	  "testpilot.statusPage.todayAt", [endDate.toLocaleTimeString()], 1);
-    } else {
-      span.textContent =
-        stringBundle.formatStringFromName(
-	  "testpilot.statusPage.endOn", [endDate.toLocaleString()], 1);
-    }
-  }
-
-  function showMetaData() {
-    Components.utils.import("resource://testpilot/modules/metadata.js");
-    Components.utils.import("resource://gre/modules/PluralForm.jsm");
-    MetadataCollector.getMetadata(function(md) {
-      var mdLocale = document.getElementById("md-locale");
-      if (mdLocale)
-        mdLocale.textContent = md.location;
-      var mdVersion = document.getElementById("md-version");
-      if (mdVersion)
-        mdVersion.textContent = md.version;
-      var mdOs = document.getElementById("md-os");
-      if (mdOs)
-        mdOs.textContent = md.operatingSystem;
-      var mdNumExt = document.getElementById("md-num-ext");
-      if (mdNumExt) {
-        // This computes the correctly localized singular or plural string
-        // of the number of extensions, e.g. "1 extension", "2 extensions", etc.
-        let str = stringBundle.GetStringFromName("testpilot.statusPage.numExtensions");
-        var numExt = md.extensions.length;
-        mdNumExt.textContent = PluralForm.get(numExt, str).replace("#1", numExt);
-      }
-    });
-  }
-
-  function onQuitPageLoad() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    setStrings(PAGE_TYPE_QUIT);
-    let eid = getUrlParam("eid");
-    let task = TestPilotSetup.getTaskById(eid);
-    let header = document.getElementById("about-quit-title");
-    header.textContent =
-      stringBundle.formatStringFromName(
-	"testpilot.quitPage.aboutToQuit", [task.title], 1);
-
-    if (task._recursAutomatically) {
-      document.getElementById("recur-options").setAttribute("style", "");
-      document.getElementById("recur-checkbox-container").
-        setAttribute("style", "");
-    }
-  }
-
-  function quitExperiment() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    Components.utils.import("resource://testpilot/modules/tasks.js");
-    let eid = getUrlParam("eid");
-    let reason = document.getElementById("reason-for-quit").value;
-    let task = TestPilotSetup.getTaskById(eid);
-    task.optOut(reason, function(success) {
-      // load the you-are-canceleed page.
-      $("#quit-ui").slideUp();
-      $("#main-experiment-ui").slideDown();
-      onStatusPageLoad();
-    });
-
-    // If opt-out-forever checkbox is checked, opt out forever!
-    if (task._recursAutomatically) {
-      let checkBox = document.getElementById("opt-out-forever");
-      if (checkBox.checked) {
-        task.setRecurPref(TaskConstants.NEVER_SUBMIT);
-      }
-      // quit test so rescheduling
-      task._reschedule();
-    }
-  }
-
-  function updateRecurSettings() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    let eid = getUrlParam("eid");
-    let experiment = TestPilotSetup.getTaskById(eid);
-    let recurSelector = document.getElementById("recur-selector");
-    let newValue = recurSelector.options[recurSelector.selectedIndex].value;
-    experiment.setRecurPref(parseInt(newValue));
-  }
-
-  function showRecurControls(experiment) {
-    Components.utils.import("resource://testpilot/modules/tasks.js");
-    let recurPrefSpan = document.getElementById("recur-pref");
-    if (!recurPrefSpan) {
-      return;
-    }
-    let days = experiment._recurrenceInterval;
-    recurPrefSpan.textContent =
-      stringBundle.formatStringFromName(
-	"testpilot.statusPage.recursEveryNumberOfDays", [days], 1);
-
-    let controls = document.getElementById("recur-controls");
-    let selector = document.createElement("select");
-    controls.appendChild(selector);
-    selector.addEventListener("change", updateRecurSettings, false);
-    selector.setAttribute("id", "recur-selector");
-
-    let option = document.createElement("option");
-    option.setAttribute("value", TaskConstants.ASK_EACH_TIME);
-    if (experiment.recurPref == TaskConstants.ASK_EACH_TIME) {
-      option.setAttribute("selected", "true");
-    }
-    option.textContent =
-      stringBundle.GetStringFromName(
-	"testpilot.statusPage.askMeBeforeSubmitData");
-    selector.appendChild(option);
-
-    option = document.createElement("option");
-    option.setAttribute("value", TaskConstants.ALWAYS_SUBMIT);
-    if (experiment.recurPref == TaskConstants.ALWAYS_SUBMIT) {
-      option.setAttribute("selected", "true");
-    }
-    option.textContent =
-      stringBundle.GetStringFromName(
-	"testpilot.statusPage.alwaysSubmitData");
-    selector.appendChild(option);
-
-    option = document.createElement("option");
-    option.setAttribute("value", TaskConstants.NEVER_SUBMIT);
-    if (experiment.recurPref == TaskConstants.NEVER_SUBMIT) {
-      option.setAttribute("selected", "true");
-    }
-    option.textContent =
-      stringBundle.GetStringFromName(
-	"testpilot.statusPage.neverSubmitData");
-    selector.appendChild(option);
-  }
-
-  function loadExperimentPage() {
-    Components.utils.import("resource://testpilot/modules/setup.js");
-    Components.utils.import("resource://testpilot/modules/tasks.js");
-    var contentDiv = $("#experiment-specific-text");
-    var dataPrivacyDiv = $("#data-privacy-text");
-    // Get experimentID from the GET args of page
-    var eid = getUrlParam("eid");
-    var experiment = TestPilotSetup.getTaskById(eid);
-    if (!experiment) {
-      // Possible that experiments aren't done loading yet.  Try again in
-      // a few seconds.
-      contentDiv.html(stringBundle.GetStringFromName("testpilot.statusPage.loading"));
-      window.setTimeout(function() { loadExperimentPage(); }, 2000);
-      return;
-    }
-
-    // Fill in "opt out" and "raw data" links.
-    $("#raw-data-link").attr("href", "raw-data.html?eid=" + eid);
-
-    // Let the experiment fill in its web content (asynchronous)
-    experiment.getWebContent(function(webContent) {
-      contentDiv.html(webContent);
-
-      // Metadata and start/end date should be filled in for every experiment:
-      showMetaData();
-      getTestEndingDate(eid);
-      if (experiment._recursAutomatically &&
-        experiment.status != TaskConstants.STATUS_FINISHED) {
-        showRecurControls(experiment);
-      }
-
-      // Do whatever the experiment's web content wants done on load
-      // (Usually drawing a graph) - must be done after innerHTML is set.
-      experiment.webContent.onPageLoad(experiment, document, jQuery);
-    });
-
-    experiment.getDataPrivacyContent(function(dataPrivacyContent) {
-      if (dataPrivacyContent && dataPrivacyContent.length > 0) {
-        dataPrivacyDiv.html(dataPrivacyContent);
-        dataPrivacyDiv.removeAttr("hidden");
-      }
-    });
-  }
-
-  function onStatusPageLoad() {
-    setStrings(PAGE_TYPE_STATUS);
-    /* An experiment ID (eid) must be provided in the url params. Show status
-     * for that experiment.*/
-    loadExperimentPage();
-  }
-
-  function toggleSection(id) {
-    let div = $("#" + id + "-text");
-    div.slideToggle();
-    let button = $("#" + id + "-button");
-    if (button.html() == "Hide") {
-      button.html("Show");
-    } else {
-      button.html("Hide");
-    }
-  }
-
-  function setStrings(pageType) {
-    Components.utils.import("resource://gre/modules/Services.jsm");
-
-    stringBundle =
-      Components.classes["@mozilla.org/intl/stringbundle;1"].
-        getService(Components.interfaces.nsIStringBundleService).
-	  createBundle("chrome://testpilot/locale/main.properties");
-    let map;
-    let mapLength;
-
-    if (pageType == PAGE_TYPE_STATUS) {
-      map = [
-	{ id: "page-title", stringKey: "testpilot.fullBrandName" },
-	{ id: "comments-and-discussions-link",
-	  stringKey: "testpilot.page.commentsAndDiscussions" },
-	{ id: "propose-test-link",
-	  stringKey: "testpilot.page.proposeATest" },
-	{ id: "testpilot-twitter-link",
-	  stringKey: "testpilot.page.testpilotOnTwitter" }
-      ];
-    } else if (pageType == PAGE_TYPE_QUIT) {
-      map = [
-	{ id: "page-title", stringKey: "testpilot.fullBrandName" },
-	{ id: "comments-and-discussions-link",
-	  stringKey: "testpilot.page.commentsAndDiscussions" },
-	{ id: "propose-test-link",
-	  stringKey: "testpilot.page.proposeATest" },
-	{ id: "testpilot-twitter-link",
-	  stringKey: "testpilot.page.testpilotOnTwitter" },
-	{ id: "optional-message",
-	  stringKey: "testpilot.quitPage.optionalMessage" },
-	{ id: "reason-text",
-	  stringKey: "testpilot.quitPage.reason" },
-	{ id: "recur-options",
-	  stringKey: "testpilot.quitPage.recurringStudy" },
-	{ id: "quit-forever-text",
-	  stringKey: "testpilot.quitPage.quitForever" },
-	{ id: "quit-study-link",
-	  stringKey: "testpilot.quitPage.quitStudy" }
-      ];
-    }
-    mapLength = map.length;
-    for (let i = 0; i < mapLength; i++) {
-      let entry = map[i];
-      let elem = document.getElementById(entry.id);
-      if (!elem) {
-        Services.console.logStringMessage("No elem as " + entry.id +".\n");
-        continue;
-      }
-      elem.textContent = stringBundle.GetStringFromName(entry.stringKey);
-    }
-  }
-
-function showDbContentsHtml() {
-  Components.utils.import("resource://testpilot/modules/setup.js");
-  var experimentId = getUrlParam("eid");
-  var experiment = TestPilotSetup.getTaskById(experimentId);
-  var dataStore = experiment.dataStore;
-  var table = document.getElementById("raw-data-table");
-  var columnNames = dataStore.getHumanReadableColumnNames();
-  var propertyNames = dataStore.getPropertyNames();
-
-  $("title").html("Raw Data For " + experiment.title + " Study");
-
-  var headerRow = $("#raw-data-header-row");
-
-  var i, j;
-  for (j = 0; j < columnNames.length; j++) {
-    headerRow.append($("<th></th>").html(columnNames[j]));
-  }
-
-  dataStore.getAllDataAsJSON(true, function(rawData) {
-    // Convert each object in the JSON into a row of the table.
-    for (i = 0; i < rawData.length; i++) {
-      var row = $("<tr></tr>");
-      for (j = 0; j < columnNames.length; j++) {
-        row.append($("<td></td>").html(rawData[i][propertyNames[j]]));
-      }
-      $("#raw-data-table").append(row);
-    }
-  });
-
-}
-
-function showQuitUi() {
-  $('#quit-ui').slideDown();
-  $("#main-experiment-ui").slideUp();
-  onQuitPageLoad();
-}
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/feedback-browser.xul
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<?xml-stylesheet href="chrome://testpilot/content/browser.css" type="text/css"?>
-<?xml-stylesheet href="chrome://testpilot-os/skin/feedback.css" type="text/css"?>
-
-<!DOCTYPE overlay [
-  <!ENTITY % testpilotDTD SYSTEM "chrome://testpilot/locale/main.dtd">
-    %testpilotDTD;
-]>
-
-<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-<menupopup id="menu_ToolsPopup">
-  <menu id="pilot-menu" insertafter="menu_openAddons" />
-</menupopup>
-<menupopup id="taskPopup">
-  <menu id="pilot-menu" insertafter="addonsManager" />
-</menupopup>
-
-<toolbar id="nav-bar">
-  <panel id="pilot-notification-popup"/>
-</toolbar>
-<!-- XXX Disabled until we're ready for the feedback button.
-<toolbar id="mail-bar3">
-  <panel id="pilot-notification-popup"/>
-</toolbar>
--->
-
-
-<panel id="pilot-notification-popup" hidden="true" noautofocus="true"
-  level="parent" position="after_start">
-  <vbox class="pilot-notification-popup-container">
-    <hbox class="pilot-notification-toprow">
-      <image id="pilot-notification-icon" />
-      <vbox pack="center">
-        <label id="pilot-notification-title" class="pilot-title" />
-      </vbox>
-      <spacer flex="1" />
-      <vbox pack="start">
-        <image id="pilot-notification-close"
-          tooltiptext="&testpilot.notification.close.tooltip;" />
-      </vbox>
-    </hbox>
-    <description id="pilot-notification-text" />
-    <hbox align="right"><label id="pilot-notification-link" /></hbox>
-    <hbox>
-      <checkbox id="pilot-notification-always-submit-checkbox"
-        label="&testpilot.settings.alwaysSubmitData.shortLabel;" />
-      <spacer flex="1" />
-    </hbox>
-    <hbox align="right">
-      <button id="pilot-notification-submit" />
-    </hbox>
-  </vbox>
-</panel>
-
-<menu id="pilot-menu" class="menu-iconic"
-      label="&testpilot.feedbackbutton.label;"
-      insertafter="addonsManager">
-  <menupopup id="pilot-menu-popup"
-             onpopupshowing="TestPilotMenuUtils.onPopupShowing(event);"
-             onpopuphiding="TestPilotMenuUtils.onPopupHiding(event);">
-<!-- XXX Disabled until we're ready for the feedback button.
-    <menuitem id="feedback-menu-happy-button"
-              class="menuitem-iconic"
-              image="chrome://testpilot-os/skin/feedback-smile-16x16.png"
-              label="&testpilot.happy.label;"
-              thunderbirdLabel="&testpilot.happy.thunderbirdLabel;"
-              oncommand="TestPilotWindowUtils.openFeedbackPage('happy');"/>
-    <menuitem id="feedback-menu-sad-button"
-              class="menuitem-iconic"
-              image="chrome://testpilot-os/skin/feedback-frown-16x16.png"
-              label="&testpilot.sad.label;"
-              thunderbirdLabel="&testpilot.sad.thunderbirdLabel;"
-              oncommand="TestPilotWindowUtils.openFeedbackPage('sad');"/>
-    <menuseparator/>
--->
-    <menuitem id="feedback-menu-show-studies"
-              label="&testpilot.allYourStudies.label;"
-              oncommand="TestPilotWindowUtils.openAllStudiesWindow();"/>
-    <menuitem id="feedback-menu-enable-studies" 
-              label="&testpilot.enable.label;"
-              oncommand="TestPilotMenuUtils.togglePref('runStudies');"/>
-  </menupopup>
-</menu>
-</overlay>
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/fennec-options.xul
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-
-<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <setting pref="extensions.testpilot.runStudies" type="bool" title="Run User Studies"/>
-  <setting pref="extensions.testpilot.alwaysSubmitData" type="bool" title="Automatically Submit">
-    Data from finished studies will be submitted without asking you each time.
-  </setting>
-  <setting title="Test Pilot Studies" type="control">
-    See all Test Pilot studies currently running
-    <button id="see-all-studies-button" label="See All Studies"
-            oncommand="TestPilotWindowUtils.openAllStudies();"/>
-  </setting>
-</vbox>
\ No newline at end of file
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.colorhelpers.js
+++ /dev/null
@@ -1,174 +0,0 @@
-/* Plugin for jQuery for working with colors.
- * 
- * Version 1.0.
- * 
- * Inspiration from jQuery color animation plugin by John Resig.
- *
- * Released under the MIT license by Ole Laursen, October 2009.
- *
- * Examples:
- *
- *   $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
- *   var c = $.color.extract($("#mydiv"), 'background-color');
- *   console.log(c.r, c.g, c.b, c.a);
- *   $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
- *
- * Note that .scale() and .add() work in-place instead of returning
- * new objects.
- */ 
-
-(function() {
-    jQuery.color = {};
-
-    // construct color object with some convenient chainable helpers
-    jQuery.color.make = function (r, g, b, a) {
-        var o = {};
-        o.r = r || 0;
-        o.g = g || 0;
-        o.b = b || 0;
-        o.a = a != null ? a : 1;
-
-        o.add = function (c, d) {
-            for (var i = 0; i < c.length; ++i)
-                o[c.charAt(i)] += d;
-            return o.normalize();
-        };
-        
-        o.scale = function (c, f) {
-            for (var i = 0; i < c.length; ++i)
-                o[c.charAt(i)] *= f;
-            return o.normalize();
-        };
-        
-        o.toString = function () {
-            if (o.a >= 1.0) {
-                return "rgb("+[o.r, o.g, o.b].join(",")+")";
-            } else {
-                return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")";
-            }
-        };
-
-        o.normalize = function () {
-            function clamp(min, value, max) {
-                return value < min ? min: (value > max ? max: value);
-            }
-            
-            o.r = clamp(0, parseInt(o.r), 255);
-            o.g = clamp(0, parseInt(o.g), 255);
-            o.b = clamp(0, parseInt(o.b), 255);
-            o.a = clamp(0, o.a, 1);
-            return o;
-        };
-
-        o.clone = function () {
-            return jQuery.color.make(o.r, o.b, o.g, o.a);
-        };
-
-        return o.normalize();
-    }
-
-    // extract CSS color property from element, going up in the DOM
-    // if it's "transparent"
-    jQuery.color.extract = function (elem, css) {
-        var c;
-        do {
-            c = elem.css(css).toLowerCase();
-            // keep going until we find an element that has color, or
-            // we hit the body
-            if (c != '' && c != 'transparent')
-                break;
-            elem = elem.parent();
-        } while (!jQuery.nodeName(elem.get(0), "body"));
-
-        // catch Safari's way of signalling transparent
-        if (c == "rgba(0, 0, 0, 0)")
-            c = "transparent";
-        
-        return jQuery.color.parse(c);
-    }
-    
-    // parse CSS color string (like "rgb(10, 32, 43)" or "#fff"),
-    // returns color object
-    jQuery.color.parse = function (str) {
-        var res, m = jQuery.color.make;
-
-        // Look for rgb(num,num,num)
-        if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
-            return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
-        
-        // Look for rgba(num,num,num,num)
-        if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
-            return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
-            
-        // Look for rgb(num%,num%,num%)
-        if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
-            return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);
-
-        // Look for rgba(num%,num%,num%,num)
-        if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
-            return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));
-        
-        // Look for #a0b1c2
-        if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
-            return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
-
-        // Look for #fff
-        if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
-            return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));
-
-        // Otherwise, we're most likely dealing with a named color
-        var name = jQuery.trim(str).toLowerCase();
-        if (name == "transparent")
-            return m(255, 255, 255, 0);
-        else {
-            res = lookupColors[name];
-            return m(res[0], res[1], res[2]);
-        }
-    }
-    
-    var lookupColors = {
-        aqua:[0,255,255],
-        azure:[240,255,255],
-        beige:[245,245,220],
-        black:[0,0,0],
-        blue:[0,0,255],
-        brown:[165,42,42],
-        cyan:[0,255,255],
-        darkblue:[0,0,139],
-        darkcyan:[0,139,139],
-        darkgrey:[169,169,169],
-        darkgreen:[0,100,0],
-        darkkhaki:[189,183,107],
-        darkmagenta:[139,0,139],
-        darkolivegreen:[85,107,47],
-        darkorange:[255,140,0],
-        darkorchid:[153,50,204],
-        darkred:[139,0,0],
-        darksalmon:[233,150,122],
-        darkviolet:[148,0,211],
-        fuchsia:[255,0,255],
-        gold:[255,215,0],
-        green:[0,128,0],
-        indigo:[75,0,130],
-        khaki:[240,230,140],
-        lightblue:[173,216,230],
-        lightcyan:[224,255,255],
-        lightgreen:[144,238,144],
-        lightgrey:[211,211,211],
-        lightpink:[255,182,193],
-        lightyellow:[255,255,224],
-        lime:[0,255,0],
-        magenta:[255,0,255],
-        maroon:[128,0,0],
-        navy:[0,0,128],
-        olive:[128,128,0],
-        orange:[255,165,0],
-        pink:[255,192,203],
-        purple:[128,0,128],
-        violet:[128,0,128],
-        red:[255,0,0],
-        silver:[192,192,192],
-        white:[255,255,255],
-        yellow:[255,255,0]
-    };    
-})();
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.crosshair.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-Flot plugin for showing a crosshair, thin lines, when the mouse hovers
-over the plot.
-
-  crosshair: {
-    mode: null or "x" or "y" or "xy"
-    color: color
-    lineWidth: number
-  }
-
-Set the mode to one of "x", "y" or "xy". The "x" mode enables a
-vertical crosshair that lets you trace the values on the x axis, "y"
-enables a horizontal crosshair and "xy" enables them both. "color" is
-the color of the crosshair (default is "rgba(170, 0, 0, 0.80)"),
-"lineWidth" is the width of the drawn lines (default is 1).
-
-The plugin also adds four public methods:
-
-  - setCrosshair(pos)
-
-    Set the position of the crosshair. Note that this is cleared if
-    the user moves the mouse. "pos" should be on the form { x: xpos,
-    y: ypos } (or x2 and y2 if you're using the secondary axes), which
-    is coincidentally the same format as what you get from a "plothover"
-    event. If "pos" is null, the crosshair is cleared.
-
-  - clearCrosshair()
-
-    Clear the crosshair.
-
-  - lockCrosshair(pos)
-
-    Cause the crosshair to lock to the current location, no longer
-    updating if the user moves the mouse. Optionally supply a position
-    (passed on to setCrosshair()) to move it to.
-
-    Example usage:
-      var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
-      $("#graph").bind("plothover", function (evt, position, item) {
-        if (item) {
-          // Lock the crosshair to the data point being hovered
-          myFlot.lockCrosshair({ x: item.datapoint[0], y: item.datapoint[1] });
-        }
-        else {
-          // Return normal crosshair operation
-          myFlot.unlockCrosshair();
-        }
-      });
-
-  - unlockCrosshair()
-
-    Free the crosshair to move again after locking it.
-*/
-
-(function ($) {
-    var options = {
-        crosshair: {
-            mode: null, // one of null, "x", "y" or "xy",
-            color: "rgba(170, 0, 0, 0.80)",
-            lineWidth: 1
-        }
-    };
-    
-    function init(plot) {
-        // position of crosshair in pixels
-        var crosshair = { x: -1, y: -1, locked: false };
-
-        plot.setCrosshair = function setCrosshair(pos) {
-            if (!pos)
-                crosshair.x = -1;
-            else {
-                var axes = plot.getAxes();
-                
-                crosshair.x = Math.max(0, Math.min(pos.x != null ? axes.xaxis.p2c(pos.x) : axes.x2axis.p2c(pos.x2), plot.width()));
-                crosshair.y = Math.max(0, Math.min(pos.y != null ? axes.yaxis.p2c(pos.y) : axes.y2axis.p2c(pos.y2), plot.height()));
-            }
-            
-            plot.triggerRedrawOverlay();
-        };
-        
-        plot.clearCrosshair = plot.setCrosshair; // passes null for pos
-        
-        plot.lockCrosshair = function lockCrosshair(pos) {
-            if (pos)
-                plot.setCrosshair(pos);
-            crosshair.locked = true;
-        }
-
-        plot.unlockCrosshair = function unlockCrosshair() {
-            crosshair.locked = false;
-        }
-
-        plot.hooks.bindEvents.push(function (plot, eventHolder) {
-            if (!plot.getOptions().crosshair.mode)
-                return;
-
-            eventHolder.mouseout(function () {
-                if (crosshair.x != -1) {
-                    crosshair.x = -1;
-                    plot.triggerRedrawOverlay();
-                }
-            });
-            
-            eventHolder.mousemove(function (e) {
-                if (plot.getSelection && plot.getSelection()) {
-                    crosshair.x = -1; // hide the crosshair while selecting
-                    return;
-                }
-                
-                if (crosshair.locked)
-                    return;
-                
-                var offset = plot.offset();
-                crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
-                crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
-                plot.triggerRedrawOverlay();
-            });
-        });
-
-        plot.hooks.drawOverlay.push(function (plot, ctx) {
-            var c = plot.getOptions().crosshair;
-            if (!c.mode)
-                return;
-
-            var plotOffset = plot.getPlotOffset();
-            
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            if (crosshair.x != -1) {
-                ctx.strokeStyle = c.color;
-                ctx.lineWidth = c.lineWidth;
-                ctx.lineJoin = "round";
-
-                ctx.beginPath();
-                if (c.mode.indexOf("x") != -1) {
-                    ctx.moveTo(crosshair.x, 0);
-                    ctx.lineTo(crosshair.x, plot.height());
-                }
-                if (c.mode.indexOf("y") != -1) {
-                    ctx.moveTo(0, crosshair.y);
-                    ctx.lineTo(plot.width(), crosshair.y);
-                }
-                ctx.stroke();
-            }
-            ctx.restore();
-        });
-    }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'crosshair',
-        version: '1.0'
-    });
-})(jQuery);
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.image.js
+++ /dev/null
@@ -1,241 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-Flot plugin for plotting images, e.g. useful for putting ticks on a
-prerendered complex visualization.
-
-The data syntax is [[image, x1, y1, x2, y2], ...] where (x1, y1) and
-(x2, y2) are where you intend the two opposite corners of the image to
-end up in the plot. Image must be a fully loaded Javascript image (you
-can make one with new Image()). If the image is not complete, it's
-skipped when plotting.
-
-There are two helpers included for retrieving images. The easiest work
-the way that you put in URLs instead of images in the data (like
-["myimage.png", 0, 0, 10, 10]), then call $.plot.image.loadData(data,
-options, callback) where data and options are the same as you pass in
-to $.plot. This loads the images, replaces the URLs in the data with
-the corresponding images and calls "callback" when all images are
-loaded (or failed loading). In the callback, you can then call $.plot
-with the data set. See the included example.
-
-A more low-level helper, $.plot.image.load(urls, callback) is also
-included. Given a list of URLs, it calls callback with an object
-mapping from URL to Image object when all images are loaded or have
-failed loading.
-
-Options for the plugin are
-
-  series: {
-      images: {
-          show: boolean
-          anchor: "corner" or "center"
-          alpha: [0,1]
-      }
-  }
-
-which can be specified for a specific series
-
-  $.plot($("#placeholder"), [{ data: [ ... ], images: { ... } ])
-
-Note that because the data format is different from usual data points,
-you can't use images with anything else in a specific data series.
-
-Setting "anchor" to "center" causes the pixels in the image to be
-anchored at the corner pixel centers inside of at the pixel corners,
-effectively letting half a pixel stick out to each side in the plot.
-
-
-A possible future direction could be support for tiling for large
-images (like Google Maps).
-
-*/
-
-(function ($) {
-    var options = {
-        series: {
-            images: {
-                show: false,
-                alpha: 1,
-                anchor: "corner" // or "center"
-            }
-        }
-    };
-
-    $.plot.image = {};
-
-    $.plot.image.loadDataImages = function (series, options, callback) {
-        var urls = [], points = [];
-
-        var defaultShow = options.series.images.show;
-        
-        $.each(series, function (i, s) {
-            if (!(defaultShow || s.images.show))
-                return;
-            
-            if (s.data)
-                s = s.data;
-
-            $.each(s, function (i, p) {
-                if (typeof p[0] == "string") {
-                    urls.push(p[0]);
-                    points.push(p);
-                }
-            });
-        });
-
-        $.plot.image.load(urls, function (loadedImages) {
-            $.each(points, function (i, p) {
-                var url = p[0];
-                if (loadedImages[url])
-                    p[0] = loadedImages[url];
-            });
-
-            callback();
-        });
-    }
-    
-    $.plot.image.load = function (urls, callback) {
-        var missing = urls.length, loaded = {};
-        if (missing == 0)
-            callback({});
-
-        $.each(urls, function (i, url) {
-            var handler = function () {
-                --missing;
-                
-                loaded[url] = this;
-                
-                if (missing == 0)
-                    callback(loaded);
-            };
-
-            $('<img />').load(handler).error(handler).attr('src', url);
-        });
-    }
-    
-    function draw(plot, ctx) {
-        var plotOffset = plot.getPlotOffset();
-        
-        $.each(plot.getData(), function (i, series) {
-            var points = series.datapoints.points,
-                ps = series.datapoints.pointsize;
-            
-            for (var i = 0; i < points.length; i += ps) {
-                var img = points[i],
-                    x1 = points[i + 1], y1 = points[i + 2],
-                    x2 = points[i + 3], y2 = points[i + 4],
-                    xaxis = series.xaxis, yaxis = series.yaxis,
-                    tmp;
-
-                // actually we should check img.complete, but it
-                // appears to be a somewhat unreliable indicator in
-                // IE6 (false even after load event)
-                if (!img || img.width <= 0 || img.height <= 0)
-                    continue;
-
-                if (x1 > x2) {
-                    tmp = x2;
-                    x2 = x1;
-                    x1 = tmp;
-                }
-                if (y1 > y2) {
-                    tmp = y2;
-                    y2 = y1;
-                    y1 = tmp;
-                }
-                
-                // if the anchor is at the center of the pixel, expand the 
-                // image by 1/2 pixel in each direction
-                if (series.images.anchor == "center") {
-                    tmp = 0.5 * (x2-x1) / (img.width - 1);
-                    x1 -= tmp;
-                    x2 += tmp;
-                    tmp = 0.5 * (y2-y1) / (img.height - 1);
-                    y1 -= tmp;
-                    y2 += tmp;
-                }
-                
-                // clip
-                if (x1 == x2 || y1 == y2 ||
-                    x1 >= xaxis.max || x2 <= xaxis.min ||
-                    y1 >= yaxis.max || y2 <= yaxis.min)
-                    continue;
-
-                var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
-                if (x1 < xaxis.min) {
-                    sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
-                    x1 = xaxis.min;
-                }
-
-                if (x2 > xaxis.max) {
-                    sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
-                    x2 = xaxis.max;
-                }
-
-                if (y1 < yaxis.min) {
-                    sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
-                    y1 = yaxis.min;
-                }
-
-                if (y2 > yaxis.max) {
-                    sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
-                    y2 = yaxis.max;
-                }
-                
-                x1 = xaxis.p2c(x1);
-                x2 = xaxis.p2c(x2);
-                y1 = yaxis.p2c(y1);
-                y2 = yaxis.p2c(y2);
-                
-                // the transformation may have swapped us
-                if (x1 > x2) {
-                    tmp = x2;
-                    x2 = x1;
-                    x1 = tmp;
-                }
-                if (y1 > y2) {
-                    tmp = y2;
-                    y2 = y1;
-                    y1 = tmp;
-                }
-
-                tmp = ctx.globalAlpha;
-                ctx.globalAlpha *= series.images.alpha;
-                ctx.drawImage(img,
-                              sx1, sy1, sx2 - sx1, sy2 - sy1,
-                              x1 + plotOffset.left, y1 + plotOffset.top,
-                              x2 - x1, y2 - y1);
-                ctx.globalAlpha = tmp;
-            }
-        });
-    }
-
-    function processRawData(plot, series, data, datapoints) {
-        if (!series.images.show)
-            return;
-
-        // format is Image, x1, y1, x2, y2 (opposite corners)
-        datapoints.format = [
-            { required: true },
-            { x: true, number: true, required: true },
-            { y: true, number: true, required: true },
-            { x: true, number: true, required: true },
-            { y: true, number: true, required: true }
-        ];
-    }
-    
-    function init(plot) {
-        plot.hooks.processRawData.push(processRawData);
-        plot.hooks.draw.push(draw);
-    }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'image',
-        version: '1.1'
-    });
-})(jQuery);
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.js
+++ /dev/null
@@ -1,2119 +0,0 @@
-/* Javascript plotting library for jQuery, v. 0.6.
- *
- * Released under the MIT license by IOLA, December 2007.
- *
- */
-
-// first an inline dependency, jquery.colorhelpers.js, we inline it here
-// for convenience
-
-/* Plugin for jQuery for working with colors.
- * 
- * Version 1.0.
- * 
- * Inspiration from jQuery color animation plugin by John Resig.
- *
- * Released under the MIT license by Ole Laursen, October 2009.
- *
- * Examples:
- *
- *   $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
- *   var c = $.color.extract($("#mydiv"), 'background-color');
- *   console.log(c.r, c.g, c.b, c.a);
- *   $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
- *
- * Note that .scale() and .add() work in-place instead of returning
- * new objects.
- */ 
-(function(){jQuery.color={};jQuery.color.make=function(E,D,B,C){var F={};F.r=E||0;F.g=D||0;F.b=B||0;F.a=C!=null?C:1;F.add=function(I,H){for(var G=0;G<I.length;++G){F[I.charAt(G)]+=H}return F.normalize()};F.scale=function(I,H){for(var G=0;G<I.length;++G){F[I.charAt(G)]*=H}return F.normalize()};F.toString=function(){if(F.a>=1){return"rgb("+[F.r,F.g,F.b].join(",")+")"}else{return"rgba("+[F.r,F.g,F.b,F.a].join(",")+")"}};F.normalize=function(){function G(I,J,H){return J<I?I:(J>H?H:J)}F.r=G(0,parseInt(F.r),255);F.g=G(0,parseInt(F.g),255);F.b=G(0,parseInt(F.b),255);F.a=G(0,F.a,1);return F};F.clone=function(){return jQuery.color.make(F.r,F.b,F.g,F.a)};return F.normalize()};jQuery.color.extract=function(C,B){var D;do{D=C.css(B).toLowerCase();if(D!=""&&D!="transparent"){break}C=C.parent()}while(!jQuery.nodeName(C.get(0),"body"));if(D=="rgba(0, 0, 0, 0)"){D="transparent"}return jQuery.color.parse(D)};jQuery.color.parse=function(E){var D,B=jQuery.color.make;if(D=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(E)){return B(parseInt(D[1],10),parseInt(D[2],10),parseInt(D[3],10))}if(D=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(E)){return B(parseInt(D[1],10),parseInt(D[2],10),parseInt(D[3],10),parseFloat(D[4]))}if(D=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(E)){return B(parseFloat(D[1])*2.55,parseFloat(D[2])*2.55,parseFloat(D[3])*2.55)}if(D=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(E)){return B(parseFloat(D[1])*2.55,parseFloat(D[2])*2.55,parseFloat(D[3])*2.55,parseFloat(D[4]))}if(D=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(E)){return B(parseInt(D[1],16),parseInt(D[2],16),parseInt(D[3],16))}if(D=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(E)){return B(parseInt(D[1]+D[1],16),parseInt(D[2]+D[2],16),parseInt(D[3]+D[3],16))}var C=jQuery.trim(E).toLowerCase();if(C=="transparent"){return B(255,255,255,0)}else{D=A[C];return B(D[0],D[1],D[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})();
-
-// the actual Flot code
-(function($) {
-    function Plot(placeholder, data_, options_, plugins) {
-        // data is on the form:
-        //   [ series1, series2 ... ]
-        // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
-        // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
-        
-        var series = [],
-            options = {
-                // the color theme used for graphs
-                colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
-                legend: {
-                    show: true,
-                    noColumns: 1, // number of colums in legend table
-                    labelFormatter: null, // fn: string -> string
-                    labelBoxBorderColor: "#ccc", // border color for the little label boxes
-                    container: null, // container (as jQuery object) to put legend in, null means default on top of graph
-                    position: "ne", // position of default legend container within plot
-                    margin: 5, // distance from grid edge to default legend container within plot
-                    backgroundColor: null, // null means auto-detect
-                    backgroundOpacity: 0.85 // set to 0 to avoid background
-                },
-                xaxis: {
-                    mode: null, // null or "time"
-                    transform: null, // null or f: number -> number to transform axis
-                    inverseTransform: null, // if transform is set, this should be the inverse function
-                    min: null, // min. value to show, null means set automatically
-                    max: null, // max. value to show, null means set automatically
-                    autoscaleMargin: null, // margin in % to add if auto-setting min/max
-                    ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
-                    tickFormatter: null, // fn: number -> string
-                    labelWidth: null, // size of tick labels in pixels
-                    labelHeight: null,
-                    
-                    // mode specific options
-                    tickDecimals: null, // no. of decimals, null means auto
-                    tickSize: null, // number or [number, "unit"]
-                    minTickSize: null, // number or [number, "unit"]
-                    monthNames: null, // list of names of months
-                    timeformat: null, // format string to use
-                    twelveHourClock: false // 12 or 24 time in time mode
-                },
-                yaxis: {
-                    autoscaleMargin: 0.02
-                },
-                x2axis: {
-                    autoscaleMargin: null
-                },
-                y2axis: {
-                    autoscaleMargin: 0.02
-                },
-                series: {
-                    points: {
-                        show: false,
-                        radius: 3,
-                        lineWidth: 2, // in pixels
-                        fill: true,
-                        fillColor: "#ffffff"
-                    },
-                    lines: {
-                        // we don't put in show: false so we can see
-                        // whether lines were actively disabled 
-                        lineWidth: 2, // in pixels
-                        fill: false,
-                        fillColor: null,
-                        steps: false
-                    },
-                    bars: {
-                        show: false,
-                        lineWidth: 2, // in pixels
-                        barWidth: 1, // in units of the x axis
-                        fill: true,
-                        fillColor: null,
-                        align: "left", // or "center" 
-                        horizontal: false // when horizontal, left is now top
-                    },
-                    shadowSize: 3
-                },
-                grid: {
-                    show: true,
-                    aboveData: false,
-                    color: "#545454", // primary color used for outline and labels
-                    backgroundColor: null, // null for transparent, else color
-                    tickColor: "rgba(0,0,0,0.15)", // color used for the ticks
-                    labelMargin: 5, // in pixels
-                    borderWidth: 2, // in pixels
-                    borderColor: null, // set if different from the grid color
-                    markings: null, // array of ranges or fn: axes -> array of ranges
-                    markingsColor: "#f4f4f4",
-                    markingsLineWidth: 2,
-                    // interactive stuff
-                    clickable: false,
-                    hoverable: false,
-                    autoHighlight: true, // highlight in case mouse is near
-                    mouseActiveRadius: 10 // how far the mouse can be away to activate an item
-                },
-                hooks: {}
-            },
-        canvas = null,      // the canvas for the plot itself
-        overlay = null,     // canvas for interactive stuff on top of plot
-        eventHolder = null, // jQuery object that events should be bound to
-        ctx = null, octx = null,
-        axes = { xaxis: {}, yaxis: {}, x2axis: {}, y2axis: {} },
-        plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
-        canvasWidth = 0, canvasHeight = 0,
-        plotWidth = 0, plotHeight = 0,
-        hooks = {
-            processOptions: [],
-            processRawData: [],
-            processDatapoints: [],
-            draw: [],
-            bindEvents: [],
-            drawOverlay: []
-        },
-        plot = this;
-
-        // public functions
-        plot.setData = setData;
-        plot.setupGrid = setupGrid;
-        plot.draw = draw;
-        plot.getPlaceholder = function() { return placeholder; };
-        plot.getCanvas = function() { return canvas; };
-        plot.getPlotOffset = function() { return plotOffset; };
-        plot.width = function () { return plotWidth; };
-        plot.height = function () { return plotHeight; };
-        plot.offset = function () {
-            var o = eventHolder.offset();
-            o.left += plotOffset.left;
-            o.top += plotOffset.top;
-            return o;
-        };
-        plot.getData = function() { return series; };
-        plot.getAxes = function() { return axes; };
-        plot.getOptions = function() { return options; };
-        plot.highlight = highlight;
-        plot.unhighlight = unhighlight;
-        plot.triggerRedrawOverlay = triggerRedrawOverlay;
-        plot.pointOffset = function(point) {
-            return { left: parseInt(axisSpecToRealAxis(point, "xaxis").p2c(+point.x) + plotOffset.left),
-                     top: parseInt(axisSpecToRealAxis(point, "yaxis").p2c(+point.y) + plotOffset.top) };
-        };
-        
-
-        // public attributes
-        plot.hooks = hooks;
-        
-        // initialize
-        initPlugins(plot);
-        parseOptions(options_);
-        constructCanvas();
-        setData(data_);
-        setupGrid();
-        draw();
-        bindEvents();
-
-
-        function executeHooks(hook, args) {
-            args = [plot].concat(args);
-            for (var i = 0; i < hook.length; ++i)
-                hook[i].apply(this, args);
-        }
-
-        function initPlugins() {
-            for (var i = 0; i < plugins.length; ++i) {
-                var p = plugins[i];
-                p.init(plot);
-                if (p.options)
-                    $.extend(true, options, p.options);
-            }
-        }
-        
-        function parseOptions(opts) {
-            $.extend(true, options, opts);
-            if (options.grid.borderColor == null)
-                options.grid.borderColor = options.grid.color;
-            // backwards compatibility, to be removed in future
-            if (options.xaxis.noTicks && options.xaxis.ticks == null)
-                options.xaxis.ticks = options.xaxis.noTicks;
-            if (options.yaxis.noTicks && options.yaxis.ticks == null)
-                options.yaxis.ticks = options.yaxis.noTicks;
-            if (options.grid.coloredAreas)
-                options.grid.markings = options.grid.coloredAreas;
-            if (options.grid.coloredAreasColor)
-                options.grid.markingsColor = options.grid.coloredAreasColor;
-            if (options.lines)
-                $.extend(true, options.series.lines, options.lines);
-            if (options.points)
-                $.extend(true, options.series.points, options.points);
-            if (options.bars)
-                $.extend(true, options.series.bars, options.bars);
-            if (options.shadowSize)
-                options.series.shadowSize = options.shadowSize;
-
-            for (var n in hooks)
-                if (options.hooks[n] && options.hooks[n].length)
-                    hooks[n] = hooks[n].concat(options.hooks[n]);
-
-            executeHooks(hooks.processOptions, [options]);
-        }
-
-        function setData(d) {
-            series = parseData(d);
-            fillInSeriesOptions();
-            processData();
-        }
-        
-        function parseData(d) {
-            var res = [];
-            for (var i = 0; i < d.length; ++i) {
-                var s = $.extend(true, {}, options.series);
-
-                if (d[i].data) {
-                    s.data = d[i].data; // move the data instead of deep-copy
-                    delete d[i].data;
-
-                    $.extend(true, s, d[i]);
-
-                    d[i].data = s.data;
-                }
-                else
-                    s.data = d[i];
-                res.push(s);
-            }
-
-            return res;
-        }
-        
-        function axisSpecToRealAxis(obj, attr) {
-            var a = obj[attr];
-            if (!a || a == 1)
-                return axes[attr];
-            if (typeof a == "number")
-                return axes[attr.charAt(0) + a + attr.slice(1)];
-            return a; // assume it's OK
-        }
-        
-        function fillInSeriesOptions() {
-            var i;
-            
-            // collect what we already got of colors
-            var neededColors = series.length,
-                usedColors = [],
-                assignedColors = [];
-            for (i = 0; i < series.length; ++i) {
-                var sc = series[i].color;
-                if (sc != null) {
-                    --neededColors;
-                    if (typeof sc == "number")
-                        assignedColors.push(sc);
-                    else
-                        usedColors.push($.color.parse(series[i].color));
-                }
-            }
-            
-            // we might need to generate more colors if higher indices
-            // are assigned
-            for (i = 0; i < assignedColors.length; ++i) {
-                neededColors = Math.max(neededColors, assignedColors[i] + 1);
-            }
-
-            // produce colors as needed
-            var colors = [], variation = 0;
-            i = 0;
-            while (colors.length < neededColors) {
-                var c;
-                if (options.colors.length == i) // check degenerate case
-                    c = $.color.make(100, 100, 100);
-                else
-                    c = $.color.parse(options.colors[i]);
-
-                // vary color if needed
-                var sign = variation % 2 == 1 ? -1 : 1;
-                c.scale('rgb', 1 + sign * Math.ceil(variation / 2) * 0.2)
-
-                // FIXME: if we're getting to close to something else,
-                // we should probably skip this one
-                colors.push(c);
-                
-                ++i;
-                if (i >= options.colors.length) {
-                    i = 0;
-                    ++variation;
-                }
-            }
-
-            // fill in the options
-            var colori = 0, s;
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                
-                // assign colors
-                if (s.color == null) {
-                    s.color = colors[colori].toString();
-                    ++colori;
-                }
-                else if (typeof s.color == "number")
-                    s.color = colors[s.color].toString();
-
-                // turn on lines automatically in case nothing is set
-                if (s.lines.show == null) {
-                    var v, show = true;
-                    for (v in s)
-                        if (s[v].show) {
-                            show = false;
-                            break;
-                        }
-                    if (show)
-                        s.lines.show = true;
-                }
-
-                // setup axes
-                s.xaxis = axisSpecToRealAxis(s, "xaxis");
-                s.yaxis = axisSpecToRealAxis(s, "yaxis");
-            }
-        }
-        
-        function processData() {
-            var topSentry = Number.POSITIVE_INFINITY,
-                bottomSentry = Number.NEGATIVE_INFINITY,
-                i, j, k, m, length,
-                s, points, ps, x, y, axis, val, f, p;
-
-            for (axis in axes) {
-                axes[axis].datamin = topSentry;
-                axes[axis].datamax = bottomSentry;
-                axes[axis].used = false;
-            }
-
-            function updateAxis(axis, min, max) {
-                if (min < axis.datamin)
-                    axis.datamin = min;
-                if (max > axis.datamax)
-                    axis.datamax = max;
-            }
-
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                s.datapoints = { points: [] };
-                
-                executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
-            }
-            
-            // first pass: clean and copy data
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-
-                var data = s.data, format = s.datapoints.format;
-
-                if (!format) {
-                    format = [];
-                    // find out how to copy
-                    format.push({ x: true, number: true, required: true });
-                    format.push({ y: true, number: true, required: true });
-
-                    if (s.bars.show)
-                        format.push({ y: true, number: true, required: false, defaultValue: 0 });
-                    
-                    s.datapoints.format = format;
-                }
-
-                if (s.datapoints.pointsize != null)
-                    continue; // already filled in
-
-                if (s.datapoints.pointsize == null)
-                    s.datapoints.pointsize = format.length;
-                
-                ps = s.datapoints.pointsize;
-                points = s.datapoints.points;
-
-                insertSteps = s.lines.show && s.lines.steps;
-                s.xaxis.used = s.yaxis.used = true;
-                
-                for (j = k = 0; j < data.length; ++j, k += ps) {
-                    p = data[j];
-
-                    var nullify = p == null;
-                    if (!nullify) {
-                        for (m = 0; m < ps; ++m) {
-                            val = p[m];
-                            f = format[m];
-
-                            if (f) {
-                                if (f.number && val != null) {
-                                    val = +val; // convert to number
-                                    if (isNaN(val))
-                                        val = null;
-                                }
-
-                                if (val == null) {
-                                    if (f.required)
-                                        nullify = true;
-                                    
-                                    if (f.defaultValue != null)
-                                        val = f.defaultValue;
-                                }
-                            }
-                            
-                            points[k + m] = val;
-                        }
-                    }
-                    
-                    if (nullify) {
-                        for (m = 0; m < ps; ++m) {
-                            val = points[k + m];
-                            if (val != null) {
-                                f = format[m];
-                                // extract min/max info
-                                if (f.x)
-                                    updateAxis(s.xaxis, val, val);
-                                if (f.y)
-                                    updateAxis(s.yaxis, val, val);
-                            }
-                            points[k + m] = null;
-                        }
-                    }
-                    else {
-                        // a little bit of line specific stuff that
-                        // perhaps shouldn't be here, but lacking
-                        // better means...
-                        if (insertSteps && k > 0
-                            && points[k - ps] != null
-                            && points[k - ps] != points[k]
-                            && points[k - ps + 1] != points[k + 1]) {
-                            // copy the point to make room for a middle point
-                            for (m = 0; m < ps; ++m)
-                                points[k + ps + m] = points[k + m];
-
-                            // middle point has same y
-                            points[k + 1] = points[k - ps + 1];
-
-                            // we've added a point, better reflect that
-                            k += ps;
-                        }
-                    }
-                }
-            }
-
-            // give the hooks a chance to run
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                
-                executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
-            }
-
-            // second pass: find datamax/datamin for auto-scaling
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                points = s.datapoints.points,
-                ps = s.datapoints.pointsize;
-
-                var xmin = topSentry, ymin = topSentry,
-                    xmax = bottomSentry, ymax = bottomSentry;
-                
-                for (j = 0; j < points.length; j += ps) {
-                    if (points[j] == null)
-                        continue;
-
-                    for (m = 0; m < ps; ++m) {
-                        val = points[j + m];
-                        f = format[m];
-                        if (!f)
-                            continue;
-                        
-                        if (f.x) {
-                            if (val < xmin)
-                                xmin = val;
-                            if (val > xmax)
-                                xmax = val;
-                        }
-                        if (f.y) {
-                            if (val < ymin)
-                                ymin = val;
-                            if (val > ymax)
-                                ymax = val;
-                        }
-                    }
-                }
-                
-                if (s.bars.show) {
-                    // make sure we got room for the bar on the dancing floor
-                    var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2;
-                    if (s.bars.horizontal) {
-                        ymin += delta;
-                        ymax += delta + s.bars.barWidth;
-                    }
-                    else {
-                        xmin += delta;
-                        xmax += delta + s.bars.barWidth;
-                    }
-                }
-                
-                updateAxis(s.xaxis, xmin, xmax);
-                updateAxis(s.yaxis, ymin, ymax);
-            }
-
-            for (axis in axes) {
-                if (axes[axis].datamin == topSentry)
-                    axes[axis].datamin = null;
-                if (axes[axis].datamax == bottomSentry)
-                    axes[axis].datamax = null;
-            }
-        }
-
-        function constructCanvas() {
-            function makeCanvas(width, height) {
-                var c = document.createElement('canvas');
-                c.width = width;
-                c.height = height;
-                if ($.browser.msie) // excanvas hack
-                    c = window.G_vmlCanvasManager.initElement(c);
-                return c;
-            }
-            
-            canvasWidth = placeholder.width();
-            canvasHeight = placeholder.height();
-            placeholder.html(""); // clear placeholder
-            if (placeholder.css("position") == 'static')
-                placeholder.css("position", "relative"); // for positioning labels and overlay
-
-            if (canvasWidth <= 0 || canvasHeight <= 0)
-                throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;
-
-            if ($.browser.msie) // excanvas hack
-                window.G_vmlCanvasManager.init_(document); // make sure everything is setup
-            
-            // the canvas
-            canvas = $(makeCanvas(canvasWidth, canvasHeight)).appendTo(placeholder).get(0);
-            ctx = canvas.getContext("2d");
-
-            // overlay canvas for interactive features
-            overlay = $(makeCanvas(canvasWidth, canvasHeight)).css({ position: 'absolute', left: 0, top: 0 }).appendTo(placeholder).get(0);
-            octx = overlay.getContext("2d");
-            octx.stroke();
-        }
-
-        function bindEvents() {
-            // we include the canvas in the event holder too, because IE 7
-            // sometimes has trouble with the stacking order
-            eventHolder = $([overlay, canvas]);
-
-            // bind events
-            if (options.grid.hoverable)
-                eventHolder.mousemove(onMouseMove);
-
-            if (options.grid.clickable)
-                eventHolder.click(onClick);
-
-            executeHooks(hooks.bindEvents, [eventHolder]);
-        }
-
-        function setupGrid() {
-            function setTransformationHelpers(axis, o) {
-                function identity(x) { return x; }
-                
-                var s, m, t = o.transform || identity,
-                    it = o.inverseTransform;
-                    
-                // add transformation helpers
-                if (axis == axes.xaxis || axis == axes.x2axis) {
-                    // precompute how much the axis is scaling a point
-                    // in canvas space
-                    s = axis.scale = plotWidth / (t(axis.max) - t(axis.min));
-                    m = t(axis.min);
-
-                    // data point to canvas coordinate
-                    if (t == identity) // slight optimization
-                        axis.p2c = function (p) { return (p - m) * s; };
-                    else
-                        axis.p2c = function (p) { return (t(p) - m) * s; };
-                    // canvas coordinate to data point
-                    if (!it)
-                        axis.c2p = function (c) { return m + c / s; };
-                    else
-                        axis.c2p = function (c) { return it(m + c / s); };
-                }
-                else {
-                    s = axis.scale = plotHeight / (t(axis.max) - t(axis.min));
-                    m = t(axis.max);
-                    
-                    if (t == identity)
-                        axis.p2c = function (p) { return (m - p) * s; };
-                    else
-                        axis.p2c = function (p) { return (m - t(p)) * s; };
-                    if (!it)
-                        axis.c2p = function (c) { return m - c / s; };
-                    else
-                        axis.c2p = function (c) { return it(m - c / s); };
-                }
-            }
-
-            function measureLabels(axis, axisOptions) {
-                var i, labels = [], l;
-                
-                axis.labelWidth = axisOptions.labelWidth;
-                axis.labelHeight = axisOptions.labelHeight;
-
-                if (axis == axes.xaxis || axis == axes.x2axis) {
-                    // to avoid measuring the widths of the labels, we
-                    // construct fixed-size boxes and put the labels inside
-                    // them, we don't need the exact figures and the
-                    // fixed-size box content is easy to center
-                    if (axis.labelWidth == null)
-                        axis.labelWidth = canvasWidth / (axis.ticks.length > 0 ? axis.ticks.length : 1);
-
-                    // measure x label heights
-                    if (axis.labelHeight == null) {
-                        labels = [];
-                        for (i = 0; i < axis.ticks.length; ++i) {
-                            l = axis.ticks[i].label;
-                            if (l)
-                                labels.push('<div class="tickLabel" style="float:left;width:' + axis.labelWidth + 'px">' + l + '</div>');
-                        }
-                        
-                        if (labels.length > 0) {
-                            var dummyDiv = $('<div style="position:absolute;top:-10000px;width:10000px;font-size:smaller">'
-                                             + labels.join("") + '<div style="clear:left"></div></div>').appendTo(placeholder);
-                            axis.labelHeight = dummyDiv.height();
-                            dummyDiv.remove();
-                        }
-                    }
-                }
-                else if (axis.labelWidth == null || axis.labelHeight == null) {
-                    // calculate y label dimensions
-                    for (i = 0; i < axis.ticks.length; ++i) {
-                        l = axis.ticks[i].label;
-                        if (l)
-                            labels.push('<div class="tickLabel">' + l + '</div>');
-                    }
-                    
-                    if (labels.length > 0) {
-                        var dummyDiv = $('<div style="position:absolute;top:-10000px;font-size:smaller">'
-                                         + labels.join("") + '</div>').appendTo(placeholder);
-                        if (axis.labelWidth == null)
-                            axis.labelWidth = dummyDiv.width();
-                        if (axis.labelHeight == null)
-                            axis.labelHeight = dummyDiv.find("div").height();
-                        dummyDiv.remove();
-                    }
-                    
-                }
-
-                if (axis.labelWidth == null)
-                    axis.labelWidth = 0;
-                if (axis.labelHeight == null)
-                    axis.labelHeight = 0;
-            }
-            
-            function setGridSpacing() {
-                // get the most space needed around the grid for things
-                // that may stick out
-                var maxOutset = options.grid.borderWidth;
-                for (i = 0; i < series.length; ++i)
-                    maxOutset = Math.max(maxOutset, 2 * (series[i].points.radius + series[i].points.lineWidth/2));
-                
-                plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = maxOutset;
-                
-                var margin = options.grid.labelMargin + options.grid.borderWidth;
-                
-                if (axes.xaxis.labelHeight > 0)
-                    plotOffset.bottom = Math.max(maxOutset, axes.xaxis.labelHeight + margin);
-                if (axes.yaxis.labelWidth > 0)
-                    plotOffset.left = Math.max(maxOutset, axes.yaxis.labelWidth + margin);
-                if (axes.x2axis.labelHeight > 0)
-                    plotOffset.top = Math.max(maxOutset, axes.x2axis.labelHeight + margin);
-                if (axes.y2axis.labelWidth > 0)
-                    plotOffset.right = Math.max(maxOutset, axes.y2axis.labelWidth + margin);
-            
-                plotWidth = canvasWidth - plotOffset.left - plotOffset.right;
-                plotHeight = canvasHeight - plotOffset.bottom - plotOffset.top;
-            }
-            
-            var axis;
-            for (axis in axes)
-                setRange(axes[axis], options[axis]);
-            
-            if (options.grid.show) {
-                for (axis in axes) {
-                    prepareTickGeneration(axes[axis], options[axis]);
-                    setTicks(axes[axis], options[axis]);
-                    measureLabels(axes[axis], options[axis]);
-                }
-
-                setGridSpacing();
-            }
-            else {
-                plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = 0;
-                plotWidth = canvasWidth;
-                plotHeight = canvasHeight;
-            }
-            
-            for (axis in axes)
-                setTransformationHelpers(axes[axis], options[axis]);
-
-            if (options.grid.show)
-                insertLabels();
-            
-            insertLegend();
-        }
-        
-        function setRange(axis, axisOptions) {
-            var min = +(axisOptions.min != null ? axisOptions.min : axis.datamin),
-                max = +(axisOptions.max != null ? axisOptions.max : axis.datamax),
-                delta = max - min;
-
-            if (delta == 0.0) {
-                // degenerate case
-                var widen = max == 0 ? 1 : 0.01;
-
-                if (axisOptions.min == null)
-                    min -= widen;
-                // alway widen max if we couldn't widen min to ensure we
-                // don't fall into min == max which doesn't work
-                if (axisOptions.max == null || axisOptions.min != null)
-                    max += widen;
-            }
-            else {
-                // consider autoscaling
-                var margin = axisOptions.autoscaleMargin;
-                if (margin != null) {
-                    if (axisOptions.min == null) {
-                        min -= delta * margin;
-                        // make sure we don't go below zero if all values
-                        // are positive
-                        if (min < 0 && axis.datamin != null && axis.datamin >= 0)
-                            min = 0;
-                    }
-                    if (axisOptions.max == null) {
-                        max += delta * margin;
-                        if (max > 0 && axis.datamax != null && axis.datamax <= 0)
-                            max = 0;
-                    }
-                }
-            }
-            axis.min = min;
-            axis.max = max;
-        }
-
-        function prepareTickGeneration(axis, axisOptions) {
-            // estimate number of ticks
-            var noTicks;
-            if (typeof axisOptions.ticks == "number" && axisOptions.ticks > 0)
-                noTicks = axisOptions.ticks;
-            else if (axis == axes.xaxis || axis == axes.x2axis)
-                 // heuristic based on the model a*sqrt(x) fitted to
-                 // some reasonable data points
-                noTicks = 0.3 * Math.sqrt(canvasWidth);
-            else
-                noTicks = 0.3 * Math.sqrt(canvasHeight);
-            
-            var delta = (axis.max - axis.min) / noTicks,
-                size, generator, unit, formatter, i, magn, norm;
-
-            if (axisOptions.mode == "time") {
-                // pretty handling of time
-                
-                // map of app. size of time units in milliseconds
-                var timeUnitSize = {
-                    "second": 1000,
-                    "minute": 60 * 1000,
-                    "hour": 60 * 60 * 1000,
-                    "day": 24 * 60 * 60 * 1000,
-                    "month": 30 * 24 * 60 * 60 * 1000,
-                    "year": 365.2425 * 24 * 60 * 60 * 1000
-                };
-
-
-                // the allowed tick sizes, after 1 year we use
-                // an integer algorithm
-                var spec = [
-                    [1, "second"], [2, "second"], [5, "second"], [10, "second"],
-                    [30, "second"], 
-                    [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
-                    [30, "minute"], 
-                    [1, "hour"], [2, "hour"], [4, "hour"],
-                    [8, "hour"], [12, "hour"],
-                    [1, "day"], [2, "day"], [3, "day"],
-                    [0.25, "month"], [0.5, "month"], [1, "month"],
-                    [2, "month"], [3, "month"], [6, "month"],
-                    [1, "year"]
-                ];
-
-                var minSize = 0;
-                if (axisOptions.minTickSize != null) {
-                    if (typeof axisOptions.tickSize == "number")
-                        minSize = axisOptions.tickSize;
-                    else
-                        minSize = axisOptions.minTickSize[0] * timeUnitSize[axisOptions.minTickSize[1]];
-                }
-
-                for (i = 0; i < spec.length - 1; ++i)
-                    if (delta < (spec[i][0] * timeUnitSize[spec[i][1]]
-                                 + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
-                       && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize)
-                        break;
-                size = spec[i][0];
-                unit = spec[i][1];
-                
-                // special-case the possibility of several years
-                if (unit == "year") {
-                    magn = Math.pow(10, Math.floor(Math.log(delta / timeUnitSize.year) / Math.LN10));
-                    norm = (delta / timeUnitSize.year) / magn;
-                    if (norm < 1.5)
-                        size = 1;
-                    else if (norm < 3)
-                        size = 2;
-                    else if (norm < 7.5)
-                        size = 5;
-                    else
-                        size = 10;
-
-                    size *= magn;
-                }
-
-                if (axisOptions.tickSize) {
-                    size = axisOptions.tickSize[0];
-                    unit = axisOptions.tickSize[1];
-                }
-                
-                generator = function(axis) {
-                    var ticks = [],
-                        tickSize = axis.tickSize[0], unit = axis.tickSize[1],
-                        d = new Date(axis.min);
-                    
-                    var step = tickSize * timeUnitSize[unit];
-
-                    if (unit == "second")
-                        d.setUTCSeconds(floorInBase(d.getUTCSeconds(), tickSize));
-                    if (unit == "minute")
-                        d.setUTCMinutes(floorInBase(d.getUTCMinutes(), tickSize));
-                    if (unit == "hour")
-                        d.setUTCHours(floorInBase(d.getUTCHours(), tickSize));
-                    if (unit == "month")
-                        d.setUTCMonth(floorInBase(d.getUTCMonth(), tickSize));
-                    if (unit == "year")
-                        d.setUTCFullYear(floorInBase(d.getUTCFullYear(), tickSize));
-                    
-                    // reset smaller components
-                    d.setUTCMilliseconds(0);
-                    if (step >= timeUnitSize.minute)
-                        d.setUTCSeconds(0);
-                    if (step >= timeUnitSize.hour)
-                        d.setUTCMinutes(0);
-                    if (step >= timeUnitSize.day)
-                        d.setUTCHours(0);
-                    if (step >= timeUnitSize.day * 4)
-                        d.setUTCDate(1);
-                    if (step >= timeUnitSize.year)
-                        d.setUTCMonth(0);
-
-
-                    var carry = 0, v = Number.NaN, prev;
-                    do {
-                        prev = v;
-                        v = d.getTime();
-                        ticks.push({ v: v, label: axis.tickFormatter(v, axis) });
-                        if (unit == "month") {
-                            if (tickSize < 1) {
-                                // a bit complicated - we'll divide the month
-                                // up but we need to take care of fractions
-                                // so we don't end up in the middle of a day
-                                d.setUTCDate(1);
-                                var start = d.getTime();
-                                d.setUTCMonth(d.getUTCMonth() + 1);
-                                var end = d.getTime();
-                                d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
-                                carry = d.getUTCHours();
-                                d.setUTCHours(0);
-                            }
-                            else
-                                d.setUTCMonth(d.getUTCMonth() + tickSize);
-                        }
-                        else if (unit == "year") {
-                            d.setUTCFullYear(d.getUTCFullYear() + tickSize);
-                        }
-                        else
-                            d.setTime(v + step);
-                    } while (v < axis.max && v != prev);
-
-                    return ticks;
-                };
-
-                formatter = function (v, axis) {
-                    var d = new Date(v);
-
-                    // first check global format
-                    if (axisOptions.timeformat != null)
-                        return $.plot.formatDate(d, axisOptions.timeformat, axisOptions.monthNames);
-                    
-                    var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
-                    var span = axis.max - axis.min;
-                    var suffix = (axisOptions.twelveHourClock) ? " %p" : "";
-                    
-                    if (t < timeUnitSize.minute)
-                        fmt = "%h:%M:%S" + suffix;
-                    else if (t < timeUnitSize.day) {
-                        if (span < 2 * timeUnitSize.day)
-                            fmt = "%h:%M" + suffix;
-                        else
-                            fmt = "%b %d %h:%M" + suffix;
-                    }
-                    else if (t < timeUnitSize.month)
-                        fmt = "%b %d";
-                    else if (t < timeUnitSize.year) {
-                        if (span < timeUnitSize.year)
-                            fmt = "%b";
-                        else
-                            fmt = "%b %y";
-                    }
-                    else
-                        fmt = "%y";
-                    
-                    return $.plot.formatDate(d, fmt, axisOptions.monthNames);
-                };
-            }
-            else {
-                // pretty rounding of base-10 numbers
-                var maxDec = axisOptions.tickDecimals;
-                var dec = -Math.floor(Math.log(delta) / Math.LN10);
-                if (maxDec != null && dec > maxDec)
-                    dec = maxDec;
-
-                magn = Math.pow(10, -dec);
-                norm = delta / magn; // norm is between 1.0 and 10.0
-                
-                if (norm < 1.5)
-                    size = 1;
-                else if (norm < 3) {
-                    size = 2;
-                    // special case for 2.5, requires an extra decimal
-                    if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
-                        size = 2.5;
-                        ++dec;
-                    }
-                }
-                else if (norm < 7.5)
-                    size = 5;
-                else
-                    size = 10;
-
-                size *= magn;
-                
-                if (axisOptions.minTickSize != null && size < axisOptions.minTickSize)
-                    size = axisOptions.minTickSize;
-
-                if (axisOptions.tickSize != null)
-                    size = axisOptions.tickSize;
-
-                axis.tickDecimals = Math.max(0, (maxDec != null) ? maxDec : dec);
-
-                generator = function (axis) {
-                    var ticks = [];
-
-                    // spew out all possible ticks
-                    var start = floorInBase(axis.min, axis.tickSize),
-                        i = 0, v = Number.NaN, prev;
-                    do {
-                        prev = v;
-                        v = start + i * axis.tickSize;
-                        ticks.push({ v: v, label: axis.tickFormatter(v, axis) });
-                        ++i;
-                    } while (v < axis.max && v != prev);
-                    return ticks;
-                };
-
-                formatter = function (v, axis) {
-                    return v.toFixed(axis.tickDecimals);
-                };
-            }
-
-            axis.tickSize = unit ? [size, unit] : size;
-            axis.tickGenerator = generator;
-            if ($.isFunction(axisOptions.tickFormatter))
-                axis.tickFormatter = function (v, axis) { return "" + axisOptions.tickFormatter(v, axis); };
-            else
-                axis.tickFormatter = formatter;
-        }
-        
-        function setTicks(axis, axisOptions) {
-            axis.ticks = [];
-
-            if (!axis.used)
-                return;
-            
-            if (axisOptions.ticks == null)
-                axis.ticks = axis.tickGenerator(axis);
-            else if (typeof axisOptions.ticks == "number") {
-                if (axisOptions.ticks > 0)
-                    axis.ticks = axis.tickGenerator(axis);
-            }
-            else if (axisOptions.ticks) {
-                var ticks = axisOptions.ticks;
-
-                if ($.isFunction(ticks))
-                    // generate the ticks
-                    ticks = ticks({ min: axis.min, max: axis.max });
-                
-                // clean up the user-supplied ticks, copy them over
-                var i, v;
-                for (i = 0; i < ticks.length; ++i) {
-                    var label = null;
-                    var t = ticks[i];
-                    if (typeof t == "object") {
-                        v = t[0];
-                        if (t.length > 1)
-                            label = t[1];
-                    }
-                    else
-                        v = t;
-                    if (label == null)
-                        label = axis.tickFormatter(v, axis);
-                    axis.ticks[i] = { v: v, label: label };
-                }
-            }
-
-            if (axisOptions.autoscaleMargin != null && axis.ticks.length > 0) {
-                // snap to ticks
-                if (axisOptions.min == null)
-                    axis.min = Math.min(axis.min, axis.ticks[0].v);
-                if (axisOptions.max == null && axis.ticks.length > 1)
-                    axis.max = Math.max(axis.max, axis.ticks[axis.ticks.length - 1].v);
-            }
-        }
-      
-        function draw() {
-            ctx.clearRect(0, 0, canvasWidth, canvasHeight);
-
-            var grid = options.grid;
-            
-            if (grid.show && !grid.aboveData)
-                drawGrid();
-
-            for (var i = 0; i < series.length; ++i)
-                drawSeries(series[i]);
-
-            executeHooks(hooks.draw, [ctx]);
-            
-            if (grid.show && grid.aboveData)
-                drawGrid();
-        }
-
-        function extractRange(ranges, coord) {
-            var firstAxis = coord + "axis",
-                secondaryAxis = coord + "2axis",
-                axis, from, to, reverse;
-
-            if (ranges[firstAxis]) {
-                axis = axes[firstAxis];
-                from = ranges[firstAxis].from;
-                to = ranges[firstAxis].to;
-            }
-            else if (ranges[secondaryAxis]) {
-                axis = axes[secondaryAxis];
-                from = ranges[secondaryAxis].from;
-                to = ranges[secondaryAxis].to;
-            }
-            else {
-                // backwards-compat stuff - to be removed in future
-                axis = axes[firstAxis];
-                from = ranges[coord + "1"];
-                to = ranges[coord + "2"];
-            }
-
-            // auto-reverse as an added bonus
-            if (from != null && to != null && from > to)
-                return { from: to, to: from, axis: axis };
-            
-            return { from: from, to: to, axis: axis };
-        }
-        
-        function drawGrid() {
-            var i;
-            
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            // draw background, if any
-            if (options.grid.backgroundColor) {
-                ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
-                ctx.fillRect(0, 0, plotWidth, plotHeight);
-            }
-
-            // draw markings
-            var markings = options.grid.markings;
-            if (markings) {
-                if ($.isFunction(markings))
-                    // xmin etc. are backwards-compatible, to be removed in future
-                    markings = markings({ xmin: axes.xaxis.min, xmax: axes.xaxis.max, ymin: axes.yaxis.min, ymax: axes.yaxis.max, xaxis: axes.xaxis, yaxis: axes.yaxis, x2axis: axes.x2axis, y2axis: axes.y2axis });
-
-                for (i = 0; i < markings.length; ++i) {
-                    var m = markings[i],
-                        xrange = extractRange(m, "x"),
-                        yrange = extractRange(m, "y");
-
-                    // fill in missing
-                    if (xrange.from == null)
-                        xrange.from = xrange.axis.min;
-                    if (xrange.to == null)
-                        xrange.to = xrange.axis.max;
-                    if (yrange.from == null)
-                        yrange.from = yrange.axis.min;
-                    if (yrange.to == null)
-                        yrange.to = yrange.axis.max;
-
-                    // clip
-                    if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
-                        yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
-                        continue;
-
-                    xrange.from = Math.max(xrange.from, xrange.axis.min);
-                    xrange.to = Math.min(xrange.to, xrange.axis.max);
-                    yrange.from = Math.max(yrange.from, yrange.axis.min);
-                    yrange.to = Math.min(yrange.to, yrange.axis.max);
-
-                    if (xrange.from == xrange.to && yrange.from == yrange.to)
-                        continue;
-
-                    // then draw
-                    xrange.from = xrange.axis.p2c(xrange.from);
-                    xrange.to = xrange.axis.p2c(xrange.to);
-                    yrange.from = yrange.axis.p2c(yrange.from);
-                    yrange.to = yrange.axis.p2c(yrange.to);
-                    
-                    if (xrange.from == xrange.to || yrange.from == yrange.to) {
-                        // draw line
-                        ctx.beginPath();
-                        ctx.strokeStyle = m.color || options.grid.markingsColor;
-                        ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth;
-                        //ctx.moveTo(Math.floor(xrange.from), yrange.from);
-                        //ctx.lineTo(Math.floor(xrange.to), yrange.to);
-                        ctx.moveTo(xrange.from, yrange.from);
-                        ctx.lineTo(xrange.to, yrange.to);
-                        ctx.stroke();
-                    }
-                    else {
-                        // fill area
-                        ctx.fillStyle = m.color || options.grid.markingsColor;
-                        ctx.fillRect(xrange.from, yrange.to,
-                                     xrange.to - xrange.from,
-                                     yrange.from - yrange.to);
-                    }
-                }
-            }
-            
-            // draw the inner grid
-            ctx.lineWidth = 1;
-            ctx.strokeStyle = options.grid.tickColor;
-            ctx.beginPath();
-            var v, axis = axes.xaxis;
-            for (i = 0; i < axis.ticks.length; ++i) {
-                v = axis.ticks[i].v;
-                if (v <= axis.min || v >= axes.xaxis.max)
-                    continue;   // skip those lying on the axes
-
-                ctx.moveTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, 0);
-                ctx.lineTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, plotHeight);
-            }
-
-            axis = axes.yaxis;
-            for (i = 0; i < axis.ticks.length; ++i) {
-                v = axis.ticks[i].v;
-                if (v <= axis.min || v >= axis.max)
-                    continue;
-
-                ctx.moveTo(0, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
-                ctx.lineTo(plotWidth, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
-            }
-
-            axis = axes.x2axis;
-            for (i = 0; i < axis.ticks.length; ++i) {
-                v = axis.ticks[i].v;
-                if (v <= axis.min || v >= axis.max)
-                    continue;
-    
-                ctx.moveTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, -5);
-                ctx.lineTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, 5);
-            }
-
-            axis = axes.y2axis;
-            for (i = 0; i < axis.ticks.length; ++i) {
-                v = axis.ticks[i].v;
-                if (v <= axis.min || v >= axis.max)
-                    continue;
-
-                ctx.moveTo(plotWidth-5, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
-                ctx.lineTo(plotWidth+5, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
-            }
-            
-            ctx.stroke();
-            
-            if (options.grid.borderWidth) {
-                // draw border
-                var bw = options.grid.borderWidth;
-                ctx.lineWidth = bw;
-                ctx.strokeStyle = options.grid.borderColor;
-                ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
-            }
-
-            ctx.restore();
-        }
-
-        function insertLabels() {
-            placeholder.find(".tickLabels").remove();
-            
-            var html = ['<div class="tickLabels" style="font-size:smaller;color:' + options.grid.color + '">'];
-
-            function addLabels(axis, labelGenerator) {
-                for (var i = 0; i < axis.ticks.length; ++i) {
-                    var tick = axis.ticks[i];
-                    if (!tick.label || tick.v < axis.min || tick.v > axis.max)
-                        continue;
-                    html.push(labelGenerator(tick, axis));
-                }
-            }
-
-            var margin = options.grid.labelMargin + options.grid.borderWidth;
-            
-            addLabels(axes.xaxis, function (tick, axis) {
-                return '<div style="position:absolute;top:' + (plotOffset.top + plotHeight + margin) + 'px;left:' + Math.round(plotOffset.left + axis.p2c(tick.v) - axis.labelWidth/2) + 'px;width:' + axis.labelWidth + 'px;text-align:center" class="tickLabel">' + tick.label + "</div>";
-            });
-            
-            
-            addLabels(axes.yaxis, function (tick, axis) {
-                return '<div style="position:absolute;top:' + Math.round(plotOffset.top + axis.p2c(tick.v) - axis.labelHeight/2) + 'px;right:' + (plotOffset.right + plotWidth + margin) + 'px;width:' + axis.labelWidth + 'px;text-align:right" class="tickLabel">' + tick.label + "</div>";
-            });
-            
-            addLabels(axes.x2axis, function (tick, axis) {
-                return '<div style="position:absolute;bottom:' + (plotOffset.bottom + plotHeight + margin) + 'px;left:' + Math.round(plotOffset.left + axis.p2c(tick.v) - axis.labelWidth/2) + 'px;width:' + axis.labelWidth + 'px;text-align:center" class="tickLabel">' + tick.label + "</div>";
-            });
-            
-            addLabels(axes.y2axis, function (tick, axis) {
-                return '<div style="position:absolute;top:' + Math.round(plotOffset.top + axis.p2c(tick.v) - axis.labelHeight/2) + 'px;left:' + (plotOffset.left + plotWidth + margin) +'px;width:' + axis.labelWidth + 'px;text-align:left" class="tickLabel">' + tick.label + "</div>";
-            });
-
-            html.push('</div>');
-            
-            placeholder.append(html.join(""));
-        }
-
-        function drawSeries(series) {
-            if (series.lines.show)
-                drawSeriesLines(series);
-            if (series.bars.show)
-                drawSeriesBars(series);
-            if (series.points.show)
-                drawSeriesPoints(series);
-        }
-        
-        function drawSeriesLines(series) {
-            function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
-                var points = datapoints.points,
-                    ps = datapoints.pointsize,
-                    prevx = null, prevy = null;
-                
-                ctx.beginPath();
-                for (var i = ps; i < points.length; i += ps) {
-                    var x1 = points[i - ps], y1 = points[i - ps + 1],
-                        x2 = points[i], y2 = points[i + 1];
-                    
-                    if (x1 == null || x2 == null)
-                        continue;
-
-                    // clip with ymin
-                    if (y1 <= y2 && y1 < axisy.min) {
-                        if (y2 < axisy.min)
-                            continue;   // line segment is outside
-                        // compute new intersection point
-                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.min;
-                    }
-                    else if (y2 <= y1 && y2 < axisy.min) {
-                        if (y1 < axisy.min)
-                            continue;
-                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.min;
-                    }
-
-                    // clip with ymax
-                    if (y1 >= y2 && y1 > axisy.max) {
-                        if (y2 > axisy.max)
-                            continue;
-                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.max;
-                    }
-                    else if (y2 >= y1 && y2 > axisy.max) {
-                        if (y1 > axisy.max)
-                            continue;
-                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.max;
-                    }
-
-                    // clip with xmin
-                    if (x1 <= x2 && x1 < axisx.min) {
-                        if (x2 < axisx.min)
-                            continue;
-                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.min;
-                    }
-                    else if (x2 <= x1 && x2 < axisx.min) {
-                        if (x1 < axisx.min)
-                            continue;
-                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.min;
-                    }
-
-                    // clip with xmax
-                    if (x1 >= x2 && x1 > axisx.max) {
-                        if (x2 > axisx.max)
-                            continue;
-                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.max;
-                    }
-                    else if (x2 >= x1 && x2 > axisx.max) {
-                        if (x1 > axisx.max)
-                            continue;
-                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.max;
-                    }
-
-                    if (x1 != prevx || y1 != prevy)
-                        ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
-                    
-                    prevx = x2;
-                    prevy = y2;
-                    ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
-                }
-                ctx.stroke();
-            }
-
-            function plotLineArea(datapoints, axisx, axisy) {
-                var points = datapoints.points,
-                    ps = datapoints.pointsize,
-                    bottom = Math.min(Math.max(0, axisy.min), axisy.max),
-                    top, lastX = 0, areaOpen = false;
-                
-                for (var i = ps; i < points.length; i += ps) {
-                    var x1 = points[i - ps], y1 = points[i - ps + 1],
-                        x2 = points[i], y2 = points[i + 1];
-                    
-                    if (areaOpen && x1 != null && x2 == null) {
-                        // close area
-                        ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom));
-                        ctx.fill();
-                        areaOpen = false;
-                        continue;
-                    }
-
-                    if (x1 == null || x2 == null)
-                        continue;
-
-                    // clip x values
-                    
-                    // clip with xmin
-                    if (x1 <= x2 && x1 < axisx.min) {
-                        if (x2 < axisx.min)
-                            continue;
-                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.min;
-                    }
-                    else if (x2 <= x1 && x2 < axisx.min) {
-                        if (x1 < axisx.min)
-                            continue;
-                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.min;
-                    }
-
-                    // clip with xmax
-                    if (x1 >= x2 && x1 > axisx.max) {
-                        if (x2 > axisx.max)
-                            continue;
-                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x1 = axisx.max;
-                    }
-                    else if (x2 >= x1 && x2 > axisx.max) {
-                        if (x1 > axisx.max)
-                            continue;
-                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
-                        x2 = axisx.max;
-                    }
-
-                    if (!areaOpen) {
-                        // open area
-                        ctx.beginPath();
-                        ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
-                        areaOpen = true;
-                    }
-                    
-                    // now first check the case where both is outside
-                    if (y1 >= axisy.max && y2 >= axisy.max) {
-                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
-                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
-                        lastX = x2;
-                        continue;
-                    }
-                    else if (y1 <= axisy.min && y2 <= axisy.min) {
-                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
-                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
-                        lastX = x2;
-                        continue;
-                    }
-                    
-                    // else it's a bit more complicated, there might
-                    // be two rectangles and two triangles we need to fill
-                    // in; to find these keep track of the current x values
-                    var x1old = x1, x2old = x2;
-
-                    // and clip the y values, without shortcutting
-                    
-                    // clip with ymin
-                    if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
-                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.min;
-                    }
-                    else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
-                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.min;
-                    }
-
-                    // clip with ymax
-                    if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
-                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y1 = axisy.max;
-                    }
-                    else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
-                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
-                        y2 = axisy.max;
-                    }
-
-
-                    // if the x value was changed we got a rectangle
-                    // to fill
-                    if (x1 != x1old) {
-                        if (y1 <= axisy.min)
-                            top = axisy.min;
-                        else
-                            top = axisy.max;
-                        
-                        ctx.lineTo(axisx.p2c(x1old), axisy.p2c(top));
-                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(top));
-                    }
-                    
-                    // fill the triangles
-                    ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
-                    ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
-
-                    // fill the other rectangle if it's there
-                    if (x2 != x2old) {
-                        if (y2 <= axisy.min)
-                            top = axisy.min;
-                        else
-                            top = axisy.max;
-                        
-                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(top));
-                        ctx.lineTo(axisx.p2c(x2old), axisy.p2c(top));
-                    }
-
-                    lastX = Math.max(x2, x2old);
-                }
-
-                if (areaOpen) {
-                    ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom));
-                    ctx.fill();
-                }
-            }
-            
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-            ctx.lineJoin = "round";
-
-            var lw = series.lines.lineWidth,
-                sw = series.shadowSize;
-            // FIXME: consider another form of shadow when filling is turned on
-            if (lw > 0 && sw > 0) {
-                // draw shadow as a thick and thin line with transparency
-                ctx.lineWidth = sw;
-                ctx.strokeStyle = "rgba(0,0,0,0.1)";
-                // position shadow at angle from the mid of line
-                var angle = Math.PI/18;
-                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);
-                ctx.lineWidth = sw/2;
-                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);
-            }
-
-            ctx.lineWidth = lw;
-            ctx.strokeStyle = series.color;
-            var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
-            if (fillStyle) {
-                ctx.fillStyle = fillStyle;
-                plotLineArea(series.datapoints, series.xaxis, series.yaxis);
-            }
-
-            if (lw > 0)
-                plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
-            ctx.restore();
-        }
-
-        function drawSeriesPoints(series) {
-            function plotPoints(datapoints, radius, fillStyle, offset, circumference, axisx, axisy) {
-                var points = datapoints.points, ps = datapoints.pointsize;
-                
-                for (var i = 0; i < points.length; i += ps) {
-                    var x = points[i], y = points[i + 1];
-                    if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
-                        continue;
-                    
-                    ctx.beginPath();
-                    ctx.arc(axisx.p2c(x), axisy.p2c(y) + offset, radius, 0, circumference, false);
-                    if (fillStyle) {
-                        ctx.fillStyle = fillStyle;
-                        ctx.fill();
-                    }
-                    ctx.stroke();
-                }
-            }
-            
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            var lw = series.lines.lineWidth,
-                sw = series.shadowSize,
-                radius = series.points.radius;
-            if (lw > 0 && sw > 0) {
-                // draw shadow in two steps
-                var w = sw / 2;
-                ctx.lineWidth = w;
-                ctx.strokeStyle = "rgba(0,0,0,0.1)";
-                plotPoints(series.datapoints, radius, null, w + w/2, Math.PI,
-                           series.xaxis, series.yaxis);
-
-                ctx.strokeStyle = "rgba(0,0,0,0.2)";
-                plotPoints(series.datapoints, radius, null, w/2, Math.PI,
-                           series.xaxis, series.yaxis);
-            }
-
-            ctx.lineWidth = lw;
-            ctx.strokeStyle = series.color;
-            plotPoints(series.datapoints, radius,
-                       getFillStyle(series.points, series.color), 0, 2 * Math.PI,
-                       series.xaxis, series.yaxis);
-            ctx.restore();
-        }
-
-        function drawBar(x, y, b, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c, horizontal) {
-            var left, right, bottom, top,
-                drawLeft, drawRight, drawTop, drawBottom,
-                tmp;
-
-            if (horizontal) {
-                drawBottom = drawRight = drawTop = true;
-                drawLeft = false;
-                left = b;
-                right = x;
-                top = y + barLeft;
-                bottom = y + barRight;
-
-                // account for negative bars
-                if (right < left) {
-                    tmp = right;
-                    right = left;
-                    left = tmp;
-                    drawLeft = true;
-                    drawRight = false;
-                }
-            }
-            else {
-                drawLeft = drawRight = drawTop = true;
-                drawBottom = false;
-                left = x + barLeft;
-                right = x + barRight;
-                bottom = b;
-                top = y;
-
-                // account for negative bars
-                if (top < bottom) {
-                    tmp = top;
-                    top = bottom;
-                    bottom = tmp;
-                    drawBottom = true;
-                    drawTop = false;
-                }
-            }
-           
-            // clip
-            if (right < axisx.min || left > axisx.max ||
-                top < axisy.min || bottom > axisy.max)
-                return;
-            
-            if (left < axisx.min) {
-                left = axisx.min;
-                drawLeft = false;
-            }
-
-            if (right > axisx.max) {
-                right = axisx.max;
-                drawRight = false;
-            }
-
-            if (bottom < axisy.min) {
-                bottom = axisy.min;
-                drawBottom = false;
-            }
-            
-            if (top > axisy.max) {
-                top = axisy.max;
-                drawTop = false;
-            }
-
-            left = axisx.p2c(left);
-            bottom = axisy.p2c(bottom);
-            right = axisx.p2c(right);
-            top = axisy.p2c(top);
-            
-            // fill the bar
-            if (fillStyleCallback) {
-                c.beginPath();
-                c.moveTo(left, bottom);
-                c.lineTo(left, top);
-                c.lineTo(right, top);
-                c.lineTo(right, bottom);
-                c.fillStyle = fillStyleCallback(bottom, top);
-                c.fill();
-            }
-
-            // draw outline
-            if (drawLeft || drawRight || drawTop || drawBottom) {
-                c.beginPath();
-
-                // FIXME: inline moveTo is buggy with excanvas
-                c.moveTo(left, bottom + offset);
-                if (drawLeft)
-                    c.lineTo(left, top + offset);
-                else
-                    c.moveTo(left, top + offset);
-                if (drawTop)
-                    c.lineTo(right, top + offset);
-                else
-                    c.moveTo(right, top + offset);
-                if (drawRight)
-                    c.lineTo(right, bottom + offset);
-                else
-                    c.moveTo(right, bottom + offset);
-                if (drawBottom)
-                    c.lineTo(left, bottom + offset);
-                else
-                    c.moveTo(left, bottom + offset);
-                c.stroke();
-            }
-        }
-        
-        function drawSeriesBars(series) {
-            function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {
-                var points = datapoints.points, ps = datapoints.pointsize;
-                
-                for (var i = 0; i < points.length; i += ps) {
-                    if (points[i] == null)
-                        continue;
-                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal);
-                }
-            }
-
-            ctx.save();
-            ctx.translate(plotOffset.left, plotOffset.top);
-
-            // FIXME: figure out a way to add shadows (for instance along the right edge)
-            ctx.lineWidth = series.bars.lineWidth;
-            ctx.strokeStyle = series.color;
-            var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
-            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
-            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis);
-            ctx.restore();
-        }
-
-        function getFillStyle(filloptions, seriesColor, bottom, top) {
-            var fill = filloptions.fill;
-            if (!fill)
-                return null;
-
-            if (filloptions.fillColor)
-                return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
-            
-            var c = $.color.parse(seriesColor);
-            c.a = typeof fill == "number" ? fill : 0.4;
-            c.normalize();
-            return c.toString();
-        }
-        
-        function insertLegend() {
-            placeholder.find(".legend").remove();
-
-            if (!options.legend.show)
-                return;
-            
-            var fragments = [], rowStarted = false,
-                lf = options.legend.labelFormatter, s, label;
-            for (i = 0; i < series.length; ++i) {
-                s = series[i];
-                label = s.label;
-                if (!label)
-                    continue;
-                
-                if (i % options.legend.noColumns == 0) {
-                    if (rowStarted)
-                        fragments.push('</tr>');
-                    fragments.push('<tr>');
-                    rowStarted = true;
-                }
-
-                if (lf)
-                    label = lf(label, s);
-                
-                fragments.push(
-                    '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + s.color + ';overflow:hidden"></div></div></td>' +
-                    '<td class="legendLabel">' + label + '</td>');
-            }
-            if (rowStarted)
-                fragments.push('</tr>');
-            
-            if (fragments.length == 0)
-                return;
-
-            var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>';
-            if (options.legend.container != null)
-                $(options.legend.container).html(table);
-            else {
-                var pos = "",
-                    p = options.legend.position,
-                    m = options.legend.margin;
-                if (m[0] == null)
-                    m = [m, m];
-                if (p.charAt(0) == "n")
-                    pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
-                else if (p.charAt(0) == "s")
-                    pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
-                if (p.charAt(1) == "e")
-                    pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
-                else if (p.charAt(1) == "w")
-                    pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
-                var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder);
-                if (options.legend.backgroundOpacity != 0.0) {
-                    // put in the transparent background
-                    // separately to avoid blended labels and
-                    // label boxes
-                    var c = options.legend.backgroundColor;
-                    if (c == null) {
-                        c = options.grid.backgroundColor;
-                        if (c && typeof c == "string")
-                            c = $.color.parse(c);
-                        else
-                            c = $.color.extract(legend, 'background-color');
-                        c.a = 1;
-                        c = c.toString();
-                    }
-                    var div = legend.children();
-                    $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
-                }
-            }
-        }
-
-
-        // interactive features
-        
-        var highlights = [],
-            redrawTimeout = null;
-        
-        // returns the data item the mouse is over, or null if none is found
-        function findNearbyItem(mouseX, mouseY, seriesFilter) {
-            var maxDistance = options.grid.mouseActiveRadius,
-                smallestDistance = maxDistance * maxDistance + 1,
-                item = null, foundPoint = false, i, j;
-
-            for (i = 0; i < series.length; ++i) {
-                if (!seriesFilter(series[i]))
-                    continue;
-                
-                var s = series[i],
-                    axisx = s.xaxis,
-                    axisy = s.yaxis,
-                    points = s.datapoints.points,
-                    ps = s.datapoints.pointsize,
-                    mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
-                    my = axisy.c2p(mouseY),
-                    maxx = maxDistance / axisx.scale,
-                    maxy = maxDistance / axisy.scale;
-
-                if (s.lines.show || s.points.show) {
-                    for (j = 0; j < points.length; j += ps) {
-                        var x = points[j], y = points[j + 1];
-                        if (x == null)
-                            continue;
-                        
-                        // For points and lines, the cursor must be within a
-                        // certain distance to the data point
-                        if (x - mx > maxx || x - mx < -maxx ||
-                            y - my > maxy || y - my < -maxy)
-                            continue;
-
-                        // We have to calculate distances in pixels, not in
-                        // data units, because the scales of the axes may be different
-                        var dx = Math.abs(axisx.p2c(x) - mouseX),
-                            dy = Math.abs(axisy.p2c(y) - mouseY),
-                            dist = dx * dx + dy * dy; // we save the sqrt
-
-                        // use <= to ensure last point takes precedence
-                        // (last generally means on top of)
-                        if (dist <= smallestDistance) {
-                            smallestDistance = dist;
-                            item = [i, j / ps];
-                        }
-                    }
-                }
-                    
-                if (s.bars.show && !item) { // no other point can be nearby
-                    var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2,
-                        barRight = barLeft + s.bars.barWidth;
-                    
-                    for (j = 0; j < points.length; j += ps) {
-                        var x = points[j], y = points[j + 1], b = points[j + 2];
-                        if (x == null)
-                            continue;
-  
-                        // for a bar graph, the cursor must be inside the bar
-                        if (series[i].bars.horizontal ? 
-                            (mx <= Math.max(b, x) && mx >= Math.min(b, x) && 
-                             my >= y + barLeft && my <= y + barRight) :
-                            (mx >= x + barLeft && mx <= x + barRight &&
-                             my >= Math.min(b, y) && my <= Math.max(b, y)))
-                                item = [i, j / ps];
-                    }
-                }
-            }
-
-            if (item) {
-                i = item[0];
-                j = item[1];
-                ps = series[i].datapoints.pointsize;
-                
-                return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
-                         dataIndex: j,
-                         series: series[i],
-                         seriesIndex: i };
-            }
-            
-            return null;
-        }
-
-        function onMouseMove(e) {
-            if (options.grid.hoverable)
-                triggerClickHoverEvent("plothover", e,
-                                       function (s) { return s["hoverable"] != false; });
-        }
-        
-        function onClick(e) {
-            triggerClickHoverEvent("plotclick", e,
-                                   function (s) { return s["clickable"] != false; });
-        }
-
-        // trigger click or hover event (they send the same parameters
-        // so we share their code)
-        function triggerClickHoverEvent(eventname, event, seriesFilter) {
-            var offset = eventHolder.offset(),
-                pos = { pageX: event.pageX, pageY: event.pageY },
-                canvasX = event.pageX - offset.left - plotOffset.left,
-                canvasY = event.pageY - offset.top - plotOffset.top;
-
-            if (axes.xaxis.used)
-                pos.x = axes.xaxis.c2p(canvasX);
-            if (axes.yaxis.used)
-                pos.y = axes.yaxis.c2p(canvasY);
-            if (axes.x2axis.used)
-                pos.x2 = axes.x2axis.c2p(canvasX);
-            if (axes.y2axis.used)
-                pos.y2 = axes.y2axis.c2p(canvasY);
-
-            var item = findNearbyItem(canvasX, canvasY, seriesFilter);
-
-            if (item) {
-                // fill in mouse pos for any listeners out there
-                item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left);
-                item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top);
-            }
-
-            if (options.grid.autoHighlight) {
-                // clear auto-highlights
-                for (var i = 0; i < highlights.length; ++i) {
-                    var h = highlights[i];
-                    if (h.auto == eventname &&
-                        !(item && h.series == item.series && h.point == item.datapoint))
-                        unhighlight(h.series, h.point);
-                }
-                
-                if (item)
-                    highlight(item.series, item.datapoint, eventname);
-            }
-            
-            placeholder.trigger(eventname, [ pos, item ]);
-        }
-
-        function triggerRedrawOverlay() {
-            if (!redrawTimeout)
-                redrawTimeout = setTimeout(drawOverlay, 30);
-        }
-
-        function drawOverlay() {
-            redrawTimeout = null;
-
-            // draw highlights
-            octx.save();
-            octx.clearRect(0, 0, canvasWidth, canvasHeight);
-            octx.translate(plotOffset.left, plotOffset.top);
-            
-            var i, hi;
-            for (i = 0; i < highlights.length; ++i) {
-                hi = highlights[i];
-
-                if (hi.series.bars.show)
-                    drawBarHighlight(hi.series, hi.point);
-                else
-                    drawPointHighlight(hi.series, hi.point);
-            }
-            octx.restore();
-            
-            executeHooks(hooks.drawOverlay, [octx]);
-        }
-        
-        function highlight(s, point, auto) {
-            if (typeof s == "number")
-                s = series[s];
-
-            if (typeof point == "number")
-                point = s.data[point];
-
-            var i = indexOfHighlight(s, point);
-            if (i == -1) {
-                highlights.push({ series: s, point: point, auto: auto });
-
-                triggerRedrawOverlay();
-            }
-            else if (!auto)
-                highlights[i].auto = false;
-        }
-            
-        function unhighlight(s, point) {
-            if (s == null && point == null) {
-                highlights = [];
-                triggerRedrawOverlay();
-            }
-            
-            if (typeof s == "number")
-                s = series[s];
-
-            if (typeof point == "number")
-                point = s.data[point];
-
-            var i = indexOfHighlight(s, point);
-            if (i != -1) {
-                highlights.splice(i, 1);
-
-                triggerRedrawOverlay();
-            }
-        }
-        
-        function indexOfHighlight(s, p) {
-            for (var i = 0; i < highlights.length; ++i) {
-                var h = highlights[i];
-                if (h.series == s && h.point[0] == p[0]
-                    && h.point[1] == p[1])
-                    return i;
-            }
-            return -1;
-        }
-        
-        function drawPointHighlight(series, point) {
-            var x = point[0], y = point[1],
-                axisx = series.xaxis, axisy = series.yaxis;
-            
-            if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
-                return;
-            
-            var pointRadius = series.points.radius + series.points.lineWidth / 2;
-            octx.lineWidth = pointRadius;
-            octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
-            var radius = 1.5 * pointRadius;
-            octx.beginPath();
-            octx.arc(axisx.p2c(x), axisy.p2c(y), radius, 0, 2 * Math.PI, false);
-            octx.stroke();
-        }
-
-        function drawBarHighlight(series, point) {
-            octx.lineWidth = series.bars.lineWidth;
-            octx.strokeStyle = $.color.parse(series.color).scale('a', 0.5).toString();
-            var fillStyle = $.color.parse(series.color).scale('a', 0.5).toString();
-            var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
-            drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
-                    0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal);
-        }
-
-        function getColorOrGradient(spec, bottom, top, defaultColor) {
-            if (typeof spec == "string")
-                return spec;
-            else {
-                // assume this is a gradient spec; IE currently only
-                // supports a simple vertical gradient properly, so that's
-                // what we support too
-                var gradient = ctx.createLinearGradient(0, top, 0, bottom);
-                
-                for (var i = 0, l = spec.colors.length; i < l; ++i) {
-                    var c = spec.colors[i];
-                    if (typeof c != "string") {
-                        c = $.color.parse(defaultColor).scale('rgb', c.brightness);
-                        c.a *= c.opacity;
-                        c = c.toString();
-                    }
-                    gradient.addColorStop(i / (l - 1), c);
-                }
-                
-                return gradient;
-            }
-        }
-    }
-
-    $.plot = function(placeholder, data, options) {
-        var plot = new Plot($(placeholder), data, options, $.plot.plugins);
-        /*var t0 = new Date();
-        var t1 = new Date();
-        var tstr = "time used (msecs): " + (t1.getTime() - t0.getTime())
-        if (window.console)
-            console.log(tstr);
-        else
-            alert(tstr);*/
-        return plot;
-    };
-
-    $.plot.plugins = [];
-
-    // returns a string with the date d formatted according to fmt
-    $.plot.formatDate = function(d, fmt, monthNames) {
-        var leftPad = function(n) {
-            n = "" + n;
-            return n.length == 1 ? "0" + n : n;
-        };
-        
-        var r = [];
-        var escape = false;
-        var hours = d.getUTCHours();
-        var isAM = hours < 12;
-        if (monthNames == null)
-            monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
-
-        if (fmt.search(/%p|%P/) != -1) {
-            if (hours > 12) {
-                hours = hours - 12;
-            } else if (hours == 0) {
-                hours = 12;
-            }
-        }
-        for (var i = 0; i < fmt.length; ++i) {
-            var c = fmt.charAt(i);
-            
-            if (escape) {
-                switch (c) {
-                case 'h': c = "" + hours; break;
-                case 'H': c = leftPad(hours); break;
-                case 'M': c = leftPad(d.getUTCMinutes()); break;
-                case 'S': c = leftPad(d.getUTCSeconds()); break;
-                case 'd': c = "" + d.getUTCDate(); break;
-                case 'm': c = "" + (d.getUTCMonth() + 1); break;
-                case 'y': c = "" + d.getUTCFullYear(); break;
-                case 'b': c = "" + monthNames[d.getUTCMonth()]; break;
-                case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
-                case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
-                }
-                r.push(c);
-                escape = false;
-            }
-            else {
-                if (c == "%")
-                    escape = true;
-                else
-                    r.push(c);
-            }
-        }
-        return r.join("");
-    };
-    
-    // round to nearby lower multiple of base
-    function floorInBase(n, base) {
-        return base * Math.floor(n / base);
-    }
-    
-})(jQuery);
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.navigate.js
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
-Flot plugin for adding panning and zooming capabilities to a plot.
-
-The default behaviour is double click and scrollwheel up/down to zoom
-in, drag to pan. The plugin defines plot.zoom({ center }),
-plot.zoomOut() and plot.pan(offset) so you easily can add custom
-controls. It also fires a "plotpan" and "plotzoom" event when
-something happens, useful for synchronizing plots.
-
-Example usage:
-
-  plot = $.plot(...);
-  
-  // zoom default amount in on the pixel (100, 200) 
-  plot.zoom({ center: { left: 10, top: 20 } });
-
-  // zoom out again
-  plot.zoomOut({ center: { left: 10, top: 20 } });
-
-  // pan 100 pixels to the left and 20 down
-  plot.pan({ left: -100, top: 20 })
-
-
-Options:
-
-  zoom: {
-    interactive: false
-    trigger: "dblclick" // or "click" for single click
-    amount: 1.5         // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
-  }
-  
-  pan: {
-    interactive: false
-  }
-
-  xaxis, yaxis, x2axis, y2axis: {
-    zoomRange: null  // or [number, number] (min range, max range)
-    panRange: null   // or [number, number] (min, max)
-  }
-  
-"interactive" enables the built-in drag/click behaviour. "amount" is
-the amount to zoom the viewport relative to the current range, so 1 is
-100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out).
-
-"zoomRange" is the interval in which zooming can happen, e.g. with
-zoomRange: [1, 100] the zoom will never scale the axis so that the
-difference between min and max is smaller than 1 or larger than 100.
-You can set either of them to null to ignore.
-
-"panRange" confines the panning to stay within a range, e.g. with
-panRange: [-10, 20] panning stops at -10 in one end and at 20 in the
-other. Either can be null.
-*/
-
-
-// First two dependencies, jquery.event.drag.js and
-// jquery.mousewheel.js, we put them inline here to save people the
-// effort of downloading them.
-
-/*
-jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)  
-Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
-*/
-(function(E){E.fn.drag=function(L,K,J){if(K){this.bind("dragstart",L)}if(J){this.bind("dragend",J)}return !L?this.trigger("drag"):this.bind("drag",K?K:L)};var A=E.event,B=A.special,F=B.drag={not:":input",distance:0,which:1,dragging:false,setup:function(J){J=E.extend({distance:F.distance,which:F.which,not:F.not},J||{});J.distance=I(J.distance);A.add(this,"mousedown",H,J);if(this.attachEvent){this.attachEvent("ondragstart",D)}},teardown:function(){A.remove(this,"mousedown",H);if(this===F.dragging){F.dragging=F.proxy=false}G(this,true);if(this.detachEvent){this.detachEvent("ondragstart",D)}}};B.dragstart=B.dragend={setup:function(){},teardown:function(){}};function H(L){var K=this,J,M=L.data||{};if(M.elem){K=L.dragTarget=M.elem;L.dragProxy=F.proxy||K;L.cursorOffsetX=M.pageX-M.left;L.cursorOffsetY=M.pageY-M.top;L.offsetX=L.pageX-L.cursorOffsetX;L.offsetY=L.pageY-L.cursorOffsetY}else{if(F.dragging||(M.which>0&&L.which!=M.which)||E(L.target).is(M.not)){return }}switch(L.type){case"mousedown":E.extend(M,E(K).offset(),{elem:K,target:L.target,pageX:L.pageX,pageY:L.pageY});A.add(document,"mousemove mouseup",H,M);G(K,false);F.dragging=null;return false;case !F.dragging&&"mousemove":if(I(L.pageX-M.pageX)+I(L.pageY-M.pageY)<M.distance){break}L.target=M.target;J=C(L,"dragstart",K);if(J!==false){F.dragging=K;F.proxy=L.dragProxy=E(J||K)[0]}case"mousemove":if(F.dragging){J=C(L,"drag",K);if(B.drop){B.drop.allowed=(J!==false);B.drop.handler(L)}if(J!==false){break}L.type="mouseup"}case"mouseup":A.remove(document,"mousemove mouseup",H);if(F.dragging){if(B.drop){B.drop.handler(L)}C(L,"dragend",K)}G(K,true);F.dragging=F.proxy=M.elem=false;break}return true}function C(M,K,L){M.type=K;var J=E.event.handle.call(L,M);return J===false?false:J||M.result}function I(J){return Math.pow(J,2)}function D(){return(F.dragging===false)}function G(K,J){if(!K){return }K.unselectable=J?"off":"on";K.onselectstart=function(){return J};if(K.style){K.style.MozUserSelect=J?"":"none"}}})(jQuery);
-
-
-/* jquery.mousewheel.min.js
- * Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
- * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
- * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
- * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
- * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
- *
- * Version: 3.0.2
- * 
- * Requires: 1.2.2+
- */
-(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery);
-
-
-
-
-(function ($) {
-    var options = {
-        xaxis: {
-            zoomRange: null, // or [number, number] (min range, max range)
-            panRange: null // or [number, number] (min, max)
-        },
-        zoom: {
-            interactive: false,
-            trigger: "dblclick", // or "click" for single click
-            amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
-        },
-        pan: {
-            interactive: false
-        }
-    };
-
-    function init(plot) {
-        function bindEvents(plot, eventHolder) {
-            var o = plot.getOptions();
-            if (o.zoom.interactive) {
-                function clickHandler(e, zoomOut) {
-                    var c = plot.offset();
-                    c.left = e.pageX - c.left;
-                    c.top = e.pageY - c.top;
-                    if (zoomOut)
-                        plot.zoomOut({ center: c });
-                    else
-                        plot.zoom({ center: c });
-                }
-                
-                eventHolder[o.zoom.trigger](clickHandler);
-
-                eventHolder.mousewheel(function (e, delta) {
-                    clickHandler(e, delta < 0);
-                    return false;
-                });
-            }
-            if (o.pan.interactive) {
-                var prevCursor = 'default', pageX = 0, pageY = 0;
-                
-                eventHolder.bind("dragstart", { distance: 10 }, function (e) {
-                    if (e.which != 1)  // only accept left-click
-                        return false;
-                    eventHolderCursor = eventHolder.css('cursor');
-                    eventHolder.css('cursor', 'move');
-                    pageX = e.pageX;
-                    pageY = e.pageY;
-                });
-                eventHolder.bind("drag", function (e) {
-                    // unused at the moment, but we need it here to
-                    // trigger the dragstart/dragend events
-                });
-                eventHolder.bind("dragend", function (e) {
-                    eventHolder.css('cursor', prevCursor);
-                    plot.pan({ left: pageX - e.pageX,
-                               top: pageY - e.pageY });
-                });
-            }
-        }
-
-        plot.zoomOut = function (args) {
-            if (!args)
-                args = {};
-            
-            if (!args.amount)
-                args.amount = plot.getOptions().zoom.amount
-
-            args.amount = 1 / args.amount;
-            plot.zoom(args);
-        }
-        
-        plot.zoom = function (args) {
-            if (!args)
-                args = {};
-            
-            var axes = plot.getAxes(),
-                options = plot.getOptions(),
-                c = args.center,
-                amount = args.amount ? args.amount : options.zoom.amount,
-                w = plot.width(), h = plot.height();
-
-            if (!c)
-                c = { left: w / 2, top: h / 2 };
-                
-            var xf = c.left / w,
-                x1 = c.left - xf * w / amount,
-                x2 = c.left + (1 - xf) * w / amount,
-                yf = c.top / h,
-                y1 = c.top - yf * h / amount,
-                y2 = c.top + (1 - yf) * h / amount;
-
-            function scaleAxis(min, max, name) {
-                var axis = axes[name],
-                    axisOptions = options[name];
-                
-                if (!axis.used)
-                    return;
-                    
-                min = axis.c2p(min);
-                max = axis.c2p(max);
-                if (max < min) { // make sure min < max
-                    var tmp = min
-                    min = max;
-                    max = tmp;
-                }
-
-                var range = max - min, zr = axisOptions.zoomRange;
-                if (zr &&
-                    ((zr[0] != null && range < zr[0]) ||
-                     (zr[1] != null && range > zr[1])))
-                    return;
-            
-                axisOptions.min = min;
-                axisOptions.max = max;
-            }
-
-            scaleAxis(x1, x2, 'xaxis');
-            scaleAxis(x1, x2, 'x2axis');
-            scaleAxis(y1, y2, 'yaxis');
-            scaleAxis(y1, y2, 'y2axis');
-            
-            plot.setupGrid();
-            plot.draw();
-            
-            if (!args.preventEvent)
-                plot.getPlaceholder().trigger("plotzoom", [ plot ]);
-        }
-
-        plot.pan = function (args) {
-            var l = +args.left, t = +args.top,
-                axes = plot.getAxes(), options = plot.getOptions();
-
-            if (isNaN(l))
-                l = 0;
-            if (isNaN(t))
-                t = 0;
-
-            function panAxis(delta, name) {
-                var axis = axes[name],
-                    axisOptions = options[name],
-                    min, max;
-                
-                if (!axis.used)
-                    return;
-
-                min = axis.c2p(axis.p2c(axis.min) + delta),
-                max = axis.c2p(axis.p2c(axis.max) + delta);
-
-                var pr = axisOptions.panRange;
-                if (pr) {
-                    // check whether we hit the wall
-                    if (pr[0] != null && pr[0] > min) {
-                        delta = pr[0] - min;
-                        min += delta;
-                        max += delta;
-                    }
-                    
-                    if (pr[1] != null && pr[1] < max) {
-                        delta = pr[1] - max;
-                        min += delta;
-                        max += delta;
-                    }
-                }
-                
-                axisOptions.min = min;
-                axisOptions.max = max;
-            }
-
-            panAxis(l, 'xaxis');
-            panAxis(l, 'x2axis');
-            panAxis(t, 'yaxis');
-            panAxis(t, 'y2axis');
-            
-            plot.setupGrid();
-            plot.draw();
-            
-            if (!args.preventEvent)
-                plot.getPlaceholder().trigger("plotpan", [ plot ]);
-        }
-        
-        plot.hooks.bindEvents.push(bindEvents);
-    }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'navigate',
-        version: '1.1'
-    });
-})(jQuery);
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.selection.js
+++ /dev/null
@@ -1,303 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-Flot plugin for selecting regions.
-
-The plugin defines the following options:
-
-  selection: {
-    mode: null or "x" or "y" or "xy",
-    color: color
-  }
-
-You enable selection support by setting the mode to one of "x", "y" or
-"xy". In "x" mode, the user will only be able to specify the x range,
-similarly for "y" mode. For "xy", the selection becomes a rectangle
-where both ranges can be specified. "color" is color of the selection.
-
-When selection support is enabled, a "plotselected" event will be emitted
-on the DOM element you passed into the plot function. The event
-handler gets one extra parameter with the ranges selected on the axes,
-like this:
-
-  placeholder.bind("plotselected", function(event, ranges) {
-    alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
-    // similar for yaxis, secondary axes are in x2axis
-    // and y2axis if present
-  });
-
-The "plotselected" event is only fired when the user has finished
-making the selection. A "plotselecting" event is fired during the
-process with the same parameters as the "plotselected" event, in case
-you want to know what's happening while it's happening,
-
-A "plotunselected" event with no arguments is emitted when the user
-clicks the mouse to remove the selection.
-
-The plugin allso adds the following methods to the plot object:
-
-- setSelection(ranges, preventEvent)
-
-  Set the selection rectangle. The passed in ranges is on the same
-  form as returned in the "plotselected" event. If the selection
-  mode is "x", you should put in either an xaxis (or x2axis) object,
-  if the mode is "y" you need to put in an yaxis (or y2axis) object
-  and both xaxis/x2axis and yaxis/y2axis if the selection mode is
-  "xy", like this:
-
-    setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
-
-  setSelection will trigger the "plotselected" event when called. If
-  you don't want that to happen, e.g. if you're inside a
-  "plotselected" handler, pass true as the second parameter.
-  
-- clearSelection(preventEvent)
-
-  Clear the selection rectangle. Pass in true to avoid getting a
-  "plotunselected" event.
-
-- getSelection()
-
-  Returns the current selection in the same format as the
-  "plotselected" event. If there's currently no selection, the
-  function returns null.
-
-*/
-
-(function ($) {
-    function init(plot) {
-        var selection = {
-                first: { x: -1, y: -1}, second: { x: -1, y: -1},
-                show: false,
-                active: false
-            };
-
-        // FIXME: The drag handling implemented here should be
-        // abstracted out, there's some similar code from a library in
-        // the navigation plugin, this should be massaged a bit to fit
-        // the Flot cases here better and reused. Doing this would
-        // make this plugin much slimmer.
-        var savedhandlers = {};
-
-        function onMouseMove(e) {
-            if (selection.active) {
-                plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
-
-                updateSelection(e);
-            }
-        }
-
-        function onMouseDown(e) {
-            if (e.which != 1)  // only accept left-click
-                return;
-            
-            // cancel out any text selections
-            document.body.focus();
-
-            // prevent text selection and drag in old-school browsers
-            if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
-                savedhandlers.onselectstart = document.onselectstart;
-                document.onselectstart = function () { return false; };
-            }
-            if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
-                savedhandlers.ondrag = document.ondrag;
-                document.ondrag = function () { return false; };
-            }
-
-            setSelectionPos(selection.first, e);
-
-            selection.active = true;
-            
-            $(document).one("mouseup", onMouseUp);
-        }
-
-        function onMouseUp(e) {
-            // revert drag stuff for old-school browsers
-            if (document.onselectstart !== undefined)
-                document.onselectstart = savedhandlers.onselectstart;
-            if (document.ondrag !== undefined)
-                document.ondrag = savedhandlers.ondrag;
-
-            // no more draggy-dee-drag
-            selection.active = false;
-            updateSelection(e);
-
-            if (selectionIsSane())
-                triggerSelectedEvent();
-            else {
-                // this counts as a clear
-                plot.getPlaceholder().trigger("plotunselected", [ ]);
-                plot.getPlaceholder().trigger("plotselecting", [ null ]);
-            }
-
-            return false;
-        }
-
-        function getSelection() {
-            if (!selectionIsSane())
-                return null;
-
-            var x1 = Math.min(selection.first.x, selection.second.x),
-                x2 = Math.max(selection.first.x, selection.second.x),
-                y1 = Math.max(selection.first.y, selection.second.y),
-                y2 = Math.min(selection.first.y, selection.second.y);
-
-            var r = {};
-            var axes = plot.getAxes();
-            if (axes.xaxis.used)
-                r.xaxis = { from: axes.xaxis.c2p(x1), to: axes.xaxis.c2p(x2) };
-            if (axes.x2axis.used)
-                r.x2axis = { from: axes.x2axis.c2p(x1), to: axes.x2axis.c2p(x2) };
-            if (axes.yaxis.used)
-                r.yaxis = { from: axes.yaxis.c2p(y1), to: axes.yaxis.c2p(y2) };
-            if (axes.y2axis.used)
-                r.y2axis = { from: axes.y2axis.c2p(y1), to: axes.y2axis.c2p(y2) };
-            return r;
-        }
-
-        function triggerSelectedEvent() {
-            var r = getSelection();
-
-            plot.getPlaceholder().trigger("plotselected", [ r ]);
-
-            // backwards-compat stuff, to be removed in future
-            var axes = plot.getAxes();
-            if (axes.xaxis.used && axes.yaxis.used)
-                plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
-        }
-
-        function clamp(min, value, max) {
-            return value < min? min: (value > max? max: value);
-        }
-
-        function setSelectionPos(pos, e) {
-            var o = plot.getOptions();
-            var offset = plot.getPlaceholder().offset();
-            var plotOffset = plot.getPlotOffset();
-            pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
-            pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
-
-            if (o.selection.mode == "y")
-                pos.x = pos == selection.first? 0: plot.width();
-
-            if (o.selection.mode == "x")
-                pos.y = pos == selection.first? 0: plot.height();
-        }
-
-        function updateSelection(pos) {
-            if (pos.pageX == null)
-                return;
-
-            setSelectionPos(selection.second, pos);
-            if (selectionIsSane()) {
-                selection.show = true;
-                plot.triggerRedrawOverlay();
-            }
-            else
-                clearSelection(true);
-        }
-
-        function clearSelection(preventEvent) {
-            if (selection.show) {
-                selection.show = false;
-                plot.triggerRedrawOverlay();
-                if (!preventEvent)
-                    plot.getPlaceholder().trigger("plotunselected", [ ]);
-            }
-        }
-
-        function setSelection(ranges, preventEvent) {
-            var axis, range, axes = plot.getAxes();
-            var o = plot.getOptions();
-
-            if (o.selection.mode == "y") {
-                selection.first.x = 0;
-                selection.second.x = plot.width();
-            }
-            else {
-                axis = ranges["xaxis"]? axes["xaxis"]: (ranges["x2axis"]? axes["x2axis"]: axes["xaxis"]);
-                range = ranges["xaxis"] || ranges["x2axis"] || { from:ranges["x1"], to:ranges["x2"] }
-                selection.first.x = axis.p2c(Math.min(range.from, range.to));
-                selection.second.x = axis.p2c(Math.max(range.from, range.to));
-            }
-
-            if (o.selection.mode == "x") {
-                selection.first.y = 0;
-                selection.second.y = plot.height();
-            }
-            else {
-                axis = ranges["yaxis"]? axes["yaxis"]: (ranges["y2axis"]? axes["y2axis"]: axes["yaxis"]);
-                range = ranges["yaxis"] || ranges["y2axis"] || { from:ranges["y1"], to:ranges["y2"] }
-                selection.first.y = axis.p2c(Math.min(range.from, range.to));
-                selection.second.y = axis.p2c(Math.max(range.from, range.to));
-            }
-
-            selection.show = true;
-            plot.triggerRedrawOverlay();
-            if (!preventEvent)
-                triggerSelectedEvent();
-        }
-
-        function selectionIsSane() {
-            var minSize = 5;
-            return Math.abs(selection.second.x - selection.first.x) >= minSize &&
-                Math.abs(selection.second.y - selection.first.y) >= minSize;
-        }
-
-        plot.clearSelection = clearSelection;
-        plot.setSelection = setSelection;
-        plot.getSelection = getSelection;
-
-        plot.hooks.bindEvents.push(function(plot, eventHolder) {
-            var o = plot.getOptions();
-            if (o.selection.mode != null)
-                eventHolder.mousemove(onMouseMove);
-
-            if (o.selection.mode != null)
-                eventHolder.mousedown(onMouseDown);
-        });
-
-
-        plot.hooks.drawOverlay.push(function (plot, ctx) {
-            // draw selection
-            if (selection.show && selectionIsSane()) {
-                var plotOffset = plot.getPlotOffset();
-                var o = plot.getOptions();
-
-                ctx.save();
-                ctx.translate(plotOffset.left, plotOffset.top);
-
-                var c = $.color.parse(o.selection.color);
-
-                ctx.strokeStyle = c.scale('a', 0.8).toString();
-                ctx.lineWidth = 1;
-                ctx.lineJoin = "round";
-                ctx.fillStyle = c.scale('a', 0.4).toString();
-
-                var x = Math.min(selection.first.x, selection.second.x),
-                    y = Math.min(selection.first.y, selection.second.y),
-                    w = Math.abs(selection.second.x - selection.first.x),
-                    h = Math.abs(selection.second.y - selection.first.y);
-
-                ctx.fillRect(x, y, w, h);
-                ctx.strokeRect(x, y, w, h);
-
-                ctx.restore();
-            }
-        });
-    }
-
-    $.plot.plugins.push({
-        init: init,
-        options: {
-            selection: {
-                mode: null, // one of null, "x", "y" or "xy"
-                color: "#e8cfac"
-            }
-        },
-        name: 'selection',
-        version: '1.0'
-    });
-})(jQuery);
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.stack.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-Flot plugin for stacking data sets, i.e. putting them on top of each
-other, for accumulative graphs. Note that the plugin assumes the data
-is sorted on x. Also note that stacking a mix of positive and negative
-values in most instances doesn't make sense (so it looks weird).
-
-Two or more series are stacked when their "stack" attribute is set to
-the same key (which can be any number or string or just "true"). To
-specify the default stack, you can set
-
-  series: {
-    stack: null or true or key (number/string)
-  }
-
-or specify it for a specific series
-
-  $.plot($("#placeholder"), [{ data: [ ... ], stack: true ])
-  
-The stacking order is determined by the order of the data series in
-the array (later series end up on top of the previous).
-
-Internally, the plugin modifies the datapoints in each series, adding
-an offset to the y value. For line series, extra data points are
-inserted through interpolation. For bar charts, the second y value is
-also adjusted.
-*/
-
-(function ($) {
-    var options = {
-        series: { stack: null } // or number/string
-    };
-    
-    function init(plot) {
-        function findMatchingSeries(s, allseries) {
-            var res = null
-            for (var i = 0; i < allseries.length; ++i) {
-                if (s == allseries[i])
-                    break;
-                
-                if (allseries[i].stack == s.stack)
-                    res = allseries[i];
-            }
-            
-            return res;
-        }
-        
-        function stackData(plot, s, datapoints) {
-            if (s.stack == null)
-                return;
-
-            var other = findMatchingSeries(s, plot.getData());
-            if (!other)
-                return;
-            
-            var ps = datapoints.pointsize,
-                points = datapoints.points,
-                otherps = other.datapoints.pointsize,
-                otherpoints = other.datapoints.points,
-                newpoints = [],
-                px, py, intery, qx, qy, bottom,
-                withlines = s.lines.show, withbars = s.bars.show,
-                withsteps = withlines && s.lines.steps,
-                i = 0, j = 0, l;
-
-            while (true) {
-                if (i >= points.length)
-                    break;
-
-                l = newpoints.length;
-
-                if (j >= otherpoints.length
-                    || otherpoints[j] == null
-                    || points[i] == null) {
-                    // degenerate cases
-                    for (m = 0; m < ps; ++m)
-                        newpoints.push(points[i + m]);
-                    i += ps;
-                }
-                else {
-                    // cases where we actually got two points
-                    px = points[i];
-                    py = points[i + 1];
-                    qx = otherpoints[j];
-                    qy = otherpoints[j + 1];
-                    bottom = 0;
-
-                    if (px == qx) {
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-
-                        newpoints[l + 1] += qy;
-                        bottom = qy;
-                        
-                        i += ps;
-                        j += otherps;
-                    }
-                    else if (px > qx) {
-                        // we got past point below, might need to
-                        // insert interpolated extra point
-                        if (withlines && i > 0 && points[i - ps] != null) {
-                            intery = py + (points[i - ps + 1] - py) * (qx - px) / (points[i - ps] - px);
-                            newpoints.push(qx);
-                            newpoints.push(intery + qy)
-                            for (m = 2; m < ps; ++m)
-                                newpoints.push(points[i + m]);
-                            bottom = qy; 
-                        }
-
-                        j += otherps;
-                    }
-                    else {
-                        for (m = 0; m < ps; ++m)
-                            newpoints.push(points[i + m]);
-                        
-                        // we might be able to interpolate a point below,
-                        // this can give us a better y
-                        if (withlines && j > 0 && otherpoints[j - ps] != null)
-                            bottom = qy + (otherpoints[j - ps + 1] - qy) * (px - qx) / (otherpoints[j - ps] - qx);
-
-                        newpoints[l + 1] += bottom;
-                        
-                        i += ps;
-                    }
-                    
-                    if (l != newpoints.length && withbars)
-                        newpoints[l + 2] += bottom;
-                }
-
-                // maintain the line steps invariant
-                if (withsteps && l != newpoints.length && l > 0
-                    && newpoints[l] != null
-                    && newpoints[l] != newpoints[l - ps]
-                    && newpoints[l + 1] != newpoints[l - ps + 1]) {
-                    for (m = 0; m < ps; ++m)
-                        newpoints[l + ps + m] = newpoints[l + m];
-                    newpoints[l + 1] = newpoints[l - ps + 1];
-                }
-            }
-            
-            datapoints.points = newpoints;
-        }
-        
-        plot.hooks.processDatapoints.push(stackData);
-    }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'stack',
-        version: '1.0'
-    });
-})(jQuery);
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.flot.threshold.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-Flot plugin for thresholding data. Controlled through the option
-"threshold" in either the global series options
-
-  series: {
-    threshold: {
-      below: number
-      color: colorspec
-    }
-  }
-
-or in a specific series
-
-  $.plot($("#placeholder"), [{ data: [ ... ], threshold: { ... }}])
-
-The data points below "below" are drawn with the specified color. This
-makes it easy to mark points below 0, e.g. for budget data.
-
-Internally, the plugin works by splitting the data into two series,
-above and below the threshold. The extra series below the threshold
-will have its label cleared and the special "originSeries" attribute
-set to the original series. You may need to check for this in hover
-events.
-*/
-
-(function ($) {
-    var options = {
-        series: { threshold: null } // or { below: number, color: color spec}
-    };
-    
-    function init(plot) {
-        function thresholdData(plot, s, datapoints) {
-            if (!s.threshold)
-                return;
-            
-            var ps = datapoints.pointsize, i, x, y, p, prevp,
-                thresholded = $.extend({}, s); // note: shallow copy
-
-            thresholded.datapoints = { points: [], pointsize: ps };
-            thresholded.label = null;
-            thresholded.color = s.threshold.color;
-            thresholded.threshold = null;
-            thresholded.originSeries = s;
-            thresholded.data = [];
-
-            var below = s.threshold.below,
-                origpoints = datapoints.points,
-                addCrossingPoints = s.lines.show;
-
-            threspoints = [];
-            newpoints = [];
-
-            for (i = 0; i < origpoints.length; i += ps) {
-                x = origpoints[i]
-                y = origpoints[i + 1];
-
-                prevp = p;
-                if (y < below)
-                    p = threspoints;
-                else
-                    p = newpoints;
-
-                if (addCrossingPoints && prevp != p && x != null
-                    && i > 0 && origpoints[i - ps] != null) {
-                    var interx = (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]) * (below - y) + x;
-                    prevp.push(interx);
-                    prevp.push(below);
-                    for (m = 2; m < ps; ++m)
-                        prevp.push(origpoints[i + m]);
-                    
-                    p.push(null); // start new segment
-                    p.push(null);
-                    for (m = 2; m < ps; ++m)
-                        p.push(origpoints[i + m]);
-                    p.push(interx);
-                    p.push(below);
-                    for (m = 2; m < ps; ++m)
-                        p.push(origpoints[i + m]);
-                }
-
-                p.push(x);
-                p.push(y);
-            }
-
-            datapoints.points = newpoints;
-            thresholded.datapoints.points = threspoints;
-            
-            if (thresholded.datapoints.points.length > 0)
-                plot.getData().push(thresholded);
-                
-            // FIXME: there are probably some edge cases left in bars
-        }
-        
-        plot.hooks.processDatapoints.push(thresholdData);
-    }
-    
-    $.plot.plugins.push({
-        init: init,
-        options: options,
-        name: 'threshold',
-        version: '1.0'
-    });
-})(jQuery);
deleted file mode 100644
--- a/mail/app/profile/extensions/tbtestpilot@labs.mozilla.com/content/flot/jquery.js
+++ /dev/null
@@ -1,4376 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.3.2
- * http://jquery.com/
- *
- * Copyright (c) 2009 John Resig
- * Dual licensed under the MIT and GPL licenses.
- * http://docs.jquery.com/License
- *
- * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
- * Revision: 6246
- */
-(function(){
-
-var 
-	// Will speed up references to window, and allows munging its name.
-	window = this,
-	// Will speed up references to undefined, and allows munging its name.
-	undefined,
-	// Map over jQuery in case of overwrite
-	_jQuery = window.jQuery,
-	// Map over the $ in case of overwrite
-	_$ = window.$,
-
-	jQuery = window.jQuery = window.$ = function( selector, context ) {
-		// The jQuery object is actually just the init constructor 'enhanced'
-		return new jQuery.fn.init( selector, context );
-	},
-
-	// A simple way to check for HTML strings or ID strings
-	// (both of which we optimize for)
-	quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
-	// Is it a simple selector
-	isSimple = /^.[^:#\[\.,]*$/;
-
-jQuery.fn = jQuery.prototype = {
-	init: function( selector, context ) {
-		// Make sure that a selection was provided
-		selector = selector || document;
-
-		// Handle $(DOMElement)
-		if ( selector.nodeType ) {
-			this[0] = selector;
-			this.length = 1;
-			this.context = selector;
-			return this;
-		}
-		// Handle HTML strings
-		if ( typeof selector === "string" ) {
-			// Are we dealing with HTML string or an ID?
-			var match = quickExpr.exec( selector );
-
-			// Verify a match, and that no context was specified for #id
-			if ( match && (match[1] || !context) ) {
-
-				// HANDLE: $(html) -> $(array)
-				if ( match[1] )
-					selector = jQuery.clean( [ match[1] ], context );
-
-				// HANDLE: $("#id")
-				else {
-					var elem = document.getElementById( match[3] );
-
-					// Handle the case where IE and Opera return items
-					// by name instead of ID
-					if ( elem && elem.id != match[3] )
-						return jQuery().find( selector );
-
-					// Otherwise, we inject the element directly into the jQuery object
-					var ret = jQuery( elem || [] );
-					ret.context = document;
-					ret.selector = selector;
-					return ret;
-				}
-
-			// HANDLE: $(expr, [context])
-			// (which is just equivalent to: $(content).find(expr)
-			} else
-				return jQuery( context ).find( selector );
-
-		// HANDLE: $(function)
-		// Shortcut for document ready
-		} else if ( jQuery.isFunction( selector ) )
-			return jQuery( document ).ready( selector );
-
-		// Make sure that old selector state is passed along
-		if ( selector.selector && selector.context ) {
-			this.selector = selector.selector;
-			this.context = selector.context;
-		}
-
-		return this.setArray(jQuery.isArray( selector ) ?
-			selector :
-			jQuery.makeArray(selector));
-	},
-
-	// Start with an empty selector
-	selector: "",
-
-	// The current version of jQuery being used
-	jquery: "1.3.2",
-
-	// The number of elements contained in the matched element set
-	size: function() {
-		return this.length;
-	},
-
-	// Get the Nth element in the matched element set OR
-	// Get the whole matched element set as a clean array
-	get: function( num ) {
-		return num === undefined ?
-
-			// Return a 'clean' array
-			Array.prototype.slice.call( this ) :
-
-			// Return just the object
-			this[ num ];
-	},
-
-	// Take an array of elements and push it onto the stack
-	// (returning the new matched element set)
-	pushStack: function( elems, name, selector ) {
-		// Build a new jQuery matched element set
-		var ret = jQuery( elems );
-
-		// Add the old object onto the stack (as a reference)
-		ret.prevObject = this;
-
-		ret.context = this.context;
-
-		if ( name === "find" )
-			ret.selector = this.selector + (this.selector ? " " : "") + selector;
-		else if ( name )
-			ret.selector = this.selector + "." + name + "(" + selector + ")";
-
-		// Return the newly-formed element set
-		return ret;
-	},
-
-	// Force the current matched set of elements to become
-	// the specified array of elements (destroying the stack in the process)
-	// You should use pushStack() in order to do this, but maintain the stack
-	setArray: function( elems ) {
-		// Resetting the length to 0, then using the native Array push
-		// is a super-fast way to populate an object with array-like properties
-		this.length = 0;
-		Array.prototype.push.apply( this, elems );
-
-		return this;
-	},
-
-	// Execute a callback for every element in the matched set.
-	// (You can seed the arguments with an array of args, but this is
-	// only used internally.)
-	each: function( callback, args ) {
-		return jQuery.each( this, callback, args );
-	},
-
-	// Determine the position of an element within
-	// the matched set of elements
-	index: function( elem ) {
-		// Locate the position of the desired element
-		return jQuery.inArray(
-			// If it receives a jQuery object, the first element is used
-			elem && elem.jquery ? elem[0] : elem
-		, this );
-	},
-
-	attr: function( name, value, type ) {
-		var options = name;
-
-		// Look for the case where we're accessing a style value
-		if ( typeof name === "string" )
-			if ( value === undefined )
-				return this[0] && jQuery[ type || "attr" ]( this[0], name );
-
-			else {
-				options = {};
-				options[ name ] = value;
-			}
-
-		// Check to see if we're setting style values
-		return this.each(function(i){
-			// Set all the styles
-			for ( name in options )
-				jQuery.attr(
-					type ?
-						this.style :
-						this,
-					name, jQuery.prop( this, options[ name ], type, i, name )
-				);
-		});
-	},
-
-	css: function( key, value ) {
-		// ignore negative width and height values
-		if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
-			value = undefined;
-		return this.attr( key, value, "curCSS" );
-	},
-
-	text: function( text ) {
-		if ( typeof text !== "object" && text != null )
-			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
-
-		var ret = "";
-
-		jQuery.each( text || this, function(){
-			jQuery.each( this.childNodes, function(){
-				if ( this.nodeType != 8 )
-					ret += this.nodeType != 1 ?
-						this.nodeValue :
-						jQuery.fn.text( [ this ] );
-			});
-		});
-
-		return ret;
-	},
-
-	wrapAll: function( html ) {
-		if ( this[0] ) {
-			// The elements to wrap the target around
-			var wrap = jQuery( html, this[0].ownerDocument ).clone();
-
-			if ( this[0].parentNode )
-				wrap.insertBefore( this[0] );
-
-			wrap.map(function(){
-				var elem = this;
-
-				while ( elem.firstChild )
-					elem = elem.firstChild;
-
-				return elem;
-			}).append(this);
-		}
-
-		return this;
-	},
-
-	wrapInner: function( html ) {
-		return this.each(function(){
-			jQuery( this ).contents().wrapAll( html );
-		});
-	},
-
-	wrap: function( html ) {
-		return this.each(function(){
-			jQuery( this ).wrapAll( html );
-		});
-	},
-
-	append: function() {
-		return this.domManip(arguments, true, function(elem){
-			if (this.nodeType == 1)
-				this.appendChild( elem );
-		});
-	},
-
-	prepend: function() {
-		return this.domManip(arguments, true, function(elem){
-			if (this.nodeType == 1)
-				this.insertBefore( elem, this.firstChild );
-		});
-	},
-
-	before: function() {
-		return this.domManip(arguments, false, function(elem){
-			this.parentNode.insertBefore( elem, this );
-		});
-	},
-
-	after: function() {
-		return this.domManip(arguments, false, function(elem){
-			this.parentNode.insertBefore( elem, this.nextSibling );
-		});
-	},
-
-	end: function() {
-		return this.prevObject || jQuery( [] );
-	},
-
-	// For internal use only.
-	// Behaves like an Array's method, not like a jQuery method.
-	push: [].push,
-	sort: [].sort,
-	splice: [].splice,
-
-	find: function( selector ) {
-		if ( this.length === 1 ) {
-			var ret = this.pushStack( [], "find", selector );
-			ret.length = 0;
-			jQuery.find( selector, this[0], ret );
-			return ret;
-		} else {
-			return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
-				return jQuery.find( selector, elem );
-			})), "find", selector );
-		}
-	},
-
-	clone: function( events ) {
-		// Do the clone
-		var ret = this.map(function(){
-			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
-				// IE copies events bound via attachEvent when
-				// using cloneNode. Calling detachEvent on the
-				// clone will also remove the events from the orignal
-				// In order to get around this, we use innerHTML.
-				// Unfortunately, this means some modifications to
-				// attributes in IE that are actually only stored
-				// as properties will not be copied (such as the
-				// the name attribute on an input).
-				var html = this.outerHTML;
-				if ( !html ) {
-					var div = this.ownerDocument.createElement("div");
-					div.appendChild( this.cloneNode(true) );
-					html = div.innerHTML;
-				}
-
-				return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
-			} else
-				return this.cloneNode(true);
-		});
-
-		// Copy the events from the original to the clone
-		if ( events === true ) {
-			var orig = this.find("*").andSelf(), i = 0;
-
-			ret.find("*").andSelf().each(function(){
-				if ( this.nodeName !== orig[i].nodeName )
-					return;
-
-				var events = jQuery.data( orig[i], "events" );
-
-				for ( var type in events ) {
-					for ( var handler in events[ type ] ) {
-						jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
-					}
-				}
-
-				i++;
-			});
-		}
-
-		// Return the cloned set
-		return ret;
-	},
-
-	filter: function( selector ) {
-		return this.pushStack(
-			jQuery.isFunction( selector ) &&
-			jQuery.grep(this, function(elem, i){
-				return selector.call( elem, i );
-			}) ||
-
-			jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
-				return elem.nodeType === 1;
-			}) ), "filter", selector );
-	},
-
-	closest: function( selector ) {
-		var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
-			closer = 0;
-
-		return this.map(function(){
-			var cur = this;
-			while ( cur && cur.ownerDocument ) {
-				if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
-					jQuery.data(cur, "closest", closer);
-					return cur;
-				}
-				cur = cur.parentNode;
-				closer++;
-			}
-		});
-	},
-
-	not: function( selector ) {
-		if ( typeof selector === "string" )
-			// test special case where just one selector is passed in
-			if ( isSimple.test( selector ) )
-				return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
-			else
-				selector = jQuery.multiFilter( selector, this );
-
-		var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
-		return this.filter(function() {
-			return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
-		});
-	},
-
-	add: function( selector ) {
-		return this.pushStack( jQuery.unique( jQuery.merge(
-			this.get(),
-			typeof selector === "string" ?
-				jQuery( selector ) :
-				jQuery.makeArray( selector )
-		)));
-	},
-
-	is: function( selector ) {
-		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
-	},
-
-	hasClass: function( selector ) {
-		return !!selector && this.is( "." + selector );
-	},
-
-	val: function( value ) {
-		if ( value === undefined ) {			
-			var elem = this[0];
-
-			if ( elem ) {
-				if( jQuery.nodeName( elem, 'option' ) )
-					return (elem.attributes.value || {}).specified ? elem.value : elem.text;
-				
-				// We need to handle select boxes special
-				if ( jQuery.nodeName( elem, "select" ) ) {
-					var index = elem.selectedIndex,
-						values = [],
-						options = elem.options,
-						one = elem.type == "select-one";
-
-					// Nothing was selected
-					if ( index < 0 )
-						return null;
-
-					// Loop through all the selected options
-					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
-						var option = options[ i ];
-
-						if ( option.selected ) {
-							// Get the specifc value for the option
-							value = jQuery(option).val();
-
-							// We don't need an array for one selects
-							if ( one )
-								return value;
-
-							// Multi-Selects return an array
-							values.push( value );
-						}
-					}
-
-					return values;				
-				}
-
-				// Everything else, we just grab the value
-				return (elem.value || "").replace(/\r/g, "");
-
-			}
-
-			return undefined;
-		}
-
-		if ( typeof value === "number" )
-			value += '';
-
-		return this.each(function(){
-			if ( this.nodeType != 1 )
-				return;
-
-			if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
-				this.checked = (jQuery.inArray(this.value, value) >= 0 ||
-					jQuery.inArray(this.name, value) >= 0);
-
-			else if ( jQuery.nodeName( this, "select" ) ) {
-				var values = jQuery.makeArray(value);
-
-				jQuery( "option", this ).each(function(){
-					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
-						jQuery.inArray( this.text, values ) >= 0);
-				});
-
-				if ( !values.length )
-					this.selectedIndex = -1;
-
-			} else
-				this.value = value;
-		});
-	},
-
-	html: function( value ) {
-		return value === undefined ?
-			(this[0] ?
-				this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
-				null) :
-			this.empty().append( value );
-	},
-
-	replaceWith: function( value ) {
-		return this.after( value ).remove();
-	},
-
-	eq: function( i ) {
-		return this.slice( i, +i + 1 );
-	},
-
-	slice: function() {
-		return this.pushStack( Array.prototype.slice.apply( this, arguments ),
-			"slice", Array.prototype.slice.call(arguments).join(",") );
-	},
-
-	map: function( callback ) {
-		return this.pushStack( jQuery.map(this, function(elem, i){
-			return callback.call( elem, i, elem );
-		}));
-	},
-
-	andSelf: function() {
-		return this.add( this.prevObject );
-	},
-
-	domManip: function( args, table, callback ) {
-		if ( this[0] ) {
-			var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
-				scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
-				first = fragment.firstChild;
-
-			if ( first )
-				for ( var i = 0, l = this.length; i < l; i++ )
-					callback.call( root(this[i], first), this.length > 1 || i > 0 ?
-							fragment.cloneNode(true) : fragment );
-		
-			if ( scripts )
-				jQuery.each( scripts, evalScript );
-		}
-
-		return this;
-		
-		function root( elem, cur ) {
-			return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
-				(elem.getElementsByTagName("tbody")[0] ||
-				elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
-				elem;
-		}
-	}
-};
-
-// Give the init function the jQuery prototype for later instantiation
-jQuery.fn.init.prototype = jQuery.fn;
-
-function evalScript( i, elem ) {
-	if ( elem.src )
-		jQuery.ajax({
-			url: elem.src,
-			async: false,
-			dataType: "script"
-		});
-
-	else
-		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
-
-	if ( elem.parentNode )
-		elem.parentNode.removeChild( elem );
-}
-
-function now(){
-	return +new Date;
-}
-
-jQuery.extend = jQuery.fn.extend = function() {
-	// copy reference to target object
-	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
-
-	// Handle a deep copy situation
-	if ( typeof target === "boolean" ) {
-		deep = target;
-		target = arguments[1] || {};
-		// skip the boolean and the target
-		i = 2;
-	}
-
-	// Handle case when target is a string or something (possible in deep copy)
-	if ( typeof target !== "object" && !jQuery.isFunction(target) )
-		target = {};
-
-	// extend jQuery itself if only one argument is passed
-	if ( length == i ) {
-		target = this;
-		--i;
-	}
-
-	for ( ; i < length; i++ )
-		// Only deal with non-null/undefined values
-		if ( (options = arguments[ i ]) != null )
-			// Extend the base object
-			for ( var name in options ) {
-				var src = target[ name ], copy = options[ name ];
-
-				// Prevent never-ending loop
-				if ( target === copy )
-					continue;
-
-				// Recurse if we're merging object values
-				if ( deep && copy && typeof copy === "object" && !copy.nodeType )
-					target[ name ] = jQuery.extend( deep, 
-						// Never move original objects, clone them
-						src || ( copy.length != null ? [ ] : { } )
-					, copy );
-
-				// Don't bring in undefined values
-				else if ( copy !== undefined )
-					target[ name ] = copy;
-
-			}
-
-	// Return the modified object
-	return target;
-};
-
-// exclude the following css properties to add px
-var	exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
-	// cache defaultView
-	defaultView = document.defaultView || {},
-	toString = Object.prototype.toString;
-
-jQuery.extend({
-	noConflict: function( deep ) {
-		window.$ = _$;
-
-		if ( deep )
-			window.jQuery = _jQuery;
-
-		return jQuery;
-	},
-
-	// See test/unit/core.js for details concerning isFunction.
-	// Since version 1.3, DOM methods and functions like alert
-	// aren't supported. They return false on IE (#2968).
-	isFunction: function( obj ) {
-		return toString.call(obj) === "[object Function]";
-	},
-
-	isArray: function( obj ) {
-		return toString.call(obj) === "[object Array]";
-	},
-
-	// check if an element is in a (or is an) XML document
-	isXMLDoc: function( elem ) {
-		return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
-			!!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
-	},
-
-	// Evalulates a script in a global context
-	globalEval: function( data ) {
-		if ( data && /\S/.test(data) ) {
-			// Inspired by code by Andrea Giammarchi
-			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
-			var head = document.getElementsByTagName("head")[0] || document.documentElement,
-				script = document.createElement("script");
-
-			script.type = "text/javascript";
-			if ( jQuery.support.scriptEval )
-				script.appendChild( document.createTextNode( data ) );
-			else
-				script.text = data;
-
-			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
-			// This arises when a base node is used (#2709).
-			head.insertBefore( script, head.firstChild );
-			head.removeChild( script );
-		}
-	},
-
-	nodeName: function( elem, name ) {
-		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
-	},
-
-	// args is for internal usage only
-	each: function( object, callback, args ) {
-		var name, i = 0, length = object.length;
-
-		if ( args ) {
-			if ( length === undefined ) {
-				for ( name in object )
-					if ( callback.apply( object[ name ], args ) === false )
-						break;
-			} else
-				for ( ; i < length; )
-					if ( callback.apply( object[ i++ ], args ) === false )
-						break;
-
-		// A special, fast, case for the most common use of each
-		} else {
-			if ( length === undefined ) {
-				for ( name in object )
-					if ( callback.call( object[ name ], name, object[ name ] ) === false )
-						break;
-			} else
-				for ( var value = object[0];
-					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
-		}
-
-		return object;
-	},
-
-	prop: function( elem, value, type, i, name ) {
-		// Handle executable functions
-		if ( jQuery.isFunction( value ) )
-			value = value.call( elem, i );
-
-		// Handle passing in a number to a CSS property
-		return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
-			value + "px" :
-			value;
-	},
-
-	className: {
-		// internal only, use addClass("class")
-		add: function( elem, classNames ) {
-			jQuery.each((classNames || "").split(/\s+/), function(i, className){
-				if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
-					elem.className += (elem.className ? " " : "") + className;
-			});
-		},
-
-		// internal only, use removeClass("class")
-		remove: function( elem, classNames ) {
-			if (elem.nodeType == 1)
-				elem.className = classNames !== undefined ?
-					jQuery.grep(elem.className.split(/\s+/), function(className){
-						return !jQuery.className.has( classNames, className );
-					}).join(" ") :
-					"";
-		},
-
-		// internal only, use hasClass("class")
-		has: function( elem, className ) {
-			return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
-		}
-	},
-
-	// A method for quickly swapping in/out CSS properties to get correct calculations
-	swap: function( elem, options, callback ) {
-		var old = {};
-		// Remember the old values, and insert the new ones
-		for ( var name in options ) {
-			old[ name ] = elem.style[ name ];
-			elem.style[ name ] = options[ name ];
-		}
-
-		callback.call( elem );
-
-		// Revert the old values
-		for ( var name in options )
-			elem.style[ name ] = old[ name ];
-	},
-
-	css: function( elem, name, force, extra ) {
-		if ( name == "width" || name == "height" ) {
-			var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
-
-			function getWH() {
-				val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
-
-				if ( extra === "border" )
-					return;
-
-				jQuery.each( which, function() {
-					if ( !extra )
-						val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
-					if ( extra === "margin" )
-						val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
-					else
-						val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
-				});
-			}
-
-			if ( elem.offsetWidth !== 0 )
-				getWH();
-			else
-				jQuery.swap( elem, props, getWH );
-
-			return Math.max(0, Math.round(val));
-		}
-
-		return jQuery.curCSS( elem, name, force );
-	},
-
-	curCSS: function( elem, name, force ) {
-		var ret, style = elem.style;
-
-		// We need to handle opacity special in IE
-		if ( name == "opacity" && !jQuery.support.opacity ) {
-			ret = jQuery.attr( style, "opacity" );
-
-			return ret == "" ?
-				"1" :
-				ret;
-		}
-
-		// Make sure we're using the right name for getting the float value
-		if ( name.match( /float/i ) )
-			name = styleFloat;
-
-		if ( !force && style && style[ name ] )
-			ret = style[ name ];
-
-		else if ( defaultView.getComputedStyle ) {
-
-			// Only "float" is needed here
-			if ( name.match( /float/i ) )
-				name = "float";
-
-			name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
-
-			var computedStyle = defaultView.getComputedStyle( elem, null );
-
-			if ( computedStyle )
-				ret = computedStyle.getPropertyValue( name );
-
-			// We should always get a number back from opacity
-			if ( name == "opacity" && ret == "" )
-				ret = "1";
-
-		} else if ( elem.currentStyle ) {
-			var camelCase = name.replace(/\-(\w)/g, function(all, letter){
-				return letter.toUpperCase();
-			});
-
-			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
-
-			// From the awesome hack by Dean Edwards
-			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
-			// If we're not dealing with a regular pixel number
-			// but a number that has a weird ending, we need to convert it to pixels
-			if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
-				// Remember the original values
-				var left = style.left, rsLeft = elem.runtimeStyle.left;
-
-				// Put in the new values to get a computed value out
-				elem.runtimeStyle.left = elem.currentStyle.left;
-				style.left = ret || 0;
-				ret = style.pixelLeft + "px";
-
-				// Revert the changed values
-				style.left = left;
-				elem.runtimeStyle.left = rsLeft;
-			}
-		}
-
-		return ret;
-	},
-
-	clean: function( elems, context, fragment ) {
-		context = context || document;
-
-		// !context.createElement fails in IE with an error but returns typeof 'object'
-		if ( typeof context.createElement === "undefined" )
-			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
-
-		// If a single string is passed in and it's a single tag
-		// just do a createElement and skip the rest
-		if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
-			var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
-			if ( match )
-				return [ context.createElement( match[1] ) ];
-		}
-
-		var ret = [], scripts = [], div = context.createElement("div");
-
-		jQuery.each(elems, function(i, elem){
-			if ( typeof elem === "number" )
-				elem += '';
-
-			if ( !elem )
-				return;
-
-			// Convert html string into DOM nodes
-			if ( typeof elem === "string" ) {
-				// Fix "XHTML"-style tags in all browsers
-				elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
-					return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
-						all :
-						front + "></" + tag + ">";
-				});
-
-				// Trim whitespace, otherwise indexOf won't work as expected
-				var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
-
-				var wrap =
-					// option or optgroup
-					!tags.indexOf("<opt") &&
-					[ 1, "<select multiple='multiple'>", "</select>" ] ||
-
-					!tags.indexOf("<leg") &&
-					[ 1, "<fieldset>", "</fieldset>" ] ||
-
-					tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
-					[ 1, "<table>", "</table>" ] ||
-
-					!tags.indexOf("<tr") &&
-					[ 2, "<table><tbody>", "</tbody></table>" ] ||
-
-				 	// <thead> matched above
-					(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
-					[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
-
-					!tags.indexOf("<col") &&
-					[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
-
-					// IE can't serialize <link> and <script> tags normally
-					!jQuery.support.htmlSerialize &&
-					[ 1, "div<div>", "</div>" ] ||
-
-					[ 0, "", "" ];
-
-				// Go to html and back, then peel off extra wrappers
-				div.innerHTML = wrap[1] + elem + wrap[2];
-
-				// Move to the right depth
-				while ( wrap[0]-- )
-					div = div.lastChild;
-
-				// Remove IE's autoinserted <tbody> from table fragments
-				if ( !jQuery.support.tbody ) {
-
-					// String was a <table>, *may* have spurious <tbody>
-					var hasBody = /<tbody/i.test(elem),
-						tbody = !tags.indexOf("<table") && !hasBody ?
-							div.firstChild && div.firstChild.childNodes :
-
-						// String was a bare <thead> or <tfoot>
-						wrap[1] == "<table>" && !hasBody ?
-							div.childNodes :
-							[];
-
-					for ( var j = tbody.length - 1; j >= 0 ; --j )
-						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
-							tbody[ j ].parentNode.removeChild( tbody[ j ] );
-
-					}
-
-				// IE completely kills leading whitespace when innerHTML is used
-				if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
-					div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
-				
-				elem = jQuery.makeArray( div.childNodes );
-			}
-
-			if ( elem.nodeType )
-				ret.push( elem );
-			else
-				ret = jQuery.merge( ret, elem );
-
-		});
-
-		if ( fragment ) {
-			for ( var i = 0; ret[i]; i++ ) {
-				if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
-					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
-				} else {
-					if ( ret[i].nodeType === 1 )
-						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
-					fragment.appendChild( ret[i] );
-				}
-			}
-			
-			return scripts;
-		}
-
-		return ret;
-	},
-
-	attr: function( elem, name, value ) {
-		// don't set attributes on text and comment nodes
-		if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
-			return undefined;
-
-		var notxml = !jQuery.isXMLDoc( elem ),
-			// Whether we are setting (or getting)
-			set = value !== undefined;
-
-		// Try to normalize/fix the name
-		name = notxml && jQuery.props[ name ] || name;
-
-		// Only do all the following if this is a node (faster for style)
-		// IE elem.getAttribute passes even for style
-		if ( elem.tagName ) {
-
-			// These attributes require special treatment
-			var special = /href|src|style/.test( name );
-
-			// Safari mis-reports the default selected property of a hidden option
-			// Accessing the parent's selectedIndex property fixes it
-			if ( name == "selected" && elem.parentNode )
-				elem.parentNode.selectedIndex;
-
-			// If applicable, access the attribute via the DOM 0 way
-			if ( name in elem && notxml && !special ) {
-				if ( set ){
-					// We can't allow the type property to be changed (since it causes problems in IE)
-					if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
-						throw "type property can't be changed";
-
-					elem[ name ] = value;
-				}
-
-				// browsers index elements by id/name on forms, give priority to attributes.
-				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
-					return elem.getAttributeNode( name ).nodeValue;
-
-				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
-				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
-				if ( name == "tabIndex" ) {
-					var attributeNode = elem.getAttributeNode( "tabIndex" );
-					return attributeNode && attributeNode.specified
-						? attributeNode.value
-						: elem.nodeName.match(/(button|input|object|select|textarea)/i)
-							? 0
-							: elem.nodeName.match(/^(a|area)$/i) && elem.href
-								? 0
-								: undefined;
-				}
-
-				return elem[ name ];
-			}
-
-			if ( !jQuery.support.style && notxml &&  name == "style" )
-				return jQuery.attr( elem.style, "cssText", value );
-
-			if ( set )
-				// convert the value to a string (all browsers do this but IE) see #1070
-				elem.setAttribute( name, "" + value );
-
-			var attr = !jQuery.support.hrefNormalized && notxml && special
-					// Some attributes require a special call on IE
-					? elem.getAttribute( name, 2 )
-					: elem.getAttribute( name );
-
-			// Non-existent attributes return null, we normalize to undefined
-			return attr === null ? undefined : attr;
-		}
-
-		// elem is actually elem.style ... set the style
-
-		// IE uses filters for opacity
-		if ( !jQuery.support.opacity && name == "opacity" ) {
-			if ( set ) {
-				// IE has trouble with opacity if it does not have layout
-				// Force it by setting the zoom level
-				elem.zoom = 1;
-
-				// Set the alpha filter to set the opacity
-				elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
-					(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
-			}
-
-			return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
-				(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
-				"";
-		}
-
-		name = name.replace(/-([a-z])/ig, function(all, letter){
-			return letter.toUpperCase();
-		});
-
-		if ( set )
-			elem[ name ] = value;
-
-		return elem[ name ];
-	},
-
-	trim: function( text ) {
-		return (text || "").replace( /^\s+|\s+$/g, "" );
-	},
-
-	makeArray: function( array ) {
-		var ret = [];
-
-		if( array != null ){
-			var i = array.length;
-			// The window, strings (and functions) also have 'length'
-			if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
-				ret[0] = array;
-			else
-				while( i )
-					ret[--i] = array[i];
-		}
-
-		return ret;
-	},
-
-	inArray: function( elem, array ) {
-		for ( var i = 0, length = array.length; i < length; i++ )
-		// Use === because on IE, window == document
-			if ( array[ i ] === elem )
-				return i;
-
-		return -1;
-	},
-
-	merge: function( first, second ) {
-		// We have to loop this way because IE & Opera overwrite the length
-		// expando of getElementsByTagName
-		var i = 0, elem, pos = first.length;
-		// Also, we need to make sure that the correct elements are being returned
-		// (IE returns comment nodes in a '*' query)
-		if ( !jQuery.support.getAll ) {
-			while ( (elem = second[ i++ ]) != null )
-				if ( elem.nodeType != 8 )
-					first[ pos++ ] = elem;
-
-		} else
-			while ( (elem = second[ i++ ]) != null )
-				first[ pos++ ] = elem;
-
-		return first;
-	},
-
-	unique: function( array ) {
-		var ret = [], done = {};
-
-		try {
-
-			for ( var i = 0, length = array.length; i < length; i++ ) {
-				var id = jQuery.data( array[ i ] );
-
-				if ( !done[ id ] ) {
-					done[ id ] = true;
-					ret.push( array[ i ] );
-				}
-			}
-
-		} catch( e ) {
-			ret = array;
-		}
-
-		return ret;
-	},
-
-	grep: function( elems, callback, inv ) {
-		var ret = [];
-
-		// Go through the array, only saving the items
-		// that pass the validator function
-		for ( var i = 0, length = elems.length; i < length; i++ )
-			if ( !inv != !callback( elems[ i ], i ) )
-				ret.push( elems[ i ] );
-
-		return ret;
-	},
-
-	map: function( elems, callback ) {
-		var ret = [];
-
-		// Go through the array, translating each of the items to their
-		// new value (or values).
-		for ( var i = 0, length = elems.length; i < length; i++ ) {
-			var value = callback( elems[ i ], i );
-
-			if ( value != null )
-				ret[ ret.length ] = value;
-		}
-
-		return ret.concat.apply( [], ret );
-	}
-});
-
-// Use of jQuery.browser is deprecated.
-// It's included for backwards compatibility and plugins,
-// although they should work to migrate away.
-
-var userAgent = navigator.userAgent.toLowerCase();
-
-// Figure out what browser is being used
-jQuery.browser = {
-	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
-	safari: /webkit/.test( userAgent ),
-	opera: /opera/.test( userAgent ),
-	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
-	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
-};
-
-jQuery.each({
-	parent: function(elem){return elem.parentNode;},
-	parents: function(elem){return jQuery.dir(elem,"parentNode");},
-	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
-	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
-	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
-	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
-	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
-	children: function(elem){return jQuery.sibling(elem.firstChild);},
-	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
-}, function(name, fn){
-	jQuery.fn[ name ] = function( selector ) {
-		var ret = jQuery.map( this, fn );
-
-		if ( selector && typeof selector == "string" )
-			ret = jQuery.multiFilter( selector, ret );
-
-		return this.pushStack( jQuery.unique( ret ), name, selector );
-	};
-});
-
-jQuery.each({
-	appendTo: "append",
-	prependTo: "prepend",
-	insertBefore: "before",
-	insertAfter: "after",
-	replaceAll: "replaceWith"
-}, function(name, original){
-	jQuery.fn[ name ] = function( selector ) {
-		var ret = [], insert = jQuery( selector );
-
-		for ( var i = 0, l = insert.length; i < l; i++ ) {
-			var elems = (i > 0 ? this.clone(true) : this).get();
-			jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
-			ret = ret.concat( elems );
-		}
-
-		return this.pushStack( ret, name, selector );
-	};
-});
-
-jQuery.each({
-	removeAttr: function( name ) {
-		jQuery.attr( this, name, "" );
-		if (this.nodeType == 1)
-			this.removeAttribute( name );
-	},
-
-	addClass: function( classNames ) {
-		jQuery.className.add( this, classNames );
-	},
-
-	removeClass: function( classNames ) {
-		jQuery.className.remove( this, classNames );
-	},
-
-	toggleClass: function( classNames, state ) {
-		if( typeof state !== "boolean" )
-			state = !jQuery.className.has( this, classNames );
-		jQuery.className[ state ? "add" : "remove" ]( this, classNames );
-	},
-
-	remove: function( selector ) {
-		if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
-			// Prevent memory leaks
-			jQuery( "*", this ).add([this]).each(function(){
-				jQuery.event.remove(this);
-				jQuery.removeData(this);
-			});
-			if (this.parentNode)
-				this.parentNode.removeChild( this );
-		}
-	},
-
-	empty: function() {
-		// Remove element nodes and prevent memory leaks
-		jQuery(this).children().remove();
-
-		// Remove any remaining nodes
-		while ( this.firstChild )
-			this.removeChild( this.firstChild );
-	}
-}, function(name, fn){
-	jQuery.fn[ name ] = function(){
-		return this.each( fn, arguments );
-	};
-});
-
-// Helper function used by the dimensions and offset modules
-function num(elem, prop) {
-	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
-}
-var expando = "jQuery" + now(), uuid = 0, windowData = {};
-
-jQuery.extend({
-	cache: {},
-
-	data: function( elem, name, data ) {
-		elem = elem == window ?
-			windowData :
-			elem;
-
-		var id = elem[ expando ];
-
-		// Compute a unique ID for the element
-		if ( !id )
-			id = elem[ expando ] = ++uuid;
-
-		// Only generate the data cache if we're
-		// trying to access or manipulate it
-		if ( name && !jQuery.cache[ id ] )
-			jQuery.cache[ id ] = {};
-
-		// Prevent overriding the named cache with undefined values
-		if ( data !== undefined )
-			jQuery.cache[ id ][ name ] = data;
-
-		// Return the named cache data, or the ID for the element
-		return name ?
-			jQuery.cache[ id ][ name ] :
-			id;
-	},
-
-	removeData: function( elem, name ) {
-		elem = elem == window ?
-			windowData :
-			elem;
-
-		var id = elem[ expando ];
-
-		// If we want to remove a specific section of the element's data
-		if ( name ) {
-			if ( jQuery.cache[ id ] ) {
-				// Remove the section of cache data
-				delete jQuery.cache[ id ][ name ];
-
-				// If we've removed all the data, remove the element's cache
-				name = "";
-
-				for ( name in jQuery.cache[ id ] )
-					break;
-
-				if ( !name )
-					jQuery.removeData( elem );
-			}
-
-		// Otherwise, we want to remove all of the element's data
-		} else {
-			// Clean up the element expando
-			try {
-				delete elem[ expando ];
-			} catch(e){
-				// IE has trouble directly removing the expando
-				// but it's ok with using removeAttribute
-				if ( elem.removeAttribute )
-					elem.removeAttribute( expando );
-			}
-
-			// Completely remove the data cache
-			delete jQuery.cache[ id ];
-		}
-	},
-	queue: function( elem, type, data ) {
-		if ( elem ){
-	
-			type = (type || "fx") + "queue";
-	
-			var q = jQuery.data( elem, type );
-	
-			if ( !q || jQuery.isArray(data) )
-				q = jQuery.data( elem, type, jQuery.makeArray(data) );
-			else if( data )
-				q.push( data );
-	
-		}
-		return q;
-	},
-
-	dequeue: function( elem, type ){
-		var queue = jQuery.queue( elem, type ),
-			fn = queue.shift();
-		
-		if( !type || type === "fx" )
-			fn = queue[0];
-			
-		if( fn !== undefined )
-			fn.call(elem);
-	}
-});
-
-jQuery.fn.extend({
-	data: function( key, value ){
-		var parts = key.split(".");
-		parts[1] = parts[1] ? "." + parts[1] : "";
-
-		if ( value === undefined ) {
-			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
-
-			if ( data === undefined && this.length )
-				data = jQuery.data( this[0], key );
-
-			return data === undefined && parts[1] ?
-				this.data( parts[0] ) :
-				data;
-		} else
-			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
-				jQuery.data( this, key, value );
-			});
-	},
-
-	removeData: function( key ){
-		return this.each(function(){
-			jQuery.removeData( this, key );
-		});
-	},
-	queue: function(type, data){
-		if ( typeof type !== "string" ) {
-			data = type;
-			type = "fx";
-		}
-
-		if ( data === undefined )
-			return jQuery.queue( this[0], type );
-
-		return this.each(function(){
-			var queue = jQuery.queue( this, type, data );
-			
-			 if( type == "fx" && queue.length == 1 )
-				queue[0].call(this);
-		});
-	},
-	dequeue: function(type){
-		return this.each(function(){
-			jQuery.dequeue( this, type );
-		});
-	}
-});/*!
- * Sizzle CSS Selector Engine - v0.9.3
- *  Copyright 2009, The Dojo Foundation
- *  Released under the MIT, BSD, and GPL Licenses.
- *  More information: http://sizzlejs.com/
- */
-(function(){
-
-var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
-	done = 0,
-	toString = Object.prototype.toString;
-
-var Sizzle = function(selector, context, results, seed) {
-	results = results || [];
-	context = context || document;
-
-	if ( context.nodeType !== 1 && context.nodeType !== 9 )
-		return [];
-	
-	if ( !selector || typeof selector !== "string" ) {
-		return results;
-	}
-
-	var parts = [], m, set, checkSet, check, mode, extra, prune = true;
-	
-	// Reset the position of the chunker regexp (start from head)
-	chunker.lastIndex = 0;
-	
-	while ( (m = chunker.exec(selector)) !== null ) {
-		parts.push( m[1] );
-		
-		if ( m[2] ) {
-			extra = RegExp.rightContext;
-			break;
-		}
-	}
-
-	if ( parts.length > 1 && origPOS.exec( selector ) ) {
-		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
-			set = posProcess( parts[0] + parts[1], context );
-		} else {
-			set = Expr.relative[ parts[0] ] ?
-				[ context ] :
-				Sizzle( parts.shift(), context );
-
-			while ( parts.length ) {
-				selector = parts.shift();
-
-				if ( Expr.relative[ selector ] )
-					selector += parts.shift();
-
-				set = posProcess( selector, set );
-			}
-		}
-	} else {
-		var ret = seed ?
-			{ expr: parts.pop(), set: makeArray(seed) } :
-			Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
-		set = Sizzle.filter( ret.expr, ret.set );
-
-		if ( parts.length > 0 ) {
-			checkSet = makeArray(set);
-		} else {
-			prune = false;
-		}
-
-		while ( parts.length ) {
-			var cur = parts.pop(), pop = cur;
-
-			if ( !Expr.relative[ cur ] ) {
-				cur = "";
-			} else {
-				pop = parts.pop();
-			}
-
-			if ( pop == null ) {
-				pop = context;
-			}
-
-			Expr.relative[ cur ]( checkSet, pop, isXML(context) );
-		}
-	}
-
-	if ( !checkSet ) {
-		checkSet = set;
-	}
-
-	if ( !checkSet ) {
-		throw "Syntax error, unrecognized expression: " + (cur || selector);
-	}
-
-	if ( toString.call(checkSet) === "[object Array]" ) {
-		if ( !prune ) {
-			results.push.apply( results, checkSet );
-		} else if ( context.nodeType === 1 ) {
-			for ( var i = 0; checkSet[i] != null; i++ ) {
-				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
-					results.push( set[i] );
-				}
-			}
-		} else {
-			for ( var i = 0; checkSet[i] != null; i++ ) {
-				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
-					results.push( set[i] );
-				}
-			}
-		}
-	} else {
-		makeArray( checkSet, results );
-	}
-
-	if ( extra ) {
-		Sizzle( extra, context, results, seed );
-
-		if ( sortOrder ) {
-			hasDuplicate = false;
-			results.sort(sortOrder);
-
-			if ( hasDuplicate ) {
-				for ( var i = 1; i < results.length; i++ ) {
-					if ( results[i] === results[i-1] ) {
-						results.splice(i--, 1);
-					}
-				}
-			}
-		}
-	}
-
-	return results;
-};
-
-Sizzle.matches = function(expr, set){
-	return Sizzle(expr, null, null, set);
-};
-
-Sizzle.find = function(expr, context, isXML){
-	var set, match;
-
-	if ( !expr ) {
-		return [];
-	}
-
-	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
-		var type = Expr.order[i], match;
-		
-		if ( (match = Expr.match[ type ].exec( expr )) ) {
-			var left = RegExp.leftContext;
-
-			if ( left.substr( left.length - 1 ) !== "\\" ) {
-				match[1] = (match[1] || "").replace(/\\/g, "");
-				set = Expr.find[ type ]( match, context, isXML );
-				if ( set != null ) {
-					expr = expr.replace( Expr.match[ type ], "" );
-					break;
-				}
-			}
-		}
-	}
-
-	if ( !set ) {
-		set = context.getElementsByTagName("*");
-	}
-
-	return {set: set, expr: expr};
-};
-
-Sizzle.filter = function(expr, set, inplace, not){
-	var old = expr, result = [], curLoop = set, match, anyFound,
-		isXMLFilter = set && set[0] && isXML(set[0]);
-
-	while ( expr && set.length ) {
-		for ( var type in Expr.filter ) {
-			if ( (match = Expr.match[ type ].exec( expr )) != null ) {
-				var filter = Expr.filter[ type ], found, item;
-				anyFound = false;
-
-				if ( curLoop == result ) {
-					result = [];
-				}
-
-				if ( Expr.preFilter[ type ] ) {
-					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
-
-					if ( !match ) {
-						anyFound = found = true;
-					} else if ( match === true ) {
-						continue;
-					}
-				}
-
-				if ( match ) {
-					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
-						if ( item ) {
-							found = filter( item, match, i, curLoop );
-							var pass = not ^ !!found;
-
-							if ( inplace && found != null ) {
-								if ( pass ) {
-									anyFound = true;
-								} else {
-									curLoop[i] = false;
-								}
-							} else if ( pass ) {
-								result.push( item );
-								anyFound = true;
-							}
-						}
-					}
-				}
-
-				if ( found !== undefined ) {
-					if ( !inplace ) {
-						curLoop = result;
-					}
-
-					expr = expr.replace( Expr.match[ type ], "" );
-
-					if ( !anyFound ) {
-						return [];
-					}
-
-					break;
-				}
-			}
-		}
-
-		// Improper expression
-		if ( expr == old ) {
-			if ( anyFound == null ) {
-				throw "Syntax error, unrecognized expression: " + expr;
-			} else {
-				break;
-			}
-		}
-
-		old = expr;
-	}
-
-	return curLoop;
-};
-
-var Expr = Sizzle.selectors = {
-	order: [ "ID", "NAME", "TAG" ],
-	match: {
-		ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
-		CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
-		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
-		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
-		TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
-		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
-		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
-		PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
-	},
-	attrMap: {
-		"class": "className",
-		"for": "htmlFor"
-	},
-	attrHandle: {
-		href: function(elem){
-			return elem.getAttribute("href");
-		}
-	},
-	relative: {
-		"+": function(checkSet, part, isXML){
-			var isPartStr = typeof part === "string",
-				isTag = isPartStr && !/\W/.test(part),
-				isPartStrNotTag = isPartStr && !isTag;
-
-			if ( isTag && !isXML ) {
-				part = part.toUpperCase();
-			}
-
-			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
-				if ( (elem = checkSet[i]) ) {
-					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
-
-					checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
-						elem || false :
-						elem === part;
-				}
-			}
-
-			if ( isPartStrNotTag ) {
-				Sizzle.filter( part, checkSet, true );
-			}
-		},
-		">": function(checkSet, part, isXML){
-			var isPartStr = typeof part === "string";
-
-			if ( isPartStr && !/\W/.test(part) ) {
-				part = isXML ? part : part.toUpperCase();
-
-				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-					var elem = checkSet[i];
-					if ( elem ) {
-						var parent = elem.parentNode;
-						checkSet[i] = parent.nodeName === part ? parent : false;
-					}
-				}
-			} else {
-				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-					var elem = checkSet[i];
-					if ( elem ) {
-						checkSet[i] = isPartStr ?
-							elem.parentNode :
-							elem.parentNode === part;
-					}
-				}
-
-				if ( isPartStr ) {
-					Sizzle.filter( part, checkSet, true );
-				}
-			}
-		},
-		"": function(checkSet, part, isXML){
-			var doneName = done++, checkFn = dirCheck;
-
-			if ( !part.match(/\W/) ) {
-				var nodeCheck = part = isXML ? part : part.toUpperCase();
-				checkFn = dirNodeCheck;
-			}
-
-			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
-		},
-		"~": function(checkSet, part, isXML){
-			var doneName = done++, checkFn = dirCheck;
-
-			if ( typeof part === "string" && !part.match(/\W/) ) {
-				var nodeCheck = part = isXML ? part : part.toUpperCase();
-				checkFn = dirNodeCheck;
-			}
-
-			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
-		}
-	},
-	find: {
-		ID: function(match, context, isXML){
-			if ( typeof context.getElementById !== "undefined" && !isXML ) {
-				var m = context.getElementById(match[1]);
-				return m ? [m] : [];
-			}
-		},
-		NAME: function(match, context, isXML){
-			if ( typeof context.getElementsByName !== "undefined" ) {
-				var ret = [], results = context.getElementsByName(match[1]);
-
-				for ( var i = 0, l = results.length; i < l; i++ ) {
-					if ( results[i].getAttribute("name") === match[1] ) {
-						ret.push( results[i] );
-					}
-				}
-
-				return ret.length === 0 ? null : ret;
-			}
-		},
-		TAG: function(match, context){
-			return context.getElementsByTagName(match[1]);
-		}
-	},
-	preFilter: {
-		CLASS: function(match, curLoop, inplace, result, not, isXML){
-			match = " " + match[1].replace(/\\/g, "") + " ";
-
-			if ( isXML ) {
-				return match;
-			}
-
-			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
-				if ( elem ) {
-					if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
-						if ( !inplace )
-							result.push( elem );
-					} else if ( inplace ) {
-						curLoop[i] = false;
-					}
-				}
-			}
-
-			return false;
-		},
-		ID: function(match){
-			return match[1].replace(/\\/g, "");
-		},
-		TAG: function(match, curLoop){
-			for ( var i = 0; curLoop[i] === false; i++ ){}
-			return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
-		},
-		CHILD: function(match){
-			if ( match[1] == "nth" ) {
-				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
-				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
-					match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
-					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
-
-				// calculate the numbers (first)n+(last) including if they are negative
-				match[2] = (test[1] + (test[2] || 1)) - 0;
-				match[3] = test[3] - 0;
-			}
-
-			// TODO: Move to normal caching system
-			match[0] = done++;
-
-			return match;
-		},
-		ATTR: function(match, curLoop, inplace, result, not, isXML){
-			var name = match[1].replace(/\\/g, "");
-			
-			if ( !isXML && Expr.attrMap[name] ) {
-				match[1] = Expr.attrMap[name];
-			}
-
-			if ( match[2] === "~=" ) {
-				match[4] = " " + match[4] + " ";
-			}
-
-			return match;
-		},
-		PSEUDO: function(match, curLoop, inplace, result, not){
-			if ( match[1] === "not" ) {
-				// If we're dealing with a complex expression, or a simple one
-				if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
-					match[3] = Sizzle(match[3], null, null, curLoop);
-				} else {
-					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
-					if ( !inplace ) {
-						result.push.apply( result, ret );
-					}
-					return false;
-				}
-			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
-				return true;
-			}
-			
-			return match;
-		},
-		POS: function(match){
-			match.unshift( true );
-			return match;
-		}
-	},
-	filters: {
-		enabled: function(elem){
-			return elem.disabled === false && elem.type !== "hidden";
-		},
-		disabled: function(elem){
-			return elem.disabled === true;
-		},
-		checked: function(elem){
-			return elem.checked === true;
-		},
-		selected: function(elem){
-			// Accessing this property makes selected-by-default
-			// options in Safari work properly
-			elem.parentNode.selectedIndex;
-			return elem.selected === true;
-		},
-		parent: function(elem){
-			return !!elem.firstChild;
-		},
-		empty: function(elem){
-			return !elem.firstChild;
-		},
-		has: function(elem, i, match){
-			return !!Sizzle( match[3], elem ).length;
-		},
-		header: function(elem){
-			return /h\d/i.test( elem.nodeName );
-		},
-		text: function(elem){
-			return "text" === elem.type;
-		},
-		radio: function(elem){
-			return "radio" === elem.type;
-		},
-		checkbox: function(elem){
-			return "checkbox" === elem.type;
-		},
-		file: function(elem){
-			return "file" === elem.type;
-		},
-		password: function(elem){
-			return "password" === elem.type;
-		},
-		submit: function(elem){
-			return "submit" === elem.type;
-		},
-		image: function(elem){
-			return "image" === elem.type;
-		},
-		reset: function(elem){
-			return "reset" === elem.type;
-		},
-		button: function(elem){
-			return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
-		},
-		input: function(elem){
-			return /input|select|textarea|button/i.test(elem.nodeName);
-		}
-	},
-	setFilters: {
-		first: function(elem, i){
-			return i === 0;
-		},
-		last: function(elem, i, match, array){
-			return i === array.length - 1;
-		},
-		even: function(elem, i){
-			return i % 2 === 0;
-		},
-		odd: function(elem, i){
-			return i % 2 === 1;
-		},
-		lt: function(elem, i, match){
-			return i < match[3] - 0;
-		},
-		gt: function(elem, i, match){
-			return i > match[3] - 0;
-		},
-		nth: function(elem, i, match){
-			return match[3] - 0 == i;
-		},
-		eq: function(elem, i, match){
-			return match[3] - 0 == i;
-		}
-	},
-	filter: {
-		PSEUDO: function(elem, match, i, array){
-			var name = match[1], filter = Expr.filters[ name ];
-
-			if ( filter ) {
-				return filter( elem, i, match, array );
-			} else if ( name === "contains" ) {
-				return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
-			} else if ( name === "not" ) {
-				var not = match[3];
-
-				for ( var i = 0, l = not.length; i < l; i++ ) {
-					if ( not[i] === elem ) {
-						return false;
-					}
-				}
-
-				return true;
-			}
-		},
-		CHILD: function(elem, match){
-			var type = match[1], node = elem;
-			switch (type) {
-				case 'only':
-				case 'first':
-					while (node = node.previousSibling)  {
-						if ( node.nodeType === 1 ) return false;
-					}
-					if ( type == 'first') return true;
-					node = elem;
-				case 'last':
-					while (node = node.nextSibling)  {
-						if ( node.nodeType === 1 ) return false;
-					}
-					return true;
-				case 'nth':
-					var first = match[2], last = match[3];
-
-					if ( first == 1 && last == 0 ) {
-						return true;
-					}
-					
-					var doneName = match[0],
-						parent = elem.parentNode;
-	
-					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
-						var count = 0;
-						for ( node = parent.firstChild; node; node = node.nextSibling ) {
-							if ( node.nodeType === 1 ) {
-								node.nodeIndex = ++count;
-							}
-						} 
-						parent.sizcache = doneName;
-					}
-					
-					var diff = elem.nodeIndex - last;
-					if ( first == 0 ) {
-						return diff == 0;
-					} else {
-						return ( diff % first == 0 && diff / first >= 0 );
-					}
-			}
-		},
-		ID: function(elem, match){
-			return elem.nodeType === 1 && elem.getAttribute("id") === match;
-		},
-		TAG: function(elem, match){
-			return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
-		},
-		CLASS: function(elem, match){
-			return (" " + (elem.className || elem.getAttribute("class")) + " ")
-				.indexOf( match ) > -1;
-		},
-		ATTR: function(elem, match){
-			var name = match[1],
-				result = Expr.attrHandle[ name ] ?
-					Expr.attrHandle[ name ]( elem ) :
-					elem[ name ] != null ?
-						elem[ name ] :
-						elem.getAttribute( name ),
-				value = result + "",
-				type = match[2],
-				check = match[4];
-
-			return result == null ?
-				type === "!=" :
-				type === "=" ?
-				value === check :
-				type === "*=" ?
-				value.indexOf(check) >= 0 :
-				type === "~=" ?
-				(" " + value + " ").indexOf(check) >= 0 :
-				!check ?
-				value && result !== false :
-				type === "!=" ?
-				value != check :
-				type === "^=" ?
-				value.indexOf(check) === 0 :
-				type === "$=" ?
-				value.substr(value.length - check.length) === check :
-				type === "|=" ?
-				value === check || value.substr(0, check.length + 1) === check + "-" :
-				false;
-		},
-		POS: function(elem, match, i, array){
-			var name = match[2], filter = Expr.setFilters[ name ];
-
-			if ( filter ) {
-				return filter( elem, i, match, array );
-			}
-		}
-	}
-};
-
-var origPOS = Expr.match.POS;
-
-for ( var type in Expr.match ) {
-	Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
-}
-
-var makeArray = function(array, results) {
-	array = Array.prototype.slice.call( array );
-
-	if ( results ) {
-		results.push.apply( results, array );
-		return results;
-	}
-	
-	return array;
-};
-
-// Perform a simple check to determine if the browser is capable of
-// converting a NodeList to an array using builtin methods.
-try {
-	Array.prototype.slice.call( document.documentElement.childNodes );
-
-// Provide a fallback method if it does not work
-} catch(e){
-	makeArray = function(array, results) {
-		var ret = results || [];
-
-		if ( toString.call(array) === "[object Array]" ) {
-			Array.prototype.push.apply( ret, array );
-		} else {
-			if ( typeof array.length === "number" ) {
-				for ( var i = 0, l = array.length; i < l; i++ ) {
-					ret.push( array[i] );
-				}
-			} else {
-				for ( var i = 0; array[i]; i++ ) {
-					ret.push( array[i] );
-				}
-			}
-		}
-
-		return ret;
-	};
-}
-
-var sortOrder;
-
-if ( document.documentElement.compareDocumentPosition ) {
-	sortOrder = function( a, b ) {
-		var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
-		if ( ret === 0 ) {
-			hasDuplicate = true;
-		}
-		return ret;
-	};
-} else if ( "sourceIndex" in document.documentElement ) {
-	sortOrder = function( a, b ) {
-		var ret = a.sourceIndex - b.sourceIndex;
-		if ( ret === 0 ) {
-			hasDuplicate = true;
-		}
-		return ret;
-	};
-} else if ( document.createRange ) {
-	sortOrder = function( a, b ) {
-		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
-		aRange.selectNode(a);
-		aRange.collapse(true);
-		bRange.selectNode(b);
-		bRange.collapse(true);
-		var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
-		if ( ret === 0 ) {
-			hasDuplicate = true;
-		}
-		return ret;
-	};
-}
-
-// Check to see if the browser returns elements by name when
-// querying by getElementById (and provide a workaround)
-(function(){
-	// We're going to inject a fake input element with a specified name
-	var form = document.createElement("form"),
-		id = "script" + (new Date).getTime();
-	form.innerHTML = "<input name='" + id + "'/>";
-
-	// Inject it into the root element, check its status, and remove it quickly
-	var root = document.documentElement;
-	root.insertBefore( form, root.firstChild );
-
-	// The workaround has to do additional checks after a getElementById
-	// Which slows things down for other browsers (hence the branching)
-	if ( !!document.getElementById( id ) ) {
-		Expr.find.ID = function(match, context, isXML){
-			if ( typeof context.getElementById !== "undefined" && !isXML ) {
-				var m = context.getElementById(match[1]);
-				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
-			}
-		};
-
-		Expr.filter.ID = function(elem, match){
-			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
-			return elem.nodeType === 1 && node && node.nodeValue === match;
-		};
-	}
-
-	root.removeChild( form );
-})();
-
-(function(){
-	// Check to see if the browser returns only elements
-	// when doing getElementsByTagName("*")
-
-	// Create a fake element
-	var div = document.createElement("div");
-	div.appendChild( document.createComment("") );
-
-	// Make sure no comments are found
-	if ( div.getElementsByTagName("*").length > 0 ) {
-		Expr.find.TAG = function(match, context){
-			var results = context.getElementsByTagName(match[1]);
-
-			// Filter out possible comments
-			if ( match[1] === "*" ) {
-				var tmp = [];
-
-				for ( var i = 0; results[i]; i++ ) {
-					if ( results[i].nodeType === 1 ) {
-						tmp.push( results[i] );
-					}
-				}
-
-				results = tmp;
-			}
-
-			return results;
-		};
-	}
-
-	// Check to see if an attribute returns normalized href attributes
-	div.innerHTML = "<a href='#'></a>";
-	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
-			div.firstChild.getAttribute("href") !== "#" ) {
-		Expr.attrHandle.href = function(elem){
-			return elem.getAttribute("href", 2);
-		};
-	}
-})();
-
-if ( document.querySelectorAll ) (function(){
-	var oldSizzle = Sizzle, div = document.createElement("div");
-	div.innerHTML = "<p class='TEST'></p>";
-
-	// Safari can't handle uppercase or unicode characters when
-	// in quirks mode.
-	if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
-		return;
-	}
-	
-	Sizzle = function(query, context, extra, seed){
-		context = context || document;
-
-		// Only use querySelectorAll on non-XML documents
-		// (ID selectors don't work in non-HTML documents)
-		if ( !seed && context.nodeType === 9 && !isXML(context) ) {
-			try {
-				return makeArray( context.querySelectorAll(query), extra );
-			} catch(e){}
-		}
-		
-		return oldSizzle(query, context, extra, seed);
-	};
-
-	Sizzle.find = oldSizzle.find;
-	Sizzle.filter = oldSizzle.filter;
-	Sizzle.selectors = oldSizzle.selectors;
-	Sizzle.matches = oldSizzle.matches;
-})();
-
-if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
-	var div = document.createElement("div");
-	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
-
-	// Opera can't find a second classname (in 9.6)
-	if ( div.getElementsByClassName("e").length === 0 )
-		return;
-
-	// Safari caches class attributes, doesn't catch changes (in 3.2)
-	div.lastChild.className = "e";
-
-	if ( div.getElementsByClassName("e").length === 1 )
-		return;
-
-	Expr.order.splice(1, 0, "CLASS");
-	Expr.find.CLASS = function(match, context, isXML) {
-		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
-			return context.getElementsByClassName(match[1]);
-		}
-	};
-})();
-
-function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
-	var sibDir = dir == "previousSibling" && !isXML;
-	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-		var elem = checkSet[i];
-		if ( elem ) {
-			if ( sibDir && elem.nodeType === 1 ){
-				elem.sizcache = doneName;
-				elem.sizset = i;
-			}
-			elem = elem[dir];
-			var match = false;
-
-			while ( elem ) {
-				if ( elem.sizcache === doneName ) {
-					match = checkSet[elem.sizset];
-					break;
-				}
-
-				if ( elem.nodeType === 1 && !isXML ){
-					elem.sizcache = doneName;
-					elem.sizset = i;
-				}
-
-				if ( elem.nodeName === cur ) {
-					match = elem;
-					break;
-				}
-
-				elem = elem[dir];
-			}
-
-			checkSet[i] = match;
-		}
-	}
-}
-
-function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
-	var sibDir = dir == "previousSibling" && !isXML;
-	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
-		var elem = checkSet[i];
-		if ( elem ) {
-			if ( sibDir && elem.nodeType === 1 ) {
-				elem.sizcache = doneName;
-				elem.sizset = i;
-			}
-			elem = elem[dir];
-			var match = false;
-
-			while ( elem ) {
-				if ( elem.sizcache === doneName ) {
-					match = checkSet[elem.sizset];
-					break;
-				}
-
-				if ( elem.nodeType === 1 ) {
-					if ( !isXML ) {
-						elem.sizcache = doneName;
-						elem.sizset = i;
-					}
-					if ( typeof cur !== "string" ) {
-						if ( elem === cur ) {
-							match = true;
-							break;
-						}
-
-					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
-						match = elem;
-						break;
-					}
-				}
-
-				elem = elem[dir];
-			}
-
-			checkSet[i] = match;
-		}
-	}
-}
-
-var contains = document.compareDocumentPosition ?  function(a, b){
-	return a.compareDocumentPosition(b) & 16;
-} : function(a, b){
-	return a !== b && (a.contains ? a.contains(b) : true);
-};
-
-var isXML = function(elem){
-	return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
-		!!elem.ownerDocument && isXML( elem.ownerDocument );
-};
-
-var posProcess = function(selector, context){
-	var tmpSet = [], later = "", match,
-		root = context.nodeType ? [context] : context;
-
-	// Position selectors must be done after the filter
-	// And so must :not(positional) so we move all PSEUDOs to the end
-	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
-		later += match[0];
-		selector = selector.replace( Expr.match.PSEUDO, "" );
-	}
-
-	selector = Expr.relative[selector] ? selector + "*" : selector;
-
-	for ( var i = 0, l = root.length; i < l; i++ ) {
-		Sizzle( selector, root[i], tmpSet );
-	}
-
-	return Sizzle.filter( later, tmpSet );
-};
-
-// EXPOSE
-jQuery.find = Sizzle;
-jQuery.filter = Sizzle.filter;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.filters;
-
-Sizzle.selectors.filters.hidden = function(elem){
-	return elem.offsetWidth === 0 || elem.offsetHeight === 0;
-};
-
-Sizzle.selectors.filters.visible = function(elem){
-	return elem.offsetWidth > 0 || elem.offsetHeight > 0;
-};
-
-Sizzle.selectors.filters.animated = function(elem){
-	return jQuery.grep(jQuery.timers, function(fn){
-		return elem === fn.elem;
-	}).length;
-};
-
-jQuery.multiFilter = function( expr, elems, not ) {
-	if ( not ) {
-		expr = ":not(" + expr + ")";
-	}
-
-	return Sizzle.matches(expr, elems);
-};
-
-jQuery.dir = function( elem, dir ){
-	var matched = [], cur = elem[dir];
-	while ( cur && cur != document ) {
-		if ( cur.nodeType == 1 )
-			matched.push( cur );
-		cur = cur[dir];
-	}
-	return matched;
-};
-
-jQuery.nth = function(cur, result, dir, elem){
-	result = result || 1;
-	var num = 0;
-
-	for ( ; cur; cur = cur[dir] )
-		if ( cur.nodeType == 1 && ++num == result )
-			break;
-
-	return cur;
-};
-
-jQuery.sibling = function(n, elem){
-	var r = [];
-
-	for ( ; n; n = n.nextSibling ) {
-		if ( n.nodeType == 1 && n != elem )
-			r.push( n );
-	}
-
-	return r;
-};
-
-return;
-
-window.Sizzle = Sizzle;
-
-})();
-/*
- * A number of helper functions used for managing events.
- * Many of the ideas behind this code originated from
- * Dean Edwards' addEvent library.
- */
-jQuery.event = {
-
-	// Bind an event to an element
-	// Original by Dean Edwards
-	add: function(elem, types, handler, data) {
-		if ( elem.nodeType == 3 || elem.nodeType == 8 )
-			return;
-
-		// For whatever reason, IE has trouble passing the window object
-		// around, causing it to be cloned in the process
-		if ( elem.setInterval && elem != window )
-			elem = window;
-
-		// Make sure that the function being executed has a unique ID
-		if ( !handler.guid )
-			handler.guid = this.guid++;
-
-		// if data is passed, bind to handler
-		if ( data !== undefined ) {
-			// Create temporary function pointer to original handler
-			var fn = handler;
-
-			// Create unique handler function, wrapped around original handler
-			handler = this.proxy( fn );
-
-			// Store data in unique handler
-			handler.data = data;
-		}
-
-		// Init the element's event structure
-		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
-			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
-				// Handle the second event of a trigger and when
-				// an event is called after a page has unloaded
-				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
-					jQuery.event.handle.apply(arguments.callee.elem, arguments) :
-					undefined;
-			});
-		// Add elem as a property of the handle function
-		// This is to prevent a memory leak with non-native
-		// event in IE.
-		handle.elem = elem;
-
-		// Handle multiple events separated by a space
-		// jQuery(...).bind("mouseover mouseout", fn);
-		jQuery.each(types.split(/\s+/), function(index, type) {
-			// Namespaced event handlers
-			var namespaces = type.split(".");
-			type = namespaces.shift();
-			handler.type = namespaces.slice().sort().join(".");
-
-			// Get the current list of functions bound to this event
-			var handlers = events[type];
-			
-			if ( jQuery.event.specialAll[type] )
-				jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
-
-			// Init the event handler queue
-			if (!handlers) {
-				handlers = events[type] = {};
-
-				// Check for a special event handler
-				// Only use addEventListener/attachEvent if the special
-				// events handler returns false
-				if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
-					// Bind the global event handler to the element
-					if (elem.addEventListener)
-						elem.addEventListener(type, handle, false);
-					else if (elem.attachEvent)
-						elem.attachEvent("on" + type, handle);
-				}
-			}
-
-			// Add the function to the element's handler list
-			handlers[handler.guid] = handler;
-
-			// Keep track of which events have been used, for global triggering
-			jQuery.event.global[type] = true;
-		});
-
-		// Nullify elem to prevent memory leaks in IE
-		elem = null;
-	},
-
-	guid: 1,
-	global: {},
-
-	// Detach an event or set of events from an element
-	remove: function(elem, types, handler) {
-		// don't do events on text and comment nodes
-		if ( elem.nodeType == 3 || elem.nodeType == 8 )
-			return;
-
-		var events = jQuery.data(elem, "events"), ret, index;
-
-		if ( events ) {
-			// Unbind all events for the element
-			if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
-				for ( var type in events )
-					this.remove( elem, type + (types || "") );
-			else {
-				// types is actually an event object here
-				if ( types.type ) {
-					handler = types.handler;
-					types = types.type;
-				}
-
-				// Handle multiple events seperated by a space
-				// jQuery(...).unbind("mouseover mouseout", fn);
-				jQuery.each(types.split(/\s+/), function(index, type){
-					// Namespaced event handlers
-					var namespaces = type.split(".");
-					type = namespaces.shift();
-					var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
-
-					if ( events[type] ) {
-						// remove the given handler for the given type
-						if ( handler )
-							delete events[type][handler.guid];
-
-						// remove all handlers for the given type
-						else
-							for ( var handle in events[type] )
-								// Handle the removal of namespaced events
-								if ( namespace.test(events[type][handle].type) )
-									delete events[type][handle];
-									
-						if ( jQuery.event.specialAll[type] )
-							jQuery.event.specialAll[type].teardown.call(elem, namespaces);
-
-						// remove generic event handler if no more handlers exist
-						for ( ret in events[type] ) break;
-						if ( !ret ) {
-							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
-								if (elem.removeEventListener)
-									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
-								else if (elem.detachEvent)
-									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
-							}
-							ret = null;
-							delete events[type];
-						}
-					}
-				});
-			}
-
-			// Remove the expando if it's no longer used
-			for ( ret in events ) break;
-			if ( !ret ) {
-				var handle = jQuery.data( elem, "handle" );
-				if ( handle ) handle.elem = null;
-				jQuery.removeData( elem, "events" );
-				jQuery.removeData( elem, "handle" );
-			}
-		}
-	},
-
-	// bubbling is internal
-	trigger: function( event, data, elem, bubbling ) {
-		// Event object or event type
-		var type = event.type || event;
-
-		if( !bubbling ){
-			event = typeof event === "object" ?
-				// jQuery.Event object
-				event[expando] ? event :
-				// Object literal
-				jQuery.extend( jQuery.Event(type), event ) :
-				// Just the event type (string)
-				jQuery.Event(type);
-
-			if ( type.indexOf("!") >= 0 ) {
-				event.type = type = type.slice(0, -1);
-				event.exclusive = true;
-			}
-
-			// Handle a global trigger
-			if ( !elem ) {
-				// Don't bubble custom events when global (to avoid too much overhead)
-				event.stopPropagation();
-				// Only trigger if we've ever bound an event for it
-				if ( this.global[type] )
-					jQuery.each( jQuery.cache, function(){
-						if ( this.events && this.events[type] )
-							jQuery.event.trigger( event, data, this.handle.elem );
-					});
-			}
-
-			// Handle triggering a single element
-
-			// don't do events on text and comment nodes
-			if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
-				return undefined;
-			
-			// Clean up in case it is reused
-			event.result = undefined;
-			event.target = elem;
-			
-			// Clone the incoming data, if any
-			data = jQuery.makeArray(data);
-			data.unshift( event );
-		}
-
-		event.currentTarget = elem;
-
-		// Trigger the event, it is assumed that "handle" is a function
-		var handle = jQuery.data(elem, "handle");
-		if ( handle )
-			handle.apply( elem, data );
-
-		// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
-		if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
-			event.result = false;
-
-		// Trigger the native events (except for clicks on links)
-		if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
-			this.triggered = true;
-			try {
-				elem[ type ]();
-			// prevent IE from throwing an error for some hidden elements
-			} catch (e) {}
-		}
-
-		this.triggered = false;
-
-		if ( !event.isPropagationStopped() ) {
-			var parent = elem.parentNode || elem.ownerDocument;
-			if ( parent )
-				jQuery.event.trigger(event, data, parent, true);
-		}
-	},
-
-	handle: function(event) {
-		// returned undefined or false
-		var all, handlers;
-
-		event = arguments[0] = jQuery.event.fix( event || window.event );
-		event.currentTarget = this;
-		
-		// Namespaced event handlers
-		var namespaces = event.type.split(".");
-		event.type = namespaces.shift();
-
-		// Cache this now, all = true means, any handler
-		all = !namespaces.length && !event.exclusive;
-		
-		var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
-
-		handlers = ( jQuery.data(this, "events") || {} )[event.type];
-
-		for ( var j in handlers ) {
-			var handler = handlers[j];
-
-			// Filter the functions by class
-			if ( all || namespace.test(handler.type) ) {
-				// Pass in a reference to the handler function itself
-				// So that we can later remove it
-				event.handler = handler;