tor-commits
Threads by month
- ----- 2025 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
January 2017
- 22 participants
- 1796 discussions

09 Jan '17
commit 9b3292904c7b1426d1a9d2e4b631ee2a287d7a1a
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Dec 14 20:36:23 2016 +0100
Update contents on Research page.
---
website/web/WEB-INF/research.jsp | 38 +++++++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/website/web/WEB-INF/research.jsp b/website/web/WEB-INF/research.jsp
index 2acff3d..901c3e1 100644
--- a/website/web/WEB-INF/research.jsp
+++ b/website/web/WEB-INF/research.jsp
@@ -30,9 +30,45 @@ of data, rather than just dogma or perspective."
<br>
<!-- Navigation end -->
-<h3>Research</h3>
+<h1>Research</h1>
<br>
+<p>Tor started out as a research project! We encourage research on all things
+Tor.</p>
+
+<p>Look around the papers section below for some ideas on what others have
+researched in the past. Contact <some general email list here, torproject?> if
+you want to discuss ideas.</p>
+
+<h2>Feel free to use our data for your research!</h2>
+
+<p>If you do, please cite https://metrics.torproject.org/ or the following <a
+href="http://freehaven.net/anonbib/#wecsr10measuring-tor">paper</a>:</p>
+
+<pre>
+@inproceedings{wecsr10measuring-tor,
+ title = {A Case Study on Measuring Statistical Data in the {T}or Anonymity Network},
+ author = {Karsten Loesing and Steven J. Murdoch and Roger Dingledine},
+ booktitle = {Proceedings of the Workshop on Ethics in Computer Security Research (WECSR 2010)},
+ year = {2010},
+ month = {January},
+ location = {Tenerife, Canary Islands, Spain},
+ publisher = {Springer},
+ series = {LNCS},
+}
+</pre>
+
+<p>Thank you for acknowledging this work through a citation.</p>
+
+<h2>Want to collect your own data for research?</h2>
+
+<p>Look at the <a href="tools.html">tools pages</a> for services that collect
+Tor-related data.</p>
+
+<h2>Research Papers</h2>
+
+<p>Here are some Tor-related papers. (...)</p>
+
</div>
</div>
<div class="bottom" id="bottom">
1
0
commit 46b10f20a015523c9fc777b05a28e051a27489fb
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Dec 14 20:29:39 2016 +0100
Update contents on Tools page.
---
website/etc/categories.json | 11 ++-
.../org/torproject/metrics/web/GraphServlet.java | 1 +
.../org/torproject/metrics/web/LinkServlet.java | 27 ++++++
.../org/torproject/metrics/web/TableServlet.java | 13 +++
website/web/WEB-INF/link.jsp | 32 +++++++-
website/web/WEB-INF/table.jsp | 4 +
website/web/WEB-INF/tools.jsp | 95 +++++++++++++++++++++-
7 files changed, 178 insertions(+), 5 deletions(-)
diff --git a/website/etc/categories.json b/website/etc/categories.json
index 103ac9d..9a10aea 100644
--- a/website/etc/categories.json
+++ b/website/etc/categories.json
@@ -12,7 +12,8 @@
"userstats-bridge-version",
"userstats-relay-table",
"userstats-censorship-events",
- "userstats-bridge-table"
+ "userstats-bridge-table",
+ "oxford-anonymous-internet"
]
},
{
@@ -24,7 +25,10 @@
"networksize",
"relayflags",
"versions",
- "platforms"
+ "platforms",
+ "uptimes",
+ "networkchurn",
+ "bubbles"
]
},
{
@@ -38,7 +42,8 @@
"advbwdist-perc",
"advbwdist-relay",
"bwhist-flags",
- "dirbytes"
+ "dirbytes",
+ "uncharted-data-flow"
]
},
{
diff --git a/website/src/org/torproject/metrics/web/GraphServlet.java b/website/src/org/torproject/metrics/web/GraphServlet.java
index 5e90499..917980b 100644
--- a/website/src/org/torproject/metrics/web/GraphServlet.java
+++ b/website/src/org/torproject/metrics/web/GraphServlet.java
@@ -135,6 +135,7 @@ public class GraphServlet extends MetricServlet {
return;
}
List<String[]> categories = new ArrayList<String[]>();
+ /* TODO Some of the following code should move to init(). */
for (Category category :
ContentProvider.getInstance().getCategoriesList()) {
if (category.getMetrics().isEmpty()
diff --git a/website/src/org/torproject/metrics/web/LinkServlet.java b/website/src/org/torproject/metrics/web/LinkServlet.java
index fc413f5..c8f4d46 100644
--- a/website/src/org/torproject/metrics/web/LinkServlet.java
+++ b/website/src/org/torproject/metrics/web/LinkServlet.java
@@ -4,6 +4,8 @@
package org.torproject.metrics.web;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -28,8 +30,33 @@ public class LinkServlet extends MetricServlet {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
+ List<String[]> categories = new ArrayList<String[]>();
+ /* TODO Some of the following code should move to init(). */
+ for (Category category :
+ ContentProvider.getInstance().getCategoriesList()) {
+ if (category.getMetrics().isEmpty()
+ || this.categories.get(requestedId).equals(category)) {
+ categories.add(new String[] { "", category.getHeader() });
+ } else {
+ categories.add(new String[] { category.getMetrics().get(0),
+ category.getHeader() });
+ }
+ }
+ request.setAttribute("categories", categories);
request.setAttribute("id", requestedId);
request.setAttribute("title", this.titles.get(requestedId));
+ if (this.categories.containsKey(requestedId)) {
+ Category category = this.categories.get(requestedId);
+ request.setAttribute("categoryHeader", category.getHeader());
+ request.setAttribute("categoryDescription", category.getDescription());
+ List<String[]> categoryTabs = new ArrayList<String[]>();
+ for (String metricId : category.getMetrics()) {
+ categoryTabs.add(new String[] {
+ this.titles.get(metricId),
+ requestedId.equals(metricId) ? null : metricId });
+ }
+ request.setAttribute("categoryTabs", categoryTabs);
+ }
request.setAttribute("description",
this.descriptions.get(requestedId));
request.setAttribute("data", this.data.get(requestedId));
diff --git a/website/src/org/torproject/metrics/web/TableServlet.java b/website/src/org/torproject/metrics/web/TableServlet.java
index 035c0be..a47a720 100644
--- a/website/src/org/torproject/metrics/web/TableServlet.java
+++ b/website/src/org/torproject/metrics/web/TableServlet.java
@@ -48,6 +48,19 @@ public class TableServlet extends MetricServlet {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
+ List<String[]> categories = new ArrayList<String[]>();
+ /* TODO Some of the following code should move to init(). */
+ for (Category category :
+ ContentProvider.getInstance().getCategoriesList()) {
+ if (category.getMetrics().isEmpty()
+ || this.categories.get(requestedId).equals(category)) {
+ categories.add(new String[] { "", category.getHeader() });
+ } else {
+ categories.add(new String[] { category.getMetrics().get(0),
+ category.getHeader() });
+ }
+ }
+ request.setAttribute("categories", categories);
request.setAttribute("id", requestedId);
request.setAttribute("title", this.titles.get(requestedId));
if (this.categories.containsKey(requestedId)) {
diff --git a/website/web/WEB-INF/link.jsp b/website/web/WEB-INF/link.jsp
index 08f7d7b..096fddb 100644
--- a/website/web/WEB-INF/link.jsp
+++ b/website/web/WEB-INF/link.jsp
@@ -12,8 +12,38 @@
<body>
<div class="center">
<div class="main-column">
+ <h2><a href="/"><img src="images/metrics-logo.png" width="153" height="200" alt="Metrics logo"><img src="images/metrics-wordmark.png" width="384" height="50" alt="Metrics wordmark"></a></h2>
+ <br>
+
+<p>"Tor metrics are the ammunition that lets Tor and other security
+advocates argue for a more private and secure Internet from a position
+of data, rather than just dogma or perspective."
+<i>- Bruce Schneier (June 1, 2016)</i></p>
+
+ <!-- Navigation start -->
+ Metrics |
+ <a href="about.html">About</a> |
+ <a href="news.html">News</a> |
+ <a href="sources.html">Sources</a> |
+ <a href="tools.html">Tools</a> |
+ <a href="research.html">Research</a>
+ <br>
+ <br>
+ <!-- Navigation end -->
+
+<c:forEach var="category" items="${categories}"><c:if test="${fn:length(category[0]) > 0}"><a href="${category[0]}.html"></c:if>${category[1]}<c:if test="${fn:length(category[0]) > 0}"></a></c:if> |
+</c:forEach>
+<br>
+
+<h2>${categoryHeader}</h2>
+
+<p>${categoryDescription}</p>
+
+<c:forEach var="tab" items="${categoryTabs}">
+<c:if test="${fn:length(tab[1]) > 0}"><a href="${tab[1]}.html"></c:if>${tab[0]}<c:if test="${fn:length(tab[1]) > 0}"></a></c:if> |
+</c:forEach>
+<br>
-<h2><a href="."><img src="images/metrics-wordmark-small.png" width="138" height="18" alt="Metrics wordmark"></a> — ${title}</h2>
<br>
${description}
diff --git a/website/web/WEB-INF/table.jsp b/website/web/WEB-INF/table.jsp
index eece114..1e867a8 100644
--- a/website/web/WEB-INF/table.jsp
+++ b/website/web/WEB-INF/table.jsp
@@ -31,6 +31,10 @@ of data, rather than just dogma or perspective."
<br>
<!-- Navigation end -->
+<c:forEach var="category" items="${categories}"><c:if test="${fn:length(category[0]) > 0}"><a href="${category[0]}.html"></c:if>${category[1]}<c:if test="${fn:length(category[0]) > 0}"></a></c:if> |
+</c:forEach>
+<br>
+
<h2>${categoryHeader}</h2>
<p>${categoryDescription}</p>
diff --git a/website/web/WEB-INF/tools.jsp b/website/web/WEB-INF/tools.jsp
index d935989..c1a2512 100644
--- a/website/web/WEB-INF/tools.jsp
+++ b/website/web/WEB-INF/tools.jsp
@@ -31,9 +31,102 @@ of data, rather than just dogma or perspective."
<br>
<!-- Navigation end -->
-<h3>Tools</h3>
+<h1>Tools</h1>
<br>
+<p>We list some tools that you can use to collect data about Tor. We don't use
+all of the tools listed here. We use CollecTor to collect (relay data, bridge
+data, etc), OONI to collect (data, data, data), and Onionoo to collect (data,
+data, data).</p>
+
+<p>With these other tools, you can measure different things about Tor that we
+currently do not! We encourage you to do so if you are curious, want check up on
+your relays, or conduct some research.</p>
+
+<h2>Our sources</h2>
+
+<ul>
+<li><a href="https://collector.torproject.org/">CollecTor</a> collects data from
+various nodes and services in the public Tor network.</li>
+<li><a href="https://ooni.torproject.org/">OONI</a>, detects censorship,
+surveillance and traffic manipulation on the internet.</li>
+<li><a href="https://onionoo.torproject.org/">Onionoo</a> provides current and
+past data on relays and bridges to other services.</li>
+</ul>
+
+<h2>Others</h2>
+
+<ul>
+<li><a href="https://gitweb.torproject.org/user/phw/exitmap.git">Exitmap</a> is
+a fast and extensible scanner for Tor exit relays.</li>
+<li><a href="https://github.com/robgjansen/onionperf">OnionPerf</a> measures the
+performance of onion services.</li>
+<li><a href="https://gitweb.torproject.org/torperf.git">Torperf</a> measures Tor
+performance with a set of utilities and Python scripts.</li>
+<li><a href="https://www.torproject.org/projects/tordnsel.html.en">TorDNSEL</a>
+publishes lists of IP addresses of multi-homed Tor exits.</li>
+<li><a
+href="https://gitweb.torproject.org/user/phw/sybilhunter.git/">Sybilhunter</a>
+attempts to detect Sybil attacks on the Tor network.</li>
+<li><a href="https://exonerator.torproject.org/">ExoneraTor</a> tells you if an
+IP was used by a Tor relay on a given date.</li>
+<li><a href="https://torps.github.io/">TorPS</a> simulates changes to Tor's path
+selection algorithm using archived data.</li>
+<li><a
+href="https://play.google.com/store/apps/details?id=com.networksaremadeofstring.a…">AnOnionooid</a>
+is an Android app that helps find and explore Tor relays and bridges.</li>
+<li><a href="https://atlas.torproject.org/">Atlas</a> displays data about single
+relays and bridges in the Tor network.</li>
+<li><a href="https://compass.torproject.org/">Compass</a> groups current relays in
+different ways to measure Tor's network diversity.</li>
+<li><a href="https://oniontip.com/">OnionTip</a> distributes bitcoin donations
+to relays that can receive them.</li>
+<li><a href="https://onionview.codeplex.com/">OnionView</a> plots the location
+of active Tor nodes on an interactive map of the world.</li>
+<li><a href="https://consensus-health.torproject.org/">Consensus Health</a>
+displays information about the current directory consensus and votes.</li>
+<li><a
+href="https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-consensus-health">Consensus
+Issues</a> emails directory authority operators about consensus problems.</li>
+<li><a href="https://onionview.codeplex.com/">Check</a> uses<a
+href="https://www.torproject.org/projects/tordnsel.html.en">TorDNSEL</a> data to
+tell users whether they are using Tor or not.</li>
+<li><a href="https://shadow.github.io/">Shadow</a> uses archived Tor directory
+data to generate realistic network topologies.</li>
+<li><a href="http://lists.infolabe.net/lists/listinfo/infolabe-anomalies">OII's
+anomaly detection system</a> ranks countries by how anomalous their Tor usage
+is.</li>
+<li>Tor's <a
+href="https://gitweb.torproject.org/tor.git/tree/scripts/maint/updateFallbackDirs…">fallback
+directories script</a> generates a list of stable directories.</li>
+<li><a href="https://github.com/duk3luk3/onion-py">OnionPy</a> provides memcached support to cache queried data.</li>
+</ul>
+
+<h2>Things we took out for now</h2>
+
+<ul>
+<li><a href="http://tor2web.org/">Tor2web</a> is a web proxy for Tor Hidden
+Services.</li>
+<li><a href="https://tor-explorer-10kapart2016.azurewebsites.net/">Tor
+Explorer</a> displays data on each individual Tor node.</li>
+<li><a href="https://nos-oignons.net/Services/index.en.html">Nos oignons</a>
+visualizes bandwidth histories of their relays.</li>
+<li><a href="https://github.com/kloesing/challenger">challenger</a> aggregates
+data from relays participating in EFF's 2014 Tor Challenge.</li>
+<li>A <a href="https://duckduckgo.com/">DuckDuckGo</a> search with "tor node"
+keywords displays Tor node details.</li>
+<li><a
+href="https://metrics.torproject.org/uncharted-data-flow.html">metrics-lib</a>
+is a Java library to fetch and parse Tor descriptors.</li>
+<li><a href="https://stem.torproject.org/">Stem</a> is a Python library that
+parses Tor descriptors.</li>
+<li><a href="https://github.com/meejah/txtorcon">Txtorcon</a> is an asynchronous
+Tor controller library written in Twisted Python.</li>
+<li><a href="https://github.com/NullHypothesis/zoossh">Zoossh</a> is a parser written in Go for Tor-specific data formats.</li>
+<li><a href="https://savannah.nongnu.org/projects/koninoo/">koninoo</a> is a
+simple Java command line interface for querying Onionoo data.</li>
+</ul>
+
</div>
</div>
<div class="bottom" id="bottom">
1
0
commit 08d8e8ee84dec03dd9e541e4de20a8eeb3ee4ea2
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Tue Dec 20 15:36:25 2016 +0100
Include images.
---
website/web/images/ajax-loader.gif | Bin 0 -> 3208 bytes
website/web/images/android-icon.png | Bin 0 -> 21630 bytes
website/web/images/apple-touch-icon-152x152.png | Bin 0 -> 15346 bytes
website/web/images/largetile.png | Bin 0 -> 37140 bytes
website/web/images/mediumtile.png | Bin 0 -> 15037 bytes
website/web/images/metrics-logo-large.png | Bin 0 -> 119786 bytes
website/web/images/metrics-wordmark-white.png | Bin 0 -> 12343 bytes
website/web/images/smalltile.png | Bin 0 -> 4979 bytes
website/web/images/widetile.png | Bin 0 -> 25074 bytes
9 files changed, 0 insertions(+), 0 deletions(-)
diff --git a/website/web/images/ajax-loader.gif b/website/web/images/ajax-loader.gif
new file mode 100644
index 0000000..3288d10
Binary files /dev/null and b/website/web/images/ajax-loader.gif differ
diff --git a/website/web/images/android-icon.png b/website/web/images/android-icon.png
new file mode 100644
index 0000000..9ac8ee6
Binary files /dev/null and b/website/web/images/android-icon.png differ
diff --git a/website/web/images/apple-touch-icon-152x152.png b/website/web/images/apple-touch-icon-152x152.png
new file mode 100644
index 0000000..e705c7f
Binary files /dev/null and b/website/web/images/apple-touch-icon-152x152.png differ
diff --git a/website/web/images/largetile.png b/website/web/images/largetile.png
new file mode 100644
index 0000000..3bbc32b
Binary files /dev/null and b/website/web/images/largetile.png differ
diff --git a/website/web/images/mediumtile.png b/website/web/images/mediumtile.png
new file mode 100644
index 0000000..ab60681
Binary files /dev/null and b/website/web/images/mediumtile.png differ
diff --git a/website/web/images/metrics-logo-large.png b/website/web/images/metrics-logo-large.png
new file mode 100644
index 0000000..24001c6
Binary files /dev/null and b/website/web/images/metrics-logo-large.png differ
diff --git a/website/web/images/metrics-wordmark-white.png b/website/web/images/metrics-wordmark-white.png
new file mode 100644
index 0000000..f5d98f2
Binary files /dev/null and b/website/web/images/metrics-wordmark-white.png differ
diff --git a/website/web/images/smalltile.png b/website/web/images/smalltile.png
new file mode 100644
index 0000000..d8b8adc
Binary files /dev/null and b/website/web/images/smalltile.png differ
diff --git a/website/web/images/widetile.png b/website/web/images/widetile.png
new file mode 100644
index 0000000..f4d644b
Binary files /dev/null and b/website/web/images/widetile.png differ
1
0

[metrics-web/master] Combine data pages on single new page with sections.
by karsten@torproject.org 09 Jan '17
by karsten@torproject.org 09 Jan '17
09 Jan '17
commit 223528c2550224bc5be904d48decc962443053a4
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Dec 21 10:06:23 2016 +0100
Combine data pages on single new page with sections.
---
website/etc/metrics.json | 145 ------
website/etc/web.xml | 30 +-
.../org/torproject/metrics/web/DataServlet.java | 43 --
.../org/torproject/metrics/web/MetricServlet.java | 11 -
.../org/torproject/metrics/web/StatsServlet.java | 31 ++
website/web/WEB-INF/data.jsp | 53 ---
website/web/WEB-INF/stats.jsp | 490 +++++++++++++++++++++
7 files changed, 532 insertions(+), 271 deletions(-)
diff --git a/website/etc/metrics.json b/website/etc/metrics.json
index 6f26a86..2173db8 100644
--- a/website/etc/metrics.json
+++ b/website/etc/metrics.json
@@ -57,23 +57,6 @@
]
},
{
- "id": "servers-data",
- "title": "Number of relays and bridges",
- "type": "Data",
- "description": "<p>The following data file contains the number of running <a href=\"about.html#relay\">relays</a> and <a href=\"about.html#bridge\">bridges</a> in the network. Statistics include subsets of relays or bridges by <a href=\"about.html#relay-flag\">relay flag</a> (relays only), country code (relays only, and only until February 2013), tor software version (relays only), operating system (relays only), and by whether or not they are running in the EC2 cloud (bridges only). The data file contains daily (mean) averages of relay and bridge numbers.</p>",
- "data_file": "stats/servers.csv",
- "data_column_spec": [
- "<b>date:</b> UTC date (YYYY-MM-DD) when relays or bridges have been listed as running.",
- "<b>flag:</b> Relay flag assigned by the directory authorities. Examples are <b>\"Exit\"</b>, <b>\"Guard\"</b>, <b>\"Fast\"</b>, <b>\"Stable\"</b>, and <b>\"HSDir\"</b>. Relays can have none, some, or all these relay flags assigned. Relays that don't have the <b>\"Running\"</b> flag are not included in these statistics regardless of their other flags. If this column contains the empty string, all running relays are included, regardless of assigned flags. There are no statistics on the number of bridges by relay flag.",
- "<b>country:</b> Two-letter lower-case country code as found in a GeoIP database by resolving the relay's first onion-routing IP address, or <b>\"??\"</b> if an IP addresses could not be resolved. If this column contains the empty string, all running relays are included, regardless of their resolved country code. Statistics on relays by country code are only available until January 31, 2013. There are no statistics on the number of bridges by country code.",
- "<b>version:</b> First three dotted numbers of the Tor software version as reported by the relay. An example is <b>\"0.2.5\"</b>. If this column contains the empty string, all running relays are included, regardless of the Tor software version they run. There are no statistics on the number of bridges by Tor software version.",
- "<b>platform:</b> Operating system as reported by the relay. Examples are <b>\"Linux\"</b>, <b>\"Darwin\"</b> (Mac OS X), <b>\"BSD\"</b>, <b>\"Windows\"</b>, and <b>\"Other\"</b>. If this column contains the empty string, all running relays are included, regardless of the operating system they run on. There are no statistics on the number of bridges by operating system.",
- "<b>ec2bridge:</b> Whether bridges are running in the EC2 cloud or not. More precisely, bridges in the EC2 cloud running an image provided by Tor by default set their nickname to <b>\"ec2bridger\"</b> plus 8 random hex characters. This column either contains <b>\"t\"</b> for bridges matching this naming scheme, or the empty string for all bridges regardless of their nickname. There are no statistics on the number of relays running in the EC2 cloud.",
- "<b>relays:</b> The average number of relays matching the criteria in the previous columns. If the values in previous columns are specific to bridges only, this column contains the empty string.",
- "<b>bridges:</b> The average number of bridges matching the criteria in the previous columns. If the values in previous columns are specific to relays only, this column contains the empty string."
- ]
- },
- {
"id": "bandwidth",
"title": "Total relay bandwidth in the network",
"type": "Graph",
@@ -160,37 +143,6 @@
]
},
{
- "id": "bandwidth-data",
- "title": "Bandwidth provided and consumed by relays",
- "type": "Data",
- "description": "<p>The following data file contains statistics on <a href=\"about.html#advertised-bandwidth\">advertised</a> and <a href=\"about.html#bandwidth-history\">consumed bandwidth</a> of <a href=\"about.html#relay\">relays</a> in the network. Statistics on advertised bandwidth include any kind of traffic handled by a relay, whereas statistics on consumed bandwidth are available either for all traffic combined, or specifically for directory traffic. Some of the statistics are available for subsets of relays that have the \"Exit\" and/or the \"Guard\" <a href=\"about.html#relay-flag\">flag</a>. The data file contains daily (mean) averages of bandwidth numbers.</p>",
- "data_file": "stats/bandwidth.csv",
- "data_column_spec": [
- "<b>date:</b> UTC date (YYYY-MM-DD) that relays reported bandwidth data for.",
- "<b>isexit:</b> Whether relays included in this line have the <b>\"Exit\"</b> relay flag or not, which can be <b>\"t\"</b> or <b>\"f\"</b>. If this column contains the empty string, bandwidth data from all running relays are included, regardless of assigned relay flags.",
- "<b>isguard:</b> Whether relays included in this line have the <b>\"Guard\"</b> relay flag or not, which can be <b>\"t\"</b> or <b>\"f\"</b>. If this column contains the empty string, bandwidth data from all running relays are included, regardless of assigned relay flags.",
- "<b>advbw:</b> Total advertised bandwidth in bytes per second that relays are capable to provide.",
- "<b>bwread:</b> Total bandwidth in bytes per second that relays have read. This metric includes any kind of traffic.",
- "<b>bwwrite:</b> Similar to <b>bwread</b>, but for traffic written by relays.",
- "<b>dirread:</b> Bandwidth in bytes per second that relays have read when serving directory data. Not all relays report how many bytes they read when serving directory data which is why this value is an estimate from the available data. This metric is not available for subsets of relays with certain relay flags, so that this column will contain the empty string if either <b>isexit</b> or <b>isguard</b> is non-empty.",
- "<b>dirwrite:</b> Similar to <b>dirread</b>, but for traffic written by relays when serving directory data."
- ]
- },
- {
- "id": "advbwdist-data",
- "title": "Advertised bandwidth distribution and n-th fastest relays",
- "type": "Data",
- "description": "<p>The following data file contains statistics on the distribution of <a href=\"about.html#advertised-bandwidth\">advertised bandwidth</a> of relays in the network. These statistics include advertised bandwidth percentiles and advertised bandwidth values of the n-th fastest relays. All values are obtained from advertised bandwidths of running relays in a <a href=\"about.html#consensus\">network status consensus</a>. The data file contains daily (median) averages of percentiles and n-th largest values.</p>",
- "data_file": "stats/advbwdist.csv",
- "data_column_spec": [
- "<b>date:</b> UTC date (YYYY-MM-DD) when relays have been listed as running.",
- "<b>isexit:</b> Whether relays included in this line have the <b>\"Exit\"</b> relay flag, which would be indicated as <b>\"t\"</b>. If this column contains the empty string, advertised bandwidths from all running relays are included, regardless of assigned relay flags.",
- "<b>relay:</b> Position of the relay in an ordered list of all advertised bandwidths, starting at 1 for the fastest relay in the network. May be the empty string if this line contains advertised bandwidth by percentile.",
- "<b>percentile:</b> Advertised bandwidth percentile given in this line. May be the empty string if this line contains advertised bandwidth by fastest relays.",
- "<b>advbw:</b> Advertised bandwidth in B/s."
- ]
- },
- {
"id": "bubbles",
"title": "Network bubble graphs",
"type": "Graph"
@@ -346,41 +298,6 @@
"description": "<p>The Oxford Internet Institute made a cartogram visualization of Tor users as compared to the overall Internet population. They used the average number of Tor <a href=\"about.html#client\">users</a> per country from August 2012 to August 2013 and put it in relation to total Internet users per country. More details and conclusions can be found on the <a href=\"http://geography.oii.ox.ac.uk/?page=tor\">Information Geographies website at the Oxford Internet Institute</a>.</p><p><a href=\"http://geography.oii.ox.ac.uk/?page=tor\"><img src=\"images/oxford-anonymous-internet.png\" alt=\"The anonymous Internet\"></a></p>"
},
{
- "id": "clients-data",
- "title": "Estimated number of clients in the Tor network",
- "type": "Data",
- "description": "<p>The following data file contains estimates on the number of <a href=\"about.html#client\">clients</a> in the network. These numbers are derived from directory requests counted on <a href=\"about.html#directory-authority\">directory authorities</a>, <a href=\"about.html#directory-mirror\">directory mirrors</a>, and <a href=\"about.html#bridge\">bridges</a>. Statistics are available for clients connecting directly relays and clients connecting via bridges. There are statistics available by country (for both directly-connecting clients and clients connecting via bridges), by transport protocol (only for clients connecting via bridges), and by IP version (only for clients connecting via bridges). Statistics also include predicted client numbers from past observations, which can be used to detect censorship events.</p>",
- "data_file": "stats/clients.csv",
- "data_column_spec": [
- "<b>date:</b> UTC date (YYYY-MM-DD) for which client numbers are estimated.",
- "<b>node:</b> The node type to which clients connect first, which can be either <b>\"relay\"</b> or <b>\"bridge\"</b>.",
- "<b>country:</b> Two-letter lower-case country code as found in a GeoIP database by resolving clients' IP addresses, or <b>\"??\"</b> if client IP addresses could not be resolved. If this column contains the empty string, all clients are included, regardless of their country code.",
- "<b>transport:</b> Transport name used by clients to connect to the Tor network using bridges. Examples are <b>\"obfs2\"</b>, <b>\"obfs3\"</b>, <b>\"websocket\"</b>, or <b>\"<OR>\"</b> (original onion routing protocol). If this column contains the empty string, all clients are included, regardless of their transport. There are no statistics on the number of clients by transport that connect to the Tor network via relays.",
- "<b>version:</b> IP version used by clients to connect to the Tor network using bridges. Examples are <b>\"v4\"</b> and <b>\"v6\"</b>. If this column contains the empty string, all clients are included, regardless of their IP version. There are no statistics on the number of clients by IP version that connect directly to the Tor network using relays.",
- "<b>lower:</b> Lower number of expected clients under the assumption that there has been no censorship event. If this column contains the empty string, there are no expectations on the number of clients.",
- "<b>upper:</b> Upper number of expected clients under the assumption that there has been no release of censorship. If this column contains the empty string, there are no expectations on the number of clients.",
- "<b>clients:</b> Estimated number of clients.",
- "<b>frac:</b> Fraction of relays or bridges in percent that the estimate is based on. The higher this value, the more reliable is the estimate. Values above 50 can be considered reliable enough for most purposes, lower values should be handled with more care."
- ]
- },
- {
- "id": "userstats-combined-data",
- "title": "Estimated number of clients by country and transport",
- "type": "Data",
- "description": "<p>The following data file contains additional statistics on the number of <a href=\"about.html#client\">clients</a> in the network. This data file is related to the <a href=\"clients-data.html\">clients-data file</a> that contains estimates on the number of clients by country and by transport protocol. This data file enhances these statistics by containing estimates of clients connecting to <a href=\"about.html#bridge\">bridges</a> by a given country and using a given <a href=\"about.html#pluggable-transport\">transport protocol</a>. Even though bridges don't report a combination of clients by country and transport, it's possible to derive lower and upper bounds from existing usage statistics.</p>",
- "data_file": "stats/userstats-combined.csv",
- "data_column_spec": [
- "<b>date:</b> UTC date (YYYY-MM-DD) for which client numbers are estimated.",
- "<b>node:</b> The node type to which clients connect first, which is always <b>\"bridge\"</b>, because relays don't report responses by transport.",
- "<b>country:</b> Two-letter lower-case country code as found in a GeoIP database by resolving clients' IP addresses, or <b>\"??\"</b> if client IP addresses could not be resolved.",
- "<b>transport:</b> Transport name used by clients to connect to the Tor network using bridges. Examples are <b>\"obfs2\"</b>, <b>\"obfs3\"</b>, <b>\"websocket\"</b>, or <b>\"<OR>\"</b> (original onion routing protocol).",
- "<b>version:</b> IP version used by clients to connect to the Tor network using bridges. This column always contains the empty string and is only included for compatibility reasons.",
- "<b>frac:</b> Fraction of relays or bridges in percent that the estimate is based on. The higher this value, the more reliable is the estimate. Values above 50 can be considered reliable enough for most purposes, lower values should be handled with more care.",
- "<b>low:</b> Lower bound of users by country and transport, calculated as sum over all bridges having reports for the given country and transport, that is, the sum of <b>M(b)</b>, where for each bridge <b>b</b> define <b>M(b) := max(0, C(b) + T(b) - S(b))</b> using the following definitions: <b>C(b)</b> is the number of users from a given country reported by <b>b</b>; <b>T(b)</b> is the number of users using a given transport reported by <b>b</b>; and <b>S(b)</b> is the total numbers of users reported by <b>b</b>. Reasoning: If the sum <b>C(b) + T(b)</b> exceeds the total number of users from all countries and transports <b>S(b)</b>, there must be users from that country and transport. And if that is not the case, <b>0</b> is the lower limit.",
- "<b>high:</b> Upper bound of users by country and transport, calculated as sum over all bridges having reports for the given country and transport, that is, the sum of <b>m(b)</b>, where for each bridge <b>b</b> define <b>m(b):=min(C(b), T(b))</b> where we use the definitions from <b>low</b> (above). Reasoning: there cannot be more users by country and transport than there are users by either of the two numbers."
- ]
- },
- {
"id": "torperf",
"title": "Time to download files over Tor",
"type": "Graph",
@@ -427,37 +344,6 @@
]
},
{
- "id": "torperf-data",
- "title": "Performance of downloading static files over Tor",
- "type": "Data",
- "description": "<p>The following data file contains aggregate statistics on performance when downloading static files of different sizes over Tor. These statistics are generated by the <a href=\"https://gitweb.torproject.org/torperf.git\">Torperf</a> tool, which periodically fetches static files over Tor and records several timestamps in the process. The data file contains daily medians and quartiles as well as total numbers of requests, timeouts, and failures. Raw Torperf measurement data are available on the <a href=\"https://collector.torproject.org/formats.html#torperf\">CollecTor</a> website.</p>",
- "data_file": "stats/torperf.csv",
- "data_column_spec": [
- "<b>date:</b> UTC date (YYYY-MM-DD) when download performance was measured.",
- "<b>size:</b> Size of the downloaded file in bytes.",
- "<b>source:</b> Name of the Torperf service performing measurements. If this column contains the empty string, all measurements are included, regardless of which Torperf service performed them. Examples are <b>\"moria\"</b>, <b>\"siv\"</b>, and <b>\"torperf\"</b>.",
- "<b>q1:</b> First quartile of time until receiving the last byte in milliseconds.",
- "<b>md:</b> Median of time until receiving the last byte in milliseconds.",
- "<b>q3:</b> Third quartile of time until receiving the last byte in milliseconds.",
- "<b>timeouts:</b> Number of timeouts that occurred when attempting to download the static file over Tor.",
- "<b>failures:</b> Number of failures that occurred when attempting to download the static file over Tor.",
- "<b>requests:</b> Total number of requests made to download the static file over Tor."
- ]
- },
- {
- "id": "connbidirect2-data",
- "title": "Fraction of connections used uni-/bidirectionally",
- "type": "Data",
- "description": "<p>The following data file contains statistics on the fraction of direct connections between a <a href=\"about.html#relay\">relay</a> and other nodes in the network that are used uni- or bidirectionally. Every 10 seconds, relays determine for every direct connection whether they read and wrote less than a threshold of 20 KiB. Connections below this threshold are excluded from the statistics file. For the remaining connections, relays determine whether they read/wrote at least 10 times as many bytes as they wrote/read. If so, they classify a connection as \"mostly reading\" or \"mostly writing\", respectively. All other connections are classified as \"both reading and writing\". After classifying connections, read and write counters are reset for the next 10-second interval. The data file contains daily medians and quartiles of reported fractions.</p>",
- "data_file": "stats/connbidirect2.csv",
- "data_column_spec": [
- "<b>date:</b> UTC date (YYYY-MM-DD) for which statistics on uni-/bidirectional connection usage were reported.",
- "<b>direction:</b> Direction of reported fraction, which can be <b>\"read\"</b>, <b>\"write\"</b>, or <b>\"both\"</b> for connections classified as \"mostly reading\", \"mostly writing\", or \"both reading as writing\". Connections below the threshold have been removed from this statistics file entirely.",
- "<b>quantile:</b> Quantile of the reported fraction when considering all statistics reported for this date. Examples are <b>\"0.5\"</b> for the median and <b>\"0.25\"</b> and <b>\"0.75\"</b> for the lower and upper quartile.",
- "<b>fraction:</b> Fraction of connections in percent for the given date, direction, and quantile. For each daily statistic reported by a relay, fractions for the three directions \"read\", \"write\", and \"both\" sum up to exactly 100."
- ]
- },
- {
"id": "hidserv-dir-onions-seen",
"title": "Unique .onion addresses",
"type": "Graph",
@@ -500,43 +386,12 @@
]
},
{
- "id": "hidserv-data",
- "title": "Hidden-service statistics",
- "type": "Data",
- "description": "<p>The following data file contains <a href=\"about.html#hidden-service\">hidden-service</a> statistics gathered by a small subset of <a href=\"about.html#relay\">relays</a> and extrapolated to network totals. Statistics include the amount of hidden-service traffic and the number of hidden-service addresses in the network per day. For more details on the extrapolation algorithm, see <a href=\"https://blog.torproject.org/blog/some-statistics-about-onions\">this blog post</a> and <a href=\"https://research.torproject.org/techreports/extrapolating-hidserv-stats-201…">this technical report</a>.</p>",
- "data_file": "stats/hidserv.csv",
- "data_column_spec": [
- "<b>date:</b> UTC date (YYYY-MM-DD) when relays or bridges have been listed as running.",
- "<b>type:</b> Type of hidden-service statistic reported by relays and extrapolated to network totals. Examples include <b>\"rend-relayed-cells\"</b> for the number of cells on rendezvous circuits observed by rendezvous points and <b>\"dir-onions-seen\"</b> for the number of unique .onion addresses observed by hidden-service directories.",
- "<b>wmean:</b> Weighted mean of extrapolated network totals.",
- "<b>wmedian:</b> Weighted median of extrapolated network totals.",
- "<b>wiqm:</b> Weighted interquartile mean of extrapolated network totals.",
- "<b>frac:</b> Total network fraction of reported statistics.",
- "<b>stats:</b> Number of reported statistics with non-zero computed network fraction."
- ]
- },
- {
"id": "uncharted-data-flow",
"title": "Data flow in the Tor network",
"type": "Link",
"description": "<p>Uncharted made a visualization of data flow in the Tor network where they place each <a href=\"about.html#relay\">relay</a> on a world map and illustrate traffic exchanged between relays as animated dots. More details can be found on the <a href=\"https://torflow.uncharted.software/\">Uncharted website</a>.</p><p><a href=\"https://torflow.uncharted.software/\"><img src=\"images/uncharted-data-flow.png\" alt=\"Data flow in the Tor network\"></a></p>"
},
{
- "id": "disagreement-data",
- "title": "Disagreement among the directory authorities (deprecated)",
- "type": "Data",
- "description": "<p><font color=\"red\">As of September 29, 2016, the linked data file is not updated anymore. This page and the linked data file will be removed in the future.</font></p><p>The following data file contains statistics about agreement or disagreement among the <a href=\"about.html#directory-authority\">directory authorities</a>. Once per hour the directory authorities exchange votes with their view of the <a href=\"about.html#relay\">relays</a> in the network including attributes like <a href=\"about.html#relay-flag\">relay flags</a> or bandwidth measurements. This data file includes counts of relays by number of directory authorities assigning them a given attribute.</p>",
- "data_file": "stats/disagreement.csv",
- "data_column_spec": [
- "<b>validafter:</b> UTC timestamp (YYYY-MM-DD HH:MM:SS) after which votes became valid, which may be used as the vote publication time.",
- "<b>attribute:</b> Attribute assigned to relays by directory authorities, which includes relay flags like <b>\"Exit\"</b> or <b>\"BadExit\"</b> as well as <b>\"Listed\"</b> for relays being listed in a vote and <b>\"Measured\"</b> for relays being measured by the bandwidth authorities.",
- "<b>votes:</b> Number of votes assigning the attribute to relays.",
- "<b>required:</b> Required number of votes for the attribute to be assigned to a relay for being included in the consensus.",
- "<b>max:</b> Maximum number of possible votes assigning the attribute to relays.",
- "<b>relays:</b> Number of relays that got the given number of votes for the given attribute."
- ]
- },
- {
"id": "uptimes",
"title": "Monthly uptime of relays",
"type": "Link",
diff --git a/website/etc/web.xml b/website/etc/web.xml
index 69fa359..4a53b86 100644
--- a/website/etc/web.xml
+++ b/website/etc/web.xml
@@ -62,25 +62,6 @@
</servlet-mapping>
<servlet>
- <servlet-name>Data</servlet-name>
- <servlet-class>
- org.torproject.metrics.web.DataServlet
- </servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>Data</servlet-name>
- <url-pattern>/servers-data.html</url-pattern>
- <url-pattern>/bandwidth-data.html</url-pattern>
- <url-pattern>/advbwdist-data.html</url-pattern>
- <url-pattern>/clients-data.html</url-pattern>
- <url-pattern>/userstats-combined-data.html</url-pattern>
- <url-pattern>/torperf-data.html</url-pattern>
- <url-pattern>/connbidirect2-data.html</url-pattern>
- <url-pattern>/hidserv-data.html</url-pattern>
- <url-pattern>/disagreement-data.html</url-pattern>
- </servlet-mapping>
-
- <servlet>
<servlet-name>Link</servlet-name>
<servlet-class>
org.torproject.metrics.web.LinkServlet
@@ -234,6 +215,17 @@
</servlet-mapping>
<servlet>
+ <servlet-name>StatsServlet</servlet-name>
+ <servlet-class>
+ org.torproject.metrics.web.StatsServlet
+ </servlet-class>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>StatsServlet</servlet-name>
+ <url-pattern>/stats.html</url-pattern>
+ </servlet-mapping>
+
+ <servlet>
<servlet-name>ResearchServlet</servlet-name>
<servlet-class>
org.torproject.metrics.web.ResearchServlet
diff --git a/website/src/org/torproject/metrics/web/DataServlet.java b/website/src/org/torproject/metrics/web/DataServlet.java
deleted file mode 100644
index 2aa7ccd..0000000
--- a/website/src/org/torproject/metrics/web/DataServlet.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright 2016 The Tor Project
- * See LICENSE for licensing information */
-
-package org.torproject.metrics.web;
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-@SuppressWarnings("serial")
-public class DataServlet extends MetricServlet {
-
- @Override
- public void doGet(HttpServletRequest request,
- HttpServletResponse response) throws IOException, ServletException {
- String requestUri = request.getRequestURI();
- if (requestUri == null || !requestUri.endsWith(".html")) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- String requestedId = requestUri.substring(
- requestUri.contains("/") ? requestUri.lastIndexOf("/") + 1 : 0,
- requestUri.length() - 5);
- if (!this.idsByType.containsKey("Data")
- || !this.idsByType.get("Data").contains(requestedId)) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- request.setAttribute("id", requestedId);
- request.setAttribute("title", this.titles.get(requestedId));
- request.setAttribute("description",
- this.descriptions.get(requestedId));
- request.setAttribute("data_file", this.dataFiles.get(requestedId));
- request.setAttribute("data_column_spec",
- this.dataColumnSpecs.get(requestedId));
- request.setAttribute("data", this.data.get(requestedId));
- request.getRequestDispatcher("WEB-INF/data.jsp").forward(request,
- response);
- }
-}
-
diff --git a/website/src/org/torproject/metrics/web/MetricServlet.java b/website/src/org/torproject/metrics/web/MetricServlet.java
index 901f4e2..b643a02 100644
--- a/website/src/org/torproject/metrics/web/MetricServlet.java
+++ b/website/src/org/torproject/metrics/web/MetricServlet.java
@@ -35,11 +35,6 @@ public abstract class MetricServlet extends AnyServlet {
protected Map<String, String[]> tableCellFormats =
new HashMap<String, String[]>();
- protected Map<String, String> dataFiles = new HashMap<String, String>();
-
- protected Map<String, String[]> dataColumnSpecs =
- new HashMap<String, String[]>();
-
protected Map<String, List<String[]>> data =
new HashMap<String, List<String[]>>();
@@ -72,12 +67,6 @@ public abstract class MetricServlet extends AnyServlet {
if (metric.getTableCellFormats() != null) {
this.tableCellFormats.put(id, metric.getTableCellFormats());
}
- if (metric.getDataFile() != null) {
- this.dataFiles.put(id, metric.getDataFile());
- }
- if (metric.getDataColumnSpec() != null) {
- this.dataColumnSpecs.put(id, metric.getDataColumnSpec());
- }
if (metric.getData() != null) {
dataIds.put(id, metric.getData());
}
diff --git a/website/src/org/torproject/metrics/web/StatsServlet.java b/website/src/org/torproject/metrics/web/StatsServlet.java
new file mode 100644
index 0000000..59634c7
--- /dev/null
+++ b/website/src/org/torproject/metrics/web/StatsServlet.java
@@ -0,0 +1,31 @@
+/* Copyright 2016 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.web;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class StatsServlet extends AnyServlet {
+
+ private static final long serialVersionUID = 6850919895248020945L;
+
+ @Override
+ public void init() throws ServletException {
+ super.init();
+ }
+
+ @Override
+ public void doGet(HttpServletRequest request,
+ HttpServletResponse response) throws IOException, ServletException {
+
+ /* Forward the request to the JSP that does all the hard work. */
+ request.setAttribute("categories", this.categories);
+ request.getRequestDispatcher("WEB-INF/stats.jsp").forward(request,
+ response);
+ }
+}
+
diff --git a/website/web/WEB-INF/data.jsp b/website/web/WEB-INF/data.jsp
deleted file mode 100644
index 0c86fd7..0000000
--- a/website/web/WEB-INF/data.jsp
+++ /dev/null
@@ -1,53 +0,0 @@
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <title>Tor Metrics — ${title}</title>
- <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
- <link href="css/stylesheet-ltr.css" type="text/css" rel="stylesheet">
- <link href="css/bootstrap.min.css" type="text/css" rel="stylesheet">
- <link href="images/favicon.ico" type="image/x-icon" rel="shortcut icon">
-</head>
-<body>
- <div class="center">
- <div class="main-column">
-
-<h2><a href="."><img src="images/metrics-wordmark-small.png" width="138" height="18" alt="Metrics wordmark"></a> — ${title}</h2>
-<br>
-${description}
-
-<p><b>Download as <a href="${data_file}">CSV file</a>.</b></p>
-
-<p>The statistics file contains the following columns:</p>
-<ul>
-<c:forEach var="row" items="${data_column_spec}">
-<li>${row}</li>
-</c:forEach>
-</ul>
-
-<c:if test="${fn:length(data) > 0}">
-<h4>Underlying data</h4>
-<ul>
-<c:forEach var="row" items="${data}">
-<li><a href="${row[0]}">${row[1]}</a></li>
-</c:forEach>
-</ul>
-</c:if>
-
-<c:if test="${fn:length(related) > 0}">
-<h4>Related metrics</h4>
-<ul>
-<c:forEach var="row" items="${related}">
-<li><a href="${row[0]}">${row[1]}</a></li>
-</c:forEach>
-</ul>
-</c:if>
-
- </div>
- </div>
- <div class="bottom" id="bottom">
- <%@ include file="footer.jsp"%>
- </div>
-</body>
-</html>
diff --git a/website/web/WEB-INF/stats.jsp b/website/web/WEB-INF/stats.jsp
new file mode 100644
index 0000000..2690e89
--- /dev/null
+++ b/website/web/WEB-INF/stats.jsp
@@ -0,0 +1,490 @@
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
+<jsp:include page="top.jsp">
+ <jsp:param name="pageTitle" value="Sources – Tor Metrics"/>
+ <jsp:param name="navActive" value="Sources"/>
+</jsp:include>
+
+ <div class="container">
+ <ul class="breadcrumb">
+ <li><a href="index.html">Home</a></li>
+ <li><a href="sources.html">Sources</a></li>
+ <li class="active">Statistics</li>
+ </ul>
+ </div>
+
+ <div class="container">
+ <h1>Pre-aggregated statistics files used on this website</h1>
+ <p>This page contains specifications and links to pre-aggregated statistics files used on this website.</p>
+ </div>
+
+<div class="container">
+<h2>Number of relays and bridges</h2>
+
+<p>The following data file contains the number of running <a
+href="about.html#relay">relays</a> and <a href="about.html#bridge">bridges</a>
+in the network. Statistics include subsets of relays or bridges by <a
+href="about.html#relay-flag">relay flag</a> (relays only), country code (relays
+only, and only until February 2013), tor software version (relays only),
+operating system (relays only), and by whether or not they are running in the
+EC2 cloud (bridges only). The data file contains daily (mean) averages of relay
+and bridge numbers.</p>
+
+<p><b>Download as <a href="stats/servers.csv">CSV file</a>.</b></p>
+
+<p>The statistics file contains the following columns:</p>
+<ul>
+
+<li><b>date:</b> UTC date (YYYY-MM-DD) when relays or bridges have been listed
+as running.</li>
+
+<li><b>flag:</b> Relay flag assigned by the directory authorities. Examples are
+<b>"Exit"</b>, <b>"Guard"</b>, <b>"Fast"</b>, <b>"Stable"</b>, and
+<b>"HSDir"</b>. Relays can have none, some, or all these relay flags assigned.
+Relays that don't have the <b>"Running"</b> flag are not included in these
+statistics regardless of their other flags. If this column contains the empty
+string, all running relays are included, regardless of assigned flags. There
+are no statistics on the number of bridges by relay flag.</li>
+
+<li><b>country:</b> Two-letter lower-case country code as found in a GeoIP
+database by resolving the relay's first onion-routing IP address, or <b>"??"</b>
+if an IP addresses could not be resolved. If this column contains the empty
+string, all running relays are included, regardless of their resolved country
+code. Statistics on relays by country code are only available until January 31,
+2013. There are no statistics on the number of bridges by country code.</li>
+
+<li><b>version:</b> First three dotted numbers of the Tor software version as
+reported by the relay. An example is <b>"0.2.5"</b>. If this column contains
+the empty string, all running relays are included, regardless of the Tor
+software version they run. There are no statistics on the number of bridges by
+Tor software version.</li>
+
+<li><b>platform:</b> Operating system as reported by the relay. Examples are
+<b>"Linux"</b>, <b>"Darwin"</b> (Mac OS X), <b>"BSD"</b>, <b>"Windows"</b>, and
+<b>"Other"</b>. If this column contains the empty string, all running relays
+are included, regardless of the operating system they run on. There are no
+statistics on the number of bridges by operating system.</li>
+
+<li><b>ec2bridge:</b> Whether bridges are running in the EC2 cloud or not. More
+precisely, bridges in the EC2 cloud running an image provided by Tor by default
+set their nickname to <b>"ec2bridger"</b> plus 8 random hex characters. This
+column either contains <b>"t"</b> for bridges matching this naming scheme, or
+the empty string for all bridges regardless of their nickname. There are no
+statistics on the number of relays running in the EC2 cloud.</li>
+
+<li><b>relays:</b> The average number of relays matching the criteria in the
+previous columns. If the values in previous columns are specific to bridges
+only, this column contains the empty string.</li>
+
+<li><b>bridges:</b> The average number of bridges matching the criteria in the
+previous columns. If the values in previous columns are specific to relays
+only, this column contains the empty string.</li>
+
+</ul>
+
+</div>
+
+<div class="container">
+<h2>Bandwidth provided and consumed by relays</h2>
+
+<p>The following data file contains statistics on <a
+href="about.html#advertised-bandwidth">advertised</a> and <a
+href="about.html#bandwidth-history">consumed bandwidth</a> of <a
+href="about.html#relay">relays</a> in the network. Statistics on advertised
+bandwidth include any kind of traffic handled by a relay, whereas statistics on
+consumed bandwidth are available either for all traffic combined, or
+specifically for directory traffic. Some of the statistics are available for
+subsets of relays that have the "Exit" and/or the "Guard" <a
+href="about.html#relay-flag">flag</a>. The data file contains daily (mean)
+averages of bandwidth numbers.</p>
+
+<p><b>Download as <a href="stats/bandwidth.csv">CSV file</a>.</b></p>
+
+<p>The statistics file contains the following columns:</p>
+<ul>
+
+<li><b>date:</b> UTC date (YYYY-MM-DD) that relays reported bandwidth data
+for.</li>
+
+<li><b>isexit:</b> Whether relays included in this line have the <b>"Exit"</b>
+relay flag or not, which can be <b>"t"</b> or <b>"f"</b>. If this column
+contains the empty string, bandwidth data from all running relays are included,
+regardless of assigned relay flags.</li>
+
+<li><b>isguard:</b> Whether relays included in this line have the <b>"Guard"</b>
+relay flag or not, which can be <b>"t"</b> or <b>"f"</b>. If this column
+contains the empty string, bandwidth data from all running relays are included,
+regardless of assigned relay flags.</li>
+
+<li><b>advbw:</b> Total advertised bandwidth in bytes per second that relays are
+capable to provide.</li>
+
+<li><b>bwread:</b> Total bandwidth in bytes per second that relays have read.
+This metric includes any kind of traffic.</li>
+
+<li><b>bwwrite:</b> Similar to <b>bwread</b>, but for traffic written by
+relays.</li>
+
+<li><b>dirread:</b> Bandwidth in bytes per second that relays have read when
+serving directory data. Not all relays report how many bytes they read when
+serving directory data which is why this value is an estimate from the available
+data. This metric is not available for subsets of relays with certain relay
+flags, so that this column will contain the empty string if either <b>isexit</b>
+or <b>isguard</b> is non-empty.</li>
+
+<li><b>dirwrite:</b> Similar to <b>dirread</b>, but for traffic written by
+relays when serving directory data.</li>
+
+</ul>
+
+</div>
+
+<div class="container">
+<h2>Advertised bandwidth distribution and n-th fastest relays</h2>
+
+<p>The following data file contains statistics on the distribution of <a
+href="about.html#advertised-bandwidth">advertised bandwidth</a> of relays in the
+network. These statistics include advertised bandwidth percentiles and
+advertised bandwidth values of the n-th fastest relays. All values are obtained
+from advertised bandwidths of running relays in a <a
+href="about.html#consensus">network status consensus</a>. The data file
+contains daily (median) averages of percentiles and n-th largest values.</p>
+
+<p><b>Download as <a href="stats/advbwdist.csv">CSV file</a>.</b></p>
+
+<p>The statistics file contains the following columns:</p>
+<ul>
+
+<li><b>date:</b> UTC date (YYYY-MM-DD) when relays have been listed as
+running.</li>
+
+<li><b>isexit:</b> Whether relays included in this line have the <b>"Exit"</b>
+relay flag, which would be indicated as <b>"t"</b>. If this column contains the
+empty string, advertised bandwidths from all running relays are included,
+regardless of assigned relay flags.</li>
+
+<li><b>relay:</b> Position of the relay in an ordered list of all advertised
+bandwidths, starting at 1 for the fastest relay in the network. May be the
+empty string if this line contains advertised bandwidth by percentile.</li>
+
+<li><b>percentile:</b> Advertised bandwidth percentile given in this line. May
+be the empty string if this line contains advertised bandwidth by fastest
+relays.</li>
+
+<li><b>advbw:</b> Advertised bandwidth in B/s.</li>
+
+</ul>
+
+</div>
+
+<div class="container">
+<h2>Estimated number of clients in the Tor network</h2>
+
+<p>The following data file contains estimates on the number of <a
+href="about.html#client">clients</a> in the network. These numbers are derived
+from directory requests counted on <a
+href="about.html#directory-authority">directory authorities</a>, <a
+href="about.html#directory-mirror">directory mirrors</a>, and <a
+href="about.html#bridge">bridges</a>. Statistics are available for clients
+connecting directly relays and clients connecting via bridges. There are
+statistics available by country (for both directly-connecting clients and
+clients connecting via bridges), by transport protocol (only for clients
+connecting via bridges), and by IP version (only for clients connecting via
+bridges). Statistics also include predicted client numbers from past
+observations, which can be used to detect censorship events.</p>
+
+<p><b>Download as <a href="stats/clients.csv">CSV file</a>.</b></p>
+
+<p>The statistics file contains the following columns:</p>
+<ul>
+
+<li><b>date:</b> UTC date (YYYY-MM-DD) for which client numbers are
+estimated.</li>
+
+<li><b>node:</b> The node type to which clients connect first, which can be
+either <b>"relay"</b> or <b>"bridge"</b>.</li>
+
+<li><b>country:</b> Two-letter lower-case country code as found in a GeoIP
+database by resolving clients' IP addresses, or <b>"??"</b> if client IP
+addresses could not be resolved. If this column contains the empty string, all
+clients are included, regardless of their country code.</li>
+
+<li><b>transport:</b> Transport name used by clients to connect to the Tor
+network using bridges. Examples are <b>"obfs2"</b>, <b>"obfs3"</b>,
+<b>"websocket"</b>, or <b>"<OR>"</b> (original onion routing protocol).
+If this column contains the empty string, all clients are included, regardless
+of their transport. There are no statistics on the number of clients by
+transport that connect to the Tor network via relays.</li>
+
+<li><b>version:</b> IP version used by clients to connect to the Tor network
+using bridges. Examples are <b>"v4"</b> and <b>"v6"</b>. If this column
+contains the empty string, all clients are included, regardless of their IP
+version. There are no statistics on the number of clients by IP version that
+connect directly to the Tor network using relays.</li>
+
+<li><b>lower:</b> Lower number of expected clients under the assumption that
+there has been no censorship event. If this column contains the empty string,
+there are no expectations on the number of clients.</li>
+
+<li><b>upper:</b> Upper number of expected clients under the assumption that
+there has been no release of censorship. If this column contains the empty
+string, there are no expectations on the number of clients.</li>
+
+<li><b>clients:</b> Estimated number of clients.</li>
+
+<li><b>frac:</b> Fraction of relays or bridges in percent that the estimate is
+based on. The higher this value, the more reliable is the estimate. Values
+above 50 can be considered reliable enough for most purposes, lower values
+should be handled with more care.</li>
+
+</ul>
+
+</div>
+
+<div class="container">
+<h2>Estimated number of clients by country and transport</h2>
+
+<p>The following data file contains additional statistics on the number of <a
+href="about.html#client">clients</a> in the network. This data file is related
+to the <a href="clients-data.html">clients-data file</a> that contains estimates
+on the number of clients by country and by transport protocol. This data file
+enhances these statistics by containing estimates of clients connecting to <a
+href="about.html#bridge">bridges</a> by a given country and using a given <a
+href="about.html#pluggable-transport">transport protocol</a>. Even though
+bridges don't report a combination of clients by country and transport, it's
+possible to derive lower and upper bounds from existing usage statistics.</p>
+
+<p><b>Download as <a href="stats/userstats-combined.csv">CSV file</a>.</b></p>
+
+<p>The statistics file contains the following columns:</p>
+<ul>
+
+<li><b>date:</b> UTC date (YYYY-MM-DD) for which client numbers are
+estimated.</li>
+
+<li><b>node:</b> The node type to which clients connect first, which is always
+<b>"bridge"</b>, because relays don't report responses by transport.</li>
+
+<li><b>country:</b> Two-letter lower-case country code as found in a GeoIP
+database by resolving clients' IP addresses, or <b>"??"</b> if client IP
+addresses could not be resolved.</li>
+
+<li><b>transport:</b> Transport name used by clients to connect to the Tor
+network using bridges. Examples are <b>"obfs2"</b>, <b>"obfs3"</b>,
+<b>"websocket"</b>, or <b>"<OR>"</b> (original onion routing
+protocol).</li>
+
+<li><b>version:</b> IP version used by clients to connect to the Tor network
+using bridges. This column always contains the empty string and is only
+included for compatibility reasons.</li>
+
+<li><b>frac:</b> Fraction of relays or bridges in percent that the estimate is
+based on. The higher this value, the more reliable is the estimate. Values
+above 50 can be considered reliable enough for most purposes, lower values
+should be handled with more care.</li>
+
+<li><b>low:</b> Lower bound of users by country and transport, calculated as sum
+over all bridges having reports for the given country and transport, that is,
+the sum of <b>M(b)</b>, where for each bridge <b>b</b> define <b>M(b) := max(0,
+C(b) + T(b) - S(b))</b> using the following definitions: <b>C(b)</b> is the
+number of users from a given country reported by <b>b</b>; <b>T(b)</b> is the
+number of users using a given transport reported by <b>b</b>; and <b>S(b)</b> is
+the total numbers of users reported by <b>b</b>. Reasoning: If the sum <b>C(b)
++ T(b)</b> exceeds the total number of users from all countries and transports
+<b>S(b)</b>, there must be users from that country and transport. And if that
+is not the case, <b>0</b> is the lower limit.</li>
+
+<li><b>high:</b> Upper bound of users by country and transport, calculated as
+sum over all bridges having reports for the given country and transport, that
+is, the sum of <b>m(b)</b>, where for each bridge <b>b</b> define
+<b>m(b):=min(C(b), T(b))</b> where we use the definitions from <b>low</b>
+(above). Reasoning: there cannot be more users by country and transport than
+there are users by either of the two numbers.</li>
+
+</ul>
+
+</div>
+
+<div class="container">
+<h2>Performance of downloading static files over Tor</h2>
+
+<p>The following data file contains aggregate statistics on performance when
+downloading static files of different sizes over Tor. These statistics are
+generated by the <a href="https://gitweb.torproject.org/torperf.git">Torperf</a>
+tool, which periodically fetches static files over Tor and records several
+timestamps in the process. The data file contains daily medians and quartiles
+as well as total numbers of requests, timeouts, and failures. Raw Torperf
+measurement data are available on the <a
+href="https://collector.torproject.org/formats.html#torperf">CollecTor</a>
+website.</p>
+
+<p><b>Download as <a href="stats/torperf.csv">CSV file</a>.</b></p>
+
+<p>The statistics file contains the following columns:</p>
+<ul>
+
+<li><b>date:</b> UTC date (YYYY-MM-DD) when download performance was
+measured.</li>
+
+<li><b>size:</b> Size of the downloaded file in bytes.</li>
+
+<li><b>source:</b> Name of the Torperf service performing measurements. If this
+column contains the empty string, all measurements are included, regardless of
+which Torperf service performed them. Examples are <b>"moria"</b>,
+<b>"siv"</b>, and <b>"torperf"</b>.</li>
+
+<li><b>q1:</b> First quartile of time until receiving the last byte in
+milliseconds.</li>
+
+<li><b>md:</b> Median of time until receiving the last byte in
+milliseconds.</li>
+
+<li><b>q3:</b> Third quartile of time until receiving the last byte in
+milliseconds.</li>
+
+<li><b>timeouts:</b> Number of timeouts that occurred when attempting to
+download the static file over Tor.</li>
+
+<li><b>failures:</b> Number of failures that occurred when attempting to
+download the static file over Tor.</li>
+
+<li><b>requests:</b> Total number of requests made to download the static file
+over Tor.</li>
+
+</ul>
+
+</div>
+
+<div class="container">
+<h2>Fraction of connections used uni-/bidirectionally</h2>
+
+<p>The following data file contains statistics on the fraction of direct
+connections between a <a href="about.html#relay">relay</a> and other nodes in
+the network that are used uni- or bidirectionally. Every 10 seconds, relays
+determine for every direct connection whether they read and wrote less than a
+threshold of 20 KiB. Connections below this threshold are excluded from the
+statistics file. For the remaining connections, relays determine whether they
+read/wrote at least 10 times as many bytes as they wrote/read. If so, they
+classify a connection as "mostly reading" or "mostly writing", respectively.
+All other connections are classified as "both reading and writing". After
+classifying connections, read and write counters are reset for the next
+10-second interval. The data file contains daily medians and quartiles of
+reported fractions.</p>
+
+<p><b>Download as <a href="stats/connbidirect2.csv">CSV file</a>.</b></p>
+
+<p>The statistics file contains the following columns:</p>
+<ul>
+
+<li><b>date:</b> UTC date (YYYY-MM-DD) for which statistics on
+uni-/bidirectional connection usage were reported.</li>
+
+<li><b>direction:</b> Direction of reported fraction, which can be
+<b>"read"</b>, <b>"write"</b>, or <b>"both"</b> for connections classified as
+"mostly reading", "mostly writing", or "both reading as writing". Connections
+below the threshold have been removed from this statistics file entirely.</li>
+
+<li><b>quantile:</b> Quantile of the reported fraction when considering all
+statistics reported for this date. Examples are <b>"0.5"</b> for the median and
+<b>"0.25"</b> and <b>"0.75"</b> for the lower and upper quartile.</li>
+
+<li><b>fraction:</b> Fraction of connections in percent for the given date,
+direction, and quantile. For each daily statistic reported by a relay,
+fractions for the three directions "read", "write", and "both" sum up to exactly
+100.</li>
+
+</ul>
+
+</div>
+
+<div class="container">
+<h2>Hidden-service statistics</h2>
+
+<p>The following data file contains <a
+href="about.html#hidden-service">hidden-service</a> statistics gathered by a
+small subset of <a href="about.html#relay">relays</a> and extrapolated to
+network totals. Statistics include the amount of hidden-service traffic and the
+number of hidden-service addresses in the network per day. For more details on
+the extrapolation algorithm, see <a
+href="https://blog.torproject.org/blog/some-statistics-about-onions">this blog
+post</a> and <a
+href="https://research.torproject.org/techreports/extrapolating-hidserv-stats-201…">this
+technical report</a>.</p>
+
+<p><b>Download as <a href="stats/hidserv.csv">CSV file</a>.</b></p>
+
+<p>The statistics file contains the following columns:</p>
+<ul>
+
+<li><b>date:</b> UTC date (YYYY-MM-DD) when relays or bridges have been listed
+as running.</li>
+
+<li><b>type:</b> Type of hidden-service statistic reported by relays and
+extrapolated to network totals. Examples include <b>"rend-relayed-cells"</b>
+for the number of cells on rendezvous circuits observed by rendezvous points and
+<b>"dir-onions-seen"</b> for the number of unique .onion addresses observed by
+hidden-service directories.</li>
+
+<li><b>wmean:</b> Weighted mean of extrapolated network totals.</li>
+
+<li><b>wmedian:</b> Weighted median of extrapolated network totals.</li>
+
+<li><b>wiqm:</b> Weighted interquartile mean of extrapolated network
+totals.</li>
+
+<li><b>frac:</b> Total network fraction of reported statistics.</li>
+
+<li><b>stats:</b> Number of reported statistics with non-zero computed network
+fraction.</li>
+
+</ul>
+
+</div>
+
+<div class="container">
+<h2>Disagreement among the directory authorities (deprecated)</h2>
+
+<div class="bs-callout bs-callout-warning">
+<h3>Deprecated</h3>
+<p>As of September 29, 2016, the linked data file is not updated anymore. This section and the linked data file will be removed in the future.</p>
+</div>
+
+<p>The following data file contains statistics about agreement
+or disagreement among the <a href="about.html#directory-authority">directory
+authorities</a>. Once per hour the directory authorities exchange votes with
+their view of the <a href="about.html#relay">relays</a> in the network including
+attributes like <a href="about.html#relay-flag">relay flags</a> or bandwidth
+measurements. This data file includes counts of relays by number of directory
+authorities assigning them a given attribute.</p>
+
+<p><b>Download as <a href="stats/disagreement.csv">CSV file</a>.</b></p>
+
+<p>The statistics file contains the following columns:</p>
+<ul>
+
+<li><b>validafter:</b> UTC timestamp (YYYY-MM-DD HH:MM:SS) after which votes
+became valid, which may be used as the vote publication time.</li>
+
+<li><b>attribute:</b> Attribute assigned to relays by directory authorities,
+which includes relay flags like <b>"Exit"</b> or <b>"BadExit"</b> as well as
+<b>"Listed"</b> for relays being listed in a vote and <b>"Measured"</b> for
+relays being measured by the bandwidth authorities.</li>
+
+<li><b>votes:</b> Number of votes assigning the attribute to relays.</li>
+
+<li><b>required:</b> Required number of votes for the attribute to be assigned
+to a relay for being included in the consensus.</li>
+
+<li><b>max:</b> Maximum number of possible votes assigning the attribute to
+relays.</li>
+
+<li><b>relays:</b> Number of relays that got the given number of votes for the
+given attribute.</li>
+
+</ul>
+
+ </div>
+ </div>
+
+<jsp:include page="bottom.jsp"/>
+
1
0
commit f2ea20289c8c7e52aee7c45ff9450499c269636b
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Dec 21 11:30:48 2016 +0100
Create sources page.
---
website/etc/web.xml | 12 ++-
.../org/torproject/metrics/web/SourcesServlet.java | 31 ++++++
website/web/WEB-INF/sources.jsp | 104 +++++++++++++++++++++
website/web/images/collector-logo.png | Bin 0 -> 90241 bytes
website/web/images/default-logo.png | Bin 0 -> 96441 bytes
website/web/images/ooni-logo.png | Bin 0 -> 5573 bytes
6 files changed, 146 insertions(+), 1 deletion(-)
diff --git a/website/etc/web.xml b/website/etc/web.xml
index 4a53b86..b6f2015 100644
--- a/website/etc/web.xml
+++ b/website/etc/web.xml
@@ -202,6 +202,17 @@
</servlet-mapping>
<servlet>
+ <servlet-name>SourcesServlet</servlet-name>
+ <servlet-class>
+ org.torproject.metrics.web.SourcesServlet
+ </servlet-class>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>SourcesServlet</servlet-name>
+ <url-pattern>/sources.html</url-pattern>
+ </servlet-mapping>
+
+ <servlet>
<servlet-name>ToolsServlet</servlet-name>
<servlet-class>
org.torproject.metrics.web.ToolsServlet
@@ -209,7 +220,6 @@
</servlet>
<servlet-mapping>
<servlet-name>ToolsServlet</servlet-name>
- <url-pattern>/sources.html</url-pattern>
<url-pattern>/operation.html</url-pattern>
<url-pattern>/development.html</url-pattern>
</servlet-mapping>
diff --git a/website/src/org/torproject/metrics/web/SourcesServlet.java b/website/src/org/torproject/metrics/web/SourcesServlet.java
new file mode 100644
index 0000000..3c0e894
--- /dev/null
+++ b/website/src/org/torproject/metrics/web/SourcesServlet.java
@@ -0,0 +1,31 @@
+/* Copyright 2016 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.metrics.web;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class SourcesServlet extends AnyServlet {
+
+ private static final long serialVersionUID = 6850919895248020945L;
+
+ @Override
+ public void init() throws ServletException {
+ super.init();
+ }
+
+ @Override
+ public void doGet(HttpServletRequest request,
+ HttpServletResponse response) throws IOException, ServletException {
+
+ /* Forward the request to the JSP that does all the hard work. */
+ request.setAttribute("categories", this.categories);
+ request.getRequestDispatcher("WEB-INF/sources.jsp").forward(request,
+ response);
+ }
+}
+
diff --git a/website/web/WEB-INF/sources.jsp b/website/web/WEB-INF/sources.jsp
new file mode 100644
index 0000000..3c36611
--- /dev/null
+++ b/website/web/WEB-INF/sources.jsp
@@ -0,0 +1,104 @@
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
+<jsp:include page="top.jsp">
+ <jsp:param name="pageTitle" value="Sources – Tor Metrics"/>
+ <jsp:param name="navActive" value="Sources"/>
+</jsp:include>
+
+ <div class="container">
+ <ul class="breadcrumb">
+ <li><a href="index.html">Home</a></li>
+ <li class="active">Sources</li>
+ </ul>
+ </div>
+
+ <div class="container">
+ <h1>Sources</h1>
+ <p>You're a data person and only trust the statistics that you doctored yourself? Here's all the data right from the source, doctor.</p>
+ </div>
+
+ <div class="container tools">
+ <a name="archive" id="anchor-archive"></a>
+ <h2>Network archives</h2>
+ <p>We get our data from the network archives below.</p>
+ <div class="row">
+
+ <div class="col-md-3 col-sm-4 col-xs-6">
+ <a href="https://collector.torproject.org/" target="_blank">
+ <div class="logo" style="background-image:url(images/collector-logo.png);"></div>
+ <h2>CollecTor</h2>
+ <p>collects data from various nodes and services in the public Tor network.</p>
+ </a>
+ </div>
+
+ <div class="col-md-3 col-sm-4 col-xs-6">
+ <a href="https://ooni.torproject.org/" target="_blank">
+ <div class="logo" style="background-image:url(images/ooni-logo.png);"></div>
+ <h2>OONI</h2>
+ <p>detects censorship, surveillance, and traffic manipulation on the internet.</p>
+ </a>
+ </div>
+
+ </div>
+ </div>
+
+ <div class="container tools">
+ <a name="measurement" id="anchor-measurement"></a>
+ <h2>Measurement tools</h2>
+ <p>The following tools perform active measurements in the Tor network. (They don't have pretty logos yet, but they are all uniquely useful!)</p>
+ <div class="row">
+
+ <div class="col-md-2 col-sm-3 col-xs-4">
+ <a href="https://www.torproject.org/projects/tordnsel.html.en" target="_blank">
+ <div class="logo" style="background-image:url(images/default-logo.png);"></div>
+ <h3>TorDNSEL</h3>
+ <p>publishes lists of IP addresses of multi-homed Tor exits.</p>
+ </a>
+ </div>
+
+ <div class="col-md-2 col-sm-3 col-xs-4">
+ <a href="https://gitweb.torproject.org/torperf.git" target="_blank">
+ <div class="logo" style="background-image:url(images/default-logo.png);"></div>
+ <h3>Torperf</h3>
+ <p>measures Tor performance with a set of utilities and Python scripts.</p>
+ </a>
+ </div>
+
+ <div class="col-md-2 col-sm-3 col-xs-4">
+ <a href="https://github.com/robgjansen/onionperf" target="_blank">
+ <div class="logo" style="background-image:url(images/default-logo.png);"></div>
+ <h3>OnionPerf</h3>
+ <p>measures the performance of onion services.</p>
+ </a>
+ </div>
+
+ </div>
+ </div>
+
+ <div class="container tools">
+ <a name="aggregated" id="anchor-aggregated"></a>
+ <h2>Pre-aggregated data</h2>
+ <p>Sometimes the data from the original sources can be hard to process. If you want to take a little shortcut, try out the following pre-aggregated statistics.</p>
+ <div class="row">
+
+ <div class="col-md-2 col-sm-3 col-xs-4">
+ <a href="stats.html">
+ <div class="logo" style="background-image:url(images/default-logo.png);"></div>
+ <h3>CSV files</h3>
+ <p>are available with aggregated statistics of visualizations on this site.</p>
+ </a>
+ </div>
+
+ <div class="col-md-2 col-sm-3 col-xs-4">
+ <a href="https://onionoo.torproject.org/" target="_blank">
+ <div class="logo" style="background-image:url(images/default-logo.png);"></div>
+ <h3>Onionoo</h3>
+ <p>provides current and historical data about relays and bridges via a web-based API.</p>
+ </a>
+ </div>
+
+ </div>
+ </div>
+
+<jsp:include page="bottom.jsp"/>
+
diff --git a/website/web/images/collector-logo.png b/website/web/images/collector-logo.png
new file mode 100644
index 0000000..90a72d8
Binary files /dev/null and b/website/web/images/collector-logo.png differ
diff --git a/website/web/images/default-logo.png b/website/web/images/default-logo.png
new file mode 100644
index 0000000..ef0cd90
Binary files /dev/null and b/website/web/images/default-logo.png differ
diff --git a/website/web/images/ooni-logo.png b/website/web/images/ooni-logo.png
new file mode 100644
index 0000000..777481b
Binary files /dev/null and b/website/web/images/ooni-logo.png differ
1
0

09 Jan '17
commit b324c54e8551153c33024728cadbce1c214d0dd5
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Tue Dec 20 21:36:50 2016 +0100
Apply new design to start page.
---
website/etc/categories.json | 24 ++--
website/etc/web.xml | 4 +-
.../src/org/torproject/metrics/web/Category.java | 6 +
.../org/torproject/metrics/web/IndexServlet.java | 2 +-
website/web/WEB-INF/bottom.jsp | 41 +++++++
website/web/WEB-INF/index.jsp | 77 +++++--------
website/web/WEB-INF/top.jsp | 125 +++++++++++++++++++++
7 files changed, 216 insertions(+), 63 deletions(-)
diff --git a/website/etc/categories.json b/website/etc/categories.json
index 9a10aea..766108a 100644
--- a/website/etc/categories.json
+++ b/website/etc/categories.json
@@ -1,8 +1,9 @@
[
{
"id": "clients",
+ "icon": "fa-users",
"header": "Users",
- "summary": "Where are Tor users from and how they connect to Tor.",
+ "summary": "Where Tor users are from and how they connect to Tor.",
"description": "We estimate the number of users by analyzing the requests induced by Tor clients. These papers detail on how we count users and how we count bridge users.",
"metrics": [
"userstats-relay-country",
@@ -18,7 +19,8 @@
},
{
"id": "servers",
- "header": "Relays and Bridges",
+ "icon": "fa-server",
+ "header": "Servers",
"summary": "How many relays and bridges are online and what we know about them.",
"description": "Country and ISP diversity are approximated by resolving IP addresses to a country code an an autonomous system. We process the capabilities and properties relays and bridges reported to directory authorities.",
"metrics": [
@@ -33,9 +35,10 @@
},
{
"id": "traffic",
+ "icon": "fa-road",
"header": "Traffic",
- "summary": "How much traffic can the Tor network can handle and how much traffic there is.",
-"description": "We measure total available bandwidth and current capacity by aggregating what relays and bridges report to directory authorities.",
+ "summary": "How much traffic the Tor network can handle and how much traffic there is.",
+ "description": "We measure total available bandwidth and current capacity by aggregating what relays and bridges report to directory authorities.",
"metrics": [
"bandwidth",
"bandwidth-flags",
@@ -48,9 +51,10 @@
},
{
"id": "performance",
+ "icon": "fa-dashboard",
"header": "Performance",
"summary": "How fast and reliable the Tor network is.",
-description": "We use <a href=\"https://gitweb.torproject.org/torperf.git\">Torperf</a> to run performance measurements. It works by fetching files of different sizes over Tor and measuring how long that takes.",
+ "description": "We use <a href=\"https://gitweb.torproject.org/torperf.git\">Torperf</a> to run performance measurements. It works by fetching files of different sizes over Tor and measuring how long that takes.",
"metrics": [
"torperf",
"torperf-failures",
@@ -59,20 +63,14 @@ description": "We use <a href=\"https://gitweb.torproject.org/torperf.git\">Torp
},
{
"id": "onion-services",
+ "icon": "fa-map-signs",
"header": "Onion Services",
- "summary": "How many onion services are there and how much traffic they pull.",
+ "summary": "How many onion services there are and how much traffic they pull.",
"description": "Onion services are services that are only accessible via the Tor network.",
"metrics": [
"hidserv-dir-onions-seen",
"hidserv-rend-relayed-cells",
"hidserv-frac-reporting"
]
- },
- {
- "id": "downloads",
- "header": "Downloads",
- "summary": "How many downloaded Tor application with respect to version updates.",
- "description": "We measure how many people downloaded which versions of Tor by using a web stats.",
- "metrics": []
}
]
diff --git a/website/etc/web.xml b/website/etc/web.xml
index 0e9011a..69fa359 100644
--- a/website/etc/web.xml
+++ b/website/etc/web.xml
@@ -228,7 +228,9 @@
</servlet>
<servlet-mapping>
<servlet-name>ToolsServlet</servlet-name>
- <url-pattern>/tools.html</url-pattern>
+ <url-pattern>/sources.html</url-pattern>
+ <url-pattern>/operation.html</url-pattern>
+ <url-pattern>/development.html</url-pattern>
</servlet-mapping>
<servlet>
diff --git a/website/src/org/torproject/metrics/web/Category.java b/website/src/org/torproject/metrics/web/Category.java
index 172929f..935dc14 100644
--- a/website/src/org/torproject/metrics/web/Category.java
+++ b/website/src/org/torproject/metrics/web/Category.java
@@ -9,6 +9,8 @@ public class Category {
private String id;
+ private String icon;
+
private String header;
private String summary;
@@ -21,6 +23,10 @@ public class Category {
return this.id;
}
+ public String getIcon() {
+ return this.icon;
+ }
+
public String getHeader() {
return this.header;
}
diff --git a/website/src/org/torproject/metrics/web/IndexServlet.java b/website/src/org/torproject/metrics/web/IndexServlet.java
index b287102..f3bb218 100644
--- a/website/src/org/torproject/metrics/web/IndexServlet.java
+++ b/website/src/org/torproject/metrics/web/IndexServlet.java
@@ -25,7 +25,7 @@ public class IndexServlet extends HttpServlet {
ContentProvider.getInstance().getCategoriesList()) {
categories.add(new String[] {
category.getMetrics().isEmpty() ? "" : category.getMetrics().get(0),
- category.getHeader(), category.getSummary() });
+ category.getHeader(), category.getSummary(), category.getIcon() });
}
this.categories = categories;
}
diff --git a/website/web/WEB-INF/bottom.jsp b/website/web/WEB-INF/bottom.jsp
new file mode 100644
index 0000000..5549cc8
--- /dev/null
+++ b/website/web/WEB-INF/bottom.jsp
@@ -0,0 +1,41 @@
+ <div class="container-fluid" id="footer">
+
+ <div class="container no-gutter">
+ <div class="col-xs-6">
+ <p>
+ © 2009–2016 The Tor Project
+ </p>
+ </div>
+ <div class="col-xs-6">
+ <p class="pull-right">
+
+ <a href="?page=about#contact">Contact</a>
+
+ </p>
+ </div>
+ </div>
+
+ <div class="container small">
+
+ <p>This material is supported in part by the National Science Foundation
+under Grant No. CNS-0959138. Any opinions, finding, and conclusions or
+recommendations expressed in this material are those of the author(s) and do not
+necessarily reflect the views of the National Science Foundation. "Tor" and the
+"Onion Logo" are <a href="https://www.torproject.org/docs/trademark-faq.html.en"
+target="_blank">registered trademarks</a> of The Tor Project, Inc.. Data on this
+site is freely available under a <a
+href="http://creativecommons.org/publicdomain/zero/1.0/" target="_blank">CC0 no
+copyright declaration</a>: To the extent possible under law, the Tor Project has
+waived all copyright and related or neighboring rights in the data. Graphs are
+licensed under a <a href="http://creativecommons.org/licenses/by/3.0/us/"
+target="_blank">Creative Commons Attribution 3.0 United States License</a>.</p>
+
+ </div>
+
+ </div><!-- /footer -->
+
+</div><!-- /wrapper -->
+
+</body>
+</html>
+
diff --git a/website/web/WEB-INF/index.jsp b/website/web/WEB-INF/index.jsp
index 55c882a..e55b389 100644
--- a/website/web/WEB-INF/index.jsp
+++ b/website/web/WEB-INF/index.jsp
@@ -1,56 +1,37 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <title>Tor Metrics</title>
- <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
- <link href="css/stylesheet-ltr.css" type="text/css" rel="stylesheet">
- <link href="css/bootstrap.min.css" type="text/css" rel="stylesheet">
- <link href="images/favicon.ico" type="image/x-icon" rel="shortcut icon">
-</head>
-<body>
- <div class="center">
- <div class="main-column">
- <h2><a href="/"><img src="images/metrics-logo.png" width="153" height="200" alt="Metrics logo"><img src="images/metrics-wordmark.png" width="384" height="50" alt="Metrics wordmark"></a></h2>
- <br>
-
-<p>"Tor metrics are the ammunition that lets Tor and other security
-advocates argue for a more private and secure Internet from a position
-of data, rather than just dogma or perspective."
-<i>- Bruce Schneier (June 1, 2016)</i></p>
-
- <!-- Navigation start -->
- Metrics |
- <a href="about.html">About</a> |
- <a href="news.html">News</a> |
- <a href="tools.html">Tools</a> |
- <a href="research.html">Research</a>
- <br>
- <br>
- <!-- Navigation end -->
-
- <h1>Welcome!</h1>
- <p>What would you like to know about the Tor network?</p>
-
-<div>
-
-<c:forEach var="category" items="${categories}">
-<c:if test="${fn:length(category[0]) > 0}"><a href="${category[0]}.html"></c:if><h2>${category[1]}</h2><c:if test="${fn:length(category[0]) > 0}"></a></c:if>
-<p>${category[2]}</p>
-</c:forEach>
-<br>
-
-</div>
+<jsp:include page="top.jsp">
+ <jsp:param name="pageTitle" value="Welcome to Tor Metrics"/>
+ <jsp:param name="navActive" value="Home"/>
+</jsp:include>
+
+ <!-- empty breadcrumb, just to keep everything in line... -->
+ <div class="container">
+ <ul class="breadcrumb">
+ <li class="active"> </li>
+ </ul>
+ </div>
-<p>Let us know if we're missing anything, or if we should measure something
-else.</p>
+ <div class="container">
+ <h1>Welcome!</h1>
+ <p>
+ What would you like to know about the Tor network?
+ </p>
+ </div>
+ <div class="container dashboard">
+ <div class="row">
+ <c:forEach var="category" items="${categories}">
+ <div class="col-sm-4">
+ <a href="${category[0]}.html"><i class="fa ${category[3]} fa-fw fa-4x" aria-hidden="true"></i> <h2>${category[1]}</h2> <p>${category[2]}</p></a>
+ </div>
+ </c:forEach>
</div>
</div>
- <div class="bottom" id="bottom">
- <%@ include file="footer.jsp"%>
+
+ <div class="container">
+ <p><a href="?page=about&sub=contact" target="_blank">Let us know</a> if we're missing anything, or if we should measure something else.</p>
</div>
-</body>
-</html>
+
+<jsp:include page="bottom.jsp"/>
diff --git a/website/web/WEB-INF/top.jsp b/website/web/WEB-INF/top.jsp
new file mode 100644
index 0000000..93397f0
--- /dev/null
+++ b/website/web/WEB-INF/top.jsp
@@ -0,0 +1,125 @@
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
+<!DOCTYPE HTML>
+<html lang="en" style="min-height:100%;">
+<head>
+
+ <title>${param.pageTitle}</title>
+
+ <meta charset="utf-8">
+ <link href="images/favicon.ico" type="image/x-icon" rel="shortcut icon">
+
+ <!-- yes, we are handheld friendly :) -->
+ <meta name="HandheldFriendly" content="True">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+
+ <!-- icons for mobile devices -->
+ <link rel="apple-touch-icon" href="images/apple-touch-icon-152x152.png">
+ <link rel="shortcut icon" href="images/android-icon.png" sizes="196x196">
+ <meta name="msapplication-square70x70logo" content="images/smalltile.png">
+ <meta name="msapplication-square150x150logo" content="images/mediumtile.png">
+ <meta name="msapplication-wide310x150logo" content="images/widetile.png">
+ <meta name="msapplication-square310x310logo" content="images/largetile.png">
+
+ <!-- jQuery -->
+ <script src="js/jquery-3.1.1.min.js"></script>
+
+ <!-- Bootstrap -->
+ <link rel="stylesheet" href="css/bootstrap.min.css">
+ <script src="js/bootstrap.min.js"></script>
+
+ <!-- Fonts -->
+ <link rel="stylesheet" href="css/font-awesome.min.css">
+ <link rel="stylesheet" href="fonts/source-sans-pro.css">
+
+ <!-- custom styles and javascript -->
+ <link rel="stylesheet" href="css/style.css">
+ <script src="js/script.js"></script>
+
+</head>
+
+<body class="noscript" style="background-image:url(images/ajax-loader.gif);background-repeat:no-repeat;background-position:center center;">
+
+<!-- Using evil inline stylesheets to hide the FOUC for slow connections... -->
+
+<div id="wrapper" style="display:none;">
+
+<!-- backToTop-Button and Anchor -->
+<noscript>
+<div class="topButton" style="display:block;"><a href="#top"><i class="fa fa-chevron-up" aria-hidden="true"></i></a></div>
+</noscript>
+<script type="text/javascript">
+document.write('<div class="topButton" style="display:none;"><a href="#top"><i class="fa fa-chevron-up" aria-hidden="true"></i></a></div>');
+</script>
+<a name="top" id="anchor-top"></a>
+
+<!-- secondary navigation -->
+<nav class="navbar navbar-default navbar-secondary">
+ <div class="container-fluid">
+ <input type="checkbox" id="navbar-toggle-checkbox">
+ <div class="navbar-header">
+ <label for="navbar-toggle-checkbox" type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-secondary" aria-expanded="false">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </label>
+ <a class="navbar-brand visible-xs" href="index.html"><img src="images/metrics-wordmark-white.png" width="384" height="50" alt="Tor Metrics"></a>
+ </div>
+
+ <!-- Collect the nav links, forms, and other content for toggling -->
+ <div class="collapse navbar-collapse" id="bs-example-navbar-secondary">
+ <ul class="nav navbar-nav navbar-right">
+
+ <!-- we have to copy the primary navigation items here for mobile accessibility -->
+ <li class="visible-xs<c:if test="${'Home'.equals(param.navActive)}"> active</c:if>"><a href="index.html"><i class="fa fa-home fa-fw" aria-hidden="true"></i> Home</a></li>
+ <c:forEach var="category" items="${categories}">
+ <li class="visible-xs<c:if test="${category[1].equals(param.navActive)}"> active</c:if>"><a href="${category[0]}.html"><i class="fa ${category[3]} fa-fw" aria-hidden="true"></i> ${category[1]}</a></li>
+ </c:forEach>
+ <!-- /end of primary copy -->
+
+ <!-- secondary navigation items -->
+ <li <c:if test="${'News'.equals(param.navActive)}"> class="active"</c:if>><a href="news.html"><i class="fa fa-newspaper-o fa-fw" aria-hidden="true"></i> News</a></li>
+ <li <c:if test="${'Sources'.equals(param.navActive)}"> class="active"</c:if>><a href="sources.html"><i class="fa fa-archive fa-fw" aria-hidden="true"></i> Sources</a></li>
+ <li <c:if test="${'Operation'.equals(param.navActive)}"> class="active"</c:if>><a href="operation.html"><i class="fa fa-cogs fa-fw" aria-hidden="true"></i> Operation</a></li>
+ <li <c:if test="${'Development'.equals(param.navActive)}"> class="active"</c:if>><a href="development.html"><i class="fa fa-code fa-fw" aria-hidden="true"></i> Development</a></li>
+ <li <c:if test="${'Research'.equals(param.navActive)}"> class="active"</c:if>><a href="research.html"><i class="fa fa-university fa-fw" aria-hidden="true"></i> Research</a></li>
+ <li <c:if test="${'About'.equals(param.navActive)}"> class="active"</c:if>><a href="about.html"><i class="fa fa-lightbulb-o fa-fw" aria-hidden="true"></i> About</a></li>
+ <!-- /secondary navigation items -->
+
+ </ul>
+ </div><!-- /.navbar-collapse -->
+ </div><!-- /.container-fluid -->
+</nav>
+<!-- /secondary navigation -->
+
+<!-- page header for every single page -->
+<div class="page-header hidden-xs">
+ <a href="index.html"><img src="images/metrics-logo.png" width="102" height="133" alt="" id="metrics-logo"></a>
+ <a href="index.html"><img src="images/metrics-wordmark-white.png" width="384" height="50" alt="Tor Metrics" id="metrics-wordmark"></a>
+ <div>
+ <p>
+ <i>“Tor metrics are the ammunition that lets Tor and other security advocates argue for a more private and secure Internet from a position of data, rather than just dogma or perspective.”</i><br>
+ –Bruce Schneier (June 1, 2016)
+ </p>
+ </div>
+ <div class="clearfix"></div>
+</div>
+<!-- /page header -->
+
+<!-- primary navigation -->
+<nav class="navbar navbar-default hidden-xs">
+ <div class="container-fluid">
+ <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-primary">
+ <ul class="nav navbar-nav">
+ <li <c:if test="${'Home'.equals(param.navActive)}"> class="active"</c:if>><a href="index.html"><i class="fa fa-home fa-fw hidden-sm" aria-hidden="true"></i> Home</a></li>
+ <c:forEach var="category" items="${categories}">
+ <li <c:if test="${category[1].equals(param.navActive)}"> class="active"</c:if>><a href="${category[0]}.html"><i class="fa ${category[3]} fa-fw hidden-sm" aria-hidden="true"></i> ${category[1]}</a></li>
+ </c:forEach>
+ </ul>
+ </div><!-- /.navbar-collapse -->
+ </div><!-- /.container-fluid -->
+</nav>
+<!-- /primary navigation -->
+
1
0

09 Jan '17
commit 57893aed03d1d3dcb09b1845e5de89fa72cbd04b
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Tue Dec 20 23:27:09 2016 +0100
Apply new design to research page.
---
.../torproject/metrics/web/ResearchServlet.java | 9 +-
website/web/WEB-INF/research.jsp | 103 +++++++++------------
2 files changed, 50 insertions(+), 62 deletions(-)
diff --git a/website/src/org/torproject/metrics/web/ResearchServlet.java b/website/src/org/torproject/metrics/web/ResearchServlet.java
index ed415b7..e847ebe 100644
--- a/website/src/org/torproject/metrics/web/ResearchServlet.java
+++ b/website/src/org/torproject/metrics/web/ResearchServlet.java
@@ -6,19 +6,24 @@ package org.torproject.metrics.web;
import java.io.IOException;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-public class ResearchServlet extends HttpServlet {
+public class ResearchServlet extends AnyServlet {
private static final long serialVersionUID = 7380914323836427960L;
@Override
+ public void init() throws ServletException {
+ super.init();
+ }
+
+ @Override
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
/* Forward the request to the JSP that does all the hard work. */
+ request.setAttribute("categories", this.categories);
request.getRequestDispatcher("WEB-INF/research.jsp").forward(request,
response);
}
diff --git a/website/web/WEB-INF/research.jsp b/website/web/WEB-INF/research.jsp
index 901c3e1..3ec2e21 100644
--- a/website/web/WEB-INF/research.jsp
+++ b/website/web/WEB-INF/research.jsp
@@ -1,51 +1,32 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <title>Tor Metrics</title>
- <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
- <link href="css/stylesheet-ltr.css" type="text/css" rel="stylesheet">
- <link href="css/bootstrap.min.css" type="text/css" rel="stylesheet">
- <link href="images/favicon.ico" type="image/x-icon" rel="shortcut icon">
-</head>
-<body>
- <div class="center">
- <div class="main-column">
- <h2><a href="/"><img src="images/metrics-logo.png" width="153" height="200" alt="Metrics logo"><img src="images/metrics-wordmark.png" width="384" height="50" alt="Metrics wordmark"></a></h2>
- <br>
-
-<p>"Tor metrics are the ammunition that lets Tor and other security
-advocates argue for a more private and secure Internet from a position
-of data, rather than just dogma or perspective."
-<i>- Bruce Schneier (June 1, 2016)</i></p>
-
- <!-- Navigation start -->
- <a href="index.html">Metrics</a> |
- <a href="about.html">About</a> |
- <a href="news.html">News</a> |
- <a href="tools.html">Tools</a> |
- Research
- <br>
- <br>
- <!-- Navigation end -->
-
-<h1>Research</h1>
-<br>
-
-<p>Tor started out as a research project! We encourage research on all things
-Tor.</p>
-
-<p>Look around the papers section below for some ideas on what others have
-researched in the past. Contact <some general email list here, torproject?> if
-you want to discuss ideas.</p>
-
-<h2>Feel free to use our data for your research!</h2>
-
-<p>If you do, please cite https://metrics.torproject.org/ or the following <a
-href="http://freehaven.net/anonbib/#wecsr10measuring-tor">paper</a>:</p>
-
-<pre>
+<jsp:include page="top.jsp">
+ <jsp:param name="pageTitle" value="Research – Tor Metrics"/>
+ <jsp:param name="navActive" value="Research"/>
+</jsp:include>
+
+ <div class="container">
+ <ul class="breadcrumb">
+ <li><a href="index.html">Home</a></li>
+ <li class="active">Research</li>
+ </ul>
+ </div>
+
+ <div class="container">
+ <h1>Research</h1>
+ <p>Tor started out as a research project! We encourage research on all things Tor.</p>
+ <p>Look around the papers section below for some ideas on what others have researched in the past. Contact <a href="mailto:#">[some general email list here, torproject?]</a> if you want to discuss ideas.</p>
+
+ </div>
+
+ <div class="container">
+
+ <a name="use" id="anchor-use"></a>
+
+ <h2>Feel free to use our data for your research!</h2>
+
+ <p>If you do, please cite <a href="https://metrics.torproject.org/" target="_self">https://metrics.torproject.org/</a> or the following <a href="http://freehaven.net/anonbib/#wecsr10measuring-tor" target="_blank">paper</a>:</p>
+ <p><pre>
@inproceedings{wecsr10measuring-tor,
title = {A Case Study on Measuring Statistical Data in the {T}or Anonymity Network},
author = {Karsten Loesing and Steven J. Murdoch and Roger Dingledine},
@@ -55,25 +36,27 @@ href="http://freehaven.net/anonbib/#wecsr10measuring-tor">paper</a>:</p>
location = {Tenerife, Canary Islands, Spain},
publisher = {Springer},
series = {LNCS},
-}
-</pre>
+}</pre></p>
+ <p>Thank you for acknowledging this work through a citation.</p>
+
+ </div>
-<p>Thank you for acknowledging this work through a citation.</p>
+ <div class="container">
-<h2>Want to collect your own data for research?</h2>
+ <a name="collect" id="anchor-collect"></a>
+ <h2>Want to collect your own data for research?</h2>
+ <p>Look at the <a href="sources.html">sources page</a> for services that collect Tor-related data.</p>
+
+ </div>
-<p>Look at the <a href="tools.html">tools pages</a> for services that collect
-Tor-related data.</p>
-<h2>Research Papers</h2>
+ <div class="container">
-<p>Here are some Tor-related papers. (...)</p>
+ <a name="research" id="anchor-research"></a>
+ <h2>Research Papers</h2>
+ <p>Here are some Tor-related papers. (...) If we're missing yours, let us know!</p>
</div>
- </div>
- <div class="bottom" id="bottom">
- <%@ include file="footer.jsp"%>
- </div>
-</body>
-</html>
+
+<jsp:include page="bottom.jsp"/>
1
0
commit 9ab2682015fde45fa53e2fa9954468c9c2dac145
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Tue Dec 20 15:07:22 2016 +0100
Include jQuery 3.1.1.
---
website/web/js/jquery-3.1.1.min.js | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/website/web/js/jquery-3.1.1.min.js b/website/web/js/jquery-3.1.1.min.js
new file mode 100644
index 0000000..4c5be4c
--- /dev/null
+++ b/website/web/js/jquery-3.1.1.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v3.1.1 | (c) jQuery Foundation | jquery.org/license */
+!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){retu
rn r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:funct
ion(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b
||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=
!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>
+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-
1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=
b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a
){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return
a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TA
G=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='dis
abled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition
(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.discon
nectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[
d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+"
"];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[
m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):fu
nction(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},em
pty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b
]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLower
Case())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b
,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);
if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortSta
ble=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c
;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):C.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=t
his.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:par
ents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){retu
rn y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/[^\x20\t\r\n\f]+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e
=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b
,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=
function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?v
oid 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a
!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),
+a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,
b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:X.test(a)?JSON.parse(a):a)}function $(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=Z(c)}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.h
asData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),$(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=$(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var
c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=V.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.pro
mise(b)}});var _=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,aa=new RegExp("^(?:([+-])=|)("+_+")([a-z%]*)$","i"),ba=["Top","Right","Bottom","Left"],ca=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},da=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function ea(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&aa.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var fa={};function ga(a){var b,c=a.ownerDocument,d=a.nodeName,e=fa[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&
&(e="block"),fa[d]=e,e)}function ha(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=V.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&ca(d)&&(e[f]=ga(d))):"none"!==c&&(e[f]="none",V.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ha(this,!0)},hide:function(){return ha(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){ca(this)?r(this).show():r(this).hide()})}});var ia=/^(?:checkbox|radio)$/i,ja=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,ka=/^$|\/(?:java|ecma)script/i,la={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};la.optgroup=la.option,la.tbody=la.tfoot=la.colgroup=la.caption=la.thead,la.th=la.td
;function ma(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function na(a,b){for(var c=0,d=a.length;c<d;c++)V.set(a[c],"globalEval",!b||V.get(b[c],"globalEval"))}var oa=/<|&#?\w+;/;function pa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(oa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ja.exec(f)||["",""])[1].toLowerCase(),i=la[h]||la._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=ma(l.appendChild(f),"script"),j&&na(g),c){k=0;while(f=g[k++])ka.test(f.type||"")
&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var qa=d.documentElement,ra=/^key/,sa=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ta=/^([^.]*)(?:\.(.+)|)/;function ua(){return!0}function va(){return!1}function wa(){try{return d.activeElement}catch(a){}}function xa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)xa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=va;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(f
unction(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(qa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:fu
nction(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDis
patch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.
defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==wa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===wa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&r.nodeName(this,"input"))return this.click(),!1},_default:function(a){return r.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this
instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ua:va,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:va,isPropagationStopped:va,isImmediatePropagationStopped:va,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ua,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ua,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ua,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,
bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&ra.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&sa.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return xa(this,a,b,c,d)},one:function(a,b,c,d){return xa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.
preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=va),this.each(function(){r.event.remove(this,a,c,b)})}});var ya=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,za=/<script|<style|<link/i,Aa=/checked\s*(?:[^=]|=\s*.checked.)/i,Ba=/^true\/(.*)/,Ca=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Da(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Ea(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Fa(a){var b=Ba.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ga(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.event
s={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ha(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ia.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ia(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Aa.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ia(f,b,c,d)});if(m&&(e=pa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(ma(e,"script"),Ea),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,ma(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Fa),l=0;l<i;l++)j=h[l],ka.test(j.type||"")&&!V.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ca,""),k))}return a}function Ja(a,b,c){for(var
d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(ma(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&na(ma(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(ya,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=ma(h),f=ma(a),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);if(b)if(c)for(f=f||ma(a),g=g||ma(h),d=0,e=f.length;d<e;d++)Ga(f[d],g[d]);else Ga(a,h);return g=ma(h,"script"),g.length>0&&na(g,!i&&ma(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ja(this,a,!0)},remove:function(a){return Ja(this,a)},text:function(a){return S(this,fu
nction(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.appendChild(a)}})},prepend:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(ma(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,funct
ion(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!za.test(a)&&!la[(ja.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(ma(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ia(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(ma(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ka=/^margin/,La=new RegExp("^("+_+")(?!px)[a-z%]+$","i"),Ma=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.styl
e.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",qa.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,qa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Na(a,b,c){var d,e,f,g,h=a.style;return c=c||Ma(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight(
)&&La.test(g)&&Ka.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Oa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Pa=/^(none|table(?!-c[ea]).+)/,Qa={position:"absolute",visibility:"hidden",display:"block"},Ra={letterSpacing:"0",fontWeight:"400"},Sa=["Webkit","Moz","ms"],Ta=d.createElement("div").style;function Ua(a){if(a in Ta)return a;var b=a[0].toUpperCase()+a.slice(1),c=Sa.length;while(c--)if(a=Sa[c]+b,a in Ta)return a}function Va(a,b,c){var d=aa.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Wa(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ba[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ba[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ba[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ba[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ba[f]+"Width"
,!0,e)));return g}function Xa(a,b,c){var d,e=!0,f=Ma(a),g="border-box"===r.css(a,"boxSizing",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),d<=0||null==d){if(d=Na(a,b,f),(d<0||null==d)&&(d=a.style[b]),La.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Wa(a,b,c||(g?"border":"content"),e,f)+"px"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Na(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ua(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=aa.exec(c))&&e[1]&&(c=ea(a,b,e),f="number"),null!=c&
&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ua(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Na(a,b,d)),"normal"===e&&b in Ra&&(e=Ra[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Pa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?Xa(a,b,d):da(a,Qa,function(){return Xa(a,b,d)})},set:function(a,c,d){var e,f=d&&Ma(a),g=d&&Wa(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=aa.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Va(a,c,g)}}}),r.cssHooks.marginLeft=Oa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Na(a,"marginLeft"))||a.getBoun
dingClientRect().left-da(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ba[d]+b]=f[d]||f[d-2]||f[0];return e}},Ka.test(a)||(r.cssHooks[a+b].set=Va)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=Ma(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Ya(a,b,c,d,e){return new Ya.prototype.init(a,b,c,d,e)}r.Tween=Ya,Ya.prototype={constructor:Ya,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Ya.propHooks[this.prop];return a&&a.get?a.get(this):Ya.propHooks._default.get(this)},run:function(a){var b,c=Ya.propHo
oks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ya.propHooks._default.set(this),this}},Ya.prototype.init.prototype=Ya.prototype,Ya.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Ya.propHooks.scrollTop=Ya.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Ya.prototype.init,r.fx.s
tep={};var Za,$a,_a=/^(?:toggle|show|hide)$/,ab=/queueHooks$/;function bb(){$a&&(a.requestAnimationFrame(bb),r.fx.tick())}function cb(){return a.setTimeout(function(){Za=void 0}),Za=r.now()}function db(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ba[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function eb(a,b,c){for(var d,e=(hb.tweeners[b]||[]).concat(hb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function fb(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&ca(a),q=V.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],_a.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmpty
Object(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ha([a],!0),j=a.style.display||j,k=r.css(a,"display"),ha([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=V.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ha([a],!0),m.done(function(){p||ha([a]),V.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=eb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function gb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expan
d"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function hb(a,b,c){var d,e,f=0,g=hb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Za||cb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Za||cb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(gb(k,j.opts.specialEasing);f<g;f++)if(d=hb.prefilters[f].call(j,a,k,j.
opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,eb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(hb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return ea(c.elem,a,aa.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(K);for(var c,d=0,e=a.length;d<e;d++)c=a[d],hb.tweeners[c]=hb.tweeners[c]||[],hb.tweeners[c].unshift(b)},prefilters:[fb],prefilter:function(a,b){b?hb.prefilters.unshift(a):hb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:"number"!=typeof e.duration&&(e.duration in r.fx.speeds?e.duration=r.fx.speeds[e.duration]:e.dur
ation=r.fx.speeds._default),null!=e.queue&&e.queue!==!0||(e.queue="fx"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ca).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=hb(this,r.extend({},a),f);(e||V.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&ab.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return
a!==!1&&(a=a||"fx"),this.each(function(){var b,c=V.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(db(b,!0),a,d,e)}}),r.each({slideDown:db("show"),slideUp:db("hide"),slideToggle:db("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Za=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),Za=void 0},r.fx.timer=function(a){r.timers.push(a),a()?r.fx.start():r.timers.pop()},r.fx.interval=13
,r.fx.start=function(){$a||($a=a.requestAnimationFrame?a.requestAnimationFrame(bb):a.setInterval(r.fx.tick,r.fx.interval))},r.fx.stop=function(){a.cancelAnimationFrame?a.cancelAnimationFrame($a):a.clearInterval($a),$a=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var ib,jb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return S(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop
(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?ib:void 0)),
+void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),ib={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=jb[b]||r.find.attr;jb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=jb[g],jb[g]=e,e=null!=c(a,b,d)?g:null,jb[g]=f),e}});var kb=/^(?:input|select|textarea|button)$/i,lb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var
d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):kb.test(a.nodeName)||lb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function mb(a){var b=a.match(K)||[];return b.join(" ")}function nb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if
(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,nb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,nb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,nb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r
(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=nb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(nb(c))+" ").indexOf(b)>-1)return!0;return!1}});var ob=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(ob,""):null==c?"":c)}}}),r
.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:mb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespac
e.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(
),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={
setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":
c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ia.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.to
LowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.convert
ers[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"t
ext html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e
&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,"$1"),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modifi
ed-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&
(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,
this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&
&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a)
{a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Qb=[],Rb=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Qb.pop()||r.expando+"_"+rb++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Rb.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&
&Rb.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Rb,"$1"+e):b.jsonp!==!1&&(b.url+=(sb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Qb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=B.exec(a),g=!c&&[],f?[b.createElement(f[1])
]:(f=pa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=mb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length};function Sb(a){return r.isWindow(a)?a:9===a.nodeType&&a.defaultView}r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"
===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),d.width||d.height?(e=f.ownerDocument,c=Sb(e),b=e.documentElement,{top:d.top+c.pageYOffset-b.clientTop,left:d.left+c.pageXOffset-b.clientLeft}):d):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),r.nodeName(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left
:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||qa})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return S(this,function(a,d,e){var f=Sb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Oa(o.pixelPosition,function(a,c){if(c)return c=Na(a,b),La.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return S(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.d
ocumentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.parseJSON=JSON.parse,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Tb=a.jQuery,Ub=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Ub),b&&a.jQuery===r&&(a.jQuery=Tb),r},b||(a.jQuery=a.$=r),r});
1
0
commit 774d428699cf681abc47c1e4442746b5c766f1b5
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Dec 14 20:32:46 2016 +0100
Remove Sources page.
---
website/etc/web.xml | 11 ------
.../org/torproject/metrics/web/SourcesServlet.java | 26 -------------
website/web/WEB-INF/about.jsp | 1 -
website/web/WEB-INF/graph.jsp | 1 -
website/web/WEB-INF/index.jsp | 1 -
website/web/WEB-INF/link.jsp | 1 -
website/web/WEB-INF/news.jsp | 1 -
website/web/WEB-INF/research.jsp | 1 -
website/web/WEB-INF/sources.jsp | 44 ----------------------
website/web/WEB-INF/table.jsp | 1 -
website/web/WEB-INF/tools.jsp | 1 -
11 files changed, 89 deletions(-)
diff --git a/website/etc/web.xml b/website/etc/web.xml
index 17f6901..0e9011a 100644
--- a/website/etc/web.xml
+++ b/website/etc/web.xml
@@ -221,17 +221,6 @@
</servlet-mapping>
<servlet>
- <servlet-name>SourcesServlet</servlet-name>
- <servlet-class>
- org.torproject.metrics.web.SourcesServlet
- </servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>SourcesServlet</servlet-name>
- <url-pattern>/sources.html</url-pattern>
- </servlet-mapping>
-
- <servlet>
<servlet-name>ToolsServlet</servlet-name>
<servlet-class>
org.torproject.metrics.web.ToolsServlet
diff --git a/website/src/org/torproject/metrics/web/SourcesServlet.java b/website/src/org/torproject/metrics/web/SourcesServlet.java
deleted file mode 100644
index 98e37d1..0000000
--- a/website/src/org/torproject/metrics/web/SourcesServlet.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright 2016 The Tor Project
- * See LICENSE for licensing information */
-
-package org.torproject.metrics.web;
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-public class SourcesServlet extends HttpServlet {
-
- private static final long serialVersionUID = 8809159168990390124L;
-
- @Override
- public void doGet(HttpServletRequest request,
- HttpServletResponse response) throws IOException, ServletException {
-
- /* Forward the request to the JSP that does all the hard work. */
- request.getRequestDispatcher("WEB-INF/sources.jsp").forward(request,
- response);
- }
-}
-
diff --git a/website/web/WEB-INF/about.jsp b/website/web/WEB-INF/about.jsp
index f16a114..3e8a309 100644
--- a/website/web/WEB-INF/about.jsp
+++ b/website/web/WEB-INF/about.jsp
@@ -22,7 +22,6 @@ of data, rather than just dogma or perspective."
<a href="index.html">Metrics</a> |
About |
<a href="news.html">News</a> |
- <a href="sources.html">Sources</a> |
<a href="tools.html">Tools</a> |
<a href="research.html">Research</a>
<br>
diff --git a/website/web/WEB-INF/graph.jsp b/website/web/WEB-INF/graph.jsp
index aab373a..133fd80 100644
--- a/website/web/WEB-INF/graph.jsp
+++ b/website/web/WEB-INF/graph.jsp
@@ -24,7 +24,6 @@ of data, rather than just dogma or perspective."
Metrics |
<a href="about.html">About</a> |
<a href="news.html">News</a> |
- <a href="sources.html">Sources</a> |
<a href="tools.html">Tools</a> |
<a href="research.html">Research</a>
<br>
diff --git a/website/web/WEB-INF/index.jsp b/website/web/WEB-INF/index.jsp
index 3e0d03a..55c882a 100644
--- a/website/web/WEB-INF/index.jsp
+++ b/website/web/WEB-INF/index.jsp
@@ -24,7 +24,6 @@ of data, rather than just dogma or perspective."
Metrics |
<a href="about.html">About</a> |
<a href="news.html">News</a> |
- <a href="sources.html">Sources</a> |
<a href="tools.html">Tools</a> |
<a href="research.html">Research</a>
<br>
diff --git a/website/web/WEB-INF/link.jsp b/website/web/WEB-INF/link.jsp
index 096fddb..efff3b4 100644
--- a/website/web/WEB-INF/link.jsp
+++ b/website/web/WEB-INF/link.jsp
@@ -24,7 +24,6 @@ of data, rather than just dogma or perspective."
Metrics |
<a href="about.html">About</a> |
<a href="news.html">News</a> |
- <a href="sources.html">Sources</a> |
<a href="tools.html">Tools</a> |
<a href="research.html">Research</a>
<br>
diff --git a/website/web/WEB-INF/news.jsp b/website/web/WEB-INF/news.jsp
index b99e260..fa9eb13 100644
--- a/website/web/WEB-INF/news.jsp
+++ b/website/web/WEB-INF/news.jsp
@@ -24,7 +24,6 @@ of data, rather than just dogma or perspective."
<a href="index.html">Metrics</a> |
<a href="about.html">About</a> |
News |
- <a href="sources.html">Sources</a> |
<a href="tools.html">Tools</a> |
<a href="research.html">Research</a>
<br>
diff --git a/website/web/WEB-INF/research.jsp b/website/web/WEB-INF/research.jsp
index 52fd50e..2acff3d 100644
--- a/website/web/WEB-INF/research.jsp
+++ b/website/web/WEB-INF/research.jsp
@@ -24,7 +24,6 @@ of data, rather than just dogma or perspective."
<a href="index.html">Metrics</a> |
<a href="about.html">About</a> |
<a href="news.html">News</a> |
- <a href="sources.html">Sources</a> |
<a href="tools.html">Tools</a> |
Research
<br>
diff --git a/website/web/WEB-INF/sources.jsp b/website/web/WEB-INF/sources.jsp
deleted file mode 100644
index dc53c52..0000000
--- a/website/web/WEB-INF/sources.jsp
+++ /dev/null
@@ -1,44 +0,0 @@
-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <title>Tor Metrics</title>
- <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
- <link href="css/stylesheet-ltr.css" type="text/css" rel="stylesheet">
- <link href="css/bootstrap.min.css" type="text/css" rel="stylesheet">
- <link href="images/favicon.ico" type="image/x-icon" rel="shortcut icon">
-</head>
-<body>
- <div class="center">
- <div class="main-column">
- <h2><a href="/"><img src="images/metrics-logo.png" width="153" height="200" alt="Metrics logo"><img src="images/metrics-wordmark.png" width="384" height="50" alt="Metrics wordmark"></a></h2>
- <br>
-
-<p>"Tor metrics are the ammunition that lets Tor and other security
-advocates argue for a more private and secure Internet from a position
-of data, rather than just dogma or perspective."
-<i>- Bruce Schneier (June 1, 2016)</i></p>
-
- <!-- Navigation start -->
- <a href="index.html">Metrics</a> |
- <a href="about.html">About</a> |
- <a href="news.html">News</a> |
- Sources |
- <a href="tools.html">Tools</a> |
- <a href="research.html">Research</a>
- <br>
- <br>
- <!-- Navigation end -->
-
-<h3>Sources</h3>
-<br>
-
- </div>
- </div>
- <div class="bottom" id="bottom">
- <%@ include file="footer.jsp"%>
- </div>
-</body>
-</html>
-
diff --git a/website/web/WEB-INF/table.jsp b/website/web/WEB-INF/table.jsp
index 1e867a8..ab91db7 100644
--- a/website/web/WEB-INF/table.jsp
+++ b/website/web/WEB-INF/table.jsp
@@ -24,7 +24,6 @@ of data, rather than just dogma or perspective."
Metrics |
<a href="about.html">About</a> |
<a href="news.html">News</a> |
- <a href="sources.html">Sources</a> |
<a href="tools.html">Tools</a> |
<a href="research.html">Research</a>
<br>
diff --git a/website/web/WEB-INF/tools.jsp b/website/web/WEB-INF/tools.jsp
index c1a2512..b68d6ba 100644
--- a/website/web/WEB-INF/tools.jsp
+++ b/website/web/WEB-INF/tools.jsp
@@ -24,7 +24,6 @@ of data, rather than just dogma or perspective."
<a href="index.html">Metrics</a> |
<a href="about.html">About</a> |
<a href="news.html">News</a> |
- <a href="sources.html">Sources</a> |
Tools |
<a href="research.html">Research</a>
<br>
1
0

09 Jan '17
commit fb496966a7f5500db4e97625670d318912ee2380
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Dec 21 12:45:22 2016 +0100
Apply new design to bubbles page.
---
.../metrics/web/graphs/BubblesServlet.java | 35 ++++++++++--
website/web/WEB-INF/bubbles.jsp | 64 +++++++++++++---------
2 files changed, 70 insertions(+), 29 deletions(-)
diff --git a/website/src/org/torproject/metrics/web/graphs/BubblesServlet.java b/website/src/org/torproject/metrics/web/graphs/BubblesServlet.java
index c990eac..685f30c 100644
--- a/website/src/org/torproject/metrics/web/graphs/BubblesServlet.java
+++ b/website/src/org/torproject/metrics/web/graphs/BubblesServlet.java
@@ -3,22 +3,49 @@
package org.torproject.metrics.web.graphs;
+import org.torproject.metrics.web.Category;
+import org.torproject.metrics.web.MetricServlet;
+
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-public class BubblesServlet extends HttpServlet {
+public class BubblesServlet extends MetricServlet {
private static final long serialVersionUID = -6011833075497881033L;
@Override
+ public void init() throws ServletException {
+ super.init();
+ }
+
+ @Override
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
-
- /* Forward the request to the JSP that does all the hard work. */
+ String requestUri = request.getRequestURI();
+ if (requestUri == null || !requestUri.endsWith(".html")) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+ String requestedId = requestUri.substring(
+ requestUri.contains("/") ? requestUri.lastIndexOf("/") + 1 : 0,
+ requestUri.length() - 5);
+ request.setAttribute("categories", this.categories);
+ request.setAttribute("id", requestedId);
+ if (this.categoriesById.containsKey(requestedId)) {
+ Category category = this.categoriesById.get(requestedId);
+ request.setAttribute("categoryHeader", category.getHeader());
+ request.setAttribute("categoryDescription", category.getDescription());
+ List<String[]> categoryTabs = new ArrayList<String[]>();
+ for (String metricId : category.getMetrics()) {
+ categoryTabs.add(new String[] { this.titles.get(metricId), metricId });
+ }
+ request.setAttribute("categoryTabs", categoryTabs);
+ }
request.getRequestDispatcher("WEB-INF/bubbles.jsp").forward(request,
response);
}
diff --git a/website/web/WEB-INF/bubbles.jsp b/website/web/WEB-INF/bubbles.jsp
index 9edc575..70af5d0 100644
--- a/website/web/WEB-INF/bubbles.jsp
+++ b/website/web/WEB-INF/bubbles.jsp
@@ -1,21 +1,35 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <title>Tor Metrics — Network bubble graphs</title>
- <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
- <link href="css/stylesheet-ltr.css" type="text/css" rel="stylesheet">
- <link href="css/bootstrap.min.css" type="text/css" rel="stylesheet">
- <link href="images/favicon.ico" type="image/x-icon" rel="shortcut icon">
- <script src="js/d3.min.js"></script>
- <script src="js/bubbles.js"></script>
-</head>
-<body>
- <div class="center">
- <div class="main-column">
-
-<h2><a href="/"><img src="images/metrics-wordmark-small.png" width="138" height="18" alt="Metrics wordmark"></a> — Network bubble graphs</h2>
-<br>
+<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
+<jsp:include page="top.jsp">
+ <jsp:param name="pageTitle" value="${categoryHeader} – Tor Metrics"/>
+ <jsp:param name="navActive" value="${categoryHeader}"/>
+</jsp:include>
+
+ <div class="container">
+ <ul class="breadcrumb">
+ <li><a href="index.html">Home</a></li>
+ <li class="active">${categoryHeader}</li>
+ </ul>
+ </div>
+
+ <div class="container">
+ <h1>${categoryHeader}</h1>
+ <p>${categoryDescription}</p>
+ </div>
+
+ <div class="container">
+
+ <!-- tabs -->
+ <ul class="nav nav-tabs">
+ <c:forEach var="tab" items="${categoryTabs}">
+ <li role="presentation"<c:if test="${id.equals(tab[1])}"> class="active"</c:if>><a href="${tab[1]}.html" data-tab="${tab[1]}">${tab[0]}</a></li>
+ </c:forEach>
+ </ul>
+
+ <!-- tab-content -->
+ <div class="tab-content">
+ <div class="tab-pane active" id="tab-${tab[1]}">
+
<p>The following graph visualizes diversity of currently running
<a href="about.html#relay">relays</a> in terms of their probability to be
selected for <a href="about.html#circuit">circuits</a>.
@@ -48,14 +62,14 @@ information, country, or network family.</p>
<a href="#country-exits-only" onclick="make_bubble_graph('country-exits-only');">Country</a> |
<a href="#network-family-exits-only" onclick="make_bubble_graph('network-family-exits-only');">Network family (/16)</a>
</p>
+ <script src="js/d3.min.js"></script>
+ <script src="js/bubbles.js"></script>
<script>make_bubble_graph();</script>
- <noscript>Sorry, you need to turn on JavaScript.</script>
+ <noscript>Sorry, you need to turn on JavaScript.</noscript>
- </div>
- </div>
- <div class="bottom" id="bottom">
- <%@ include file="footer.jsp"%>
- </div>
-</body>
-</html>
+ </div>
+ </div><!-- tab-content -->
+ </div><!-- container -->
+
+<jsp:include page="bottom.jsp"/>
1
0