[tor-commits] [onionoo/master] Implements #19613: changed filestructure, added coverage task,

karsten at torproject.org karsten at torproject.org
Mon Jul 25 15:14:44 UTC 2016


commit 254824395abea80787ef06af32ae72d0f288c2d7
Author: iwakeh <iwakeh at torproject.org>
Date:   Thu Jul 21 15:13:16 2016 +0200

    Implements #19613: changed filestructure, added coverage task,
    updated some dependencies to current debian stable.
---
 build.xml                            |  160 ++-
 etc/context.xml.template             |    3 -
 etc/jetty.xml                        |   45 -
 etc/logback.xml                      |   82 --
 etc/web.xml.template                 |   78 --
 src/main/resources/context.xml       |    3 +
 src/main/resources/jetty.xml         |   45 +
 src/main/resources/logback.xml       |   82 ++
 src/main/resources/web.xml           |   78 ++
 src/main/resources/web/css/style.css |   36 +
 src/main/resources/web/favicon.ico   |  Bin 0 -> 1150 bytes
 src/main/resources/web/index.html    |  141 ++
 src/main/resources/web/protocol.html | 2338 ++++++++++++++++++++++++++++++++++
 src/main/resources/web/robots.txt    |    8 +
 web/css/style.css                    |   36 -
 web/favicon.ico                      |  Bin 1150 -> 0 bytes
 web/index.html                       |  141 --
 web/protocol.html                    | 2338 ----------------------------------
 web/robots.txt                       |    8 -
 19 files changed, 2840 insertions(+), 2782 deletions(-)

diff --git a/build.xml b/build.xml
index 467c991..7cfd870 100644
--- a/build.xml
+++ b/build.xml
@@ -5,21 +5,19 @@
             value="${onionoo.protocol.version}.0"/>
   <property name="descriptorversion" value="1.3.0"/>
   <property name="javasources" value="src/main/java"/>
-  <property name="tests" value="src/test/java"/>
-  <property name="generated" value="generated/"/>
-  <property name="classes" value="classes"/>
+  <property name="testsources" value="src/test/java"/>
+  <property name="generated" value="generated"/>
+  <property name="classes" value="${generated}/classes"/>
+  <property name="testclasses" value="${generated}/testclasses/"/>
+  <property name="resources" value="src/main/resources/"/>
   <property name="testresources" value="src/test/resources/"/>
-  <property name="dist" value="dist"/>
+  <property name="testresult" value="${generated}/test-results"/>
+  <property name="coverageresult" value="${generated}/coverage-report/"/>
+  <property name="instrument" value="${generated}/instrument/"/>
+  <property name="cobertura.ser.file" value="${basedir}/cobertura.ser" />
+  <property name="dist" value="${generated}/dist"/>
   <property name="docs" value="${generated}/javadoc/"/>
-  <property name="libs" value="lib"/>
-  <property name="config" value="etc"/>
-  <property name="webxmlfile" value="${config}/web.xml"/>
-  <property name="contextxmltemplate"
-            value="${config}/context.xml.template"/>
-  <property name="contextxml" value="${config}/context.xml"/>
-  <property name="webxmltemplate"
-            value="${config}/web.xml.template"/>
-  <property name="webxml" value="${config}/web.xml"/>
+  <property name="libs" value="${basedir}/lib"/>
   <property name="warfile"
             value="${dist}/onionoo-${release.version}.war"/>
   <property name="onionoo.jarfile"
@@ -28,13 +26,13 @@
 
   <patternset id="runtime" >
     <include name="descriptor-${descriptorversion}.jar"/>
-    <include name="commons-codec-1.6.jar"/>
-    <include name="commons-compress-1.4.1.jar"/>
-    <include name="commons-lang3-3.1.jar"/>
-    <include name="gson-2.1.jar"/>
-    <include name="logback-classic-1.0.4.jar"/>
-    <include name="logback-core-1.0.4.jar"/>
-    <include name="slf4j-api-1.6.5.jar"/>
+    <include name="commons-codec-1.9.jar"/>
+    <include name="commons-compress-1.9.jar"/>
+    <include name="commons-lang3-3.3.2.jar"/>
+    <include name="gson-2.2.4.jar"/>
+    <include name="logback-classic-1.1.2.jar"/>
+    <include name="logback-core-1.1.2.jar"/>
+    <include name="slf4j-api-1.7.7.jar"/>
   </patternset>
 
   <patternset id="web" >
@@ -52,7 +50,7 @@
   </patternset>
 
   <patternset id="test" >
-    <include name="junit4-4.10.jar"/>
+    <include name="junit4-4.11.jar"/>
     <include name="hamcrest-core-1.3.jar"/>
   </patternset>
 
@@ -62,13 +60,14 @@
       <patternset refid="runtime" />
       <patternset refid="web" />
     </fileset>
-    <fileset dir="${config}">
+    <fileset dir="${resources}">
       <include name="logback.xml,jetty.xml"/>
     </fileset>
   </path>
 
-  <path id="testclasspath">
+  <path id="test.classpath">
     <path refid="classpath" />
+    <pathelement path="${testclasses}"/>
     <fileset dir="${libs}">
       <patternset refid="runtime" />
       <patternset refid="test" />
@@ -82,20 +81,42 @@
     </fileset>
   </path>
 
+  <path id="cobertura.classpath">
+    <fileset dir="${libs}">
+      <include name="descriptor-${descriptorversion}.jar"/>
+      <include name="cobertura-2.1.1.jar" />
+      <include name="slf4j-api-1.7.7.jar" />
+      <include name="commons-lang3-3.3.2.jar" />
+      <include name="asm4-5.0.3.jar" />
+      <include name="asm4-util-5.0.3.jar" />
+      <include name="asm4-tree-5.0.3.jar" />
+      <include name="asm4-commons-5.0.3.jar" />
+      <include name="asm4-analysis-5.0.3.jar" />
+      <include name="oro-2.0.8.jar" />
+      <include name="logback-core-1.1.2.jar" />
+      <include name="logback-classic-1.1.2.jar" />
+    </fileset>
+  </path>
+
+  <path id="cobertura.test.classpath">
+    <path location="${instrument}" />
+    <path refid="test.classpath" />
+    <path refid="cobertura.classpath" />
+  </path>
+
   <target name="init">
-    <copy file="${contextxmltemplate}" tofile="${contextxml}"/>
-    <copy file="${webxmltemplate}" tofile="${webxml}"/>
     <mkdir dir="${classes}"/>
+    <mkdir dir="${testclasses}"/>
+    <mkdir dir="${testresult}"/>
     <mkdir dir="${docs}"/>
     <mkdir dir="${dist}"/>
-    <mkdir dir="${generated}"/>
   </target>
 
   <target name="clean" >
-    <delete includeEmptyDirs="true">
-      <fileset dir="${classes}" defaultexcludes="false" includes="**" />
-      <fileset dir="${dist}" defaultexcludes="false" includes="**" />
+    <delete includeEmptyDirs="true" quiet="true" >
+      <fileset dir="${generated}" defaultexcludes="false" includes="**" />
     </delete>
+    <delete file="${cobertura.ser.file}" quiet="true"/>
   </target>
 
   <target name="compile"
@@ -113,6 +134,20 @@
     </javac>
   </target>
 
+  <target name="compile-tests" depends="compile">
+    <javac destdir="${testclasses}"
+            srcdir="${testsources}"
+            source="${source-and-target-java-version}"
+            target="${source-and-target-java-version}"
+            debug="true" debuglevel="lines,source"
+            deprecation="true"
+            optimize="false"
+            failonerror="true"
+            includeantruntime="false">
+      <classpath refid="test.classpath"/>
+    </javac>
+  </target>
+
   <target name="docs" depends="init">
     <javadoc destdir="${docs}"
              footer="&copy; 2016 The Tor Project"
@@ -124,23 +159,12 @@
     </javadoc>
   </target>
 
-  <target name="test" depends="compile">
-    <javac destdir="${classes}"
-           srcdir="${tests}"
-           source="${source-and-target-java-version}"
-           target="${source-and-target-java-version}"
-           debug="true"
-           deprecation="true"
-           optimize="false"
-           failonerror="true"
-           includeantruntime="false">
-      <classpath refid="testclasspath" />
-    </javac>
-    <junit fork="true" haltonfailure="true" printsummary="off">
-      <classpath refid="testclasspath" />
+  <target name="test" depends="compile,compile-tests">
+    <junit fork="true" haltonfailure="true" printsummary="on">
+      <classpath refid="test.classpath" />
       <formatter type="plain" usefile="false"/>
       <batchtest>
-        <fileset dir="${classes}"
+        <fileset dir="${testclasses}"
                  includes="**/*Test.class"/>
       </batchtest>
     </junit>
@@ -165,8 +189,8 @@
   <target name="war"
           depends="compile">
     <war destfile="${warfile}"
-         webxml="${webxmlfile}">
-      <fileset dir="web"/>
+         webxml="${resources}/web.xml">
+      <fileset dir="${resources}/web"/>
       <restrict>
         <not>
           <name name="META-INF/*" />
@@ -183,14 +207,14 @@
       <fileset dir="${classes}"
                includes="**/*"
                excludes="**/Test*.class"/>
-      <fileset dir="${config}" includes="jetty.xml" />
-      <zipfileset dir="${config}"
+      <fileset dir="${resources}" includes="jetty.xml" />
+      <zipfileset dir="${resources}"
                   prefix=""
                   includes="logback.xml"/>
-      <zipfileset dir="${config}"
+      <zipfileset dir="${resources}"
                   prefix="WEB-INF/classes"
                   includes="logback.xml"/>
-      <metainf dir="${config}"
+      <metainf dir="${resources}"
                includes="context.xml"/>
       <manifest>
         <attribute name="Created-By" value="The Tor Project" />
@@ -222,7 +246,7 @@
       </restrict>
       <fileset dir="${classes}"
                excludes="org/torproject/onionoo/server/" />
-      <fileset dir="${config}" includes="logback.xml" />
+      <fileset dir="${resources}" includes="logback.xml" />
       <exclude name="**/Test*.class"/>
       <manifest>
         <attribute name="Created-By" value="The Tor Project" />
@@ -239,5 +263,39 @@
 
   <target name="dist" depends="test, war, jar"/>
 
+  <taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
+  <target name="coverage" depends="compile,compile-tests">
+    <copy todir="${instrument}" >
+      <fileset dir="${classes}" >
+       <include name="**/*"/>
+      </fileset>
+    </copy>
+    <cobertura-instrument ignoreTrivial="true">
+      <fileset dir="${instrument}">
+        <include name="**/**/*.class" />
+      </fileset>
+    </cobertura-instrument>
+    <junit fork="true" haltonfailure="false" printsummary="on">
+      <sysproperty key="net.sourceforge.cobertura.datafile"
+                   file="${cobertura.ser.file}" />
+      <classpath refid="cobertura.test.classpath" />
+      <formatter type="xml" />
+      <batchtest toDir="${testresult}" >
+        <fileset dir="${testclasses}" includes="**/*Test.class" />
+      </batchtest>
+    </junit>
+    <cobertura-report format="html" destdir="${coverageresult}" >
+      <fileset dir="${javasources}">
+        <include name="**/*.java" />
+      </fileset>
+    </cobertura-report>
+    <cobertura-check branchrate="0" linerate="0" totallinerate="34" totalbranchrate="30" >
+      <regex pattern="org.torproject.onionoo.server" branchrate="67" linerate="77"/>
+      <regex pattern="org.torproject.onionoo.docs" branchrate="19" linerate="29"/>
+      <regex pattern="org.torproject.onionoo.updater" branchrate="17" linerate="18"/>
+      <regex pattern="org.torproject.onionoo.writer" branchrate="22" linerate="20"/>
+    </cobertura-check>
+  </target>
+
 </project>
 
