mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-17 11:19:15 +00:00
Merge branch 'main' into bug6095
This commit is contained in:
+4
-4
@@ -24,7 +24,7 @@ import java.util.Map;
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSailNumberCanonicalizerAndMatcher<CompetitorType> {
|
||||
protected static final String sailIdRegexpPattern = "^([A-Z][A-Z][A-Z])\\s*[^0-9]*([0-9]*)$";
|
||||
protected static final String sailIdRegexpPattern = "^([A-Z][A-Z][A-Z])?\\s*[^0-9]*([0-9]*)$";
|
||||
|
||||
public static class SailNumberMatch {
|
||||
private final String iocCode;
|
||||
@@ -43,7 +43,7 @@ public abstract class AbstractSailNumberCanonicalizerAndMatcher<CompetitorType>
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a sail number into a nationality code expected at the beginning of the string,
|
||||
* Parses a sail number into a nationality code expected at the beginning of the string but possibly empty,
|
||||
* and a numeric part assumed to be at the end of the string. Before matching, the {@code sailId}
|
||||
* string will be {@link String#trim() trimmed}, removing leading and trailing whitespace. If
|
||||
* the parameter matches the {@link #sailIdRegexpPattern} then a valid {@link SailNumberMatch}
|
||||
@@ -102,10 +102,10 @@ public abstract class AbstractSailNumberCanonicalizerAndMatcher<CompetitorType>
|
||||
}
|
||||
|
||||
public Map<String, CompetitorType> canonicalizeLeaderboardSailIDs(final Iterable<CompetitorType> competitors) {
|
||||
Map<String, CompetitorType> result = new HashMap<>();
|
||||
final Map<String, CompetitorType> result = new HashMap<>();
|
||||
for (final CompetitorType competitor : competitors) {
|
||||
final String competitorIdentifyingText = getCompetitorIdentifyingText(competitor);
|
||||
String canonicalizedSailID = canonicalizeSailID(competitorIdentifyingText.trim(), getThreeLetterIocCountryCode(competitor).trim());
|
||||
final String canonicalizedSailID = canonicalizeSailID(competitorIdentifyingText.trim(), getThreeLetterIocCountryCode(competitor).trim());
|
||||
if (canonicalizedSailID != null) {
|
||||
result.put(canonicalizedSailID, competitor);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
<plugin id="com.sap.sailing.resultimport" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.sailti.resultimport" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.sailwave.resultimport" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.sailwave.html.resultimport" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.server" autoStart="true" startLevel="5" />
|
||||
<plugin id="com.sap.sailing.server.gateway" autoStart="true" startLevel="5" />
|
||||
<plugin id="com.sap.sailing.shared.server" autoStart="true" startLevel="5" />
|
||||
|
||||
@@ -133,6 +133,10 @@ Computes leaderboard information for sailing races and offers RESTful APIs to al
|
||||
id="com.sap.sailing.sailwave.resultimport"
|
||||
version="0.0.0"/>
|
||||
|
||||
<plugin
|
||||
id="com.sap.sailing.sailwave.html.resultimport"
|
||||
version="0.0.0"/>
|
||||
|
||||
<plugin
|
||||
id="com.sap.sailing.manage2sail.resultimport"
|
||||
version="0.0.0"/>
|
||||
|
||||
+2
@@ -1,5 +1,6 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -82,6 +83,7 @@ public class ResultImportUrlsListComposite extends Composite {
|
||||
sailingServiceWrite.getUrlResultProviderNamesAndOptionalSampleURL(new AsyncCallback<List<Pair<String, String>>>() {
|
||||
@Override
|
||||
public void onSuccess(List<Pair<String, String>> urlProviderNamesAndOptionalSampleURL) {
|
||||
Collections.sort(urlProviderNamesAndOptionalSampleURL, (u1, u2)->u1.getA().compareTo(u2.getA()));
|
||||
urlProviderListBox.clear();
|
||||
urlProviderListBox.addItem(stringMessages.pleaseSelectAURLProvider());
|
||||
for (Pair<String, String> urlProviderNameAndSampleURL : urlProviderNamesAndOptionalSampleURL) {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src">
|
||||
<attributes>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="resources">
|
||||
<attributes>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.sap.sailing.sailwave.html.resultimport.test</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
pluginProject.extensions=false
|
||||
resolve.requirebundle=false
|
||||
@@ -0,0 +1,10 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Test
|
||||
Bundle-SymbolicName: com.sap.sailing.sailwave.html.resultimport.test
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Fragment-Host: com.sap.sailing.sailwave.html.resultimport
|
||||
Require-Bundle: org.junit
|
||||
Automatic-Module-Name: com.sap.sailing.sailwave.html.resultimport.test
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
@@ -0,0 +1,6 @@
|
||||
source.. = src/,\
|
||||
resources/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
resources/
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>root</artifactId>
|
||||
<groupId>com.sap.sailing</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>com.sap.sailing.sailwave.html.resultimport.test</artifactId>
|
||||
<packaging>eclipse-test-plugin</packaging>
|
||||
</project>
|
||||
@@ -0,0 +1,542 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=Big5">
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="description" content="sailwave results">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<title>Sailwave results for 2025 29er Asian Championship at 2025</title>
|
||||
|
||||
<style type="text/css">
|
||||
body {font: 72% arial, helvetica, sans-serif; text-align: center;}
|
||||
.hardleft {text-align: left; float: left; margin: 15px 0 15px 25px;}
|
||||
.hardright {text-align: right; float: right; margin: 15px 25px 15px 0;}
|
||||
table {text-align: left; margin: 0px auto 30px auto; font-size: 1em; border-collapse: collapse; border: 1px #fff solid;}
|
||||
td, th {padding: 4px; border: 2px #fff solid; vertical-align: top;}
|
||||
.caption {padding: 5px; text-align: center; border: 0; font-weight: bold;}
|
||||
h1 {font-size: 1.6em;}
|
||||
h2 {font-size: 1.4em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {text-align: center;}
|
||||
th {background-color: #aaf;}
|
||||
.contents {text-align: left; margin-left: 20%;}
|
||||
.even {background-color: #bbf;}
|
||||
.odd {background-color: #ddf;}
|
||||
.natflag {border: 1px #999 solid;}
|
||||
.nattext {font-size: 0.8em;}
|
||||
.place1 {font-weight: bold; background-color: #ffffaa;}
|
||||
.place2 {font-weight: bold; background-color: #aaaaff;}
|
||||
.place3 {font-weight: bold; background-color: #ffaaaa;}
|
||||
.placen {}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
</header>
|
||||
|
||||
<div id="wrap">
|
||||
|
||||
|
||||
<h1>2025 29er Asian Championship</h1>
|
||||
<h2></h2>
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
|
||||
<style>
|
||||
div.applicant-break {page-break-after:always;}
|
||||
</style>
|
||||
<h3 class="seriestitle">Results are provisional as of 19:09 on February 15, 2025</h3>
|
||||
<h3 class="summarytitle">Overall</h3>
|
||||
<div class="caption summarycaption">Sailed: 12, Discards: 2, To count: 10, Entries: 19, Scoring system: Appendix A</div>
|
||||
<table class="summarytable" cellspacing="0" cellpadding="0" border="0">
|
||||
<colgroup span="20">
|
||||
<col class="rank">
|
||||
<col class="class">
|
||||
<col class="division">
|
||||
<col class="nat">
|
||||
<col class="sailno">
|
||||
<col class="helmname">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="total">
|
||||
<col class="nett">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="titlerow">
|
||||
<th>Rank</th>
|
||||
<th>Class</th>
|
||||
<th>Divisions</th>
|
||||
<th>Nat</th>
|
||||
<th>Sail No</th>
|
||||
<th>Sailors</th>
|
||||
<th>R1</th>
|
||||
<th>R2</th>
|
||||
<th>R3</th>
|
||||
<th>R4</th>
|
||||
<th>R5</th>
|
||||
<th>R6</th>
|
||||
<th>R7</th>
|
||||
<th>R8</th>
|
||||
<th>R9</th>
|
||||
<th>R10</th>
|
||||
<th>R11</th>
|
||||
<th>R12</th>
|
||||
<th>Total</th>
|
||||
<th>Nett</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd summaryrow">
|
||||
<td>1st</td>
|
||||
<td>29er</td>
|
||||
<td>Mixed</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>3356</td>
|
||||
<td>Raphael Mak, Tiffany Mak</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank3">(3.0)</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td>(6.0)</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td>25.0</td>
|
||||
<td>16.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>2nd</td>
|
||||
<td>29er</td>
|
||||
<td>Men</td>
|
||||
<td><img class="natflag" title="USA" src="29er_files/USA.jpg"></td>
|
||||
<td>20</td>
|
||||
<td>Kevin Cason, Holland Vierling</td>
|
||||
<td>(7.0)</td>
|
||||
<td>(6.0)</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td>5.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>36.0</td>
|
||||
<td>23.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>3rd</td>
|
||||
<td>29er</td>
|
||||
<td>Mixed</td>
|
||||
<td><img class="natflag" title="THA" src="29er_files/THA.jpg"></td>
|
||||
<td>621</td>
|
||||
<td>Patcharaphan Ongkaloy, Kan Kachachuen</td>
|
||||
<td>4.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>(6.0)</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>5.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td>6.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td>4.0</td>
|
||||
<td>(7.0)</td>
|
||||
<td>5.0</td>
|
||||
<td>4.0</td>
|
||||
<td>51.0</td>
|
||||
<td>38.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>4th</td>
|
||||
<td>29er</td>
|
||||
<td>Junior , Men</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>3354</td>
|
||||
<td>Ethan Kiu, Louis Polson</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td>(8.0)</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td>7.0</td>
|
||||
<td>(9.0)</td>
|
||||
<td>7.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td>6.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>8.0</td>
|
||||
<td>4.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td>58.0</td>
|
||||
<td>41.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>5th</td>
|
||||
<td>29er</td>
|
||||
<td>Women</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>2840</td>
|
||||
<td>Sienne Thiry, Tomoe Thiry</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>5.0</td>
|
||||
<td>7.0</td>
|
||||
<td>4.0</td>
|
||||
<td>4.0</td>
|
||||
<td>4.0</td>
|
||||
<td>4.0</td>
|
||||
<td>(20.0 DSQ)</td>
|
||||
<td>5.0</td>
|
||||
<td>(9.0)</td>
|
||||
<td>8.0</td>
|
||||
<td>5.0</td>
|
||||
<td>78.0</td>
|
||||
<td>49.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>6th</td>
|
||||
<td>29er</td>
|
||||
<td>Men</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>3398</td>
|
||||
<td>Ayden Pang, Xu Peng CHEN</td>
|
||||
<td>6.0</td>
|
||||
<td>4.0</td>
|
||||
<td>4.0</td>
|
||||
<td>(11.0)</td>
|
||||
<td>6.0</td>
|
||||
<td>11.0</td>
|
||||
<td>(20.0 DSQ)</td>
|
||||
<td>5.0</td>
|
||||
<td>7.0</td>
|
||||
<td>5.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>7.0</td>
|
||||
<td>89.0</td>
|
||||
<td>58.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>7th</td>
|
||||
<td>29er</td>
|
||||
<td>Mixed</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>2566</td>
|
||||
<td>Chloe Kong, Ethan Kong</td>
|
||||
<td>5.0</td>
|
||||
<td>11.0</td>
|
||||
<td>5.0</td>
|
||||
<td>5.0</td>
|
||||
<td>8.0</td>
|
||||
<td>6.0</td>
|
||||
<td>(20.0 SCP50)</td>
|
||||
<td>(20.0 DSQ)</td>
|
||||
<td>9.0</td>
|
||||
<td>6.0</td>
|
||||
<td>6.0</td>
|
||||
<td>6.0</td>
|
||||
<td>107.0</td>
|
||||
<td>67.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>8th</td>
|
||||
<td>29er</td>
|
||||
<td>Junior , Women</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>3355</td>
|
||||
<td>ZiHan Liu, Bernice Pang</td>
|
||||
<td>8.0</td>
|
||||
<td>(12.0)</td>
|
||||
<td>10.0</td>
|
||||
<td>(12.0)</td>
|
||||
<td>11.0</td>
|
||||
<td>9.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>4.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>10.0</td>
|
||||
<td>9.0</td>
|
||||
<td>92.0</td>
|
||||
<td>68.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>9th</td>
|
||||
<td>29er</td>
|
||||
<td>Junior , Men</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>3405</td>
|
||||
<td>Nicholas Hon, Kaden Chan</td>
|
||||
<td>(12.0)</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td>8.0</td>
|
||||
<td>10.0</td>
|
||||
<td>(15.0)</td>
|
||||
<td>12.0</td>
|
||||
<td>12.0</td>
|
||||
<td>7.0</td>
|
||||
<td>10.0</td>
|
||||
<td>4.0</td>
|
||||
<td>7.0</td>
|
||||
<td>8.0</td>
|
||||
<td>107.0</td>
|
||||
<td>80.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>10th</td>
|
||||
<td>29er</td>
|
||||
<td>Women</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>3393</td>
|
||||
<td>Kristen Hwang, McCarley Wong</td>
|
||||
<td>9.0</td>
|
||||
<td>7.0</td>
|
||||
<td>12.0</td>
|
||||
<td>8.0</td>
|
||||
<td>7.0</td>
|
||||
<td>5.0</td>
|
||||
<td>7.0</td>
|
||||
<td>10.0</td>
|
||||
<td>8.0</td>
|
||||
<td>(14.0)</td>
|
||||
<td>(13.0)</td>
|
||||
<td>10.0</td>
|
||||
<td>110.0</td>
|
||||
<td>83.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>11th</td>
|
||||
<td>29er</td>
|
||||
<td>Men</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>3055</td>
|
||||
<td>Yan Cheuk NG, Kam Hing HU</td>
|
||||
<td>11.0</td>
|
||||
<td>9.0</td>
|
||||
<td>9.0</td>
|
||||
<td>6.0</td>
|
||||
<td>(13.0)</td>
|
||||
<td>10.0</td>
|
||||
<td>9.0</td>
|
||||
<td>(20.0 DSQ)</td>
|
||||
<td>12.0</td>
|
||||
<td>11.0</td>
|
||||
<td>9.0</td>
|
||||
<td>11.0</td>
|
||||
<td>130.0</td>
|
||||
<td>97.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>12th</td>
|
||||
<td>29er</td>
|
||||
<td>Junior , Men</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>3383</td>
|
||||
<td>James Ashwood, Conrad Lumsden</td>
|
||||
<td>(13.0)</td>
|
||||
<td>10.0</td>
|
||||
<td>11.0</td>
|
||||
<td>9.0</td>
|
||||
<td>12.0</td>
|
||||
<td>(20.0 RET)</td>
|
||||
<td>8.0</td>
|
||||
<td>9.0</td>
|
||||
<td>13.0</td>
|
||||
<td>12.0</td>
|
||||
<td>11.0</td>
|
||||
<td>12.0</td>
|
||||
<td>140.0</td>
|
||||
<td>107.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>13th</td>
|
||||
<td>29er</td>
|
||||
<td>Men</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>3056</td>
|
||||
<td>Kyle Lee, Brandon Liu</td>
|
||||
<td>10.0</td>
|
||||
<td>(14.0)</td>
|
||||
<td>(13.0)</td>
|
||||
<td>13.0</td>
|
||||
<td>10.0</td>
|
||||
<td>13.0</td>
|
||||
<td>10.0</td>
|
||||
<td>8.0</td>
|
||||
<td>11.0</td>
|
||||
<td>10.0</td>
|
||||
<td>12.0</td>
|
||||
<td>13.0</td>
|
||||
<td>137.0</td>
|
||||
<td>110.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>14th</td>
|
||||
<td>29er</td>
|
||||
<td>Mixed</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>2750</td>
|
||||
<td>Hins Law, Daisy Chan</td>
|
||||
<td>14.0</td>
|
||||
<td>13.0</td>
|
||||
<td>14.0</td>
|
||||
<td>14.0</td>
|
||||
<td>(16.0)</td>
|
||||
<td>14.0</td>
|
||||
<td>13.0</td>
|
||||
<td>(20.0 UFD)</td>
|
||||
<td>15.0</td>
|
||||
<td>13.0</td>
|
||||
<td>14.0</td>
|
||||
<td>14.0</td>
|
||||
<td>174.0</td>
|
||||
<td>138.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>15th</td>
|
||||
<td>29er</td>
|
||||
<td>Junior , Women</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>2846</td>
|
||||
<td>Alexandra Yam, Keira Slaughter</td>
|
||||
<td>15.0</td>
|
||||
<td>15.0</td>
|
||||
<td>(20.0 RET)</td>
|
||||
<td>(20.0 DNF)</td>
|
||||
<td>20.0 RET</td>
|
||||
<td>15.0</td>
|
||||
<td>14.0</td>
|
||||
<td>12.0</td>
|
||||
<td>14.0</td>
|
||||
<td>16.0</td>
|
||||
<td>15.0</td>
|
||||
<td>15.0</td>
|
||||
<td>191.0</td>
|
||||
<td>151.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>16th</td>
|
||||
<td>29er</td>
|
||||
<td>Men</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>3053</td>
|
||||
<td>Cameron Law, Christopher Lam</td>
|
||||
<td>(20.0 DNC)</td>
|
||||
<td>(20.0 DNC)</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td>8.0</td>
|
||||
<td>4.5 RDG</td>
|
||||
<td>20.0 DNS</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>193.5</td>
|
||||
<td>153.5</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>17th</td>
|
||||
<td>29er</td>
|
||||
<td>Junior, Mixed</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>2531</td>
|
||||
<td>Belmira Iong, Alfred Fong</td>
|
||||
<td>(20.0 NSC)</td>
|
||||
<td>(20.0 NSC)</td>
|
||||
<td>20.0 DNS</td>
|
||||
<td>20.0 RET</td>
|
||||
<td>17.0</td>
|
||||
<td>20.0 DNF</td>
|
||||
<td>20.0 DNF</td>
|
||||
<td>13.0</td>
|
||||
<td>16.0</td>
|
||||
<td>15.0</td>
|
||||
<td>16.0</td>
|
||||
<td>16.0</td>
|
||||
<td>213.0</td>
|
||||
<td>173.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>18th</td>
|
||||
<td>29er</td>
|
||||
<td>Mixed</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>2521</td>
|
||||
<td>Jade Zirah, Alfred Yip</td>
|
||||
<td>16.0</td>
|
||||
<td>(20.0 DNF)</td>
|
||||
<td>(20.0 DNF)</td>
|
||||
<td>20.0 RET</td>
|
||||
<td>14.0</td>
|
||||
<td>20.0 RET</td>
|
||||
<td>15.0</td>
|
||||
<td>11.0</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>216.0</td>
|
||||
<td>176.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>19th</td>
|
||||
<td>29er</td>
|
||||
<td>Junior , Men</td>
|
||||
<td><img class="natflag" title="HKG" src="29er_files/HKG.jpg"></td>
|
||||
<td>2411</td>
|
||||
<td>Sebastian Chun, Ambrose Chan</td>
|
||||
<td>(20.0 DNC)</td>
|
||||
<td>(20.0 DNC)</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>20.0 DNC</td>
|
||||
<td>240.0</td>
|
||||
<td>200.0</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="hardleft"><a href="https://"></a><br><a href="mailto:"></a></p>
|
||||
<p class="hardright"><a href="https://"></a><br><a href="mailto:"></a></p>
|
||||
<p>Sailwave Scoring Software 2.37.00<br><a href="https://www.sailwave.com/">www.sailwave.com</a></p>
|
||||
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
</footer>
|
||||
|
||||
<div id="scrollbottom"></div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body></html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,422 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=Big5">
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="description" content="sailwave results">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<title>Sailwave results for Sun Hung Kai & Co. Hong Kong Race Week 2025 at 2025</title>
|
||||
|
||||
<style type="text/css">
|
||||
body {font: 72% arial, helvetica, sans-serif; text-align: center;}
|
||||
.hardleft {text-align: left; float: left; margin: 15px 0 15px 25px;}
|
||||
.hardright {text-align: right; float: right; margin: 15px 25px 15px 0;}
|
||||
table {text-align: left; margin: 0px auto 30px auto; font-size: 1em; border-collapse: collapse; border: 1px #fff solid;}
|
||||
td, th {padding: 4px; border: 2px #fff solid; vertical-align: top;}
|
||||
.caption {padding: 5px; text-align: center; border: 0; font-weight: bold;}
|
||||
h1 {font-size: 1.6em;}
|
||||
h2 {font-size: 1.4em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {text-align: center;}
|
||||
th {background-color: #aaf;}
|
||||
.contents {text-align: left; margin-left: 20%;}
|
||||
.even {background-color: #bbf;}
|
||||
.odd {background-color: #ddf;}
|
||||
.natflag {border: 1px #999 solid;}
|
||||
.nattext {font-size: 0.8em;}
|
||||
.place1 {font-weight: bold; background-color: #ffffaa;}
|
||||
.place2 {font-weight: bold; background-color: #aaaaff;}
|
||||
.place3 {font-weight: bold; background-color: #ffaaaa;}
|
||||
.placen {}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
</header>
|
||||
|
||||
<div id="wrap">
|
||||
|
||||
|
||||
<h1>Sun Hung Kai & Co. Hong Kong Race Week 2025</h1>
|
||||
<h2></h2>
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
|
||||
<style>
|
||||
div.applicant-break {page-break-after:always;}
|
||||
</style>
|
||||
<h3 class="seriestitle">Results are provisional as of 9:43 on February 16, 2025</h3>
|
||||
<h3 class="summarytitle" id="summaryilca_6">ILCA 6 Class</h3>
|
||||
<div class="caption summarycaption">Sailed: 9, Discards: 2, To count: 7, Entries: 17, Scoring system: Appendix A</div>
|
||||
<table class="summarytable" cellspacing="0" cellpadding="0" border="0">
|
||||
<colgroup span="16">
|
||||
<col class="rank">
|
||||
<col class="class">
|
||||
<col class="nat">
|
||||
<col class="sailno">
|
||||
<col class="helmname">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="total">
|
||||
<col class="nett">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="titlerow">
|
||||
<th>Rank</th>
|
||||
<th>Class</th>
|
||||
<th>Nat</th>
|
||||
<th>Sail No</th>
|
||||
<th>Helm Name</th>
|
||||
<th>R1</th>
|
||||
<th>R2</th>
|
||||
<th>R3</th>
|
||||
<th>R4</th>
|
||||
<th>R5</th>
|
||||
<th>R6</th>
|
||||
<th>R7</th>
|
||||
<th>R8</th>
|
||||
<th>R9</th>
|
||||
<th>Total</th>
|
||||
<th>Nett</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd summaryrow">
|
||||
<td>1st</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>191713</td>
|
||||
<td>Stephanie Norton</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank2">(2.0)</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank2">(2.0)</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td>11.0</td>
|
||||
<td>7.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>2nd</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>211717</td>
|
||||
<td>Nancy Highfield</td>
|
||||
<td class="rank2">(2.0)</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td>(11.0)</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td>25.0</td>
|
||||
<td>12.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>3rd</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="JPN" src="ILCA6_files/JPN.jpg"></td>
|
||||
<td>208625</td>
|
||||
<td>NANA Funazawa</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>4.0</td>
|
||||
<td>5.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>4.0</td>
|
||||
<td>(7.0)</td>
|
||||
<td>(6.0)</td>
|
||||
<td>38.0</td>
|
||||
<td>25.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>4th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>223750</td>
|
||||
<td>Daniel Kin Chung Chan</td>
|
||||
<td>(10.0)</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>4.0</td>
|
||||
<td>(5.0)</td>
|
||||
<td>4.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>4.0</td>
|
||||
<td>4.0</td>
|
||||
<td>40.0</td>
|
||||
<td>25.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>5th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="JPN" src="ILCA6_files/JPN.jpg"></td>
|
||||
<td>217702</td>
|
||||
<td>Haruka Hattori</td>
|
||||
<td>4.0</td>
|
||||
<td>6.0</td>
|
||||
<td>8.0</td>
|
||||
<td>8.0</td>
|
||||
<td>7.0</td>
|
||||
<td>(9.0)</td>
|
||||
<td>5.0</td>
|
||||
<td>(10.0)</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>60.0</td>
|
||||
<td>41.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>6th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>209319</td>
|
||||
<td>Seb Van Ommeren</td>
|
||||
<td>5.0</td>
|
||||
<td>(8.0)</td>
|
||||
<td>7.0</td>
|
||||
<td>7.0</td>
|
||||
<td>(13.0)</td>
|
||||
<td>8.0</td>
|
||||
<td>6.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td>8.0</td>
|
||||
<td>64.0</td>
|
||||
<td>43.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>7th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="CHN" src="ILCA6_files/CHN.jpg"></td>
|
||||
<td>223276</td>
|
||||
<td>Xinran Chen</td>
|
||||
<td>7.0</td>
|
||||
<td>7.0</td>
|
||||
<td>(11.0)</td>
|
||||
<td>(9.0)</td>
|
||||
<td>4.0</td>
|
||||
<td>6.0</td>
|
||||
<td>8.0</td>
|
||||
<td>6.0</td>
|
||||
<td>9.0</td>
|
||||
<td>67.0</td>
|
||||
<td>47.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>8th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="CHN" src="ILCA6_files/CHN.jpg"></td>
|
||||
<td>210199</td>
|
||||
<td>Haolun Xia</td>
|
||||
<td>(11.0 SCP30%)</td>
|
||||
<td>5.0</td>
|
||||
<td>6.0</td>
|
||||
<td>5.0</td>
|
||||
<td>6.0</td>
|
||||
<td>(11.0)</td>
|
||||
<td>10.0</td>
|
||||
<td>8.0</td>
|
||||
<td>7.0</td>
|
||||
<td>69.0</td>
|
||||
<td>47.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>9th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>213211</td>
|
||||
<td>Xavier Wilde</td>
|
||||
<td>8.0</td>
|
||||
<td>(11.0)</td>
|
||||
<td>4.0</td>
|
||||
<td>6.0</td>
|
||||
<td>9.0</td>
|
||||
<td>7.0</td>
|
||||
<td>(11.0)</td>
|
||||
<td>9.0</td>
|
||||
<td>5.0</td>
|
||||
<td>70.0</td>
|
||||
<td>48.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>10th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>221934</td>
|
||||
<td>Samuel Tan-Hardy</td>
|
||||
<td>9.0</td>
|
||||
<td>9.0</td>
|
||||
<td>10.0</td>
|
||||
<td>(12.0)</td>
|
||||
<td>8.0</td>
|
||||
<td>5.0</td>
|
||||
<td>9.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>(11.0)</td>
|
||||
<td>76.0</td>
|
||||
<td>53.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>11th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>221401</td>
|
||||
<td>Ziyan Huang</td>
|
||||
<td>11.0</td>
|
||||
<td>10.0</td>
|
||||
<td>9.0</td>
|
||||
<td>10.0</td>
|
||||
<td>11.0</td>
|
||||
<td>10.0</td>
|
||||
<td>7.0</td>
|
||||
<td>(17.0)</td>
|
||||
<td>(15.0 SCP30%)</td>
|
||||
<td>100.0</td>
|
||||
<td>68.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>12th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="SGP" src="ILCA6_files/SGP.jpg"></td>
|
||||
<td>225262</td>
|
||||
<td>John Gabriel LIM</td>
|
||||
<td>(12.0)</td>
|
||||
<td>12.0</td>
|
||||
<td>12.0</td>
|
||||
<td>11.0</td>
|
||||
<td>10.0</td>
|
||||
<td>12.0</td>
|
||||
<td>12.0</td>
|
||||
<td>(13.9 SCP5%)</td>
|
||||
<td>12.0</td>
|
||||
<td>106.9</td>
|
||||
<td>81.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>13th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="CHN" src="ILCA6_files/CHN.jpg"></td>
|
||||
<td>225505</td>
|
||||
<td>Yan Duo Pu</td>
|
||||
<td>(15.0)</td>
|
||||
<td>(16.0)</td>
|
||||
<td>14.0</td>
|
||||
<td>15.0</td>
|
||||
<td>14.0</td>
|
||||
<td>14.0</td>
|
||||
<td>13.0</td>
|
||||
<td>5.0</td>
|
||||
<td>14.0</td>
|
||||
<td>120.0</td>
|
||||
<td>89.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>14th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>213316</td>
|
||||
<td>Adam Kan</td>
|
||||
<td>(13.0)</td>
|
||||
<td>13.0</td>
|
||||
<td>13.0</td>
|
||||
<td>13.0</td>
|
||||
<td>12.0</td>
|
||||
<td>13.0</td>
|
||||
<td>(14.0)</td>
|
||||
<td>12.0</td>
|
||||
<td>13.0</td>
|
||||
<td>116.0</td>
|
||||
<td>89.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>15th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>213251</td>
|
||||
<td>Nick Akov</td>
|
||||
<td>14.0</td>
|
||||
<td>(15.0)</td>
|
||||
<td>(15.0)</td>
|
||||
<td>14.0</td>
|
||||
<td>15.0</td>
|
||||
<td>15.0</td>
|
||||
<td>15.0</td>
|
||||
<td>14.0</td>
|
||||
<td>15.0</td>
|
||||
<td>132.0</td>
|
||||
<td>102.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>16th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>211730</td>
|
||||
<td>Jeremy Chan</td>
|
||||
<td>(16.0)</td>
|
||||
<td>14.0</td>
|
||||
<td>16.0</td>
|
||||
<td>16.0</td>
|
||||
<td>16.0</td>
|
||||
<td>16.0</td>
|
||||
<td>(18.0 DNF)</td>
|
||||
<td>16.0</td>
|
||||
<td>16.0</td>
|
||||
<td>144.0</td>
|
||||
<td>110.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>17th</td>
|
||||
<td>ILCA 6</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg"></td>
|
||||
<td>213343</td>
|
||||
<td>Marcello Giamporcaro</td>
|
||||
<td>(18.0 DNC)</td>
|
||||
<td>(18.0 DNC)</td>
|
||||
<td>18.0 DNC</td>
|
||||
<td>18.0 DNC</td>
|
||||
<td>18.0 DNC</td>
|
||||
<td>18.0 DNC</td>
|
||||
<td>18.0 DNC</td>
|
||||
<td>15.0</td>
|
||||
<td>17.0</td>
|
||||
<td>158.0</td>
|
||||
<td>122.0</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="hardleft"><a href="https://"></a><br><a href="mailto:"></a></p>
|
||||
<p class="hardright"><a href="https://"></a><br><a href="mailto:"></a></p>
|
||||
<p>Sailwave Scoring Software 2.37.00<br><a href="https://www.sailwave.com/">www.sailwave.com</a></p>
|
||||
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
</footer>
|
||||
|
||||
<div id="scrollbottom"></div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body></html>
|
||||
@@ -0,0 +1,188 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=Big5">
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="description" content="sailwave results">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<title>Sailwave results for Sun Hung Kai & Co. Hong Kong Race Week 2025 at 2025</title>
|
||||
|
||||
<style type="text/css">
|
||||
body {font: 72% arial, helvetica, sans-serif; text-align: center;}
|
||||
.hardleft {text-align: left; float: left; margin: 15px 0 15px 25px;}
|
||||
.hardright {text-align: right; float: right; margin: 15px 25px 15px 0;}
|
||||
table {text-align: left; margin: 0px auto 30px auto; font-size: 1em; border-collapse: collapse; border: 1px #fff solid;}
|
||||
td, th {padding: 4px; border: 2px #fff solid; vertical-align: top;}
|
||||
.caption {padding: 5px; text-align: center; border: 0; font-weight: bold;}
|
||||
h1 {font-size: 1.6em;}
|
||||
h2 {font-size: 1.4em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
p {text-align: center;}
|
||||
th {background-color: #aaf;}
|
||||
.contents {text-align: left; margin-left: 20%;}
|
||||
.even {background-color: #bbf;}
|
||||
.odd {background-color: #ddf;}
|
||||
.natflag {border: 1px #999 solid;}
|
||||
.nattext {font-size: 0.8em;}
|
||||
.place1 {font-weight: bold; background-color: #ffffaa;}
|
||||
.place2 {font-weight: bold; background-color: #aaaaff;}
|
||||
.place3 {font-weight: bold; background-color: #ffaaaa;}
|
||||
.placen {}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
</header>
|
||||
|
||||
<div id="wrap">
|
||||
|
||||
|
||||
<h1>Sun Hung Kai & Co. Hong Kong Race Week 2025</h1>
|
||||
<h2></h2>
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
|
||||
<style>
|
||||
div.applicant-break {page-break-after:always;}
|
||||
</style>
|
||||
<h3 class="seriestitle">Results are provisional as of 19:08 on February 15, 2025</h3>
|
||||
<h3 class="summarytitle" id="summaryilca_7">ILCA 7 Class</h3>
|
||||
<div class="caption summarycaption">Sailed: 9, Discards: 2, To count: 7, Entries: 4, Scoring system: Appendix A</div>
|
||||
<table class="summarytable" cellspacing="0" cellpadding="0" border="0">
|
||||
<colgroup span="16">
|
||||
<col class="rank">
|
||||
<col class="class">
|
||||
<col class="nat">
|
||||
<col class="sailno">
|
||||
<col class="helmname">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="race">
|
||||
<col class="total">
|
||||
<col class="nett">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="titlerow">
|
||||
<th>Rank</th>
|
||||
<th>Class</th>
|
||||
<th>Nat</th>
|
||||
<th>Sail No</th>
|
||||
<th>Helm Name</th>
|
||||
<th>R1</th>
|
||||
<th>R2</th>
|
||||
<th>R3</th>
|
||||
<th>R4</th>
|
||||
<th>R5</th>
|
||||
<th>R6</th>
|
||||
<th>R7</th>
|
||||
<th>R8</th>
|
||||
<th>R9</th>
|
||||
<th>Total</th>
|
||||
<th>Nett</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd summaryrow">
|
||||
<td>1st</td>
|
||||
<td>ILCA 7</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA7_files/HKG.jpg"></td>
|
||||
<td>171979</td>
|
||||
<td>Nicholas Halliday</td>
|
||||
<td class="rank1">(1.0)</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank2">(2.0)</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td>10.0</td>
|
||||
<td>7.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>2nd</td>
|
||||
<td>ILCA 7</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA7_files/HKG.jpg"></td>
|
||||
<td>215313</td>
|
||||
<td>Peter Jessop</td>
|
||||
<td class="rank2">(2.0)</td>
|
||||
<td class="rank2">(2.0)</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank1">1.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td class="rank2">2.0</td>
|
||||
<td>17.0</td>
|
||||
<td>13.0</td>
|
||||
</tr>
|
||||
<tr class="odd summaryrow">
|
||||
<td>3rd</td>
|
||||
<td>ILCA 7</td>
|
||||
<td><img class="natflag" title="HKG" src="ILCA7_files/HKG.jpg"></td>
|
||||
<td>150109</td>
|
||||
<td>Michael Wilson</td>
|
||||
<td>(5.0 DNF)</td>
|
||||
<td>(5.0 DNF)</td>
|
||||
<td class="rank3">5.0 DNF</td>
|
||||
<td class="rank3">5.0 DNC</td>
|
||||
<td class="rank3">5.0 DNC</td>
|
||||
<td class="rank3">5.0 DNC</td>
|
||||
<td class="rank3">5.0 DNC</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td>41.0</td>
|
||||
<td>31.0</td>
|
||||
</tr>
|
||||
<tr class="even summaryrow">
|
||||
<td>4th</td>
|
||||
<td>ILCA 7</td>
|
||||
<td><img class="natflag" title="SWE" src="ILCA7_files/SWE.jpg"></td>
|
||||
<td>221751</td>
|
||||
<td>Axel Wieland</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td class="rank3">3.0</td>
|
||||
<td class="rank3">(5.0 DNC)</td>
|
||||
<td class="rank3">(5.0 DNC)</td>
|
||||
<td class="rank3">5.0 DNC</td>
|
||||
<td class="rank3">5.0 DNC</td>
|
||||
<td class="rank3">5.0 DNC</td>
|
||||
<td>5.0 DNC</td>
|
||||
<td>5.0 DNC</td>
|
||||
<td>41.0</td>
|
||||
<td>31.0</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="hardleft"><a href="https://"></a><br><a href="mailto:"></a></p>
|
||||
<p class="hardright"><a href="https://"></a><br><a href="mailto:"></a></p>
|
||||
<p>Sailwave Scoring Software 2.37.00<br><a href="https://www.sailwave.com/">www.sailwave.com</a></p>
|
||||
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
</footer>
|
||||
|
||||
<div id="scrollbottom"></div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body></html>
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
package com.sap.sailing.sailwave.html.resultimport.test;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.resultimport.CompetitorRow;
|
||||
import com.sap.sailing.resultimport.RegattaResults;
|
||||
import com.sap.sailing.sailwave.html.resultimport.impl.SailwaveHtmlParser;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class SimpleHtmlParsingTest {
|
||||
@Test
|
||||
public void testOpenSampleHtml() throws IOException {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("ILCA4.html")));
|
||||
final String readLine = br.readLine();
|
||||
assertNotNull(readLine);
|
||||
br.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiLineTD() throws IOException {
|
||||
final InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("ILCA6.html");
|
||||
SailwaveHtmlParser parser = new SailwaveHtmlParser();
|
||||
final RegattaResults regattaResults = parser.getRegattaResults(resourceAsStream);
|
||||
List<CompetitorRow> result = regattaResults.getCompetitorResults();
|
||||
assertFalse(result.isEmpty());
|
||||
assertEquals(17, result.size());
|
||||
assertTrue(regattaResults.getMetadata().get("seriestitle").contains("Results are provisional as of 9:43 on February 16, 2025"));
|
||||
int competitorsChecked = 0;
|
||||
for (CompetitorRow row : result) {
|
||||
if (Util.contains(row.getNames(), "Daniel Kin Chung Chan")) {
|
||||
competitorsChecked++;
|
||||
assertEquals("HKG 223750", row.getSailID());
|
||||
assertEquals(25.0, row.getScoreAfterDiscarding(), 0.000000001);
|
||||
assertEquals(40.0, row.getTotalPointsBeforeDiscarding(), 0.000000001);
|
||||
}
|
||||
if (Util.contains(row.getNames(), "Haolun Xia")) {
|
||||
competitorsChecked++;
|
||||
assertEquals("CHN 210199", row.getSailID());
|
||||
assertEquals(47.0, row.getScoreAfterDiscarding(), 0.000000001);
|
||||
assertEquals(69.0, row.getTotalPointsBeforeDiscarding(), 0.000000001);
|
||||
assertEquals((double) 11.00, (double) Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 0).getScore(), 0.000000001);
|
||||
assertEquals("SCP", Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 0).getMaxPointsReason());
|
||||
assertEquals(true, Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 0).isDiscarded());
|
||||
}
|
||||
}
|
||||
assertEquals(2, competitorsChecked);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCompetitorRows29er() throws IOException {
|
||||
SailwaveHtmlParser parser = new SailwaveHtmlParser();
|
||||
final InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("29er.html");
|
||||
List<CompetitorRow> result = parser.getRegattaResults(resourceAsStream).getCompetitorResults();
|
||||
assertFalse(result.isEmpty());
|
||||
assertEquals(19, result.size());
|
||||
int competitorsChecked = 0;
|
||||
for (CompetitorRow row : result) {
|
||||
if (Util.contains(row.getNames(), "Ethan Kiu")) {
|
||||
competitorsChecked++;
|
||||
assertEquals("HKG 3354", row.getSailID());
|
||||
assertEquals(41.00, row.getScoreAfterDiscarding(), 0.000000001);
|
||||
assertEquals(58.00, row.getTotalPointsBeforeDiscarding(), 0.000000001);
|
||||
assertEquals((double) 2, (double) Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 0).getScore(), 0.000000001);
|
||||
assertEquals(false, Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 0).isDiscarded());
|
||||
} else if (Util.contains(row.getNames(), "Kaden Chan")) {
|
||||
competitorsChecked++;
|
||||
assertEquals("HKG 3405", row.getSailID());
|
||||
assertEquals(80.00, row.getScoreAfterDiscarding(), 0.000000001);
|
||||
assertEquals(107.00, row.getTotalPointsBeforeDiscarding(), 0.000000001);
|
||||
assertEquals((double) 8, (double) Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 2).getScore(), 0.000000001);
|
||||
assertEquals(false, Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 2).isDiscarded());
|
||||
assertEquals((double) 15, (double) Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 4).getScore(), 0.000000001);
|
||||
assertEquals(true, Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 4).isDiscarded());
|
||||
} else if (Util.contains(row.getNames(), "Chloe Kong")) {
|
||||
competitorsChecked++;
|
||||
assertEquals("HKG 2566", row.getSailID());
|
||||
assertEquals(67.00, row.getScoreAfterDiscarding(), 0.000000001);
|
||||
assertEquals(107.00, row.getTotalPointsBeforeDiscarding(), 0.000000001);
|
||||
assertEquals("SCP", Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 6).getMaxPointsReason());
|
||||
assertEquals((double) 20, (double) Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 6).getScore(), 0.000000001);
|
||||
assertEquals(true, Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 6).isDiscarded());
|
||||
}
|
||||
}
|
||||
assertEquals(3, competitorsChecked);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCompetitorRowsILCA4() throws IOException {
|
||||
SailwaveHtmlParser parser = new SailwaveHtmlParser();
|
||||
final InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("ILCA4.html");
|
||||
List<CompetitorRow> result = parser.getRegattaResults(resourceAsStream).getCompetitorResults();
|
||||
assertFalse(result.isEmpty());
|
||||
assertEquals(50, result.size());
|
||||
int competitorsChecked = 0;
|
||||
for (CompetitorRow row : result) {
|
||||
if (Util.contains(row.getNames(), "YONG LIANG Chuang")) {
|
||||
competitorsChecked++;
|
||||
assertEquals("TPE 221094", row.getSailID());
|
||||
assertEquals(198.00, row.getScoreAfterDiscarding(), 0.000000001);
|
||||
assertEquals(300.00, row.getTotalPointsBeforeDiscarding(), 0.000000001);
|
||||
assertEquals((double) 17, (double) Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 0).getScore(), 0.000000001);
|
||||
assertEquals(false, Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 0).isDiscarded());
|
||||
assertEquals((double) 30, (double) Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 1).getScore(), 0.000000001);
|
||||
assertEquals(false, Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 1).isDiscarded());
|
||||
assertEquals("DNC", Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 6).getMaxPointsReason());
|
||||
assertEquals((double) 51, (double) Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 6).getScore(), 0.000000001);
|
||||
assertEquals(false, Util.get(row.getRankAndMaxPointsReasonAndPointsAndDiscarded(), 6).isDiscarded());
|
||||
}
|
||||
}
|
||||
assertEquals(1, competitorsChecked);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.sap.sailing.sailwave.html.resultimport</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
@@ -0,0 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
@@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
pluginProject.extensions=false
|
||||
resolve.requirebundle=false
|
||||
@@ -0,0 +1,17 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Resultimport
|
||||
Bundle-SymbolicName: com.sap.sailing.sailwave.html.resultimport
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Activator: com.sap.sailing.sailwave.html.resultimport.impl.Activator
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Automatic-Module-Name: com.sap.sailing.sailwave.html.resultimport
|
||||
Import-Package: org.apache.commons.lang;version="[2.6.0,3.0.0)",
|
||||
org.osgi.framework;version="1.3.0",
|
||||
org.osgi.util.tracker;version="[1.5.0,2.0.0)"
|
||||
Require-Bundle: com.sap.sailing.resultimport,
|
||||
com.sap.sailing.domain.common,
|
||||
com.sap.sailing.domain.shared.android,
|
||||
com.sap.sse.common
|
||||
Bundle-ActivationPolicy: lazy
|
||||
@@ -0,0 +1,4 @@
|
||||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>root</artifactId>
|
||||
<groupId>com.sap.sailing</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>com.sap.sailing.sailwave.html.resultimport</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.sap.sailing.sailwave.html.resultimport.impl;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
import com.sap.sailing.domain.common.ScoreCorrectionProvider;
|
||||
import com.sap.sailing.resultimport.ResultUrlRegistry;
|
||||
import com.sap.sailing.resultimport.impl.ResultUrlRegistryServiceTrackerCustomizer;
|
||||
|
||||
public class Activator implements BundleActivator {
|
||||
private ServiceTracker<ResultUrlRegistry, ResultUrlRegistry> resultUrlRegistryServiceTracker;
|
||||
|
||||
public void start(BundleContext bundleContext) throws Exception {
|
||||
resultUrlRegistryServiceTracker = new ServiceTracker<>(bundleContext, ResultUrlRegistry.class,
|
||||
new ResultUrlRegistryServiceTrackerCustomizer(bundleContext) {
|
||||
@Override
|
||||
protected ScoreCorrectionProvider configureScoreCorrectionProvider(
|
||||
ResultUrlRegistry resultUrlRegistry) {
|
||||
final ScoreCorrectionProviderImpl service = new ScoreCorrectionProviderImpl(resultUrlRegistry);
|
||||
return service;
|
||||
}
|
||||
});
|
||||
resultUrlRegistryServiceTracker.open();
|
||||
}
|
||||
|
||||
public void stop(BundleContext bundleContext) throws Exception {
|
||||
resultUrlRegistryServiceTracker.close();
|
||||
}
|
||||
}
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
package com.sap.sailing.sailwave.html.resultimport.impl;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
|
||||
import com.sap.sailing.resultimport.CompetitorEntry;
|
||||
import com.sap.sailing.resultimport.CompetitorRow;
|
||||
import com.sap.sailing.resultimport.RegattaResults;
|
||||
import com.sap.sailing.resultimport.impl.CompetitorRowImpl;
|
||||
import com.sap.sailing.resultimport.impl.DefaultCompetitorEntryImpl;
|
||||
|
||||
public class SailwaveHtmlParser {
|
||||
static final String CLASS_METADATA = "class";
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SailwaveHtmlParser.class.getName());
|
||||
|
||||
public List<String> getRowContents(BufferedReader br) throws IOException {
|
||||
Pattern tr = Pattern.compile("<(tr|TR)([^<>]*)>");
|
||||
Pattern slashTr = Pattern.compile("</(tr|TR)([^<>]*)>");
|
||||
boolean inTr = false;
|
||||
final StringBuilder trContents = new StringBuilder();
|
||||
final List<String> tableRows = new ArrayList<String>(); // the contents of the <tr> tags found
|
||||
String readLine = br.readLine();
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
while (readLine != null && !readLine.contains("</tbody>")) {
|
||||
if (!inTr) {
|
||||
final Matcher trMatcher = tr.matcher(readLine);
|
||||
boolean foundTr = trMatcher.find(end);
|
||||
if (foundTr) {
|
||||
start = trMatcher.end(0);
|
||||
inTr = true;
|
||||
} else {
|
||||
readLine = br.readLine();
|
||||
end = 0;
|
||||
}
|
||||
} else { // we are within the contents of a <tr> tag here
|
||||
final Matcher slashTrMatcher = slashTr.matcher(readLine);
|
||||
boolean foundSlashTr = slashTrMatcher.find(start);
|
||||
if (foundSlashTr) {
|
||||
end = slashTrMatcher.start();
|
||||
inTr = false;
|
||||
} else {
|
||||
end = readLine.length();
|
||||
}
|
||||
trContents.append(readLine.substring(start, end));
|
||||
if (!foundSlashTr) {
|
||||
trContents.append('\n');
|
||||
readLine = br.readLine();
|
||||
start = 0;
|
||||
} else {
|
||||
tableRows.add(trContents.toString());
|
||||
trContents.delete(0, trContents.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
return tableRows;
|
||||
}
|
||||
|
||||
public List<String> getTagContents(String s, String tag) {
|
||||
Pattern tagPattern = Pattern.compile("<("+tag.toLowerCase()+"|"+tag.toUpperCase()+")([^<>]*)>");
|
||||
Pattern slashTag = Pattern.compile("</("+tag.toLowerCase()+"|"+tag.toUpperCase()+")([^<>]*)>");
|
||||
boolean inTag = false;
|
||||
List<String> result = new ArrayList<String>(); // the contents of the <td> tags found
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
boolean finished = false;
|
||||
while (!finished) {
|
||||
if (!inTag) {
|
||||
final Matcher tagMatcher = tagPattern.matcher(s);
|
||||
boolean foundTag = tagMatcher.find(end);
|
||||
if (foundTag) {
|
||||
start = tagMatcher.end(0);
|
||||
inTag = true;
|
||||
} else {
|
||||
finished = true;
|
||||
}
|
||||
} else { // we are within the contents of a <tr> tag here
|
||||
final Matcher slashTagMatcher = slashTag.matcher(s);
|
||||
boolean foundSlashTag = slashTagMatcher.find(start);
|
||||
if (foundSlashTag) {
|
||||
end = slashTagMatcher.start();
|
||||
inTag = false;
|
||||
result.add(StringEscapeUtils.unescapeHtml(s.substring(start, end).trim()));
|
||||
} else {
|
||||
result.add(StringEscapeUtils.unescapeHtml(s.substring(start).trim()));
|
||||
finished = true;
|
||||
logger.warning("unclosed "+tag+" tag in string \""+s+"\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param is closed before the method returns, also in case of exception
|
||||
*/
|
||||
public RegattaResults getRegattaResults(InputStream is) throws IOException {
|
||||
try {
|
||||
Map<String, Integer> classesCounts = new HashMap<>(); // counts the occurrences of boat class names
|
||||
final List<CompetitorRow> result = new ArrayList<CompetitorRow>();
|
||||
final BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
final Map<String, String> metadata = readMetadataBeforeTable(br);
|
||||
final LinkedHashMap<String, String> columnNamesAndStyles = readTableHeader(br);
|
||||
findTableBody(br);
|
||||
final List<String> rowContents = getRowContents(br);
|
||||
for (final String row : rowContents) {
|
||||
final List<String> tdContent = getTagContents(row, "td");
|
||||
result.add(createCompetitorRow(tdContent, columnNamesAndStyles, classesCounts));
|
||||
}
|
||||
addMostLikelyClassToMetadata(classesCounts, metadata);
|
||||
return new RegattaResults() {
|
||||
@Override
|
||||
public Map<String, String> getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
@Override
|
||||
public List<CompetitorRow> getCompetitorResults() {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void addMostLikelyClassToMetadata(Map<String, Integer> classesCounts, Map<String, String> metadata) {
|
||||
if (!classesCounts.isEmpty()) {
|
||||
// sort descending and pick first:
|
||||
metadata.put(CLASS_METADATA, classesCounts.entrySet().stream().sorted((e1, e2)->Integer.compare(e2.getValue(), e1.getValue())).findFirst().get().getKey());
|
||||
}
|
||||
}
|
||||
|
||||
private void findTableBody(BufferedReader br) throws IOException {
|
||||
String line;
|
||||
while ((line=br.readLine()) != null && !line.contains("<tbody>"))
|
||||
;
|
||||
}
|
||||
|
||||
private LinkedHashMap<String, String> readTableHeader(BufferedReader br) throws IOException {
|
||||
final LinkedHashMap<String, String> result = new LinkedHashMap<>();
|
||||
final List<String> classes = new ArrayList<>();
|
||||
final Pattern colClassPattern = Pattern.compile("<col class=\"([^\"]*)\" */?>");
|
||||
final Pattern colTitlePattern = Pattern.compile("<th>([^<]*)</th>");
|
||||
String line;
|
||||
while ((line=br.readLine()) != null && !line.contains("<colgroup"))
|
||||
;
|
||||
while (line != null && !line.contains("</colgroup")) {
|
||||
final Matcher colMatcher = colClassPattern.matcher(line);
|
||||
if (colMatcher.matches()) {
|
||||
classes.add(colMatcher.group(1));
|
||||
}
|
||||
line = br.readLine();
|
||||
}
|
||||
while ((line=br.readLine()) != null && !line.contains("<tr class=\"titlerow\">"))
|
||||
;
|
||||
final Iterator<String> classIter = classes.iterator();
|
||||
while (line != null && !line.contains("</tr")) {
|
||||
final Matcher colTitleMatcher = colTitlePattern.matcher(line);
|
||||
if (colTitleMatcher.matches()) {
|
||||
result.put(colTitleMatcher.group(1), classIter.next());
|
||||
}
|
||||
line = br.readLine();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, String> readMetadataBeforeTable(BufferedReader br) throws IOException {
|
||||
final Pattern h3MetadataElementPattern = Pattern.compile("<h3 class=\"([^\"]*)\"[^>]*>([^<]*)</h3>");
|
||||
final Pattern divMetadataElementPattern = Pattern.compile("<div class=\"([^\"]*)\"[^>]*>([^<]*)</div>");
|
||||
final Map<String, String> result = new HashMap<>();
|
||||
String line;
|
||||
while ((line=br.readLine()) != null && !line.contains("<h3"))
|
||||
;
|
||||
while (line != null && !line.contains("<table")) {
|
||||
final Matcher h3Matcher = h3MetadataElementPattern.matcher(line);
|
||||
if (h3Matcher.matches()) {
|
||||
result.put(h3Matcher.group(1), h3Matcher.group(2));
|
||||
}
|
||||
final Matcher divMatcher = divMetadataElementPattern.matcher(line);
|
||||
if (divMatcher.matches()) {
|
||||
result.put(divMatcher.group(1), divMatcher.group(2));
|
||||
}
|
||||
line = br.readLine();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private CompetitorRow createCompetitorRow(List<String> trContent, LinkedHashMap<String, String> columnNamesAndStyles, Map<String, Integer> classesCounts) throws UnsupportedEncodingException {
|
||||
final Pattern rankPattern = Pattern.compile("([0-9]+)[A-Za-z]*"); // captures the 3 in "3rd"
|
||||
final Pattern nationalityPattern = Pattern.compile("^(<img .*\\btitle=\")?([A-Za-z][A-Za-z][A-Za-z])(\".*>)?$"); // captures the 3 in "3rd"
|
||||
final Iterator<String> columnValueIterator = trContent.iterator();
|
||||
String nationality = null;
|
||||
String sailNumber = null;
|
||||
Integer totalRank = null;
|
||||
List<String> names = null;
|
||||
List<CompetitorEntry> rankAndMaxPointsReasonAndPointsAndDiscarded = new ArrayList<CompetitorEntry>();
|
||||
Double scoreAfterDiscarding = null;
|
||||
Double totalPointsBeforeDiscarding = null;
|
||||
for (final Entry<String, String> columnNameAndStyle : columnNamesAndStyles.entrySet()) {
|
||||
final String columnValue = columnValueIterator.next();
|
||||
switch (columnNameAndStyle.getValue()) {
|
||||
case "rank":
|
||||
final Matcher rankMatcher = rankPattern.matcher(columnValue);
|
||||
if (rankMatcher.matches()) {
|
||||
totalRank = Integer.parseInt(rankMatcher.group(1));
|
||||
}
|
||||
break;
|
||||
case "class":
|
||||
if (classesCounts.containsKey(columnValue)) {
|
||||
classesCounts.put(columnValue, classesCounts.get(columnValue)+1);
|
||||
} else {
|
||||
classesCounts.put(columnValue, 1);
|
||||
}
|
||||
break;
|
||||
case "nat":
|
||||
// example value: <img class="natflag" title="HKG" src="ILCA6_files/HKG.jpg">
|
||||
// but we should also be prepared for just the nationality string, such as "HKG"
|
||||
final Matcher natMatcher = nationalityPattern.matcher(columnValue);
|
||||
if (natMatcher.matches()) {
|
||||
nationality = natMatcher.group(2);
|
||||
} else {
|
||||
nationality = columnValue;
|
||||
}
|
||||
break;
|
||||
case "sailno":
|
||||
sailNumber = columnValue;
|
||||
break;
|
||||
case "helmname":
|
||||
names = getNames(columnValue);
|
||||
break;
|
||||
case "race":
|
||||
CompetitorEntry rankAndMaxPointsReasonAndPointsAndDiscardedForOnceRace = getRankAndMaxPointsReasonAndPointsAndDiscardedForOnceRace(columnValue.trim());
|
||||
rankAndMaxPointsReasonAndPointsAndDiscarded.add(rankAndMaxPointsReasonAndPointsAndDiscardedForOnceRace);
|
||||
break;
|
||||
case "total":
|
||||
totalPointsBeforeDiscarding = Double.parseDouble(columnValue);
|
||||
break;
|
||||
case "nett":
|
||||
scoreAfterDiscarding = Double.parseDouble(columnValue);
|
||||
}
|
||||
}
|
||||
return new CompetitorRowImpl(totalRank, nationality+" "+sailNumber, names, scoreAfterDiscarding, totalPointsBeforeDiscarding,
|
||||
rankAndMaxPointsReasonAndPointsAndDiscarded);
|
||||
}
|
||||
|
||||
private CompetitorEntry getRankAndMaxPointsReasonAndPointsAndDiscardedForOnceRace(String cell) {
|
||||
final Pattern oneRaceScorePattern = Pattern.compile("^\\(?([0-9]+\\.[0-9]+)( ([A-Z][A-Z][A-Z]))?.*$");
|
||||
boolean isDiscarded = cell.trim().startsWith("(") && cell.trim().endsWith(")");
|
||||
final Matcher matcher = oneRaceScorePattern.matcher(cell);
|
||||
final CompetitorEntry result;
|
||||
if (matcher.matches()) {
|
||||
final String maxPointsReason = matcher.group(3);
|
||||
final Double points = Double.parseDouble(matcher.group(1));
|
||||
result = new DefaultCompetitorEntryImpl(/* rank */ null, maxPointsReason, points, isDiscarded);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<String> getNames(String cell) {
|
||||
return Arrays.asList(cell.split(", *"));
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
package com.sap.sailing.sailwave.html.resultimport.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.common.RegattaScoreCorrections;
|
||||
import com.sap.sailing.domain.common.ScoreCorrectionProvider;
|
||||
import com.sap.sailing.domain.resultimport.ResultUrlProvider;
|
||||
import com.sap.sailing.resultimport.AbstractResultUrlProvider;
|
||||
import com.sap.sailing.resultimport.RegattaResults;
|
||||
import com.sap.sailing.resultimport.ResultUrlRegistry;
|
||||
import com.sap.sailing.resultimport.impl.RegattaScoreCorrectionsImpl;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class ScoreCorrectionProviderImpl extends AbstractResultUrlProvider implements ScoreCorrectionProvider, ResultUrlProvider {
|
||||
private static final long serialVersionUID = 5853404150107387702L;
|
||||
public static final String PROVIDER_NAME = "Sailwave HTML Score Importer";
|
||||
|
||||
public ScoreCorrectionProviderImpl(ResultUrlRegistry resultUrlRegistry) {
|
||||
super(resultUrlRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return PROVIDER_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Set<Util.Pair<String, TimePoint>>> getHasResultsForBoatClassFromDateByEventName() {
|
||||
Map<String, Set<Util.Pair<String, TimePoint>>> result = new HashMap<String, Set<Util.Pair<String,TimePoint>>>();
|
||||
SailwaveHtmlParser parser = new SailwaveHtmlParser();
|
||||
for (URL url : getReadableUrls()) {
|
||||
URLConnection conn;
|
||||
try {
|
||||
conn = url.openConnection();
|
||||
TimePoint lastModified = new MillisecondsTimePoint(conn.getLastModified());
|
||||
RegattaResults regattaResult = parser.getRegattaResults((InputStream) conn.getContent());
|
||||
final String boatClassName = getBoatClassName(regattaResult);
|
||||
result.put(boatClassName, Collections.singleton(new Util.Pair<String, TimePoint>(boatClassName, lastModified)));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the first non-empty string of the list of metadata, hoping it's something pointing at the boat class at least...
|
||||
*/
|
||||
private String getBoatClassName(RegattaResults regattaResult) {
|
||||
Map<String, String> metadata = regattaResult.getMetadata();
|
||||
if (metadata.containsKey(SailwaveHtmlParser.CLASS_METADATA)) {
|
||||
return metadata.get(SailwaveHtmlParser.CLASS_METADATA);
|
||||
} else {
|
||||
for (String metadatum : metadata.values()) {
|
||||
if (metadatum != null && metadatum.length() > 0) {
|
||||
return metadatum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL resolveUrl(String url) throws MalformedURLException {
|
||||
return new URL(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegattaScoreCorrections getScoreCorrections(String eventName, String boatClassName,
|
||||
TimePoint timePoint) throws Exception {
|
||||
final SailwaveHtmlParser parser = new SailwaveHtmlParser();
|
||||
for (URL url : getReadableUrls()) {
|
||||
final URLConnection conn = url.openConnection();
|
||||
final RegattaResults regattaResult = parser.getRegattaResults((InputStream) conn.getContent());
|
||||
if ((boatClassName == null && getBoatClassName(regattaResult) == null) ||
|
||||
boatClassName.equals(getBoatClassName(regattaResult))) {
|
||||
return new RegattaScoreCorrectionsImpl(this, regattaResult);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegattaScoreCorrections getScoreCorrections(InputStream inputStream) throws Exception {
|
||||
return new RegattaScoreCorrectionsImpl(this, new SailwaveHtmlParser().getRegattaResults(inputStream));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOptionalSampleURL() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -180,6 +180,11 @@
|
||||
<level>4</level>
|
||||
<autoStart>true</autoStart>
|
||||
</bundle>
|
||||
<bundle>
|
||||
<id>com.sap.sailing.sailwave.html.resultimport</id>
|
||||
<level>4</level>
|
||||
<autoStart>true</autoStart>
|
||||
</bundle>
|
||||
<bundle>
|
||||
<id>com.sap.sailing.manage2sail.resultimport</id>
|
||||
<level>4</level>
|
||||
|
||||
@@ -241,6 +241,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -270,6 +274,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -247,6 +247,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -276,6 +280,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -247,6 +247,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -276,6 +280,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -239,6 +239,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -268,6 +272,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -245,6 +245,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -274,6 +278,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -244,6 +244,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -273,6 +277,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -238,6 +238,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -267,6 +271,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -234,6 +234,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -263,6 +267,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
+5
@@ -240,6 +240,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -269,6 +273,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
+5
@@ -238,6 +238,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -267,6 +271,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
+5
@@ -240,6 +240,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -269,6 +273,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -238,6 +238,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -267,6 +271,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
+5
@@ -238,6 +238,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -267,6 +271,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -234,6 +234,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -263,6 +267,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -271,6 +275,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -240,6 +240,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -269,6 +273,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -240,6 +240,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -269,6 +273,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -245,6 +245,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -274,6 +278,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
+5
@@ -241,6 +241,10 @@
|
||||
<setEntry value="com.diffplug.osgi.extension.sun.misc@default:default"/>
|
||||
<setEntry value="com.google.protobuf@default:default"/>
|
||||
<setEntry value="com.google.protobuf.source@default:default"/>
|
||||
<setEntry value="com.sun.jna@default:default"/>
|
||||
<setEntry value="com.sun.jna.source@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform@default:default"/>
|
||||
<setEntry value="com.sun.jna.platform.source@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
<setEntry value="com.sap.sailing.geocoding@default:default"/>
|
||||
@@ -270,6 +274,7 @@
|
||||
<setEntry value="com.sap.sailing.freg.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.barbados.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailwave.html.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.manage2sail.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.sailti.resultimport@4:true"/>
|
||||
<setEntry value="com.sap.sailing.yachtscoring.resultimport@4:true"/>
|
||||
|
||||
@@ -36,6 +36,10 @@
|
||||
<li>When upgrading an application replica set through the Landscape Management panel,
|
||||
other target groups such as those from an NLB will be considered correctly for adding
|
||||
and removing temporary upgrade replicas and the primary/master node.</li>
|
||||
<li>Added a result importer for the typical Sailwave HTML output, such as
|
||||
<a href="https://www.rhkyc.org.hk/storage/app/media/Sailing/result/HONG-KONG-RACE-WEEK/2025/ILCA4.htm">https://www.rhkyc.org.hk/storage/app/media/Sailing/result/HONG-KONG-RACE-WEEK/2025/ILCA4.htm</a>.
|
||||
You can add these types of URLs now in the <a href="/gwt/AdminConsole.html#ResultImportUrlsPlace:">Result import URLs</a> tab
|
||||
of the Connectors category in the administration console.</li>
|
||||
</ul>
|
||||
<h2 class="articleSubheadline">January 2025</h2>
|
||||
<ul class="bulletList">
|
||||
|
||||
@@ -1101,7 +1101,9 @@ public class Util {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given String is <code>null</code> or empty.
|
||||
* Checks whether a given String is <code>null</code> or empty. Note that the string is not trimmed
|
||||
* before performing the "empty" check, so for example " " (three spaces) <em>will</em> be considered
|
||||
* having a length and <tt>true</tt> would be returned in this case.
|
||||
*
|
||||
* @param str
|
||||
* String to check
|
||||
|
||||
@@ -252,6 +252,8 @@
|
||||
<module>com.sap.sailing.velum.resultimport.test</module>
|
||||
<module>com.sap.sailing.sailwave.resultimport</module>
|
||||
<module>com.sap.sailing.sailwave.resultimport.test</module>
|
||||
<module>com.sap.sailing.sailwave.html.resultimport</module>
|
||||
<module>com.sap.sailing.sailwave.html.resultimport.test</module>
|
||||
<module>com.sap.sailing.manage2sail</module>
|
||||
<module>com.sap.sailing.manage2sail.resultimport</module>
|
||||
<module>com.sap.sailing.manage2sail.resultimport.test</module>
|
||||
|
||||
Reference in New Issue
Block a user