+ * To circumvent the limitations of older JREs that do not support connect timeout a
+ * controller thread is executed. The controller thread attempts to create a new socket
+ * within the given limit of time. If socket constructor does not return until the
+ * timeout expires, the controller terminates and throws an {@link ConnectTimeoutException}
+ *
+ *
+ * @param host the host name/IP
+ * @param port the port on the host
+ * @param params {@link HttpConnectionParams Http connection parameters}
+ *
+ * @return Socket a new socket
+ *
+ * @throws IOException if an I/O error occurs while creating the socket
+ * @throws UnknownHostException if the IP address of the host cannot be
+ * determined
+ */
+ public Socket createSocket(
+ final String host,
+ final int port,
+ final InetAddress localAddress,
+ final int localPort,
+ final HttpConnectionParams params
+ ) throws IOException, UnknownHostException, ConnectTimeoutException {
+ if (params == null) {
+ throw new IllegalArgumentException("Parameters may not be null");
+ }
+ int timeout = params.getConnectionTimeout();
+ SocketFactory socketfactory = getSSLContext().getSocketFactory();
+ if (timeout == 0) {
+ return socketfactory.createSocket(host, port, localAddress, localPort);
+ } else {
+ Socket socket = socketfactory.createSocket();
+ SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
+ SocketAddress remoteaddr = new InetSocketAddress(host, port);
+ socket.bind(localaddr);
+ socket.connect(remoteaddr, timeout);
+ return socket;
+ }
+ }
+
+ /**
+ * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
+ */
+ public Socket createSocket(String host, int port)
+ throws IOException, UnknownHostException {
+ return getSSLContext().getSocketFactory().createSocket(
+ host,
+ port
+ );
+ }
+
+ /**
+ * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
+ */
+ public Socket createSocket(
+ Socket socket,
+ String host,
+ int port,
+ boolean autoClose)
+ throws IOException, UnknownHostException {
+ return getSSLContext().getSocketFactory().createSocket(
+ socket,
+ host,
+ port,
+ autoClose
+ );
+ }
+
+ public boolean equals(Object obj) {
+ return ((obj != null) && obj.getClass().equals(AllowAllSslProtocolSocketFactory.class));
+ }
+
+ public int hashCode() {
+ return AllowAllSslProtocolSocketFactory.class.hashCode();
+ }
+}
diff --git a/src/main/java/eu/odp/harvest/geo/oai/http/AllowAllX509TrustManager.java b/src/main/java/eu/odp/harvest/geo/oai/http/AllowAllX509TrustManager.java
new file mode 100644
index 0000000..8191325
--- /dev/null
+++ b/src/main/java/eu/odp/harvest/geo/oai/http/AllowAllX509TrustManager.java
@@ -0,0 +1,61 @@
+package eu.odp.harvest.geo.oai.http;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+/**
+ * Based on AllowAllX509TrustManager from Apache httpclient-ssl-contrib, but trusts all server certificates, not just
+ * self-signed.
+ * WARNING: Use of this class is insecure, as it basically nullifies the purpose of HTTPS.
+ * Do not use it if you need connections to trusted providers.
+ */
+public class AllowAllX509TrustManager implements X509TrustManager {
+ private X509TrustManager standardTrustManager = null;
+
+ /**
+ * Constructor for AllowAllX509TrustManager.
+ */
+ public AllowAllX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
+ super();
+ TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ factory.init(keystore);
+ TrustManager[] trustmanagers = factory.getTrustManagers();
+ if (trustmanagers.length == 0) {
+ throw new NoSuchAlgorithmException("no trust manager found");
+ }
+ this.standardTrustManager = (X509TrustManager)trustmanagers[0];
+ }
+
+ /**
+ * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
+ */
+ public void checkClientTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
+ standardTrustManager.checkClientTrusted(certificates,authType);
+ }
+
+ /**
+ * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
+ */
+ public void checkServerTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
+/*
+ if ((certificates != null) && (certificates.length == 1)) {
+ certificates[0].checkValidity();
+ } else {
+ standardTrustManager.checkServerTrusted(certificates,authType);
+ }
+*/
+ }
+
+ /**
+ * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
+ */
+ public X509Certificate[] getAcceptedIssuers() {
+ return this.standardTrustManager.getAcceptedIssuers();
+ }
+}
diff --git a/src/main/resources/align_EuroVoc_Inspire.rdf b/src/main/resources/align_EuroVoc_Inspire.rdf
new file mode 100644
index 0000000..779f8bd
--- /dev/null
+++ b/src/main/resources/align_EuroVoc_Inspire.rdf
@@ -0,0 +1,481 @@
+
+
+
+
+
+
Facades for open.nrw: Provide CKAN data to the catalog service of the Geoportal and vice versa.
+
+
+ - Provides an OAI-PMH interface to harvest ISO 19139 metadata from CSW (INSPIRE catalogs) and returns it in DCAT-AP schema
+ - Provides an OAI-PMH interface to harvest DCAT-AP metadata from CKAN and returns it in ISO 19139 schema (STILL WORK IN PROGRESS)
+ - Deployed as a web application in Java servlet container
+ - Implementation is based on Apache Camel
+
+
+
+
+
+ -
+
cd to the root folder of this project (the folder that contains the pom.xml and this readme)
+
+ -
+
from the command line run
+ > mvn clean package
+
+
+
+
+
Use your preferred method to deploy the webapp in Tomcat, e.g.:
+
+ - Copy the war file to the Tomcat webapps folder
+ - Create a context file in the Tomcat host folder
+
+
+
Logging can be configured with the log4j framework (see http://logging.apache.org/log4j/1.2/).
+ By default a logfile is created here: tomcat/logs/open-nrw-ci-fassaden.log.
+
If you build with the env-dev profile, you can set your parameters during build, by including a build.poperties
+ file in the modile base directory. Please check the pom.xml
+ to see how parameters are set. The parameters can be changed after deployment in the file
+ camel-oai-pmh.properties. The available parameters are:
+
+ - oai-pmh.base.url.external: URL that external clients use to access the OAI-PMH interface web application
+ - db.item.csw.TYPE: should be one of inspire, inspireSoap11 or inspireSoap11, depending on the protocol of the Geoportal
+ - db.item.csw.URL: GetRecords URL of the geoportal to be harvested
+ - db.item.ckan.TYPE: currently only ckan is supported
+ - db.item.ckan.URL: CKAN catalog URL to be harvested
+
+
Note on HTTPS: There are a few catalogs that use HTTPS connections. However, some use self-signed certificates, or
+ certificates from a CA that is not trusted by the JVM per default. In order to allow integration of such catalogs,
+ the Facades trusts all server certificates. Of course this is insecure, as it makes the harvester vulnerable
+ to man-in-the-middle attacks. But the same is true for catalogs that are connected via plain HTTP (ca. 90% of
+ catalogs), so this vulnerability is inherent as long as HTTP connections are allowed.
+ If you require trusted connections via HTTPS, just remove the bean
+ eu.odp.harvest.geo.oai.http.AllowAllHttpClientConfig from the Apache Camel Spring configuration
+ (/WEB-INF/classes/camel-oai-pmh.xml).
+
+
+
Each Facades is exposed by a distinct HTTP endpoint. The endpoints are reached with this URL pattern:
+
<tomcat-base-url><webapp-path>/omdf/<harvester>?<verb=operation>&<OPTIONAL argument>
+
+
So for example if tomcat-base-url is "http://localhost:8080", webapp-path is "/" and
+ you have a harvester "gp-csw" for the Geoportal, you can reach it with this URL:
+
http://localhost:8080/omdf/gp-csw
+
+
a harvester "gp-ckan" for the NRW open data portal:
+
http://localhost:8080/omdf/gp-ckan
+
+
You can issue OAI-PMH requests to all of the available endpoints. All endpoints support the same set of operations.
+
Supported operations:
+
+ - ListIdentifiers: This verb is used to retrieve the identifiers of records that can be harvested from a repository. Optional arguments permit selectivity of the identifiers - based on their membership in a specific Set in the repository or based on their modification, creation, or deletion within a specific date range.
+ - ListRecords: This verb is used to harvest records from a repository. Optional arguments permit selective harvesting of records based on set membership and/or datestamp. Depending on the repository's support for deletions, a returned header may have a status attribute of "deleted" if a record matching the arguments specified in the request has been deleted. No metadata will be present for records with deleted status.
+ - GetRecord: This verb is used to retrieve an individual metadata record from a repository. Required arguments specify the identifier of the item from which the record is requested and the format of the metadata that should be included in the record. Depending on the level at which a repository tracks deletions, a header with a "deleted" value for the status attribute may be returned, in case the metadata format specified by the metadataPrefix is no longer available from the repository or from the specified item.
+
+
Operations arguments:
+
+ -
+
ListIdentifiers
+
+ - from an OPTIONAL argument with a date value, which specifies that only the unique identifiers of records with a datestamp that is more recent than or equal to the specified date should be returned.
+ - until an OPTIONAL argument with a date value, which specifies that only the unique identifiers of records with a datestamp older than or equal to the specified date should be returned.
+ - resumptionToken an EXCLUSIVE argument with a value that is the flow control token returned by a previous ListIdentifiers request that issued a partial response.
+
+
+
+
+ -
+
ListRecords
+
+ - from an optional argument with a UTCdatetime value, which specifies a lower bound for datestamp-based selective harvesting.
+ - until an optional argument with a UTCdatetime value, which specifies a upper bound for datestamp-based selective harvesting.
+ - resumptionToken an EXCLUSIVE argument with a value that is the flow control token returned by a previous ListIdentifiers request that issued a partial response.
+
+
+
+
+ -
+
GetRecord
+
+ - identifier a required argument that specifies the unique identifier of the item in the repository from which the record must be disseminated.
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/webapp/multimarkdown_default.css b/src/main/webapp/multimarkdown_default.css
new file mode 100644
index 0000000..039efbc
--- /dev/null
+++ b/src/main/webapp/multimarkdown_default.css
@@ -0,0 +1,221 @@
+/*
+ ~ Copyright (c) 2015-2016 Vladimir Schneider vladimir.schneider@gmail.com
+ ~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+
+*/
+
+/*
+ Default Color Theme for the MultiMarkdown plugin
+*/
+
+
+address {
+ color: #333366;
+}
+
+kbd,
+span.kbd{
+ background-color: #fcfcfc;
+ border: solid 1px #ccc;
+ box-shadow: inset 0 -1px 0 #bbb;
+ color: #555;
+}
+
+body.multimarkdown-preview,
+body.multimarkdown-wiki-preview {
+ color: #222222;
+}
+
+img.local-only {
+ border: 2px solid #b0a803;
+}
+
+img.absent {
+ border: 2px solid #B00020;
+ color: #B00020;
+}
+
+/**********************************
+ * Anchor Related Formatting
+ **********************************/
+
+a {
+ color: #4183C4;
+}
+
+a.mail-link {
+ color: #aa33bb;
+}
+
+a.absent {
+ color: #B00020;
+}
+
+a.local-only {
+ color: #be8000;
+}
+
+/**********************************
+ * Header Related Formatting
+ **********************************/
+div.page-header {
+ background-color: #E0E0E0;
+}
+
+div.page-header a {
+ color: #000;
+}
+
+h2,
+h2 a {
+ color: #222222;
+}
+
+h1,
+h3,
+h4,
+h5,
+h1 a,
+h3 a,
+h4 a,
+h5 a {
+ color: #222222;
+}
+
+h6,
+h6 a {
+ color: #777777;
+}
+
+h1 {
+ border-bottom: 1px solid #bbbbbb;
+}
+
+h2 {
+ border-bottom: 1px solid #bbbbbb;
+}
+
+/**********************************
+ * Block Quote Related Formatting
+ **********************************/
+
+blockquote {
+ border-left: 4px solid #cccccc;
+ color: #666666;
+}
+
+blockquote h1,
+blockquote h2,
+blockquote h3,
+blockquote h4,
+blockquote h5,
+blockquote h6,
+blockquote h1 a,
+blockquote h2 a,
+blockquote h3 a,
+blockquote h4 a,
+blockquote h5 a,
+blockquote h6 a {
+ color: #666666;
+}
+
+/**********************************
+* Code Block Related Formatting
+ **********************************/
+
+tt,
+span.tt {
+ border: 1px solid #eaeaea;
+ background-color: #f8f8f8;
+}
+
+pre code,
+pre span.code {
+ color: #222222;
+}
+
+pre {
+ background-color: #f8f8f8;
+ border: 1px solid #cccccc;
+}
+
+code,
+span.code {
+ color: #B00020;
+ background-color: #f8f8f8;
+}
+
+/**********************************
+ * Table Related formatting
+ **********************************/
+
+table tr th {
+ border: solid 1px #d4d4d4;
+}
+
+table tr.thead-first-child,
+table tr.thead-odd-child {
+ background-color: #e8e8e8;
+}
+
+table tr.thead-even-child {
+ background-color: #dcdcdc;
+}
+
+table tr td {
+ border: solid 1px #dddddd;
+}
+
+table tr.tbody-first-child,
+table tr.tbody-odd-child {
+ background-color: #ffffff;
+}
+
+table tr.tbody-even-child {
+ background-color: #f4f4f4;
+}
+
+body table {
+ border: solid 1px #dddddd;
+ background-color: #ffffff;
+}
+
+/************************************
+ * Horizontal Rule Related Formatting
+ ************************************/
+
+hr {
+}
+
+div.hr {
+ border-top: 1px solid #bbbbbb;
+}
+
+.search-highlight {
+ color: #000;
+ padding:1px 0 1px 0;
+ background-color: #ffff00;
+}
+
+.selection-highlight {
+ color: #FFFFFF;
+ padding:1px 0 1px 0;
+ background-color: #5974AB;
+}
+
diff --git a/src/main/webapp/multimarkdown_layout.css b/src/main/webapp/multimarkdown_layout.css
new file mode 100644
index 0000000..04b7c3e
--- /dev/null
+++ b/src/main/webapp/multimarkdown_layout.css
@@ -0,0 +1,518 @@
+/*
+ ~ Copyright (c) 2015-2016 Vladimir Schneider vladimir.schneider@gmail.com
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* Swing Layout Stylesheet */
+
+strike {
+ text-decoration: line-through;
+}
+
+/* del is simulated via span.del */
+del,
+span.del {
+ text-decoration: line-through;
+}
+
+s {
+ text-decoration: line-through;
+}
+
+cite {
+ font-style: italic;
+}
+
+sub {
+ font-size: 0.9em;
+}
+
+sup {
+ font-size: 0.9em;
+}
+
+em {
+ font-style: italic;
+}
+
+strong {
+ font-weight: bold;
+}
+
+b {
+ font-weight: bold;
+}
+
+u {
+ text-decoration: underline;
+}
+
+address {
+ font-style: italic;
+}
+
+i {
+ font-style: italic;
+}
+
+var,
+span.var {
+ font-weight: bold;
+ font-style: italic;
+}
+
+kbd,
+span.kbd{
+ display: inline-block;
+ padding: 3px 5px;
+ vertical-align: middle;
+}
+
+/* NOTE: all other font sizes are set relative to font size given here and this is overridden in the CssProvider */
+body.multimarkdown-preview,
+body.multimarkdown-wiki-preview {
+ background-color: white;
+ font-family: "Helvetica Neue", Helvetica, Arial, freesans, sans-serif;
+ font-size: 11px;
+ padding: 20px;
+}
+
+img.local-only {
+}
+
+img.absent {
+ font-weight: bold;
+}
+
+/**********************************
+ * Anchor Related Formatting
+ **********************************/
+
+a {
+ text-decoration: underline;
+}
+
+a.mail-link {
+}
+
+a.absent {
+}
+
+a.local-only {
+}
+
+a.anchor {
+ display: block;
+ padding-left: 30px;
+ margin-left: -30px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+}
+
+/**********************************
+ * Header Related Formatting
+ **********************************/
+div.page-header {
+ padding: 2px 0 4px 15px;
+}
+
+div.page-header a {
+ text-decoration: none;
+ font-weight: bold;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ padding: 0;
+ cursor: text;
+ position: relative;
+}
+
+h2,
+h2 a {
+ text-decoration: none;
+}
+
+h1,
+h3,
+h4,
+h5,
+h1 a,
+h3 a,
+h4 a,
+h5 a {
+ text-decoration: none;
+}
+
+h1 p,
+h2 p,
+h3 p,
+h4 p,
+h5 p,
+h6 p {
+ margin-top: 0;
+}
+
+h6,
+h6 a {
+ text-decoration: none;
+}
+
+h1 tt,
+h2 tt,
+h3 tt,
+h4 tt,
+h5 tt,
+h6 tt,
+h1 code,
+h2 code,
+h3 code,
+h4 code,
+h5 code,
+h6 code,
+h1 span.code,
+h2 span.code,
+h3 span.code,
+h4 span.code,
+h5 span.code,
+h6 span.code {
+ font-size: inherit;
+}
+
+h1 {
+ font-weight: bold;
+ font-size: 1.5em;
+ margin: 20px 0 10px 0;
+}
+
+h1.first-child,
+h2.first-child,
+h3.first-child,
+h4.first-child,
+h5.first-child,
+h6.first-child {
+ margin-top: 0;
+}
+
+.multimarkdown-wiki-preview h1 {
+ font-weight: normal;
+}
+
+h2 {
+ font-weight: bold;
+ font-size: 1.35em;
+ margin: 20px 0 10px 0;
+}
+
+h3 {
+ font-weight: bold;
+ font-size: 1.25em;
+ margin: 20px 0 10px 0;
+}
+
+h4 {
+ font-weight: bold;
+ font-size: 1.15em;
+ margin: 10px 0 7px;
+}
+
+h5 {
+ font-weight: bold;
+ font-size: 1.1em;
+ margin: 7px 0 7px;
+}
+
+h6 {
+ font-weight: bold;
+ font-size: 1.1em;
+ margin: 7px 0 7px;
+}
+
+/**********************************
+ * Block Quote Related Formatting
+ **********************************/
+
+blockquote {
+ margin: 5px 0;
+ padding: 0 15px;
+ font-size: 1em;
+}
+
+blockquote h1,
+blockquote h2,
+blockquote h3,
+blockquote h4,
+blockquote h5,
+blockquote h6,
+blockquote h1 a,
+blockquote h2 a,
+blockquote h3 a,
+blockquote h4 a,
+blockquote h5 a,
+blockquote h6 a {
+}
+
+/**********************************
+* Code Block Related Formatting
+ **********************************/
+
+code,
+span.code,
+samp,
+var,
+span.var,
+kbd,
+span.kbd,
+span.tt {
+ font-family: Consolas, Inconsolata, "Liberation Mono", Menlo, Courier, Monospaced, monospace;
+ font-size: 1em;
+}
+
+pre {
+ margin: 5px 0;
+}
+
+tt,
+span.tt {
+ margin: 0 2px;
+ padding: 0 5px;
+ white-space: nowrap;
+}
+
+pre code,
+pre span.code {
+ margin: 0;
+ padding: 0;
+ white-space: pre;
+ border: none;
+ background: transparent;
+}
+
+pre {
+ overflow: auto;
+ padding: 6px 0 6px 10px;
+ white-space: pre;
+}
+
+code,
+span.code {
+ padding: 3px;
+ white-space: normal;
+}
+
+/**********************************
+ * Table Related formatting
+ **********************************/
+
+body table {
+ background-color: transparent;
+ margin-bottom: 20px;
+ border-spacing: 0;
+ border-collapse: collapse;
+ font-size: inherit;
+}
+
+table tr th {
+ font-weight: bold;
+ margin: 0;
+ padding: 6px 13px;
+}
+
+table tr td {
+ margin: 0;
+ padding: 6px 13px;
+}
+
+th {
+ text-align: center;
+}
+
+table caption {
+ font-weight: bold;
+ padding: 5px 0 5px 10px;
+ text-align: left;
+}
+
+table thead tr th {
+ vertical-align: bottom;
+}
+
+/************************************
+ * Horizontal Rule Related Formatting
+ ************************************/
+
+hr {
+ /*
+ nothing is used in the CSS by the HTMLEditorKit hr element except alignment, margin, width.
+ size and noshade attributes are only setable in the element and size is 2px minimum, of any
+ color you want just as long as its black, hardcoded in the library.
+
+ ie. nothing useful that we can use to change the look so hr is simulated with a div and nbsp
+ */
+}
+
+div.hr {
+ height: 1px;
+ margin: 10px 0 5px 0;
+}
+
+/**********************************
+ * List Item Related Formatting
+ **********************************/
+
+ul,
+ol {
+ margin: 10px 0 10px 0;
+}
+
+ul {
+ list-style-type: disc;
+}
+
+li {
+ margin: 2px 0 3px 0;
+}
+
+li.dtask,
+li.bulleti,
+li.taski {
+ margin: 1px 0 1px 0;
+}
+
+/* loosely spaced list items that reflect the markdown source */
+li.bulletp,
+li.dtaskp,
+li.taskp,
+li.p {
+ margin: 0 0 10px 0;
+}
+
+/* loosely spaced list items that duplicate quirky GFM implementation */
+li.bulletp,
+li.dtaskp,
+li.taskp,
+li.p {
+ margin: 10px 0 10px 0;
+}
+
+p {
+ margin: 5px 0 5px 0;
+}
+
+li p {
+ margin: 10px 0 10px 0;
+}
+
+/* loose list item first paragraph, loose task item first paragraph */
+li.bulletp p.p,
+li.taskp p.p,
+li.dtaskp p.p,
+li.p p.p {
+ margin: 0;
+}
+
+ul ul,
+ol ul {
+ list-style-type: circle;
+}
+
+ul li.bulleti,
+ul li.bulletp,
+ul li.task-chk,
+ul li.taskp-chk {
+ list-style-type: none;
+ padding-left: 0;
+ text-indent: -17px;
+}
+
+ul li.task-list-item {
+ list-style-type: none;
+}
+
+ul li.taski,
+ul li.taskp,
+ul li.dtask,
+ul li.dtaskp {
+ list-style-type: square;
+}
+
+ul,
+ol {
+ padding-left: 30px;
+}
+
+ol {
+ list-style-type: decimal;
+}
+
+ul ol,
+ol ol {
+ list-style-type: lower-roman;
+}
+
+ul ul ol,
+ul ol ol,
+ol ul ol,
+ol ol ol {
+ list-style-type: lower-alpha;
+}
+
+dfn {
+ font-style: italic;
+}
+
+dt {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+dl {
+ margin: 5px 0 5px 0;
+ padding: 0;
+}
+
+dl dt {
+ font-size: 1.05em;
+ font-weight: bold;
+ font-style: italic;
+ padding: 0;
+ margin: 5px 0 5px;
+}
+
+dl dd {
+ margin: 0 0 5px;
+ padding: 0 20px;
+}
+
+
+caption {
+ text-align: center;
+}
+
+img.emoji {
+ width: 20px;
+ height: 20px;
+ vertical-alignment: text-bottom;
+}