diff --git a/etc/context.xml.template b/etc/context.xml.template
deleted file mode 100644
index 09e5bac..0000000
--- a/etc/context.xml.template
+++ /dev/null
@@ -1,3 +0,0 @@
-<Context cookies="false">
-</Context>
-
diff --git a/etc/jetty.xml b/etc/jetty.xml
deleted file mode 100644
index c172902..0000000
--- a/etc/jetty.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
-  "http://www.eclipse.org/jetty/configure.dtd">
-
-<Configure id="server" class="org.eclipse.jetty.server.Server" >
-  <Set name="dumpAfterStart">false</Set>
-
-  <Set name="threadPool">
-    <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
-      <Set name="minThreads">25</Set>
-      <Set name="maxThreads">250</Set>
-      <Set name="detailedDump">false</Set>
-    </New>
-  </Set>
-
-  <New id="webAppContext" class="org.eclipse.jetty.webapp.WebAppContext">
-    <Set name="logUrlOnStart">true</Set>
-    <Set name="war">
-      <Call class="java.lang.System" name="getProperty">
-        <Arg>java.class.path</Arg>
-      </Call>
-    </Set>
-  </New>
-
-  <Call name="addConnector">
-    <Arg>
-      <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
-        <Set name="port">8080</Set>
-      </New>
-    </Arg>
-  </Call>
-
-  <Set name="handler">
-    <!-- maybe add more handlers (statistics, logging, etc.) later -->
-    <New class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
-      <Call name="addHandler">
-        <Arg>
-          <Ref id="webAppContext"/>
-        </Arg>
-      </Call>
-    </New>
-  </Set>
-
-</Configure>
-
diff --git a/etc/logback.xml b/etc/logback.xml
deleted file mode 100644
index 19ae9f7..0000000
--- a/etc/logback.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<configuration debug="false">
-
-  <!-- a path and a prefix -->
-  <property name="logfile-base" value="${LOGBASE}/onionoo-" />
-
-  <!-- log file names -->
-  <property name="fileall-logname" value="${logfile-base}all" />
-  <property name="fileerr-logname" value="${logfile-base}err" />
-  <property name="filestatistics-logname" value="${logfile-base}statistics" />
-
-  <!-- date pattern -->
-  <property name="utc-date-pattern" value="%date{ISO8601, UTC}" />
-
-  <!-- appender section -->
-  <appender name="FILEALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
-    <file>${fileall-logname}.log</file>
-    <encoder>
-      <pattern>${utc-date-pattern} %level %logger{20}:%line %msg%n</pattern>
-    </encoder>
-    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-      <!-- rollover daily -->
-      <FileNamePattern>${fileall-logname}.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
-      <maxHistory>10</maxHistory>
-      <timeBasedFileNamingAndTriggeringPolicy
-            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
-        <!-- or whenever the file size reaches 1MB -->
-        <maxFileSize>1MB</maxFileSize>
-      </timeBasedFileNamingAndTriggeringPolicy>
-    </rollingPolicy>
-  </appender>
-
-  <appender name="FILEERR" class="ch.qos.logback.core.FileAppender">
-    <file>${fileerr-logname}.log</file>
-    <encoder>
-      <pattern>${utc-date-pattern} %level %logger{20}:%line %msg%n</pattern>
-    </encoder>
-
-    <!-- ERROR or worse -->
-    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
-      <level>ERROR</level>
-    </filter>
-  </appender>
-
-  <appender name="FILESTATISTICS" class="ch.qos.logback.core.FileAppender">
-    <file>${filestatistics-logname}.log</file>
-    <encoder>
-      <pattern>${utc-date-pattern} %msg%n</pattern>
-    </encoder>
-
-    <!-- only INFO level -->
-    <filter class="ch.qos.logback.classic.filter.LevelFilter">
-      <level>INFO</level>
-      <onMatch>ACCEPT</onMatch>
-      <onMismatch>DENY</onMismatch>
-    </filter>
-  </appender>
-
-  <!-- logger section -->
-  <logger name="org.torproject" >
-    <appender-ref ref="FILEERR" />
-  </logger>
-
-  <logger name="org.eclipse" level="INFO" />
-
-  <logger name="org.torproject.onionoo.cron.Main" >
-    <appender-ref ref="FILESTATISTICS" />
-  </logger>
-
-  <logger name="org.torproject.onionoo.server.PerformanceMetrics" >
-    <appender-ref ref="FILESTATISTICS" />
-  </logger>
-
-  <logger name="statistics" >
-    <appender-ref ref="FILESTATISTICS" />
-  </logger>
-
-  <root level="ALL">
-    <appender-ref ref="FILEALL" />
-  </root>
-
-</configuration>
-
diff --git a/etc/web.xml.template b/etc/web.xml.template
deleted file mode 100644
index cefdfae..0000000
--- a/etc/web.xml.template
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<web-app version="2.4"
-  xmlns="http://java.sun.com/xml/ns/j2ee"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
-  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
-
-  <servlet>
-    <servlet-name>Resource</servlet-name>
-    <servlet-class>
-      org.torproject.onionoo.server.ResourceServlet
-    </servlet-class>
-    <init-param>
-      <param-name>maintenance</param-name>
-      <param-value>0</param-value>
-    </init-param>
-  </servlet>
-  <servlet-mapping>
-    <servlet-name>Resource</servlet-name>
-    <url-pattern>/summary</url-pattern>
-  </servlet-mapping>
-  <servlet-mapping>
-    <servlet-name>Resource</servlet-name>
-    <url-pattern>/details</url-pattern>
-  </servlet-mapping>
-  <servlet-mapping>
-    <servlet-name>Resource</servlet-name>
-    <url-pattern>/bandwidth</url-pattern>
-  </servlet-mapping>
-  <servlet-mapping>
-    <servlet-name>Resource</servlet-name>
-    <url-pattern>/weights</url-pattern>
-  </servlet-mapping>
-  <servlet-mapping>
-    <servlet-name>Resource</servlet-name>
-    <url-pattern>/clients</url-pattern>
-  </servlet-mapping>
-  <servlet-mapping>
-    <servlet-name>Resource</servlet-name>
-    <url-pattern>/uptime</url-pattern>
-  </servlet-mapping>
-
-  <context-param>
-    <param-name>outDir</param-name>
-    <param-value>/srv/onionoo.torproject.org/onionoo/out/</param-value>
-  </context-param>
-
-  <listener>
-    <listener-class>
-      org.torproject.onionoo.server.NodeIndexer
-    </listener-class>
-  </listener>
-
-  <filter>
-    <filter-name>GzipFilter</filter-name>
-    <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
-    <init-param>
-      <param-name>mimeTypes</param-name>
-      <param-value>text/html,text/xml,text/plain,application/json</param-value>
-    </init-param>
-    <init-param>
-      <param-name>excludedAgents</param-name>
-      <param-value>gozilla,traviata</param-value>
-    </init-param>
-    <init-param>
-      <param-name>minGzipSize</param-name>
-      <param-value>2048</param-value>
-    </init-param>
-  </filter>
-
-  <filter-mapping>
-    <filter-name>GzipFilter</filter-name>
-    <url-pattern>/*</url-pattern>
-  </filter-mapping>
-
-</web-app>
-
diff --git a/src/main/resources/context.xml b/src/main/resources/context.xml
new file mode 100644
index 0000000..09e5bac
--- /dev/null
+++ b/src/main/resources/context.xml
@@ -0,0 +1,3 @@
+<Context cookies="false">
+</Context>
+
diff --git a/src/main/resources/jetty.xml b/src/main/resources/jetty.xml
new file mode 100644
index 0000000..c172902
--- /dev/null
+++ b/src/main/resources/jetty.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
+  "http://www.eclipse.org/jetty/configure.dtd">
+
+<Configure id="server" class="org.eclipse.jetty.server.Server" >
+  <Set name="dumpAfterStart">false</Set>
+
+  <Set name="threadPool">
+    <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
+      <Set name="minThreads">25</Set>
+      <Set name="maxThreads">250</Set>
+      <Set name="detailedDump">false</Set>
+    </New>
+  </Set>
+
+  <New id="webAppContext" class="org.eclipse.jetty.webapp.WebAppContext">
+    <Set name="logUrlOnStart">true</Set>
+    <Set name="war">
+      <Call class="java.lang.System" name="getProperty">
+        <Arg>java.class.path</Arg>
+      </Call>
+    </Set>
+  </New>
+
+  <Call name="addConnector">
+    <Arg>
+      <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
+        <Set name="port">8080</Set>
+      </New>
+    </Arg>
+  </Call>
+
+  <Set name="handler">
+    <!-- maybe add more handlers (statistics, logging, etc.) later -->
+    <New class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
+      <Call name="addHandler">
+        <Arg>
+          <Ref id="webAppContext"/>
+        </Arg>
+      </Call>
+    </New>
+  </Set>
+
+</Configure>
+
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 0000000..19ae9f7
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,82 @@
+<configuration debug="false">
+
+  <!-- a path and a prefix -->
+  <property name="logfile-base" value="${LOGBASE}/onionoo-" />
+
+  <!-- log file names -->
+  <property name="fileall-logname" value="${logfile-base}all" />
+  <property name="fileerr-logname" value="${logfile-base}err" />
+  <property name="filestatistics-logname" value="${logfile-base}statistics" />
+
+  <!-- date pattern -->
+  <property name="utc-date-pattern" value="%date{ISO8601, UTC}" />
+
+  <!-- appender section -->
+  <appender name="FILEALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <file>${fileall-logname}.log</file>
+    <encoder>
+      <pattern>${utc-date-pattern} %level %logger{20}:%line %msg%n</pattern>
+    </encoder>
+    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+      <!-- rollover daily -->
+      <FileNamePattern>${fileall-logname}.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
+      <maxHistory>10</maxHistory>
+      <timeBasedFileNamingAndTriggeringPolicy
+            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+        <!-- or whenever the file size reaches 1MB -->
+        <maxFileSize>1MB</maxFileSize>
+      </timeBasedFileNamingAndTriggeringPolicy>
+    </rollingPolicy>
+  </appender>
+
+  <appender name="FILEERR" class="ch.qos.logback.core.FileAppender">
+    <file>${fileerr-logname}.log</file>
+    <encoder>
+      <pattern>${utc-date-pattern} %level %logger{20}:%line %msg%n</pattern>
+    </encoder>
+
+    <!-- ERROR or worse -->
+    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+      <level>ERROR</level>
+    </filter>
+  </appender>
+
+  <appender name="FILESTATISTICS" class="ch.qos.logback.core.FileAppender">
+    <file>${filestatistics-logname}.log</file>
+    <encoder>
+      <pattern>${utc-date-pattern} %msg%n</pattern>
+    </encoder>
+
+    <!-- only INFO level -->
+    <filter class="ch.qos.logback.classic.filter.LevelFilter">
+      <level>INFO</level>
+      <onMatch>ACCEPT</onMatch>
+      <onMismatch>DENY</onMismatch>
+    </filter>
+  </appender>
+
+  <!-- logger section -->
+  <logger name="org.torproject" >
+    <appender-ref ref="FILEERR" />
+  </logger>
+
+  <logger name="org.eclipse" level="INFO" />
+
+  <logger name="org.torproject.onionoo.cron.Main" >
+    <appender-ref ref="FILESTATISTICS" />
+  </logger>
+
+  <logger name="org.torproject.onionoo.server.PerformanceMetrics" >
+    <appender-ref ref="FILESTATISTICS" />
+  </logger>
+
+  <logger name="statistics" >
+    <appender-ref ref="FILESTATISTICS" />
+  </logger>
+
+  <root level="ALL">
+    <appender-ref ref="FILEALL" />
+  </root>
+
+</configuration>
+
diff --git a/src/main/resources/web.xml b/src/main/resources/web.xml
new file mode 100644
index 0000000..cefdfae
--- /dev/null
+++ b/src/main/resources/web.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app version="2.4"
+  xmlns="http://java.sun.com/xml/ns/j2ee"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
+  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
+
+  <servlet>
+    <servlet-name>Resource</servlet-name>
+    <servlet-class>
+      org.torproject.onionoo.server.ResourceServlet
+    </servlet-class>
+    <init-param>
+      <param-name>maintenance</param-name>
+      <param-value>0</param-value>
+    </init-param>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>Resource</servlet-name>
+    <url-pattern>/summary</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>Resource</servlet-name>
+    <url-pattern>/details</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>Resource</servlet-name>
+    <url-pattern>/bandwidth</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>Resource</servlet-name>
+    <url-pattern>/weights</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>Resource</servlet-name>
+    <url-pattern>/clients</url-pattern>
+  </servlet-mapping>
+  <servlet-mapping>
+    <servlet-name>Resource</servlet-name>
+    <url-pattern>/uptime</url-pattern>
+  </servlet-mapping>
+
+  <context-param>
+    <param-name>outDir</param-name>
+    <param-value>/srv/onionoo.torproject.org/onionoo/out/</param-value>
+  </context-param>
+
+  <listener>
+    <listener-class>
+      org.torproject.onionoo.server.NodeIndexer
+    </listener-class>
+  </listener>
+
+  <filter>
+    <filter-name>GzipFilter</filter-name>
+    <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
+    <init-param>
+      <param-name>mimeTypes</param-name>
+      <param-value>text/html,text/xml,text/plain,application/json</param-value>
+    </init-param>
+    <init-param>
+      <param-name>excludedAgents</param-name>
+      <param-value>gozilla,traviata</param-value>
+    </init-param>
+    <init-param>
+      <param-name>minGzipSize</param-name>
+      <param-value>2048</param-value>
+    </init-param>
+  </filter>
+
+  <filter-mapping>
+    <filter-name>GzipFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+</web-app>
+
diff --git a/src/main/resources/web/css/style.css b/src/main/resources/web/css/style.css
new file mode 100644
index 0000000..e3caa4a
--- /dev/null
+++ b/src/main/resources/web/css/style.css
@@ -0,0 +1,36 @@
+body { font-family: "Open Sans","lucida grande","Segoe UI",arial,verdana,
+  "lucida sans unicode",tahoma,sans-serif; background: #fafafa;
+  font-size: 13px; line-height: 22px; color: #222; }
+h3 { color: #7D4698; position: relative }
+a { color: #7D4698; text-decoration: none; font-weight: bold; }
+p { margin: 0; padding: 10px; }
+a[name] { padding: 0; margin: 0; }
+.box { max-width: 850px; width: 100%; margin: 0 auto 30px auto;
+  padding-bottom: 30px; background: white; border: 1px solid #eee; }
+.box > * { margin-left: 30px; margin-right: 30px; }
+.box h3 a { visibility: hidden; }
+.box:hover h3 a { visibility: visible; }
+.api-request { border-bottom: 1px solid #eee; position: relative }
+.request-url, .request-type, .request-response { padding: 8px 10px;
+  vertical-align: middle }
+.request-type { color: #57145F; display: inline-block; }
+.request-url { color: #333; font-size: 18px; }
+.request-response { position: absolute; color: #666; right: 0; }
+h3 .request-response { padding: 0 !important; }
+.api-urls>li:last-child { border-bottom: 0; }
+.required-true, .required-false, .typeof { display: inline-block;
+  vertical-align: middle; padding: 5px 10px; }
+.required-true { color: #1d7508; }
+.required-false { color: #aaa; }
+.properties { margin-top: 10px; margin-bottom: 10px;
+  border: 1px solid #eee; }
+.properties li { padding: 5px 0; }
+.properties li ul { border: 1px solid #eee; margin: 10px 10px 10px 40px;
+  background: white; }
+.properties .properties { margin-left: 10px; }
+.properties li:nth-child(even) { background: #fafafa; }
+.properties p { padding: 10px 15px; }
+.properties b { padding: 5px 10px; display: inline-block;
+  vertical-align: middle; }
+.api-urls{ margin-top: 30px; margin-bottom: 30px; }
+
diff --git a/src/main/resources/web/favicon.ico b/src/main/resources/web/favicon.ico
new file mode 100644
index 0000000..48060b1
Binary files /dev/null and b/src/main/resources/web/favicon.ico differ
diff --git a/src/main/resources/web/index.html b/src/main/resources/web/index.html
new file mode 100644
index 0000000..c7095ec
--- /dev/null
+++ b/src/main/resources/web/index.html
@@ -0,0 +1,141 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>Onionoo — a Tor network status protocol</title>
+<link href="css/style.css" type="text/css" rel="stylesheet">
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+<link href="favicon.ico" type="image/x-icon" rel="shortcut icon">
+</head>
+<body>
+
+<div class="box">
+
+<h1><a href="index.html">Onionoo</a> —</h1>
+<h2>a Tor network status <a href="protocol.html">protocol</a></h2>
+
+<p>Onionoo is a web-based protocol to learn about currently running
+Tor relays and bridges.  Onionoo itself was not designed as a service
+for human beings—at least not directly.  Onionoo provides the
+data for other applications and websites which in turn present Tor
+network status information to humans.  The following Onionoo clients
+are currently available:</p>
+<ul>
+<li><a href="https://atlas.torproject.org/">Atlas</a> is a web
+application to discover Tor relays. It provides useful
+information on how relays are configured along with graphics about
+their past.</li>
+<li><a href="https://compass.torproject.org/">Compass</a>
+is a Python script and website that extracts consensus weight
+information of currently running relays and aggregates weights of
+relays running in the same country or same autonomous system.</li>
+<li><a href="http://tor2web.org/">Tor2web</a> is a web proxy to Tor
+Hidden Services. It uses Onionoo to get the list of currently running
+Tor Exits to detect if the client is a Tor user and if so redirect
+them to the .onion address.</li>
+<li>The <a href="https://nos-oignons.net/Services/index.en.html">Nos
+oignons</a> website uses Onionoo to visualize bandwidth histories of
+their relays.</li>
+<li>The <a href="https://metrics.torproject.org/bubbles.html">metrics
+website</a> visualizes diversity of the Tor network using bubble
+graphs.</li>
+<li><a href="https://github.com/woeisme/torchart">torchart</a> is a PHP
+WordPress plugin which draws 3 day traffic charts using pChart currently
+used for displaying metric charts on
+<a href="http://icetor.is/wordpress/metrics/">icetor.is</a>.</li>
+<li><a href="https://github.com/kloesing/challenger">challenger</a>
+aggregates graph data from relays participating in
+<a href="https://www.eff.org/torchallenge/">EFF's 2014 Tor Challenge</a>
+to provide statistics like total bytes transferred.</li>
+<li><a href="https://play.google.com/store/apps/details?id=com.networksaremadeofstring.anonionooid">AnOnionooid</a>
+is an Android app that helps find and explore Tor relays and bridges.</li>
+<li><a href="https://oniontip.com/">OnionTip</a> uses Onionoo's data to
+distribute donations to relays that have a bitcoin address in their
+contact line.</li>
+<li><a href="https://savannah.nongnu.org/projects/koninoo/">koninoo</a> is
+a simple Java command line interface for querying Onionoo data.</li>
+<li>The <a href="https://duckduckgo.com/">DuckDuckGo</a> search engine
+displays Tor node details when being asked for "tor node" followed by a
+search term.</li>
+<li><a href="https://onionview.com/">OnionView</a> is a simple web service
+which uses Tor relay data to plot the location of active Tor nodes onto an
+interactive map of the world.</li>
+</ul>
+
+<p>The following library facilitates development of Onionoo clients:</p>
+<ul>
+<li><a href="https://github.com/duk3luk3/onion-py">OnionPy</a> is a
+comprehensive pure-Python (2.7+) Onionoo wrapper with caching
+support.</li>
+</ul>
+
+<h2>Developing Onionoo applications</h2>
+
+<p>The project pages of the Onionoo clients listed above have further
+information for contacting the authors and contributing ideas or code.
+The authors will be happy to hear your thoughts!</p>
+
+<p>You don't find your favorite Onionoo client above?  Want to
+implement your own and tell us to add it to the list?  The Onionoo
+clients above are backed by a web-based
+<a href="protocol.html">protocol</a>, which
+facilitates developing new applications displaying Tor status
+information.  Here are a few ideas for new Onionoo clients:</p>
+<ul>
+<li>Tor controller extension: Extend
+<a href="https://www.torproject.org/projects/vidalia.html.en">Vidalia</a> and/or
+<a href="https://www.torproject.org/projects/arm.html.en">arm</a> to look up details for the bridge
+that the user is running and display what pool the bridge is contained
+in.</li>
+<li>Social network site plugin: Add a plugin to the social network
+site of your choice to show your friends what Tor relays and bridges
+you're running and how that helps users around the world.</li>
+<li>Desktop tray icon: Write a tray icon for your favorite desktop
+environment that tells you when your relay or bridge is down and that
+displays some basic usage statistics.</li>
+<li>E-mail notification service: Improve our e-mail notification
+service <a href="https://weather.torproject.org/">Weather</a> by
+implementing its own relay search or extending it to report when a
+bridge drops off the network.</li>
+<li>Command-line tool: Implement a command-line tool that quickly
+searches a relay or bridge and prints out some status information to
+help debug problems.</li>
+<li>(Insert your idea here.)</li>
+</ul>
+
+<p>Want to help with developing the Onionoo server that provides
+Tor status data, or want to run your own Onionoo server instance?  The
+Onionoo server is written in Java with a tiny portion of Java
+Servlets.  Instructions for setting up the Onionoo server to fetch the
+required data from the Tor servers is described in the INSTALL file in
+the sources.  For more details see the
+<a href="https://gitweb.torproject.org/onionoo.git">source code</a> and
+<a href="https://trac.torproject.org/projects/tor/query?status=!closed&component=Onionoo">issue
+tracker</a>.</p>
+
+<h2>Related projects</h2>
+
+<p>TorStatus is the name of a nowadays
+<a href="https://svn.torproject.org/svn/torstatus/trunk/">unmaintained</a>
+website that displays Tor relay information similar to
+<a href="http://atlas.torproject.org/">Atlas</a>.  There are still a
+few <a href="http://torstatus.blutmagie.de/">TorStatus</a>
+<a href="https://torstatus.rueckgr.at/">websites</a>
+<a href="http://tns.hermetix.org/">running</a>.</p>
+
+<p>There's another project from summer 2011 called TorStatus which is
+a <a href="https://gitweb.torproject.org/torstatus.git">rewrite</a> of
+the original TorStatus in Python/Django.  Unfortunately, it's also
+unmaintained.</p>
+
+<p>Finally, there's the
+<a href="https://consensus-health.torproject.org/">consensus-health
+page</a> which has the primary purpose of indicating problems with
+creating a network status consensus.  As a side-effect this page lists
+all currently running relays and how the directory authorities voted
+on them.</p>
+
+</div> <!-- box -->
+
+</body>
+</html>
+
diff --git a/src/main/resources/web/protocol.html b/src/main/resources/web/protocol.html
new file mode 100644
index 0000000..c6cc534
--- /dev/null
+++ b/src/main/resources/web/protocol.html
@@ -0,0 +1,2338 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>Onionoo — protocol overview</title>
+<link href="css/style.css" type="text/css" rel="stylesheet">
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+<link href="favicon.ico" type="image/x-icon" rel="shortcut icon">
+</head>
+<body>
+
+<div class="box">
+
+<h1><a href="index.html">Onionoo</a> —</h1>
+<h2>protocol overview</h2>
+
+    <h4>Table of contents</h4>
+    <ul>
+        <li><a href="#general">General</a></li>
+        <li><a href="#methods">Methods</a></li>
+        <li><a href="#summary">Summary documents</a></li>
+        <li><a href="#details">Details documents</a></li>
+        <li><a href="#history">History objects</a></li>
+        <li><a href="#bandwidth">Bandwidth documents</a></li>
+        <li><a href="#weights">Weights documents</a></li>
+        <li><a href="#clients">Clients documents</a></li>
+        <li><a href="#uptime">Uptime documents</a></li>
+        <li><a href="#examples">Example usage</a></li>
+    </ul>
+
+</div>
+<div class="box">
+
+<a name="general"></a>
+<h3>General <a href="#general">#</a></h3>
+
+<p>
+The Onionoo service is designed as a RESTful web service.
+Onionoo clients send HTTP GET requests to the Onionoo server which
+responds with JSON-formatted replies.
+Onionoo clients and their developers should follow a few rules:
+</p>
+
+<h4>Compression</h4>
+<p>
+Clients should include an <strong>"Accept-Encoding:
+gzip"</strong> header in their requests and handle gzip-compressed
+responses.
+Only requests starting at a certain size will be compressed by the
+server.
+</p>
+
+<h4>Caching</h4>
+<p>Clients should make use of the <strong>"Last-Modified"</strong>
+header of responses and include that timestamp in a
+<strong>"If-Modified-Since"</strong> header of subsequent requests.
+</p>
+
+<h4>Response codes</h4>
+<p>
+Clients should handle response codes by
+distinguishing between client and server errors, and if there's a problem,
+informing their users about the kind of problem.
+The following response codes are used:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>200 OK</b>
+<p>
+The request was processed successfully.
+</p>
+</li>
+
+<li>
+<b>304 Not Modified</b>
+<p>
+Server data has not changed since the
+<strong>"If-Modified-Since"</strong> header included in the request.
+</p>
+</li>
+
+<li>
+<b>400 Bad Request</b>
+<p>
+The request for a known resource could not be processed because of bad
+syntax.
+This is most likely a client problem.
+</p>
+</li>
+
+<li>
+<b>404 Not Available</b>
+<p>
+The request could not be processed because the requested resource could
+not be found.
+This is most likely a client problem.
+</p>
+</li>
+
+<li>
+<b>500 Internal Server Error</b>
+<p>
+There is an unspecific problem with
+the server which the service operator may not yet be aware of.
+Please check if there's already a bug report for this problem, and if not,
+file one.
+</p>
+</li>
+
+<li>
+<b>503 Service Unavailable</b>
+<p>
+The server is temporarily down for
+maintenance, or there is a temporary problem with the server that the
+service operator is already aware of.
+Only file a bug report if this problem persists.
+</p>
+</li>
+
+</ul>
+
+<h4>Protocol versions</h4>
+<p>
+There are plenty of reasons why we may have
+to change the protocol described here.
+Clients should be able to handle all valid JSON responses, ignoring
+unknown fields and not breaking horribly in case of missing fields.
+Protocol changes will be announced here by writing deprecated API parts in
+<strong><font color="red">red</font></strong> and new parts in
+<strong><font color="blue">blue</font></strong>.
+Deprecated parts will be removed one month after their announcement.
+If you want to be informed of upcoming protocol changes, subscribe to the
+<a href="https://lists.torproject.org/cgi-bin/mailman/listinfo/onionoo-announce">onionoo-announce</a>
+mailing list.
+</p>
+
+<p>All responses contain a <strong>"version"</strong> string that
+indicates whether clients can parse the document or not.
+Version strings consist of a major and a minor version number.
+The major version number is raised when previously required fields are
+dropped or turned into optional fields, when request parameters or
+response documents are removed, or when there are structural changes.
+The minor version number is raised when new fields, request parameters, or
+response documents are added or optional fields are dropped.
+If clients support the same major version given in a response but only a
+lower minor version, they should be able to parse the document but may not
+understand all fields.
+If clients support a lower major version, they should not attempt to parse
+a document, because there may be backward-incompatible changes.</p>
+
+<p>Responses may also contain the optional
+<strong>"next_major_version_scheduled"</strong> field that announces when
+the next major version is scheduled to be deployed.
+Clients should inform their users that they should upgrade to the next
+major protocol version before the provided date.</p>
+
+<p>The following versions have been used in the past six months or are
+scheduled to be deployed in the next months:</p>
+
+<ul>
+<li><strong>1.0</strong>: First assigned version number on August 31,
+2014.</li>
+<li><strong>1.1</strong>: Added optional "next_major_version_scheduled"
+field on September 16, 2014.</li>
+<li><strong>1.2</strong>: Added qualified search terms to "search"
+parameter on October 17, 2014.</li>
+<li><strong>2.0</strong>: Extended search parameter to base64-encoded
+fingerprints on November 15, 2014.</li>
+<li><strong>2.1</strong>: Removed optional "advertised_bandwidth_fraction"
+field from details documents and optional "advertised_bandwidth" and
+"advertised_bandwidth_fraction" fields from weights documents on November
+16, 2014.</li>
+<li><strong>2.2</strong>: Removed optional "pool_assignment" field and
+added "transports" field to bridge details documents on December 8,
+2014.</li>
+<li><strong>2.3</strong>: Added optional "flags" field to uptime
+documents on March 22, 2015.</li>
+<li><strong>2.4</strong>: Added optional "effective_family" field to
+details documents on July 3, 2015.</li>
+<li><strong>2.5</strong>: Added optional "measured" field to details
+documents on August 13, 2015.</li>
+<li><strong>2.6</strong>: Added optional "alleged_family" and
+"indirect_family" fields and deprecated optional "family" field in details
+documents on August 25, 2015.</li>
+<li><strong>3.0</strong>: Extended search parameter to match any 4 hex
+characters of a space-separated fingerprint on November 15, 2015.</li>
+<li><strong>3.1</strong>: Removed optional "family" field on January 18,
+2016.</li>
+</ul>
+
+</div> <!-- box -->
+
+<div class="box">
+
+<a name="methods"></a>
+<h3>Methods <a href="#methods">#</a></h3>
+
+<p>
+The following methods each return a single document containing zero or
+more objects of relays and/or bridges.
+By default, all relays and bridges are included that have been running in
+the past week.
+</p>
+
+<ul class="api-urls">
+
+<li class="api-request">
+<span class="request-type">GET</span>
+<span class="request-url">https://onionoo.torproject.org/summary</span>
+<span class="request-response">returns a <a href="#summary">summary
+document</a></span>
+</li>
+
+<li class="api-request">
+<span class="request-type">GET</span>
+<span class="request-url">https://onionoo.torproject.org/details</span>
+<span class="request-response">returns a <a href="#details">details
+document</a></span>
+</li>
+
+<li class="api-request">
+<span class="request-type">GET</span>
+<span class="request-url">https://onionoo.torproject.org/bandwidth</span>
+<span class="request-response">returns a <a href="#bandwidth">bandwidth
+document</a></span>
+</li>
+
+<li class="api-request">
+<span class="request-type">GET</span>
+<span class="request-url">https://onionoo.torproject.org/weights</span>
+<span class="request-response">returns a <a href="#weights">weights
+document</a></span>
+</li>
+
+<li class="api-request">
+<span class="request-type">GET</span>
+<span class="request-url">https://onionoo.torproject.org/clients</span>
+<span class="request-response">returns a <a href="#clients">clients
+document</a></span>
+</li>
+
+<li class="api-request">
+<span class="request-type">GET</span>
+<span class="request-url">https://onionoo.torproject.org/uptime</span>
+<span class="request-response">returns a <a href="#uptime">uptime
+document</a></span>
+</li>
+
+</ul>
+
+<h4>Parameters</h4>
+<p>
+Each of the methods can be parameterized to select only a subset of relay
+and/or bridge documents that are currently running or that have been
+running in the past week.
+(The <strong>fingerprint</strong> parameter is special here, because it
+allows selecting a specific relay or bridge, regardless of whether it has
+been running in the past week.)
+If multiple parameters are specified, they are combined using a logical
+AND operation, meaning that only the intersection of relays and bridges
+matching all parameters is returned.
+If the same parameter is specified more than once, only the first
+parameter value is considered.
+</p>
+
+<ul class="properties">
+
+<li>
+<b>type</b>
+<p>
+Return only relay (parameter value
+<strong>relay</strong>) or only bridge documents (parameter value
+<strong>bridge</strong>).
+Parameter values are case-insensitive.
+</p>
+</li>
+
+<li>
+<b>running</b>
+<p>
+Return only running (parameter value
+<strong>true</strong>) or only non-running relays and/or bridges
+(paramter value
+<strong>false</strong>).
+Parameter values are case-insensitive.
+</p>
+</li>
+
+<li>
+<b>search</b>
+<p>
+Return only (1) relays with the parameter value matching (part of a)
+nickname, (possibly $-prefixed) beginning of a hex-encoded fingerprint,
+any 4 hex characters of a space-separated fingerprint, beginning of a
+base64-encoded fingerprint without trailing equal signs, or beginning of
+an IP address, (2) bridges with (part of a) nickname or (possibly
+$-prefixed) beginning of a hashed hex-encoded fingerprint, and (3) relays
+and/or bridges matching a given qualified search term.
+Searches by relay IP address include all known addresses used for onion
+routing and for exiting to the Internet.
+Searches for beginnings of IP addresses are performed on textual
+representations of canonical IP address forms, so that searches using CIDR
+notation or non-canonical forms will return empty results.
+Searches are case-insensitive, except for base64-encoded fingerprints.
+If multiple search terms are given, separated by spaces, the intersection
+of all relays and bridges matching all search terms will be returned.
+Complete hex-encoded fingerprints should always be hashed using SHA-1,
+regardless of searching for a relay or a bridge, in order to not
+accidentally leak non-hashed bridge fingerprints in the URL.
+Qualified search terms have the form "key:value" (without double quotes)
+with "key" being one of the parameters listed here except for "search",
+"fingerprint", "order", "limit", "offset", and "fields", and "value" being
+the string that will internally be passed to that parameter.
+</p>
+</li>
+
+<li>
+<b>lookup</b>
+<p>
+Return only the relay with the parameter
+value matching the fingerprint or the bridge with the parameter value
+matching the hashed fingerprint.
+Fingerprints should always be hashed using SHA-1, regardless of looking up
+a relay or a bridge, in order to not accidentally leak non-hashed bridge
+fingerprints in the URL.
+Lookups only work for full fingerprints or hashed fingerprints consisting
+of 40 hex characters.
+Lookups are case-insensitive.
+</p>
+</li>
+
+<li>
+<b>fingerprint</b>
+<p>
+Return only the relay with the parameter value matching the fingerprint
+or the bridge with the parameter value matching the hashed fingerprint.
+Fingerprints must consist of 40 hex characters, case does not matter.
+This parameter is quite similar to the <strong>lookup</strong> parameter
+with two exceptions:
+(1) the provided relay fingerprint or hashed bridge fingerprint <i>must
+not</i> be hashed (again) using SHA-1;
+(2) the response will contain any matching relay or bridge regardless of
+whether they have been running in the past week.
+</p>
+</li>
+
+<li>
+<b>country</b>
+<p>
+Return only relays which are located in the
+given country as identified by a two-letter country code.
+Filtering by country code is case-insensitive.
+</p>
+</li>
+
+<li>
+<b>as</b>
+<p>
+Return only relays which are located in the
+given autonomous system (AS) as identified by the AS number (with or
+without preceding "AS" part).
+Filtering by AS number is case-insensitive.
+</p>
+</li>
+
+<li>
+<b>flag</b>
+<p>
+Return only relays which have the
+given relay flag assigned by the directory authorities.
+Note that if the flag parameter is specified more than once, only the
+first parameter value will be considered.
+Filtering by flag is case-insensitive.
+</p>
+</li>
+
+<li>
+<b>first_seen_days</b>
+<p>
+Return only relays or bridges which
+have first been seen during the given range of days ago.
+A parameter value "x-y" with x <= y returns relays or bridges that have
+first been seen at least x and at most y days ago.
+Accepted short forms are "x", "x-", and "-y" which are interpreted as
+"x-x", "x-infinity", and "0-y".
+</p>
+</li>
+
+<li>
+<b>last_seen_days</b>
+<p>
+Return only relays or bridges which
+have last been seen during the given range of days ago.
+A parameter value "x-y" with x <= y returns relays or bridges that have
+last been seen at least x and at most y days ago.
+Accepted short forms are "x", "x-", and "-y" which are interpreted as
+"x-x", "x-infinity", and "0-y".
+Note that relays and bridges that haven't been running in the past week
+are not included in results, so that setting x to 8 or higher will lead to
+an empty result set.
+</p>
+</li>
+
+<li>
+<b>contact</b>
+<p>
+Return only relays with the parameter value
+matching (part of) the contact line.
+If the parameter value contains spaces, only relays are returned which
+contain all space-separated parts in their contact line.
+Only printable ASCII characters are permitted in the parameter value,
+some of which need to be percent-encoded (# as %23, % as %25, & as
+%26, + as %2B, and / as %2F).
+Comparisons are case-insensitive.
+</p>
+</li>
+
+<li>
+<b>family</b>
+<p>
+Return only the relay whose fingerprint matches the parameter value and
+all relays that this relay has listed in its family by fingerprint and
+that in turn have listed this relay in their family by fingerprint.
+If relays have listed other relays in their family by nickname, those
+family relationships will not be considered, regardless of whether they
+have the Named flag or not.
+The provided relay fingerprint must consist of 40 hex characters where
+case does not matter, and it must not be hashed using SHA-1.
+Bridges are not contained in the result, regardless of whether they define
+a family.
+</p>
+</li>
+
+</ul>
+
+<p>
+Response documents can be reduced in size by requesting only a subset
+of contained fields.
+</p>
+
+<ul class="properties">
+
+<li>
+<b>fields</b>
+<p>
+Comma-separated list of fields that will be
+included in the result.
+So far, only top-level fields in relay or bridge objects of details
+documents can be specified, e.g.,
+<strong>nickname,hashed_fingerprint</strong>.
+If the fields parameter is provided, all other fields which are not
+contained in the provided list will be removed from the result.
+Field names are case-insensitive.
+</p>
+</li>
+
+</ul>
+
+<p>
+Relay and/or bridge documents in the response can be ordered and
+limited by providing further parameters.
+If the same parameter is specified more than once, only the first
+parameter value is considered.
+</p>
+
+<ul class="properties">
+
+<li>
+<b>order</b>
+<p>
+Re-order results by a comma-separated list
+of fields in ascending or descending order.
+Results are first ordered by the first list element, then by the second,
+and so on.
+Possible fields for ordering are: <strong>consensus_weight</strong>.
+Field names are case-insensitive.
+Ascending order is the default; descending order is selected by prepending
+fields with a minus sign (<strong>-</strong>).
+Relays or bridges which don't have any value for a field to be ordered by
+are always appended to the end, regardless or sorting order.
+The ordering is defined independent of the requested document type and
+does not require the ordering field to be contained in the document.
+If no <strong>order</strong> parameter is given, ordering of results is
+undefined.
+</p>
+</li>
+
+<li>
+<b>offset</b>
+<p>
+Skip the given number of relays and/or
+bridges.
+Relays are skipped first, then bridges.
+Non-positive <strong>offset</strong> values are treated as zero and don't
+change the
+result.
+</p>
+</li>
+
+<li>
+<b>limit</b>
+<p>
+Limit result to the given number of
+relays and/or bridges.
+Relays are kept first, then bridges.
+Non-positive <strong>limit</strong> values are treated as zero and lead
+to an empty
+result.
+When used together with <strong>offset</strong>, the offsetting step
+precedes the
+limiting step.
+</p>
+</li>
+
+</ul>
+
+</div> <!-- box -->
+
+<div class="box">
+<a name="summary"></a>
+<h3>Summary documents <a href="#summary">#</a>
+<span class="request-response">
+<a href="summary?limit=4">example request</a>
+</span>
+</h3>
+
+<p>Summary documents contain short summaries of relays with nicknames,
+fingerprints, IP addresses, and running information as well as bridges
+with hashed fingerprints and running information.
+Summary documents contain the following fields:</p>
+
+<ul class="properties">
+
+<li>
+<b>version</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Onionoo protocol version string.
+</p>
+</li>
+
+<li>
+<b>next_major_version_scheduled</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
+be deployed.
+Omitted if no major protocol changes are planned.
+</p>
+</li>
+
+<li>
+<b>relays_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when the last known relay network
+status consensus started being valid.
+Indicates how recent the relay summaries in this document are.
+</p>
+</li>
+
+<li>
+<b>relays</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Array of relay summary objects as specified below.
+</p>
+</li>
+
+<li>
+<b>bridges_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known bridge network status was published.
+Indicates how recent the bridge summaries in this document are.
+</p>
+</li>
+
+<li>
+<b>bridges</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Array of bridge summary objects as specified below.
+</p>
+</li>
+
+</ul>
+
+<h4>Relay summary objects</h4>
+
+<p>
+Relay summary objects contain the following key-value pairs:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>n</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Relay nickname consisting of 1–19 alphanumerical characters.
+Omitted if the relay nickname is <strong>"Unnamed"</strong>.
+</p>
+</li>
+
+<li>
+<b>f</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Relay fingerprint consisting of 40 upper-case hexadecimal characters.
+</p>
+</li>
+
+<li>
+<b>a</b>
+<code class="typeof">array of strings</code>
+<span class="required-true">required</span>
+<p>
+Array of IPv4 or IPv6 addresses where the relay accepts
+onion-routing connections or which the relay used to exit to the Internet
+in the past 24 hours.
+The first address is the primary onion-routing address that the relay used
+to register in the network, subsequent addresses are in arbitrary order.
+IPv6 hex characters are all lower-case.
+</p>
+</li>
+
+<li>
+<b>r</b>
+<code class="typeof">boolean</code>
+<span class="required-true">required</span>
+<p>
+Boolean field saying whether this relay was listed as
+running in the last relay network status consensus.
+</p>
+</li>
+
+</ul>
+
+<h4>Bridge summary objects</h4>
+
+<p>
+Bridge summary objects contain the following key-value pairs:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>n</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Bridge nickname consisting of 1–19 alphanumerical characters.
+Omitted if the bridge nickname is <strong>"Unnamed"</strong>.
+</p>
+</li>
+
+<li>
+<b>h</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+SHA-1 hash of the bridge fingerprint consisting of 40
+upper-case hexadecimal characters.
+</p>
+</li>
+
+<li>
+<b>r</b>
+<code class="typeof">boolean</code>
+<span class="required-true">required</span>
+<p>
+Boolean field saying whether this bridge was listed as
+running in the last bridge network status.
+</p>
+</li>
+
+</ul>
+
+</div> <!-- box -->
+
+<div class="box">
+<a name="details"></a>
+<h3>Details documents <a href="#details">#</a>
+<span class="request-response">
+<a href="details?limit=4">example request</a>
+</span>
+</h3>
+
+<p>
+Details documents are based on network statuses published by the Tor
+directories, server descriptors published by relays and bridges, and data
+published by Tor network services TorDNSEL and BridgeDB.
+Details documents use the most recently published data from these sources,
+which may lead to contradictions between fields based on different sources
+in rare edge cases.
+Details documents contain the following fields:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>version</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Onionoo protocol version string.
+</p>
+</li>
+
+<li>
+<b>next_major_version_scheduled</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
+be deployed.
+Omitted if no major protocol changes are planned.
+</p>
+</li>
+
+<li>
+<b>relays_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known relay network status consensus started being valid.
+Indicates how recent the relay details in this document are.
+</p>
+</li>
+
+<li>
+<b>relays</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Array of relay details objects as specified below.
+</p>
+</li>
+
+<li>
+<b>bridges_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known bridge network status was published.
+Indicates how recent the bridge details in this document are.
+</p>
+</li>
+
+<li>
+<b>bridges</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Array of bridge details objects as specified below.
+</p>
+
+</li>
+
+</ul>
+
+<h4>Relay details objects</h4>
+
+<p>
+Relay details objects contain the following key-value pairs:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>nickname</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Relay nickname consisting of 1–19 alphanumerical characters.
+Omitted if the relay nickname is <strong>"Unnamed"</strong>.
+</p>
+</li>
+
+<li>
+<b>fingerprint</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Relay fingerprint consisting of 40 upper-case
+hexadecimal characters.
+</p>
+</li>
+
+<li>
+<b>or_addresses</b>
+<code class="typeof">array of strings</code>
+<span class="required-true">required</span>
+<p>
+Array of IPv4 or IPv6 addresses and TCP ports
+or port lists where the relay accepts onion-routing connections.
+The first address is the primary onion-routing address that the relay used
+to register in the network, subsequent addresses are in arbitrary order.
+IPv6 hex characters are all lower-case.
+</p>
+</li>
+
+<li>
+<b>exit_addresses</b>
+<code class="typeof">array of strings</code>
+<span class="required-false">optional</span>
+<p>
+Array of IPv4 or IPv6 addresses that the
+relay used to exit to the Internet in the past 24 hours.
+IPv6 hex characters are all lower-case.
+Only those addresses are listed that are different from onion-routing
+addresses.
+Omitted if array is empty.
+</p>
+</li>
+
+<li>
+<b>dir_address</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+IPv4 address and TCP port where the relay
+accepts directory connections.
+Omitted if the relay does not accept directory connections.
+</p>
+</li>
+
+<li>
+<b>last_seen</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when this
+relay was last seen in a network status consensus.
+</p>
+</li>
+
+<li>
+<b>last_changed_address_or_port</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD
+hh:mm:ss) when this relay last stopped announcing an IPv4 or IPv6 address
+or TCP port where it previously accepted onion-routing or directory
+connections.
+This timestamp can serve as indicator whether this relay would be a
+suitable fallback directory.
+</p>
+</li>
+
+<li>
+<b>first_seen</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when this
+relay was first seen in a network status consensus.
+</p>
+</li>
+
+<li>
+<b>running</b>
+<code class="typeof">boolean</code>
+<span class="required-true">required</span>
+<p>
+Boolean field saying whether this relay was listed as
+running in the last relay network status consensus.
+</p>
+</li>
+
+<li>
+<b>hibernating</b>
+<code class="typeof">boolean</code>
+<span class="required-false">optional</span>
+<p>
+Boolean field saying whether this relay indicated that it is hibernating
+in its last known server descriptor.
+This information may be helpful to decide whether a relay that is not
+running anymore has reached its accounting limit and has not dropped out
+of the network for another, unknown reason.
+Omitted if either the relay is not hibernating, or if no information is
+available about the hiberation status of the relay.
+</p>
+</li>
+
+<li>
+<b>flags</b>
+<code class="typeof">array of strings</code>
+<span class="required-false">optional</span>
+<p>
+Array of relay flags that the directory authorities
+assigned to this relay.
+Omitted if empty.
+</p>
+</li>
+
+<li>
+<b>country</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Two-letter lower-case country code as found in a
+GeoIP database by resolving the relay's first onion-routing IP address.
+Omitted if the relay IP address could not be found in the GeoIP
+database.
+</p>
+</li>
+
+<li>
+<b>country_name</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Country name as found in a GeoIP database by
+resolving the relay's first onion-routing IP address.
+Omitted if the relay IP address could not be found in the GeoIP
+database, or if the GeoIP database did not contain a country name.
+</p>
+</li>
+
+<li>
+<b>region_name</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Region name as found in a GeoIP database by
+resolving the relay's first onion-routing IP address.
+Omitted if the relay IP address could not be found in the GeoIP
+database, or if the GeoIP database did not contain a region name.
+</p>
+</li>
+
+<li>
+<b>city_name</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+City name as found in a
+GeoIP database by resolving the relay's first onion-routing IP address.
+Omitted if the relay IP address could not be found in the GeoIP
+database, or if the GeoIP database did not contain a city name.
+</p>
+</li>
+
+<li>
+<b>latitude</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Latitude as found in a GeoIP database by resolving
+the relay's first onion-routing IP address.
+Omitted if the relay IP address could not be found in the GeoIP
+database.
+</p>
+</li>
+
+<li>
+<b>longitude</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Longitude as found in a GeoIP database by
+resolving the relay's first onion-routing IP address.
+Omitted if the relay IP address could not be found in the GeoIP
+database.
+</p>
+</li>
+
+<li>
+<b>as_number</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+AS number as found in an AS database by
+resolving the relay's first onion-routing IP address.
+AS number strings start with "AS", followed directly by the AS number.
+Omitted if the relay IP address could not be found in the AS
+database.
+</p>
+</li>
+
+<li>
+<b>as_name</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+AS name as found in an AS database by resolving the
+relay's first onion-routing IP address.
+Omitted if the relay IP address could not be found in the AS
+database.
+</p>
+</li>
+
+<li>
+<b>consensus_weight</b>
+<code class="typeof">number</code>
+<span class="required-true">required</span>
+<p>
+Weight assigned to this relay by the
+directory authorities that clients use in their path selection algorithm.
+The unit is arbitrary; currently it's kilobytes per second, but that might
+change in the future.
+</p>
+</li>
+
+<li>
+<b>host_name</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Host name as found in a reverse DNS lookup of the
+relay IP address.
+This field is updated at most once in 12 hours, unless the relay IP
+address changes.
+Omitted if the relay IP address was not looked up or if no lookup request
+was successful yet.
+</p>
+</li>
+
+<li>
+<b>last_restarted</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when the
+relay was last (re-)started.
+Missing if router descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>bandwidth_rate</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Average bandwidth
+in bytes per second that this relay is willing to sustain over long
+periods.
+Missing if router descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>bandwidth_burst</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Bandwidth in bytes
+per second that this relay is willing to sustain in very short intervals.
+Missing if router descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>observed_bandwidth</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Bandwidth
+estimate in bytes per second of the capacity this relay can handle.
+The relay remembers the maximum bandwidth sustained output over any ten
+second period in the past day, and another sustained input.
+The "observed_bandwidth" value is the lesser of these two numbers.
+Missing if router descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>advertised_bandwidth</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Bandwidth in bytes per second that this
+relay is willing and capable to provide.
+This bandwidth value is the minimum of <strong>bandwidth_rate</strong>,
+<strong>bandwidth_burst</strong>, and <strong>observed_bandwidth</strong>.
+Missing if router descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>exit_policy</b>
+<code class="typeof">array of strings</code>
+<span class="required-false">optional</span>
+<p>
+Array of exit-policy lines.
+Missing if router descriptor containing this information cannot be
+found.
+May contradict the <strong>"exit_policy_summary"</strong> field in a rare
+edge case: this happens when the relay changes its exit policy after the
+directory authorities summarized the previous exit policy.
+</p>
+</li>
+
+<li>
+<b>exit_policy_summary</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Summary
+version of the relay's exit policy containing a dictionary with either an
+"accept" or a "reject" element.
+If there is an "accept" ("reject") element, the relay accepts (rejects)
+all TCP ports or port ranges in the given list for most IP addresses and
+rejects (accepts) all other ports.
+May contradict the <strong>"exit_policy"</strong> field in a rare edge
+case: this happens when the relay changes its exit policy after the
+directory authorities summarized the previous exit policy.
+</p>
+</li>
+
+<li>
+<b>exit_policy_v6_summary</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Summary version of the relay's IPv6 exit policy containing a dictionary
+with either an "accept" or a "reject" element.
+If there is an "accept" ("reject") element, the relay accepts (rejects)
+all TCP ports or port ranges in the given list for most IP addresses and
+rejects (accepts) all other ports.
+Missing if the relay rejects all connections to IPv6 addresses.
+May contradict the <strong>"exit_policy_summary"</strong> field in a rare
+edge case: this happens when the relay changes its exit policy after the
+directory authorities summarized the previous exit policy.
+</p>
+</li>
+
+<li>
+<b>contact</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Contact address of the relay operator.
+Omitted if empty or if descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>platform</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Platform string containing operating system and Tor
+version details.
+Omitted if empty or if descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>recommended_version</b>
+<code class="typeof">boolean</code>
+<span class="required-false">optional</span>
+<p>
+Boolean field saying whether the Tor software version of this relay is
+recommended by the directory authorities or not.
+Omitted if either the directory authorities did not recommend versions, or
+the relay did not report which version it runs.
+</p>
+</li>
+
+<li>
+<b><font color="red">family</font></b>
+<code class="typeof">array of strings</code>
+<span class="required-false">optional</span>
+<p>
+Array of fingerprints or nicknames of relays that this relay considers to
+be part of its family.
+There are no cross-checks whether the listed relays exist or consider this
+relay part of their family, so that the effective family of this relay may
+be smaller.
+Omitted if empty or if descriptor containing this information cannot be
+found.
+<font color="red">Deprecated on August 25, 2015, removed on January 18,
+2016.</font>
+</p>
+</li>
+
+<li>
+<b>effective_family</b>
+<code class="typeof">array of strings</code>
+<span class="required-false">optional</span>
+<p>
+Array of $-prefixed fingerprints of relays that are in an effective,
+mutual family relationship with this relay.
+These relays are part of this relay's family and they consider this relay
+to be part of their family.
+Omitted if empty or if descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>alleged_family</b>
+<code class="typeof">array of strings</code>
+<span class="required-false">optional</span>
+<p>
+Array of $-prefixed fingerprints of relays that are not in an effective,
+mutual family relationship with this relay.
+These relays are part of this relay's family but they don't consider this
+relay to be part of their family.
+Omitted if empty or if descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>indirect_family</b>
+<code class="typeof">array of strings</code>
+<span class="required-false">optional</span>
+<p>
+Array of $-prefixed fingerprints of relays that are not in an effective,
+mutual family relationship with this relay but that can be reached by
+following effective, mutual family relationships starting at this relay.
+Omitted if empty or if descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>consensus_weight_fraction</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Fraction of this relay's consensus weight compared to the sum of all
+consensus weights in the network.
+This fraction is a very rough approximation of the probability of this
+relay to be selected by clients.
+Omitted if the relay is not running.
+</p>
+</li>
+
+<li>
+<b>guard_probability</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Probability of this relay to be selected for the guard position.
+This probability is calculated based on consensus weights, relay flags,
+and bandwidth weights in the consensus.
+Path selection depends on more factors, so that this probability can only
+be an approximation.
+Omitted if the relay is not running, or the consensus does not contain
+bandwidth weights.
+</p>
+</li>
+
+<li>
+<b>middle_probability</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Probability of this relay to be selected for the middle position.
+This probability is calculated based on consensus weights, relay flags,
+and bandwidth weights in the consensus.
+Path selection depends on more factors, so that this probability can only
+be an approximation.
+Omitted if the relay is not running, or the consensus does not contain
+bandwidth weights.
+</p>
+</li>
+
+<li>
+<b>exit_probability</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Probability of this relay to be selected for the exit position.
+This probability is calculated based on consensus weights, relay flags,
+and bandwidth weights in the consensus.
+Path selection depends on more factors, so that this probability can only
+be an approximation.
+Omitted if the relay is not running, or the consensus does not contain
+bandwidth weights.
+</p>
+</li>
+
+<li>
+<b>measured</b>
+<code class="typeof">boolean</code>
+<span class="required-false">optional</span>
+<p>
+Boolean field saying whether the consensus weight of this relay is based
+on a threshold of 3 or more measurements by Tor bandwidth authorities.
+Omitted if the network status consensus containing this relay does not
+contain measurement information.
+</p>
+</li>
+
+</ul>
+
+<h4>Bridge details objects</h4>
+
+<p>
+Bridge details objects contain the following key-value pairs:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>nickname</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Bridge nickname consisting of 1–19
+alphanumerical characters.
+Omitted if the bridge nickname is <strong>"Unnamed"</strong>.
+</p>
+</li>
+
+<li>
+<b>hashed_fingerprint</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+SHA-1 hash of the bridge fingerprint
+consisting of 40 upper-case hexadecimal characters.
+</p>
+</li>
+
+<li>
+<b>or_addresses</b>
+<code class="typeof">array of strings</code>
+<span class="required-true">required</span>
+<p>
+Array of sanitized IPv4 or IPv6 addresses and
+TCP ports or port lists where the bridge accepts onion-routing
+connections.
+The first address is the primary onion-routing address that the bridge
+used to register in the network, subsequent addresses are in arbitrary
+order.
+IPv6 hex characters are all lower-case.
+Sanitized IP addresses are always in <strong>10/8</strong> or
+<strong>[fd9f:2e19:3bcf/48]</strong> IP networks and are only useful to
+learn which
+IP version the bridge uses and to detect whether the bridge changed its
+address.
+Sanitized IP addresses always change on the 1st of every month at 00:00:00
+UTC, regardless of the bridge actually changing its IP address.
+TCP ports are not sanitized.
+</p>
+</li>
+
+<li>
+<b>last_seen</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when this
+bridge was last seen in a bridge network status.
+</p>
+</li>
+
+<li>
+<b>first_seen</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when this
+bridge was first seen in a bridge network status.
+</p>
+</li>
+
+<li>
+<b>running</b>
+<code class="typeof">boolean</code>
+<span class="required-true">required</span>
+<p>
+Boolean field saying whether this bridge was listed
+as running in the last bridge network status.
+</p>
+</li>
+
+<li>
+<b>flags</b>
+<code class="typeof">array of strings</code>
+<span class="required-false">optional</span>
+<p>
+Array of relay flags that the bridge authority
+assigned to this bridge.
+Omitted if empty.
+</p>
+</li>
+
+<li>
+<b>last_restarted</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when the
+bridge was last (re-)started.
+Missing if router descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>advertised_bandwidth</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Bandwidth in bytes per second that this
+bridge is willing and capable to provide.
+This bandwidth value is the minimum of <strong>bandwidth_rate</strong>,
+<strong>bandwidth_burst</strong>, and <strong>observed_bandwidth</strong>.
+Missing if router descriptor containing this information cannot be
+found.
+</p>
+</li>
+
+<li>
+<b>platform</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+Platform string containing operating system and Tor
+version details.
+Omitted if not provided by the bridge or if descriptor containing this
+information cannot be found.
+</p>
+</li>
+
+<li>
+<b>transports</b>
+<code class="typeof">array of strings</code>
+<span class="required-false">optional</span>
+<p>
+Array of (pluggable) transport names supported by this bridge.
+</p>
+</li>
+
+</ul>
+
+</div> <!-- box -->
+
+<div class="box">
+<a name="history"></a>
+<h3>History objects <a href="#history">#</a></h3>
+
+<p>
+History objects are no documents by themselves, but are contained in
+subsequent documents.
+<p>
+
+<h4>Graph history objects</h4>
+
+<p>
+Graph history objects contain the following fields:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>first</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) of the first data point, or more
+specifically the interval midpoint of the first interval.
+</p>
+</li>
+
+<li>
+<b>last</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) of the last data point, or more
+specifically the interval midpoint of the last interval.
+</p>
+</li>
+
+<li>
+<b>interval</b>
+<code class="typeof">number</code>
+<span class="required-true">required</span>
+<p>
+Time interval between two data points in seconds.
+</p>
+</li>
+
+<li>
+<b>factor</b>
+<code class="typeof">number</code>
+<span class="required-true">required</span>
+<p>
+Factor by which subsequent data values need to be multiplied to obtain
+original values.
+The idea is to reduce document size while still providing sufficient
+detail for very different data scales.
+</p>
+</li>
+
+<li>
+<b>count</b>
+<code class="typeof">number</code>
+<span class="required-false">optional</span>
+<p>
+Number of provided data points, included mostly for debugging purposes.
+Can also be derived from the number of elements in the subsequent array.
+</p>
+</li>
+
+<li>
+<b>values</b>
+<code class="typeof">array of numbers</code>
+<span class="required-true">required</span>
+<p>
+Array of normalized values between 0 and 999.
+May contain null values.
+Contains at least two subsequent non-null values to enable drawing of line
+graphs.
+</p>
+</li>
+
+</ul>
+
+</div> <!-- box -->
+
+<div class="box">
+<a name="bandwidth"></a>
+<h3>Bandwidth documents <a href="#bandwidth">#</a>
+<span class="request-response">
+<a href="bandwidth?limit=4">example request</a>
+</span>
+</h3>
+
+<p>
+Bandwidth documents contain aggregate statistics of a relay's or
+bridge's consumed bandwidth for different time intervals.
+Bandwidth documents are only updated when a relay or bridge publishes a
+new server descriptor, which may take up to 18 hours during normal
+operation.
+Bandwidth documents contain the following fields:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>version</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Onionoo protocol version string.
+</p>
+</li>
+
+<li>
+<b>next_major_version_scheduled</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
+be deployed.
+Omitted if no major protocol changes are planned.
+</p>
+</li>
+
+<li>
+<b>relays_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known relay network status consensus started being valid.
+Indicates how recent the relay bandwidth documents in this document are.
+</p>
+</li>
+
+<li>
+<b>relays</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Array of relay bandwidth objects as specified below.
+</p>
+</li>
+
+<li>
+<b>bridges_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known bridge network status was published.
+Indicates how recent the bridge bandwidth documents in this document are.
+</p>
+</li>
+
+<li>
+<b>bridges</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Array of bridge bandwidth objects as specified below.
+</p>
+</li>
+
+</ul>
+
+<h4>Relay bandwidth objects</h4>
+
+<p>
+Relay bandwidth objects contain the following key-value pairs:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>fingerprint</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Relay fingerprint consisting of 40 upper-case
+hexadecimal characters.
+</p>
+</li>
+
+<li>
+<b>write_history</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing graph history objects with written bytes for different
+time periods.
+Keys are string representation of the time period covered by the graph
+history object.
+Keys are fixed strings <strong>"3_days"</strong>,
+<strong>"1_week"</strong>, <strong>"1_month"</strong>,
+<strong>"3_months"</strong>, <strong>"1_year"</strong>, and
+<strong>"5_years"</strong>.
+Keys refer to the last known bandwidth history of a relay, not to the time
+when the bandwidth document was published.
+A graph history object is only contained if the time period it covers is
+not already contained in another graph history object with shorter time
+period and higher data resolution.
+Similarly, a graph history object is excluded if the relay did not provide
+bandwidth histories on the required level of detail.
+The unit is bytes per second.
+Contained graph history objects may contain null values if the relay did
+not provide any bandwidth data or only data for less than 20% of a given
+time period.
+</p>
+</li>
+
+<li>
+<b>read_history</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing graph history objects with read bytes for different time
+periods.
+The specification of graph history objects is similar to those in the
+<strong>write_history</strong> field.
+</p>
+</li>
+
+</ul>
+
+<h4>Bridge bandwidth objects</h4>
+
+<p>
+Bridge bandwidth objects contain the following key-value pairs:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>fingerprint</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+SHA-1 hash of the bridge fingerprint consisting
+of 40 upper-case hexadecimal characters.
+</p>
+</li>
+
+<li>
+<b>write_history</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing graph history objects with written bytes for different
+time periods.
+The specification of graph history objects is similar to those in the
+<strong>write_history</strong> field of <strong>relays</strong>.
+</p>
+</li>
+
+<li>
+<b>read_history</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing graph history objects with read bytes for different time
+periods.
+The specification of graph history objects is similar to those in the
+<strong>write_history</strong> field of <strong>relays</strong>.
+</p>
+</li>
+
+</ul>
+
+</div> <!-- box -->
+
+<div class="box">
+<a name="weights"></a>
+<h3>Weights documents <a href="#weights">#</a>
+<span class="request-response">
+<a href="weights?limit=4">example request</a>
+</span>
+</h3>
+
+<p>
+Weights documents contain aggregate statistics of a relay's probability
+to be selected by clients for building paths.
+Weights documents contain different time intervals and are available for
+relays only.
+Weights documents contain the following fields:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>version</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Onionoo protocol version string.
+</p>
+</li>
+
+<li>
+<b>next_major_version_scheduled</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
+be deployed.
+Omitted if no major protocol changes are planned.
+</p>
+</li>
+
+<li>
+<b>relays_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known relay network status consensus started being valid.
+Indicates how recent the relay weights documents in this document are.
+</p>
+</li>
+
+<li>
+<b>relays</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Array of relay weights objects as specified below.
+</p>
+</li>
+
+<li>
+<b>bridges_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known bridge network status was published.
+Only included for compatibility reasons with the other document types.
+</p>
+</li>
+
+<li>
+<b>bridges</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Empty array of objects that would represent bridge weights documents.
+Only included for compatibility reasons with the other document types.
+</p>
+</li>
+
+</ul>
+
+<h4>Relay weights objects</h4>
+
+<p>
+Relay weights objects contain the following key-value pairs: 
+</p>
+
+<ul class="properties">
+
+<li>
+<b>fingerprint</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Relay fingerprint consisting of 40 upper-case
+hexadecimal characters.
+</p>
+</li>
+
+<li>
+<b>consensus_weight_fraction</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+History object containing the
+fraction of this relay's consensus weight compared to the sum of all
+consensus weights in the network.
+This fraction is a very rough approximation of the probability of this
+relay to be selected by clients.
+Keys are string representation of the time period covered by the graph
+history object.
+Keys are fixed strings <strong>"1_week"</strong>,
+<strong>"1_month"</strong>, <strong>"3_months"</strong>,
+<strong>"1_year"</strong>, and <strong>"5_years"</strong>.
+Keys refer to the last known weights history of a relay, not to the time
+when the weights document was published.
+A graph history object is only contained if the time period it covers is
+not already contained in another graph history object with shorter time
+period and higher data resolution.
+The unit is path-selection probability.
+Contained graph history objects may contain null values if the relay was
+running less than 20% of a given time period.
+</p>
+</li>
+
+<li>
+<b>guard_probability</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+History object containing the probability
+of this relay to be selected for the guard position.
+This probability is calculated based on consensus weights, relay flags,
+and bandwidth weights in the consensus.
+Path selection depends on more factors, so that this probability can only
+be an approximation.
+The specification of this history object is similar to that in the
+<strong>consensus_weight_fraction</strong> field above.
+</p>
+</li>
+
+<li>
+<b>middle_probability</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+History object containing the probability
+of this relay to be selected for the middle position.
+This probability is calculated based on consensus weights, relay flags,
+and bandwidth weights in the consensus.
+Path selection depends on more factors, so that this probability can only
+be an approximation.
+The specification of this history object is similar to that in the
+<strong>consensus_weight_fraction</strong> field above.
+</p>
+</li>
+
+<li>
+<b>exit_probability</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+History object containing the probability
+of this relay to be selected for the exit position.
+This probability is calculated based on consensus weights, relay flags,
+and bandwidth weights in the consensus.
+Path selection depends on more factors, so that this probability can only
+be an approximation.
+The specification of this history object is similar to that in the
+<strong>consensus_weight_fraction</strong> field above.
+</p>
+</li>
+
+<li>
+<b>consensus_weight</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+History object containing the absolute consensus weight of this relay.
+The specification of this history object is similar to that in the
+<strong>consensus_weight_fraction</strong> field above.
+</p>
+</li>
+
+</ul>
+
+</div> <!-- box -->
+
+<div class="box">
+<a name="clients"></a>
+<h3>Clients documents <a href="#clients">#</a>
+<span class="request-response">
+<a href="clients?limit=4">example request</a>
+</span>
+</h3>
+
+<p>
+Clients documents contain estimates of the average number of clients
+connecting to a bridge every day.
+There are no clients documents available for relays, just for bridges.
+Clients documents contain different time intervals and are available for
+bridges only.
+Clients documents contain the following fields:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>version</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Onionoo protocol version string.
+</p>
+</li>
+
+<li>
+<b>next_major_version_scheduled</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
+be deployed.
+Omitted if no major protocol changes are planned.
+</p>
+</li>
+
+<li>
+<b>relays_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known relay network status consensus started being valid.
+Only included for compatibility reasons with the other document types.
+</p>
+</li>
+
+<li>
+<b>relays</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Empty array of objects that would represent relay clients documents.
+Only included for compatibility reasons with the other document types.
+</p>
+</li>
+
+<li>
+<b>bridges_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known bridge network status was published.
+Indicates how recent the bridge clients documents in this document are.
+</p>
+</li>
+
+<li>
+<b>bridges</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Array of bridge clients objects as specified below.
+</p>
+
+</li>
+
+</ul>
+
+<h4>Bridge clients objects</h4>
+
+<p>
+Bridge clients objects contain the following key-value pairs:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>fingerprint</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+SHA-1 hash of the bridge fingerprint consisting
+of 40 upper-case hexadecimal characters.
+</p>
+</li>
+
+<li>
+<b>average_clients</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing graph history objects with the average number of clients
+connecting to this bridge.
+Keys are string representation of the time period covered by the graph
+history object.
+Keys are fixed strings <strong>"1_week"</strong>,
+<strong>"1_month"</strong>, <strong>"3_months"</strong>,
+<strong>"1_year"</strong>, and <strong>"5_years"</strong>.
+Keys refer to the last known clients history of a bridge, not to the time
+when the clients document was published.
+A graph history object is only contained if the time period it covers
+is not already contained in another clients graph object with shorter
+time period and higher data resolution.
+The unit is number of clients.
+Contained graph history objects may contain null values if the bridge did
+not report client statistics for at least 50% of a given time period.
+Each graph history object contains the following additional key-value
+pairs:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>countries</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing fractions of clients by country in the considered time
+period.
+Keys are two-letter lower-case country codes as found in a GeoIP database.
+Values are numbers between 0 and 1 standing for the fraction of clients by
+country.
+A country is only included if at least 1% of clients came from this
+country.
+Omitted if the bridge did not report client statistics by country.
+<font color="red"><strong>BETA:</strong> This field breaks compatibility
+with the history objects contained in other documents pretty badly.
+It might be removed in the future without notice.</font>
+</p>
+</li>
+
+<li>
+<b>transports</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing fractions of clients by transport in the considered time
+period.
+Keys are transport names, or <strong>"<OR>"</strong> for the default
+onion-routing transport protocol.
+Values are numbers between 0 and 1 standing for the fraction of clients by
+transport.
+Omitted if the bridge did not report client statistics by transport.
+<font color="red"><strong>BETA:</strong> This field breaks compatibility
+with the history objects contained in other documents pretty badly.
+It might be removed in the future without notice.</font>
+</p>
+</li>
+
+<li>
+<b>versions</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing fractions of clients by IP version in the considered
+time period.
+Keys are either <strong>"v4"</strong> for IPv4 or <strong>"v6"</strong>
+for IPv6.
+Values are numbers between 0 and 1 standing for the fraction of clients by
+version.
+Omitted if the bridge did not report client statistics by IP version.
+<font color="red"><strong>BETA:</strong> This field breaks compatibility
+with the history objects contained in other documents pretty badly.
+It might be removed in the future without notice.</font>
+</p>
+</li>
+
+</ul>
+
+</li>
+
+</ul>
+
+</div> <!-- box -->
+
+<div class="box">
+<a name="uptime"></a>
+<h3>Uptime documents <a href="#uptime">#</a>
+<span class="request-response">
+<a href="uptime?limit=4">example request</a>
+</span>
+</h3>
+
+<p>
+Uptime documents contain fractional uptimes of relays and bridges.
+Uptime documents contain different time intervals and are available for
+relays and bridges.
+Uptime documents contain the following fields:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>version</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Onionoo protocol version string.
+</p>
+</li>
+
+<li>
+<b>next_major_version_scheduled</b>
+<code class="typeof">string</code>
+<span class="required-false">optional</span>
+<p>
+UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
+be deployed.
+Omitted if no major protocol changes are planned.
+</p>
+</li>
+
+<li>
+<b>relays_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known relay network status consensus started being valid.
+Indicates how recent the relay uptime documents in this document are.
+</p>
+</li>
+
+<li>
+<b>relays</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Array of relay uptime objects as specified below.
+</p>
+</li>
+
+<li>
+<b>bridges_published</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+UTC timestamp (YYYY-MM-DD hh:mm:ss) when
+the last known bridge network status was published.
+Indicates how recent the bridge uptime documents in this document are.
+</p>
+</li>
+
+<li>
+<b>bridges</b>
+<code class="typeof">array of objects</code>
+<span class="required-true">required</span>
+<p>
+Array of bridge uptime objects as specified below.
+</p>
+</li>
+
+</ul>
+
+<h4>Relay uptime objects</h4>
+
+<p>
+Relay uptime objects contain the following key-value pairs:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>fingerprint</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+Relay fingerprint consisting of 40 upper-case
+hexadecimal characters.
+</p>
+</li>
+
+<li>
+<b>uptime</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing graph history objects with the fractional uptime of this
+relay.
+Keys are string representation of the time period covered by the graph
+history object.
+Keys are fixed strings <strong>"1_week"</strong>,
+<strong>"1_month"</strong>, <strong>"3_months"</strong>,
+<strong>"1_year"</strong>, and <strong>"5_years"</strong>.
+Keys refer to the last known uptime history of a relay, not to the time
+when the uptime document was published.
+A graph history object is only contained if the time period it covers is
+not already contained in another graph history object with shorter time
+period and higher data resolution.
+The unit is fractional uptime from 0 to 1.
+Contained graph history objects may contain null values if less than 20%
+of network statuses have been processed for a given time period.
+</p>
+</li>
+
+<li>
+<b>flags</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing fractional times of this relay having relay flags
+assigned.
+Keys are flag names like <strong>"Running"</strong> or
+<strong>"Exit"</strong>, values are objects similar to the
+<strong>uptime</strong> field above, again with keys like
+<strong>"1_week"</strong> etc.
+If a relay never had a given relay flag assigned, no object is included
+for that flag.
+</p>
+</li>
+
+</ul>
+
+<h4>Bridge uptime objects</h4>
+
+<p>
+Bridge uptime objects contain the following key-value pairs:
+</p>
+
+<ul class="properties">
+
+<li>
+<b>fingerprint</b>
+<code class="typeof">string</code>
+<span class="required-true">required</span>
+<p>
+SHA-1 hash of the bridge fingerprint consisting
+of 40 upper-case hexadecimal characters.
+</p>
+</li>
+
+<li>
+<b>uptime</b>
+<code class="typeof">object</code>
+<span class="required-false">optional</span>
+<p>
+Object containing uptime history objects for different time periods.
+The specification of uptime history objects is similar to those in the
+<strong>uptime</strong> field of <strong>relays</strong>.
+</p>
+</li>
+
+</ul>
+
+</div> <!-- box -->
+
+<div class="box">
+<a name="examples"></a>
+<h3>Example usage <a href="#examples">#</a>
+</h3>
+
+<p>
+The following examples illustrate how to build requests for some trivial
+and some more complex use cases.
+While Onionoo is designed mainly for developers and not end users, there
+may be cases when it's easier to quickly write a specific query Onionoo
+rather than to find an Onionoo client that provides the desired
+information.
+</p>
+
+<pre>https://onionoo.torproject.org/summary?limit=4</pre>
+
+<p>
+This first query returns the first four summary documents that Onionoo can
+find.
+The <code>limit</code> parameter should always be used while developing
+new queries to avoid downloading huge responses.
+</p>
+
+<pre>https://onionoo.torproject.org/summary?limit=4&search=moria</pre>
+
+<p>
+The second query restricts results to relays and bridges containing the
+string "moria" in one of a few searched fields.
+</p>
+
+<pre>https://onionoo.torproject.org/details?limit=4&search=moria</pre>
+
+<p>
+The third query switches from the short summary documents to the longer
+details documents containing, well, more details.
+</p>
+
+<pre>https://onionoo.torproject.org/details?limit=4&search=moria&fields=nickname</pre>
+
+<p>
+The fourth query adds the <code>fields</code> parameter which removes all
+fields except the specified ones from the result.
+This parameter is only implemented for details documents.
+</p>
+
+<pre>https://onionoo.torproject.org/details?limit=4&search=moria&fields=nickname&order=-consensus_weight</pre>
+
+<p>
+The fifth query sorts results by relay consensus weight from largest to
+smallest.
+</p>
+
+<p>
+Obviously, this query can be made even more complex by adding more
+parameters, and in some cases this is necessary and useful.
+Please refer to the protocol specification for details.
+</p>
+
+</div> <!-- box -->
+
+</body>
+</html>
+
diff --git a/src/main/resources/web/robots.txt b/src/main/resources/web/robots.txt
new file mode 100644
index 0000000..9b19f8f
--- /dev/null
+++ b/src/main/resources/web/robots.txt
@@ -0,0 +1,8 @@
+User-agent: *
+Disallow: /summary
+Disallow: /details
+Disallow: /bandwidth
+Disallow: /weights
+Disallow: /clients
+Disallow: /uptime
+
diff --git a/web/css/style.css b/web/css/style.css
deleted file mode 100644
index e3caa4a..0000000
--- a/web/css/style.css
+++ /dev/null
@@ -1,36 +0,0 @@
-body { font-family: "Open Sans","lucida grande","Segoe UI",arial,verdana,
-  "lucida sans unicode",tahoma,sans-serif; background: #fafafa;
-  font-size: 13px; line-height: 22px; color: #222; }
-h3 { color: #7D4698; position: relative }
-a { color: #7D4698; text-decoration: none; font-weight: bold; }
-p { margin: 0; padding: 10px; }
-a[name] { padding: 0; margin: 0; }
-.box { max-width: 850px; width: 100%; margin: 0 auto 30px auto;
-  padding-bottom: 30px; background: white; border: 1px solid #eee; }
-.box > * { margin-left: 30px; margin-right: 30px; }
-.box h3 a { visibility: hidden; }
-.box:hover h3 a { visibility: visible; }
-.api-request { border-bottom: 1px solid #eee; position: relative }
-.request-url, .request-type, .request-response { padding: 8px 10px;
-  vertical-align: middle }
-.request-type { color: #57145F; display: inline-block; }
-.request-url { color: #333; font-size: 18px; }
-.request-response { position: absolute; color: #666; right: 0; }
-h3 .request-response { padding: 0 !important; }
-.api-urls>li:last-child { border-bottom: 0; }
-.required-true, .required-false, .typeof { display: inline-block;
-  vertical-align: middle; padding: 5px 10px; }
-.required-true { color: #1d7508; }
-.required-false { color: #aaa; }
-.properties { margin-top: 10px; margin-bottom: 10px;
-  border: 1px solid #eee; }
-.properties li { padding: 5px 0; }
-.properties li ul { border: 1px solid #eee; margin: 10px 10px 10px 40px;
-  background: white; }
-.properties .properties { margin-left: 10px; }
-.properties li:nth-child(even) { background: #fafafa; }
-.properties p { padding: 10px 15px; }
-.properties b { padding: 5px 10px; display: inline-block;
-  vertical-align: middle; }
-.api-urls{ margin-top: 30px; margin-bottom: 30px; }
-
diff --git a/web/favicon.ico b/web/favicon.ico
deleted file mode 100644
index 48060b1..0000000
Binary files a/web/favicon.ico and /dev/null differ
diff --git a/web/index.html b/web/index.html
deleted file mode 100644
index c7095ec..0000000
--- a/web/index.html
+++ /dev/null
@@ -1,141 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
-<title>Onionoo — a Tor network status protocol</title>
-<link href="css/style.css" type="text/css" rel="stylesheet">
-<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
-<link href="favicon.ico" type="image/x-icon" rel="shortcut icon">
-</head>
-<body>
-
-<div class="box">
-
-<h1><a href="index.html">Onionoo</a> —</h1>
-<h2>a Tor network status <a href="protocol.html">protocol</a></h2>
-
-<p>Onionoo is a web-based protocol to learn about currently running
-Tor relays and bridges.  Onionoo itself was not designed as a service
-for human beings—at least not directly.  Onionoo provides the
-data for other applications and websites which in turn present Tor
-network status information to humans.  The following Onionoo clients
-are currently available:</p>
-<ul>
-<li><a href="https://atlas.torproject.org/">Atlas</a> is a web
-application to discover Tor relays. It provides useful
-information on how relays are configured along with graphics about
-their past.</li>
-<li><a href="https://compass.torproject.org/">Compass</a>
-is a Python script and website that extracts consensus weight
-information of currently running relays and aggregates weights of
-relays running in the same country or same autonomous system.</li>
-<li><a href="http://tor2web.org/">Tor2web</a> is a web proxy to Tor
-Hidden Services. It uses Onionoo to get the list of currently running
-Tor Exits to detect if the client is a Tor user and if so redirect
-them to the .onion address.</li>
-<li>The <a href="https://nos-oignons.net/Services/index.en.html">Nos
-oignons</a> website uses Onionoo to visualize bandwidth histories of
-their relays.</li>
-<li>The <a href="https://metrics.torproject.org/bubbles.html">metrics
-website</a> visualizes diversity of the Tor network using bubble
-graphs.</li>
-<li><a href="https://github.com/woeisme/torchart">torchart</a> is a PHP
-WordPress plugin which draws 3 day traffic charts using pChart currently
-used for displaying metric charts on
-<a href="http://icetor.is/wordpress/metrics/">icetor.is</a>.</li>
-<li><a href="https://github.com/kloesing/challenger">challenger</a>
-aggregates graph data from relays participating in
-<a href="https://www.eff.org/torchallenge/">EFF's 2014 Tor Challenge</a>
-to provide statistics like total bytes transferred.</li>
-<li><a href="https://play.google.com/store/apps/details?id=com.networksaremadeofstring.anonionooid">AnOnionooid</a>
-is an Android app that helps find and explore Tor relays and bridges.</li>
-<li><a href="https://oniontip.com/">OnionTip</a> uses Onionoo's data to
-distribute donations to relays that have a bitcoin address in their
-contact line.</li>
-<li><a href="https://savannah.nongnu.org/projects/koninoo/">koninoo</a> is
-a simple Java command line interface for querying Onionoo data.</li>
-<li>The <a href="https://duckduckgo.com/">DuckDuckGo</a> search engine
-displays Tor node details when being asked for "tor node" followed by a
-search term.</li>
-<li><a href="https://onionview.com/">OnionView</a> is a simple web service
-which uses Tor relay data to plot the location of active Tor nodes onto an
-interactive map of the world.</li>
-</ul>
-
-<p>The following library facilitates development of Onionoo clients:</p>
-<ul>
-<li><a href="https://github.com/duk3luk3/onion-py">OnionPy</a> is a
-comprehensive pure-Python (2.7+) Onionoo wrapper with caching
-support.</li>
-</ul>
-
-<h2>Developing Onionoo applications</h2>
-
-<p>The project pages of the Onionoo clients listed above have further
-information for contacting the authors and contributing ideas or code.
-The authors will be happy to hear your thoughts!</p>
-
-<p>You don't find your favorite Onionoo client above?  Want to
-implement your own and tell us to add it to the list?  The Onionoo
-clients above are backed by a web-based
-<a href="protocol.html">protocol</a>, which
-facilitates developing new applications displaying Tor status
-information.  Here are a few ideas for new Onionoo clients:</p>
-<ul>
-<li>Tor controller extension: Extend
-<a href="https://www.torproject.org/projects/vidalia.html.en">Vidalia</a> and/or
-<a href="https://www.torproject.org/projects/arm.html.en">arm</a> to look up details for the bridge
-that the user is running and display what pool the bridge is contained
-in.</li>
-<li>Social network site plugin: Add a plugin to the social network
-site of your choice to show your friends what Tor relays and bridges
-you're running and how that helps users around the world.</li>
-<li>Desktop tray icon: Write a tray icon for your favorite desktop
-environment that tells you when your relay or bridge is down and that
-displays some basic usage statistics.</li>
-<li>E-mail notification service: Improve our e-mail notification
-service <a href="https://weather.torproject.org/">Weather</a> by
-implementing its own relay search or extending it to report when a
-bridge drops off the network.</li>
-<li>Command-line tool: Implement a command-line tool that quickly
-searches a relay or bridge and prints out some status information to
-help debug problems.</li>
-<li>(Insert your idea here.)</li>
-</ul>
-
-<p>Want to help with developing the Onionoo server that provides
-Tor status data, or want to run your own Onionoo server instance?  The
-Onionoo server is written in Java with a tiny portion of Java
-Servlets.  Instructions for setting up the Onionoo server to fetch the
-required data from the Tor servers is described in the INSTALL file in
-the sources.  For more details see the
-<a href="https://gitweb.torproject.org/onionoo.git">source code</a> and
-<a href="https://trac.torproject.org/projects/tor/query?status=!closed&component=Onionoo">issue
-tracker</a>.</p>
-
-<h2>Related projects</h2>
-
-<p>TorStatus is the name of a nowadays
-<a href="https://svn.torproject.org/svn/torstatus/trunk/">unmaintained</a>
-website that displays Tor relay information similar to
-<a href="http://atlas.torproject.org/">Atlas</a>.  There are still a
-few <a href="http://torstatus.blutmagie.de/">TorStatus</a>
-<a href="https://torstatus.rueckgr.at/">websites</a>
-<a href="http://tns.hermetix.org/">running</a>.</p>
-
-<p>There's another project from summer 2011 called TorStatus which is
-a <a href="https://gitweb.torproject.org/torstatus.git">rewrite</a> of
-the original TorStatus in Python/Django.  Unfortunately, it's also
-unmaintained.</p>
-
-<p>Finally, there's the
-<a href="https://consensus-health.torproject.org/">consensus-health
-page</a> which has the primary purpose of indicating problems with
-creating a network status consensus.  As a side-effect this page lists
-all currently running relays and how the directory authorities voted
-on them.</p>
-
-</div> <!-- box -->
-
-</body>
-</html>
-
diff --git a/web/protocol.html b/web/protocol.html
deleted file mode 100644
index c6cc534..0000000
--- a/web/protocol.html
+++ /dev/null
@@ -1,2338 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
-<title>Onionoo — protocol overview</title>
-<link href="css/style.css" type="text/css" rel="stylesheet">
-<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
-<link href="favicon.ico" type="image/x-icon" rel="shortcut icon">
-</head>
-<body>
-
-<div class="box">
-
-<h1><a href="index.html">Onionoo</a> —</h1>
-<h2>protocol overview</h2>
-
-    <h4>Table of contents</h4>
-    <ul>
-        <li><a href="#general">General</a></li>
-        <li><a href="#methods">Methods</a></li>
-        <li><a href="#summary">Summary documents</a></li>
-        <li><a href="#details">Details documents</a></li>
-        <li><a href="#history">History objects</a></li>
-        <li><a href="#bandwidth">Bandwidth documents</a></li>
-        <li><a href="#weights">Weights documents</a></li>
-        <li><a href="#clients">Clients documents</a></li>
-        <li><a href="#uptime">Uptime documents</a></li>
-        <li><a href="#examples">Example usage</a></li>
-    </ul>
-
-</div>
-<div class="box">
-
-<a name="general"></a>
-<h3>General <a href="#general">#</a></h3>
-
-<p>
-The Onionoo service is designed as a RESTful web service.
-Onionoo clients send HTTP GET requests to the Onionoo server which
-responds with JSON-formatted replies.
-Onionoo clients and their developers should follow a few rules:
-</p>
-
-<h4>Compression</h4>
-<p>
-Clients should include an <strong>"Accept-Encoding:
-gzip"</strong> header in their requests and handle gzip-compressed
-responses.
-Only requests starting at a certain size will be compressed by the
-server.
-</p>
-
-<h4>Caching</h4>
-<p>Clients should make use of the <strong>"Last-Modified"</strong>
-header of responses and include that timestamp in a
-<strong>"If-Modified-Since"</strong> header of subsequent requests.
-</p>
-
-<h4>Response codes</h4>
-<p>
-Clients should handle response codes by
-distinguishing between client and server errors, and if there's a problem,
-informing their users about the kind of problem.
-The following response codes are used:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>200 OK</b>
-<p>
-The request was processed successfully.
-</p>
-</li>
-
-<li>
-<b>304 Not Modified</b>
-<p>
-Server data has not changed since the
-<strong>"If-Modified-Since"</strong> header included in the request.
-</p>
-</li>
-
-<li>
-<b>400 Bad Request</b>
-<p>
-The request for a known resource could not be processed because of bad
-syntax.
-This is most likely a client problem.
-</p>
-</li>
-
-<li>
-<b>404 Not Available</b>
-<p>
-The request could not be processed because the requested resource could
-not be found.
-This is most likely a client problem.
-</p>
-</li>
-
-<li>
-<b>500 Internal Server Error</b>
-<p>
-There is an unspecific problem with
-the server which the service operator may not yet be aware of.
-Please check if there's already a bug report for this problem, and if not,
-file one.
-</p>
-</li>
-
-<li>
-<b>503 Service Unavailable</b>
-<p>
-The server is temporarily down for
-maintenance, or there is a temporary problem with the server that the
-service operator is already aware of.
-Only file a bug report if this problem persists.
-</p>
-</li>
-
-</ul>
-
-<h4>Protocol versions</h4>
-<p>
-There are plenty of reasons why we may have
-to change the protocol described here.
-Clients should be able to handle all valid JSON responses, ignoring
-unknown fields and not breaking horribly in case of missing fields.
-Protocol changes will be announced here by writing deprecated API parts in
-<strong><font color="red">red</font></strong> and new parts in
-<strong><font color="blue">blue</font></strong>.
-Deprecated parts will be removed one month after their announcement.
-If you want to be informed of upcoming protocol changes, subscribe to the
-<a href="https://lists.torproject.org/cgi-bin/mailman/listinfo/onionoo-announce">onionoo-announce</a>
-mailing list.
-</p>
-
-<p>All responses contain a <strong>"version"</strong> string that
-indicates whether clients can parse the document or not.
-Version strings consist of a major and a minor version number.
-The major version number is raised when previously required fields are
-dropped or turned into optional fields, when request parameters or
-response documents are removed, or when there are structural changes.
-The minor version number is raised when new fields, request parameters, or
-response documents are added or optional fields are dropped.
-If clients support the same major version given in a response but only a
-lower minor version, they should be able to parse the document but may not
-understand all fields.
-If clients support a lower major version, they should not attempt to parse
-a document, because there may be backward-incompatible changes.</p>
-
-<p>Responses may also contain the optional
-<strong>"next_major_version_scheduled"</strong> field that announces when
-the next major version is scheduled to be deployed.
-Clients should inform their users that they should upgrade to the next
-major protocol version before the provided date.</p>
-
-<p>The following versions have been used in the past six months or are
-scheduled to be deployed in the next months:</p>
-
-<ul>
-<li><strong>1.0</strong>: First assigned version number on August 31,
-2014.</li>
-<li><strong>1.1</strong>: Added optional "next_major_version_scheduled"
-field on September 16, 2014.</li>
-<li><strong>1.2</strong>: Added qualified search terms to "search"
-parameter on October 17, 2014.</li>
-<li><strong>2.0</strong>: Extended search parameter to base64-encoded
-fingerprints on November 15, 2014.</li>
-<li><strong>2.1</strong>: Removed optional "advertised_bandwidth_fraction"
-field from details documents and optional "advertised_bandwidth" and
-"advertised_bandwidth_fraction" fields from weights documents on November
-16, 2014.</li>
-<li><strong>2.2</strong>: Removed optional "pool_assignment" field and
-added "transports" field to bridge details documents on December 8,
-2014.</li>
-<li><strong>2.3</strong>: Added optional "flags" field to uptime
-documents on March 22, 2015.</li>
-<li><strong>2.4</strong>: Added optional "effective_family" field to
-details documents on July 3, 2015.</li>
-<li><strong>2.5</strong>: Added optional "measured" field to details
-documents on August 13, 2015.</li>
-<li><strong>2.6</strong>: Added optional "alleged_family" and
-"indirect_family" fields and deprecated optional "family" field in details
-documents on August 25, 2015.</li>
-<li><strong>3.0</strong>: Extended search parameter to match any 4 hex
-characters of a space-separated fingerprint on November 15, 2015.</li>
-<li><strong>3.1</strong>: Removed optional "family" field on January 18,
-2016.</li>
-</ul>
-
-</div> <!-- box -->
-
-<div class="box">
-
-<a name="methods"></a>
-<h3>Methods <a href="#methods">#</a></h3>
-
-<p>
-The following methods each return a single document containing zero or
-more objects of relays and/or bridges.
-By default, all relays and bridges are included that have been running in
-the past week.
-</p>
-
-<ul class="api-urls">
-
-<li class="api-request">
-<span class="request-type">GET</span>
-<span class="request-url">https://onionoo.torproject.org/summary</span>
-<span class="request-response">returns a <a href="#summary">summary
-document</a></span>
-</li>
-
-<li class="api-request">
-<span class="request-type">GET</span>
-<span class="request-url">https://onionoo.torproject.org/details</span>
-<span class="request-response">returns a <a href="#details">details
-document</a></span>
-</li>
-
-<li class="api-request">
-<span class="request-type">GET</span>
-<span class="request-url">https://onionoo.torproject.org/bandwidth</span>
-<span class="request-response">returns a <a href="#bandwidth">bandwidth
-document</a></span>
-</li>
-
-<li class="api-request">
-<span class="request-type">GET</span>
-<span class="request-url">https://onionoo.torproject.org/weights</span>
-<span class="request-response">returns a <a href="#weights">weights
-document</a></span>
-</li>
-
-<li class="api-request">
-<span class="request-type">GET</span>
-<span class="request-url">https://onionoo.torproject.org/clients</span>
-<span class="request-response">returns a <a href="#clients">clients
-document</a></span>
-</li>
-
-<li class="api-request">
-<span class="request-type">GET</span>
-<span class="request-url">https://onionoo.torproject.org/uptime</span>
-<span class="request-response">returns a <a href="#uptime">uptime
-document</a></span>
-</li>
-
-</ul>
-
-<h4>Parameters</h4>
-<p>
-Each of the methods can be parameterized to select only a subset of relay
-and/or bridge documents that are currently running or that have been
-running in the past week.
-(The <strong>fingerprint</strong> parameter is special here, because it
-allows selecting a specific relay or bridge, regardless of whether it has
-been running in the past week.)
-If multiple parameters are specified, they are combined using a logical
-AND operation, meaning that only the intersection of relays and bridges
-matching all parameters is returned.
-If the same parameter is specified more than once, only the first
-parameter value is considered.
-</p>
-
-<ul class="properties">
-
-<li>
-<b>type</b>
-<p>
-Return only relay (parameter value
-<strong>relay</strong>) or only bridge documents (parameter value
-<strong>bridge</strong>).
-Parameter values are case-insensitive.
-</p>
-</li>
-
-<li>
-<b>running</b>
-<p>
-Return only running (parameter value
-<strong>true</strong>) or only non-running relays and/or bridges
-(paramter value
-<strong>false</strong>).
-Parameter values are case-insensitive.
-</p>
-</li>
-
-<li>
-<b>search</b>
-<p>
-Return only (1) relays with the parameter value matching (part of a)
-nickname, (possibly $-prefixed) beginning of a hex-encoded fingerprint,
-any 4 hex characters of a space-separated fingerprint, beginning of a
-base64-encoded fingerprint without trailing equal signs, or beginning of
-an IP address, (2) bridges with (part of a) nickname or (possibly
-$-prefixed) beginning of a hashed hex-encoded fingerprint, and (3) relays
-and/or bridges matching a given qualified search term.
-Searches by relay IP address include all known addresses used for onion
-routing and for exiting to the Internet.
-Searches for beginnings of IP addresses are performed on textual
-representations of canonical IP address forms, so that searches using CIDR
-notation or non-canonical forms will return empty results.
-Searches are case-insensitive, except for base64-encoded fingerprints.
-If multiple search terms are given, separated by spaces, the intersection
-of all relays and bridges matching all search terms will be returned.
-Complete hex-encoded fingerprints should always be hashed using SHA-1,
-regardless of searching for a relay or a bridge, in order to not
-accidentally leak non-hashed bridge fingerprints in the URL.
-Qualified search terms have the form "key:value" (without double quotes)
-with "key" being one of the parameters listed here except for "search",
-"fingerprint", "order", "limit", "offset", and "fields", and "value" being
-the string that will internally be passed to that parameter.
-</p>
-</li>
-
-<li>
-<b>lookup</b>
-<p>
-Return only the relay with the parameter
-value matching the fingerprint or the bridge with the parameter value
-matching the hashed fingerprint.
-Fingerprints should always be hashed using SHA-1, regardless of looking up
-a relay or a bridge, in order to not accidentally leak non-hashed bridge
-fingerprints in the URL.
-Lookups only work for full fingerprints or hashed fingerprints consisting
-of 40 hex characters.
-Lookups are case-insensitive.
-</p>
-</li>
-
-<li>
-<b>fingerprint</b>
-<p>
-Return only the relay with the parameter value matching the fingerprint
-or the bridge with the parameter value matching the hashed fingerprint.
-Fingerprints must consist of 40 hex characters, case does not matter.
-This parameter is quite similar to the <strong>lookup</strong> parameter
-with two exceptions:
-(1) the provided relay fingerprint or hashed bridge fingerprint <i>must
-not</i> be hashed (again) using SHA-1;
-(2) the response will contain any matching relay or bridge regardless of
-whether they have been running in the past week.
-</p>
-</li>
-
-<li>
-<b>country</b>
-<p>
-Return only relays which are located in the
-given country as identified by a two-letter country code.
-Filtering by country code is case-insensitive.
-</p>
-</li>
-
-<li>
-<b>as</b>
-<p>
-Return only relays which are located in the
-given autonomous system (AS) as identified by the AS number (with or
-without preceding "AS" part).
-Filtering by AS number is case-insensitive.
-</p>
-</li>
-
-<li>
-<b>flag</b>
-<p>
-Return only relays which have the
-given relay flag assigned by the directory authorities.
-Note that if the flag parameter is specified more than once, only the
-first parameter value will be considered.
-Filtering by flag is case-insensitive.
-</p>
-</li>
-
-<li>
-<b>first_seen_days</b>
-<p>
-Return only relays or bridges which
-have first been seen during the given range of days ago.
-A parameter value "x-y" with x <= y returns relays or bridges that have
-first been seen at least x and at most y days ago.
-Accepted short forms are "x", "x-", and "-y" which are interpreted as
-"x-x", "x-infinity", and "0-y".
-</p>
-</li>
-
-<li>
-<b>last_seen_days</b>
-<p>
-Return only relays or bridges which
-have last been seen during the given range of days ago.
-A parameter value "x-y" with x <= y returns relays or bridges that have
-last been seen at least x and at most y days ago.
-Accepted short forms are "x", "x-", and "-y" which are interpreted as
-"x-x", "x-infinity", and "0-y".
-Note that relays and bridges that haven't been running in the past week
-are not included in results, so that setting x to 8 or higher will lead to
-an empty result set.
-</p>
-</li>
-
-<li>
-<b>contact</b>
-<p>
-Return only relays with the parameter value
-matching (part of) the contact line.
-If the parameter value contains spaces, only relays are returned which
-contain all space-separated parts in their contact line.
-Only printable ASCII characters are permitted in the parameter value,
-some of which need to be percent-encoded (# as %23, % as %25, & as
-%26, + as %2B, and / as %2F).
-Comparisons are case-insensitive.
-</p>
-</li>
-
-<li>
-<b>family</b>
-<p>
-Return only the relay whose fingerprint matches the parameter value and
-all relays that this relay has listed in its family by fingerprint and
-that in turn have listed this relay in their family by fingerprint.
-If relays have listed other relays in their family by nickname, those
-family relationships will not be considered, regardless of whether they
-have the Named flag or not.
-The provided relay fingerprint must consist of 40 hex characters where
-case does not matter, and it must not be hashed using SHA-1.
-Bridges are not contained in the result, regardless of whether they define
-a family.
-</p>
-</li>
-
-</ul>
-
-<p>
-Response documents can be reduced in size by requesting only a subset
-of contained fields.
-</p>
-
-<ul class="properties">
-
-<li>
-<b>fields</b>
-<p>
-Comma-separated list of fields that will be
-included in the result.
-So far, only top-level fields in relay or bridge objects of details
-documents can be specified, e.g.,
-<strong>nickname,hashed_fingerprint</strong>.
-If the fields parameter is provided, all other fields which are not
-contained in the provided list will be removed from the result.
-Field names are case-insensitive.
-</p>
-</li>
-
-</ul>
-
-<p>
-Relay and/or bridge documents in the response can be ordered and
-limited by providing further parameters.
-If the same parameter is specified more than once, only the first
-parameter value is considered.
-</p>
-
-<ul class="properties">
-
-<li>
-<b>order</b>
-<p>
-Re-order results by a comma-separated list
-of fields in ascending or descending order.
-Results are first ordered by the first list element, then by the second,
-and so on.
-Possible fields for ordering are: <strong>consensus_weight</strong>.
-Field names are case-insensitive.
-Ascending order is the default; descending order is selected by prepending
-fields with a minus sign (<strong>-</strong>).
-Relays or bridges which don't have any value for a field to be ordered by
-are always appended to the end, regardless or sorting order.
-The ordering is defined independent of the requested document type and
-does not require the ordering field to be contained in the document.
-If no <strong>order</strong> parameter is given, ordering of results is
-undefined.
-</p>
-</li>
-
-<li>
-<b>offset</b>
-<p>
-Skip the given number of relays and/or
-bridges.
-Relays are skipped first, then bridges.
-Non-positive <strong>offset</strong> values are treated as zero and don't
-change the
-result.
-</p>
-</li>
-
-<li>
-<b>limit</b>
-<p>
-Limit result to the given number of
-relays and/or bridges.
-Relays are kept first, then bridges.
-Non-positive <strong>limit</strong> values are treated as zero and lead
-to an empty
-result.
-When used together with <strong>offset</strong>, the offsetting step
-precedes the
-limiting step.
-</p>
-</li>
-
-</ul>
-
-</div> <!-- box -->
-
-<div class="box">
-<a name="summary"></a>
-<h3>Summary documents <a href="#summary">#</a>
-<span class="request-response">
-<a href="summary?limit=4">example request</a>
-</span>
-</h3>
-
-<p>Summary documents contain short summaries of relays with nicknames,
-fingerprints, IP addresses, and running information as well as bridges
-with hashed fingerprints and running information.
-Summary documents contain the following fields:</p>
-
-<ul class="properties">
-
-<li>
-<b>version</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Onionoo protocol version string.
-</p>
-</li>
-
-<li>
-<b>next_major_version_scheduled</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
-be deployed.
-Omitted if no major protocol changes are planned.
-</p>
-</li>
-
-<li>
-<b>relays_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when the last known relay network
-status consensus started being valid.
-Indicates how recent the relay summaries in this document are.
-</p>
-</li>
-
-<li>
-<b>relays</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Array of relay summary objects as specified below.
-</p>
-</li>
-
-<li>
-<b>bridges_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known bridge network status was published.
-Indicates how recent the bridge summaries in this document are.
-</p>
-</li>
-
-<li>
-<b>bridges</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Array of bridge summary objects as specified below.
-</p>
-</li>
-
-</ul>
-
-<h4>Relay summary objects</h4>
-
-<p>
-Relay summary objects contain the following key-value pairs:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>n</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Relay nickname consisting of 1–19 alphanumerical characters.
-Omitted if the relay nickname is <strong>"Unnamed"</strong>.
-</p>
-</li>
-
-<li>
-<b>f</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Relay fingerprint consisting of 40 upper-case hexadecimal characters.
-</p>
-</li>
-
-<li>
-<b>a</b>
-<code class="typeof">array of strings</code>
-<span class="required-true">required</span>
-<p>
-Array of IPv4 or IPv6 addresses where the relay accepts
-onion-routing connections or which the relay used to exit to the Internet
-in the past 24 hours.
-The first address is the primary onion-routing address that the relay used
-to register in the network, subsequent addresses are in arbitrary order.
-IPv6 hex characters are all lower-case.
-</p>
-</li>
-
-<li>
-<b>r</b>
-<code class="typeof">boolean</code>
-<span class="required-true">required</span>
-<p>
-Boolean field saying whether this relay was listed as
-running in the last relay network status consensus.
-</p>
-</li>
-
-</ul>
-
-<h4>Bridge summary objects</h4>
-
-<p>
-Bridge summary objects contain the following key-value pairs:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>n</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Bridge nickname consisting of 1–19 alphanumerical characters.
-Omitted if the bridge nickname is <strong>"Unnamed"</strong>.
-</p>
-</li>
-
-<li>
-<b>h</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-SHA-1 hash of the bridge fingerprint consisting of 40
-upper-case hexadecimal characters.
-</p>
-</li>
-
-<li>
-<b>r</b>
-<code class="typeof">boolean</code>
-<span class="required-true">required</span>
-<p>
-Boolean field saying whether this bridge was listed as
-running in the last bridge network status.
-</p>
-</li>
-
-</ul>
-
-</div> <!-- box -->
-
-<div class="box">
-<a name="details"></a>
-<h3>Details documents <a href="#details">#</a>
-<span class="request-response">
-<a href="details?limit=4">example request</a>
-</span>
-</h3>
-
-<p>
-Details documents are based on network statuses published by the Tor
-directories, server descriptors published by relays and bridges, and data
-published by Tor network services TorDNSEL and BridgeDB.
-Details documents use the most recently published data from these sources,
-which may lead to contradictions between fields based on different sources
-in rare edge cases.
-Details documents contain the following fields:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>version</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Onionoo protocol version string.
-</p>
-</li>
-
-<li>
-<b>next_major_version_scheduled</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
-be deployed.
-Omitted if no major protocol changes are planned.
-</p>
-</li>
-
-<li>
-<b>relays_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known relay network status consensus started being valid.
-Indicates how recent the relay details in this document are.
-</p>
-</li>
-
-<li>
-<b>relays</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Array of relay details objects as specified below.
-</p>
-</li>
-
-<li>
-<b>bridges_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known bridge network status was published.
-Indicates how recent the bridge details in this document are.
-</p>
-</li>
-
-<li>
-<b>bridges</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Array of bridge details objects as specified below.
-</p>
-
-</li>
-
-</ul>
-
-<h4>Relay details objects</h4>
-
-<p>
-Relay details objects contain the following key-value pairs:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>nickname</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Relay nickname consisting of 1–19 alphanumerical characters.
-Omitted if the relay nickname is <strong>"Unnamed"</strong>.
-</p>
-</li>
-
-<li>
-<b>fingerprint</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Relay fingerprint consisting of 40 upper-case
-hexadecimal characters.
-</p>
-</li>
-
-<li>
-<b>or_addresses</b>
-<code class="typeof">array of strings</code>
-<span class="required-true">required</span>
-<p>
-Array of IPv4 or IPv6 addresses and TCP ports
-or port lists where the relay accepts onion-routing connections.
-The first address is the primary onion-routing address that the relay used
-to register in the network, subsequent addresses are in arbitrary order.
-IPv6 hex characters are all lower-case.
-</p>
-</li>
-
-<li>
-<b>exit_addresses</b>
-<code class="typeof">array of strings</code>
-<span class="required-false">optional</span>
-<p>
-Array of IPv4 or IPv6 addresses that the
-relay used to exit to the Internet in the past 24 hours.
-IPv6 hex characters are all lower-case.
-Only those addresses are listed that are different from onion-routing
-addresses.
-Omitted if array is empty.
-</p>
-</li>
-
-<li>
-<b>dir_address</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-IPv4 address and TCP port where the relay
-accepts directory connections.
-Omitted if the relay does not accept directory connections.
-</p>
-</li>
-
-<li>
-<b>last_seen</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when this
-relay was last seen in a network status consensus.
-</p>
-</li>
-
-<li>
-<b>last_changed_address_or_port</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD
-hh:mm:ss) when this relay last stopped announcing an IPv4 or IPv6 address
-or TCP port where it previously accepted onion-routing or directory
-connections.
-This timestamp can serve as indicator whether this relay would be a
-suitable fallback directory.
-</p>
-</li>
-
-<li>
-<b>first_seen</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when this
-relay was first seen in a network status consensus.
-</p>
-</li>
-
-<li>
-<b>running</b>
-<code class="typeof">boolean</code>
-<span class="required-true">required</span>
-<p>
-Boolean field saying whether this relay was listed as
-running in the last relay network status consensus.
-</p>
-</li>
-
-<li>
-<b>hibernating</b>
-<code class="typeof">boolean</code>
-<span class="required-false">optional</span>
-<p>
-Boolean field saying whether this relay indicated that it is hibernating
-in its last known server descriptor.
-This information may be helpful to decide whether a relay that is not
-running anymore has reached its accounting limit and has not dropped out
-of the network for another, unknown reason.
-Omitted if either the relay is not hibernating, or if no information is
-available about the hiberation status of the relay.
-</p>
-</li>
-
-<li>
-<b>flags</b>
-<code class="typeof">array of strings</code>
-<span class="required-false">optional</span>
-<p>
-Array of relay flags that the directory authorities
-assigned to this relay.
-Omitted if empty.
-</p>
-</li>
-
-<li>
-<b>country</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Two-letter lower-case country code as found in a
-GeoIP database by resolving the relay's first onion-routing IP address.
-Omitted if the relay IP address could not be found in the GeoIP
-database.
-</p>
-</li>
-
-<li>
-<b>country_name</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Country name as found in a GeoIP database by
-resolving the relay's first onion-routing IP address.
-Omitted if the relay IP address could not be found in the GeoIP
-database, or if the GeoIP database did not contain a country name.
-</p>
-</li>
-
-<li>
-<b>region_name</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Region name as found in a GeoIP database by
-resolving the relay's first onion-routing IP address.
-Omitted if the relay IP address could not be found in the GeoIP
-database, or if the GeoIP database did not contain a region name.
-</p>
-</li>
-
-<li>
-<b>city_name</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-City name as found in a
-GeoIP database by resolving the relay's first onion-routing IP address.
-Omitted if the relay IP address could not be found in the GeoIP
-database, or if the GeoIP database did not contain a city name.
-</p>
-</li>
-
-<li>
-<b>latitude</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Latitude as found in a GeoIP database by resolving
-the relay's first onion-routing IP address.
-Omitted if the relay IP address could not be found in the GeoIP
-database.
-</p>
-</li>
-
-<li>
-<b>longitude</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Longitude as found in a GeoIP database by
-resolving the relay's first onion-routing IP address.
-Omitted if the relay IP address could not be found in the GeoIP
-database.
-</p>
-</li>
-
-<li>
-<b>as_number</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-AS number as found in an AS database by
-resolving the relay's first onion-routing IP address.
-AS number strings start with "AS", followed directly by the AS number.
-Omitted if the relay IP address could not be found in the AS
-database.
-</p>
-</li>
-
-<li>
-<b>as_name</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-AS name as found in an AS database by resolving the
-relay's first onion-routing IP address.
-Omitted if the relay IP address could not be found in the AS
-database.
-</p>
-</li>
-
-<li>
-<b>consensus_weight</b>
-<code class="typeof">number</code>
-<span class="required-true">required</span>
-<p>
-Weight assigned to this relay by the
-directory authorities that clients use in their path selection algorithm.
-The unit is arbitrary; currently it's kilobytes per second, but that might
-change in the future.
-</p>
-</li>
-
-<li>
-<b>host_name</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Host name as found in a reverse DNS lookup of the
-relay IP address.
-This field is updated at most once in 12 hours, unless the relay IP
-address changes.
-Omitted if the relay IP address was not looked up or if no lookup request
-was successful yet.
-</p>
-</li>
-
-<li>
-<b>last_restarted</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when the
-relay was last (re-)started.
-Missing if router descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>bandwidth_rate</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Average bandwidth
-in bytes per second that this relay is willing to sustain over long
-periods.
-Missing if router descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>bandwidth_burst</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Bandwidth in bytes
-per second that this relay is willing to sustain in very short intervals.
-Missing if router descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>observed_bandwidth</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Bandwidth
-estimate in bytes per second of the capacity this relay can handle.
-The relay remembers the maximum bandwidth sustained output over any ten
-second period in the past day, and another sustained input.
-The "observed_bandwidth" value is the lesser of these two numbers.
-Missing if router descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>advertised_bandwidth</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Bandwidth in bytes per second that this
-relay is willing and capable to provide.
-This bandwidth value is the minimum of <strong>bandwidth_rate</strong>,
-<strong>bandwidth_burst</strong>, and <strong>observed_bandwidth</strong>.
-Missing if router descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>exit_policy</b>
-<code class="typeof">array of strings</code>
-<span class="required-false">optional</span>
-<p>
-Array of exit-policy lines.
-Missing if router descriptor containing this information cannot be
-found.
-May contradict the <strong>"exit_policy_summary"</strong> field in a rare
-edge case: this happens when the relay changes its exit policy after the
-directory authorities summarized the previous exit policy.
-</p>
-</li>
-
-<li>
-<b>exit_policy_summary</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Summary
-version of the relay's exit policy containing a dictionary with either an
-"accept" or a "reject" element.
-If there is an "accept" ("reject") element, the relay accepts (rejects)
-all TCP ports or port ranges in the given list for most IP addresses and
-rejects (accepts) all other ports.
-May contradict the <strong>"exit_policy"</strong> field in a rare edge
-case: this happens when the relay changes its exit policy after the
-directory authorities summarized the previous exit policy.
-</p>
-</li>
-
-<li>
-<b>exit_policy_v6_summary</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Summary version of the relay's IPv6 exit policy containing a dictionary
-with either an "accept" or a "reject" element.
-If there is an "accept" ("reject") element, the relay accepts (rejects)
-all TCP ports or port ranges in the given list for most IP addresses and
-rejects (accepts) all other ports.
-Missing if the relay rejects all connections to IPv6 addresses.
-May contradict the <strong>"exit_policy_summary"</strong> field in a rare
-edge case: this happens when the relay changes its exit policy after the
-directory authorities summarized the previous exit policy.
-</p>
-</li>
-
-<li>
-<b>contact</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Contact address of the relay operator.
-Omitted if empty or if descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>platform</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Platform string containing operating system and Tor
-version details.
-Omitted if empty or if descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>recommended_version</b>
-<code class="typeof">boolean</code>
-<span class="required-false">optional</span>
-<p>
-Boolean field saying whether the Tor software version of this relay is
-recommended by the directory authorities or not.
-Omitted if either the directory authorities did not recommend versions, or
-the relay did not report which version it runs.
-</p>
-</li>
-
-<li>
-<b><font color="red">family</font></b>
-<code class="typeof">array of strings</code>
-<span class="required-false">optional</span>
-<p>
-Array of fingerprints or nicknames of relays that this relay considers to
-be part of its family.
-There are no cross-checks whether the listed relays exist or consider this
-relay part of their family, so that the effective family of this relay may
-be smaller.
-Omitted if empty or if descriptor containing this information cannot be
-found.
-<font color="red">Deprecated on August 25, 2015, removed on January 18,
-2016.</font>
-</p>
-</li>
-
-<li>
-<b>effective_family</b>
-<code class="typeof">array of strings</code>
-<span class="required-false">optional</span>
-<p>
-Array of $-prefixed fingerprints of relays that are in an effective,
-mutual family relationship with this relay.
-These relays are part of this relay's family and they consider this relay
-to be part of their family.
-Omitted if empty or if descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>alleged_family</b>
-<code class="typeof">array of strings</code>
-<span class="required-false">optional</span>
-<p>
-Array of $-prefixed fingerprints of relays that are not in an effective,
-mutual family relationship with this relay.
-These relays are part of this relay's family but they don't consider this
-relay to be part of their family.
-Omitted if empty or if descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>indirect_family</b>
-<code class="typeof">array of strings</code>
-<span class="required-false">optional</span>
-<p>
-Array of $-prefixed fingerprints of relays that are not in an effective,
-mutual family relationship with this relay but that can be reached by
-following effective, mutual family relationships starting at this relay.
-Omitted if empty or if descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>consensus_weight_fraction</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Fraction of this relay's consensus weight compared to the sum of all
-consensus weights in the network.
-This fraction is a very rough approximation of the probability of this
-relay to be selected by clients.
-Omitted if the relay is not running.
-</p>
-</li>
-
-<li>
-<b>guard_probability</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Probability of this relay to be selected for the guard position.
-This probability is calculated based on consensus weights, relay flags,
-and bandwidth weights in the consensus.
-Path selection depends on more factors, so that this probability can only
-be an approximation.
-Omitted if the relay is not running, or the consensus does not contain
-bandwidth weights.
-</p>
-</li>
-
-<li>
-<b>middle_probability</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Probability of this relay to be selected for the middle position.
-This probability is calculated based on consensus weights, relay flags,
-and bandwidth weights in the consensus.
-Path selection depends on more factors, so that this probability can only
-be an approximation.
-Omitted if the relay is not running, or the consensus does not contain
-bandwidth weights.
-</p>
-</li>
-
-<li>
-<b>exit_probability</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Probability of this relay to be selected for the exit position.
-This probability is calculated based on consensus weights, relay flags,
-and bandwidth weights in the consensus.
-Path selection depends on more factors, so that this probability can only
-be an approximation.
-Omitted if the relay is not running, or the consensus does not contain
-bandwidth weights.
-</p>
-</li>
-
-<li>
-<b>measured</b>
-<code class="typeof">boolean</code>
-<span class="required-false">optional</span>
-<p>
-Boolean field saying whether the consensus weight of this relay is based
-on a threshold of 3 or more measurements by Tor bandwidth authorities.
-Omitted if the network status consensus containing this relay does not
-contain measurement information.
-</p>
-</li>
-
-</ul>
-
-<h4>Bridge details objects</h4>
-
-<p>
-Bridge details objects contain the following key-value pairs:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>nickname</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Bridge nickname consisting of 1–19
-alphanumerical characters.
-Omitted if the bridge nickname is <strong>"Unnamed"</strong>.
-</p>
-</li>
-
-<li>
-<b>hashed_fingerprint</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-SHA-1 hash of the bridge fingerprint
-consisting of 40 upper-case hexadecimal characters.
-</p>
-</li>
-
-<li>
-<b>or_addresses</b>
-<code class="typeof">array of strings</code>
-<span class="required-true">required</span>
-<p>
-Array of sanitized IPv4 or IPv6 addresses and
-TCP ports or port lists where the bridge accepts onion-routing
-connections.
-The first address is the primary onion-routing address that the bridge
-used to register in the network, subsequent addresses are in arbitrary
-order.
-IPv6 hex characters are all lower-case.
-Sanitized IP addresses are always in <strong>10/8</strong> or
-<strong>[fd9f:2e19:3bcf/48]</strong> IP networks and are only useful to
-learn which
-IP version the bridge uses and to detect whether the bridge changed its
-address.
-Sanitized IP addresses always change on the 1st of every month at 00:00:00
-UTC, regardless of the bridge actually changing its IP address.
-TCP ports are not sanitized.
-</p>
-</li>
-
-<li>
-<b>last_seen</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when this
-bridge was last seen in a bridge network status.
-</p>
-</li>
-
-<li>
-<b>first_seen</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when this
-bridge was first seen in a bridge network status.
-</p>
-</li>
-
-<li>
-<b>running</b>
-<code class="typeof">boolean</code>
-<span class="required-true">required</span>
-<p>
-Boolean field saying whether this bridge was listed
-as running in the last bridge network status.
-</p>
-</li>
-
-<li>
-<b>flags</b>
-<code class="typeof">array of strings</code>
-<span class="required-false">optional</span>
-<p>
-Array of relay flags that the bridge authority
-assigned to this bridge.
-Omitted if empty.
-</p>
-</li>
-
-<li>
-<b>last_restarted</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when the
-bridge was last (re-)started.
-Missing if router descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>advertised_bandwidth</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Bandwidth in bytes per second that this
-bridge is willing and capable to provide.
-This bandwidth value is the minimum of <strong>bandwidth_rate</strong>,
-<strong>bandwidth_burst</strong>, and <strong>observed_bandwidth</strong>.
-Missing if router descriptor containing this information cannot be
-found.
-</p>
-</li>
-
-<li>
-<b>platform</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-Platform string containing operating system and Tor
-version details.
-Omitted if not provided by the bridge or if descriptor containing this
-information cannot be found.
-</p>
-</li>
-
-<li>
-<b>transports</b>
-<code class="typeof">array of strings</code>
-<span class="required-false">optional</span>
-<p>
-Array of (pluggable) transport names supported by this bridge.
-</p>
-</li>
-
-</ul>
-
-</div> <!-- box -->
-
-<div class="box">
-<a name="history"></a>
-<h3>History objects <a href="#history">#</a></h3>
-
-<p>
-History objects are no documents by themselves, but are contained in
-subsequent documents.
-<p>
-
-<h4>Graph history objects</h4>
-
-<p>
-Graph history objects contain the following fields:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>first</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) of the first data point, or more
-specifically the interval midpoint of the first interval.
-</p>
-</li>
-
-<li>
-<b>last</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) of the last data point, or more
-specifically the interval midpoint of the last interval.
-</p>
-</li>
-
-<li>
-<b>interval</b>
-<code class="typeof">number</code>
-<span class="required-true">required</span>
-<p>
-Time interval between two data points in seconds.
-</p>
-</li>
-
-<li>
-<b>factor</b>
-<code class="typeof">number</code>
-<span class="required-true">required</span>
-<p>
-Factor by which subsequent data values need to be multiplied to obtain
-original values.
-The idea is to reduce document size while still providing sufficient
-detail for very different data scales.
-</p>
-</li>
-
-<li>
-<b>count</b>
-<code class="typeof">number</code>
-<span class="required-false">optional</span>
-<p>
-Number of provided data points, included mostly for debugging purposes.
-Can also be derived from the number of elements in the subsequent array.
-</p>
-</li>
-
-<li>
-<b>values</b>
-<code class="typeof">array of numbers</code>
-<span class="required-true">required</span>
-<p>
-Array of normalized values between 0 and 999.
-May contain null values.
-Contains at least two subsequent non-null values to enable drawing of line
-graphs.
-</p>
-</li>
-
-</ul>
-
-</div> <!-- box -->
-
-<div class="box">
-<a name="bandwidth"></a>
-<h3>Bandwidth documents <a href="#bandwidth">#</a>
-<span class="request-response">
-<a href="bandwidth?limit=4">example request</a>
-</span>
-</h3>
-
-<p>
-Bandwidth documents contain aggregate statistics of a relay's or
-bridge's consumed bandwidth for different time intervals.
-Bandwidth documents are only updated when a relay or bridge publishes a
-new server descriptor, which may take up to 18 hours during normal
-operation.
-Bandwidth documents contain the following fields:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>version</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Onionoo protocol version string.
-</p>
-</li>
-
-<li>
-<b>next_major_version_scheduled</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
-be deployed.
-Omitted if no major protocol changes are planned.
-</p>
-</li>
-
-<li>
-<b>relays_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known relay network status consensus started being valid.
-Indicates how recent the relay bandwidth documents in this document are.
-</p>
-</li>
-
-<li>
-<b>relays</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Array of relay bandwidth objects as specified below.
-</p>
-</li>
-
-<li>
-<b>bridges_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known bridge network status was published.
-Indicates how recent the bridge bandwidth documents in this document are.
-</p>
-</li>
-
-<li>
-<b>bridges</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Array of bridge bandwidth objects as specified below.
-</p>
-</li>
-
-</ul>
-
-<h4>Relay bandwidth objects</h4>
-
-<p>
-Relay bandwidth objects contain the following key-value pairs:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>fingerprint</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Relay fingerprint consisting of 40 upper-case
-hexadecimal characters.
-</p>
-</li>
-
-<li>
-<b>write_history</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing graph history objects with written bytes for different
-time periods.
-Keys are string representation of the time period covered by the graph
-history object.
-Keys are fixed strings <strong>"3_days"</strong>,
-<strong>"1_week"</strong>, <strong>"1_month"</strong>,
-<strong>"3_months"</strong>, <strong>"1_year"</strong>, and
-<strong>"5_years"</strong>.
-Keys refer to the last known bandwidth history of a relay, not to the time
-when the bandwidth document was published.
-A graph history object is only contained if the time period it covers is
-not already contained in another graph history object with shorter time
-period and higher data resolution.
-Similarly, a graph history object is excluded if the relay did not provide
-bandwidth histories on the required level of detail.
-The unit is bytes per second.
-Contained graph history objects may contain null values if the relay did
-not provide any bandwidth data or only data for less than 20% of a given
-time period.
-</p>
-</li>
-
-<li>
-<b>read_history</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing graph history objects with read bytes for different time
-periods.
-The specification of graph history objects is similar to those in the
-<strong>write_history</strong> field.
-</p>
-</li>
-
-</ul>
-
-<h4>Bridge bandwidth objects</h4>
-
-<p>
-Bridge bandwidth objects contain the following key-value pairs:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>fingerprint</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-SHA-1 hash of the bridge fingerprint consisting
-of 40 upper-case hexadecimal characters.
-</p>
-</li>
-
-<li>
-<b>write_history</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing graph history objects with written bytes for different
-time periods.
-The specification of graph history objects is similar to those in the
-<strong>write_history</strong> field of <strong>relays</strong>.
-</p>
-</li>
-
-<li>
-<b>read_history</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing graph history objects with read bytes for different time
-periods.
-The specification of graph history objects is similar to those in the
-<strong>write_history</strong> field of <strong>relays</strong>.
-</p>
-</li>
-
-</ul>
-
-</div> <!-- box -->
-
-<div class="box">
-<a name="weights"></a>
-<h3>Weights documents <a href="#weights">#</a>
-<span class="request-response">
-<a href="weights?limit=4">example request</a>
-</span>
-</h3>
-
-<p>
-Weights documents contain aggregate statistics of a relay's probability
-to be selected by clients for building paths.
-Weights documents contain different time intervals and are available for
-relays only.
-Weights documents contain the following fields:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>version</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Onionoo protocol version string.
-</p>
-</li>
-
-<li>
-<b>next_major_version_scheduled</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
-be deployed.
-Omitted if no major protocol changes are planned.
-</p>
-</li>
-
-<li>
-<b>relays_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known relay network status consensus started being valid.
-Indicates how recent the relay weights documents in this document are.
-</p>
-</li>
-
-<li>
-<b>relays</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Array of relay weights objects as specified below.
-</p>
-</li>
-
-<li>
-<b>bridges_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known bridge network status was published.
-Only included for compatibility reasons with the other document types.
-</p>
-</li>
-
-<li>
-<b>bridges</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Empty array of objects that would represent bridge weights documents.
-Only included for compatibility reasons with the other document types.
-</p>
-</li>
-
-</ul>
-
-<h4>Relay weights objects</h4>
-
-<p>
-Relay weights objects contain the following key-value pairs: 
-</p>
-
-<ul class="properties">
-
-<li>
-<b>fingerprint</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Relay fingerprint consisting of 40 upper-case
-hexadecimal characters.
-</p>
-</li>
-
-<li>
-<b>consensus_weight_fraction</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-History object containing the
-fraction of this relay's consensus weight compared to the sum of all
-consensus weights in the network.
-This fraction is a very rough approximation of the probability of this
-relay to be selected by clients.
-Keys are string representation of the time period covered by the graph
-history object.
-Keys are fixed strings <strong>"1_week"</strong>,
-<strong>"1_month"</strong>, <strong>"3_months"</strong>,
-<strong>"1_year"</strong>, and <strong>"5_years"</strong>.
-Keys refer to the last known weights history of a relay, not to the time
-when the weights document was published.
-A graph history object is only contained if the time period it covers is
-not already contained in another graph history object with shorter time
-period and higher data resolution.
-The unit is path-selection probability.
-Contained graph history objects may contain null values if the relay was
-running less than 20% of a given time period.
-</p>
-</li>
-
-<li>
-<b>guard_probability</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-History object containing the probability
-of this relay to be selected for the guard position.
-This probability is calculated based on consensus weights, relay flags,
-and bandwidth weights in the consensus.
-Path selection depends on more factors, so that this probability can only
-be an approximation.
-The specification of this history object is similar to that in the
-<strong>consensus_weight_fraction</strong> field above.
-</p>
-</li>
-
-<li>
-<b>middle_probability</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-History object containing the probability
-of this relay to be selected for the middle position.
-This probability is calculated based on consensus weights, relay flags,
-and bandwidth weights in the consensus.
-Path selection depends on more factors, so that this probability can only
-be an approximation.
-The specification of this history object is similar to that in the
-<strong>consensus_weight_fraction</strong> field above.
-</p>
-</li>
-
-<li>
-<b>exit_probability</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-History object containing the probability
-of this relay to be selected for the exit position.
-This probability is calculated based on consensus weights, relay flags,
-and bandwidth weights in the consensus.
-Path selection depends on more factors, so that this probability can only
-be an approximation.
-The specification of this history object is similar to that in the
-<strong>consensus_weight_fraction</strong> field above.
-</p>
-</li>
-
-<li>
-<b>consensus_weight</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-History object containing the absolute consensus weight of this relay.
-The specification of this history object is similar to that in the
-<strong>consensus_weight_fraction</strong> field above.
-</p>
-</li>
-
-</ul>
-
-</div> <!-- box -->
-
-<div class="box">
-<a name="clients"></a>
-<h3>Clients documents <a href="#clients">#</a>
-<span class="request-response">
-<a href="clients?limit=4">example request</a>
-</span>
-</h3>
-
-<p>
-Clients documents contain estimates of the average number of clients
-connecting to a bridge every day.
-There are no clients documents available for relays, just for bridges.
-Clients documents contain different time intervals and are available for
-bridges only.
-Clients documents contain the following fields:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>version</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Onionoo protocol version string.
-</p>
-</li>
-
-<li>
-<b>next_major_version_scheduled</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
-be deployed.
-Omitted if no major protocol changes are planned.
-</p>
-</li>
-
-<li>
-<b>relays_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known relay network status consensus started being valid.
-Only included for compatibility reasons with the other document types.
-</p>
-</li>
-
-<li>
-<b>relays</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Empty array of objects that would represent relay clients documents.
-Only included for compatibility reasons with the other document types.
-</p>
-</li>
-
-<li>
-<b>bridges_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known bridge network status was published.
-Indicates how recent the bridge clients documents in this document are.
-</p>
-</li>
-
-<li>
-<b>bridges</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Array of bridge clients objects as specified below.
-</p>
-
-</li>
-
-</ul>
-
-<h4>Bridge clients objects</h4>
-
-<p>
-Bridge clients objects contain the following key-value pairs:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>fingerprint</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-SHA-1 hash of the bridge fingerprint consisting
-of 40 upper-case hexadecimal characters.
-</p>
-</li>
-
-<li>
-<b>average_clients</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing graph history objects with the average number of clients
-connecting to this bridge.
-Keys are string representation of the time period covered by the graph
-history object.
-Keys are fixed strings <strong>"1_week"</strong>,
-<strong>"1_month"</strong>, <strong>"3_months"</strong>,
-<strong>"1_year"</strong>, and <strong>"5_years"</strong>.
-Keys refer to the last known clients history of a bridge, not to the time
-when the clients document was published.
-A graph history object is only contained if the time period it covers
-is not already contained in another clients graph object with shorter
-time period and higher data resolution.
-The unit is number of clients.
-Contained graph history objects may contain null values if the bridge did
-not report client statistics for at least 50% of a given time period.
-Each graph history object contains the following additional key-value
-pairs:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>countries</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing fractions of clients by country in the considered time
-period.
-Keys are two-letter lower-case country codes as found in a GeoIP database.
-Values are numbers between 0 and 1 standing for the fraction of clients by
-country.
-A country is only included if at least 1% of clients came from this
-country.
-Omitted if the bridge did not report client statistics by country.
-<font color="red"><strong>BETA:</strong> This field breaks compatibility
-with the history objects contained in other documents pretty badly.
-It might be removed in the future without notice.</font>
-</p>
-</li>
-
-<li>
-<b>transports</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing fractions of clients by transport in the considered time
-period.
-Keys are transport names, or <strong>"<OR>"</strong> for the default
-onion-routing transport protocol.
-Values are numbers between 0 and 1 standing for the fraction of clients by
-transport.
-Omitted if the bridge did not report client statistics by transport.
-<font color="red"><strong>BETA:</strong> This field breaks compatibility
-with the history objects contained in other documents pretty badly.
-It might be removed in the future without notice.</font>
-</p>
-</li>
-
-<li>
-<b>versions</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing fractions of clients by IP version in the considered
-time period.
-Keys are either <strong>"v4"</strong> for IPv4 or <strong>"v6"</strong>
-for IPv6.
-Values are numbers between 0 and 1 standing for the fraction of clients by
-version.
-Omitted if the bridge did not report client statistics by IP version.
-<font color="red"><strong>BETA:</strong> This field breaks compatibility
-with the history objects contained in other documents pretty badly.
-It might be removed in the future without notice.</font>
-</p>
-</li>
-
-</ul>
-
-</li>
-
-</ul>
-
-</div> <!-- box -->
-
-<div class="box">
-<a name="uptime"></a>
-<h3>Uptime documents <a href="#uptime">#</a>
-<span class="request-response">
-<a href="uptime?limit=4">example request</a>
-</span>
-</h3>
-
-<p>
-Uptime documents contain fractional uptimes of relays and bridges.
-Uptime documents contain different time intervals and are available for
-relays and bridges.
-Uptime documents contain the following fields:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>version</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Onionoo protocol version string.
-</p>
-</li>
-
-<li>
-<b>next_major_version_scheduled</b>
-<code class="typeof">string</code>
-<span class="required-false">optional</span>
-<p>
-UTC date (YYYY-MM-DD) when the next major protocol version is scheduled to
-be deployed.
-Omitted if no major protocol changes are planned.
-</p>
-</li>
-
-<li>
-<b>relays_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known relay network status consensus started being valid.
-Indicates how recent the relay uptime documents in this document are.
-</p>
-</li>
-
-<li>
-<b>relays</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Array of relay uptime objects as specified below.
-</p>
-</li>
-
-<li>
-<b>bridges_published</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-UTC timestamp (YYYY-MM-DD hh:mm:ss) when
-the last known bridge network status was published.
-Indicates how recent the bridge uptime documents in this document are.
-</p>
-</li>
-
-<li>
-<b>bridges</b>
-<code class="typeof">array of objects</code>
-<span class="required-true">required</span>
-<p>
-Array of bridge uptime objects as specified below.
-</p>
-</li>
-
-</ul>
-
-<h4>Relay uptime objects</h4>
-
-<p>
-Relay uptime objects contain the following key-value pairs:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>fingerprint</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-Relay fingerprint consisting of 40 upper-case
-hexadecimal characters.
-</p>
-</li>
-
-<li>
-<b>uptime</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing graph history objects with the fractional uptime of this
-relay.
-Keys are string representation of the time period covered by the graph
-history object.
-Keys are fixed strings <strong>"1_week"</strong>,
-<strong>"1_month"</strong>, <strong>"3_months"</strong>,
-<strong>"1_year"</strong>, and <strong>"5_years"</strong>.
-Keys refer to the last known uptime history of a relay, not to the time
-when the uptime document was published.
-A graph history object is only contained if the time period it covers is
-not already contained in another graph history object with shorter time
-period and higher data resolution.
-The unit is fractional uptime from 0 to 1.
-Contained graph history objects may contain null values if less than 20%
-of network statuses have been processed for a given time period.
-</p>
-</li>
-
-<li>
-<b>flags</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing fractional times of this relay having relay flags
-assigned.
-Keys are flag names like <strong>"Running"</strong> or
-<strong>"Exit"</strong>, values are objects similar to the
-<strong>uptime</strong> field above, again with keys like
-<strong>"1_week"</strong> etc.
-If a relay never had a given relay flag assigned, no object is included
-for that flag.
-</p>
-</li>
-
-</ul>
-
-<h4>Bridge uptime objects</h4>
-
-<p>
-Bridge uptime objects contain the following key-value pairs:
-</p>
-
-<ul class="properties">
-
-<li>
-<b>fingerprint</b>
-<code class="typeof">string</code>
-<span class="required-true">required</span>
-<p>
-SHA-1 hash of the bridge fingerprint consisting
-of 40 upper-case hexadecimal characters.
-</p>
-</li>
-
-<li>
-<b>uptime</b>
-<code class="typeof">object</code>
-<span class="required-false">optional</span>
-<p>
-Object containing uptime history objects for different time periods.
-The specification of uptime history objects is similar to those in the
-<strong>uptime</strong> field of <strong>relays</strong>.
-</p>
-</li>
-
-</ul>
-
-</div> <!-- box -->
-
-<div class="box">
-<a name="examples"></a>
-<h3>Example usage <a href="#examples">#</a>
-</h3>
-
-<p>
-The following examples illustrate how to build requests for some trivial
-and some more complex use cases.
-While Onionoo is designed mainly for developers and not end users, there
-may be cases when it's easier to quickly write a specific query Onionoo
-rather than to find an Onionoo client that provides the desired
-information.
-</p>
-
-<pre>https://onionoo.torproject.org/summary?limit=4</pre>
-
-<p>
-This first query returns the first four summary documents that Onionoo can
-find.
-The <code>limit</code> parameter should always be used while developing
-new queries to avoid downloading huge responses.
-</p>
-
-<pre>https://onionoo.torproject.org/summary?limit=4&search=moria</pre>
-
-<p>
-The second query restricts results to relays and bridges containing the
-string "moria" in one of a few searched fields.
-</p>
-
-<pre>https://onionoo.torproject.org/details?limit=4&search=moria</pre>
-
-<p>
-The third query switches from the short summary documents to the longer
-details documents containing, well, more details.
-</p>
-
-<pre>https://onionoo.torproject.org/details?limit=4&search=moria&fields=nickname</pre>
-
-<p>
-The fourth query adds the <code>fields</code> parameter which removes all
-fields except the specified ones from the result.
-This parameter is only implemented for details documents.
-</p>
-
-<pre>https://onionoo.torproject.org/details?limit=4&search=moria&fields=nickname&order=-consensus_weight</pre>
-
-<p>
-The fifth query sorts results by relay consensus weight from largest to
-smallest.
-</p>
-
-<p>
-Obviously, this query can be made even more complex by adding more
-parameters, and in some cases this is necessary and useful.
-Please refer to the protocol specification for details.
-</p>
-
-</div> <!-- box -->
-
-</body>
-</html>
-
diff --git a/web/robots.txt b/web/robots.txt
deleted file mode 100644
index 9b19f8f..0000000
--- a/web/robots.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-User-agent: *
-Disallow: /summary
-Disallow: /details
-Disallow: /bandwidth
-Disallow: /weights
-Disallow: /clients
-Disallow: /uptime
-



More information about the tor-commits mailing list