Skip to content
Snippets Groups Projects
Commit e5d8b173 authored by Jesper Zedlitz's avatar Jesper Zedlitz
Browse files

Refactored to support HEAD requests

parent 0d31de20
No related branches found
No related tags found
No related merge requests found
Pipeline #172 passed
Showing with 512 additions and 90 deletions
......@@ -15,5 +15,5 @@ build:
script: "mvn clean package -B"
artifacts:
paths:
- target/*-jar-with-dependencies.jar
- target/data-proxy-jar-with-dependencies.jar
......@@ -13,6 +13,7 @@
<jena.version>4.2.0</jena.version>
</properties>
<build>
<finalName>data-proxy</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
......@@ -26,7 +27,7 @@
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.5</version>
<version>4.9.3</version>
<executions>
<execution>
<goals>
......@@ -85,7 +86,14 @@
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.5</version>
<version>4.9.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
......@@ -12,7 +12,7 @@ pair: NAME ':' VALUE ;
NAME: [a-z_]+ ;
WS : [ \t\r\n]+ -> skip ; // Define whitespace rule, toss it out
QUOTE: [\'\"] ;
QUOTE: ['"] ;
ARS: '010' [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ;
VALUE: [0-9]+ '.'? [0-9]* ;
package de.landsh.opendata.dataproxy;
import fi.iki.elonen.router.RouterNanoHTTPD;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.util.ServerRunner;
public class App extends RouterNanoHTTPD {
public static final int PORT = 8081;
public class App extends NanoHTTPD {
public static int port = 8080;
@Override
public void addMappings() {
super.addMappings();
addRoute("/strassen-sh.geojson", StrassenSH2Geojson.class);
addRoute("/corona-rd-eck.json", CoronaRdEck.class);
}
private final StrassenSH strassenSH = new StrassenSH();
private final CoronaRdEck coronaRdEck = new CoronaRdEck();
public App() {
super(PORT);
addMappings();
System.out.println("\nRunning! Point your browser to http://localhost:" + PORT + "/ \n");
super(port);
System.out.println("\nRunning! Point your browser to http://localhost:" + port + "/ \n");
}
public static void main(String[] args) {
if( args.length > 0) {
try {
App.port = Integer.parseInt(args[0]);
} catch (NumberFormatException ignore) {
System.err.println("Usage: java -jar data-proxy.jar [PORT]");
System.exit(1);
}
}
ServerRunner.run(App.class);
}
@Override
public Response serve(IHTTPSession session) {
final CachingDataResponser responder;
if ("/strassen-sh.geojson".equals(session.getUri())) {
responder = strassenSH;
} else if ("/corona-rd-eck.json".equals(session.getUri())) {
responder = coronaRdEck;
} else {
responder = null;
}
if (responder == null) {
return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/plain", "Not Found");
} else {
if (session.getMethod() == Method.GET) {
return responder.get();
} else if (session.getMethod() == Method.HEAD) {
return responder.head();
} else {
return newFixedLengthResponse(Response.Status.METHOD_NOT_ALLOWED, "text/plain", "Method not allowed");
}
}
}
}
package de.landsh.opendata.dataproxy;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.router.RouterNanoHTTPD;
import java.io.IOException;
public abstract class CachingDataConverter extends RouterNanoHTTPD.DefaultHandler {
/**
* Return the update interval in milliseconds;
*/
abstract int getUpdateInterval();
abstract String loadData() throws IOException;
}
package de.landsh.opendata.dataproxy;
import fi.iki.elonen.NanoHTTPD;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public abstract class CachingDataResponser {
private String data = "{}";
private long lastUpdate = -1;
private NanoHTTPD.Response.Status status = NanoHTTPD.Response.Status.INTERNAL_ERROR;
/**
* Returns the update interval in milliseconds.
*/
abstract int getUpdateInterval();
/**
* Returns the MIME type for a successful response.
*/
abstract String getMimeType();
/**
* Load data from the original source.
*/
abstract String loadData() throws IOException;
private void loadDataIfNecessary() {
if (System.currentTimeMillis() - getUpdateInterval() > lastUpdate) {
System.out.println("Loading data for " + getClass().getName());
try {
data = loadData();
status = NanoHTTPD.Response.Status.OK;
} catch (IOException e) {
data = "{}";
status = NanoHTTPD.Response.Status.INTERNAL_ERROR;
}
lastUpdate = System.currentTimeMillis();
}
}
/**
* Handle GET requests.
*/
public NanoHTTPD.Response get() {
loadDataIfNecessary();
NanoHTTPD.Response response = NanoHTTPD.newFixedLengthResponse(status, getMimeType(), data);
response.addHeader("Access-Control-Allow-Origin", "*");
return response;
}
/**
* Handle HEAD requests.
*/
public NanoHTTPD.Response head() {
loadDataIfNecessary();
NanoHTTPD.Response response = new HeadResponse(status, getMimeType(), data.length());
response.addHeader("Access-Control-Allow-Origin", "*");
return response;
}
static class HeadResponse extends NanoHTTPD.Response {
protected HeadResponse(IStatus status, String mimeType, long totalBytes) {
super(status, mimeType, new ByteArrayInputStream(new byte[0]), totalBytes);
}
}
}
......@@ -2,8 +2,6 @@ package de.landsh.opendata.dataproxy;
import de.landsh.opendata.coronardeck.CoronaDataLexer;
import de.landsh.opendata.coronardeck.CoronaDataParser;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.router.RouterNanoHTTPD;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
......@@ -14,30 +12,40 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.util.Map;
public class CoronaRdEck implements RouterNanoHTTPD.UriResponder {
public static final int UPDATE_INTERVAL = 600000; // 10 minutes
private static String data = "{}";
private static long lastUpdate = -1;
private static NanoHTTPD.Response.Status status = NanoHTTPD.Response.Status.INTERNAL_ERROR;
public class CoronaRdEck extends CachingDataResponser {
private final String originalURL;
public CoronaRdEck() {
originalURL = "https://covid19dashboardrdeck.aco/daten/daten.js";
}
CoronaRdEck(String url) {
originalURL = url;
}
@Override
int getUpdateInterval() {
return 600000; // 10 minutes
}
@Override
String getMimeType() {
return "application/json";
}
String loadData() throws IOException {
InputStream inputStream = new URL("https://covid19dashboardrdeck.aco/daten/daten.js").openStream();
final InputStream inputStream = new URL(originalURL).openStream();
final ANTLRInputStream input = new ANTLRInputStream(inputStream);
final CoronaDataLexer lexer = new CoronaDataLexer(input);
final CommonTokenStream tokens = new CommonTokenStream(lexer);
final CoronaDataParser parser = new CoronaDataParser(tokens);
final ParseTree tree = parser.data();
final ParseTreeWalker walker = new ParseTreeWalker();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream out = new PrintStream(baos);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final PrintStream out = new PrintStream(baos);
walker.walk(new CoronaRdEckWalker(out), tree);
out.close();
......@@ -47,42 +55,4 @@ public class CoronaRdEck implements RouterNanoHTTPD.UriResponder {
}
@Override
public NanoHTTPD.Response get(RouterNanoHTTPD.UriResource uriResource, Map<String, String> urlParams, NanoHTTPD.IHTTPSession session) {
if (System.currentTimeMillis() - UPDATE_INTERVAL > lastUpdate) {
System.out.println("Loading data for " + getClass().getName());
try {
data = loadData();
status = NanoHTTPD.Response.Status.OK;
} catch (IOException e) {
data = "{}";
status = NanoHTTPD.Response.Status.INTERNAL_ERROR;
}
lastUpdate = System.currentTimeMillis();
}
return NanoHTTPD.newFixedLengthResponse(status, "application/json", data);
}
@Override
public NanoHTTPD.Response put(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response post(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response delete(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response other(String s, RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
}
package de.landsh.opendata.dataproxy;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.router.RouterNanoHTTPD;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
......@@ -9,24 +7,39 @@ import org.json.JSONTokener;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
public class StrassenSH2Geojson implements RouterNanoHTTPD.UriResponder {
public static final int UPDATE_INTERVAL = 180000; // 3 minutes
private static String data = "{}";
private static long lastUpdate = -1;
private static NanoHTTPD.Response.Status status = NanoHTTPD.Response.Status.INTERNAL_ERROR;
public class StrassenSH extends CachingDataResponser {
private final String baseURL;
public StrassenSH() {
baseURL = "https://strassen-sh.de/proxy/geojson/los/";
}
StrassenSH(String baseURL) {
this.baseURL = baseURL;
}
@Override
int getUpdateInterval() {
return 180000; // 3 minutes
}
@Override
String getMimeType() {
return "application/geo+json";
}
String loadData() throws IOException {
System.out.println("Loading data from strassen-sh.de...");
final JSONObject featureCollection = new JSONObject();
featureCollection.put("type", "FeatureCollection");
processQuery(featureCollection, new URL("https://strassen-sh.de/proxy/geojson/los/2/100").openStream(), "frei");
processQuery(featureCollection, new URL("https://strassen-sh.de/proxy/geojson/los/6/100").openStream(), "gestaut");
processQuery(featureCollection, new URL("https://strassen-sh.de/proxy/geojson/los/4/100").openStream(), "dicht");
processQuery(featureCollection, new URL("https://strassen-sh.de/proxy/geojson/los/5/100").openStream(), "zähfließend");
processQuery(featureCollection, new URL("https://strassen-sh.de/proxy/geojson/los/9/100").openStream(), "Datenausfall");
processQuery(featureCollection, new URL(baseURL + "2/100").openStream(), "frei");
processQuery(featureCollection, new URL(baseURL + "6/100").openStream(), "gestaut");
processQuery(featureCollection, new URL(baseURL + "4/100").openStream(), "dicht");
processQuery(featureCollection, new URL(baseURL + "5/100").openStream(), "zähfließend");
processQuery(featureCollection, new URL(baseURL + "9/100").openStream(), "Datenausfall");
return featureCollection.toString();
}
......@@ -69,43 +82,5 @@ public class StrassenSH2Geojson implements RouterNanoHTTPD.UriResponder {
return result;
}
@Override
public NanoHTTPD.Response get(RouterNanoHTTPD.UriResource uriResource, Map<String, String> urlParams, NanoHTTPD.IHTTPSession session) {
if (System.currentTimeMillis() - UPDATE_INTERVAL > lastUpdate) {
System.out.println("Loading data for " + getClass().getName());
try {
data = loadData();
status = NanoHTTPD.Response.Status.OK;
} catch (IOException e) {
data = "{}";
status = NanoHTTPD.Response.Status.INTERNAL_ERROR;
}
lastUpdate = System.currentTimeMillis();
}
return NanoHTTPD.newFixedLengthResponse(status, "application/geo+json", data);
}
@Override
public NanoHTTPD.Response put(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response post(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response delete(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response other(String s, RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
}
package de.landsh.opendata.dataproxy;
import de.landsh.opendata.coronardeck.CoronaDataLexer;
import de.landsh.opendata.coronardeck.CoronaDataParser;
import org.antlr.v4.runtime.*;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
/**
* Unit test for simple CoronaData.
*/
public class CoronaDataTest {
@Test
public void invalidData() {
final CharStream input = CharStreams.fromString("var data = {\n" +
"'010580005005: { amount_pt: 2.1037868162693, amount_t: 206, amount_i: 21, amount_d: 3, amount_h: 182 },\n}");
CoronaDataLexer lexer = new CoronaDataLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
CoronaDataParser parser = new CoronaDataParser(tokens);
parser.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
throw new RuntimeException(msg);
}
});
try {
parser.data();
fail();
} catch (RuntimeException ignore) {
// ok
}
}
@Test
public void oneEntry() {
final CharStream input = CharStreams.fromString("var data = {\n" +
"'010580005005': { amount_pt: 2.1037868162693, amount_t: 206, amount_i: 21, amount_d: 3, amount_h: 182 },\n}");
CoronaDataLexer lexer = new CoronaDataLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
CoronaDataParser parser = new CoronaDataParser(tokens);
parser.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
throw new RuntimeException(msg);
}
});
parser.data();
}
@Test
public void test() throws IOException {
final InputStream inputStream = getClass().getResourceAsStream("/2021-11-12_100007.json");
assertNotNull(inputStream);
final CharStream input = CharStreams.fromStream(inputStream);
CoronaDataLexer lexer = new CoronaDataLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
CoronaDataParser parser = new CoronaDataParser(tokens);
parser.data();
}
}
package de.landsh.opendata.dataproxy;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Test;
import static org.junit.Assert.*;
public class StrassenSH2GeojsonTest {
StrassenSH strassenSH2Geojson = new StrassenSH();
@Test
public void convertFeature() {
String json = "{\"properties\":{},\"type\":\"LineString\",\"coordinates\":[[11.1348821,54.42609306],[11.12938639,54.42167313],[11.12450702,54.41677863],[11.12069621,54.4118541],[11.11344491,54.40078343]]}";
JSONObject in = new JSONObject(json);
JSONObject result = strassenSH2Geojson.convertFeature(in);
assertTrue(result.has("properties"));
JSONObject geometry = result.getJSONObject("geometry");
assertNotNull(geometry);
assertEquals("LineString", geometry.getString("type"));
JSONArray coordinates = geometry.getJSONArray("coordinates");
assertNotNull(coordinates);
assertEquals(5, coordinates.length());
}
}
var data = {
'010580005005': { amount_pt: 2.1037868162693, amount_t: 207, amount_i: 21, amount_d: 3, amount_h: 183 },
'010580034034': { amount_pt: 0.67107659860033, amount_t: 219, amount_i: 7, amount_d: 2, amount_h: 210 },
'010580043043': { amount_pt: 0.96480749793256, amount_t: 457, amount_i: 21, amount_d: 8, amount_h: 428 },
'010580092092': { amount_pt: 1.0036801605888, amount_t: 224, amount_i: 12, amount_d: 1, amount_h: 211 },
'010580135135': { amount_pt: 1.7367744624683, amount_t: 1256, amount_i: 50, amount_d: 16, amount_h: 1190 },
'010580169169': { amount_pt: 3.0395136778116, amount_t: 35, amount_i: 7, amount_d: 0, amount_h: 28 },
'010585803001': { amount_pt: 0, amount_t: 14, amount_i: 0, amount_d: 0, amount_h: 14 },
'010585803028': { amount_pt: 3.2851511169514, amount_t: 19, amount_i: 5, amount_d: 0, amount_h: 14 },
'010585803050': { amount_pt: 1.4058106841612, amount_t: 39, amount_i: 3, amount_d: 0, amount_h: 36 },
'010585803093': { amount_pt: 0, amount_t: 9, amount_i: 0, amount_d: 0, amount_h: 9 },
'010585803104': { amount_pt: 0.53995680345572, amount_t: 34, amount_i: 1, amount_d: 0, amount_h: 33 },
'010585803126': { amount_pt: 1.0526315789474, amount_t: 27, amount_i: 1, amount_d: 0, amount_h: 26 },
'010585803130': { amount_pt: 1.7064846416382, amount_t: 25, amount_i: 3, amount_d: 0, amount_h: 22 },
'010585803171': { amount_pt: 1.2730744748568, amount_t: 23, amount_i: 2, amount_d: 0, amount_h: 21 },
'010585822037': { amount_pt: 2.326182476092, amount_t: 80, amount_i: 9, amount_d: 0, amount_h: 71 },
'010585822116': { amount_pt: 1.1547344110855, amount_t: 11, amount_i: 1, amount_d: 0, amount_h: 10 },
'010585822150': { amount_pt: 0, amount_t: 34, amount_i: 0, amount_d: 0, amount_h: 34 },
'010585822157': { amount_pt: 1.3440860215054, amount_t: 14, amount_i: 2, amount_d: 0, amount_h: 12 },
'010585824051': { amount_pt: 1.6820857863751, amount_t: 22, amount_i: 2, amount_d: 0, amount_h: 20 },
'010585824058': { amount_pt: 2.119486024639, amount_t: 89, amount_i: 16, amount_d: 1, amount_h: 72 },
'010585824096': { amount_pt: 5.1094890510949, amount_t: 18, amount_i: 7, amount_d: 0, amount_h: 11 },
'010585824110': { amount_pt: 0, amount_t: 11, amount_i: 0, amount_d: 0, amount_h: 11 },
'010585824112': { amount_pt: 0, amount_t: 17, amount_i: 0, amount_d: 0, amount_h: 17 },
'010585824121': { amount_pt: 0.79396585946804, amount_t: 26, amount_i: 2, amount_d: 0, amount_h: 24 },
'010585824142': { amount_pt: 2.9644268774704, amount_t: 10, amount_i: 3, amount_d: 0, amount_h: 7 },
'010585824165': { amount_pt: 0, amount_t: 14, amount_i: 0, amount_d: 1, amount_h: 13 },
'010585830019': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585830053': { amount_pt: 0.83114004709794, amount_t: 107, amount_i: 6, amount_d: 0, amount_h: 101 },
'010585830145': { amount_pt: 0, amount_t: 3, amount_i: 0, amount_d: 0, amount_h: 3 },
'010585830160': { amount_pt: 0, amount_t: 1, amount_i: 0, amount_d: 0, amount_h: 1 },
'010585833003': { amount_pt: 2.1108179419525, amount_t: 35, amount_i: 4, amount_d: 0, amount_h: 31 },
'010585833054': { amount_pt: 3.9701445132603, amount_t: 157, amount_i: 25, amount_d: 1, amount_h: 131 },
'010585833118': { amount_pt: 0, amount_t: 36, amount_i: 0, amount_d: 1, amount_h: 35 },
'010585833136': { amount_pt: 2.9296875, amount_t: 11, amount_i: 3, amount_d: 0, amount_h: 8 },
'010585847010': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585847029': { amount_pt: 0, amount_t: 22, amount_i: 0, amount_d: 0, amount_h: 22 },
'010585847036': { amount_pt: 0, amount_t: 5, amount_i: 0, amount_d: 0, amount_h: 5 },
'010585847047': { amount_pt: 0, amount_t: 24, amount_i: 0, amount_d: 0, amount_h: 24 },
'010585847055': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585847056': { amount_pt: 0, amount_t: 2, amount_i: 0, amount_d: 0, amount_h: 2 },
'010585847070': { amount_pt: 0, amount_t: 50, amount_i: 0, amount_d: 0, amount_h: 50 },
'010585847078': { amount_pt: 1.6535758577925, amount_t: 38, amount_i: 4, amount_d: 0, amount_h: 34 },
'010585847089': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585847097': { amount_pt: 0, amount_t: 1, amount_i: 0, amount_d: 0, amount_h: 1 },
'010585847129': { amount_pt: 0, amount_t: 7, amount_i: 0, amount_d: 0, amount_h: 7 },
'010585847154': { amount_pt: 0, amount_t: 5, amount_i: 0, amount_d: 0, amount_h: 5 },
'010585853031': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585853048': { amount_pt: 0, amount_t: 2, amount_i: 0, amount_d: 0, amount_h: 2 },
'010585853068': { amount_pt: 0, amount_t: 15, amount_i: 0, amount_d: 0, amount_h: 15 },
'010585853071': { amount_pt: 0, amount_t: 9, amount_i: 0, amount_d: 1, amount_h: 8 },
'010585853075': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585853086': { amount_pt: 0.30111412225233, amount_t: 26, amount_i: 1, amount_d: 0, amount_h: 25 },
'010585853101': { amount_pt: 0, amount_t: 9, amount_i: 0, amount_d: 0, amount_h: 9 },
'010585853148': { amount_pt: 0, amount_t: 8, amount_i: 0, amount_d: 0, amount_h: 8 },
'010585853155': { amount_pt: 0, amount_t: 1, amount_i: 0, amount_d: 0, amount_h: 1 },
'010585853172': { amount_pt: 0.9954210631097, amount_t: 90, amount_i: 5, amount_d: 0, amount_h: 85 },
'010585859018': { amount_pt: 2.8490028490028, amount_t: 20, amount_i: 2, amount_d: 0, amount_h: 18 },
'010585859105': { amount_pt: 4.3859649122807, amount_t: 39, amount_i: 6, amount_d: 0, amount_h: 33 },
'010585859107': { amount_pt: 0.59654006760787, amount_t: 57, amount_i: 3, amount_d: 1, amount_h: 53 },
'010585859138': { amount_pt: 0, amount_t: 6, amount_i: 0, amount_d: 0, amount_h: 6 },
'010585859139': { amount_pt: 0, amount_t: 6, amount_i: 0, amount_d: 0, amount_h: 6 },
'010585859141': { amount_pt: 0, amount_t: 4, amount_i: 0, amount_d: 1, amount_h: 3 },
'010585864011': { amount_pt: 5.5788005578801, amount_t: 21, amount_i: 4, amount_d: 0, amount_h: 17 },
'010585864021': { amount_pt: 0, amount_t: 6, amount_i: 0, amount_d: 0, amount_h: 6 },
'010585864023': { amount_pt: 0, amount_t: 5, amount_i: 0, amount_d: 0, amount_h: 5 },
'010585864027': { amount_pt: 5.7803468208092, amount_t: 8, amount_i: 2, amount_d: 0, amount_h: 6 },
'010585864038': { amount_pt: 0, amount_t: 16, amount_i: 0, amount_d: 0, amount_h: 16 },
'010585864045': { amount_pt: 0, amount_t: 1, amount_i: 0, amount_d: 0, amount_h: 1 },
'010585864046': { amount_pt: 0, amount_t: 10, amount_i: 0, amount_d: 0, amount_h: 10 },
'010585864049': { amount_pt: 0, amount_t: 27, amount_i: 0, amount_d: 0, amount_h: 27 },
'010585864059': { amount_pt: 0.85178875638842, amount_t: 4, amount_i: 1, amount_d: 0, amount_h: 3 },
'010585864065': { amount_pt: 0, amount_t: 16, amount_i: 0, amount_d: 1, amount_h: 15 },
'010585864091': { amount_pt: 0, amount_t: 4, amount_i: 0, amount_d: 0, amount_h: 4 },
'010585864094': { amount_pt: 0, amount_t: 27, amount_i: 0, amount_d: 0, amount_h: 27 },
'010585864117': { amount_pt: 1.1682242990654, amount_t: 142, amount_i: 8, amount_d: 3, amount_h: 131 },
'010585864120': { amount_pt: 0, amount_t: 3, amount_i: 0, amount_d: 0, amount_h: 3 },
'010585864147': { amount_pt: 1.3071895424837, amount_t: 7, amount_i: 1, amount_d: 0, amount_h: 6 },
'010585864163': { amount_pt: 0, amount_t: 30, amount_i: 0, amount_d: 0, amount_h: 30 },
'010585864168': { amount_pt: 1.4577259475219, amount_t: 5, amount_i: 1, amount_d: 0, amount_h: 4 },
'010585888026': { amount_pt: 3.6563071297989, amount_t: 17, amount_i: 4, amount_d: 0, amount_h: 13 },
'010585888073': { amount_pt: 0, amount_t: 2, amount_i: 0, amount_d: 0, amount_h: 2 },
'010585888122': { amount_pt: 5.1457975986278, amount_t: 15, amount_i: 3, amount_d: 0, amount_h: 12 },
'010585888124': { amount_pt: 0.9788566953798, amount_t: 101, amount_i: 5, amount_d: 0, amount_h: 96 },
'010585888132': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585888140': { amount_pt: 1.2484394506866, amount_t: 126, amount_i: 6, amount_d: 1, amount_h: 119 },
'010585888146': { amount_pt: 0, amount_t: 3, amount_i: 0, amount_d: 0, amount_h: 3 },
'010585889016': { amount_pt: 6.2111801242236, amount_t: 1, amount_i: 1, amount_d: 0, amount_h: 0 },
'010585889022': { amount_pt: 0.9085009733939, amount_t: 157, amount_i: 7, amount_d: 5, amount_h: 145 },
'010585889033': { amount_pt: 0, amount_t: 22, amount_i: 0, amount_d: 1, amount_h: 21 },
'010585889063': { amount_pt: 0, amount_t: 1, amount_i: 0, amount_d: 0, amount_h: 1 },
'010585889064': { amount_pt: 0, amount_t: 3, amount_i: 0, amount_d: 0, amount_h: 3 },
'010585889076': { amount_pt: 0, amount_t: 2, amount_i: 0, amount_d: 0, amount_h: 2 },
'010585889098': { amount_pt: 0, amount_t: 2, amount_i: 0, amount_d: 0, amount_h: 2 },
'010585889108': { amount_pt: 0, amount_t: 11, amount_i: 0, amount_d: 0, amount_h: 11 },
'010585889109': { amount_pt: 0, amount_t: 2, amount_i: 0, amount_d: 0, amount_h: 2 },
'010585889133': { amount_pt: 0, amount_t: 4, amount_i: 0, amount_d: 0, amount_h: 4 },
'010585889143': { amount_pt: 0, amount_t: 5, amount_i: 0, amount_d: 0, amount_h: 5 },
'010585889144': { amount_pt: 0, amount_t: 7, amount_i: 0, amount_d: 0, amount_h: 7 },
'010585889153': { amount_pt: 0, amount_t: 1, amount_i: 0, amount_d: 0, amount_h: 1 },
'010585889170': { amount_pt: 0, amount_t: 27, amount_i: 0, amount_d: 1, amount_h: 26 },
'010585890008': { amount_pt: 1.0277492291881, amount_t: 36, amount_i: 1, amount_d: 4, amount_h: 31 },
'010585890024': { amount_pt: 0, amount_t: 24, amount_i: 0, amount_d: 1, amount_h: 23 },
'010585890030': { amount_pt: 0, amount_t: 9, amount_i: 0, amount_d: 0, amount_h: 9 },
'010585890035': { amount_pt: 0, amount_t: 12, amount_i: 0, amount_d: 0, amount_h: 12 },
'010585890039': { amount_pt: 4.8192771084337, amount_t: 7, amount_i: 2, amount_d: 0, amount_h: 5 },
'010585890066': { amount_pt: 5.4858934169279, amount_t: 16, amount_i: 7, amount_d: 0, amount_h: 9 },
'010585890069': { amount_pt: 1.779359430605, amount_t: 9, amount_i: 1, amount_d: 0, amount_h: 8 },
'010585890080': { amount_pt: 3.8699690402477, amount_t: 16, amount_i: 5, amount_d: 0, amount_h: 11 },
'010585890081': { amount_pt: 0, amount_t: 1, amount_i: 0, amount_d: 0, amount_h: 1 },
'010585890083': { amount_pt: 0, amount_t: 8, amount_i: 0, amount_d: 0, amount_h: 8 },
'010585890088': { amount_pt: 0, amount_t: 1, amount_i: 0, amount_d: 0, amount_h: 1 },
'010585890111': { amount_pt: 0, amount_t: 9, amount_i: 0, amount_d: 0, amount_h: 9 },
'010585890123': { amount_pt: 3.9370078740157, amount_t: 19, amount_i: 4, amount_d: 1, amount_h: 14 },
'010585890127': { amount_pt: 0.27277686852155, amount_t: 87, amount_i: 1, amount_d: 1, amount_h: 85 },
'010585890152': { amount_pt: 0, amount_t: 14, amount_i: 0, amount_d: 0, amount_h: 14 },
'010585890175': { amount_pt: 0, amount_t: 5, amount_i: 0, amount_d: 0, amount_h: 5 },
'010585893004': { amount_pt: 0, amount_t: 5, amount_i: 0, amount_d: 0, amount_h: 5 },
'010585893012': { amount_pt: 3.2509752925878, amount_t: 30, amount_i: 5, amount_d: 0, amount_h: 25 },
'010585893032': { amount_pt: 0, amount_t: 2, amount_i: 0, amount_d: 0, amount_h: 2 },
'010585893040': { amount_pt: 0, amount_t: 20, amount_i: 0, amount_d: 0, amount_h: 20 },
'010585893042': { amount_pt: 0, amount_t: 10, amount_i: 0, amount_d: 0, amount_h: 10 },
'010585893052': { amount_pt: 2.3062730627306, amount_t: 28, amount_i: 5, amount_d: 0, amount_h: 23 },
'010585893057': { amount_pt: 1.8832391713748, amount_t: 13, amount_i: 1, amount_d: 0, amount_h: 12 },
'010585893067': { amount_pt: 1.3774104683196, amount_t: 15, amount_i: 1, amount_d: 0, amount_h: 14 },
'010585893082': { amount_pt: 0, amount_t: 5, amount_i: 0, amount_d: 0, amount_h: 5 },
'010585893084': { amount_pt: 0, amount_t: 6, amount_i: 0, amount_d: 0, amount_h: 6 },
'010585893087': { amount_pt: 0, amount_t: 4, amount_i: 0, amount_d: 0, amount_h: 4 },
'010585893090': { amount_pt: 0, amount_t: 11, amount_i: 0, amount_d: 0, amount_h: 11 },
'010585893099': { amount_pt: 2.4301336573512, amount_t: 17, amount_i: 2, amount_d: 0, amount_h: 15 },
'010585893102': { amount_pt: 0, amount_t: 21, amount_i: 0, amount_d: 0, amount_h: 21 },
'010585893137': { amount_pt: 0.36845983787767, amount_t: 56, amount_i: 1, amount_d: 1, amount_h: 54 },
'010585893162': { amount_pt: 2.5906735751295, amount_t: 3, amount_i: 1, amount_d: 0, amount_h: 2 },
'010585893166': { amount_pt: 0, amount_t: 33, amount_i: 0, amount_d: 1, amount_h: 32 },
'010585893173': { amount_pt: 0, amount_t: 12, amount_i: 0, amount_d: 0, amount_h: 12 },
'010585893174': { amount_pt: 0, amount_t: 14, amount_i: 0, amount_d: 0, amount_h: 14 },
'010585895007': { amount_pt: 0, amount_t: 10, amount_i: 0, amount_d: 1, amount_h: 9 },
'010585895009': { amount_pt: 0, amount_t: 63, amount_i: 0, amount_d: 0, amount_h: 63 },
'010585895013': { amount_pt: 10.791366906475, amount_t: 13, amount_i: 3, amount_d: 0, amount_h: 10 },
'010585895014': { amount_pt: 0, amount_t: 5, amount_i: 0, amount_d: 0, amount_h: 5 },
'010585895015': { amount_pt: 1.3422818791946, amount_t: 48, amount_i: 1, amount_d: 1, amount_h: 46 },
'010585895025': { amount_pt: 0, amount_t: 1, amount_i: 0, amount_d: 0, amount_h: 1 },
'010585895044': { amount_pt: 1.6447368421053, amount_t: 9, amount_i: 1, amount_d: 0, amount_h: 8 },
'010585895061': { amount_pt: 0, amount_t: 19, amount_i: 0, amount_d: 0, amount_h: 19 },
'010585895062': { amount_pt: 0, amount_t: 5, amount_i: 0, amount_d: 0, amount_h: 5 },
'010585895072': { amount_pt: 2.7036160865157, amount_t: 65, amount_i: 8, amount_d: 2, amount_h: 55 },
'010585895074': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585895077': { amount_pt: 1.3062138458668, amount_t: 167, amount_i: 7, amount_d: 2, amount_h: 158 },
'010585895085': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585895100': { amount_pt: 0, amount_t: 6, amount_i: 0, amount_d: 1, amount_h: 5 },
'010585895103': { amount_pt: 0, amount_t: 1, amount_i: 0, amount_d: 0, amount_h: 1 },
'010585895106': { amount_pt: 4.2735042735043, amount_t: 6, amount_i: 1, amount_d: 0, amount_h: 5 },
'010585895113': { amount_pt: 0, amount_t: 16, amount_i: 0, amount_d: 0, amount_h: 16 },
'010585895115': { amount_pt: 0, amount_t: 6, amount_i: 0, amount_d: 0, amount_h: 6 },
'010585895119': { amount_pt: 0, amount_t: 2, amount_i: 0, amount_d: 0, amount_h: 2 },
'010585895125': { amount_pt: 0, amount_t: 12, amount_i: 0, amount_d: 0, amount_h: 12 },
'010585895128': { amount_pt: 1.1771630370806, amount_t: 22, amount_i: 2, amount_d: 0, amount_h: 20 },
'010585895131': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585895134': { amount_pt: 2.3201856148492, amount_t: 10, amount_i: 1, amount_d: 0, amount_h: 9 },
'010585895151': { amount_pt: 0, amount_t: 2, amount_i: 0, amount_d: 0, amount_h: 2 },
'010585895156': { amount_pt: 0, amount_t: 6, amount_i: 0, amount_d: 0, amount_h: 6 },
'010585895158': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585895159': { amount_pt: 0, amount_t: 0, amount_i: 0, amount_d: 0, amount_h: 0 },
'010585895161': { amount_pt: 0, amount_t: 8, amount_i: 0, amount_d: 0, amount_h: 8 },
'010585895164': { amount_pt: 1.9607843137255, amount_t: 21, amount_i: 2, amount_d: 0, amount_h: 19 },
'010585895167': { amount_pt: 0, amount_t: 8, amount_i: 0, amount_d: 1, amount_h: 7 },
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment