changeset 1879:9a2fbeaabd52 dev-pdf-generation

merging in from branch default
author Bernhard Reiter <bernhard@intevation.de>
date Tue, 15 Jan 2019 10:07:10 +0100
parents f030182f82f1 (current diff) 70573eea890e (diff)
children 2b4de58a9031
files client/package.json client/src/components/Pdftool.vue client/src/locale/bg_BG/LC_MESSAGES/app.po client/src/locale/de_AT/LC_MESSAGES/app.po client/src/locale/en_GB/LC_MESSAGES/app.po client/src/locale/hr_HR/LC_MESSAGES/app.po client/src/locale/hu_HU/LC_MESSAGES/app.po client/src/locale/ro_RO/LC_MESSAGES/app.po client/src/locale/sk_SK/LC_MESSAGES/app.po client/src/locale/translations.json client/src/store/map.js pkg/controllers/bnimports.go pkg/controllers/gmimports.go pkg/imports/fwsched.go pkg/imports/polygon.go
diffstat 95 files changed, 11062 insertions(+), 2025 deletions(-) [+]
line wrap: on
line diff
--- a/.hgchurn	Tue Jan 15 09:54:46 2019 +0100
+++ b/.hgchurn	Tue Jan 15 10:07:10 2019 +0100
@@ -1,1 +1,2 @@
 teichmann@intevation.de = sascha.teichmann@intevation.de
+bernhard.reiter@intevation.de = bernhard@intevation.de
--- a/client/Makefile	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/Makefile	Tue Jan 15 10:07:10 2019 +0100
@@ -1,20 +1,20 @@
-# This is Free Software under GNU Affero General Public License v >= 3.0
-# without warranty, see README.md and license for details.
-#
-# SPDX-License-Identifier: AGPL-3.0-or-later
-# License-Filename: LICENSES/AGPL-3.0.txt
+# This is free software under MIT license taken from:
+# https://github.com/Polyconseil/vue-gettext/blob/master/Makefile
 #
-# Copyright (C) 2018 by via donau
-#  – Österreichische Wasserstraßen-Gesellschaft mbH
-# Software engineering by Intevation GmbH
-#
-# Author(s):
-# * Thomas Junk <thomas.junk@intevation.de>
+# following changes were made due to requirments:
+#   * Add additional locales for the app
+#   * Add ability to run the translations Makefile with several users on a multi-user system
+#   * prevent clean from being called accidently if ´make´ is executed without parameters
 
 # On OSX the PATH variable isn't exported unless "SHELL" is also set, see: http://stackoverflow.com/a/25506676
 SHELL = /bin/bash
 NODE_BINDIR = ./node_modules/.bin
 export PATH := $(NODE_BINDIR):$(PATH)
+LOGNAME := $(shell logname)
+
+# adding the name of the user's login name to the template file, so that
+# on a multi-user system several users can run this without interference
+TEMPLATE_POT := /tmp/template-$(LOGNAME).pot
 
 # Where to write the files generated by this makefile.
 OUTPUT_DIR = src
@@ -35,15 +35,15 @@
 	@echo choose a target from: clean makemessages translations
 
 clean:
-	rm -f /tmp/template.pot $(OUTPUT_DIR)/locale/translations.json
+	rm -f $(TEMPLATE_POT) $(OUTPUT_DIR)/locale/translations.json
 
-makemessages: /tmp/template.pot
+makemessages: $(TEMPLATE_POT)
 
 translations: ./$(OUTPUT_DIR)/locale/translations.json
 
 # Create a main .pot template, then generate .po files for each available language.
 # Thanx to Systematic: https://github.com/Polyconseil/systematic/blob/866d5a/mk/main.mk#L167-L183
-/tmp/template.pot: $(GETTEXT_HTML_SOURCES)
+$(TEMPLATE_POT): $(GETTEXT_HTML_SOURCES)
 # `dir` is a Makefile built-in expansion function which extracts the directory-part of `$@`.
 # `$@` is a Makefile automatic variable: the file name of the target of the rule.
 # => `mkdir -p /tmp/`
@@ -66,6 +66,6 @@
 		msgattrib --no-wrap --no-obsolete -o $$PO_FILE $$PO_FILE; \
 	done;
 
-$(OUTPUT_DIR)/locale/translations.json: clean /tmp/template.pot
+$(OUTPUT_DIR)/locale/translations.json: clean $(TEMPLATE_POT)
 	mkdir -p $(OUTPUT_DIR)
 	gettext-compile --output $@ $(LOCALE_FILES)
--- a/client/README.md	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/README.md	Tue Jan 15 10:07:10 2019 +0100
@@ -3,6 +3,8 @@
 
 * Install dependencies
 
+  * Install (`xgettext`) tool (e.g. for Debian xgettext (GNU gettext-tools) 0.19.8.1)
+
   * Javascript
 
     `yarn install`
@@ -21,10 +23,6 @@
 
     Run webpack-dev-server with `yarn serve`
 
-  * If you also want to start the backend, try
-
-    `yarn run:both`
-
 * Build `yarn build`
 
   builds the production ready assets to `web` folder.
@@ -34,7 +32,7 @@
 
 * Translation
   * Extract Messages via `make makemessages`
-  * Translations are converted via `make translations`
+  * Translations are converted via `make translations` which is executed automatically with yarn serve/build
 
   For more information see [developer documentation](./docs/developer.md)
 
--- a/client/docs/developer.md	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/docs/developer.md	Tue Jan 15 10:07:10 2019 +0100
@@ -75,11 +75,8 @@
 - SK
 - HU
 - HR
-- RS
-- BiH
 - BG
 - RO
-- UA
 
 ## Our preferred translation cycle is as follows:
 
@@ -113,7 +110,8 @@
 
 In order to extract the messages from the templates call `make makemessages`.
 After that you have the `.po`-file which could be translated.
-After translation, you have to call `make translations` to generate the `translations.json`
+
+After translation, `make translations` has to be called to generate the `translations.json`, that is being done automatically via yarn serve/build.
 which is consumed by `vue-gettext`.
 
 The workflow is as follows:
--- a/client/package.json	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/package.json	Tue Jan 15 10:07:10 2019 +0100
@@ -8,9 +8,9 @@
   },
   "private": true,
   "scripts": {
-    "run:both": "concurrently \"../cmd/gemma/gemma\" \"vue-cli-service serve\"",
-    "serve": "VUE_APP_HGREV=$(hg log -r . --template \"{data|shortdate}-{node|short}\") vue-cli-service serve",
-    "build": "VUE_APP_HGREV=$(hg log -r . --template \"{data|shortdate}-{node|short}\") vue-cli-service build",
+    "serve": "make translations && VUE_APP_HGREV=$(hg log -r . --template \"{data|shortdate}-{node|short}\") vue-cli-service serve",
+    "build": "make translations && VUE_APP_HGREV=$(hg log -r . --template \"{data|shortdate}-{node|short}\") vue-cli-service build",
+    "analyze": "ANALYZE=true vue-cli-service serve",
     "lint": "vue-cli-service lint",
     "test:unit": "vue-cli-service test:unit",
     "test:e2e": "vue-cli-service test:e2e"
@@ -65,7 +65,7 @@
     "node-sass": "^4.10.0",
     "pretty-quick": "^1.8.0",
     "sass-loader": "^7.0.1",
-    "vue-gettext": "^2.1.1",
+    "vue-gettext": "^2.1.2",
     "vue-template-compiler": "^2.5.17",
     "webpack-bundle-analyzer": "^3.0.3"
   },
--- a/client/src/assets/application.scss	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/assets/application.scss	Tue Jan 15 10:07:10 2019 +0100
@@ -19,7 +19,7 @@
 $icon-width: 2rem;
 $large-offset: 2rem;
 $offset: 1rem;
-$sidebar-width: 20rem;
+$sidebar-width: 21rem;
 $slight-transparent: 0.96;
 $small-offset: 0.5rem;
 $smaller: 0.9rem;
--- a/client/src/components/Contextbox.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/Contextbox.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -5,6 +5,7 @@
     </div>
     <Bottlenecks v-if="contextBoxContent === 'bottlenecks'"></Bottlenecks>
     <Staging v-if="contextBoxContent === 'staging'"></Staging>
+    <Stretches v-if="contextBoxContent === 'stretches'"></Stretches>
   </div>
 </template>
 
@@ -28,7 +29,8 @@
   name: "contextbox",
   components: {
     Bottlenecks: () => import("./Bottlenecks"),
-    Staging: () => import("./staging/Staging.vue")
+    Staging: () => import("./staging/Staging.vue"),
+    Stretches: () => import("./ImportStretches.vue")
   },
   computed: {
     ...mapState("application", [
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/ImportApprovedGaugeMeasurement.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,119 @@
+<template>
+  <div class="d-flex flex-row">
+    <Spacer></Spacer>
+    <div class="card sysconfig mt-3 shadow-xs w-100 h-100 mr-3">
+      <h6
+        class="mb-0 py-2 px-3 border-bottom d-flex text-info align-items-center"
+      >
+        <font-awesome-icon
+          icon="cloud-upload-alt"
+          class="mr-2"
+        ></font-awesome-icon>
+        <translate class="headline">Import approved gaugemeasurements</translate>
+      </h6>
+      <div class="card-body stretches-card">
+        <div class="w-95 ml-auto mr-auto mt-4 mb-4">
+          <div class="d-flex flex-row input-group mb-4">
+            <div class="flex-column w-100">
+              <div class="custom-file">
+              <input
+                accept=".csv"
+                type="file"
+                @change="fileSelected"
+                class="custom-file-input"
+                id="uploadFile"
+              />
+              <label class="custom-file-label" for="uploadFile">
+                {{ uploadLabel }}
+              </label>
+            </div>
+            </div>
+          </div>
+          <div class="buttons text-right">
+            <button
+              :disabled="disableUploadButton"
+              @click="submit"
+              class="btn btn-info mt-4"
+              type="button"
+            >
+              <font-awesome-icon
+                class="fa-fw mr-2"
+                fixed-width
+                icon="play"
+              ></font-awesome-icon>
+              <translate>Trigger import</translate>
+            </button>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+/* This is Free Software under GNU Affero General Public License v >= 3.0
+ * without warranty, see README.md and license for details.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ * License-Filename: LICENSES/AGPL-3.0.txt
+ *
+ * Copyright (C) 2018 by via donau
+ *   – Österreichische Wasserstraßen-Gesellschaft mbH
+ * Software engineering by Intevation GmbH
+ *
+ * Author(s):
+ * Thomas Junk <thomas.junk@intevation.de>
+ */
+
+import { HTTP } from "@/lib/http";
+import { displayError, displayInfo } from "@/lib/errors.js";
+
+export default {
+  name: "importapprovedgaugemeasurements",
+  data() {
+    return {
+      disableUploadButton: false,
+      uploadLabel: this.$gettext("choose file to upload"),
+      uploadFile: null
+    };
+  },
+  methods: {
+    fileSelected(e) {
+      const files = e.target.files || e.dataTransfer.files;
+      if (!files) return;
+      this.uploadLabel = files[0].name;
+      this.uploadFile = files[0];
+    },
+    submit() {
+      if (!this.uploadFile) return;
+      let formData = new FormData();
+      formData.append("approvedgm", this.uploadFile);
+      HTTP.post("/imports/approvedgm", formData, {
+        headers: {
+          "X-Gemma-Auth": localStorage.getItem("token"),
+          "Content-Type": "multipart/form-data"
+        }
+      })
+        .then(() => {
+          displayInfo({
+            title: this.$gettext("Import"),
+            message: this.$gettext("Starting import of Approved Gauge Measurements")
+          });
+          this.initialState();
+        })
+        .catch(error => {
+          const { status, data } = error.response;
+          displayError({
+            title: this.$gettext("Backend Error"),
+            message: `${status}: ${data.message || data}`
+          });
+        });
+    }
+  },
+  components: {
+    Spacer: () => import("./Spacer")
+  }
+};
+</script>
+
+<style lang="scss" scoped></style>
--- a/client/src/components/ImportStretches.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/ImportStretches.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -1,44 +1,9 @@
 <template>
-  <div class="d-flex flex-row">
-    <Spacer></Spacer>
-    <div class="card sysconfig mt-3 shadow-xs w-100 h-100 mr-3">
-      <h6
-        class="mb-0 py-2 px-3 border-bottom d-flex text-info align-items-center"
-      >
-        <font-awesome-icon
-          icon="cloud-upload-alt"
-          class="mr-2"
-        ></font-awesome-icon>
-        <translate class="headline">Import streches</translate>
-      </h6>
-      <div class="card-body stretches-card">
-        <div class="w-95 ml-auto mr-auto mt-4 mb-4">
-          <div class="d-flex flex-row input-group mb-4">
-            <div class="flex-column w-100">
-              <div class="flex-row text-left">
-                <small class="text-muted"> <translate>URL</translate> </small>
-              </div>
-              <div><input class="form-control" type="url" /></div>
-            </div>
-          </div>
-          <div class="buttons text-right">
-            <button
-              :disabled="disableUploadButton"
-              @click="submit"
-              class="btn btn-info mt-4"
-              type="button"
-            >
-              <font-awesome-icon
-                class="fa-fw mr-2"
-                fixed-width
-                icon="play"
-              ></font-awesome-icon>
-              <translate>Trigger import</translate>
-            </button>
-          </div>
-        </div>
-      </div>
-    </div>
+  <div>
+    <h6 class="mb-0 py-2 px-3 border-bottom d-flex align-items-center">
+      <font-awesome-icon icon="road" class="mr-2"></font-awesome-icon>
+      <translate>Define section and stretches</translate>
+    </h6>
   </div>
 </template>
 
@@ -57,29 +22,12 @@
  * Thomas Junk <thomas.junk@intevation.de>
  */
 
-import Spacer from "./Spacer";
-import { displayInfo } from "@/lib/errors.js";
-
 export default {
   name: "importstretches",
   data() {
-    return {
-      disableUploadButton: false,
-      uploadLabel: "",
-      uploadFile: null
-    };
+    return {};
   },
-  methods: {
-    submit() {
-      displayInfo({
-        title: this.$gettext("Import stretches"),
-        message: this.$gettext("under construction")
-      });
-    }
-  },
-  components: {
-    Spacer
-  }
+  methods: {}
 };
 </script>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/ImportWaterwayProfiles.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,99 @@
+<template>
+  <div class="d-flex flex-row">
+    <Spacer></Spacer>
+    <div class="card sysconfig mt-3 shadow-xs w-100 h-100 mr-3">
+      <h6
+        class="mb-0 py-2 px-3 border-bottom d-flex text-info align-items-center"
+      >
+        <font-awesome-icon
+          icon="cloud-upload-alt"
+          class="mr-2"
+        ></font-awesome-icon>
+        <translate class="headline">Import Waterwayprofiles</translate>
+      </h6>
+      <div class="card-body stretches-card">
+        <div class="w-95 ml-auto mr-auto mt-4 mb-4">
+          <div class="d-flex flex-row input-group mb-4">
+            <div class="flex-column w-100">
+              <div class="custom-file">
+              <input
+                accept=".zip"
+                type="file"
+                @change="fileSelected"
+                class="custom-file-input"
+                id="uploadFile"
+              />
+              <label class="custom-file-label" for="uploadFile">
+                {{ uploadLabel }}
+              </label>
+            </div>
+            </div>
+          </div>
+          <div class="buttons text-right">
+            <button
+              :disabled="disableUploadButton"
+              @click="submit"
+              class="btn btn-info mt-4"
+              type="button"
+            >
+              <font-awesome-icon
+                class="fa-fw mr-2"
+                fixed-width
+                icon="play"
+              ></font-awesome-icon>
+              <translate>Trigger import</translate>
+            </button>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+/* This is Free Software under GNU Affero General Public License v >= 3.0
+ * without warranty, see README.md and license for details.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ * License-Filename: LICENSES/AGPL-3.0.txt
+ *
+ * Copyright (C) 2018 by via donau
+ *   – Österreichische Wasserstraßen-Gesellschaft mbH
+ * Software engineering by Intevation GmbH
+ *
+ * Author(s):
+ * Thomas Junk <thomas.junk@intevation.de>
+ */
+
+import { displayInfo } from "@/lib/errors.js";
+
+export default {
+  name: "importwaterwayprofiles",
+  data() {
+    return {
+      disableUploadButton: false,
+      uploadLabel: this.$gettext("choose file to upload"),
+      uploadFile: null
+    };
+  },
+  methods: {
+    fileSelected(e) {
+      const files = e.target.files || e.dataTransfer.files;
+      if (!files) return;
+      this.uploadLabel = files[0].name;
+      this.uploadFile = files[0];
+    },
+    submit() {
+      displayInfo({
+        title: this.$gettext("Import"),
+        message: this.$gettext("under construction")
+      });
+    }
+  },
+  components: {
+    Spacer: () => import("./Spacer")
+  }
+};
+</script>
+
+<style lang="scss" scoped></style>
--- a/client/src/components/Logs.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/Logs.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -120,7 +120,6 @@
 import { mapState } from "vuex";
 import { HTTP } from "@/lib/http.js";
 import "../../node_modules/highlight.js/styles/paraiso-dark.css";
-import Spacer from "./Spacer";
 import Vue from "vue";
 import VueHighlightJS from "vue-highlightjs";
 Vue.use(VueHighlightJS);
@@ -131,7 +130,7 @@
 export default {
   name: "logs",
   components: {
-    Spacer
+    Spacer: () => import("./Spacer")
   },
   mounted() {
     this.fetch("system/log/apache2/access.log", ACCESSLOG);
--- a/client/src/components/Main.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/Main.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -20,14 +20,11 @@
  * Thomas Junk <thomas.junk@intevation.de>
  */
 
-import Maplayer from "./Maplayer";
-import FairwayProfile from "./fairway/Fairwayprofile";
-
 export default {
   name: "mainview",
   components: {
-    Maplayer,
-    FairwayProfile
+    Maplayer: () => import("./Maplayer"),
+    FairwayProfile: () => import("./fairway/Fairwayprofile")
   }
 };
 </script>
--- a/client/src/components/Maplayer.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/Maplayer.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -262,11 +262,12 @@
     layer.data.getSource().setLoader(
       this.buildVectorLoader(
         {
-          featurePrefix: "ws-wamos",
-          featureTypes: ["ienc_wtware"],
-          geometryName: "geom"
+          featureNS: "gemma",
+          featurePrefix: "gemma",
+          featureTypes: ["waterway_area"],
+          geometryName: "area"
         },
-        "/external/d4d",
+        "/internal/wfs",
         layer.data.getSource()
       )
     );
@@ -275,11 +276,12 @@
     layer.data.getSource().setLoader(
       this.buildVectorLoader(
         {
-          featurePrefix: "ws-wamos",
-          featureTypes: ["ienc_wtwaxs"],
-          geometryName: "geom"
+          featureNS: "gemma",
+          featurePrefix: "gemma",
+          featureTypes: ["waterway_axis"],
+          geometryName: "wtwaxs"
         },
-        "/external/d4d",
+        "/internal/wfs",
         layer.data.getSource()
       )
     );
--- a/client/src/components/Search.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/Search.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -12,7 +12,9 @@
           'searchgroup-collapsed': !showSearchbar,
           big:
             showContextBox &&
-            ['bottlenecks', 'staging'].indexOf(contextBoxContent) !== -1
+            ['bottlenecks', 'staging', 'stretches'].indexOf(
+              contextBoxContent
+            ) !== -1
         }
       ]"
     >
@@ -248,7 +250,6 @@
         }
       )
         .then(response => {
-          // console.log("got:", response.data);
           this.searchResults = response.data;
         })
         .catch(error => {
@@ -263,7 +264,6 @@
       this.searchQueryIsDirty = false;
     },
     moveToSearchResult(resultEntry) {
-      // DEBUG console.log("Moving to", resultEntry);
       if (resultEntry.geom.type == "Point") {
         let zoom = 11;
         if (resultEntry.type === "bottleneck") zoom = 17;
--- a/client/src/components/Sidebar.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/Sidebar.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -40,6 +40,20 @@
           ></font-awesome-icon>
           <span class="fix-trans-space" v-translate>Staging area</span>
         </a>
+        <a
+          :class="['secondary', { active: isActive('stretches') }]"
+          @click="toggleContextBox('stretches')"
+          href="#"
+        >
+          <font-awesome-icon
+            class="fa-fw mr-2"
+            fixed-width
+            icon="road"
+          ></font-awesome-icon>
+          <span class="fix-trans-space" v-translate
+            >Define sections and stretches</span
+          >
+        </a>
         <small class="text-muted pl-3"> <translate>Import</translate> </small>
         <hr class="m-0" />
         <router-link to="/importsoundingresults">
@@ -52,15 +66,27 @@
             >Import soundingresults</span
           >
         </router-link>
-        <router-link to="/importstretches" v-if="this.$options.IMPORTSTRETCHES">
+        <router-link to="/importapprovedgaugemeasurement">
           <font-awesome-icon
             class="fa-fw mr-2"
             fixed-width
-            icon="cloud-upload-alt"
+            icon="upload"
           ></font-awesome-icon>
-          <span class="fix-trans-space" v-translate>Import stretches</span>
+          <span class="fix-trans-space" v-translate
+            >Import approved gaugemeasurements</span
+          >
         </router-link>
-        <router-link to="importschedule" v-if="this.$options.IMPORTSCHEDULE">
+        <router-link to="/importwaterwayprofiles">
+          <font-awesome-icon
+            class="fa-fw mr-2"
+            fixed-width
+            icon="upload"
+          ></font-awesome-icon>
+          <span class="fix-trans-space" v-translate
+            >Import waterway profiles</span
+          >
+        </router-link>
+        <router-link to="importschedule">
           <font-awesome-icon
             class="fa-fw mr-2"
             fixed-width
@@ -72,6 +98,8 @@
           <translate>Systemadministration</translate>
         </small>
         <hr class="m-0" />
+      </div>
+      <div v-if="isSysAdmin">
         <router-link to="usermanagement">
           <font-awesome-icon
             class="fa-fw mr-2"
@@ -80,8 +108,6 @@
           ></font-awesome-icon>
           <span class="fix-trans-space" v-translate>Users</span>
         </router-link>
-      </div>
-      <div v-if="isSysAdmin">
         <router-link to="systemconfiguration">
           <font-awesome-icon
             class="fa-fw mr-2"
@@ -98,6 +124,8 @@
           ></font-awesome-icon>
           <span class="fix-trans-space" v-translate>Logs</span>
         </router-link>
+      </div>
+      <div v-if="isWaterwayAdmin">
         <router-link to="importqueue">
           <font-awesome-icon
             class="fa-fw mr-2"
@@ -136,11 +164,25 @@
  * Markus Kottländer <markus.kottlaender@intevation.de>
  */
 import { mapGetters, mapState } from "vuex";
-import app from "@/main";
+import { logOff } from "@/lib/session.js";
 
 export default {
   name: "sidebar",
   props: ["routeName"],
+  watch: {
+    $route() {
+      const { review, importlog } = this.$route.query;
+      if (review) {
+        this.toggleContextBox("staging");
+        this.$store.commit("imports/setImportToReview", review);
+      } else {
+        this.$store.commit("imports/setImportToReview", -99);
+      }
+      if (importlog) {
+        this.$router.push("/importqueue/" + importlog);
+      }
+    }
+  },
   computed: {
     ...mapGetters("user", ["isSysAdmin", "isWaterwayAdmin"]),
     ...mapState("user", ["user"]),
@@ -160,17 +202,12 @@
       ];
     }
   },
-  IMPORTSCHEDULE: process.env.VUE_APP_FEATURE_IMPORTSCHEDULE,
-  IMPORTSTRETCHES: process.env.VUE_APP_FEATURE_IMPORTSTRETCHES,
   methods: {
     logoff() {
-      app.$snotify.clear();
-      this.$store.commit("reset");
-      this.$store.commit("user/clearAuth");
-      this.$router.push("/login");
+      logOff();
     },
     toggleContextBox(context) {
-      this.$router.push("/");
+      if (this.$route.path !== "/") this.$router.push("/");
       this.$store.commit("application/showContextBox", true);
       this.$store.commit("application/contextBoxContent", context);
       this.$store.commit("application/showSearchbar", true);
@@ -243,7 +280,6 @@
 }
 
 .sidebarextended {
-  max-height: 35rem;
   max-width: $sidebar-width;
   min-width: $sidebar-width;
 }
--- a/client/src/components/Systemconfiguration.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/Systemconfiguration.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -80,7 +80,6 @@
 import { HTTP } from "@/lib/http";
 import { displayError } from "@/lib/errors.js";
 import { mapState } from "vuex";
-import Spacer from "./Spacer";
 
 export default {
   name: "systemconfiguration",
@@ -95,7 +94,7 @@
   components: {
     "chrome-picker": Chrome,
     "compact-picker": Compact,
-    Spacer
+    Spacer: () => import("./Spacer")
   },
   computed: {
     ...mapState("application", ["showSidebar"])
--- a/client/src/components/importqueue/Importqueue.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/importqueue/Importqueue.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -109,14 +109,12 @@
 import { displayError } from "@/lib/errors.js";
 import { mapState } from "vuex";
 import { HTTP } from "@/lib/http.js";
-import Importqueuedetail from "./Importqueuedetail";
-import Spacer from "@/components/Spacer";
 
 export default {
   name: "importqueue",
   components: {
-    Importqueuedetail,
-    Spacer
+    Importqueuedetail: () => import("./Importqueuedetail"),
+    Spacer: () => import("@/components/Spacer")
   },
   data() {
     return {
--- a/client/src/components/importqueue/Importqueuedetail.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/importqueue/Importqueuedetail.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -113,7 +113,13 @@
       sortAsc: true
     };
   },
+  mounted() {
+    this.openSpecificDetail();
+  },
   watch: {
+    $route() {
+      this.openSpecificDetail();
+    },
     reload() {
       if (this.reload) {
         this.entries = [];
@@ -122,6 +128,14 @@
     }
   },
   methods: {
+    openSpecificDetail() {
+      const { id } = this.$route.params;
+      if (id == this.job.id) {
+        this.showDetails(id);
+      } else {
+        this.show = false;
+      }
+    },
     formatDate(date) {
       return date
         ? new Date(date).toLocaleDateString(locale2, {
--- a/client/src/components/importschedule/Importschedule.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/importschedule/Importschedule.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -11,7 +11,7 @@
         </h6>
         <div class="card-body schedulecardbody">
           <div class="card-body schedulecardbody">
-            <div class="searchandfilter  w-50 d-flex flex-row">
+            <div class="searchandfilter mb-3  w-50 d-flex flex-row">
               <div class="searchgroup input-group">
                 <div class="input-group-prepend">
                   <span class="input-group-text" id="search">
@@ -38,40 +38,62 @@
                   <th><translate>Email</translate></th>
                   <th>&nbsp;</th>
                   <th>&nbsp;</th>
+                  <th>&nbsp;</th>
                 </tr>
               </thead>
               <tbody>
-                <tr v-for="(schedule, index) in schedules" :key="index">
-                  <td></td>
-                  <td></td>
-                  <td></td>
-                  <td></td>
-                  <td></td>
+                <tr v-for="schedule in schedules" :key="schedule.id">
+                  <td>{{ schedule.id }}</td>
+                  <td>{{ schedule.kind }}</td>
+                  <td>{{ schedule.user }}</td>
+                  <td>{{ schedule.cron }}</td>
                   <td>
                     <font-awesome-icon
+                      v-if="schedule['send-email']"
+                      class="fa-fw mr-2"
+                      fixed-width
+                      icon="check"
+                    ></font-awesome-icon>
+                  </td>
+                  <td>
+                    <font-awesome-icon
+                      :style="activeStyle"
+                      @click="editSchedule(schedule.id)"
                       icon="pencil-alt"
                       fixed-width
                     ></font-awesome-icon>
                   </td>
                   <td>
                     <font-awesome-icon
-                      @click="deleteSchedule"
+                      :style="activeStyle"
+                      @click="deleteSchedule(schedule.id)"
                       icon="trash"
                       fixed-width
                     ></font-awesome-icon>
                   </td>
+                  <td>
+                    <font-awesome-icon
+                      @click="triggerManualImport(schedule.id)"
+                      class="fa-fw mr-2"
+                      fixed-width
+                      icon="play"
+                    ></font-awesome-icon>
+                  </td>
                 </tr>
               </tbody>
             </table>
             <div v-else class="mt-4 small text-center py-3">
-              <translate>No schedules</translate>
+              <translate>No scheduled imports</translate>
             </div>
-            <button
-              @click="newImport"
-              class="btn btn-info position-absolute newbutton"
-            >
-              <translate>New Import</translate>
-            </button>
+            <div class="text-right">
+              <button
+                :disabled="importScheduleDetailVisible"
+                @click="newImport"
+                class="btn btn-info newbutton"
+              >
+                <translate>New Import</translate>
+              </button>
+            </div>
           </div>
         </div>
       </div>
@@ -96,31 +118,96 @@
  */
 
 import { mapState } from "vuex";
-import Importscheduledetail from "./Importscheduledetail";
-import Spacer from "@/components/Spacer";
+import { HTTP } from "@/lib/http";
+import { displayInfo, displayError } from "@/lib/errors.js";
 
 export default {
   name: "importschedule",
   components: {
-    Importscheduledetail,
-    Spacer
+    Importscheduledetail: () => import("./Importscheduledetail"),
+    Spacer: () => import("@/components/Spacer")
   },
   data() {
     return {
       searchQuery: ""
     };
   },
+  mounted() {
+    this.getSchedules();
+  },
   methods: {
+    editSchedule(id) {
+      this.$store
+        .dispatch("imports/loadSchedule", id)
+        .then(() => {
+          this.$store.commit("imports/setImportScheduleDetailVisible");
+        })
+        .catch(error => {
+          const { status, data } = error.response;
+          displayError({
+            title: this.$gettext("Backend Error"),
+            message: `${status}: ${data.message || data}`
+          });
+        });
+    },
+    triggerManualImport(id) {
+      HTTP.get("/imports/config/" + id + "/run", {
+        headers: { "X-Gemma-Auth": localStorage.getItem("token") }
+      })
+        .then(response => {
+          const { id } = response.data;
+          displayInfo({
+            title: this.$gettext("Imports"),
+            message: this.$gettext("Manually triggered import: #") + id
+          });
+        })
+        .catch(error => {
+          const { status, data } = error.response;
+          displayError({
+            title: this.$gettext("Backend Error"),
+            message: `${status}: ${data.message || data}`
+          });
+        });
+    },
+    getSchedules() {
+      this.$store.dispatch("imports/loadSchedules").catch(error => {
+        const { status, data } = error.response;
+        displayError({
+          title: this.$gettext("Backend Error"),
+          message: `${status}: ${data.message || data}`
+        });
+      });
+    },
     newImport() {
       this.$store.commit("imports/setImportScheduleDetailVisible");
     },
     deleteSchedule(index) {
-      this.$store.commit("imports/deleteSchedule", index);
+      if (this.importScheduleDetailVisible) return;
+      this.$store
+        .dispatch("imports/deleteSchedule", index)
+        .then(() => {
+          this.getSchedules();
+          displayInfo({
+            title: this.$gettext("Imports"),
+            message: this.$gettext("Deleted import: #") + index
+          });
+        })
+        .catch(error => {
+          const { status, data } = error.response;
+          displayError({
+            title: this.$gettext("Backend Error"),
+            message: `${status}: ${data.message || data}`
+          });
+        });
     }
   },
   computed: {
     ...mapState("application", ["showSidebar"]),
-    ...mapState("imports", ["schedules"]),
+    ...mapState("imports", ["schedules", "importScheduleDetailVisible"]),
+    activeStyle() {
+      const color = this.importScheduleDetailVisible ? "#aeaeae" : "#000000";
+      return { color: color };
+    },
     spacerStyle() {
       return [
         "spacer ml-3",
@@ -135,6 +222,14 @@
 </script>
 
 <style lang="scss" scoped>
+th {
+  border-top: 0px;
+}
+
+.card-body {
+  padding-bottom: $small-offset;
+}
+
 .schedulecard {
   margin-right: $offset;
   min-height: 20rem;
@@ -145,10 +240,4 @@
   margin-left: auto;
   margin-right: auto;
 }
-
-.newbutton {
-  position: absolute;
-  bottom: $offset;
-  right: $offset;
-}
 </style>
--- a/client/src/components/importschedule/Importscheduledetail.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/importschedule/Importscheduledetail.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -7,14 +7,14 @@
       <h6
         class="mb-0 py-2 px-3 border-bottom d-flex text-info align-items-center"
       >
-        <translate>New import</translate>
+        {{ dialogLabel }}
         <span @click="closeDetailview" class="closebutton">
           <font-awesome-icon icon="times"></font-awesome-icon>
         </span>
       </h6>
       <div class="card-body">
         <form @submit.prevent="save" class="ml-2 mr-2">
-          <div class="d-flex flex-row w-100">
+          <div class="d-flex flex-row">
             <div class="flex-column w-50 mr-3">
               <div class="flex-row text-left">
                 <small class="text-muted">
@@ -25,24 +25,45 @@
                 <option :value="$options.IMPORTTYPES.BOTTLENECK"
                   ><translate>Bottlenecks</translate></option
                 >
+                <option :value="$options.IMPORTTYPES.WATERWAYAXIS"
+                  ><translate>Waterway axis</translate></option
+                >
+                <option :value="$options.IMPORTTYPES.GAUGEMEASUREMENT"
+                  ><translate>Gauge measurement</translate></option
+                >
+                <option :value="$options.IMPORTTYPES.FAIRWAYAVAILABILITY"
+                  ><translate>Available Fairway Depths</translate></option
+                >
+                <option :value="$options.IMPORTTYPES.WATERWAYAREA"
+                  ><translate>Waterwayarea</translate></option
+                >
+                <option :value="$options.IMPORTTYPES.FAIRWAYDIMENSIONS"
+                  ><translate>Fairwaydimensions</translate></option
+                >
+                <option :value="$options.IMPORTTYPES.WATERWAYGAUGES"
+                  ><translate>Waterway gauges</translate></option
+                >
               </select>
             </div>
-            <div v-if="import_" class="flex-column w-50">
+            <div class="flex-column ml-4">
               <div class="flex-row text-left">
                 <small class="text-muted">
-                  <translate>Importtype</translate>
+                  <translate>Email Notification</translate>
                 </small>
               </div>
-              <select
-                :disabled="fixedSource"
-                v-model="importSource"
-                class="custom-select"
-                id="importsource"
-              >
-                <option :value="this.$options.IMPORTSOURCES.SOAP"
-                  ><translate>SOAP</translate></option
-                >
-              </select>
+              <div class="flex-flex-row text-left">
+                <toggle-button
+                  v-model="eMailNotification"
+                  class="mt-2"
+                  :speed="100"
+                  :labels="{
+                    checked: this.$options.on,
+                    unchecked: this.$options.off
+                  }"
+                  :width="60"
+                  :height="30"
+                />
+              </div>
             </div>
           </div>
           <div v-if="isURLRequired">
@@ -55,7 +76,7 @@
                   <input v-model="url" class="form-control" type="url" />
                 </div>
               </div>
-              <div class="flex-column mt-3 text-left">
+              <div v-if="false" class="flex-column mt-3 text-left">
                 <div class="d-flex flex-row">
                   <small class="text-muted mr-2"
                     ><translate>Insecure</translate>
@@ -81,25 +102,135 @@
                 </div>
               </div>
             </div>
+            <div v-if="!url" class="d-flex flex-row">
+              <small
+                ><translate class="text-danger"
+                  >Please enter a URL</translate
+                ></small
+              >
+            </div>
           </div>
-          <div class="flex-column mt-3 w-100 mr-2">
-            <div class="flex-row text-left">
-              <small class="text-muted">
-                <translate>Simple Schedule</translate>
-              </small>
+          <div v-if="isCredentialsRequired">
+            <div class="d-flex flex-row">
+              <div class="flex-column mt-3 mr-3 w-50">
+                <div class="flex-row text-left">
+                  <small class="text-muted">
+                    <translate>Username</translate>
+                  </small>
+                </div>
+                <div class="w-100">
+                  <input v-model="username" class="form-control" type="text" />
+                </div>
+                <div v-if="!username" class="d-flex flex-row">
+                  <small
+                    ><translate class="text-danger"
+                      >Please enter a Username</translate
+                    ></small
+                  >
+                </div>
+              </div>
+              <div class="flex-column mt-3 w-50">
+                <div class="flex-row text-left">
+                  <small class="text-muted">
+                    <translate>Password</translate>
+                  </small>
+                </div>
+                <div class="w-100">
+                  <input v-model="password" class="form-control" type="text" />
+                </div>
+                <div v-if="!password" class="d-flex flex-row">
+                  <small
+                    ><translate class="text-danger"
+                      >Please enter a Password</translate
+                    ></small
+                  >
+                </div>
+              </div>
             </div>
-            <div class="flex-flex-row text-left">
-              <toggle-button
-                v-model="easyCron"
-                class="mt-2"
-                :speed="100"
-                :labels="{
-                  checked: this.$options.on,
-                  unchecked: this.$options.off
-                }"
-                :width="60"
-                :height="30"
-              />
+          </div>
+          <div v-if="isFeatureTypeRequired">
+            <div class="d-flex flex-row">
+              <div class="flex-column mt-3 mr-3 w-50">
+                <div class="flex-row text-left">
+                  <small class="text-muted">
+                    <translate>Featuretype</translate>
+                  </small>
+                </div>
+                <div class="w-100">
+                  <input
+                    v-model="featureType"
+                    class="form-control"
+                    type="text"
+                  />
+                </div>
+                <div v-if="!featureType" class="d-flex flex-row">
+                  <small
+                    ><translate class="text-danger"
+                      >Please enter a Featuretype</translate
+                    ></small
+                  >
+                </div>
+              </div>
+              <div class="flex-column mt-3 w-50">
+                <div class="flex-row text-left">
+                  <small class="text-muted">
+                    <translate>SortBy</translate>
+                  </small>
+                </div>
+                <div class="w-100">
+                  <input v-model="sortBy" class="form-control" type="text" />
+                </div>
+                <div v-if="!sortBy" class="d-flex flex-row">
+                  <small
+                    ><translate class="text-danger"
+                      >Please enter SortBy</translate
+                    ></small
+                  >
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="d-flex flex-row">
+            <div class="flex-column mt-3 mr-4">
+              <div class="flex-row text-left">
+                <small class="text-muted">
+                  <translate>Scheduled</translate>?
+                </small>
+              </div>
+              <div class="flex-flex-row text-left">
+                <toggle-button
+                  v-model="scheduled"
+                  class="mt-2"
+                  :speed="100"
+                  :labels="{
+                    checked: this.$options.on,
+                    unchecked: this.$options.off
+                  }"
+                  :width="60"
+                  :height="30"
+                />
+              </div>
+            </div>
+            <div class="flex-column mt-3 mr-2">
+              <div class="flex-row text-left">
+                <small class="text-muted">
+                  <translate>Simple Schedule</translate>
+                </small>
+              </div>
+              <div class="flex-flex-row text-left">
+                <toggle-button
+                  :disabled="!scheduled"
+                  v-model="easyCron"
+                  class="mt-2"
+                  :speed="100"
+                  :labels="{
+                    checked: this.$options.on,
+                    unchecked: this.$options.off
+                  }"
+                  :width="60"
+                  :height="30"
+                />
+              </div>
             </div>
           </div>
           <div class="flex-column w-100 mr-2">
@@ -109,7 +240,10 @@
               </small>
             </div>
             <div v-if="easyCron" class="text-left w-50">
-              <select v-model="simple" class="form-control"
+              <select
+                :disabled="!scheduled"
+                v-model="simple"
+                class="form-control"
                 ><option value="weekly"><translate>Weekly</translate></option>
                 <option value="monthly"><translate>Monthly</translate></option>
               </select>
@@ -118,6 +252,7 @@
               <div class="d-flex flex-row">
                 <h4 class="mt-auto mb-auto mr-2">{{ $options.EVERY }}</h4>
                 <select
+                  :disabled="!scheduled"
                   style="width: 130px;"
                   v-model="cronMode"
                   class="form-control"
@@ -133,6 +268,7 @@
                 <div v-if="cronMode == 'hour'" class="ml-1 d-flex flex-row">
                   <h4 class="mt-auto mb-auto">{{ $options.ON }}</h4>
                   <input
+                    :disabled="!scheduled"
                     v-model="minutes"
                     class="cronfield ml-1 mr-1 form-control"
                     type="number"
@@ -142,11 +278,13 @@
                 <div v-if="cronMode == 'day'" class="ml-1 d-flex flex-row">
                   <h4 class="mt-auto mb-auto">{{ $options.AT }}</h4>
                   <input
+                    :disabled="!scheduled"
                     v-model="hour"
                     class="cronfield ml-1 mr-1 form-control"
                     type="number"
                   />
                   <input
+                    :disabled="!scheduled"
                     v-model="minutes"
                     class="cronfield ml-1 mr-1 form-control"
                     type="number"
@@ -155,7 +293,11 @@
                 </div>
                 <div v-if="cronMode == 'week'" class="ml-1 d-flex flex-row">
                   <h4 class="ml-1 mr-1 mt-auto mb-auto">{{ $options.ON }}</h4>
-                  <select v-model="day" class="form-control">
+                  <select
+                    :disabled="!scheduled"
+                    v-model="day"
+                    class="form-control"
+                  >
                     <option
                       v-for="(option, key) in $options.DAYSOFWEEK"
                       :key="key"
@@ -165,11 +307,13 @@
                   </select>
                   <h4 class="ml-1 mt-auto mb-auto">{{ $options.AT }}</h4>
                   <input
+                    :disabled="!scheduled"
                     v-model="hour"
                     class="cronfield ml-1 mr-1 form-control"
                     type="number"
                   />
                   <input
+                    :disabled="!scheduled"
                     v-model="minutes"
                     class="cronfield ml-1 mr-1 form-control"
                     type="number"
@@ -178,17 +322,20 @@
                 <div v-if="cronMode == 'month'" class="ml-1 d-flex flex-row">
                   <h4 class="ml-1 mt-auto mb-auto">{{ $options.ON }}</h4>
                   <input
+                    :disabled="!scheduled"
                     v-model="dayOfMonth"
                     class="cronfield ml-1 mr-1 form-control"
                     type="number"
                   />
                   <h4 class="mt-auto mb-auto">{{ $options.AT }}</h4>
                   <input
+                    :disabled="!scheduled"
                     v-model="hour"
                     class="cronfield ml-1 mr-2 form-control"
                     type="number"
                   />
                   <input
+                    :disabled="!scheduled"
                     v-model="minutes"
                     class="cronfield ml-1 mr-2 form-control"
                     type="number"
@@ -198,12 +345,17 @@
                 <div v-if="cronMode == 'year'" class="ml-1 d-flex flex-row">
                   <h4 class="ml-1 mt-auto mb-auto">{{ $options.ON }}</h4>
                   <input
+                    :disabled="!scheduled"
                     v-model="dayOfMonth"
                     class="cronfield ml-1 mr-1 form-control"
                     type="number"
                   />
                   <h4 class="mt-auto mb-auto">{{ $options.OF }}</h4>
-                  <select v-model="month" class="ml-1 mr-1 form-control">
+                  <select
+                    :disabled="!scheduled"
+                    v-model="month"
+                    class="ml-1 mr-1 form-control"
+                  >
                     <option
                       v-for="(option, key) in $options.MONTHS"
                       :value="key"
@@ -213,11 +365,13 @@
                   </select>
                   <h4 class="mt-auto mb-auto">{{ $options.ON }}</h4>
                   <input
+                    :disabled="!scheduled"
                     v-model="hour"
                     class="cronfield ml-1 mr-1 form-control"
                     type="number"
                   />
                   <input
+                    :disabled="!scheduled"
                     v-model="minutes"
                     class="cronfield ml-1 mr-1 form-control"
                     type="number"
@@ -228,40 +382,15 @@
                 <h5 class="mt-auto mb-auto mr-2">
                   <translate>Cronstring</translate>
                 </h5>
-                <input class="form-control" :value="cronString" type="text" />
+                <input
+                  :disabled="!scheduled"
+                  class="form-control"
+                  v-model="cronString"
+                  type="text"
+                />
               </div>
             </div>
           </div>
-          <div class="flex-column mt-3 w-100 mr-2">
-            <div class="flex-row text-left">
-              <small class="text-muted">
-                <translate>Email Notification</translate>
-              </small>
-            </div>
-            <div class="flex-flex-row text-left">
-              <toggle-button
-                v-model="eMailNotification"
-                class="mt-2"
-                :speed="100"
-                :labels="{
-                  checked: this.$options.on,
-                  unchecked: this.$options.off
-                }"
-                :width="60"
-                :height="30"
-              />
-            </div>
-          </div>
-          <div class="flex-column w-100 mr-2">
-            <div class="flex-row text-left">
-              <small class="text-muted"><translate>Email</translate> </small>
-            </div>
-            <input
-              :disabled="!eMailNotification"
-              class="form-control"
-              type="email"
-            />
-          </div>
           <button type="submit" class="shadow-sm btn btn-info submit-button">
             <translate>Submit</translate>
           </button>
@@ -285,39 +414,34 @@
 </template>
 
 <script>
+/* This is Free Software under GNU Affero General Public License v >= 3.0
+ * without warranty, see README.md and license for details.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ * License-Filename: LICENSES/AGPL-3.0.txt
+ *
+ * Copyright (C) 2018 by via donau
+ *   – Österreichische Wasserstraßen-Gesellschaft mbH
+ * Software engineering by Intevation GmbH
+ *
+ * Author(s):
+ * Thomas Junk <thomas.junk@intevation.de>
+ */
+import {
+  IMPORTTYPES,
+  IMPORTTYPEKIND,
+  initializeCurrentSchedule
+} from "@/store/imports.js";
 import { mapState } from "vuex";
 import { displayInfo, displayError } from "@/lib/errors.js";
 import app from "@/main.js";
-import { HTTP } from "@/lib/http.js";
 
 export default {
   name: "importscheduledetail",
   data() {
-    return {
-      importType: null,
-      schedule: null,
-      import_: null,
-      importSource: null,
-      eMailNotification: false,
-      easyCron: true,
-      cronMode: "",
-      minutes: null,
-      month: null,
-      hour: null,
-      day: null,
-      dayOfMonth: null,
-      simple: null,
-      url: null,
-      insecure: false,
-      triggerActive: true
-    };
+    return initializeCurrentSchedule();
   },
-  IMPORTTYPES: {
-    BOTTLENECK: "BOTTLENECK"
-  },
-  IMPORTSOURCES: {
-    SOAP: "SOAP"
-  },
+  IMPORTTYPES: IMPORTTYPES,
   EVERY: app.$gettext("Every"),
   MINUTESPAST: app.$gettext("minutes past"),
   ON: app.$gettext("on"),
@@ -355,7 +479,31 @@
     11: app.$gettext("November"),
     12: app.$gettext("December")
   },
+  mounted() {
+    this.initialize();
+  },
   watch: {
+    cronMode() {
+      this.cronString = this.calcCronString();
+    },
+    minutes() {
+      this.cronString = this.calcCronString();
+    },
+    hour() {
+      this.cronString = this.calcCronString();
+    },
+    month() {
+      this.cronString = this.calcCronString();
+    },
+    day() {
+      this.cronString = this.calcCronString();
+    },
+    dayOfMonth() {
+      this.cronString = this.calcCronString();
+    },
+    importScheduleDetailVisible() {
+      this.initialize();
+    },
     cronString() {
       if (this.isWeekly(this.cronString)) {
         this.simple = "weekly";
@@ -363,31 +511,53 @@
       if (this.isMonthly(this.cronString)) {
         this.simple = "monthly";
       }
-    },
-    import_() {
-      if (this.import_ === this.$options.IMPORTTYPES.BOTTLENECK) {
-        this.importSource = this.$options.IMPORTSOURCES.SOAP;
-      }
     }
   },
   computed: {
-    ...mapState("imports", ["importScheduleDetailVisible"]),
-    isURLRequired() {
-      if (this.import_ === this.$options.IMPORTTYPES.BOTTLENECK) return true;
-      return false;
+    ...mapState("imports", ["importScheduleDetailVisible", "currentSchedule"]),
+    dialogLabel() {
+      if (this.id) return this.$gettext("Import") + " " + this.id;
+      return this.$gettext("New Import");
+    },
+    isCredentialsRequired() {
+      switch (this.import_) {
+        case this.$options.IMPORTTYPES.WATERWAYGAUGES:
+          return true;
+        default:
+          return false;
+      }
     },
-    cronString: {
-      get() {
-        let getValue = value => {
-          return this[value] ? this[value] : "*";
-        };
-        if (this.cronMode === "15minutes") return "*/15 * * * *";
-        const min = getValue("minutes");
-        const h = getValue("hour");
-        const dm = getValue("dayOfMonth");
-        const m = getValue("month");
-        const wd = getValue("day");
-        return `${min} ${h} ${dm} ${m} ${wd}`;
+    isURLRequired() {
+      switch (this.import_) {
+        case this.$options.IMPORTTYPES.BOTTLENECK:
+        case this.$options.IMPORTTYPES.WATERWAYAXIS:
+        case this.$options.IMPORTTYPES.GAUGEMEASUREMENT:
+        case this.$options.IMPORTTYPES.FAIRWAYAVAILABILITY:
+        case this.$options.IMPORTTYPES.WATERWAYAREA:
+        case this.$options.IMPORTTYPES.FAIRWAYDIMENSIONS:
+        case this.$options.IMPORTTYPES.WATERWAYGAUGES:
+          return true;
+        default:
+          return false;
+      }
+    },
+    isFeatureTypeRequired() {
+      switch (this.import_) {
+        case this.$options.IMPORTTYPES.WATERWAYAXIS:
+        case this.$options.IMPORTTYPES.WATERWAYAREA:
+        case this.$options.IMPORTTYPES.FAIRWAYDIMENSIONS:
+          return true;
+        default:
+          return false;
+      }
+    },
+    isSortbyRequired() {
+      switch (this.import_) {
+        case this.$options.IMPORTTYPES.WATERWAYAXIS:
+        case this.$options.IMPORTTYPES.WATERWAYAREA:
+          return true;
+        default:
+          return false;
       }
     },
     fixedSource() {
@@ -396,28 +566,50 @@
     }
   },
   methods: {
-    isWeekly(cron) {
-      return /\d{1,2} \d{1,2} \* \* \d{1}/.test(cron);
+    calcCronString() {
+      let getValue = value => {
+        return this[value] ? this[value] : "*";
+      };
+      if (this.cronMode === "15minutes") return "0 */15 * * * *";
+      const min = getValue("minutes");
+      const h = getValue("hour");
+      const dm = getValue("dayOfMonth");
+      const m = getValue("month");
+      const wd = getValue("day");
+      return `0 ${min} ${h} ${dm} ${m} ${wd}`;
     },
-    isMonthly(cron) {
-      return /\d{1,2} \d{1,2} \d{1,2} \* \*/.test(cron);
+    validateBottleneckfields() {
+      return !!this.url;
     },
     initialize() {
-      this.importType = null;
-      this.schedule = null;
-      this.import_ = null;
-      this.importSource = null;
-      this.eMailNotification = false;
-      this.easyCron = true;
-      this.cronMode = "";
-      this.minutes = null;
-      this.month = null;
-      this.hour = null;
-      this.day = null;
-      this.dayOfMonth = null;
-      this.simple = null;
-      this.url = null;
-      this.insecure = false;
+      this.id = this.currentSchedule.id;
+      this.importType = this.currentSchedule.importType;
+      this.schedule = this.currentSchedule.schedule;
+      this.scheduled = this.currentSchedule.scheduled;
+      this.import_ = this.currentSchedule.import_;
+      this.importSource = this.currentSchedule.importSource;
+      this.eMailNotification = this.currentSchedule.eMailNotification;
+      this.easyCron = this.currentSchedule.easyCron;
+      this.cronMode = this.currentSchedule.cronMode;
+      this.minutes = this.currentSchedule.minutes;
+      this.month = this.currentSchedule.month;
+      this.hour = this.currentSchedule.hour;
+      this.day = this.currentSchedule.day;
+      this.dayOfMonth = this.currentSchedule.dayOfMonth;
+      this.simple = this.currentSchedule.simple;
+      this.url = this.currentSchedule.url;
+      this.insecure = this.currentSchedule.insecure;
+      this.cronString = this.currentSchedule.cronString;
+      this.featureType = this.currentSchedule.featureType;
+      this.sortBy = this.currentSchedule.sortBy;
+      this.username = this.currentSchedule.username;
+      this.password = this.currentSchedule.password;
+    },
+    isWeekly(cron) {
+      return /0 \d{1,2} \d{1,2} \* \* \d{1}/.test(cron);
+    },
+    isMonthly(cron) {
+      return /0 \d{1,2} \d{1,2} \d{1,2} \* \*/.test(cron);
     },
     clearInputs() {
       this.minutes = null;
@@ -428,21 +620,29 @@
     },
     triggerManualImport() {
       if (!this.triggerActive) return;
+      if (!this.import_) return;
       let data = {};
-      if (this.import_ === this.$options.IMPORTTYPES.BOTTLENECK) {
+      if (this.isURLRequired) {
         if (!this.url) return;
         data["url"] = this.url;
         data["insecure"] = this.insecure;
       }
-      const importTypes = {
-        BOTTLENECK: "bottleneck"
-      };
+      if (this.isFeatureTypeRequired) {
+        if (!this.featureType) return;
+        data["feature-type"] = this.featureType;
+      }
+      if (this.isSortbyRequired) {
+        if (!this.sortBy) return;
+        data["sort-by"] = this.sortBy;
+      }
+      if (this.isCredentialsRequired) {
+        if (!this.username || !this.password) return;
+        data["username"] = this.username;
+        data["password"] = this.password;
+      }
       this.triggerActive = false;
-      HTTP.post("imports/" + importTypes[this.import_], data, {
-        headers: {
-          "X-Gemma-Auth": localStorage.getItem("token")
-        }
-      })
+      this.$store
+        .dispatch("imports/triggerImport", { type: this.import_, data })
         .then(response => {
           const { id } = response.data;
           displayInfo({
@@ -453,7 +653,7 @@
         .catch(error => {
           const { status, data } = error.response;
           displayError({
-            title: this.gettext("Backend Error"),
+            title: this.$gettext("Backend Error"),
             message: `${status}: ${data.message || data}`
           });
         })
@@ -462,13 +662,101 @@
         });
     },
     save() {
-      displayInfo({
-        title: this.$gettext("Import"),
-        message: this.$gettext("under construction")
-      });
+      const addAttribute = (data, attribute) => {
+        if (!data["attributes"]) data.attributes = {};
+        data["attributes"] = { ...data["attributes"], ...attribute };
+      };
+      if (!this.import_) return;
+      let cron = this.cronString;
+      if (this.easyCron) {
+        if (this.simple === "weekly") cron = "0 0 0 * * 0";
+        if (this.simple === "monthly") cron = "0 0 0 1 * *";
+      }
+      let data = {};
+      if (this.isURLRequired) {
+        if (!this.url) return;
+        data["url"] = this.url;
+        addAttribute(data, {
+          insecure: this.insecure + ""
+        });
+      }
+      if (this.isSortbyRequired) {
+        if (!this.sortBy) return;
+        addAttribute(data, {
+          "sort-by": this.sortBy
+        });
+      }
+      if (this.isFeatureTypeRequired) {
+        if (!this.featureType) return;
+        addAttribute(data, {
+          "feature-type": this.featureType
+        });
+      }
+      if (this.isCredentialsRequired) {
+        if (!this.username || !this.password) return;
+        addAttribute(data, { username: this.username });
+        addAttribute(data, { password: this.password });
+      }
+      if (this.scheduled) data["cron"] = cron;
+      data["kind"] = IMPORTTYPEKIND[this.import_];
+      data["send-email"] = this.eMailNotification;
+      if (!this.id) {
+        this.$store
+          .dispatch("imports/saveCurrentSchedule", data)
+          .then(response => {
+            const { id } = response.data;
+            displayInfo({
+              title: this.$gettext("Import"),
+              message: this.$gettext("Saved import: #") + id
+            });
+            this.closeDetailview();
+            this.$store.dispatch("imports/loadSchedules").catch(error => {
+              const { status, data } = error.response;
+              displayError({
+                title: this.gettext("Backend Error"),
+                message: `${status}: ${data.message || data}`
+              });
+            });
+          })
+          .catch(error => {
+            const { status, data } = error.response;
+            displayError({
+              title: this.$gettext("Backend Error"),
+              message: `${status}: ${data.message || data}`
+            });
+          });
+      } else {
+        this.$store
+          .dispatch("imports/updateCurrentSchedule", {
+            data: data,
+            id: this.id
+          })
+          .then(response => {
+            const { id } = response.data;
+            displayInfo({
+              title: this.$gettext("Import"),
+              message: this.$gettext("update import: #") + id
+            });
+            this.closeDetailview();
+            this.$store.dispatch("imports/loadSchedules").catch(error => {
+              const { status, data } = error.response;
+              displayError({
+                title: this.gettext("Backend Error"),
+                message: `${status}: ${data.message || data}`
+              });
+            });
+          })
+          .catch(error => {
+            const { status, data } = error.response;
+            displayError({
+              title: this.$gettext("Backend Error"),
+              message: `${status}: ${data.message || data}`
+            });
+          });
+      }
     },
     closeDetailview() {
-      this.initialize();
+      this.$store.commit("imports/clearCurrentSchedule");
       this.$store.commit("imports/setImportScheduleDetailInvisible");
     }
   },
--- a/client/src/components/layers/Layers.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/layers/Layers.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -44,12 +44,11 @@
  * Thomas Junk <thomas.junk@intevation.de>
  * Markus Kottländer <markus.kottlaender@intevation.de>
  */
-import Layerselect from "./Layerselect";
 import { mapGetters, mapState } from "vuex";
 export default {
   name: "layers",
   components: {
-    Layerselect
+    Layerselect: () => import("./Layerselect")
   },
   computed: {
     ...mapGetters("map", ["layersForLegend"]),
--- a/client/src/components/layers/Layerselect.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/layers/Layerselect.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -46,7 +46,6 @@
  * Thomas Junk <thomas.junk@intevation.de>
  */
 import { HTTP } from "@/lib/http";
-import LegendElement from "./LegendElement.vue";
 export default {
   props: ["layername", "layerindex", "isVisible"],
   name: "layerselect",
@@ -56,7 +55,7 @@
     };
   },
   components: {
-    LegendElement
+    LegendElement: () => import("./LegendElement.vue")
   },
   methods: {
     visibilityToggled() {
--- a/client/src/components/staging/Staging.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/staging/Staging.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -59,7 +59,6 @@
 import { mapState } from "vuex";
 import { HTTP } from "@/lib/http.js";
 import { displayError, displayInfo } from "@/lib/errors.js";
-import StagingDetail from "./StagingDetail";
 import { STATES } from "@/store/imports.js";
 
 export default {
@@ -67,7 +66,7 @@
     return {};
   },
   components: {
-    StagingDetail
+    StagingDetail: () => import("./StagingDetail")
   },
   mounted() {
     this.loadData();
--- a/client/src/components/staging/StagingDetail.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/staging/StagingDetail.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -1,5 +1,5 @@
 <template>
-  <div class="pb-2 d-flex flex-column w-100">
+  <div :class="detail">
     <div class="d-flex flex-row">
       <div class="mt-auto d-flex flex-row mb-auto small name text-left">
         <a
@@ -149,6 +149,7 @@
 import { WFS } from "ol/format.js";
 import { or as orFilter, equalTo as equalToFilter } from "ol/format/filter.js";
 import { displayError } from "@/lib/errors.js";
+import { mapState } from "vuex";
 import center from "@turf/center";
 
 export default {
@@ -164,9 +165,37 @@
   },
   mounted() {
     this.bottlenecks = [];
+    if (this.open) this.showDetails();
+  },
+  computed: {
+    ...mapState("imports", ["importToReview"]),
+    open() {
+      return this.importToReview == this.data.id;
+    },
+    detail() {
+      return [
+        "pb-2",
+        "pt-2",
+        "d-flex",
+        "flex-column",
+        "w-100",
+        {
+          highlight: this.open && this.needsApproval(this.data)
+        }
+      ];
+    }
+  },
+  watch: {
+    open() {
+      const { review } = this.$route.query;
+      if (review) {
+        this.showDetails();
+      }
+    }
   },
   methods: {
     showDetails() {
+      if (this.data.kind.toUpperCase() !== "BN") return;
       if (this.show) {
         this.show = false;
         return;
@@ -267,6 +296,10 @@
 </script>
 
 <style lang="scss" scoped>
+.highlight {
+  background-color: #f9f9f9;
+}
+
 .condensed {
   font-stretch: condensed;
 }
--- a/client/src/components/usermanagement/Userdetail.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/usermanagement/Userdetail.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -191,7 +191,6 @@
 import { HTTP } from "@/lib/http";
 import { displayError } from "@/lib/errors.js";
 import { mapState } from "vuex";
-import PasswordField from "./Passwordfield";
 
 const emptyErrormessages = () => {
   return {
@@ -228,7 +227,7 @@
 export default {
   name: "userdetail",
   components: {
-    PasswordField
+    PasswordField: () => import("./Passwordfield")
   },
   data() {
     return {
--- a/client/src/components/usermanagement/Usermanagement.vue	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/components/usermanagement/Usermanagement.vue	Tue Jan 15 10:07:10 2019 +0100
@@ -68,6 +68,7 @@
                     <td>{{ user.email }}</td>
                     <td>
                       <font-awesome-icon
+                        v-tooltip="roleLabel(user.role)"
                         :icon="roleIcon(user.role)"
                         @click="deleteUser(user.user)"
                       ></font-awesome-icon>
@@ -115,7 +116,7 @@
   </div>
 </template>
 
-<style scoped lang="scss">
+<style lang="scss">
 @import "@/assets/tooltip.scss";
 
 .addbutton {
@@ -194,11 +195,15 @@
  * Author(s):
  * Thomas Junk <thomas.junk@intevation.de>
  */
-import Userdetail from "./Userdetail";
 import store from "@/store";
 import { mapGetters, mapState } from "vuex";
 import { displayError } from "@/lib/errors.js";
-import Spacer from "@/components/Spacer";
+import Vue from "vue";
+import { VTooltip, VPopover, VClosePopover } from "v-tooltip";
+
+Vue.directive("tooltip", VTooltip);
+Vue.directive("close-popover", VClosePopover);
+Vue.component("v-popover", VPopover);
 
 export default {
   name: "userview",
@@ -210,8 +215,8 @@
     };
   },
   components: {
-    Userdetail,
-    Spacer
+    Userdetail: () => import("./Userdetail"),
+    Spacer: () => import("@/components/Spacer")
   },
   computed: {
     ...mapGetters("usermanagement", ["isUserDetailsVisible"]),
@@ -315,6 +320,14 @@
       if (role === "sys_admin") return "star";
       if (role === "waterway_admin") return ["fab", "adn"];
       return "user";
+    },
+    roleLabel(role) {
+      const labels = {
+        sys_admin: this.$gettext("System-Administrator"),
+        waterway_admin: this.$gettext("Waterway Admin"),
+        waterway_user: this.$gettext("Waterway User")
+      };
+      return labels[role];
     }
   },
   beforeRouteEnter(to, from, next) {
--- a/client/src/lib/errors.js	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/lib/errors.js	Tue Jan 15 10:07:10 2019 +0100
@@ -26,8 +26,7 @@
 const displayError = ({ title, message, options }) => {
   if (!options) options = {};
   const mergedOptions = { ...displayOptions, ...options };
-  app.$snotify.info(message, title, mergedOptions);
-  app.$snotify.error(message, title, displayOptions);
+  app.$snotify.error(message, title, mergedOptions);
 };
 
 const displayInfo = ({ title, message, options }) => {
--- a/client/src/lib/http.js	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/lib/http.js	Tue Jan 15 10:07:10 2019 +0100
@@ -12,11 +12,28 @@
  * Thomas Junk <thomas.junk@intevation.de>
  */
 
+import { logOff } from "@/lib/session.js";
+
 import axios from "axios";
 
-export const HTTP = axios.create({
+const UNAUTHORIZED = 401;
+
+const HTTP = axios.create({
   baseURL: process.env.VUE_APP_API_URL || "/api"
   /* headers: {
     Authorization: 'Bearer {token}'
   }*/
 });
+
+HTTP.interceptors.response.use(
+  response => response,
+  error => {
+    const { status } = error.response;
+    if (status === UNAUTHORIZED) {
+      logOff();
+    }
+    return Promise.reject(error);
+  }
+);
+
+export { HTTP };
--- a/client/src/lib/session.js	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/lib/session.js	Tue Jan 15 10:07:10 2019 +0100
@@ -12,6 +12,15 @@
  * Thomas Junk <thomas.junk@intevation.de>
  */
 
+import app from "@/main";
+
+const logOff = () => {
+  app.$snotify.clear();
+  app.$store.commit("reset");
+  app.$store.commit("user/clearAuth");
+  app.$router.push("/login");
+};
+
 /**
  * Compares whether session is current
  * based on the expiry information and the
@@ -34,4 +43,4 @@
   return timestring * 1000;
 }
 
-export { sessionStillActive, toMillisFromString };
+export { logOff, sessionStillActive, toMillisFromString };
--- a/client/src/locale/bg_BG/LC_MESSAGES/app.po	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/locale/bg_BG/LC_MESSAGES/app.po	Tue Jan 15 10:07:10 2019 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gemmajs 1.99.0-dev\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-12-10 15:30+0100\n"
+"POT-Creation-Date: 2019-01-15 10:04+0100\n"
 "PO-Revision-Date: 2018-12-05 12:23+0100\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -17,138 +17,200 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/components/admin/Importqueue.vue:46
+#: src/components/importschedule/Importscheduledetail.vue:452
+msgid "15 minutes"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:46
 msgid "Accepted"
 msgstr ""
 
-#: src/components/admin/Logs.vue:25
+#: src/components/Logs.vue:25
 msgid "Accesslog"
 msgstr ""
 
-#: src/components/admin/usermanagement/Usermanagement.vue:103
+#: src/components/usermanagement/Usermanagement.vue:104
 msgid "Add User"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:35
+#: src/components/importschedule/Importscheduledetail.vue:472
+msgid "April"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:449
+msgid "at"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:476
+msgid "August"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:35
 msgid "Author"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:34
+msgid "Available Fairway Depths"
+msgstr ""
+
 #: src/components/Login.vue:70
 msgid "back to login"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:136
-#: src/components/admin/Systemconfiguration.vue:134
-#: src/components/admin/Systemconfiguration.vue:149
-#: src/components/admin/Systemconfiguration.vue:168
-#: src/components/admin/Systemconfiguration.vue:185
-#: src/components/admin/usermanagement/Userdetail.vue:305
-#: src/components/admin/usermanagement/Userdetail.vue:377
-#: src/components/admin/usermanagement/Usermanagement.vue:313
-#: src/components/admin/usermanagement/Usermanagement.vue:321
-#: src/components/admin/usermanagement/Usermanagement.vue:347
-#: src/components/map/Search.vue:257
-#: src/components/map/contextbox/Bottlenecks.vue:275
-#: src/components/map/contextbox/ImportSoundingresults.vue:205
-#: src/components/map/contextbox/ImportSoundingresults.vue:244
-#: src/components/map/contextbox/ImportSoundingresults.vue:275
+#: src/components/Bottlenecks.vue:274
+#: src/components/ImportApprovedGaugeMeasurement.vue:107
+#: src/components/ImportSoundingresults.vue:216
+#: src/components/ImportSoundingresults.vue:255
+#: src/components/ImportSoundingresults.vue:286 src/components/Search.vue:258
+#: src/components/Systemconfiguration.vue:114
+#: src/components/Systemconfiguration.vue:129
+#: src/components/Systemconfiguration.vue:148
+#: src/components/Systemconfiguration.vue:165
+#: src/components/importqueue/Importqueue.vue:160
+#: src/components/importqueue/Importqueue.vue:180
+#: src/components/importqueue/Importqueuedetail.vue:182
+#: src/components/importschedule/Importschedule.vue:148
+#: src/components/importschedule/Importschedule.vue:167
+#: src/components/importschedule/Importschedule.vue:176
+#: src/components/importschedule/Importschedule.vue:198
+#: src/components/importschedule/Importscheduledetail.vue:656
+#: src/components/importschedule/Importscheduledetail.vue:724
+#: src/components/importschedule/Importscheduledetail.vue:752
+#: src/components/staging/StagingDetail.vue:246
+#: src/components/usermanagement/Userdetail.vue:304
+#: src/components/usermanagement/Userdetail.vue:376
+#: src/components/usermanagement/Usermanagement.vue:298
+#: src/components/usermanagement/Usermanagement.vue:306
+#: src/components/usermanagement/Usermanagement.vue:340
+#: src/components/importschedule/Importscheduledetail.vue:716
+#: src/components/importschedule/Importscheduledetail.vue:744
 msgid "Backend Error"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:11
+#: src/components/ImportSoundingresults.vue:16
 msgid "Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:19
+#: src/components/Systemconfiguration.vue:19
 msgid "Bottleneck Areas fill-color"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:13
+#: src/components/Systemconfiguration.vue:13
 msgid "Bottleneck Areas stroke-color"
 msgstr ""
 
-#: src/components/Sidebar.vue:27
-#: src/components/map/contextbox/Bottlenecks.vue:4
+#: src/components/Bottlenecks.vue:4 src/components/Sidebar.vue:27
+#: src/components/importschedule/Importscheduledetail.vue:25
+#: src/components/staging/StagingDetail.vue:11
 msgid "Bottlenecks"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:121
+#: src/components/ImportSoundingresults.vue:126
 msgid "Cancel Upload"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:30
+#: src/components/Bottlenecks.vue:30
 msgid "Chainage"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:167
-#: src/components/map/contextbox/ImportSoundingresults.vue:181
+#: src/components/ImportSoundingresults.vue:178
+#: src/components/ImportSoundingresults.vue:192
 msgid "choose .zip- file"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:18
-msgid "Chose format:"
+#: src/components/ImportApprovedGaugeMeasurement.vue:76
+#: src/components/ImportWaterwayProfiles.vue:75
+msgid "choose file to upload"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:64
+#: src/components/Pdftool.vue:18
+msgid "Choose format:"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:64
 msgid "Compare with"
 msgstr ""
 
-#: src/components/Sidebar.vue:76
+#: src/components/Sidebar.vue:116
 msgid "Configuration"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:316
-#: src/components/map/contextbox/Staging.vue:70
+#: src/components/ImportSoundingresults.vue:327
+#: src/components/staging/Staging.vue:33
 msgid "Confirm"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:378
+#: src/components/fairway/Profiles.vue:382
 msgid "Coordinates copied to clipboard!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:33
+#: src/components/usermanagement/Userdetail.vue:33
 msgid "Country"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:67
-#: src/components/map/contextbox/Staging.vue:14
+#: src/components/importschedule/Importscheduledetail.vue:382
+msgid "Cronstring"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:72
+#: src/components/importqueue/Importqueuedetail.vue:49
+#: src/components/staging/Staging.vue:13
 msgid "Date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:47
+#: src/components/importschedule/Importscheduledetail.vue:454
+msgid "day"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:480
+msgid "December"
+msgstr ""
+
+#: src/components/ImportStretches.vue:4
+msgid "Define section and stretches"
+msgstr ""
+
+#: src/components/Sidebar.vue:52
+msgid "Define sections and stretches"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:192
+msgid "Deleted import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:52
 msgid "Depthreference"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:32
+#: src/components/Pdftool.vue:36
 msgid "Download"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:113
+#: src/components/ImportSoundingresults.vue:118
 msgid "Download Meta.json"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:37
-#: src/components/admin/importschedule/Importscheduledetail.vue:80
+#: src/components/importschedule/Importschedule.vue:37
 msgid "Email"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:59
+#: src/components/usermanagement/Userdetail.vue:59
 msgid "Email address"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:61
+#: src/components/importschedule/Importscheduledetail.vue:50
 msgid "Email Notification"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:53
+#: src/components/importqueue/Importqueue.vue:55
 msgid "Enqueued"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:123
+#: src/components/fairway/Profiles.vue:123
 msgid "Enter coordinates manually"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:185
+#: src/components/fairway/Profiles.vue:185
 msgid "Enter label for cross profile"
 msgstr ""
 
@@ -160,89 +222,160 @@
 msgid "Enter username"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:386
+#: src/components/usermanagement/Userdetail.vue:385
 msgid "Error while saving user"
 msgstr ""
 
-#: src/components/admin/Logs.vue:34
+#: src/components/Logs.vue:34
 msgid "Errorlog"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:37
+#: src/components/importschedule/Importscheduledetail.vue:445
+msgid "Every"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:37
 msgid "Failed"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:40
+msgid "Fairwaydimensions"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:155
+msgid "Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:470
+msgid "February"
+msgstr ""
+
 #: src/components/Login.vue:76
 msgid "Forgot password"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:10 src/components/map/Pdftool.vue:49
+#: src/components/importschedule/Importscheduledetail.vue:464
+msgid "Friday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:31
+msgid "Gauge measurement"
+msgstr ""
+
+#: src/components/Pdftool.vue:10 src/components/Pdftool.vue:53
 msgid "Generate PDF"
 msgstr ""
 
-#: src/components/map/Identify.vue:10
+#: src/components/importschedule/Importscheduledetail.vue:453
+msgid "hour"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:52
+msgid "Id"
+msgstr ""
+
+#: src/components/Identify.vue:10
 msgid "Identified"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:33
-#: src/components/map/contextbox/ImportSoundingresults.vue:267
+#: src/components/ImportApprovedGaugeMeasurement.vue:99
+#: src/components/ImportSoundingresults.vue:278
+#: src/components/ImportWaterwayProfiles.vue:88 src/components/Sidebar.vue:56
+#: src/components/importschedule/Importschedule.vue:33
+#: src/components/importschedule/Importscheduledetail.vue:519
+#: src/components/importschedule/Importscheduledetail.vue:649
+#: src/components/importschedule/Importscheduledetail.vue:709
+#: src/components/importschedule/Importscheduledetail.vue:737
 msgid "Import"
 msgstr ""
 
-#: src/components/Sidebar.vue:40
+#: src/components/ImportApprovedGaugeMeasurement.vue:11
+#: src/components/Sidebar.vue:74
+msgid "Import approved gaugemeasurements"
+msgstr ""
+
+#: src/components/Sidebar.vue:64
 msgid "Import soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:4
+#: src/components/ImportSoundingresults.vue:9
 msgid "Import Soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:15
+#: src/components/Sidebar.vue:84
+msgid "Import waterway profiles"
+msgstr ""
+
+#: src/components/ImportWaterwayProfiles.vue:11
+msgid "Import Waterwayprofiles"
+msgstr ""
+
+#: src/components/staging/Staging.vue:15
 msgid "Imported"
 msgstr ""
 
-#: src/components/Sidebar.vue:92 src/components/admin/Importqueue.vue:9
+#: src/components/Sidebar.vue:134 src/components/importqueue/Importqueue.vue:9
 msgid "Importqueue"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:20
+#: src/components/Sidebar.vue:94
+#: src/components/importschedule/Importschedule.vue:9
+#: src/components/importschedule/Importschedule.vue:160
+#: src/components/importschedule/Importschedule.vue:191
+#: src/components/importschedule/Importscheduledetail.vue:20
 msgid "Imports"
 msgstr ""
 
-#: src/components/Sidebar.vue:100
-#: src/components/admin/importschedule/Importschedule.vue:9
-msgid "Importschedule"
+#: src/components/importschedule/Importscheduledetail.vue:81
+msgid "Insecure"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:34
-msgid "Importtype"
-msgstr ""
-
-#: src/components/admin/usermanagement/Userdetail.vue:354
+#: src/components/usermanagement/Userdetail.vue:353
 msgid "invalid email"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:412
+#: src/components/fairway/Profiles.vue:416
 msgid "Invalid input"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:54
+#: src/components/Pdftool.vue:24
+msgid "ISO A3"
+msgstr ""
+
+#: src/components/Pdftool.vue:25
+msgid "ISO A4"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:469
+msgid "January"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:475
+msgid "July"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:474
+msgid "June"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:58
+#: src/components/importqueue/Importqueuedetail.vue:45
 msgid "Kind"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:20
+#: src/components/Pdftool.vue:20
 msgid "landscape"
 msgstr ""
 
-#: src/components/admin/Logs.vue:41
+#: src/components/Logs.vue:41
 msgid "Last refresh:"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:19
+#: src/components/Bottlenecks.vue:19
 msgid "Latest"
 msgstr ""
 
-#: src/components/map/layers/Layers.vue:10
+#: src/components/layers/Layers.vue:10
 msgid "Layers"
 msgstr ""
 
@@ -254,65 +387,114 @@
 msgid "Login failed"
 msgstr ""
 
-#: src/components/Sidebar.vue:110
+#: src/components/Sidebar.vue:144
 msgid "Logout"
 msgstr ""
 
-#: src/components/Sidebar.vue:84 src/components/admin/Logs.vue:9
+#: src/components/Logs.vue:9 src/components/Sidebar.vue:124
 msgid "Logs"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:140
+#: src/components/usermanagement/Userdetail.vue:140
 msgid "Mail was sent"
 msgstr ""
 
+#: src/components/importschedule/Importschedule.vue:161
+#: src/components/importschedule/Importscheduledetail.vue:650
+msgid "Manually triggered import: #"
+msgstr ""
+
 #: src/components/Sidebar.vue:15
 msgid "Map"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:20
+#: src/components/importschedule/Importscheduledetail.vue:471
+msgid "March"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:473
+msgid "May"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:20
 msgid "Measurement"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:9
-#: src/components/map/contextbox/Staging.vue:12
+#: src/components/importqueue/Importqueuedetail.vue:58
+msgid "Message"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:446
+msgid "minutes past"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:460
+msgid "Monday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:456
+msgid "month"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:247
+msgid "Monthly"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:9 src/components/staging/Staging.vue:11
 msgid "Name"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:9
-msgid "New import"
-msgstr ""
-
-#: src/components/admin/importschedule/Importschedule.vue:72
+#: src/components/importschedule/Importschedule.vue:93
+#: src/components/importschedule/Importscheduledetail.vue:520
 msgid "New Import"
 msgstr ""
 
-#: src/components/map/Identify.vue:47
+#: src/components/Identify.vue:47
 msgid "No features identified."
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:116
-#: src/components/map/contextbox/Staging.vue:63
+#: src/components/Bottlenecks.vue:115 src/components/staging/Staging.vue:36
 msgid "No results."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:66
-msgid "No schedules"
+#: src/components/importschedule/Importschedule.vue:85
+msgid "No scheduled imports"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:479
+msgid "November"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:450
+msgid "o' clock"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:41
+#: src/components/importschedule/Importscheduledetail.vue:478
+msgid "October"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:448
+msgid "of"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:447
+msgid "on"
+msgstr ""
+
+#: src/components/Pdftool.vue:45
 msgid "Open in new window"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:238
+#: src/components/usermanagement/Userdetail.vue:237
 msgid "password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:236
+#: src/components/importschedule/Importscheduledetail.vue:134
+#: src/components/usermanagement/Userdetail.vue:235
 msgid "Password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:239
+#: src/components/usermanagement/Userdetail.vue:238
 msgid "password again"
 msgstr ""
 
@@ -320,82 +502,102 @@
 msgid "Password reset requested!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:347
-#: src/components/admin/usermanagement/Userdetail.vue:348
+#: src/components/usermanagement/Userdetail.vue:346
+#: src/components/usermanagement/Userdetail.vue:347
 msgid "Password should at least be 8 char long including 1 digit and 1 special char like $"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:343
+#: src/components/usermanagement/Userdetail.vue:342
 msgid "Passwords do not match!"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:40
+#: src/components/importqueue/Importqueue.vue:40
 msgid "Pending"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:332
+#: src/components/usermanagement/Userdetail.vue:331
 msgid "Please choose a country"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:337
+#: src/components/usermanagement/Userdetail.vue:336
 msgid "Please choose a role"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:79
+#: src/components/ImportSoundingresults.vue:84
 msgid "Please enter a date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:39
+#: src/components/importschedule/Importscheduledetail.vue:167
+msgid "Please enter a Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:142
+msgid "Please enter a Password"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:44
 msgid "Please enter a projection"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:62
+#: src/components/ImportSoundingresults.vue:67
 msgid "Please enter a reference"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:413
-#: src/components/map/fairway/Profiles.vue:414
+#: src/components/importschedule/Importscheduledetail.vue:106
+msgid "Please enter a URL"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:125
+msgid "Please enter a Username"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:417
+#: src/components/fairway/Profiles.vue:418
 msgid "Please enter correct coordinates in the format: Lat,Lon,Lat,Lon"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:22
+#: src/components/importschedule/Importscheduledetail.vue:184
+msgid "Please enter SortBy"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:27
 msgid "Please select a bottleneck"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:40
-#: src/components/admin/usermanagement/Userdetail.vue:85
+#: src/components/usermanagement/Userdetail.vue:40
+#: src/components/usermanagement/Userdetail.vue:85
 msgid "Please select one"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:21
+#: src/components/Pdftool.vue:21
 msgid "portrait"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:452
+#: src/components/fairway/Profiles.vue:456
 msgid "Profile deleted!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:438
+#: src/components/fairway/Profiles.vue:442
 msgid "Profile saved!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:10
+#: src/components/fairway/Profiles.vue:10
 msgid "Profiles"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:28
+#: src/components/ImportSoundingresults.vue:33
 msgid "Projection"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:72 src/components/admin/Logs.vue:48
+#: src/components/Logs.vue:48 src/components/importqueue/Importqueue.vue:84
 msgid "Refresh"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:43
+#: src/components/importqueue/Importqueue.vue:43
 msgid "Rejected"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:237
+#: src/components/usermanagement/Userdetail.vue:236
 msgid "Repeat Password"
 msgstr ""
 
@@ -403,148 +605,241 @@
 msgid "Request password reset!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:78
+#: src/components/usermanagement/Userdetail.vue:78
 msgid "Role"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:82
+#: src/components/importschedule/Importscheduledetail.vue:465
+msgid "Saturday"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:82
 msgid "Saved cross profiles"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:36
-#: src/components/admin/importschedule/Importscheduledetail.vue:48
+#: src/components/importschedule/Importscheduledetail.vue:710
+msgid "Saved import: #"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:36
+#: src/components/importschedule/Importscheduledetail.vue:238
 msgid "Schedule"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:32
+#: src/components/importschedule/Importscheduledetail.vue:196
+msgid "Scheduled"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:32
 msgid "Select Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:25
+#: src/components/Systemconfiguration.vue:25
 msgid "Send"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:138
+#: src/components/usermanagement/Userdetail.vue:138
 msgid "Send testmail"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:56
+#: src/components/importschedule/Importscheduledetail.vue:477
+msgid "September"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:64
 msgid "Signer"
 msgstr ""
 
-#: src/components/map/Identify.vue:60
+#: src/components/importschedule/Importscheduledetail.vue:216
+msgid "Simple Schedule"
+msgstr ""
+
+#: src/components/Identify.vue:60
 msgid ""
 "Some data ©\n"
 "        <a href=\"https://www.openstreetmap.org/copyright\">%{ name }</a>\n"
 "        contributors."
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:45
+#: src/components/importschedule/Importscheduledetail.vue:176
+msgid "SortBy"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:45
 msgid "Sounding Result"
 msgstr ""
 
-#: src/components/map/Identify.vue:57
+#: src/components/Identify.vue:57
 msgid "source-code"
 msgstr ""
 
-#: src/components/Sidebar.vue:54
+#: src/components/Sidebar.vue:40
 msgid "Staging area"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:7
+#: src/components/staging/Staging.vue:7
 msgid "Staging Area"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:142
+#: src/components/fairway/Profiles.vue:142
 msgid "Start"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:268
+#: src/components/ImportSoundingresults.vue:279
 msgid "Starting import for "
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:57
+#: src/components/ImportApprovedGaugeMeasurement.vue:100
+msgid "Starting import of Approved Gauge Measurements"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:67
 msgid "State"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:85
-#: src/components/admin/usermanagement/Userdetail.vue:129
+#: src/components/importschedule/Importscheduledetail.vue:394
+#: src/components/usermanagement/Userdetail.vue:129
 msgid "Submit"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:377
+#: src/components/fairway/Profiles.vue:381
 msgid "Success"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:34
+#: src/components/importqueue/Importqueue.vue:34
 msgid "Successful"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:88
+#: src/components/importschedule/Importscheduledetail.vue:466
+msgid "Sunday"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:88
 msgid "Sysadmin"
 msgstr ""
 
-#: src/components/Sidebar.vue:57
+#: src/components/usermanagement/Usermanagement.vue:326
+msgid "System-Administrator"
+msgstr ""
+
+#: src/components/Sidebar.vue:97
 msgid "Systemadministration"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:8
+#: src/components/Systemconfiguration.vue:8
 msgid "Systemconfiguration"
 msgstr ""
 
-#: src/components/map/Identify.vue:51
+#: src/components/Identify.vue:51
 msgid ""
 "This app uses <i>gemma</i>, which is Free Software under <br/>\n"
 "        %{ license } without warranty, see docs for details."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:34
-#: src/components/map/contextbox/Staging.vue:13
+#: src/components/importschedule/Importscheduledetail.vue:463
+msgid "Thursday"
+msgstr ""
+
+#: src/components/ImportApprovedGaugeMeasurement.vue:43
+#: src/components/ImportWaterwayProfiles.vue:43
+#: src/components/importschedule/Importscheduledetail.vue:407
+msgid "Trigger import"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:461
+msgid "Tuesday"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:34
+#: src/components/staging/Staging.vue:12
 msgid "Type"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:313
+#: src/components/ImportWaterwayProfiles.vue:89
+msgid "under construction"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:738
+msgid "update import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:324
 msgid "Upload"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:55
+#: src/components/importschedule/Importscheduledetail.vue:72
+msgid "URL"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:61
 msgid "User"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:14
-#: src/components/map/contextbox/Staging.vue:16
+#: src/components/importschedule/Importscheduledetail.vue:117
+#: src/components/staging/Staging.vue:18
+#: src/components/usermanagement/Userdetail.vue:14
 msgid "Username"
 msgstr ""
 
-#: src/components/Sidebar.vue:66
-#: src/components/admin/usermanagement/Usermanagement.vue:14
+#: src/components/Sidebar.vue:108
+#: src/components/usermanagement/Usermanagement.vue:14
 msgid "Users"
 msgstr ""
 
-#: src/components/map/Identify.vue:65
+#: src/components/Identify.vue:65
 msgid ""
 "Uses\n"
 "        <a href=\"https://download.geonames.org/export/dump/readme.txt\">GeoNames</a>\n"
 "        under %{ geoLicense }."
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Usermanagement.vue:327
 msgid "Waterway Admin"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:94
+#: src/components/importschedule/Importscheduledetail.vue:28
+msgid "Waterway axis"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:43
+msgid "Waterway gauges"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:94
+#: src/components/usermanagement/Usermanagement.vue:328
 msgid "Waterway User"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:439
-#: src/components/map/fairway/Profiles.vue:440
+#: src/components/importschedule/Importscheduledetail.vue:37
+msgid "Waterwayarea"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:462
+msgid "Wednesday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:455
+msgid "week"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:246
+msgid "Weekly"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:457
+msgid "year"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:443
+#: src/components/fairway/Profiles.vue:444
 msgid "You can now select these coordinates from the \"Saved cross profiles\" menu to restore this cross profile."
 msgstr ""
 
-#: src/store/map.js:415
+#: src/store/map.js:416
 msgid "Length"
 msgstr ""
 
-#: src/store/map.js:436
+#: src/store/map.js:437
 msgid "Area"
 msgstr ""
--- a/client/src/locale/de_AT/LC_MESSAGES/app.po	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/locale/de_AT/LC_MESSAGES/app.po	Tue Jan 15 10:07:10 2019 +0100
@@ -8,11 +8,10 @@
 msgstr ""
 "Project-Id-Version: wamosjs 0.1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-12-10 15:30+0100\n"
+"POT-Creation-Date: 2019-01-15 10:04+0100\n"
 "PO-Revision-Date: 2018-12-11 17:08+0000\n"
 "Last-Translator: Sascha L. Teichmann <sascha.teichmann@intevation.de>\n"
-"Language-Team: Austrian German <https://hosted.weblate.org/projects/gemma/"
-"client/de_AT/>\n"
+"Language-Team: Austrian German <https://hosted.weblate.org/projects/gemma/client/de_AT/>\n"
 "Language: de_AT\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -20,138 +19,202 @@
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
 "X-Generator: Weblate 3.4-dev\n"
 
-#: src/components/admin/Importqueue.vue:46
+#: src/components/importschedule/Importscheduledetail.vue:452
+msgid "15 minutes"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:46
 msgid "Accepted"
 msgstr "Akzeptiert"
 
-#: src/components/admin/Logs.vue:25
+#: src/components/Logs.vue:25
 msgid "Accesslog"
 msgstr "Zugriffs-Protokoll"
 
-#: src/components/admin/usermanagement/Usermanagement.vue:103
+#: src/components/usermanagement/Usermanagement.vue:104
 msgid "Add User"
 msgstr "Benutzer hinzufügen"
 
-#: src/components/admin/importschedule/Importschedule.vue:35
+#: src/components/importschedule/Importscheduledetail.vue:472
+msgid "April"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:449
+#, fuzzy
+msgid "at"
+msgstr "Datum"
+
+#: src/components/importschedule/Importscheduledetail.vue:476
+msgid "August"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:35
 msgid "Author"
 msgstr "Autor"
 
+#: src/components/importschedule/Importscheduledetail.vue:34
+msgid "Available Fairway Depths"
+msgstr ""
+
 #: src/components/Login.vue:70
 msgid "back to login"
 msgstr "zurück zur Anmeldung"
 
-#: src/components/admin/Importqueue.vue:136
-#: src/components/admin/Systemconfiguration.vue:134
-#: src/components/admin/Systemconfiguration.vue:149
-#: src/components/admin/Systemconfiguration.vue:168
-#: src/components/admin/Systemconfiguration.vue:185
-#: src/components/admin/usermanagement/Userdetail.vue:305
-#: src/components/admin/usermanagement/Userdetail.vue:377
-#: src/components/admin/usermanagement/Usermanagement.vue:313
-#: src/components/admin/usermanagement/Usermanagement.vue:321
-#: src/components/admin/usermanagement/Usermanagement.vue:347
-#: src/components/map/Search.vue:257
-#: src/components/map/contextbox/Bottlenecks.vue:275
-#: src/components/map/contextbox/ImportSoundingresults.vue:205
-#: src/components/map/contextbox/ImportSoundingresults.vue:244
-#: src/components/map/contextbox/ImportSoundingresults.vue:275
+#: src/components/Bottlenecks.vue:274
+#: src/components/ImportApprovedGaugeMeasurement.vue:107
+#: src/components/ImportSoundingresults.vue:216
+#: src/components/ImportSoundingresults.vue:255
+#: src/components/ImportSoundingresults.vue:286 src/components/Search.vue:258
+#: src/components/Systemconfiguration.vue:114
+#: src/components/Systemconfiguration.vue:129
+#: src/components/Systemconfiguration.vue:148
+#: src/components/Systemconfiguration.vue:165
+#: src/components/importqueue/Importqueue.vue:160
+#: src/components/importqueue/Importqueue.vue:180
+#: src/components/importqueue/Importqueuedetail.vue:182
+#: src/components/importschedule/Importschedule.vue:148
+#: src/components/importschedule/Importschedule.vue:167
+#: src/components/importschedule/Importschedule.vue:176
+#: src/components/importschedule/Importschedule.vue:198
+#: src/components/importschedule/Importscheduledetail.vue:656
+#: src/components/importschedule/Importscheduledetail.vue:724
+#: src/components/importschedule/Importscheduledetail.vue:752
+#: src/components/staging/StagingDetail.vue:246
+#: src/components/usermanagement/Userdetail.vue:304
+#: src/components/usermanagement/Userdetail.vue:376
+#: src/components/usermanagement/Usermanagement.vue:298
+#: src/components/usermanagement/Usermanagement.vue:306
+#: src/components/usermanagement/Usermanagement.vue:340
+#: src/components/importschedule/Importscheduledetail.vue:716
+#: src/components/importschedule/Importscheduledetail.vue:744
 msgid "Backend Error"
 msgstr "Server-Fehler"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:11
+#: src/components/ImportSoundingresults.vue:16
 msgid "Bottleneck"
 msgstr "Seichtstelle"
 
-#: src/components/admin/Systemconfiguration.vue:19
+#: src/components/Systemconfiguration.vue:19
 msgid "Bottleneck Areas fill-color"
 msgstr "Flächenfüllfarbe Seichtstelle"
 
-#: src/components/admin/Systemconfiguration.vue:13
+#: src/components/Systemconfiguration.vue:13
 msgid "Bottleneck Areas stroke-color"
 msgstr "Flächenumrandungsfarbe Seichtstelle"
 
-#: src/components/Sidebar.vue:27
-#: src/components/map/contextbox/Bottlenecks.vue:4
+#: src/components/Bottlenecks.vue:4 src/components/Sidebar.vue:27
+#: src/components/importschedule/Importscheduledetail.vue:25
+#: src/components/staging/StagingDetail.vue:11
 msgid "Bottlenecks"
 msgstr "Seichtstellen"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:121
+#: src/components/ImportSoundingresults.vue:126
 msgid "Cancel Upload"
 msgstr "Hochladen abbrechen"
 
-#: src/components/map/contextbox/Bottlenecks.vue:30
+#: src/components/Bottlenecks.vue:30
 msgid "Chainage"
 msgstr "Stationierung"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:167
-#: src/components/map/contextbox/ImportSoundingresults.vue:181
+#: src/components/ImportSoundingresults.vue:178
+#: src/components/ImportSoundingresults.vue:192
 msgid "choose .zip- file"
 msgstr "Wählen Sie eine .zip Datei"
 
-#: src/components/map/Pdftool.vue:18
-msgid "Chose format:"
+#: src/components/ImportApprovedGaugeMeasurement.vue:76
+#: src/components/ImportWaterwayProfiles.vue:75
+msgid "choose file to upload"
+msgstr ""
+
+#: src/components/Pdftool.vue:18
+#, fuzzy
+msgid "Choose format:"
 msgstr "Format wählen:"
 
-#: src/components/map/fairway/Profiles.vue:64
+#: src/components/fairway/Profiles.vue:64
 msgid "Compare with"
 msgstr "Vergleiche mit"
 
-#: src/components/Sidebar.vue:76
+#: src/components/Sidebar.vue:116
 msgid "Configuration"
 msgstr "Konfiguration"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:316
-#: src/components/map/contextbox/Staging.vue:70
+#: src/components/ImportSoundingresults.vue:327
+#: src/components/staging/Staging.vue:33
 msgid "Confirm"
 msgstr "Bestätigen"
 
-#: src/components/map/fairway/Profiles.vue:378
+#: src/components/fairway/Profiles.vue:382
 msgid "Coordinates copied to clipboard!"
 msgstr "Koordinaten auf die Zwischenablage kopiert!"
 
-#: src/components/admin/usermanagement/Userdetail.vue:33
+#: src/components/usermanagement/Userdetail.vue:33
 msgid "Country"
 msgstr "Land"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:67
-#: src/components/map/contextbox/Staging.vue:14
+#: src/components/importschedule/Importscheduledetail.vue:382
+msgid "Cronstring"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:72
+#: src/components/importqueue/Importqueuedetail.vue:49
+#: src/components/staging/Staging.vue:13
 msgid "Date"
 msgstr "Datum"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:47
+#: src/components/importschedule/Importscheduledetail.vue:454
+msgid "day"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:480
+msgid "December"
+msgstr ""
+
+#: src/components/ImportStretches.vue:4
+msgid "Define section and stretches"
+msgstr ""
+
+#: src/components/Sidebar.vue:52
+msgid "Define sections and stretches"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:192
+msgid "Deleted import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:52
 msgid "Depthreference"
 msgstr "Tiefenreferenz"
 
-#: src/components/map/Pdftool.vue:32
+#: src/components/Pdftool.vue:36
 msgid "Download"
 msgstr "Herunterladen"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:113
+#: src/components/ImportSoundingresults.vue:118
 msgid "Download Meta.json"
 msgstr "Meta.json Herunterladen"
 
-#: src/components/admin/importschedule/Importschedule.vue:37
-#: src/components/admin/importschedule/Importscheduledetail.vue:80
+#: src/components/importschedule/Importschedule.vue:37
 msgid "Email"
 msgstr "E-Mail"
 
-#: src/components/admin/usermanagement/Userdetail.vue:59
+#: src/components/usermanagement/Userdetail.vue:59
 msgid "Email address"
 msgstr "E-Mail Adresse"
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:61
+#: src/components/importschedule/Importscheduledetail.vue:50
 msgid "Email Notification"
 msgstr "E-Mail Benachrichtigung"
 
-#: src/components/admin/Importqueue.vue:53
+#: src/components/importqueue/Importqueue.vue:55
 msgid "Enqueued"
 msgstr "Hinzugefügt"
 
-#: src/components/map/fairway/Profiles.vue:123
+#: src/components/fairway/Profiles.vue:123
 msgid "Enter coordinates manually"
 msgstr "Manuelle Koordinateneingabe"
 
-#: src/components/map/fairway/Profiles.vue:185
+#: src/components/fairway/Profiles.vue:185
 msgid "Enter label for cross profile"
 msgstr "Namen für Profilschnitt eingeben"
 
@@ -163,89 +226,162 @@
 msgid "Enter username"
 msgstr "Benutzername eingeben"
 
-#: src/components/admin/usermanagement/Userdetail.vue:386
+#: src/components/usermanagement/Userdetail.vue:385
 msgid "Error while saving user"
 msgstr "Während des Speicherns der Nutzerdaten trat ein Fehler auf"
 
-#: src/components/admin/Logs.vue:34
+#: src/components/Logs.vue:34
 msgid "Errorlog"
 msgstr "Fehlerprotokoll"
 
-#: src/components/admin/Importqueue.vue:37
+#: src/components/importschedule/Importscheduledetail.vue:445
+msgid "Every"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:37
 msgid "Failed"
 msgstr "Fehlgeschlagen"
 
+#: src/components/importschedule/Importscheduledetail.vue:40
+msgid "Fairwaydimensions"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:155
+msgid "Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:470
+msgid "February"
+msgstr ""
+
 #: src/components/Login.vue:76
 msgid "Forgot password"
 msgstr "Passwort vergessen"
 
-#: src/components/map/Pdftool.vue:10 src/components/map/Pdftool.vue:49
+#: src/components/importschedule/Importscheduledetail.vue:464
+msgid "Friday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:31
+#, fuzzy
+msgid "Gauge measurement"
+msgstr "Messung"
+
+#: src/components/Pdftool.vue:10 src/components/Pdftool.vue:53
 msgid "Generate PDF"
 msgstr "PDF generieren"
 
-#: src/components/map/Identify.vue:10
+#: src/components/importschedule/Importscheduledetail.vue:453
+msgid "hour"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:52
+msgid "Id"
+msgstr ""
+
+#: src/components/Identify.vue:10
 msgid "Identified"
 msgstr "Identifiziert"
 
-#: src/components/admin/importschedule/Importschedule.vue:33
-#: src/components/map/contextbox/ImportSoundingresults.vue:267
+#: src/components/ImportApprovedGaugeMeasurement.vue:99
+#: src/components/ImportSoundingresults.vue:278
+#: src/components/ImportWaterwayProfiles.vue:88 src/components/Sidebar.vue:56
+#: src/components/importschedule/Importschedule.vue:33
+#: src/components/importschedule/Importscheduledetail.vue:519
+#: src/components/importschedule/Importscheduledetail.vue:649
+#: src/components/importschedule/Importscheduledetail.vue:709
+#: src/components/importschedule/Importscheduledetail.vue:737
 msgid "Import"
 msgstr "Daten-Import"
 
-#: src/components/Sidebar.vue:40
+#: src/components/ImportApprovedGaugeMeasurement.vue:11
+#: src/components/Sidebar.vue:74
+msgid "Import approved gaugemeasurements"
+msgstr ""
+
+#: src/components/Sidebar.vue:64
 msgid "Import soundingresults"
 msgstr "Seichtstellenmessungen importieren"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:4
+#: src/components/ImportSoundingresults.vue:9
 msgid "Import Soundingresults"
 msgstr "Seichtstellenmessungen importieren"
 
-#: src/components/map/contextbox/Staging.vue:15
+#: src/components/Sidebar.vue:84
+msgid "Import waterway profiles"
+msgstr ""
+
+#: src/components/ImportWaterwayProfiles.vue:11
+#, fuzzy
+msgid "Import Waterwayprofiles"
+msgstr "Art des Imports"
+
+#: src/components/staging/Staging.vue:15
 msgid "Imported"
 msgstr "Importiert"
 
-#: src/components/Sidebar.vue:92 src/components/admin/Importqueue.vue:9
+#: src/components/Sidebar.vue:134 src/components/importqueue/Importqueue.vue:9
 msgid "Importqueue"
 msgstr "Import-Warteschlange"
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:20
+#: src/components/Sidebar.vue:94
+#: src/components/importschedule/Importschedule.vue:9
+#: src/components/importschedule/Importschedule.vue:160
+#: src/components/importschedule/Importschedule.vue:191
+#: src/components/importschedule/Importscheduledetail.vue:20
 msgid "Imports"
 msgstr "Daten-Import"
 
-#: src/components/Sidebar.vue:100
-#: src/components/admin/importschedule/Importschedule.vue:9
-msgid "Importschedule"
-msgstr "Import-Zeitplan"
+#: src/components/importschedule/Importscheduledetail.vue:81
+msgid "Insecure"
+msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:34
-msgid "Importtype"
-msgstr "Art des Imports"
-
-#: src/components/admin/usermanagement/Userdetail.vue:354
+#: src/components/usermanagement/Userdetail.vue:353
 msgid "invalid email"
 msgstr "Ungültige E-Mail"
 
-#: src/components/map/fairway/Profiles.vue:412
+#: src/components/fairway/Profiles.vue:416
 msgid "Invalid input"
 msgstr "Ungültige Eingabe"
 
-#: src/components/admin/Importqueue.vue:54
+#: src/components/Pdftool.vue:24
+msgid "ISO A3"
+msgstr ""
+
+#: src/components/Pdftool.vue:25
+msgid "ISO A4"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:469
+msgid "January"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:475
+msgid "July"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:474
+msgid "June"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:58
+#: src/components/importqueue/Importqueuedetail.vue:45
 msgid "Kind"
 msgstr "Art"
 
-#: src/components/map/Pdftool.vue:20
+#: src/components/Pdftool.vue:20
 msgid "landscape"
 msgstr "Querformat"
 
-#: src/components/admin/Logs.vue:41
+#: src/components/Logs.vue:41
 msgid "Last refresh:"
 msgstr "Letzter Abgleich:"
 
-#: src/components/map/contextbox/Bottlenecks.vue:19
+#: src/components/Bottlenecks.vue:19
 msgid "Latest"
 msgstr "Neuste"
 
-#: src/components/map/layers/Layers.vue:10
+#: src/components/layers/Layers.vue:10
 msgid "Layers"
 msgstr "Ebenen"
 
@@ -257,65 +393,116 @@
 msgid "Login failed"
 msgstr "Login fehlgeschlagen"
 
-#: src/components/Sidebar.vue:110
+#: src/components/Sidebar.vue:144
 msgid "Logout"
 msgstr "Abmelden"
 
-#: src/components/Sidebar.vue:84 src/components/admin/Logs.vue:9
+#: src/components/Logs.vue:9 src/components/Sidebar.vue:124
 msgid "Logs"
 msgstr "Protokolle"
 
-#: src/components/admin/usermanagement/Userdetail.vue:140
+#: src/components/usermanagement/Userdetail.vue:140
 msgid "Mail was sent"
 msgstr "E-Mail wurde gesendet"
 
+#: src/components/importschedule/Importschedule.vue:161
+#: src/components/importschedule/Importscheduledetail.vue:650
+msgid "Manually triggered import: #"
+msgstr ""
+
 #: src/components/Sidebar.vue:15
 msgid "Map"
 msgstr "Karte"
 
-#: src/components/map/contextbox/Bottlenecks.vue:20
+#: src/components/importschedule/Importscheduledetail.vue:471
+msgid "March"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:473
+#, fuzzy
+msgid "May"
+msgstr "Karte"
+
+#: src/components/Bottlenecks.vue:20
 msgid "Measurement"
 msgstr "Messung"
 
-#: src/components/map/contextbox/Bottlenecks.vue:9
-#: src/components/map/contextbox/Staging.vue:12
+#: src/components/importqueue/Importqueuedetail.vue:58
+msgid "Message"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:446
+msgid "minutes past"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:460
+msgid "Monday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:456
+msgid "month"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:247
+msgid "Monthly"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:9 src/components/staging/Staging.vue:11
 msgid "Name"
 msgstr "Name"
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:9
-msgid "New import"
-msgstr "Neuer Import"
-
-#: src/components/admin/importschedule/Importschedule.vue:72
+#: src/components/importschedule/Importschedule.vue:93
+#: src/components/importschedule/Importscheduledetail.vue:520
 msgid "New Import"
 msgstr "Neuer Import"
 
-#: src/components/map/Identify.vue:47
+#: src/components/Identify.vue:47
 msgid "No features identified."
 msgstr "Keine Objekte identifiziert."
 
-#: src/components/map/contextbox/Bottlenecks.vue:116
-#: src/components/map/contextbox/Staging.vue:63
+#: src/components/Bottlenecks.vue:115 src/components/staging/Staging.vue:36
 msgid "No results."
 msgstr "Keine Ergebnisse."
 
-#: src/components/admin/importschedule/Importschedule.vue:66
-msgid "No schedules"
+#: src/components/importschedule/Importschedule.vue:85
+#, fuzzy
+msgid "No scheduled imports"
 msgstr "Keine Pläne"
 
-#: src/components/map/Pdftool.vue:41
+#: src/components/importschedule/Importscheduledetail.vue:479
+msgid "November"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:450
+msgid "o' clock"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:478
+msgid "October"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:448
+msgid "of"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:447
+msgid "on"
+msgstr ""
+
+#: src/components/Pdftool.vue:45
 msgid "Open in new window"
 msgstr "In neuem Fenster öffnen"
 
-#: src/components/admin/usermanagement/Userdetail.vue:238
+#: src/components/usermanagement/Userdetail.vue:237
 msgid "password"
 msgstr "Passwort"
 
-#: src/components/admin/usermanagement/Userdetail.vue:236
+#: src/components/importschedule/Importscheduledetail.vue:134
+#: src/components/usermanagement/Userdetail.vue:235
 msgid "Password"
 msgstr "Passwort"
 
-#: src/components/admin/usermanagement/Userdetail.vue:239
+#: src/components/usermanagement/Userdetail.vue:238
 msgid "password again"
 msgstr "Noch einmal das Passwort"
 
@@ -323,82 +510,107 @@
 msgid "Password reset requested!"
 msgstr "Passwort Zurücksetzung angefragt!"
 
-#: src/components/admin/usermanagement/Userdetail.vue:347
-#: src/components/admin/usermanagement/Userdetail.vue:348
+#: src/components/usermanagement/Userdetail.vue:346
+#: src/components/usermanagement/Userdetail.vue:347
 msgid "Password should at least be 8 char long including 1 digit and 1 special char like $"
 msgstr "Das Passwort sollte mindestens 8 Zeichen lang sein, eine Zahlenziffer und ein Sonderzeichen wie etwa $ enthalten"
 
-#: src/components/admin/usermanagement/Userdetail.vue:343
+#: src/components/usermanagement/Userdetail.vue:342
 msgid "Passwords do not match!"
 msgstr "Die Passwörter stimmen nicht überein!"
 
-#: src/components/admin/Importqueue.vue:40
+#: src/components/importqueue/Importqueue.vue:40
 msgid "Pending"
 msgstr "Ausstehend"
 
-#: src/components/admin/usermanagement/Userdetail.vue:332
+#: src/components/usermanagement/Userdetail.vue:331
 msgid "Please choose a country"
 msgstr "Bitte wählen Sie ein Land aus"
 
-#: src/components/admin/usermanagement/Userdetail.vue:337
+#: src/components/usermanagement/Userdetail.vue:336
 msgid "Please choose a role"
 msgstr "Bitte wählen Sie eine Rolle aus"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:79
+#: src/components/ImportSoundingresults.vue:84
 msgid "Please enter a date"
 msgstr "Bitte ein Datum eingeben"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:39
+#: src/components/importschedule/Importscheduledetail.vue:167
+#, fuzzy
+msgid "Please enter a Featuretype"
+msgstr "Bitte ein Datum eingeben"
+
+#: src/components/importschedule/Importscheduledetail.vue:142
+#, fuzzy
+msgid "Please enter a Password"
+msgstr "Bitte ein Datum eingeben"
+
+#: src/components/ImportSoundingresults.vue:44
 msgid "Please enter a projection"
 msgstr "Bitte eine Projektion eingeben"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:62
+#: src/components/ImportSoundingresults.vue:67
 msgid "Please enter a reference"
 msgstr "Bitte ein Höhenreferenzsystem eingeben"
 
-#: src/components/map/fairway/Profiles.vue:413
-#: src/components/map/fairway/Profiles.vue:414
+#: src/components/importschedule/Importscheduledetail.vue:106
+#, fuzzy
+msgid "Please enter a URL"
+msgstr "Bitte ein Datum eingeben"
+
+#: src/components/importschedule/Importscheduledetail.vue:125
+#, fuzzy
+msgid "Please enter a Username"
+msgstr "Bitte ein Datum eingeben"
+
+#: src/components/fairway/Profiles.vue:417
+#: src/components/fairway/Profiles.vue:418
 msgid "Please enter correct coordinates in the format: Lat,Lon,Lat,Lon"
 msgstr "Bitte geben Sie die Koordinaten in folgendem Format an: Lat,Lon,Lat,Lon"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:22
+#: src/components/importschedule/Importscheduledetail.vue:184
+#, fuzzy
+msgid "Please enter SortBy"
+msgstr "Bitte ein Datum eingeben"
+
+#: src/components/ImportSoundingresults.vue:27
 msgid "Please select a bottleneck"
 msgstr "Bitte eine Seichtstelle wählen"
 
-#: src/components/admin/usermanagement/Userdetail.vue:40
-#: src/components/admin/usermanagement/Userdetail.vue:85
+#: src/components/usermanagement/Userdetail.vue:40
+#: src/components/usermanagement/Userdetail.vue:85
 msgid "Please select one"
 msgstr "Bitte auswählen"
 
-#: src/components/map/Pdftool.vue:21
+#: src/components/Pdftool.vue:21
 msgid "portrait"
 msgstr "Hochformat"
 
-#: src/components/map/fairway/Profiles.vue:452
+#: src/components/fairway/Profiles.vue:456
 msgid "Profile deleted!"
 msgstr "Profil gelöscht!"
 
-#: src/components/map/fairway/Profiles.vue:438
+#: src/components/fairway/Profiles.vue:442
 msgid "Profile saved!"
 msgstr "Profil gespeichert!"
 
-#: src/components/map/fairway/Profiles.vue:10
+#: src/components/fairway/Profiles.vue:10
 msgid "Profiles"
 msgstr "Profile"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:28
+#: src/components/ImportSoundingresults.vue:33
 msgid "Projection"
 msgstr "Projektion"
 
-#: src/components/admin/Importqueue.vue:72 src/components/admin/Logs.vue:48
+#: src/components/Logs.vue:48 src/components/importqueue/Importqueue.vue:84
 msgid "Refresh"
 msgstr "Aktualisieren"
 
-#: src/components/admin/Importqueue.vue:43
+#: src/components/importqueue/Importqueue.vue:43
 msgid "Rejected"
 msgstr "Abgelehnt"
 
-#: src/components/admin/usermanagement/Userdetail.vue:237
+#: src/components/usermanagement/Userdetail.vue:236
 msgid "Repeat Password"
 msgstr "Passwort erneut eingeben"
 
@@ -406,148 +618,250 @@
 msgid "Request password reset!"
 msgstr "Passwort-Zurücksetzung anfragen!"
 
-#: src/components/admin/usermanagement/Userdetail.vue:78
+#: src/components/usermanagement/Userdetail.vue:78
 msgid "Role"
 msgstr "Rolle"
 
-#: src/components/map/fairway/Profiles.vue:82
+#: src/components/importschedule/Importscheduledetail.vue:465
+msgid "Saturday"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:82
 msgid "Saved cross profiles"
 msgstr "Gespeicherte Profile"
 
-#: src/components/admin/importschedule/Importschedule.vue:36
-#: src/components/admin/importschedule/Importscheduledetail.vue:48
+#: src/components/importschedule/Importscheduledetail.vue:710
+#, fuzzy
+msgid "Saved import: #"
+msgstr "Neuer Import"
+
+#: src/components/importschedule/Importschedule.vue:36
+#: src/components/importschedule/Importscheduledetail.vue:238
 msgid "Schedule"
 msgstr "Zeitplan"
 
-#: src/components/map/fairway/Profiles.vue:32
+#: src/components/importschedule/Importscheduledetail.vue:196
+#, fuzzy
+msgid "Scheduled"
+msgstr "Zeitplan"
+
+#: src/components/fairway/Profiles.vue:32
 msgid "Select Bottleneck"
 msgstr "Wähle Seichtstelle"
 
-#: src/components/admin/Systemconfiguration.vue:25
+#: src/components/Systemconfiguration.vue:25
 msgid "Send"
 msgstr "Absenden"
 
-#: src/components/admin/usermanagement/Userdetail.vue:138
+#: src/components/usermanagement/Userdetail.vue:138
 msgid "Send testmail"
 msgstr "Test-E-Mail versenden"
 
-#: src/components/admin/Importqueue.vue:56
+#: src/components/importschedule/Importscheduledetail.vue:477
+msgid "September"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:64
 msgid "Signer"
 msgstr "Überprüft durch"
 
-#: src/components/map/Identify.vue:60
+#: src/components/importschedule/Importscheduledetail.vue:216
+#, fuzzy
+msgid "Simple Schedule"
+msgstr "Zeitplan"
+
+#: src/components/Identify.vue:60
 msgid ""
 "Some data ©\n"
 "        <a href=\"https://www.openstreetmap.org/copyright\">%{ name }</a>\n"
 "        contributors."
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:45
+#: src/components/importschedule/Importscheduledetail.vue:176
+msgid "SortBy"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:45
 msgid "Sounding Result"
 msgstr "Seichtstellenvermessung"
 
-#: src/components/map/Identify.vue:57
+#: src/components/Identify.vue:57
 msgid "source-code"
 msgstr "Quelltext"
 
-#: src/components/Sidebar.vue:54
+#: src/components/Sidebar.vue:40
 msgid "Staging area"
 msgstr "Import-Überprüfung"
 
-#: src/components/map/contextbox/Staging.vue:7
+#: src/components/staging/Staging.vue:7
 msgid "Staging Area"
 msgstr "Import-Überprüfung"
 
-#: src/components/map/fairway/Profiles.vue:142
+#: src/components/fairway/Profiles.vue:142
 msgid "Start"
 msgstr "Start"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:268
+#: src/components/ImportSoundingresults.vue:279
 msgid "Starting import for "
 msgstr "Import gestartet "
 
-#: src/components/admin/Importqueue.vue:57
+#: src/components/ImportApprovedGaugeMeasurement.vue:100
+msgid "Starting import of Approved Gauge Measurements"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:67
 msgid "State"
 msgstr "Zustand"
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:85
-#: src/components/admin/usermanagement/Userdetail.vue:129
+#: src/components/importschedule/Importscheduledetail.vue:394
+#: src/components/usermanagement/Userdetail.vue:129
 msgid "Submit"
 msgstr "Abschicken"
 
-#: src/components/map/fairway/Profiles.vue:377
+#: src/components/fairway/Profiles.vue:381
 msgid "Success"
 msgstr "Erfolg"
 
-#: src/components/admin/Importqueue.vue:34
+#: src/components/importqueue/Importqueue.vue:34
 msgid "Successful"
 msgstr "Erfolgreich"
 
-#: src/components/admin/usermanagement/Userdetail.vue:88
+#: src/components/importschedule/Importscheduledetail.vue:466
+msgid "Sunday"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:88
 msgid "Sysadmin"
 msgstr "Sys-Admin"
 
-#: src/components/Sidebar.vue:57
+#: src/components/usermanagement/Usermanagement.vue:326
+#, fuzzy
+msgid "System-Administrator"
+msgstr "System-Administration"
+
+#: src/components/Sidebar.vue:97
 msgid "Systemadministration"
 msgstr "System-Administration"
 
-#: src/components/admin/Systemconfiguration.vue:8
+#: src/components/Systemconfiguration.vue:8
 msgid "Systemconfiguration"
 msgstr "System-Konfiguation"
 
-#: src/components/map/Identify.vue:51
+#: src/components/Identify.vue:51
 msgid ""
 "This app uses <i>gemma</i>, which is Free Software under <br/>\n"
 "        %{ license } without warranty, see docs for details."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:34
-#: src/components/map/contextbox/Staging.vue:13
+#: src/components/importschedule/Importscheduledetail.vue:463
+msgid "Thursday"
+msgstr ""
+
+#: src/components/ImportApprovedGaugeMeasurement.vue:43
+#: src/components/ImportWaterwayProfiles.vue:43
+#: src/components/importschedule/Importscheduledetail.vue:407
+#, fuzzy
+msgid "Trigger import"
+msgstr "Neuer Import"
+
+#: src/components/importschedule/Importscheduledetail.vue:461
+msgid "Tuesday"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:34
+#: src/components/staging/Staging.vue:12
 msgid "Type"
 msgstr "Typ"
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:313
+#: src/components/ImportWaterwayProfiles.vue:89
+msgid "under construction"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:738
+#, fuzzy
+msgid "update import: #"
+msgstr "Neuer Import"
+
+#: src/components/ImportSoundingresults.vue:324
 msgid "Upload"
 msgstr "Hochladen"
 
-#: src/components/admin/Importqueue.vue:55
+#: src/components/importschedule/Importscheduledetail.vue:72
+msgid "URL"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:61
 msgid "User"
 msgstr "Benutzer"
 
-#: src/components/admin/usermanagement/Userdetail.vue:14
-#: src/components/map/contextbox/Staging.vue:16
+#: src/components/importschedule/Importscheduledetail.vue:117
+#: src/components/staging/Staging.vue:18
+#: src/components/usermanagement/Userdetail.vue:14
 msgid "Username"
 msgstr "Benutzername"
 
-#: src/components/Sidebar.vue:66
-#: src/components/admin/usermanagement/Usermanagement.vue:14
+#: src/components/Sidebar.vue:108
+#: src/components/usermanagement/Usermanagement.vue:14
 msgid "Users"
 msgstr "Benutzer"
 
-#: src/components/map/Identify.vue:65
+#: src/components/Identify.vue:65
 msgid ""
 "Uses\n"
 "        <a href=\"https://download.geonames.org/export/dump/readme.txt\">GeoNames</a>\n"
 "        under %{ geoLicense }."
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Usermanagement.vue:327
 msgid "Waterway Admin"
 msgstr "Waterway-Admin"
 
-#: src/components/admin/usermanagement/Userdetail.vue:94
+#: src/components/importschedule/Importscheduledetail.vue:28
+#, fuzzy
+msgid "Waterway axis"
+msgstr "Waterway-Benutzer"
+
+#: src/components/importschedule/Importscheduledetail.vue:43
+#, fuzzy
+msgid "Waterway gauges"
+msgstr "Waterway-Benutzer"
+
+#: src/components/usermanagement/Userdetail.vue:94
+#: src/components/usermanagement/Usermanagement.vue:328
 msgid "Waterway User"
 msgstr "Waterway-Benutzer"
 
-#: src/components/map/fairway/Profiles.vue:439
-#: src/components/map/fairway/Profiles.vue:440
+#: src/components/importschedule/Importscheduledetail.vue:37
+#, fuzzy
+msgid "Waterwayarea"
+msgstr "Waterway-Benutzer"
+
+#: src/components/importschedule/Importscheduledetail.vue:462
+msgid "Wednesday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:455
+msgid "week"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:246
+msgid "Weekly"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:457
+msgid "year"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:443
+#: src/components/fairway/Profiles.vue:444
 msgid "You can now select these coordinates from the \"Saved cross profiles\" menu to restore this cross profile."
 msgstr "Sie können diese Koordinaten aus dem \"Gespeicherte Profile\"-Menü auswählen, um diesen Profilschnitt wieder herzustellen."
 
-#: src/store/map.js:415
+#: src/store/map.js:416
 msgid "Length"
 msgstr "Länge"
 
-#: src/store/map.js:436
+#: src/store/map.js:437
 msgid "Area"
 msgstr "Fläche"
--- a/client/src/locale/en_GB/LC_MESSAGES/app.po	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/locale/en_GB/LC_MESSAGES/app.po	Tue Jan 15 10:07:10 2019 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: wamosjs 0.1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-12-10 15:30+0100\n"
+"POT-Creation-Date: 2019-01-15 10:04+0100\n"
 "PO-Revision-Date: 2018-07-03 17:18+0200\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -17,138 +17,200 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/components/admin/Importqueue.vue:46
+#: src/components/importschedule/Importscheduledetail.vue:452
+msgid "15 minutes"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:46
 msgid "Accepted"
 msgstr ""
 
-#: src/components/admin/Logs.vue:25
+#: src/components/Logs.vue:25
 msgid "Accesslog"
 msgstr ""
 
-#: src/components/admin/usermanagement/Usermanagement.vue:103
+#: src/components/usermanagement/Usermanagement.vue:104
 msgid "Add User"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:35
+#: src/components/importschedule/Importscheduledetail.vue:472
+msgid "April"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:449
+msgid "at"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:476
+msgid "August"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:35
 msgid "Author"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:34
+msgid "Available Fairway Depths"
+msgstr ""
+
 #: src/components/Login.vue:70
 msgid "back to login"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:136
-#: src/components/admin/Systemconfiguration.vue:134
-#: src/components/admin/Systemconfiguration.vue:149
-#: src/components/admin/Systemconfiguration.vue:168
-#: src/components/admin/Systemconfiguration.vue:185
-#: src/components/admin/usermanagement/Userdetail.vue:305
-#: src/components/admin/usermanagement/Userdetail.vue:377
-#: src/components/admin/usermanagement/Usermanagement.vue:313
-#: src/components/admin/usermanagement/Usermanagement.vue:321
-#: src/components/admin/usermanagement/Usermanagement.vue:347
-#: src/components/map/Search.vue:257
-#: src/components/map/contextbox/Bottlenecks.vue:275
-#: src/components/map/contextbox/ImportSoundingresults.vue:205
-#: src/components/map/contextbox/ImportSoundingresults.vue:244
-#: src/components/map/contextbox/ImportSoundingresults.vue:275
+#: src/components/Bottlenecks.vue:274
+#: src/components/ImportApprovedGaugeMeasurement.vue:107
+#: src/components/ImportSoundingresults.vue:216
+#: src/components/ImportSoundingresults.vue:255
+#: src/components/ImportSoundingresults.vue:286 src/components/Search.vue:258
+#: src/components/Systemconfiguration.vue:114
+#: src/components/Systemconfiguration.vue:129
+#: src/components/Systemconfiguration.vue:148
+#: src/components/Systemconfiguration.vue:165
+#: src/components/importqueue/Importqueue.vue:160
+#: src/components/importqueue/Importqueue.vue:180
+#: src/components/importqueue/Importqueuedetail.vue:182
+#: src/components/importschedule/Importschedule.vue:148
+#: src/components/importschedule/Importschedule.vue:167
+#: src/components/importschedule/Importschedule.vue:176
+#: src/components/importschedule/Importschedule.vue:198
+#: src/components/importschedule/Importscheduledetail.vue:656
+#: src/components/importschedule/Importscheduledetail.vue:724
+#: src/components/importschedule/Importscheduledetail.vue:752
+#: src/components/staging/StagingDetail.vue:246
+#: src/components/usermanagement/Userdetail.vue:304
+#: src/components/usermanagement/Userdetail.vue:376
+#: src/components/usermanagement/Usermanagement.vue:298
+#: src/components/usermanagement/Usermanagement.vue:306
+#: src/components/usermanagement/Usermanagement.vue:340
+#: src/components/importschedule/Importscheduledetail.vue:716
+#: src/components/importschedule/Importscheduledetail.vue:744
 msgid "Backend Error"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:11
+#: src/components/ImportSoundingresults.vue:16
 msgid "Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:19
+#: src/components/Systemconfiguration.vue:19
 msgid "Bottleneck Areas fill-color"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:13
+#: src/components/Systemconfiguration.vue:13
 msgid "Bottleneck Areas stroke-color"
 msgstr ""
 
-#: src/components/Sidebar.vue:27
-#: src/components/map/contextbox/Bottlenecks.vue:4
+#: src/components/Bottlenecks.vue:4 src/components/Sidebar.vue:27
+#: src/components/importschedule/Importscheduledetail.vue:25
+#: src/components/staging/StagingDetail.vue:11
 msgid "Bottlenecks"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:121
+#: src/components/ImportSoundingresults.vue:126
 msgid "Cancel Upload"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:30
+#: src/components/Bottlenecks.vue:30
 msgid "Chainage"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:167
-#: src/components/map/contextbox/ImportSoundingresults.vue:181
+#: src/components/ImportSoundingresults.vue:178
+#: src/components/ImportSoundingresults.vue:192
 msgid "choose .zip- file"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:18
-msgid "Chose format:"
+#: src/components/ImportApprovedGaugeMeasurement.vue:76
+#: src/components/ImportWaterwayProfiles.vue:75
+msgid "choose file to upload"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:64
+#: src/components/Pdftool.vue:18
+msgid "Choose format:"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:64
 msgid "Compare with"
 msgstr ""
 
-#: src/components/Sidebar.vue:76
+#: src/components/Sidebar.vue:116
 msgid "Configuration"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:316
-#: src/components/map/contextbox/Staging.vue:70
+#: src/components/ImportSoundingresults.vue:327
+#: src/components/staging/Staging.vue:33
 msgid "Confirm"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:378
+#: src/components/fairway/Profiles.vue:382
 msgid "Coordinates copied to clipboard!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:33
+#: src/components/usermanagement/Userdetail.vue:33
 msgid "Country"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:67
-#: src/components/map/contextbox/Staging.vue:14
+#: src/components/importschedule/Importscheduledetail.vue:382
+msgid "Cronstring"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:72
+#: src/components/importqueue/Importqueuedetail.vue:49
+#: src/components/staging/Staging.vue:13
 msgid "Date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:47
+#: src/components/importschedule/Importscheduledetail.vue:454
+msgid "day"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:480
+msgid "December"
+msgstr ""
+
+#: src/components/ImportStretches.vue:4
+msgid "Define section and stretches"
+msgstr ""
+
+#: src/components/Sidebar.vue:52
+msgid "Define sections and stretches"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:192
+msgid "Deleted import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:52
 msgid "Depthreference"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:32
+#: src/components/Pdftool.vue:36
 msgid "Download"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:113
+#: src/components/ImportSoundingresults.vue:118
 msgid "Download Meta.json"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:37
-#: src/components/admin/importschedule/Importscheduledetail.vue:80
+#: src/components/importschedule/Importschedule.vue:37
 msgid "Email"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:59
+#: src/components/usermanagement/Userdetail.vue:59
 msgid "Email address"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:61
+#: src/components/importschedule/Importscheduledetail.vue:50
 msgid "Email Notification"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:53
+#: src/components/importqueue/Importqueue.vue:55
 msgid "Enqueued"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:123
+#: src/components/fairway/Profiles.vue:123
 msgid "Enter coordinates manually"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:185
+#: src/components/fairway/Profiles.vue:185
 msgid "Enter label for cross profile"
 msgstr ""
 
@@ -160,89 +222,160 @@
 msgid "Enter username"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:386
+#: src/components/usermanagement/Userdetail.vue:385
 msgid "Error while saving user"
 msgstr ""
 
-#: src/components/admin/Logs.vue:34
+#: src/components/Logs.vue:34
 msgid "Errorlog"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:37
+#: src/components/importschedule/Importscheduledetail.vue:445
+msgid "Every"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:37
 msgid "Failed"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:40
+msgid "Fairwaydimensions"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:155
+msgid "Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:470
+msgid "February"
+msgstr ""
+
 #: src/components/Login.vue:76
 msgid "Forgot password"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:10 src/components/map/Pdftool.vue:49
+#: src/components/importschedule/Importscheduledetail.vue:464
+msgid "Friday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:31
+msgid "Gauge measurement"
+msgstr ""
+
+#: src/components/Pdftool.vue:10 src/components/Pdftool.vue:53
 msgid "Generate PDF"
 msgstr ""
 
-#: src/components/map/Identify.vue:10
+#: src/components/importschedule/Importscheduledetail.vue:453
+msgid "hour"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:52
+msgid "Id"
+msgstr ""
+
+#: src/components/Identify.vue:10
 msgid "Identified"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:33
-#: src/components/map/contextbox/ImportSoundingresults.vue:267
+#: src/components/ImportApprovedGaugeMeasurement.vue:99
+#: src/components/ImportSoundingresults.vue:278
+#: src/components/ImportWaterwayProfiles.vue:88 src/components/Sidebar.vue:56
+#: src/components/importschedule/Importschedule.vue:33
+#: src/components/importschedule/Importscheduledetail.vue:519
+#: src/components/importschedule/Importscheduledetail.vue:649
+#: src/components/importschedule/Importscheduledetail.vue:709
+#: src/components/importschedule/Importscheduledetail.vue:737
 msgid "Import"
 msgstr ""
 
-#: src/components/Sidebar.vue:40
+#: src/components/ImportApprovedGaugeMeasurement.vue:11
+#: src/components/Sidebar.vue:74
+msgid "Import approved gaugemeasurements"
+msgstr ""
+
+#: src/components/Sidebar.vue:64
 msgid "Import soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:4
+#: src/components/ImportSoundingresults.vue:9
 msgid "Import Soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:15
+#: src/components/Sidebar.vue:84
+msgid "Import waterway profiles"
+msgstr ""
+
+#: src/components/ImportWaterwayProfiles.vue:11
+msgid "Import Waterwayprofiles"
+msgstr ""
+
+#: src/components/staging/Staging.vue:15
 msgid "Imported"
 msgstr ""
 
-#: src/components/Sidebar.vue:92 src/components/admin/Importqueue.vue:9
+#: src/components/Sidebar.vue:134 src/components/importqueue/Importqueue.vue:9
 msgid "Importqueue"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:20
+#: src/components/Sidebar.vue:94
+#: src/components/importschedule/Importschedule.vue:9
+#: src/components/importschedule/Importschedule.vue:160
+#: src/components/importschedule/Importschedule.vue:191
+#: src/components/importschedule/Importscheduledetail.vue:20
 msgid "Imports"
 msgstr ""
 
-#: src/components/Sidebar.vue:100
-#: src/components/admin/importschedule/Importschedule.vue:9
-msgid "Importschedule"
+#: src/components/importschedule/Importscheduledetail.vue:81
+msgid "Insecure"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:34
-msgid "Importtype"
-msgstr ""
-
-#: src/components/admin/usermanagement/Userdetail.vue:354
+#: src/components/usermanagement/Userdetail.vue:353
 msgid "invalid email"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:412
+#: src/components/fairway/Profiles.vue:416
 msgid "Invalid input"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:54
+#: src/components/Pdftool.vue:24
+msgid "ISO A3"
+msgstr ""
+
+#: src/components/Pdftool.vue:25
+msgid "ISO A4"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:469
+msgid "January"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:475
+msgid "July"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:474
+msgid "June"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:58
+#: src/components/importqueue/Importqueuedetail.vue:45
 msgid "Kind"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:20
+#: src/components/Pdftool.vue:20
 msgid "landscape"
 msgstr ""
 
-#: src/components/admin/Logs.vue:41
+#: src/components/Logs.vue:41
 msgid "Last refresh:"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:19
+#: src/components/Bottlenecks.vue:19
 msgid "Latest"
 msgstr ""
 
-#: src/components/map/layers/Layers.vue:10
+#: src/components/layers/Layers.vue:10
 msgid "Layers"
 msgstr ""
 
@@ -254,65 +387,114 @@
 msgid "Login failed"
 msgstr ""
 
-#: src/components/Sidebar.vue:110
+#: src/components/Sidebar.vue:144
 msgid "Logout"
 msgstr ""
 
-#: src/components/Sidebar.vue:84 src/components/admin/Logs.vue:9
+#: src/components/Logs.vue:9 src/components/Sidebar.vue:124
 msgid "Logs"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:140
+#: src/components/usermanagement/Userdetail.vue:140
 msgid "Mail was sent"
 msgstr ""
 
+#: src/components/importschedule/Importschedule.vue:161
+#: src/components/importschedule/Importscheduledetail.vue:650
+msgid "Manually triggered import: #"
+msgstr ""
+
 #: src/components/Sidebar.vue:15
 msgid "Map"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:20
+#: src/components/importschedule/Importscheduledetail.vue:471
+msgid "March"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:473
+msgid "May"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:20
 msgid "Measurement"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:9
-#: src/components/map/contextbox/Staging.vue:12
+#: src/components/importqueue/Importqueuedetail.vue:58
+msgid "Message"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:446
+msgid "minutes past"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:460
+msgid "Monday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:456
+msgid "month"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:247
+msgid "Monthly"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:9 src/components/staging/Staging.vue:11
 msgid "Name"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:9
-msgid "New import"
-msgstr ""
-
-#: src/components/admin/importschedule/Importschedule.vue:72
+#: src/components/importschedule/Importschedule.vue:93
+#: src/components/importschedule/Importscheduledetail.vue:520
 msgid "New Import"
 msgstr ""
 
-#: src/components/map/Identify.vue:47
+#: src/components/Identify.vue:47
 msgid "No features identified."
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:116
-#: src/components/map/contextbox/Staging.vue:63
+#: src/components/Bottlenecks.vue:115 src/components/staging/Staging.vue:36
 msgid "No results."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:66
-msgid "No schedules"
+#: src/components/importschedule/Importschedule.vue:85
+msgid "No scheduled imports"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:479
+msgid "November"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:450
+msgid "o' clock"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:41
+#: src/components/importschedule/Importscheduledetail.vue:478
+msgid "October"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:448
+msgid "of"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:447
+msgid "on"
+msgstr ""
+
+#: src/components/Pdftool.vue:45
 msgid "Open in new window"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:238
+#: src/components/usermanagement/Userdetail.vue:237
 msgid "password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:236
+#: src/components/importschedule/Importscheduledetail.vue:134
+#: src/components/usermanagement/Userdetail.vue:235
 msgid "Password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:239
+#: src/components/usermanagement/Userdetail.vue:238
 msgid "password again"
 msgstr ""
 
@@ -320,82 +502,102 @@
 msgid "Password reset requested!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:347
-#: src/components/admin/usermanagement/Userdetail.vue:348
+#: src/components/usermanagement/Userdetail.vue:346
+#: src/components/usermanagement/Userdetail.vue:347
 msgid "Password should at least be 8 char long including 1 digit and 1 special char like $"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:343
+#: src/components/usermanagement/Userdetail.vue:342
 msgid "Passwords do not match!"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:40
+#: src/components/importqueue/Importqueue.vue:40
 msgid "Pending"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:332
+#: src/components/usermanagement/Userdetail.vue:331
 msgid "Please choose a country"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:337
+#: src/components/usermanagement/Userdetail.vue:336
 msgid "Please choose a role"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:79
+#: src/components/ImportSoundingresults.vue:84
 msgid "Please enter a date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:39
+#: src/components/importschedule/Importscheduledetail.vue:167
+msgid "Please enter a Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:142
+msgid "Please enter a Password"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:44
 msgid "Please enter a projection"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:62
+#: src/components/ImportSoundingresults.vue:67
 msgid "Please enter a reference"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:413
-#: src/components/map/fairway/Profiles.vue:414
+#: src/components/importschedule/Importscheduledetail.vue:106
+msgid "Please enter a URL"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:125
+msgid "Please enter a Username"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:417
+#: src/components/fairway/Profiles.vue:418
 msgid "Please enter correct coordinates in the format: Lat,Lon,Lat,Lon"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:22
+#: src/components/importschedule/Importscheduledetail.vue:184
+msgid "Please enter SortBy"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:27
 msgid "Please select a bottleneck"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:40
-#: src/components/admin/usermanagement/Userdetail.vue:85
+#: src/components/usermanagement/Userdetail.vue:40
+#: src/components/usermanagement/Userdetail.vue:85
 msgid "Please select one"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:21
+#: src/components/Pdftool.vue:21
 msgid "portrait"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:452
+#: src/components/fairway/Profiles.vue:456
 msgid "Profile deleted!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:438
+#: src/components/fairway/Profiles.vue:442
 msgid "Profile saved!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:10
+#: src/components/fairway/Profiles.vue:10
 msgid "Profiles"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:28
+#: src/components/ImportSoundingresults.vue:33
 msgid "Projection"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:72 src/components/admin/Logs.vue:48
+#: src/components/Logs.vue:48 src/components/importqueue/Importqueue.vue:84
 msgid "Refresh"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:43
+#: src/components/importqueue/Importqueue.vue:43
 msgid "Rejected"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:237
+#: src/components/usermanagement/Userdetail.vue:236
 msgid "Repeat Password"
 msgstr ""
 
@@ -403,148 +605,241 @@
 msgid "Request password reset!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:78
+#: src/components/usermanagement/Userdetail.vue:78
 msgid "Role"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:82
+#: src/components/importschedule/Importscheduledetail.vue:465
+msgid "Saturday"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:82
 msgid "Saved cross profiles"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:36
-#: src/components/admin/importschedule/Importscheduledetail.vue:48
+#: src/components/importschedule/Importscheduledetail.vue:710
+msgid "Saved import: #"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:36
+#: src/components/importschedule/Importscheduledetail.vue:238
 msgid "Schedule"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:32
+#: src/components/importschedule/Importscheduledetail.vue:196
+msgid "Scheduled"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:32
 msgid "Select Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:25
+#: src/components/Systemconfiguration.vue:25
 msgid "Send"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:138
+#: src/components/usermanagement/Userdetail.vue:138
 msgid "Send testmail"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:56
+#: src/components/importschedule/Importscheduledetail.vue:477
+msgid "September"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:64
 msgid "Signer"
 msgstr ""
 
-#: src/components/map/Identify.vue:60
+#: src/components/importschedule/Importscheduledetail.vue:216
+msgid "Simple Schedule"
+msgstr ""
+
+#: src/components/Identify.vue:60
 msgid ""
 "Some data ©\n"
 "        <a href=\"https://www.openstreetmap.org/copyright\">%{ name }</a>\n"
 "        contributors."
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:45
+#: src/components/importschedule/Importscheduledetail.vue:176
+msgid "SortBy"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:45
 msgid "Sounding Result"
 msgstr ""
 
-#: src/components/map/Identify.vue:57
+#: src/components/Identify.vue:57
 msgid "source-code"
 msgstr ""
 
-#: src/components/Sidebar.vue:54
+#: src/components/Sidebar.vue:40
 msgid "Staging area"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:7
+#: src/components/staging/Staging.vue:7
 msgid "Staging Area"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:142
+#: src/components/fairway/Profiles.vue:142
 msgid "Start"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:268
+#: src/components/ImportSoundingresults.vue:279
 msgid "Starting import for "
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:57
+#: src/components/ImportApprovedGaugeMeasurement.vue:100
+msgid "Starting import of Approved Gauge Measurements"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:67
 msgid "State"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:85
-#: src/components/admin/usermanagement/Userdetail.vue:129
+#: src/components/importschedule/Importscheduledetail.vue:394
+#: src/components/usermanagement/Userdetail.vue:129
 msgid "Submit"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:377
+#: src/components/fairway/Profiles.vue:381
 msgid "Success"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:34
+#: src/components/importqueue/Importqueue.vue:34
 msgid "Successful"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:88
+#: src/components/importschedule/Importscheduledetail.vue:466
+msgid "Sunday"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:88
 msgid "Sysadmin"
 msgstr ""
 
-#: src/components/Sidebar.vue:57
+#: src/components/usermanagement/Usermanagement.vue:326
+msgid "System-Administrator"
+msgstr ""
+
+#: src/components/Sidebar.vue:97
 msgid "Systemadministration"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:8
+#: src/components/Systemconfiguration.vue:8
 msgid "Systemconfiguration"
 msgstr ""
 
-#: src/components/map/Identify.vue:51
+#: src/components/Identify.vue:51
 msgid ""
 "This app uses <i>gemma</i>, which is Free Software under <br/>\n"
 "        %{ license } without warranty, see docs for details."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:34
-#: src/components/map/contextbox/Staging.vue:13
+#: src/components/importschedule/Importscheduledetail.vue:463
+msgid "Thursday"
+msgstr ""
+
+#: src/components/ImportApprovedGaugeMeasurement.vue:43
+#: src/components/ImportWaterwayProfiles.vue:43
+#: src/components/importschedule/Importscheduledetail.vue:407
+msgid "Trigger import"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:461
+msgid "Tuesday"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:34
+#: src/components/staging/Staging.vue:12
 msgid "Type"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:313
+#: src/components/ImportWaterwayProfiles.vue:89
+msgid "under construction"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:738
+msgid "update import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:324
 msgid "Upload"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:55
+#: src/components/importschedule/Importscheduledetail.vue:72
+msgid "URL"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:61
 msgid "User"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:14
-#: src/components/map/contextbox/Staging.vue:16
+#: src/components/importschedule/Importscheduledetail.vue:117
+#: src/components/staging/Staging.vue:18
+#: src/components/usermanagement/Userdetail.vue:14
 msgid "Username"
 msgstr ""
 
-#: src/components/Sidebar.vue:66
-#: src/components/admin/usermanagement/Usermanagement.vue:14
+#: src/components/Sidebar.vue:108
+#: src/components/usermanagement/Usermanagement.vue:14
 msgid "Users"
 msgstr ""
 
-#: src/components/map/Identify.vue:65
+#: src/components/Identify.vue:65
 msgid ""
 "Uses\n"
 "        <a href=\"https://download.geonames.org/export/dump/readme.txt\">GeoNames</a>\n"
 "        under %{ geoLicense }."
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Usermanagement.vue:327
 msgid "Waterway Admin"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:94
+#: src/components/importschedule/Importscheduledetail.vue:28
+msgid "Waterway axis"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:43
+msgid "Waterway gauges"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:94
+#: src/components/usermanagement/Usermanagement.vue:328
 msgid "Waterway User"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:439
-#: src/components/map/fairway/Profiles.vue:440
+#: src/components/importschedule/Importscheduledetail.vue:37
+msgid "Waterwayarea"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:462
+msgid "Wednesday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:455
+msgid "week"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:246
+msgid "Weekly"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:457
+msgid "year"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:443
+#: src/components/fairway/Profiles.vue:444
 msgid "You can now select these coordinates from the \"Saved cross profiles\" menu to restore this cross profile."
 msgstr ""
 
-#: src/store/map.js:415
+#: src/store/map.js:416
 msgid "Length"
 msgstr ""
 
-#: src/store/map.js:436
+#: src/store/map.js:437
 msgid "Area"
 msgstr ""
--- a/client/src/locale/hr_HR/LC_MESSAGES/app.po	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/locale/hr_HR/LC_MESSAGES/app.po	Tue Jan 15 10:07:10 2019 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gemmajs 1.99.0-dev\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-12-10 15:30+0100\n"
+"POT-Creation-Date: 2019-01-15 10:04+0100\n"
 "PO-Revision-Date: 2018-12-05 12:23+0100\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -17,138 +17,200 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
 
-#: src/components/admin/Importqueue.vue:46
+#: src/components/importschedule/Importscheduledetail.vue:452
+msgid "15 minutes"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:46
 msgid "Accepted"
 msgstr ""
 
-#: src/components/admin/Logs.vue:25
+#: src/components/Logs.vue:25
 msgid "Accesslog"
 msgstr ""
 
-#: src/components/admin/usermanagement/Usermanagement.vue:103
+#: src/components/usermanagement/Usermanagement.vue:104
 msgid "Add User"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:35
+#: src/components/importschedule/Importscheduledetail.vue:472
+msgid "April"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:449
+msgid "at"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:476
+msgid "August"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:35
 msgid "Author"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:34
+msgid "Available Fairway Depths"
+msgstr ""
+
 #: src/components/Login.vue:70
 msgid "back to login"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:136
-#: src/components/admin/Systemconfiguration.vue:134
-#: src/components/admin/Systemconfiguration.vue:149
-#: src/components/admin/Systemconfiguration.vue:168
-#: src/components/admin/Systemconfiguration.vue:185
-#: src/components/admin/usermanagement/Userdetail.vue:305
-#: src/components/admin/usermanagement/Userdetail.vue:377
-#: src/components/admin/usermanagement/Usermanagement.vue:313
-#: src/components/admin/usermanagement/Usermanagement.vue:321
-#: src/components/admin/usermanagement/Usermanagement.vue:347
-#: src/components/map/Search.vue:257
-#: src/components/map/contextbox/Bottlenecks.vue:275
-#: src/components/map/contextbox/ImportSoundingresults.vue:205
-#: src/components/map/contextbox/ImportSoundingresults.vue:244
-#: src/components/map/contextbox/ImportSoundingresults.vue:275
+#: src/components/Bottlenecks.vue:274
+#: src/components/ImportApprovedGaugeMeasurement.vue:107
+#: src/components/ImportSoundingresults.vue:216
+#: src/components/ImportSoundingresults.vue:255
+#: src/components/ImportSoundingresults.vue:286 src/components/Search.vue:258
+#: src/components/Systemconfiguration.vue:114
+#: src/components/Systemconfiguration.vue:129
+#: src/components/Systemconfiguration.vue:148
+#: src/components/Systemconfiguration.vue:165
+#: src/components/importqueue/Importqueue.vue:160
+#: src/components/importqueue/Importqueue.vue:180
+#: src/components/importqueue/Importqueuedetail.vue:182
+#: src/components/importschedule/Importschedule.vue:148
+#: src/components/importschedule/Importschedule.vue:167
+#: src/components/importschedule/Importschedule.vue:176
+#: src/components/importschedule/Importschedule.vue:198
+#: src/components/importschedule/Importscheduledetail.vue:656
+#: src/components/importschedule/Importscheduledetail.vue:724
+#: src/components/importschedule/Importscheduledetail.vue:752
+#: src/components/staging/StagingDetail.vue:246
+#: src/components/usermanagement/Userdetail.vue:304
+#: src/components/usermanagement/Userdetail.vue:376
+#: src/components/usermanagement/Usermanagement.vue:298
+#: src/components/usermanagement/Usermanagement.vue:306
+#: src/components/usermanagement/Usermanagement.vue:340
+#: src/components/importschedule/Importscheduledetail.vue:716
+#: src/components/importschedule/Importscheduledetail.vue:744
 msgid "Backend Error"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:11
+#: src/components/ImportSoundingresults.vue:16
 msgid "Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:19
+#: src/components/Systemconfiguration.vue:19
 msgid "Bottleneck Areas fill-color"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:13
+#: src/components/Systemconfiguration.vue:13
 msgid "Bottleneck Areas stroke-color"
 msgstr ""
 
-#: src/components/Sidebar.vue:27
-#: src/components/map/contextbox/Bottlenecks.vue:4
+#: src/components/Bottlenecks.vue:4 src/components/Sidebar.vue:27
+#: src/components/importschedule/Importscheduledetail.vue:25
+#: src/components/staging/StagingDetail.vue:11
 msgid "Bottlenecks"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:121
+#: src/components/ImportSoundingresults.vue:126
 msgid "Cancel Upload"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:30
+#: src/components/Bottlenecks.vue:30
 msgid "Chainage"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:167
-#: src/components/map/contextbox/ImportSoundingresults.vue:181
+#: src/components/ImportSoundingresults.vue:178
+#: src/components/ImportSoundingresults.vue:192
 msgid "choose .zip- file"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:18
-msgid "Chose format:"
+#: src/components/ImportApprovedGaugeMeasurement.vue:76
+#: src/components/ImportWaterwayProfiles.vue:75
+msgid "choose file to upload"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:64
+#: src/components/Pdftool.vue:18
+msgid "Choose format:"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:64
 msgid "Compare with"
 msgstr ""
 
-#: src/components/Sidebar.vue:76
+#: src/components/Sidebar.vue:116
 msgid "Configuration"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:316
-#: src/components/map/contextbox/Staging.vue:70
+#: src/components/ImportSoundingresults.vue:327
+#: src/components/staging/Staging.vue:33
 msgid "Confirm"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:378
+#: src/components/fairway/Profiles.vue:382
 msgid "Coordinates copied to clipboard!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:33
+#: src/components/usermanagement/Userdetail.vue:33
 msgid "Country"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:67
-#: src/components/map/contextbox/Staging.vue:14
+#: src/components/importschedule/Importscheduledetail.vue:382
+msgid "Cronstring"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:72
+#: src/components/importqueue/Importqueuedetail.vue:49
+#: src/components/staging/Staging.vue:13
 msgid "Date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:47
+#: src/components/importschedule/Importscheduledetail.vue:454
+msgid "day"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:480
+msgid "December"
+msgstr ""
+
+#: src/components/ImportStretches.vue:4
+msgid "Define section and stretches"
+msgstr ""
+
+#: src/components/Sidebar.vue:52
+msgid "Define sections and stretches"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:192
+msgid "Deleted import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:52
 msgid "Depthreference"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:32
+#: src/components/Pdftool.vue:36
 msgid "Download"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:113
+#: src/components/ImportSoundingresults.vue:118
 msgid "Download Meta.json"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:37
-#: src/components/admin/importschedule/Importscheduledetail.vue:80
+#: src/components/importschedule/Importschedule.vue:37
 msgid "Email"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:59
+#: src/components/usermanagement/Userdetail.vue:59
 msgid "Email address"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:61
+#: src/components/importschedule/Importscheduledetail.vue:50
 msgid "Email Notification"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:53
+#: src/components/importqueue/Importqueue.vue:55
 msgid "Enqueued"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:123
+#: src/components/fairway/Profiles.vue:123
 msgid "Enter coordinates manually"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:185
+#: src/components/fairway/Profiles.vue:185
 msgid "Enter label for cross profile"
 msgstr ""
 
@@ -160,89 +222,160 @@
 msgid "Enter username"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:386
+#: src/components/usermanagement/Userdetail.vue:385
 msgid "Error while saving user"
 msgstr ""
 
-#: src/components/admin/Logs.vue:34
+#: src/components/Logs.vue:34
 msgid "Errorlog"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:37
+#: src/components/importschedule/Importscheduledetail.vue:445
+msgid "Every"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:37
 msgid "Failed"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:40
+msgid "Fairwaydimensions"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:155
+msgid "Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:470
+msgid "February"
+msgstr ""
+
 #: src/components/Login.vue:76
 msgid "Forgot password"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:10 src/components/map/Pdftool.vue:49
+#: src/components/importschedule/Importscheduledetail.vue:464
+msgid "Friday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:31
+msgid "Gauge measurement"
+msgstr ""
+
+#: src/components/Pdftool.vue:10 src/components/Pdftool.vue:53
 msgid "Generate PDF"
 msgstr ""
 
-#: src/components/map/Identify.vue:10
+#: src/components/importschedule/Importscheduledetail.vue:453
+msgid "hour"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:52
+msgid "Id"
+msgstr ""
+
+#: src/components/Identify.vue:10
 msgid "Identified"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:33
-#: src/components/map/contextbox/ImportSoundingresults.vue:267
+#: src/components/ImportApprovedGaugeMeasurement.vue:99
+#: src/components/ImportSoundingresults.vue:278
+#: src/components/ImportWaterwayProfiles.vue:88 src/components/Sidebar.vue:56
+#: src/components/importschedule/Importschedule.vue:33
+#: src/components/importschedule/Importscheduledetail.vue:519
+#: src/components/importschedule/Importscheduledetail.vue:649
+#: src/components/importschedule/Importscheduledetail.vue:709
+#: src/components/importschedule/Importscheduledetail.vue:737
 msgid "Import"
 msgstr ""
 
-#: src/components/Sidebar.vue:40
+#: src/components/ImportApprovedGaugeMeasurement.vue:11
+#: src/components/Sidebar.vue:74
+msgid "Import approved gaugemeasurements"
+msgstr ""
+
+#: src/components/Sidebar.vue:64
 msgid "Import soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:4
+#: src/components/ImportSoundingresults.vue:9
 msgid "Import Soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:15
+#: src/components/Sidebar.vue:84
+msgid "Import waterway profiles"
+msgstr ""
+
+#: src/components/ImportWaterwayProfiles.vue:11
+msgid "Import Waterwayprofiles"
+msgstr ""
+
+#: src/components/staging/Staging.vue:15
 msgid "Imported"
 msgstr ""
 
-#: src/components/Sidebar.vue:92 src/components/admin/Importqueue.vue:9
+#: src/components/Sidebar.vue:134 src/components/importqueue/Importqueue.vue:9
 msgid "Importqueue"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:20
+#: src/components/Sidebar.vue:94
+#: src/components/importschedule/Importschedule.vue:9
+#: src/components/importschedule/Importschedule.vue:160
+#: src/components/importschedule/Importschedule.vue:191
+#: src/components/importschedule/Importscheduledetail.vue:20
 msgid "Imports"
 msgstr ""
 
-#: src/components/Sidebar.vue:100
-#: src/components/admin/importschedule/Importschedule.vue:9
-msgid "Importschedule"
+#: src/components/importschedule/Importscheduledetail.vue:81
+msgid "Insecure"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:34
-msgid "Importtype"
-msgstr ""
-
-#: src/components/admin/usermanagement/Userdetail.vue:354
+#: src/components/usermanagement/Userdetail.vue:353
 msgid "invalid email"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:412
+#: src/components/fairway/Profiles.vue:416
 msgid "Invalid input"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:54
+#: src/components/Pdftool.vue:24
+msgid "ISO A3"
+msgstr ""
+
+#: src/components/Pdftool.vue:25
+msgid "ISO A4"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:469
+msgid "January"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:475
+msgid "July"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:474
+msgid "June"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:58
+#: src/components/importqueue/Importqueuedetail.vue:45
 msgid "Kind"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:20
+#: src/components/Pdftool.vue:20
 msgid "landscape"
 msgstr ""
 
-#: src/components/admin/Logs.vue:41
+#: src/components/Logs.vue:41
 msgid "Last refresh:"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:19
+#: src/components/Bottlenecks.vue:19
 msgid "Latest"
 msgstr ""
 
-#: src/components/map/layers/Layers.vue:10
+#: src/components/layers/Layers.vue:10
 msgid "Layers"
 msgstr ""
 
@@ -254,65 +387,114 @@
 msgid "Login failed"
 msgstr ""
 
-#: src/components/Sidebar.vue:110
+#: src/components/Sidebar.vue:144
 msgid "Logout"
 msgstr ""
 
-#: src/components/Sidebar.vue:84 src/components/admin/Logs.vue:9
+#: src/components/Logs.vue:9 src/components/Sidebar.vue:124
 msgid "Logs"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:140
+#: src/components/usermanagement/Userdetail.vue:140
 msgid "Mail was sent"
 msgstr ""
 
+#: src/components/importschedule/Importschedule.vue:161
+#: src/components/importschedule/Importscheduledetail.vue:650
+msgid "Manually triggered import: #"
+msgstr ""
+
 #: src/components/Sidebar.vue:15
 msgid "Map"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:20
+#: src/components/importschedule/Importscheduledetail.vue:471
+msgid "March"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:473
+msgid "May"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:20
 msgid "Measurement"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:9
-#: src/components/map/contextbox/Staging.vue:12
+#: src/components/importqueue/Importqueuedetail.vue:58
+msgid "Message"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:446
+msgid "minutes past"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:460
+msgid "Monday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:456
+msgid "month"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:247
+msgid "Monthly"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:9 src/components/staging/Staging.vue:11
 msgid "Name"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:9
-msgid "New import"
-msgstr ""
-
-#: src/components/admin/importschedule/Importschedule.vue:72
+#: src/components/importschedule/Importschedule.vue:93
+#: src/components/importschedule/Importscheduledetail.vue:520
 msgid "New Import"
 msgstr ""
 
-#: src/components/map/Identify.vue:47
+#: src/components/Identify.vue:47
 msgid "No features identified."
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:116
-#: src/components/map/contextbox/Staging.vue:63
+#: src/components/Bottlenecks.vue:115 src/components/staging/Staging.vue:36
 msgid "No results."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:66
-msgid "No schedules"
+#: src/components/importschedule/Importschedule.vue:85
+msgid "No scheduled imports"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:479
+msgid "November"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:450
+msgid "o' clock"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:41
+#: src/components/importschedule/Importscheduledetail.vue:478
+msgid "October"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:448
+msgid "of"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:447
+msgid "on"
+msgstr ""
+
+#: src/components/Pdftool.vue:45
 msgid "Open in new window"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:238
+#: src/components/usermanagement/Userdetail.vue:237
 msgid "password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:236
+#: src/components/importschedule/Importscheduledetail.vue:134
+#: src/components/usermanagement/Userdetail.vue:235
 msgid "Password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:239
+#: src/components/usermanagement/Userdetail.vue:238
 msgid "password again"
 msgstr ""
 
@@ -320,82 +502,102 @@
 msgid "Password reset requested!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:347
-#: src/components/admin/usermanagement/Userdetail.vue:348
+#: src/components/usermanagement/Userdetail.vue:346
+#: src/components/usermanagement/Userdetail.vue:347
 msgid "Password should at least be 8 char long including 1 digit and 1 special char like $"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:343
+#: src/components/usermanagement/Userdetail.vue:342
 msgid "Passwords do not match!"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:40
+#: src/components/importqueue/Importqueue.vue:40
 msgid "Pending"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:332
+#: src/components/usermanagement/Userdetail.vue:331
 msgid "Please choose a country"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:337
+#: src/components/usermanagement/Userdetail.vue:336
 msgid "Please choose a role"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:79
+#: src/components/ImportSoundingresults.vue:84
 msgid "Please enter a date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:39
+#: src/components/importschedule/Importscheduledetail.vue:167
+msgid "Please enter a Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:142
+msgid "Please enter a Password"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:44
 msgid "Please enter a projection"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:62
+#: src/components/ImportSoundingresults.vue:67
 msgid "Please enter a reference"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:413
-#: src/components/map/fairway/Profiles.vue:414
+#: src/components/importschedule/Importscheduledetail.vue:106
+msgid "Please enter a URL"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:125
+msgid "Please enter a Username"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:417
+#: src/components/fairway/Profiles.vue:418
 msgid "Please enter correct coordinates in the format: Lat,Lon,Lat,Lon"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:22
+#: src/components/importschedule/Importscheduledetail.vue:184
+msgid "Please enter SortBy"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:27
 msgid "Please select a bottleneck"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:40
-#: src/components/admin/usermanagement/Userdetail.vue:85
+#: src/components/usermanagement/Userdetail.vue:40
+#: src/components/usermanagement/Userdetail.vue:85
 msgid "Please select one"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:21
+#: src/components/Pdftool.vue:21
 msgid "portrait"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:452
+#: src/components/fairway/Profiles.vue:456
 msgid "Profile deleted!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:438
+#: src/components/fairway/Profiles.vue:442
 msgid "Profile saved!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:10
+#: src/components/fairway/Profiles.vue:10
 msgid "Profiles"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:28
+#: src/components/ImportSoundingresults.vue:33
 msgid "Projection"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:72 src/components/admin/Logs.vue:48
+#: src/components/Logs.vue:48 src/components/importqueue/Importqueue.vue:84
 msgid "Refresh"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:43
+#: src/components/importqueue/Importqueue.vue:43
 msgid "Rejected"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:237
+#: src/components/usermanagement/Userdetail.vue:236
 msgid "Repeat Password"
 msgstr ""
 
@@ -403,148 +605,241 @@
 msgid "Request password reset!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:78
+#: src/components/usermanagement/Userdetail.vue:78
 msgid "Role"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:82
+#: src/components/importschedule/Importscheduledetail.vue:465
+msgid "Saturday"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:82
 msgid "Saved cross profiles"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:36
-#: src/components/admin/importschedule/Importscheduledetail.vue:48
+#: src/components/importschedule/Importscheduledetail.vue:710
+msgid "Saved import: #"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:36
+#: src/components/importschedule/Importscheduledetail.vue:238
 msgid "Schedule"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:32
+#: src/components/importschedule/Importscheduledetail.vue:196
+msgid "Scheduled"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:32
 msgid "Select Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:25
+#: src/components/Systemconfiguration.vue:25
 msgid "Send"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:138
+#: src/components/usermanagement/Userdetail.vue:138
 msgid "Send testmail"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:56
+#: src/components/importschedule/Importscheduledetail.vue:477
+msgid "September"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:64
 msgid "Signer"
 msgstr ""
 
-#: src/components/map/Identify.vue:60
+#: src/components/importschedule/Importscheduledetail.vue:216
+msgid "Simple Schedule"
+msgstr ""
+
+#: src/components/Identify.vue:60
 msgid ""
 "Some data ©\n"
 "        <a href=\"https://www.openstreetmap.org/copyright\">%{ name }</a>\n"
 "        contributors."
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:45
+#: src/components/importschedule/Importscheduledetail.vue:176
+msgid "SortBy"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:45
 msgid "Sounding Result"
 msgstr ""
 
-#: src/components/map/Identify.vue:57
+#: src/components/Identify.vue:57
 msgid "source-code"
 msgstr ""
 
-#: src/components/Sidebar.vue:54
+#: src/components/Sidebar.vue:40
 msgid "Staging area"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:7
+#: src/components/staging/Staging.vue:7
 msgid "Staging Area"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:142
+#: src/components/fairway/Profiles.vue:142
 msgid "Start"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:268
+#: src/components/ImportSoundingresults.vue:279
 msgid "Starting import for "
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:57
+#: src/components/ImportApprovedGaugeMeasurement.vue:100
+msgid "Starting import of Approved Gauge Measurements"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:67
 msgid "State"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:85
-#: src/components/admin/usermanagement/Userdetail.vue:129
+#: src/components/importschedule/Importscheduledetail.vue:394
+#: src/components/usermanagement/Userdetail.vue:129
 msgid "Submit"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:377
+#: src/components/fairway/Profiles.vue:381
 msgid "Success"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:34
+#: src/components/importqueue/Importqueue.vue:34
 msgid "Successful"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:88
+#: src/components/importschedule/Importscheduledetail.vue:466
+msgid "Sunday"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:88
 msgid "Sysadmin"
 msgstr ""
 
-#: src/components/Sidebar.vue:57
+#: src/components/usermanagement/Usermanagement.vue:326
+msgid "System-Administrator"
+msgstr ""
+
+#: src/components/Sidebar.vue:97
 msgid "Systemadministration"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:8
+#: src/components/Systemconfiguration.vue:8
 msgid "Systemconfiguration"
 msgstr ""
 
-#: src/components/map/Identify.vue:51
+#: src/components/Identify.vue:51
 msgid ""
 "This app uses <i>gemma</i>, which is Free Software under <br/>\n"
 "        %{ license } without warranty, see docs for details."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:34
-#: src/components/map/contextbox/Staging.vue:13
+#: src/components/importschedule/Importscheduledetail.vue:463
+msgid "Thursday"
+msgstr ""
+
+#: src/components/ImportApprovedGaugeMeasurement.vue:43
+#: src/components/ImportWaterwayProfiles.vue:43
+#: src/components/importschedule/Importscheduledetail.vue:407
+msgid "Trigger import"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:461
+msgid "Tuesday"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:34
+#: src/components/staging/Staging.vue:12
 msgid "Type"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:313
+#: src/components/ImportWaterwayProfiles.vue:89
+msgid "under construction"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:738
+msgid "update import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:324
 msgid "Upload"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:55
+#: src/components/importschedule/Importscheduledetail.vue:72
+msgid "URL"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:61
 msgid "User"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:14
-#: src/components/map/contextbox/Staging.vue:16
+#: src/components/importschedule/Importscheduledetail.vue:117
+#: src/components/staging/Staging.vue:18
+#: src/components/usermanagement/Userdetail.vue:14
 msgid "Username"
 msgstr ""
 
-#: src/components/Sidebar.vue:66
-#: src/components/admin/usermanagement/Usermanagement.vue:14
+#: src/components/Sidebar.vue:108
+#: src/components/usermanagement/Usermanagement.vue:14
 msgid "Users"
 msgstr ""
 
-#: src/components/map/Identify.vue:65
+#: src/components/Identify.vue:65
 msgid ""
 "Uses\n"
 "        <a href=\"https://download.geonames.org/export/dump/readme.txt\">GeoNames</a>\n"
 "        under %{ geoLicense }."
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Usermanagement.vue:327
 msgid "Waterway Admin"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:94
+#: src/components/importschedule/Importscheduledetail.vue:28
+msgid "Waterway axis"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:43
+msgid "Waterway gauges"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:94
+#: src/components/usermanagement/Usermanagement.vue:328
 msgid "Waterway User"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:439
-#: src/components/map/fairway/Profiles.vue:440
+#: src/components/importschedule/Importscheduledetail.vue:37
+msgid "Waterwayarea"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:462
+msgid "Wednesday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:455
+msgid "week"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:246
+msgid "Weekly"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:457
+msgid "year"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:443
+#: src/components/fairway/Profiles.vue:444
 msgid "You can now select these coordinates from the \"Saved cross profiles\" menu to restore this cross profile."
 msgstr ""
 
-#: src/store/map.js:415
+#: src/store/map.js:416
 msgid "Length"
 msgstr ""
 
-#: src/store/map.js:436
+#: src/store/map.js:437
 msgid "Area"
 msgstr ""
--- a/client/src/locale/hu_HU/LC_MESSAGES/app.po	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/locale/hu_HU/LC_MESSAGES/app.po	Tue Jan 15 10:07:10 2019 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gemmajs 1.99.0-dev\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-12-10 15:30+0100\n"
+"POT-Creation-Date: 2019-01-15 10:04+0100\n"
 "PO-Revision-Date: 2018-12-05 12:23+0100\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -17,138 +17,200 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/components/admin/Importqueue.vue:46
+#: src/components/importschedule/Importscheduledetail.vue:452
+msgid "15 minutes"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:46
 msgid "Accepted"
 msgstr ""
 
-#: src/components/admin/Logs.vue:25
+#: src/components/Logs.vue:25
 msgid "Accesslog"
 msgstr ""
 
-#: src/components/admin/usermanagement/Usermanagement.vue:103
+#: src/components/usermanagement/Usermanagement.vue:104
 msgid "Add User"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:35
+#: src/components/importschedule/Importscheduledetail.vue:472
+msgid "April"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:449
+msgid "at"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:476
+msgid "August"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:35
 msgid "Author"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:34
+msgid "Available Fairway Depths"
+msgstr ""
+
 #: src/components/Login.vue:70
 msgid "back to login"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:136
-#: src/components/admin/Systemconfiguration.vue:134
-#: src/components/admin/Systemconfiguration.vue:149
-#: src/components/admin/Systemconfiguration.vue:168
-#: src/components/admin/Systemconfiguration.vue:185
-#: src/components/admin/usermanagement/Userdetail.vue:305
-#: src/components/admin/usermanagement/Userdetail.vue:377
-#: src/components/admin/usermanagement/Usermanagement.vue:313
-#: src/components/admin/usermanagement/Usermanagement.vue:321
-#: src/components/admin/usermanagement/Usermanagement.vue:347
-#: src/components/map/Search.vue:257
-#: src/components/map/contextbox/Bottlenecks.vue:275
-#: src/components/map/contextbox/ImportSoundingresults.vue:205
-#: src/components/map/contextbox/ImportSoundingresults.vue:244
-#: src/components/map/contextbox/ImportSoundingresults.vue:275
+#: src/components/Bottlenecks.vue:274
+#: src/components/ImportApprovedGaugeMeasurement.vue:107
+#: src/components/ImportSoundingresults.vue:216
+#: src/components/ImportSoundingresults.vue:255
+#: src/components/ImportSoundingresults.vue:286 src/components/Search.vue:258
+#: src/components/Systemconfiguration.vue:114
+#: src/components/Systemconfiguration.vue:129
+#: src/components/Systemconfiguration.vue:148
+#: src/components/Systemconfiguration.vue:165
+#: src/components/importqueue/Importqueue.vue:160
+#: src/components/importqueue/Importqueue.vue:180
+#: src/components/importqueue/Importqueuedetail.vue:182
+#: src/components/importschedule/Importschedule.vue:148
+#: src/components/importschedule/Importschedule.vue:167
+#: src/components/importschedule/Importschedule.vue:176
+#: src/components/importschedule/Importschedule.vue:198
+#: src/components/importschedule/Importscheduledetail.vue:656
+#: src/components/importschedule/Importscheduledetail.vue:724
+#: src/components/importschedule/Importscheduledetail.vue:752
+#: src/components/staging/StagingDetail.vue:246
+#: src/components/usermanagement/Userdetail.vue:304
+#: src/components/usermanagement/Userdetail.vue:376
+#: src/components/usermanagement/Usermanagement.vue:298
+#: src/components/usermanagement/Usermanagement.vue:306
+#: src/components/usermanagement/Usermanagement.vue:340
+#: src/components/importschedule/Importscheduledetail.vue:716
+#: src/components/importschedule/Importscheduledetail.vue:744
 msgid "Backend Error"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:11
+#: src/components/ImportSoundingresults.vue:16
 msgid "Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:19
+#: src/components/Systemconfiguration.vue:19
 msgid "Bottleneck Areas fill-color"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:13
+#: src/components/Systemconfiguration.vue:13
 msgid "Bottleneck Areas stroke-color"
 msgstr ""
 
-#: src/components/Sidebar.vue:27
-#: src/components/map/contextbox/Bottlenecks.vue:4
+#: src/components/Bottlenecks.vue:4 src/components/Sidebar.vue:27
+#: src/components/importschedule/Importscheduledetail.vue:25
+#: src/components/staging/StagingDetail.vue:11
 msgid "Bottlenecks"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:121
+#: src/components/ImportSoundingresults.vue:126
 msgid "Cancel Upload"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:30
+#: src/components/Bottlenecks.vue:30
 msgid "Chainage"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:167
-#: src/components/map/contextbox/ImportSoundingresults.vue:181
+#: src/components/ImportSoundingresults.vue:178
+#: src/components/ImportSoundingresults.vue:192
 msgid "choose .zip- file"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:18
-msgid "Chose format:"
+#: src/components/ImportApprovedGaugeMeasurement.vue:76
+#: src/components/ImportWaterwayProfiles.vue:75
+msgid "choose file to upload"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:64
+#: src/components/Pdftool.vue:18
+msgid "Choose format:"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:64
 msgid "Compare with"
 msgstr ""
 
-#: src/components/Sidebar.vue:76
+#: src/components/Sidebar.vue:116
 msgid "Configuration"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:316
-#: src/components/map/contextbox/Staging.vue:70
+#: src/components/ImportSoundingresults.vue:327
+#: src/components/staging/Staging.vue:33
 msgid "Confirm"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:378
+#: src/components/fairway/Profiles.vue:382
 msgid "Coordinates copied to clipboard!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:33
+#: src/components/usermanagement/Userdetail.vue:33
 msgid "Country"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:67
-#: src/components/map/contextbox/Staging.vue:14
+#: src/components/importschedule/Importscheduledetail.vue:382
+msgid "Cronstring"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:72
+#: src/components/importqueue/Importqueuedetail.vue:49
+#: src/components/staging/Staging.vue:13
 msgid "Date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:47
+#: src/components/importschedule/Importscheduledetail.vue:454
+msgid "day"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:480
+msgid "December"
+msgstr ""
+
+#: src/components/ImportStretches.vue:4
+msgid "Define section and stretches"
+msgstr ""
+
+#: src/components/Sidebar.vue:52
+msgid "Define sections and stretches"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:192
+msgid "Deleted import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:52
 msgid "Depthreference"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:32
+#: src/components/Pdftool.vue:36
 msgid "Download"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:113
+#: src/components/ImportSoundingresults.vue:118
 msgid "Download Meta.json"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:37
-#: src/components/admin/importschedule/Importscheduledetail.vue:80
+#: src/components/importschedule/Importschedule.vue:37
 msgid "Email"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:59
+#: src/components/usermanagement/Userdetail.vue:59
 msgid "Email address"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:61
+#: src/components/importschedule/Importscheduledetail.vue:50
 msgid "Email Notification"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:53
+#: src/components/importqueue/Importqueue.vue:55
 msgid "Enqueued"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:123
+#: src/components/fairway/Profiles.vue:123
 msgid "Enter coordinates manually"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:185
+#: src/components/fairway/Profiles.vue:185
 msgid "Enter label for cross profile"
 msgstr ""
 
@@ -160,89 +222,160 @@
 msgid "Enter username"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:386
+#: src/components/usermanagement/Userdetail.vue:385
 msgid "Error while saving user"
 msgstr ""
 
-#: src/components/admin/Logs.vue:34
+#: src/components/Logs.vue:34
 msgid "Errorlog"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:37
+#: src/components/importschedule/Importscheduledetail.vue:445
+msgid "Every"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:37
 msgid "Failed"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:40
+msgid "Fairwaydimensions"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:155
+msgid "Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:470
+msgid "February"
+msgstr ""
+
 #: src/components/Login.vue:76
 msgid "Forgot password"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:10 src/components/map/Pdftool.vue:49
+#: src/components/importschedule/Importscheduledetail.vue:464
+msgid "Friday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:31
+msgid "Gauge measurement"
+msgstr ""
+
+#: src/components/Pdftool.vue:10 src/components/Pdftool.vue:53
 msgid "Generate PDF"
 msgstr ""
 
-#: src/components/map/Identify.vue:10
+#: src/components/importschedule/Importscheduledetail.vue:453
+msgid "hour"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:52
+msgid "Id"
+msgstr ""
+
+#: src/components/Identify.vue:10
 msgid "Identified"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:33
-#: src/components/map/contextbox/ImportSoundingresults.vue:267
+#: src/components/ImportApprovedGaugeMeasurement.vue:99
+#: src/components/ImportSoundingresults.vue:278
+#: src/components/ImportWaterwayProfiles.vue:88 src/components/Sidebar.vue:56
+#: src/components/importschedule/Importschedule.vue:33
+#: src/components/importschedule/Importscheduledetail.vue:519
+#: src/components/importschedule/Importscheduledetail.vue:649
+#: src/components/importschedule/Importscheduledetail.vue:709
+#: src/components/importschedule/Importscheduledetail.vue:737
 msgid "Import"
 msgstr ""
 
-#: src/components/Sidebar.vue:40
+#: src/components/ImportApprovedGaugeMeasurement.vue:11
+#: src/components/Sidebar.vue:74
+msgid "Import approved gaugemeasurements"
+msgstr ""
+
+#: src/components/Sidebar.vue:64
 msgid "Import soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:4
+#: src/components/ImportSoundingresults.vue:9
 msgid "Import Soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:15
+#: src/components/Sidebar.vue:84
+msgid "Import waterway profiles"
+msgstr ""
+
+#: src/components/ImportWaterwayProfiles.vue:11
+msgid "Import Waterwayprofiles"
+msgstr ""
+
+#: src/components/staging/Staging.vue:15
 msgid "Imported"
 msgstr ""
 
-#: src/components/Sidebar.vue:92 src/components/admin/Importqueue.vue:9
+#: src/components/Sidebar.vue:134 src/components/importqueue/Importqueue.vue:9
 msgid "Importqueue"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:20
+#: src/components/Sidebar.vue:94
+#: src/components/importschedule/Importschedule.vue:9
+#: src/components/importschedule/Importschedule.vue:160
+#: src/components/importschedule/Importschedule.vue:191
+#: src/components/importschedule/Importscheduledetail.vue:20
 msgid "Imports"
 msgstr ""
 
-#: src/components/Sidebar.vue:100
-#: src/components/admin/importschedule/Importschedule.vue:9
-msgid "Importschedule"
+#: src/components/importschedule/Importscheduledetail.vue:81
+msgid "Insecure"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:34
-msgid "Importtype"
-msgstr ""
-
-#: src/components/admin/usermanagement/Userdetail.vue:354
+#: src/components/usermanagement/Userdetail.vue:353
 msgid "invalid email"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:412
+#: src/components/fairway/Profiles.vue:416
 msgid "Invalid input"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:54
+#: src/components/Pdftool.vue:24
+msgid "ISO A3"
+msgstr ""
+
+#: src/components/Pdftool.vue:25
+msgid "ISO A4"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:469
+msgid "January"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:475
+msgid "July"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:474
+msgid "June"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:58
+#: src/components/importqueue/Importqueuedetail.vue:45
 msgid "Kind"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:20
+#: src/components/Pdftool.vue:20
 msgid "landscape"
 msgstr ""
 
-#: src/components/admin/Logs.vue:41
+#: src/components/Logs.vue:41
 msgid "Last refresh:"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:19
+#: src/components/Bottlenecks.vue:19
 msgid "Latest"
 msgstr ""
 
-#: src/components/map/layers/Layers.vue:10
+#: src/components/layers/Layers.vue:10
 msgid "Layers"
 msgstr ""
 
@@ -254,65 +387,114 @@
 msgid "Login failed"
 msgstr ""
 
-#: src/components/Sidebar.vue:110
+#: src/components/Sidebar.vue:144
 msgid "Logout"
 msgstr ""
 
-#: src/components/Sidebar.vue:84 src/components/admin/Logs.vue:9
+#: src/components/Logs.vue:9 src/components/Sidebar.vue:124
 msgid "Logs"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:140
+#: src/components/usermanagement/Userdetail.vue:140
 msgid "Mail was sent"
 msgstr ""
 
+#: src/components/importschedule/Importschedule.vue:161
+#: src/components/importschedule/Importscheduledetail.vue:650
+msgid "Manually triggered import: #"
+msgstr ""
+
 #: src/components/Sidebar.vue:15
 msgid "Map"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:20
+#: src/components/importschedule/Importscheduledetail.vue:471
+msgid "March"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:473
+msgid "May"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:20
 msgid "Measurement"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:9
-#: src/components/map/contextbox/Staging.vue:12
+#: src/components/importqueue/Importqueuedetail.vue:58
+msgid "Message"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:446
+msgid "minutes past"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:460
+msgid "Monday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:456
+msgid "month"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:247
+msgid "Monthly"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:9 src/components/staging/Staging.vue:11
 msgid "Name"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:9
-msgid "New import"
-msgstr ""
-
-#: src/components/admin/importschedule/Importschedule.vue:72
+#: src/components/importschedule/Importschedule.vue:93
+#: src/components/importschedule/Importscheduledetail.vue:520
 msgid "New Import"
 msgstr ""
 
-#: src/components/map/Identify.vue:47
+#: src/components/Identify.vue:47
 msgid "No features identified."
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:116
-#: src/components/map/contextbox/Staging.vue:63
+#: src/components/Bottlenecks.vue:115 src/components/staging/Staging.vue:36
 msgid "No results."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:66
-msgid "No schedules"
+#: src/components/importschedule/Importschedule.vue:85
+msgid "No scheduled imports"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:479
+msgid "November"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:450
+msgid "o' clock"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:41
+#: src/components/importschedule/Importscheduledetail.vue:478
+msgid "October"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:448
+msgid "of"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:447
+msgid "on"
+msgstr ""
+
+#: src/components/Pdftool.vue:45
 msgid "Open in new window"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:238
+#: src/components/usermanagement/Userdetail.vue:237
 msgid "password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:236
+#: src/components/importschedule/Importscheduledetail.vue:134
+#: src/components/usermanagement/Userdetail.vue:235
 msgid "Password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:239
+#: src/components/usermanagement/Userdetail.vue:238
 msgid "password again"
 msgstr ""
 
@@ -320,82 +502,102 @@
 msgid "Password reset requested!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:347
-#: src/components/admin/usermanagement/Userdetail.vue:348
+#: src/components/usermanagement/Userdetail.vue:346
+#: src/components/usermanagement/Userdetail.vue:347
 msgid "Password should at least be 8 char long including 1 digit and 1 special char like $"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:343
+#: src/components/usermanagement/Userdetail.vue:342
 msgid "Passwords do not match!"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:40
+#: src/components/importqueue/Importqueue.vue:40
 msgid "Pending"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:332
+#: src/components/usermanagement/Userdetail.vue:331
 msgid "Please choose a country"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:337
+#: src/components/usermanagement/Userdetail.vue:336
 msgid "Please choose a role"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:79
+#: src/components/ImportSoundingresults.vue:84
 msgid "Please enter a date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:39
+#: src/components/importschedule/Importscheduledetail.vue:167
+msgid "Please enter a Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:142
+msgid "Please enter a Password"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:44
 msgid "Please enter a projection"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:62
+#: src/components/ImportSoundingresults.vue:67
 msgid "Please enter a reference"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:413
-#: src/components/map/fairway/Profiles.vue:414
+#: src/components/importschedule/Importscheduledetail.vue:106
+msgid "Please enter a URL"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:125
+msgid "Please enter a Username"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:417
+#: src/components/fairway/Profiles.vue:418
 msgid "Please enter correct coordinates in the format: Lat,Lon,Lat,Lon"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:22
+#: src/components/importschedule/Importscheduledetail.vue:184
+msgid "Please enter SortBy"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:27
 msgid "Please select a bottleneck"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:40
-#: src/components/admin/usermanagement/Userdetail.vue:85
+#: src/components/usermanagement/Userdetail.vue:40
+#: src/components/usermanagement/Userdetail.vue:85
 msgid "Please select one"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:21
+#: src/components/Pdftool.vue:21
 msgid "portrait"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:452
+#: src/components/fairway/Profiles.vue:456
 msgid "Profile deleted!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:438
+#: src/components/fairway/Profiles.vue:442
 msgid "Profile saved!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:10
+#: src/components/fairway/Profiles.vue:10
 msgid "Profiles"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:28
+#: src/components/ImportSoundingresults.vue:33
 msgid "Projection"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:72 src/components/admin/Logs.vue:48
+#: src/components/Logs.vue:48 src/components/importqueue/Importqueue.vue:84
 msgid "Refresh"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:43
+#: src/components/importqueue/Importqueue.vue:43
 msgid "Rejected"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:237
+#: src/components/usermanagement/Userdetail.vue:236
 msgid "Repeat Password"
 msgstr ""
 
@@ -403,148 +605,241 @@
 msgid "Request password reset!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:78
+#: src/components/usermanagement/Userdetail.vue:78
 msgid "Role"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:82
+#: src/components/importschedule/Importscheduledetail.vue:465
+msgid "Saturday"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:82
 msgid "Saved cross profiles"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:36
-#: src/components/admin/importschedule/Importscheduledetail.vue:48
+#: src/components/importschedule/Importscheduledetail.vue:710
+msgid "Saved import: #"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:36
+#: src/components/importschedule/Importscheduledetail.vue:238
 msgid "Schedule"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:32
+#: src/components/importschedule/Importscheduledetail.vue:196
+msgid "Scheduled"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:32
 msgid "Select Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:25
+#: src/components/Systemconfiguration.vue:25
 msgid "Send"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:138
+#: src/components/usermanagement/Userdetail.vue:138
 msgid "Send testmail"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:56
+#: src/components/importschedule/Importscheduledetail.vue:477
+msgid "September"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:64
 msgid "Signer"
 msgstr ""
 
-#: src/components/map/Identify.vue:60
+#: src/components/importschedule/Importscheduledetail.vue:216
+msgid "Simple Schedule"
+msgstr ""
+
+#: src/components/Identify.vue:60
 msgid ""
 "Some data ©\n"
 "        <a href=\"https://www.openstreetmap.org/copyright\">%{ name }</a>\n"
 "        contributors."
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:45
+#: src/components/importschedule/Importscheduledetail.vue:176
+msgid "SortBy"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:45
 msgid "Sounding Result"
 msgstr ""
 
-#: src/components/map/Identify.vue:57
+#: src/components/Identify.vue:57
 msgid "source-code"
 msgstr ""
 
-#: src/components/Sidebar.vue:54
+#: src/components/Sidebar.vue:40
 msgid "Staging area"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:7
+#: src/components/staging/Staging.vue:7
 msgid "Staging Area"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:142
+#: src/components/fairway/Profiles.vue:142
 msgid "Start"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:268
+#: src/components/ImportSoundingresults.vue:279
 msgid "Starting import for "
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:57
+#: src/components/ImportApprovedGaugeMeasurement.vue:100
+msgid "Starting import of Approved Gauge Measurements"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:67
 msgid "State"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:85
-#: src/components/admin/usermanagement/Userdetail.vue:129
+#: src/components/importschedule/Importscheduledetail.vue:394
+#: src/components/usermanagement/Userdetail.vue:129
 msgid "Submit"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:377
+#: src/components/fairway/Profiles.vue:381
 msgid "Success"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:34
+#: src/components/importqueue/Importqueue.vue:34
 msgid "Successful"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:88
+#: src/components/importschedule/Importscheduledetail.vue:466
+msgid "Sunday"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:88
 msgid "Sysadmin"
 msgstr ""
 
-#: src/components/Sidebar.vue:57
+#: src/components/usermanagement/Usermanagement.vue:326
+msgid "System-Administrator"
+msgstr ""
+
+#: src/components/Sidebar.vue:97
 msgid "Systemadministration"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:8
+#: src/components/Systemconfiguration.vue:8
 msgid "Systemconfiguration"
 msgstr ""
 
-#: src/components/map/Identify.vue:51
+#: src/components/Identify.vue:51
 msgid ""
 "This app uses <i>gemma</i>, which is Free Software under <br/>\n"
 "        %{ license } without warranty, see docs for details."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:34
-#: src/components/map/contextbox/Staging.vue:13
+#: src/components/importschedule/Importscheduledetail.vue:463
+msgid "Thursday"
+msgstr ""
+
+#: src/components/ImportApprovedGaugeMeasurement.vue:43
+#: src/components/ImportWaterwayProfiles.vue:43
+#: src/components/importschedule/Importscheduledetail.vue:407
+msgid "Trigger import"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:461
+msgid "Tuesday"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:34
+#: src/components/staging/Staging.vue:12
 msgid "Type"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:313
+#: src/components/ImportWaterwayProfiles.vue:89
+msgid "under construction"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:738
+msgid "update import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:324
 msgid "Upload"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:55
+#: src/components/importschedule/Importscheduledetail.vue:72
+msgid "URL"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:61
 msgid "User"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:14
-#: src/components/map/contextbox/Staging.vue:16
+#: src/components/importschedule/Importscheduledetail.vue:117
+#: src/components/staging/Staging.vue:18
+#: src/components/usermanagement/Userdetail.vue:14
 msgid "Username"
 msgstr ""
 
-#: src/components/Sidebar.vue:66
-#: src/components/admin/usermanagement/Usermanagement.vue:14
+#: src/components/Sidebar.vue:108
+#: src/components/usermanagement/Usermanagement.vue:14
 msgid "Users"
 msgstr ""
 
-#: src/components/map/Identify.vue:65
+#: src/components/Identify.vue:65
 msgid ""
 "Uses\n"
 "        <a href=\"https://download.geonames.org/export/dump/readme.txt\">GeoNames</a>\n"
 "        under %{ geoLicense }."
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Usermanagement.vue:327
 msgid "Waterway Admin"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:94
+#: src/components/importschedule/Importscheduledetail.vue:28
+msgid "Waterway axis"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:43
+msgid "Waterway gauges"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:94
+#: src/components/usermanagement/Usermanagement.vue:328
 msgid "Waterway User"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:439
-#: src/components/map/fairway/Profiles.vue:440
+#: src/components/importschedule/Importscheduledetail.vue:37
+msgid "Waterwayarea"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:462
+msgid "Wednesday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:455
+msgid "week"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:246
+msgid "Weekly"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:457
+msgid "year"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:443
+#: src/components/fairway/Profiles.vue:444
 msgid "You can now select these coordinates from the \"Saved cross profiles\" menu to restore this cross profile."
 msgstr ""
 
-#: src/store/map.js:415
+#: src/store/map.js:416
 msgid "Length"
 msgstr ""
 
-#: src/store/map.js:436
+#: src/store/map.js:437
 msgid "Area"
 msgstr ""
--- a/client/src/locale/ro_RO/LC_MESSAGES/app.po	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/locale/ro_RO/LC_MESSAGES/app.po	Tue Jan 15 10:07:10 2019 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gemmajs 1.99.0-dev\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-12-10 15:30+0100\n"
+"POT-Creation-Date: 2019-01-15 10:04+0100\n"
 "PO-Revision-Date: 2018-12-05 12:23+0100\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -17,138 +17,200 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;\n"
 
-#: src/components/admin/Importqueue.vue:46
+#: src/components/importschedule/Importscheduledetail.vue:452
+msgid "15 minutes"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:46
 msgid "Accepted"
 msgstr ""
 
-#: src/components/admin/Logs.vue:25
+#: src/components/Logs.vue:25
 msgid "Accesslog"
 msgstr ""
 
-#: src/components/admin/usermanagement/Usermanagement.vue:103
+#: src/components/usermanagement/Usermanagement.vue:104
 msgid "Add User"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:35
+#: src/components/importschedule/Importscheduledetail.vue:472
+msgid "April"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:449
+msgid "at"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:476
+msgid "August"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:35
 msgid "Author"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:34
+msgid "Available Fairway Depths"
+msgstr ""
+
 #: src/components/Login.vue:70
 msgid "back to login"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:136
-#: src/components/admin/Systemconfiguration.vue:134
-#: src/components/admin/Systemconfiguration.vue:149
-#: src/components/admin/Systemconfiguration.vue:168
-#: src/components/admin/Systemconfiguration.vue:185
-#: src/components/admin/usermanagement/Userdetail.vue:305
-#: src/components/admin/usermanagement/Userdetail.vue:377
-#: src/components/admin/usermanagement/Usermanagement.vue:313
-#: src/components/admin/usermanagement/Usermanagement.vue:321
-#: src/components/admin/usermanagement/Usermanagement.vue:347
-#: src/components/map/Search.vue:257
-#: src/components/map/contextbox/Bottlenecks.vue:275
-#: src/components/map/contextbox/ImportSoundingresults.vue:205
-#: src/components/map/contextbox/ImportSoundingresults.vue:244
-#: src/components/map/contextbox/ImportSoundingresults.vue:275
+#: src/components/Bottlenecks.vue:274
+#: src/components/ImportApprovedGaugeMeasurement.vue:107
+#: src/components/ImportSoundingresults.vue:216
+#: src/components/ImportSoundingresults.vue:255
+#: src/components/ImportSoundingresults.vue:286 src/components/Search.vue:258
+#: src/components/Systemconfiguration.vue:114
+#: src/components/Systemconfiguration.vue:129
+#: src/components/Systemconfiguration.vue:148
+#: src/components/Systemconfiguration.vue:165
+#: src/components/importqueue/Importqueue.vue:160
+#: src/components/importqueue/Importqueue.vue:180
+#: src/components/importqueue/Importqueuedetail.vue:182
+#: src/components/importschedule/Importschedule.vue:148
+#: src/components/importschedule/Importschedule.vue:167
+#: src/components/importschedule/Importschedule.vue:176
+#: src/components/importschedule/Importschedule.vue:198
+#: src/components/importschedule/Importscheduledetail.vue:656
+#: src/components/importschedule/Importscheduledetail.vue:724
+#: src/components/importschedule/Importscheduledetail.vue:752
+#: src/components/staging/StagingDetail.vue:246
+#: src/components/usermanagement/Userdetail.vue:304
+#: src/components/usermanagement/Userdetail.vue:376
+#: src/components/usermanagement/Usermanagement.vue:298
+#: src/components/usermanagement/Usermanagement.vue:306
+#: src/components/usermanagement/Usermanagement.vue:340
+#: src/components/importschedule/Importscheduledetail.vue:716
+#: src/components/importschedule/Importscheduledetail.vue:744
 msgid "Backend Error"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:11
+#: src/components/ImportSoundingresults.vue:16
 msgid "Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:19
+#: src/components/Systemconfiguration.vue:19
 msgid "Bottleneck Areas fill-color"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:13
+#: src/components/Systemconfiguration.vue:13
 msgid "Bottleneck Areas stroke-color"
 msgstr ""
 
-#: src/components/Sidebar.vue:27
-#: src/components/map/contextbox/Bottlenecks.vue:4
+#: src/components/Bottlenecks.vue:4 src/components/Sidebar.vue:27
+#: src/components/importschedule/Importscheduledetail.vue:25
+#: src/components/staging/StagingDetail.vue:11
 msgid "Bottlenecks"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:121
+#: src/components/ImportSoundingresults.vue:126
 msgid "Cancel Upload"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:30
+#: src/components/Bottlenecks.vue:30
 msgid "Chainage"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:167
-#: src/components/map/contextbox/ImportSoundingresults.vue:181
+#: src/components/ImportSoundingresults.vue:178
+#: src/components/ImportSoundingresults.vue:192
 msgid "choose .zip- file"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:18
-msgid "Chose format:"
+#: src/components/ImportApprovedGaugeMeasurement.vue:76
+#: src/components/ImportWaterwayProfiles.vue:75
+msgid "choose file to upload"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:64
+#: src/components/Pdftool.vue:18
+msgid "Choose format:"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:64
 msgid "Compare with"
 msgstr ""
 
-#: src/components/Sidebar.vue:76
+#: src/components/Sidebar.vue:116
 msgid "Configuration"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:316
-#: src/components/map/contextbox/Staging.vue:70
+#: src/components/ImportSoundingresults.vue:327
+#: src/components/staging/Staging.vue:33
 msgid "Confirm"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:378
+#: src/components/fairway/Profiles.vue:382
 msgid "Coordinates copied to clipboard!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:33
+#: src/components/usermanagement/Userdetail.vue:33
 msgid "Country"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:67
-#: src/components/map/contextbox/Staging.vue:14
+#: src/components/importschedule/Importscheduledetail.vue:382
+msgid "Cronstring"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:72
+#: src/components/importqueue/Importqueuedetail.vue:49
+#: src/components/staging/Staging.vue:13
 msgid "Date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:47
+#: src/components/importschedule/Importscheduledetail.vue:454
+msgid "day"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:480
+msgid "December"
+msgstr ""
+
+#: src/components/ImportStretches.vue:4
+msgid "Define section and stretches"
+msgstr ""
+
+#: src/components/Sidebar.vue:52
+msgid "Define sections and stretches"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:192
+msgid "Deleted import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:52
 msgid "Depthreference"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:32
+#: src/components/Pdftool.vue:36
 msgid "Download"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:113
+#: src/components/ImportSoundingresults.vue:118
 msgid "Download Meta.json"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:37
-#: src/components/admin/importschedule/Importscheduledetail.vue:80
+#: src/components/importschedule/Importschedule.vue:37
 msgid "Email"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:59
+#: src/components/usermanagement/Userdetail.vue:59
 msgid "Email address"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:61
+#: src/components/importschedule/Importscheduledetail.vue:50
 msgid "Email Notification"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:53
+#: src/components/importqueue/Importqueue.vue:55
 msgid "Enqueued"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:123
+#: src/components/fairway/Profiles.vue:123
 msgid "Enter coordinates manually"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:185
+#: src/components/fairway/Profiles.vue:185
 msgid "Enter label for cross profile"
 msgstr ""
 
@@ -160,89 +222,160 @@
 msgid "Enter username"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:386
+#: src/components/usermanagement/Userdetail.vue:385
 msgid "Error while saving user"
 msgstr ""
 
-#: src/components/admin/Logs.vue:34
+#: src/components/Logs.vue:34
 msgid "Errorlog"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:37
+#: src/components/importschedule/Importscheduledetail.vue:445
+msgid "Every"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:37
 msgid "Failed"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:40
+msgid "Fairwaydimensions"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:155
+msgid "Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:470
+msgid "February"
+msgstr ""
+
 #: src/components/Login.vue:76
 msgid "Forgot password"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:10 src/components/map/Pdftool.vue:49
+#: src/components/importschedule/Importscheduledetail.vue:464
+msgid "Friday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:31
+msgid "Gauge measurement"
+msgstr ""
+
+#: src/components/Pdftool.vue:10 src/components/Pdftool.vue:53
 msgid "Generate PDF"
 msgstr ""
 
-#: src/components/map/Identify.vue:10
+#: src/components/importschedule/Importscheduledetail.vue:453
+msgid "hour"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:52
+msgid "Id"
+msgstr ""
+
+#: src/components/Identify.vue:10
 msgid "Identified"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:33
-#: src/components/map/contextbox/ImportSoundingresults.vue:267
+#: src/components/ImportApprovedGaugeMeasurement.vue:99
+#: src/components/ImportSoundingresults.vue:278
+#: src/components/ImportWaterwayProfiles.vue:88 src/components/Sidebar.vue:56
+#: src/components/importschedule/Importschedule.vue:33
+#: src/components/importschedule/Importscheduledetail.vue:519
+#: src/components/importschedule/Importscheduledetail.vue:649
+#: src/components/importschedule/Importscheduledetail.vue:709
+#: src/components/importschedule/Importscheduledetail.vue:737
 msgid "Import"
 msgstr ""
 
-#: src/components/Sidebar.vue:40
+#: src/components/ImportApprovedGaugeMeasurement.vue:11
+#: src/components/Sidebar.vue:74
+msgid "Import approved gaugemeasurements"
+msgstr ""
+
+#: src/components/Sidebar.vue:64
 msgid "Import soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:4
+#: src/components/ImportSoundingresults.vue:9
 msgid "Import Soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:15
+#: src/components/Sidebar.vue:84
+msgid "Import waterway profiles"
+msgstr ""
+
+#: src/components/ImportWaterwayProfiles.vue:11
+msgid "Import Waterwayprofiles"
+msgstr ""
+
+#: src/components/staging/Staging.vue:15
 msgid "Imported"
 msgstr ""
 
-#: src/components/Sidebar.vue:92 src/components/admin/Importqueue.vue:9
+#: src/components/Sidebar.vue:134 src/components/importqueue/Importqueue.vue:9
 msgid "Importqueue"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:20
+#: src/components/Sidebar.vue:94
+#: src/components/importschedule/Importschedule.vue:9
+#: src/components/importschedule/Importschedule.vue:160
+#: src/components/importschedule/Importschedule.vue:191
+#: src/components/importschedule/Importscheduledetail.vue:20
 msgid "Imports"
 msgstr ""
 
-#: src/components/Sidebar.vue:100
-#: src/components/admin/importschedule/Importschedule.vue:9
-msgid "Importschedule"
+#: src/components/importschedule/Importscheduledetail.vue:81
+msgid "Insecure"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:34
-msgid "Importtype"
-msgstr ""
-
-#: src/components/admin/usermanagement/Userdetail.vue:354
+#: src/components/usermanagement/Userdetail.vue:353
 msgid "invalid email"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:412
+#: src/components/fairway/Profiles.vue:416
 msgid "Invalid input"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:54
+#: src/components/Pdftool.vue:24
+msgid "ISO A3"
+msgstr ""
+
+#: src/components/Pdftool.vue:25
+msgid "ISO A4"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:469
+msgid "January"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:475
+msgid "July"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:474
+msgid "June"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:58
+#: src/components/importqueue/Importqueuedetail.vue:45
 msgid "Kind"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:20
+#: src/components/Pdftool.vue:20
 msgid "landscape"
 msgstr ""
 
-#: src/components/admin/Logs.vue:41
+#: src/components/Logs.vue:41
 msgid "Last refresh:"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:19
+#: src/components/Bottlenecks.vue:19
 msgid "Latest"
 msgstr ""
 
-#: src/components/map/layers/Layers.vue:10
+#: src/components/layers/Layers.vue:10
 msgid "Layers"
 msgstr ""
 
@@ -254,65 +387,114 @@
 msgid "Login failed"
 msgstr ""
 
-#: src/components/Sidebar.vue:110
+#: src/components/Sidebar.vue:144
 msgid "Logout"
 msgstr ""
 
-#: src/components/Sidebar.vue:84 src/components/admin/Logs.vue:9
+#: src/components/Logs.vue:9 src/components/Sidebar.vue:124
 msgid "Logs"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:140
+#: src/components/usermanagement/Userdetail.vue:140
 msgid "Mail was sent"
 msgstr ""
 
+#: src/components/importschedule/Importschedule.vue:161
+#: src/components/importschedule/Importscheduledetail.vue:650
+msgid "Manually triggered import: #"
+msgstr ""
+
 #: src/components/Sidebar.vue:15
 msgid "Map"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:20
+#: src/components/importschedule/Importscheduledetail.vue:471
+msgid "March"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:473
+msgid "May"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:20
 msgid "Measurement"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:9
-#: src/components/map/contextbox/Staging.vue:12
+#: src/components/importqueue/Importqueuedetail.vue:58
+msgid "Message"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:446
+msgid "minutes past"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:460
+msgid "Monday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:456
+msgid "month"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:247
+msgid "Monthly"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:9 src/components/staging/Staging.vue:11
 msgid "Name"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:9
-msgid "New import"
-msgstr ""
-
-#: src/components/admin/importschedule/Importschedule.vue:72
+#: src/components/importschedule/Importschedule.vue:93
+#: src/components/importschedule/Importscheduledetail.vue:520
 msgid "New Import"
 msgstr ""
 
-#: src/components/map/Identify.vue:47
+#: src/components/Identify.vue:47
 msgid "No features identified."
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:116
-#: src/components/map/contextbox/Staging.vue:63
+#: src/components/Bottlenecks.vue:115 src/components/staging/Staging.vue:36
 msgid "No results."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:66
-msgid "No schedules"
+#: src/components/importschedule/Importschedule.vue:85
+msgid "No scheduled imports"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:479
+msgid "November"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:450
+msgid "o' clock"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:41
+#: src/components/importschedule/Importscheduledetail.vue:478
+msgid "October"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:448
+msgid "of"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:447
+msgid "on"
+msgstr ""
+
+#: src/components/Pdftool.vue:45
 msgid "Open in new window"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:238
+#: src/components/usermanagement/Userdetail.vue:237
 msgid "password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:236
+#: src/components/importschedule/Importscheduledetail.vue:134
+#: src/components/usermanagement/Userdetail.vue:235
 msgid "Password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:239
+#: src/components/usermanagement/Userdetail.vue:238
 msgid "password again"
 msgstr ""
 
@@ -320,82 +502,102 @@
 msgid "Password reset requested!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:347
-#: src/components/admin/usermanagement/Userdetail.vue:348
+#: src/components/usermanagement/Userdetail.vue:346
+#: src/components/usermanagement/Userdetail.vue:347
 msgid "Password should at least be 8 char long including 1 digit and 1 special char like $"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:343
+#: src/components/usermanagement/Userdetail.vue:342
 msgid "Passwords do not match!"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:40
+#: src/components/importqueue/Importqueue.vue:40
 msgid "Pending"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:332
+#: src/components/usermanagement/Userdetail.vue:331
 msgid "Please choose a country"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:337
+#: src/components/usermanagement/Userdetail.vue:336
 msgid "Please choose a role"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:79
+#: src/components/ImportSoundingresults.vue:84
 msgid "Please enter a date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:39
+#: src/components/importschedule/Importscheduledetail.vue:167
+msgid "Please enter a Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:142
+msgid "Please enter a Password"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:44
 msgid "Please enter a projection"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:62
+#: src/components/ImportSoundingresults.vue:67
 msgid "Please enter a reference"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:413
-#: src/components/map/fairway/Profiles.vue:414
+#: src/components/importschedule/Importscheduledetail.vue:106
+msgid "Please enter a URL"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:125
+msgid "Please enter a Username"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:417
+#: src/components/fairway/Profiles.vue:418
 msgid "Please enter correct coordinates in the format: Lat,Lon,Lat,Lon"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:22
+#: src/components/importschedule/Importscheduledetail.vue:184
+msgid "Please enter SortBy"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:27
 msgid "Please select a bottleneck"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:40
-#: src/components/admin/usermanagement/Userdetail.vue:85
+#: src/components/usermanagement/Userdetail.vue:40
+#: src/components/usermanagement/Userdetail.vue:85
 msgid "Please select one"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:21
+#: src/components/Pdftool.vue:21
 msgid "portrait"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:452
+#: src/components/fairway/Profiles.vue:456
 msgid "Profile deleted!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:438
+#: src/components/fairway/Profiles.vue:442
 msgid "Profile saved!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:10
+#: src/components/fairway/Profiles.vue:10
 msgid "Profiles"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:28
+#: src/components/ImportSoundingresults.vue:33
 msgid "Projection"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:72 src/components/admin/Logs.vue:48
+#: src/components/Logs.vue:48 src/components/importqueue/Importqueue.vue:84
 msgid "Refresh"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:43
+#: src/components/importqueue/Importqueue.vue:43
 msgid "Rejected"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:237
+#: src/components/usermanagement/Userdetail.vue:236
 msgid "Repeat Password"
 msgstr ""
 
@@ -403,148 +605,241 @@
 msgid "Request password reset!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:78
+#: src/components/usermanagement/Userdetail.vue:78
 msgid "Role"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:82
+#: src/components/importschedule/Importscheduledetail.vue:465
+msgid "Saturday"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:82
 msgid "Saved cross profiles"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:36
-#: src/components/admin/importschedule/Importscheduledetail.vue:48
+#: src/components/importschedule/Importscheduledetail.vue:710
+msgid "Saved import: #"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:36
+#: src/components/importschedule/Importscheduledetail.vue:238
 msgid "Schedule"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:32
+#: src/components/importschedule/Importscheduledetail.vue:196
+msgid "Scheduled"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:32
 msgid "Select Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:25
+#: src/components/Systemconfiguration.vue:25
 msgid "Send"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:138
+#: src/components/usermanagement/Userdetail.vue:138
 msgid "Send testmail"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:56
+#: src/components/importschedule/Importscheduledetail.vue:477
+msgid "September"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:64
 msgid "Signer"
 msgstr ""
 
-#: src/components/map/Identify.vue:60
+#: src/components/importschedule/Importscheduledetail.vue:216
+msgid "Simple Schedule"
+msgstr ""
+
+#: src/components/Identify.vue:60
 msgid ""
 "Some data ©\n"
 "        <a href=\"https://www.openstreetmap.org/copyright\">%{ name }</a>\n"
 "        contributors."
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:45
+#: src/components/importschedule/Importscheduledetail.vue:176
+msgid "SortBy"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:45
 msgid "Sounding Result"
 msgstr ""
 
-#: src/components/map/Identify.vue:57
+#: src/components/Identify.vue:57
 msgid "source-code"
 msgstr ""
 
-#: src/components/Sidebar.vue:54
+#: src/components/Sidebar.vue:40
 msgid "Staging area"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:7
+#: src/components/staging/Staging.vue:7
 msgid "Staging Area"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:142
+#: src/components/fairway/Profiles.vue:142
 msgid "Start"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:268
+#: src/components/ImportSoundingresults.vue:279
 msgid "Starting import for "
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:57
+#: src/components/ImportApprovedGaugeMeasurement.vue:100
+msgid "Starting import of Approved Gauge Measurements"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:67
 msgid "State"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:85
-#: src/components/admin/usermanagement/Userdetail.vue:129
+#: src/components/importschedule/Importscheduledetail.vue:394
+#: src/components/usermanagement/Userdetail.vue:129
 msgid "Submit"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:377
+#: src/components/fairway/Profiles.vue:381
 msgid "Success"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:34
+#: src/components/importqueue/Importqueue.vue:34
 msgid "Successful"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:88
+#: src/components/importschedule/Importscheduledetail.vue:466
+msgid "Sunday"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:88
 msgid "Sysadmin"
 msgstr ""
 
-#: src/components/Sidebar.vue:57
+#: src/components/usermanagement/Usermanagement.vue:326
+msgid "System-Administrator"
+msgstr ""
+
+#: src/components/Sidebar.vue:97
 msgid "Systemadministration"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:8
+#: src/components/Systemconfiguration.vue:8
 msgid "Systemconfiguration"
 msgstr ""
 
-#: src/components/map/Identify.vue:51
+#: src/components/Identify.vue:51
 msgid ""
 "This app uses <i>gemma</i>, which is Free Software under <br/>\n"
 "        %{ license } without warranty, see docs for details."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:34
-#: src/components/map/contextbox/Staging.vue:13
+#: src/components/importschedule/Importscheduledetail.vue:463
+msgid "Thursday"
+msgstr ""
+
+#: src/components/ImportApprovedGaugeMeasurement.vue:43
+#: src/components/ImportWaterwayProfiles.vue:43
+#: src/components/importschedule/Importscheduledetail.vue:407
+msgid "Trigger import"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:461
+msgid "Tuesday"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:34
+#: src/components/staging/Staging.vue:12
 msgid "Type"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:313
+#: src/components/ImportWaterwayProfiles.vue:89
+msgid "under construction"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:738
+msgid "update import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:324
 msgid "Upload"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:55
+#: src/components/importschedule/Importscheduledetail.vue:72
+msgid "URL"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:61
 msgid "User"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:14
-#: src/components/map/contextbox/Staging.vue:16
+#: src/components/importschedule/Importscheduledetail.vue:117
+#: src/components/staging/Staging.vue:18
+#: src/components/usermanagement/Userdetail.vue:14
 msgid "Username"
 msgstr ""
 
-#: src/components/Sidebar.vue:66
-#: src/components/admin/usermanagement/Usermanagement.vue:14
+#: src/components/Sidebar.vue:108
+#: src/components/usermanagement/Usermanagement.vue:14
 msgid "Users"
 msgstr ""
 
-#: src/components/map/Identify.vue:65
+#: src/components/Identify.vue:65
 msgid ""
 "Uses\n"
 "        <a href=\"https://download.geonames.org/export/dump/readme.txt\">GeoNames</a>\n"
 "        under %{ geoLicense }."
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Usermanagement.vue:327
 msgid "Waterway Admin"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:94
+#: src/components/importschedule/Importscheduledetail.vue:28
+msgid "Waterway axis"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:43
+msgid "Waterway gauges"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:94
+#: src/components/usermanagement/Usermanagement.vue:328
 msgid "Waterway User"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:439
-#: src/components/map/fairway/Profiles.vue:440
+#: src/components/importschedule/Importscheduledetail.vue:37
+msgid "Waterwayarea"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:462
+msgid "Wednesday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:455
+msgid "week"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:246
+msgid "Weekly"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:457
+msgid "year"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:443
+#: src/components/fairway/Profiles.vue:444
 msgid "You can now select these coordinates from the \"Saved cross profiles\" menu to restore this cross profile."
 msgstr ""
 
-#: src/store/map.js:415
+#: src/store/map.js:416
 msgid "Length"
 msgstr ""
 
-#: src/store/map.js:436
+#: src/store/map.js:437
 msgid "Area"
 msgstr ""
--- a/client/src/locale/sk_SK/LC_MESSAGES/app.po	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/locale/sk_SK/LC_MESSAGES/app.po	Tue Jan 15 10:07:10 2019 +0100
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: wamosjs 0.1.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-12-10 15:30+0100\n"
+"POT-Creation-Date: 2019-01-15 10:04+0100\n"
 "PO-Revision-Date: 2018-07-03 17:18+0200\n"
 "Last-Translator: Automatically generated\n"
 "Language-Team: none\n"
@@ -17,138 +17,200 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/components/admin/Importqueue.vue:46
+#: src/components/importschedule/Importscheduledetail.vue:452
+msgid "15 minutes"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:46
 msgid "Accepted"
 msgstr ""
 
-#: src/components/admin/Logs.vue:25
+#: src/components/Logs.vue:25
 msgid "Accesslog"
 msgstr ""
 
-#: src/components/admin/usermanagement/Usermanagement.vue:103
+#: src/components/usermanagement/Usermanagement.vue:104
 msgid "Add User"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:35
+#: src/components/importschedule/Importscheduledetail.vue:472
+msgid "April"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:449
+msgid "at"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:476
+msgid "August"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:35
 msgid "Author"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:34
+msgid "Available Fairway Depths"
+msgstr ""
+
 #: src/components/Login.vue:70
 msgid "back to login"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:136
-#: src/components/admin/Systemconfiguration.vue:134
-#: src/components/admin/Systemconfiguration.vue:149
-#: src/components/admin/Systemconfiguration.vue:168
-#: src/components/admin/Systemconfiguration.vue:185
-#: src/components/admin/usermanagement/Userdetail.vue:305
-#: src/components/admin/usermanagement/Userdetail.vue:377
-#: src/components/admin/usermanagement/Usermanagement.vue:313
-#: src/components/admin/usermanagement/Usermanagement.vue:321
-#: src/components/admin/usermanagement/Usermanagement.vue:347
-#: src/components/map/Search.vue:257
-#: src/components/map/contextbox/Bottlenecks.vue:275
-#: src/components/map/contextbox/ImportSoundingresults.vue:205
-#: src/components/map/contextbox/ImportSoundingresults.vue:244
-#: src/components/map/contextbox/ImportSoundingresults.vue:275
+#: src/components/Bottlenecks.vue:274
+#: src/components/ImportApprovedGaugeMeasurement.vue:107
+#: src/components/ImportSoundingresults.vue:216
+#: src/components/ImportSoundingresults.vue:255
+#: src/components/ImportSoundingresults.vue:286 src/components/Search.vue:258
+#: src/components/Systemconfiguration.vue:114
+#: src/components/Systemconfiguration.vue:129
+#: src/components/Systemconfiguration.vue:148
+#: src/components/Systemconfiguration.vue:165
+#: src/components/importqueue/Importqueue.vue:160
+#: src/components/importqueue/Importqueue.vue:180
+#: src/components/importqueue/Importqueuedetail.vue:182
+#: src/components/importschedule/Importschedule.vue:148
+#: src/components/importschedule/Importschedule.vue:167
+#: src/components/importschedule/Importschedule.vue:176
+#: src/components/importschedule/Importschedule.vue:198
+#: src/components/importschedule/Importscheduledetail.vue:656
+#: src/components/importschedule/Importscheduledetail.vue:724
+#: src/components/importschedule/Importscheduledetail.vue:752
+#: src/components/staging/StagingDetail.vue:246
+#: src/components/usermanagement/Userdetail.vue:304
+#: src/components/usermanagement/Userdetail.vue:376
+#: src/components/usermanagement/Usermanagement.vue:298
+#: src/components/usermanagement/Usermanagement.vue:306
+#: src/components/usermanagement/Usermanagement.vue:340
+#: src/components/importschedule/Importscheduledetail.vue:716
+#: src/components/importschedule/Importscheduledetail.vue:744
 msgid "Backend Error"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:11
+#: src/components/ImportSoundingresults.vue:16
 msgid "Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:19
+#: src/components/Systemconfiguration.vue:19
 msgid "Bottleneck Areas fill-color"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:13
+#: src/components/Systemconfiguration.vue:13
 msgid "Bottleneck Areas stroke-color"
 msgstr ""
 
-#: src/components/Sidebar.vue:27
-#: src/components/map/contextbox/Bottlenecks.vue:4
+#: src/components/Bottlenecks.vue:4 src/components/Sidebar.vue:27
+#: src/components/importschedule/Importscheduledetail.vue:25
+#: src/components/staging/StagingDetail.vue:11
 msgid "Bottlenecks"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:121
+#: src/components/ImportSoundingresults.vue:126
 msgid "Cancel Upload"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:30
+#: src/components/Bottlenecks.vue:30
 msgid "Chainage"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:167
-#: src/components/map/contextbox/ImportSoundingresults.vue:181
+#: src/components/ImportSoundingresults.vue:178
+#: src/components/ImportSoundingresults.vue:192
 msgid "choose .zip- file"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:18
-msgid "Chose format:"
+#: src/components/ImportApprovedGaugeMeasurement.vue:76
+#: src/components/ImportWaterwayProfiles.vue:75
+msgid "choose file to upload"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:64
+#: src/components/Pdftool.vue:18
+msgid "Choose format:"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:64
 msgid "Compare with"
 msgstr ""
 
-#: src/components/Sidebar.vue:76
+#: src/components/Sidebar.vue:116
 msgid "Configuration"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:316
-#: src/components/map/contextbox/Staging.vue:70
+#: src/components/ImportSoundingresults.vue:327
+#: src/components/staging/Staging.vue:33
 msgid "Confirm"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:378
+#: src/components/fairway/Profiles.vue:382
 msgid "Coordinates copied to clipboard!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:33
+#: src/components/usermanagement/Userdetail.vue:33
 msgid "Country"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:67
-#: src/components/map/contextbox/Staging.vue:14
+#: src/components/importschedule/Importscheduledetail.vue:382
+msgid "Cronstring"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:72
+#: src/components/importqueue/Importqueuedetail.vue:49
+#: src/components/staging/Staging.vue:13
 msgid "Date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:47
+#: src/components/importschedule/Importscheduledetail.vue:454
+msgid "day"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:480
+msgid "December"
+msgstr ""
+
+#: src/components/ImportStretches.vue:4
+msgid "Define section and stretches"
+msgstr ""
+
+#: src/components/Sidebar.vue:52
+msgid "Define sections and stretches"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:192
+msgid "Deleted import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:52
 msgid "Depthreference"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:32
+#: src/components/Pdftool.vue:36
 msgid "Download"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:113
+#: src/components/ImportSoundingresults.vue:118
 msgid "Download Meta.json"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:37
-#: src/components/admin/importschedule/Importscheduledetail.vue:80
+#: src/components/importschedule/Importschedule.vue:37
 msgid "Email"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:59
+#: src/components/usermanagement/Userdetail.vue:59
 msgid "Email address"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:61
+#: src/components/importschedule/Importscheduledetail.vue:50
 msgid "Email Notification"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:53
+#: src/components/importqueue/Importqueue.vue:55
 msgid "Enqueued"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:123
+#: src/components/fairway/Profiles.vue:123
 msgid "Enter coordinates manually"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:185
+#: src/components/fairway/Profiles.vue:185
 msgid "Enter label for cross profile"
 msgstr ""
 
@@ -160,89 +222,160 @@
 msgid "Enter username"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:386
+#: src/components/usermanagement/Userdetail.vue:385
 msgid "Error while saving user"
 msgstr ""
 
-#: src/components/admin/Logs.vue:34
+#: src/components/Logs.vue:34
 msgid "Errorlog"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:37
+#: src/components/importschedule/Importscheduledetail.vue:445
+msgid "Every"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:37
 msgid "Failed"
 msgstr ""
 
+#: src/components/importschedule/Importscheduledetail.vue:40
+msgid "Fairwaydimensions"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:155
+msgid "Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:470
+msgid "February"
+msgstr ""
+
 #: src/components/Login.vue:76
 msgid "Forgot password"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:10 src/components/map/Pdftool.vue:49
+#: src/components/importschedule/Importscheduledetail.vue:464
+msgid "Friday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:31
+msgid "Gauge measurement"
+msgstr ""
+
+#: src/components/Pdftool.vue:10 src/components/Pdftool.vue:53
 msgid "Generate PDF"
 msgstr ""
 
-#: src/components/map/Identify.vue:10
+#: src/components/importschedule/Importscheduledetail.vue:453
+msgid "hour"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:52
+msgid "Id"
+msgstr ""
+
+#: src/components/Identify.vue:10
 msgid "Identified"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:33
-#: src/components/map/contextbox/ImportSoundingresults.vue:267
+#: src/components/ImportApprovedGaugeMeasurement.vue:99
+#: src/components/ImportSoundingresults.vue:278
+#: src/components/ImportWaterwayProfiles.vue:88 src/components/Sidebar.vue:56
+#: src/components/importschedule/Importschedule.vue:33
+#: src/components/importschedule/Importscheduledetail.vue:519
+#: src/components/importschedule/Importscheduledetail.vue:649
+#: src/components/importschedule/Importscheduledetail.vue:709
+#: src/components/importschedule/Importscheduledetail.vue:737
 msgid "Import"
 msgstr ""
 
-#: src/components/Sidebar.vue:40
+#: src/components/ImportApprovedGaugeMeasurement.vue:11
+#: src/components/Sidebar.vue:74
+msgid "Import approved gaugemeasurements"
+msgstr ""
+
+#: src/components/Sidebar.vue:64
 msgid "Import soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:4
+#: src/components/ImportSoundingresults.vue:9
 msgid "Import Soundingresults"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:15
+#: src/components/Sidebar.vue:84
+msgid "Import waterway profiles"
+msgstr ""
+
+#: src/components/ImportWaterwayProfiles.vue:11
+msgid "Import Waterwayprofiles"
+msgstr ""
+
+#: src/components/staging/Staging.vue:15
 msgid "Imported"
 msgstr ""
 
-#: src/components/Sidebar.vue:92 src/components/admin/Importqueue.vue:9
+#: src/components/Sidebar.vue:134 src/components/importqueue/Importqueue.vue:9
 msgid "Importqueue"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:20
+#: src/components/Sidebar.vue:94
+#: src/components/importschedule/Importschedule.vue:9
+#: src/components/importschedule/Importschedule.vue:160
+#: src/components/importschedule/Importschedule.vue:191
+#: src/components/importschedule/Importscheduledetail.vue:20
 msgid "Imports"
 msgstr ""
 
-#: src/components/Sidebar.vue:100
-#: src/components/admin/importschedule/Importschedule.vue:9
-msgid "Importschedule"
+#: src/components/importschedule/Importscheduledetail.vue:81
+msgid "Insecure"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:34
-msgid "Importtype"
-msgstr ""
-
-#: src/components/admin/usermanagement/Userdetail.vue:354
+#: src/components/usermanagement/Userdetail.vue:353
 msgid "invalid email"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:412
+#: src/components/fairway/Profiles.vue:416
 msgid "Invalid input"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:54
+#: src/components/Pdftool.vue:24
+msgid "ISO A3"
+msgstr ""
+
+#: src/components/Pdftool.vue:25
+msgid "ISO A4"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:469
+msgid "January"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:475
+msgid "July"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:474
+msgid "June"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:58
+#: src/components/importqueue/Importqueuedetail.vue:45
 msgid "Kind"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:20
+#: src/components/Pdftool.vue:20
 msgid "landscape"
 msgstr ""
 
-#: src/components/admin/Logs.vue:41
+#: src/components/Logs.vue:41
 msgid "Last refresh:"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:19
+#: src/components/Bottlenecks.vue:19
 msgid "Latest"
 msgstr ""
 
-#: src/components/map/layers/Layers.vue:10
+#: src/components/layers/Layers.vue:10
 msgid "Layers"
 msgstr ""
 
@@ -254,65 +387,114 @@
 msgid "Login failed"
 msgstr ""
 
-#: src/components/Sidebar.vue:110
+#: src/components/Sidebar.vue:144
 msgid "Logout"
 msgstr ""
 
-#: src/components/Sidebar.vue:84 src/components/admin/Logs.vue:9
+#: src/components/Logs.vue:9 src/components/Sidebar.vue:124
 msgid "Logs"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:140
+#: src/components/usermanagement/Userdetail.vue:140
 msgid "Mail was sent"
 msgstr ""
 
+#: src/components/importschedule/Importschedule.vue:161
+#: src/components/importschedule/Importscheduledetail.vue:650
+msgid "Manually triggered import: #"
+msgstr ""
+
 #: src/components/Sidebar.vue:15
 msgid "Map"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:20
+#: src/components/importschedule/Importscheduledetail.vue:471
+msgid "March"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:473
+msgid "May"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:20
 msgid "Measurement"
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:9
-#: src/components/map/contextbox/Staging.vue:12
+#: src/components/importqueue/Importqueuedetail.vue:58
+msgid "Message"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:446
+msgid "minutes past"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:460
+msgid "Monday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:456
+msgid "month"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:247
+msgid "Monthly"
+msgstr ""
+
+#: src/components/Bottlenecks.vue:9 src/components/staging/Staging.vue:11
 msgid "Name"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:9
-msgid "New import"
-msgstr ""
-
-#: src/components/admin/importschedule/Importschedule.vue:72
+#: src/components/importschedule/Importschedule.vue:93
+#: src/components/importschedule/Importscheduledetail.vue:520
 msgid "New Import"
 msgstr ""
 
-#: src/components/map/Identify.vue:47
+#: src/components/Identify.vue:47
 msgid "No features identified."
 msgstr ""
 
-#: src/components/map/contextbox/Bottlenecks.vue:116
-#: src/components/map/contextbox/Staging.vue:63
+#: src/components/Bottlenecks.vue:115 src/components/staging/Staging.vue:36
 msgid "No results."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:66
-msgid "No schedules"
+#: src/components/importschedule/Importschedule.vue:85
+msgid "No scheduled imports"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:479
+msgid "November"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:450
+msgid "o' clock"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:41
+#: src/components/importschedule/Importscheduledetail.vue:478
+msgid "October"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:448
+msgid "of"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:447
+msgid "on"
+msgstr ""
+
+#: src/components/Pdftool.vue:45
 msgid "Open in new window"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:238
+#: src/components/usermanagement/Userdetail.vue:237
 msgid "password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:236
+#: src/components/importschedule/Importscheduledetail.vue:134
+#: src/components/usermanagement/Userdetail.vue:235
 msgid "Password"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:239
+#: src/components/usermanagement/Userdetail.vue:238
 msgid "password again"
 msgstr ""
 
@@ -320,82 +502,102 @@
 msgid "Password reset requested!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:347
-#: src/components/admin/usermanagement/Userdetail.vue:348
+#: src/components/usermanagement/Userdetail.vue:346
+#: src/components/usermanagement/Userdetail.vue:347
 msgid "Password should at least be 8 char long including 1 digit and 1 special char like $"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:343
+#: src/components/usermanagement/Userdetail.vue:342
 msgid "Passwords do not match!"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:40
+#: src/components/importqueue/Importqueue.vue:40
 msgid "Pending"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:332
+#: src/components/usermanagement/Userdetail.vue:331
 msgid "Please choose a country"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:337
+#: src/components/usermanagement/Userdetail.vue:336
 msgid "Please choose a role"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:79
+#: src/components/ImportSoundingresults.vue:84
 msgid "Please enter a date"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:39
+#: src/components/importschedule/Importscheduledetail.vue:167
+msgid "Please enter a Featuretype"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:142
+msgid "Please enter a Password"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:44
 msgid "Please enter a projection"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:62
+#: src/components/ImportSoundingresults.vue:67
 msgid "Please enter a reference"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:413
-#: src/components/map/fairway/Profiles.vue:414
+#: src/components/importschedule/Importscheduledetail.vue:106
+msgid "Please enter a URL"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:125
+msgid "Please enter a Username"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:417
+#: src/components/fairway/Profiles.vue:418
 msgid "Please enter correct coordinates in the format: Lat,Lon,Lat,Lon"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:22
+#: src/components/importschedule/Importscheduledetail.vue:184
+msgid "Please enter SortBy"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:27
 msgid "Please select a bottleneck"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:40
-#: src/components/admin/usermanagement/Userdetail.vue:85
+#: src/components/usermanagement/Userdetail.vue:40
+#: src/components/usermanagement/Userdetail.vue:85
 msgid "Please select one"
 msgstr ""
 
-#: src/components/map/Pdftool.vue:21
+#: src/components/Pdftool.vue:21
 msgid "portrait"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:452
+#: src/components/fairway/Profiles.vue:456
 msgid "Profile deleted!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:438
+#: src/components/fairway/Profiles.vue:442
 msgid "Profile saved!"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:10
+#: src/components/fairway/Profiles.vue:10
 msgid "Profiles"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:28
+#: src/components/ImportSoundingresults.vue:33
 msgid "Projection"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:72 src/components/admin/Logs.vue:48
+#: src/components/Logs.vue:48 src/components/importqueue/Importqueue.vue:84
 msgid "Refresh"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:43
+#: src/components/importqueue/Importqueue.vue:43
 msgid "Rejected"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:237
+#: src/components/usermanagement/Userdetail.vue:236
 msgid "Repeat Password"
 msgstr ""
 
@@ -403,148 +605,241 @@
 msgid "Request password reset!"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:78
+#: src/components/usermanagement/Userdetail.vue:78
 msgid "Role"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:82
+#: src/components/importschedule/Importscheduledetail.vue:465
+msgid "Saturday"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:82
 msgid "Saved cross profiles"
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:36
-#: src/components/admin/importschedule/Importscheduledetail.vue:48
+#: src/components/importschedule/Importscheduledetail.vue:710
+msgid "Saved import: #"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:36
+#: src/components/importschedule/Importscheduledetail.vue:238
 msgid "Schedule"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:32
+#: src/components/importschedule/Importscheduledetail.vue:196
+msgid "Scheduled"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:32
 msgid "Select Bottleneck"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:25
+#: src/components/Systemconfiguration.vue:25
 msgid "Send"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:138
+#: src/components/usermanagement/Userdetail.vue:138
 msgid "Send testmail"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:56
+#: src/components/importschedule/Importscheduledetail.vue:477
+msgid "September"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:64
 msgid "Signer"
 msgstr ""
 
-#: src/components/map/Identify.vue:60
+#: src/components/importschedule/Importscheduledetail.vue:216
+msgid "Simple Schedule"
+msgstr ""
+
+#: src/components/Identify.vue:60
 msgid ""
 "Some data ©\n"
 "        <a href=\"https://www.openstreetmap.org/copyright\">%{ name }</a>\n"
 "        contributors."
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:45
+#: src/components/importschedule/Importscheduledetail.vue:176
+msgid "SortBy"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:45
 msgid "Sounding Result"
 msgstr ""
 
-#: src/components/map/Identify.vue:57
+#: src/components/Identify.vue:57
 msgid "source-code"
 msgstr ""
 
-#: src/components/Sidebar.vue:54
+#: src/components/Sidebar.vue:40
 msgid "Staging area"
 msgstr ""
 
-#: src/components/map/contextbox/Staging.vue:7
+#: src/components/staging/Staging.vue:7
 msgid "Staging Area"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:142
+#: src/components/fairway/Profiles.vue:142
 msgid "Start"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:268
+#: src/components/ImportSoundingresults.vue:279
 msgid "Starting import for "
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:57
+#: src/components/ImportApprovedGaugeMeasurement.vue:100
+msgid "Starting import of Approved Gauge Measurements"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:67
 msgid "State"
 msgstr ""
 
-#: src/components/admin/importschedule/Importscheduledetail.vue:85
-#: src/components/admin/usermanagement/Userdetail.vue:129
+#: src/components/importschedule/Importscheduledetail.vue:394
+#: src/components/usermanagement/Userdetail.vue:129
 msgid "Submit"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:377
+#: src/components/fairway/Profiles.vue:381
 msgid "Success"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:34
+#: src/components/importqueue/Importqueue.vue:34
 msgid "Successful"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:88
+#: src/components/importschedule/Importscheduledetail.vue:466
+msgid "Sunday"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:88
 msgid "Sysadmin"
 msgstr ""
 
-#: src/components/Sidebar.vue:57
+#: src/components/usermanagement/Usermanagement.vue:326
+msgid "System-Administrator"
+msgstr ""
+
+#: src/components/Sidebar.vue:97
 msgid "Systemadministration"
 msgstr ""
 
-#: src/components/admin/Systemconfiguration.vue:8
+#: src/components/Systemconfiguration.vue:8
 msgid "Systemconfiguration"
 msgstr ""
 
-#: src/components/map/Identify.vue:51
+#: src/components/Identify.vue:51
 msgid ""
 "This app uses <i>gemma</i>, which is Free Software under <br/>\n"
 "        %{ license } without warranty, see docs for details."
 msgstr ""
 
-#: src/components/admin/importschedule/Importschedule.vue:34
-#: src/components/map/contextbox/Staging.vue:13
+#: src/components/importschedule/Importscheduledetail.vue:463
+msgid "Thursday"
+msgstr ""
+
+#: src/components/ImportApprovedGaugeMeasurement.vue:43
+#: src/components/ImportWaterwayProfiles.vue:43
+#: src/components/importschedule/Importscheduledetail.vue:407
+msgid "Trigger import"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:461
+msgid "Tuesday"
+msgstr ""
+
+#: src/components/importschedule/Importschedule.vue:34
+#: src/components/staging/Staging.vue:12
 msgid "Type"
 msgstr ""
 
-#: src/components/map/contextbox/ImportSoundingresults.vue:313
+#: src/components/ImportWaterwayProfiles.vue:89
+msgid "under construction"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:738
+msgid "update import: #"
+msgstr ""
+
+#: src/components/ImportSoundingresults.vue:324
 msgid "Upload"
 msgstr ""
 
-#: src/components/admin/Importqueue.vue:55
+#: src/components/importschedule/Importscheduledetail.vue:72
+msgid "URL"
+msgstr ""
+
+#: src/components/importqueue/Importqueue.vue:61
 msgid "User"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:14
-#: src/components/map/contextbox/Staging.vue:16
+#: src/components/importschedule/Importscheduledetail.vue:117
+#: src/components/staging/Staging.vue:18
+#: src/components/usermanagement/Userdetail.vue:14
 msgid "Username"
 msgstr ""
 
-#: src/components/Sidebar.vue:66
-#: src/components/admin/usermanagement/Usermanagement.vue:14
+#: src/components/Sidebar.vue:108
+#: src/components/usermanagement/Usermanagement.vue:14
 msgid "Users"
 msgstr ""
 
-#: src/components/map/Identify.vue:65
+#: src/components/Identify.vue:65
 msgid ""
 "Uses\n"
 "        <a href=\"https://download.geonames.org/export/dump/readme.txt\">GeoNames</a>\n"
 "        under %{ geoLicense }."
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Userdetail.vue:91
+#: src/components/usermanagement/Usermanagement.vue:327
 msgid "Waterway Admin"
 msgstr ""
 
-#: src/components/admin/usermanagement/Userdetail.vue:94
+#: src/components/importschedule/Importscheduledetail.vue:28
+msgid "Waterway axis"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:43
+msgid "Waterway gauges"
+msgstr ""
+
+#: src/components/usermanagement/Userdetail.vue:94
+#: src/components/usermanagement/Usermanagement.vue:328
 msgid "Waterway User"
 msgstr ""
 
-#: src/components/map/fairway/Profiles.vue:439
-#: src/components/map/fairway/Profiles.vue:440
+#: src/components/importschedule/Importscheduledetail.vue:37
+msgid "Waterwayarea"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:462
+msgid "Wednesday"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:455
+msgid "week"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:246
+msgid "Weekly"
+msgstr ""
+
+#: src/components/importschedule/Importscheduledetail.vue:457
+msgid "year"
+msgstr ""
+
+#: src/components/fairway/Profiles.vue:443
+#: src/components/fairway/Profiles.vue:444
 msgid "You can now select these coordinates from the \"Saved cross profiles\" menu to restore this cross profile."
 msgstr ""
 
-#: src/store/map.js:415
+#: src/store/map.js:416
 msgid "Length"
 msgstr ""
 
-#: src/store/map.js:436
+#: src/store/map.js:437
 msgid "Area"
 msgstr ""
--- a/client/src/locale/translations.json	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/locale/translations.json	Tue Jan 15 10:07:10 2019 +0100
@@ -1,1 +1,1 @@
-{"bg_BG":{},"de_AT":{"Accepted":"Akzeptiert","Accesslog":"Zugriffs-Protokoll","Add User":"Benutzer hinzufügen","Author":"Autor","back to login":"zurück zur Anmeldung","Backend Error":"Server-Fehler","Bottleneck":"Seichtstelle","Bottleneck Areas fill-color":"Flächenfüllfarbe Seichtstelle","Bottleneck Areas stroke-color":"Flächenumrandungsfarbe Seichtstelle","Bottlenecks":"Seichtstellen","Cancel Upload":"Hochladen abbrechen","Chainage":"Stationierung","choose .zip- file":"Wählen Sie eine .zip Datei","Chose format:":"Format wählen:","Compare with":"Vergleiche mit","Configuration":"Konfiguration","Confirm":"Bestätigen","Coordinates copied to clipboard!":"Koordinaten auf die Zwischenablage kopiert!","Country":"Land","Date":"Datum","Depthreference":"Tiefenreferenz","Download":"Herunterladen","Download Meta.json":"Meta.json Herunterladen","Email":"E-Mail","Email address":"E-Mail Adresse","Enqueued":"Hinzugefügt","Enter coordinates manually":"Manuelle Koordinateneingabe","Enter label for cross profile":"Namen für Profilschnitt eingeben","Enter passphrase":"Passphrase eingeben","Enter username":"Benutzername eingeben","Error while saving user":"Während des Speicherns der Nutzerdaten trat ein Fehler auf","Errorlog":"Fehlerprotokoll","Failed":"Fehlgeschlagen","Forgot password":"Passwort vergessen","Generate PDF":"PDF generieren","Identified":"Identifiziert","Import":"Daten-Import","Import soundingresults":"Seichtstellenmessungen importieren","Import Soundingresults":"Seichtstellenmessungen importieren","Imported":"Importiert","Importqueue":"Import-Warteschlange","Importschedule":"Import-Zeitplan","invalid email":"Ungültige E-Mail","Invalid input":"Ungültige Eingabe","Kind":"Art","landscape":"Querformat","Last refresh:":"Letzter Abgleich:","Latest":"Neuste","Layers":"Ebenen","Login":"Login","Login failed":"Login fehlgeschlagen","Logout":"Abmelden","Logs":"Protokolle","Mail was sent":"E-Mail wurde gesendet","Map":"Karte","Measurement":"Messung","Name":"Name","New import":"Neuer Import","New Import":"Neuer Import","No features identified.":"Keine Objekte identifiziert.","No results.":"Keine Ergebnisse.","No schedules":"Keine Pläne","Open in new window":"In neuem Fenster öffnen","password":"Passwort","Password":"Passwort","password again":"Noch einmal das Passwort","Password reset requested!":"Passwort Zurücksetzung angefragt!","Password should at least be 8 char long including 1 digit and 1 special char like $":"Das Passwort sollte mindestens 8 Zeichen lang sein, eine Zahlenziffer und ein Sonderzeichen wie etwa $ enthalten","Passwords do not match!":"Die Passwörter stimmen nicht überein!","Pending":"Ausstehend","Please choose a country":"Bitte wählen Sie ein Land aus","Please choose a role":"Bitte wählen Sie eine Rolle aus","Please enter a date":"Bitte ein Datum eingeben","Please enter a projection":"Bitte eine Projektion eingeben","Please enter a reference":"Bitte ein Höhenreferenzsystem eingeben","Please enter correct coordinates in the format: Lat,Lon,Lat,Lon":"Bitte geben Sie die Koordinaten in folgendem Format an: Lat,Lon,Lat,Lon","Please select a bottleneck":"Bitte eine Seichtstelle wählen","Please select one":"Bitte auswählen","portrait":"Hochformat","Profile deleted!":"Profil gelöscht!","Profile saved!":"Profil gespeichert!","Profiles":"Profile","Projection":"Projektion","Refresh":"Aktualisieren","Rejected":"Abgelehnt","Repeat Password":"Passwort erneut eingeben","Request password reset!":"Passwort-Zurücksetzung anfragen!","Role":"Rolle","Saved cross profiles":"Gespeicherte Profile","Schedule":"Zeitplan","Select Bottleneck":"Wähle Seichtstelle","Send":"Absenden","Send testmail":"Test-E-Mail versenden","Sounding Result":"Seichtstellenvermessungsergebnisse","source-code":"Quelltext","Staging area":"Import-Überprüfung","Staging Area":"Import-Überprüfung","Start":"Start","Starting import for ":"Import gestartet ","State":"Zustand","Submit":"Abschicken","Success":"Erfolg","Successful":"Erfolgreich","Sysadmin":"Sys-Admin","Systemadministration":"System-Administration","Systemconfiguration":"System-Konfiguation","Type":"Typ","Upload":"Hochladen","User":"Benutzer","Username":"Benutzername","Users":"Benutzer","Waterway Admin":"Waterway-Admin","Waterway User":"Waterway-Benutzer","You can now select these coordinates from the \"Saved cross profiles\" menu to restore this cross profile.":"Sie können diese Koordinaten aus dem \"Gespeicherte Profile\"-Menü auswählen, um diesen Profilschnitt wieder herzustellen."},"en_GB":{},"hr_HR":{},"hu_HU":{},"ro_RO":{},"sk_SK":{}}
\ No newline at end of file
+{"bg_BG":{},"de_AT":{"Accepted":"Akzeptiert","Accesslog":"Zugriffs-Protokoll","Add User":"Benutzer hinzufügen","Author":"Autor","back to login":"zurück zur Anmeldung","Backend Error":"Server-Fehler","Bottleneck":"Seichtstelle","Bottleneck Areas fill-color":"Flächenfüllfarbe Seichtstelle","Bottleneck Areas stroke-color":"Flächenumrandungsfarbe Seichtstelle","Bottlenecks":"Seichtstellen","Cancel Upload":"Hochladen abbrechen","Chainage":"Stationierung","choose .zip- file":"Wählen Sie eine .zip Datei","Compare with":"Vergleiche mit","Configuration":"Konfiguration","Confirm":"Bestätigen","Coordinates copied to clipboard!":"Koordinaten auf die Zwischenablage kopiert!","Country":"Land","Date":"Datum","Depthreference":"Tiefenreferenz","Download":"Herunterladen","Download Meta.json":"Meta.json Herunterladen","Email":"E-Mail","Email address":"E-Mail Adresse","Email Notification":"E-Mail Benachrichtigung","Enqueued":"Hinzugefügt","Enter coordinates manually":"Manuelle Koordinateneingabe","Enter label for cross profile":"Namen für Profilschnitt eingeben","Enter passphrase":"Passphrase eingeben","Enter username":"Benutzername eingeben","Error while saving user":"Während des Speicherns der Nutzerdaten trat ein Fehler auf","Errorlog":"Fehlerprotokoll","Failed":"Fehlgeschlagen","Forgot password":"Passwort vergessen","Generate PDF":"PDF generieren","Identified":"Identifiziert","Import":"Daten-Import","Import soundingresults":"Seichtstellenmessungen importieren","Import Soundingresults":"Seichtstellenmessungen importieren","Imported":"Importiert","Importqueue":"Import-Warteschlange","Imports":"Daten-Import","invalid email":"Ungültige E-Mail","Invalid input":"Ungültige Eingabe","Kind":"Art","landscape":"Querformat","Last refresh:":"Letzter Abgleich:","Latest":"Neuste","Layers":"Ebenen","Login":"Login","Login failed":"Login fehlgeschlagen","Logout":"Abmelden","Logs":"Protokolle","Mail was sent":"E-Mail wurde gesendet","Map":"Karte","Measurement":"Messung","Name":"Name","New Import":"Neuer Import","No features identified.":"Keine Objekte identifiziert.","No results.":"Keine Ergebnisse.","Open in new window":"In neuem Fenster öffnen","password":"Passwort","Password":"Passwort","password again":"Noch einmal das Passwort","Password reset requested!":"Passwort Zurücksetzung angefragt!","Password should at least be 8 char long including 1 digit and 1 special char like $":"Das Passwort sollte mindestens 8 Zeichen lang sein, eine Zahlenziffer und ein Sonderzeichen wie etwa $ enthalten","Passwords do not match!":"Die Passwörter stimmen nicht überein!","Pending":"Ausstehend","Please choose a country":"Bitte wählen Sie ein Land aus","Please choose a role":"Bitte wählen Sie eine Rolle aus","Please enter a date":"Bitte ein Datum eingeben","Please enter a projection":"Bitte eine Projektion eingeben","Please enter a reference":"Bitte ein Höhenreferenzsystem eingeben","Please enter correct coordinates in the format: Lat,Lon,Lat,Lon":"Bitte geben Sie die Koordinaten in folgendem Format an: Lat,Lon,Lat,Lon","Please select a bottleneck":"Bitte eine Seichtstelle wählen","Please select one":"Bitte auswählen","portrait":"Hochformat","Profile deleted!":"Profil gelöscht!","Profile saved!":"Profil gespeichert!","Profiles":"Profile","Projection":"Projektion","Refresh":"Aktualisieren","Rejected":"Abgelehnt","Repeat Password":"Passwort erneut eingeben","Request password reset!":"Passwort-Zurücksetzung anfragen!","Role":"Rolle","Saved cross profiles":"Gespeicherte Profile","Schedule":"Zeitplan","Select Bottleneck":"Wähle Seichtstelle","Send":"Absenden","Send testmail":"Test-E-Mail versenden","Signer":"Überprüft durch","Sounding Result":"Seichtstellenvermessung","source-code":"Quelltext","Staging area":"Import-Überprüfung","Staging Area":"Import-Überprüfung","Start":"Start","Starting import for ":"Import gestartet ","State":"Zustand","Submit":"Abschicken","Success":"Erfolg","Successful":"Erfolgreich","Sysadmin":"Sys-Admin","Systemadministration":"System-Administration","Systemconfiguration":"System-Konfiguation","Type":"Typ","Upload":"Hochladen","User":"Benutzer","Username":"Benutzername","Users":"Benutzer","Waterway Admin":"Waterway-Admin","Waterway User":"Waterway-Benutzer","You can now select these coordinates from the \"Saved cross profiles\" menu to restore this cross profile.":"Sie können diese Koordinaten aus dem \"Gespeicherte Profile\"-Menü auswählen, um diesen Profilschnitt wieder herzustellen.","Length":"Länge","Area":"Fläche"},"en_GB":{},"hr_HR":{},"hu_HU":{},"ro_RO":{},"sk_SK":{}}
\ No newline at end of file
--- a/client/src/main.js	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/main.js	Tue Jan 15 10:07:10 2019 +0100
@@ -35,6 +35,7 @@
   faAngleUp,
   faBars,
   faBook,
+  faBullseye,
   faChartArea,
   faCheck,
   faCity,
@@ -57,6 +58,7 @@
   faPlay,
   faPlus,
   faPowerOff,
+  faRoad,
   faRuler,
   faSearch,
   faShip,
@@ -85,6 +87,7 @@
   faAngleUp,
   faBars,
   faBook,
+  faBullseye,
   faChartArea,
   faCheck,
   faCity,
@@ -107,6 +110,7 @@
   faPlay,
   faPlus,
   faPowerOff,
+  faRoad,
   faRuler,
   faSearch,
   faShip,
--- a/client/src/router.js	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/router.js	Tue Jan 15 10:07:10 2019 +0100
@@ -20,19 +20,6 @@
 
 /*  facilitate codesplitting */
 const Login = () => import("./components/Login.vue");
-const Main = () => import("./components/Main.vue");
-const Usermanagement = () =>
-  import("./components/usermanagement/Usermanagement.vue");
-const Logs = () => import("./components/Logs.vue");
-const Importqueue = () => import("./components/importqueue/Importqueue.vue");
-const Importschedule = () =>
-  import("./components/importschedule/Importschedule.vue");
-const Systemconfiguration = () =>
-  import("./components/Systemconfiguration.vue");
-const Importsoundingresults = () =>
-  import("./components/ImportSoundingresults.vue");
-
-const Importstretches = () => import("./components/ImportStretches.vue");
 
 Vue.use(Router);
 
@@ -46,7 +33,7 @@
     {
       path: "/usermanagement",
       name: "usermanagement",
-      component: Usermanagement,
+      component: () => import("./components/usermanagement/Usermanagement.vue"),
       meta: {
         requiresAuth: true
       },
@@ -62,7 +49,7 @@
     {
       path: "/logs",
       name: "logs",
-      component: Logs,
+      component: () => import("./components/Logs.vue"),
       meta: {
         requiresAuth: true
       },
@@ -78,7 +65,7 @@
     {
       path: "/systemconfiguration",
       name: "systemconfiguration",
-      component: Systemconfiguration,
+      component: () => import("./components/Systemconfiguration.vue"),
       meta: {
         requiresAuth: true
       },
@@ -93,8 +80,24 @@
     },
     {
       path: "/importqueue",
+      name: "importqueues",
+      component: () => import("./components/importqueue/Importqueue.vue"),
+      meta: {
+        requiresAuth: true
+      },
+      beforeEnter: (to, from, next) => {
+        const isWaterwayAdmin = store.getters["user/isWaterwayAdmin"];
+        if (!isWaterwayAdmin) {
+          next("/");
+        } else {
+          next();
+        }
+      }
+    },
+    {
+      path: "/importqueue/:id",
       name: "importqueue",
-      component: Importqueue,
+      component: () => import("./components/importqueue/Importqueue.vue"),
       meta: {
         requiresAuth: true
       },
@@ -110,7 +113,7 @@
     {
       path: "/importsoundingresults",
       name: "importsoundingresults",
-      component: Importsoundingresults,
+      component: () => import("./components/ImportSoundingresults.vue"),
       meta: {
         requiresAuth: true
       },
@@ -124,9 +127,25 @@
       }
     },
     {
-      path: "/importstretches",
-      name: "importstretches",
-      component: Importstretches,
+      path: "/importwaterwayprofiles",
+      name: "waterwayprofiles",
+      component: () => import("./components/ImportWaterwayProfiles"),
+      meta: {
+        requiresAuth: true
+      },
+      beforeEnter: (to, from, next) => {
+        const isWaterwayAdmin = store.getters["user/isWaterwayAdmin"];
+        if (!isWaterwayAdmin) {
+          next("/");
+        } else {
+          next();
+        }
+      }
+    },
+    {
+      path: "/importapprovedgaugemeasurement",
+      name: "approvedgaugemeasurement",
+      component: () => import("./components/ImportApprovedGaugeMeasurement"),
       meta: {
         requiresAuth: true
       },
@@ -142,7 +161,7 @@
     {
       path: "/importschedule",
       name: "importschedule",
-      component: Importschedule,
+      component: () => import("./components/importschedule/Importschedule.vue"),
       meta: {
         requiresAuth: true
       },
@@ -158,7 +177,7 @@
     {
       path: "/",
       name: "mainview",
-      component: Main,
+      component: () => import("./components/Main.vue"),
       meta: {
         requiresAuth: true
       },
--- a/client/src/store/imports.js	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/store/imports.js	Tue Jan 15 10:07:10 2019 +0100
@@ -12,7 +12,8 @@
  * Thomas Junk <thomas.junk@intevation.de>
  */
 
-import { HTTP } from "../lib/http";
+import { HTTP } from "@/lib/http";
+import Vue from "vue";
 
 /* eslint-disable no-unused-vars */
 /* eslint-disable no-unreachable */
@@ -22,18 +23,78 @@
   REJECTED: "declined"
 };
 
+const IMPORTTYPES = {
+  BOTTLENECK: "bottleneck",
+  WATERWAYAXIS: "waterwayaxis",
+  GAUGEMEASUREMENT: "gaugemeasurement",
+  FAIRWAYAVAILABILITY: "fairwayavailability",
+  WATERWAYAREA: "waterwayarea",
+  FAIRWAYDIMENSIONS: "fd",
+  WATERWAYGAUGES: "wg"
+};
+
 const SCHEDULES = {
   DAILY: "daily",
   MONTHLY: "monthly"
 };
 
+const IMPORTTYPEKIND = {
+  bottleneck: "bn",
+  fairwayavailability: "fa",
+  gaugemeasurement: "gm",
+  waterwayaxis: "wx",
+  waterwayarea: "wa",
+  fairwaydimensions: "fd",
+  waterwaygauges: "wg"
+};
+
+const KINDIMPORTTYPE = {
+  bn: "bottleneck",
+  fa: "fairwayavailability",
+  gm: "gaugemeasurement",
+  wx: "waterwayaxis",
+  wa: "waterwayarea",
+  fd: "fairwaydimensions",
+  wg: "waterwaygauges"
+};
+
+const initializeCurrentSchedule = () => {
+  return {
+    id: null,
+    importType: null,
+    schedule: null,
+    import_: null,
+    importSource: null,
+    eMailNotification: false,
+    scheduled: false,
+    easyCron: true,
+    cronString: "* * * * ",
+    cronMode: "",
+    minutes: null,
+    month: null,
+    hour: null,
+    day: null,
+    dayOfMonth: null,
+    simple: null,
+    url: null,
+    insecure: false,
+    triggerActive: true,
+    featureType: null,
+    sortBy: null,
+    username: "",
+    password: ""
+  };
+};
+
 // initial state
 const init = () => {
   return {
     imports: [],
     staging: [],
     schedules: [],
-    importScheduleDetailVisible: false
+    importScheduleDetailVisible: false,
+    currentSchedule: initializeCurrentSchedule(),
+    importToReview: null
   };
 };
 
@@ -42,8 +103,8 @@
   namespaced: true,
   state: init(),
   mutations: {
-    deleteSchedule: (state, index) => {
-      state.schedules.splice(index, 1);
+    clearCurrentSchedule: state => {
+      state.currentSchedule = initializeCurrentSchedule();
     },
     setImportScheduleDetailInvisible: state => {
       state.importScheduleDetailVisible = false;
@@ -63,7 +124,11 @@
       });
       state.staging = enriched;
     },
-
+    setImportToReview: (state, id) => {
+      if (!isNaN(parseFloat(id)) && isFinite(id)) {
+        state.importToReview = id;
+      }
+    },
     toggleApproval: (state, change) => {
       const { id, newStatus } = change;
       const stagedResult = state.staging.find(e => {
@@ -74,17 +139,129 @@
       } else {
         stagedResult.status = newStatus;
       }
+    },
+    unmarshallCurrentSchedule: (state, payload) => {
+      const { kind, id, cron, url, attributes } = payload;
+      const eMailNotification = payload["send-email"];
+      Vue.set(state.currentSchedule, "import_", KINDIMPORTTYPE[kind]);
+      Vue.set(state.currentSchedule, "id", id);
+      if (cron) {
+        Vue.set(state.currentSchedule, "scheduled", true);
+        Vue.set(state.currentSchedule, "easyCron", false);
+        Vue.set(state.currentSchedule, "cronString", cron);
+      }
+      if (eMailNotification) {
+        Vue.set(state.currentSchedule, "eMailNotification", eMailNotification);
+      }
+      if (url) {
+        Vue.set(state.currentSchedule, "url", url);
+      }
+      if (attributes) {
+        let { insecure, username, password } = attributes;
+        let sortBy = attributes["sort-by"];
+        const featureType = attributes["feature-type"];
+        insecure = insecure == "true";
+        if (insecure) {
+          Vue.set(state.currentSchedule, "insecure", insecure);
+        }
+        if (featureType) {
+          Vue.set(state.currentSchedule, "featureType", featureType);
+        }
+        if (sortBy) {
+          Vue.set(state.currentSchedule, "sortBy", sortBy);
+        }
+        if (username) {
+          Vue.set(state.currentSchedule, "username", username);
+        }
+        if (password) {
+          Vue.set(state.currentSchedule, "password", password);
+        }
+      }
     }
   },
   actions: {
-    getSchedules({ commit }) {
-      throw new Error("Not Implemented!");
+    loadSchedule({ commit }, id) {
       return new Promise((resolve, reject) => {
-        HTTP.get("/imports", {
+        HTTP.get("/imports/config/" + id, {
           headers: { "X-Gemma-Auth": localStorage.getItem("token") }
         })
           .then(response => {
-            commit("setImports", response.data.imports);
+            commit("unmarshallCurrentSchedule", response.data);
+            resolve(response);
+          })
+          .catch(error => {
+            reject(error);
+          });
+      });
+    },
+    deleteSchedule({ commit }, id) {
+      return new Promise((resolve, reject) => {
+        HTTP.delete("imports/config/" + id, {
+          headers: {
+            "X-Gemma-Auth": localStorage.getItem("token")
+          }
+        })
+          .then(response => {
+            resolve(response);
+          })
+          .catch(error => {
+            reject(error);
+          });
+      });
+    },
+    updateCurrentSchedule({ commit }, payload) {
+      const { data, id } = payload;
+      return new Promise((resolve, reject) => {
+        HTTP.patch("imports/config/" + id, data, {
+          headers: {
+            "X-Gemma-Auth": localStorage.getItem("token")
+          }
+        })
+          .then(response => {
+            resolve(response);
+          })
+          .catch(error => {
+            reject(error);
+          });
+      });
+    },
+    saveCurrentSchedule({ commit }, data) {
+      return new Promise((resolve, reject) => {
+        HTTP.post("imports/config", data, {
+          headers: {
+            "X-Gemma-Auth": localStorage.getItem("token")
+          }
+        })
+          .then(response => {
+            resolve(response);
+          })
+          .catch(error => {
+            reject(error);
+          });
+      });
+    },
+    loadSchedules({ commit }) {
+      return new Promise((resolve, reject) => {
+        HTTP.get("/imports/config", {
+          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
+        })
+          .then(response => {
+            commit("setSchedules", response.data);
+            resolve(response);
+          })
+          .catch(error => {
+            reject(error);
+          });
+      });
+    },
+    triggerImport({ commit }, { type, data }) {
+      return new Promise((resolve, reject) => {
+        HTTP.post("imports/" + type, data, {
+          headers: {
+            "X-Gemma-Auth": localStorage.getItem("token")
+          }
+        })
+          .then(response => {
             resolve(response);
           })
           .catch(error => {
@@ -123,4 +300,11 @@
   }
 };
 
-export { imports, STATES, SCHEDULES };
+export {
+  imports,
+  STATES,
+  SCHEDULES,
+  IMPORTTYPES,
+  IMPORTTYPEKIND,
+  initializeCurrentSchedule
+};
--- a/client/src/store/user.js	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/src/store/user.js	Tue Jan 15 10:07:10 2019 +0100
@@ -75,7 +75,7 @@
         const handleResponse = response => {
           const { expires } = response.data;
           const renew =
-            (new Date(toMillisFromString(expires)) - new Date()) / 1010;
+            (new Date(toMillisFromString(expires)) - new Date()) * 0.9;
           commit("authSuccess", response.data);
           resolve(response);
           setTimeout(() => {
--- a/client/vue.config.js	Tue Jan 15 09:54:46 2019 +0100
+++ b/client/vue.config.js	Tue Jan 15 10:07:10 2019 +0100
@@ -1,7 +1,9 @@
 const CopyWebpackPlugin = require("copy-webpack-plugin");
-
 module.exports = {
   outputDir: "../web",
+  configureWebpack: {
+    devtool: "source-map"
+  },
   chainWebpack: config => {
     let vendorImgPath = process.env.VUE_APP_VENDOR_IMG_PATH;
     if (!vendorImgPath) return;
@@ -10,6 +12,11 @@
       .use(CopyWebpackPlugin, [[{ from: vendorImgPath, to: "img" }]], {
         copyUnmodified: true
       });
+    if (process.env.ANALYZE) {
+      var BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
+        .BundleAnalyzerPlugin;
+      config.plugin("BundleAnalyzerPlugin").use(BundleAnalyzerPlugin, []);
+    }
   },
   css: {
     loaderOptions: {
--- a/cmd/wfs/dump.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/cmd/wfs/dump.go	Tue Jan 15 10:07:10 2019 +0100
@@ -18,6 +18,7 @@
 	"errors"
 	"fmt"
 	"io"
+	"log"
 	"os"
 
 	"gemma.intevation.de/gemma/pkg/wfs"
@@ -40,13 +41,19 @@
 			crsName = defaultCRS
 		}
 		fmt.Printf("CRS: %s\n", crsName)
-		types := map[string]struct{}{}
+		epsg, err := wfs.CRSToEPSG(crsName)
+		if err != nil {
+			log.Printf("error: %v\n", err)
+		} else {
+			fmt.Printf("EPSG: %d\n", epsg)
+		}
+		types := map[string]int{}
 		for _, feature := range rfc.Features {
-			types[feature.Geometry.Type] = struct{}{}
+			types[feature.Geometry.Type]++
 		}
 		fmt.Printf("found types in %d features:\n", len(rfc.Features))
-		for typ := range types {
-			fmt.Printf("\t%s\n", typ)
+		for typ, cnt := range types {
+			fmt.Printf("\t%s: %d\n", typ, cnt)
 		}
 		return nil
 	})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/common/attributes.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,69 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package common
+
+import (
+	"log"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// Attributes is a map of optional key/value attributes
+// of a configuration.
+type Attributes map[string]string
+
+// Get fetches a value for given key out of the configuration.
+// If the key was not found the bool component of the return value
+// return false.
+func (ca Attributes) Get(key string) (string, bool) {
+	if ca == nil {
+		return "", false
+	}
+	value, found := ca[key]
+	return value, found
+}
+
+// Bool returns a bool value for a given key.
+func (ca Attributes) Bool(key string) bool {
+	s, found := ca.Get(key)
+	return found && strings.ToLower(s) == "true"
+}
+
+// Time gives a time.Time for a given key.
+func (ca Attributes) Time(key string) (time.Time, bool) {
+	s, found := ca.Get(key)
+	if !found {
+		return time.Time{}, false
+	}
+	t, err := time.Parse("2006-01-02T15:04:05", s)
+	if err != nil {
+		log.Printf("error: %v\n", err)
+		return time.Time{}, false
+	}
+	return t, true
+}
+
+func (ca Attributes) Int(key string) (int, bool) {
+	s, found := ca.Get(key)
+	if !found {
+		return 0, false
+	}
+	i, err := strconv.Atoi(s)
+	if err != nil {
+		log.Printf("error: %v\n", err)
+		return 0, false
+	}
+	return i, true
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/controllers/agmimports.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,135 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package controllers
+
+import (
+	"bufio"
+	"io"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"os"
+	"path/filepath"
+	"strconv"
+	"time"
+
+	"gemma.intevation.de/gemma/pkg/auth"
+	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/config"
+	"gemma.intevation.de/gemma/pkg/imports"
+)
+
+const (
+	maxApprovedGaugeMeasurementSize = 25 * 1024 * 1024
+	approvedGaugeMeasurementsName   = "approvedgm"
+)
+
+func storeApprovedGaugeMeasurements(req *http.Request) (string, error) {
+
+	// Check for direct upload.
+	f, _, err := req.FormFile(approvedGaugeMeasurementsName)
+	if err != nil {
+		return "", err
+	}
+	defer f.Close()
+
+	dir, err := ioutil.TempDir(config.TmpDir(), approvedGaugeMeasurementsName)
+	if err != nil {
+		return "", err
+	}
+
+	o, err := os.Create(filepath.Join(dir, "agm.csv"))
+	if err != nil {
+		os.RemoveAll(dir)
+		return "", err
+	}
+
+	out := bufio.NewWriter(o)
+
+	if _, err = io.Copy(out, io.LimitReader(f, maxApprovedGaugeMeasurementSize)); err != nil {
+		o.Close()
+		os.RemoveAll(dir)
+		return "", err
+	}
+
+	if err = out.Flush(); err != nil {
+		o.Close()
+		os.RemoveAll(dir)
+		return "", err
+	}
+
+	return dir, nil
+}
+
+func importApprovedGaugeMeasurements(rw http.ResponseWriter, req *http.Request) {
+
+	dir, err := storeApprovedGaugeMeasurements(req)
+	if err != nil {
+		log.Printf("error: %v\n", err)
+		http.Error(rw, "error: "+err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	agm := &imports.ApprovedGaugeMeasurements{Dir: dir}
+
+	serialized, err := common.ToJSONString(agm)
+	if err != nil {
+		log.Printf("error: %v\n", err)
+		http.Error(rw, "error: "+err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	session, _ := auth.GetSession(req)
+
+	sendEmail := req.FormValue("email") != ""
+
+	var due time.Time
+	if d := req.FormValue("due"); d != "" {
+		var err error
+		if due, err = time.Parse("2006-01-02T15:04:05", d); err != nil {
+			log.Printf("error: %v\n", err)
+		}
+	}
+
+	retries := -1
+	if r := req.FormValue("retries"); r != "" {
+		var err error
+		if retries, err = strconv.Atoi(r); err != nil {
+			log.Printf("error: %v\n", err)
+			retries = -1
+		}
+	}
+
+	jobID, err := imports.AddJob(
+		imports.AGMJobKind,
+		due, retries,
+		session.User,
+		sendEmail,
+		serialized)
+
+	if err != nil {
+		log.Printf("error: %v\n", err)
+		http.Error(rw, "error: "+err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	log.Printf("info: added import #%d to queue\n", jobID)
+
+	result := struct {
+		ID int64 `json:"id"`
+	}{
+		ID: jobID,
+	}
+	SendJSON(rw, http.StatusCreated, &result)
+}
--- a/pkg/controllers/bnimports.go	Tue Jan 15 09:54:46 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-// This is Free Software under GNU Affero General Public License v >= 3.0
-// without warranty, see README.md and license for details.
-//
-// SPDX-License-Identifier: AGPL-3.0-or-later
-// License-Filename: LICENSES/AGPL-3.0.txt
-//
-// Copyright (C) 2018 by via donau
-//   – Österreichische Wasserstraßen-Gesellschaft mbH
-// Software engineering by Intevation GmbH
-//
-// Author(s):
-//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
-
-package controllers
-
-import (
-	"database/sql"
-	"log"
-	"net/http"
-
-	"gemma.intevation.de/gemma/pkg/auth"
-	"gemma.intevation.de/gemma/pkg/common"
-	"gemma.intevation.de/gemma/pkg/imports"
-	"gemma.intevation.de/gemma/pkg/models"
-)
-
-func importBottleneck(
-	input interface{},
-	req *http.Request,
-	conn *sql.Conn,
-) (jr JSONResult, err error) {
-
-	bi := input.(*models.BottleneckImport)
-
-	bn := &imports.Bottleneck{
-		URL:      bi.URL,
-		Insecure: bi.Insecure,
-	}
-
-	var serialized string
-	serialized, err = common.ToJSONString(bn)
-	if err != nil {
-		return
-	}
-
-	session, _ := auth.GetSession(req)
-
-	jobID, err := imports.AddJob(
-		imports.BNJobKind, session.User,
-		false, false,
-		serialized)
-
-	if err != nil {
-		return
-	}
-
-	log.Printf("info: added import #%d to queue\n", jobID)
-
-	result := struct {
-		ID int64 `json:"id"`
-	}{
-		ID: jobID,
-	}
-
-	jr = JSONResult{
-		Code:   http.StatusCreated,
-		Result: &result,
-	}
-	return
-}
--- a/pkg/controllers/geostyling.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/controllers/geostyling.go	Tue Jan 15 10:07:10 2019 +0100
@@ -73,7 +73,7 @@
 		return
 	}
 
-	log.Printf("uploaded file length: %d\n", len(style))
+	log.Printf("info: uploaded file length: %d\n", len(style))
 
 	if err := models.UpdateInternalStyle(req, feature, style); err != nil {
 		log.Printf("error: %v\n", err)
--- a/pkg/controllers/gmimports.go	Tue Jan 15 09:54:46 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-// This is Free Software under GNU Affero General Public License v >= 3.0
-// without warranty, see README.md and license for details.
-//
-// SPDX-License-Identifier: AGPL-3.0-or-later
-// License-Filename: LICENSES/AGPL-3.0.txt
-//
-// Copyright (C) 2018 by via donau
-//   – Österreichische Wasserstraßen-Gesellschaft mbH
-// Software engineering by Intevation GmbH
-//
-// Author(s):
-//  * Raimund Renkert <raimund.renkert@intevation.de>
-
-package controllers
-
-import (
-	"database/sql"
-	"log"
-	"net/http"
-
-	"gemma.intevation.de/gemma/pkg/auth"
-	"gemma.intevation.de/gemma/pkg/common"
-	"gemma.intevation.de/gemma/pkg/imports"
-	"gemma.intevation.de/gemma/pkg/models"
-)
-
-func importGaugeMeasurement(
-	input interface{},
-	req *http.Request,
-	conn *sql.Conn,
-) (jr JSONResult, err error) {
-
-	bi := input.(*models.GaugeMeasurementImport)
-
-	bn := &imports.GaugeMeasurement{
-		URL:      bi.URL,
-		Insecure: bi.Insecure,
-	}
-
-	var serialized string
-	serialized, err = common.ToJSONString(bn)
-	if err != nil {
-		return
-	}
-
-	session, _ := auth.GetSession(req)
-
-	jobID, err := imports.AddJob(
-		imports.GMJobKind,
-		session.User,
-		false, true,
-		serialized)
-
-	if err != nil {
-		return
-	}
-
-	log.Printf("info: added import #%d to queue\n", jobID)
-
-	result := struct {
-		ID int64 `json:"id"`
-	}{
-		ID: jobID,
-	}
-
-	jr = JSONResult{
-		Code:   http.StatusCreated,
-		Result: &result,
-	}
-	return
-}
--- a/pkg/controllers/importconfig.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/controllers/importconfig.go	Tue Jan 15 10:07:10 2019 +0100
@@ -14,15 +14,18 @@
 package controllers
 
 import (
+	"context"
 	"database/sql"
 	"errors"
 	"fmt"
 	"net/http"
+	"sort"
 	"strconv"
 
 	"github.com/gorilla/mux"
 
 	"gemma.intevation.de/gemma/pkg/auth"
+	"gemma.intevation.de/gemma/pkg/common"
 	"gemma.intevation.de/gemma/pkg/imports"
 	"gemma.intevation.de/gemma/pkg/scheduler"
 )
@@ -34,7 +37,6 @@
   username,
   kind,
   send_email,
-  auto_accept,
   cron,
   url
 FROM waterway.import_configuration`
@@ -47,30 +49,66 @@
 
 	insertImportConfigurationSQL = `
 INSERT INTO waterway.import_configuration
-(username, kind, cron, send_email, auto_accept, url)
-VALUES ($1, $2, $3, $4, $5, $6)
+(username, kind, cron, send_email, url)
+VALUES ($1, $2, $3, $4, $5)
 RETURNING id`
 
+	insertImportConfigurationAttributeSQL = `
+INSERT INTO waterway.import_configuration_attributes
+(import_configuration_id, k, v)
+VALUES ($1, $2, $3)`
+
 	hasImportConfigurationSQL = `
 SELECT true FROM waterway.import_configuration
 WHERE id = $1`
 
+	deleteImportConfiguationAttributesSQL = `
+DELETE FROM waterway.import_configuration_attributes
+WHERE import_configuration_id = $1`
+
 	deleteImportConfiguationSQL = `
 DELETE FROM waterway.import_configuration
 WHERE id = $1`
 
 	updateImportConfigurationSQL = `
 UPDATE waterway.import_configuration SET
-  username = $2
+  username = $2,
   kind = $3,
   cron = $4,
   url = $5,
-  send_email = $6,
-  auto_accept = $7
+  send_email = $6
 WHERE id = $1
 `
 )
 
+func runImportConfig(
+	_ interface{},
+	req *http.Request,
+	conn *sql.Conn,
+) (jr JSONResult, err error) {
+
+	id, _ := strconv.ParseInt(mux.Vars(req)["id"], 10, 64)
+
+	ctx := req.Context()
+
+	var jobID int64
+	if jobID, err = imports.RunConfiguredImportContext(ctx, conn, id); err != nil {
+		return
+	}
+
+	var result = struct {
+		ID int64 `json:"id"`
+	}{
+		ID: jobID,
+	}
+
+	jr = JSONResult{
+		Code:   http.StatusCreated,
+		Result: &result,
+	}
+	return
+}
+
 func modifyImportConfig(
 	input interface{},
 	req *http.Request,
@@ -93,7 +131,7 @@
 	var (
 		entry imports.IDConfig
 		kind  string
-		cron  sql.NullString
+		dummy sql.NullString
 		url   sql.NullString
 	)
 
@@ -102,8 +140,7 @@
 		&entry.User,
 		&kind,
 		&entry.SendEMail,
-		&entry.AutoAccept,
-		&cron,
+		&dummy,
 		&url,
 	)
 
@@ -121,8 +158,10 @@
 	session, _ := auth.GetSession(req)
 
 	entry.SendEMail = importConfig.SendEMail
-	entry.AutoAccept = importConfig.AutoAccept
 
+	// We always take the cron spec from the input.
+	// If there is no spec remove schedule.
+	var cron sql.NullString
 	if importConfig.Cron != nil {
 		cron = sql.NullString{String: string(*importConfig.Cron), Valid: true}
 	}
@@ -138,19 +177,26 @@
 		cron,
 		url,
 		importConfig.SendEMail,
-		importConfig.AutoAccept,
 	); err != nil {
 		return
 	}
 
+	if importConfig.Attributes != nil {
+		if _, err = tx.ExecContext(ctx, deleteImportConfiguationAttributesSQL, id); err != nil {
+			return
+		}
+		if err = storeConfigAttributes(ctx, tx, id, importConfig.Attributes); err != nil {
+			return
+		}
+	}
+
 	scheduler.UnbindByID(id)
 
 	if cron.Valid {
 		if err = scheduler.BindAction(
 			string(importConfig.Kind),
 			cron.String,
-			session.User,
-			&id,
+			id,
 		); err != nil {
 			return
 		}
@@ -180,41 +226,18 @@
 
 	id, _ := strconv.ParseInt(mux.Vars(req)["id"], 10, 64)
 
-	var (
-		entry imports.IDConfig
-		kind  string
-		cron  sql.NullString
-		url   sql.NullString
-	)
+	var entry *imports.IDConfig
 
-	err = conn.QueryRowContext(ctx, selectImportConfigurationIDSQL, id).Scan(
-		&entry.ID,
-		&entry.User,
-		&kind,
-		&entry.SendEMail,
-		&entry.AutoAccept,
-		&cron,
-		&url,
-	)
-
+	entry, err = imports.LoadIDConfigContext(ctx, conn, id)
 	switch {
-	case err == sql.ErrNoRows:
+	case err != nil:
+		return
+	case entry == nil:
 		err = JSONError{
 			Code:    http.StatusNotFound,
 			Message: fmt.Sprintf("No schedule %d found", id),
 		}
 		return
-	case err != nil:
-		return
-	}
-
-	entry.Kind = imports.ImportKind(kind)
-	if cron.Valid {
-		cs := imports.CronSpec(cron.String)
-		entry.Cron = &cs
-	}
-	if url.Valid {
-		entry.URL = &url.String
 	}
 
 	jr = JSONResult{Result: &entry}
@@ -253,6 +276,10 @@
 		return
 	}
 
+	if _, err = tx.ExecContext(ctx, deleteImportConfiguationAttributesSQL, id); err != nil {
+		return
+	}
+
 	if _, err = tx.ExecContext(ctx, deleteImportConfiguationSQL, id); err != nil {
 		return
 	}
@@ -274,6 +301,36 @@
 	return
 }
 
+func storeConfigAttributes(
+	ctx context.Context,
+	tx *sql.Tx,
+	id int64,
+	attrs common.Attributes,
+) error {
+	if len(attrs) == 0 {
+		return nil
+	}
+	attrStmt, err := tx.PrepareContext(ctx, insertImportConfigurationAttributeSQL)
+	if err != nil {
+		return err
+	}
+	defer attrStmt.Close()
+	// Sort to make it deterministic
+	keys := make([]string, len(attrs))
+	i := 0
+	for key := range attrs {
+		keys[i] = key
+		i++
+	}
+	sort.Strings(keys)
+	for _, key := range keys {
+		if _, err := attrStmt.ExecContext(ctx, id, key, attrs[key]); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
 func addImportConfig(
 	input interface{},
 	req *http.Request,
@@ -310,19 +367,22 @@
 		string(importConfig.Kind),
 		cron,
 		importConfig.SendEMail,
-		importConfig.AutoAccept,
 		url,
 	).Scan(&id); err != nil {
 		return
 	}
 
+	// Store extra attributes
+	if err = storeConfigAttributes(ctx, tx, id, importConfig.Attributes); err != nil {
+		return
+	}
+
 	// Need to start a scheduler job right away?
 	if importConfig.Cron != nil {
 		if err = scheduler.BindAction(
 			string(importConfig.Kind),
 			string(*importConfig.Cron),
-			session.User,
-			&id,
+			id,
 		); err != nil {
 			return
 		}
@@ -330,6 +390,7 @@
 
 	if err = tx.Commit(); err != nil {
 		scheduler.UnbindByID(id)
+		return
 	}
 
 	var result = struct {
@@ -373,7 +434,6 @@
 			&entry.User,
 			&kind,
 			&entry.SendEMail,
-			&entry.AutoAccept,
 			&cron,
 			&url,
 		); err != nil {
--- a/pkg/controllers/importqueue.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/controllers/importqueue.go	Tue Jan 15 10:07:10 2019 +0100
@@ -66,6 +66,25 @@
 DELETE FROM waterway.imports WHERE id = $1`
 )
 
+func toInt8Array(txt string) *pgtype.Int8Array {
+	parts := strings.Split(txt, ",")
+	var ints []int64
+	for _, part := range parts {
+		part = strings.TrimSpace(part)
+		v, err := strconv.ParseInt(part, 10, 64)
+		if err != nil {
+			continue
+		}
+		ints = append(ints, v)
+	}
+	var ia pgtype.Int8Array
+	if err := ia.Set(ints); err != nil {
+		log.Printf("warn: %v\n", err)
+		return nil
+	}
+	return &ia
+}
+
 func toTextArray(txt string, allowed []string) *pgtype.TextArray {
 	parts := strings.Split(txt, ",")
 	var accepted []string
@@ -101,6 +120,7 @@
 		args   []interface{}
 		states *pgtype.TextArray
 		kinds  *pgtype.TextArray
+		ids    *pgtype.Int8Array
 	)
 
 	arg := func(format string, v interface{}) {
@@ -116,8 +136,12 @@
 		kinds = toTextArray(ks, imports.ImportKindNames())
 	}
 
+	if idss := req.FormValue("ids"); idss != "" {
+		ids = toInt8Array(idss)
+	}
+
 	stmt.WriteString(selectImportsSQL)
-	if states != nil || kinds != nil {
+	if states != nil || kinds != nil || ids != nil {
 		stmt.WriteString(" WHERE ")
 	}
 
@@ -125,7 +149,7 @@
 		arg(" state = ANY($%d) ", states)
 	}
 
-	if states != nil && kinds != nil {
+	if states != nil && (kinds != nil || ids != nil) {
 		stmt.WriteString("AND")
 	}
 
@@ -133,6 +157,14 @@
 		arg(" kind = ANY($%d) ", kinds)
 	}
 
+	if (states != nil || kinds != nil) && ids != nil {
+		stmt.WriteString("AND")
+	}
+
+	if ids != nil {
+		arg(" id = ANY($%d) ", ids)
+	}
+
 	stmt.WriteString(" ORDER BY enqueued DESC ")
 
 	if lim := req.FormValue("limit"); lim != "" {
@@ -411,12 +443,12 @@
 	err = tx.QueryRowContext(ctx, isPendingSQL, id).Scan(&pending, &kind)
 	switch {
 	case err == sql.ErrNoRows:
-		err = fmt.Errorf("Cannot find import #%d.", id)
+		err = fmt.Errorf("cannot find import #%d", id)
 		return
 	case err != nil:
 		return
 	case !pending:
-		err = fmt.Errorf("Import %d is not pending.", id)
+		err = fmt.Errorf("import %d is not pending", id)
 		return
 	}
 
--- a/pkg/controllers/json.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/controllers/json.go	Tue Jan 15 10:07:10 2019 +0100
@@ -26,33 +26,71 @@
 	"gemma.intevation.de/gemma/pkg/auth"
 )
 
+// JSONResult defines the return type of JSONHandler handler function.
 type JSONResult struct {
-	Code   int
+	// Code is the HTTP status code to be set which defaults to http.StatusOK (200).
+	Code int
+	// Result is serialized to JSON.
+	// If the type is an io.Reader its copied through.
 	Result interface{}
 }
 
+// JSONDefaultLimit is default size limit in bytes of an accepted
+// input document.
+const JSONDefaultLimit = 2048
+
+// JSONHandler implements a middleware to ease the handing JSON input
+// streams and return JSON documents as output.
 type JSONHandler struct {
-	Input  func() interface{}
-	Handle func(interface{}, *http.Request, *sql.Conn) (JSONResult, error)
+	// Input (if not nil) is called to fill a data structure
+	// returned by this function.
+	Input func() interface{}
+	// Handle is called to handle the incoming HTTP request.
+	// in is the data structure returned by Input. Its nil if Input is nil.
+	// req is the incoming HTTP request.
+	// conn is the impersonated connection to the database.
+	Handle func(in interface{}, rep *http.Request, conn *sql.Conn) (JSONResult, error)
+	// NoConn if set to true no database connection is established and
+	// the conn parameter of the Handle call is nil.
 	NoConn bool
+	// Limit overides the default size of accepted input documents.
+	// Set to a negative value to allow an arbitrary size.
+	// Handle with care!
+	Limit int64
 }
 
+// JSONError is an error if returned by the JSONHandler.Handle function
+// which ends up encoded as a JSON document.
 type JSONError struct {
-	Code    int
+	// Code is the HTTP status code of the result defaults
+	// to http.StatusInternalServerError if not set.
+	Code int
+	// The message of the error.
 	Message string
 }
 
+// Error implements the error interface.
 func (je JSONError) Error() string {
 	return fmt.Sprintf("%d: %s", je.Code, je.Message)
 }
 
+// ServeHTTP makes the JSONHandler a middleware.
 func (j *JSONHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 
 	var input interface{}
 	if j.Input != nil {
 		input = j.Input()
 		defer req.Body.Close()
-		if err := json.NewDecoder(req.Body).Decode(input); err != nil {
+		var r io.Reader
+		switch {
+		case j.Limit == 0:
+			r = io.LimitReader(req.Body, JSONDefaultLimit)
+		case j.Limit > 0:
+			r = io.LimitReader(req.Body, j.Limit)
+		default:
+			r = req.Body
+		}
+		if err := json.NewDecoder(r).Decode(input); err != nil {
 			http.Error(rw, "error: "+err.Error(), http.StatusBadRequest)
 			return
 		}
@@ -135,6 +173,8 @@
 	}
 }
 
+// SendJSON sends data JSON encoded to the response writer
+// with a given HTTP status code.
 func SendJSON(rw http.ResponseWriter, code int, data interface{}) {
 	rw.Header().Set("Content-Type", "application/json")
 	rw.WriteHeader(code)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/controllers/manualimports.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,132 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+//  * Raimund Renkert <raimund.renkert@intevation.de>
+
+package controllers
+
+import (
+	"database/sql"
+	"log"
+	"net/http"
+	"time"
+
+	"gemma.intevation.de/gemma/pkg/auth"
+	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/imports"
+	"gemma.intevation.de/gemma/pkg/models"
+)
+
+func retry(a common.Attributes) (time.Time, int) {
+	due, _ := a.Time("due")
+	retries, ok := a.Int("retries")
+	if !ok {
+		retries = -1
+	}
+	return due, retries
+}
+
+func importBottleneck(input interface{}) (interface{}, time.Time, int, bool) {
+	bi := input.(*models.BottleneckImport)
+	bn := &imports.Bottleneck{
+		URL:      bi.URL,
+		Insecure: bi.Insecure,
+	}
+	due, retries := retry(bi.Attributes)
+	return bn, due, retries, bi.SendEmail
+}
+
+func importGaugeMeasurement(input interface{}) (interface{}, time.Time, int, bool) {
+	gi := input.(*models.GaugeMeasurementImport)
+	gm := &imports.GaugeMeasurement{
+		URL:      gi.URL,
+		Insecure: gi.Insecure,
+	}
+	due, retries := retry(gi.Attributes)
+	return gm, due, retries, gi.SendEmail
+}
+
+func importFairwayAvailability(input interface{}) (interface{}, time.Time, int, bool) {
+	fai := input.(*models.FairwayAvailabilityImport)
+	fa := &imports.FairwayAvailability{
+		URL:      fai.URL,
+		Insecure: fai.Insecure,
+	}
+	due, retries := retry(fai.Attributes)
+	return fa, due, retries, fai.SendEmail
+}
+
+func importWaterwayAxis(input interface{}) (interface{}, time.Time, int, bool) {
+	wxi := input.(*models.WaterwayAxisImport)
+	wx := &imports.WaterwayAxis{
+		URL:         wxi.URL,
+		FeatureType: wxi.FeatureType,
+		SortBy:      wxi.SortBy,
+	}
+	due, retries := retry(wxi.Attributes)
+	return wx, due, retries, wxi.SendEmail
+}
+
+func importWaterwayArea(input interface{}) (interface{}, time.Time, int, bool) {
+	wai := input.(*models.WaterwayAreaImport)
+	wa := &imports.WaterwayArea{
+		URL:         wai.URL,
+		FeatureType: wai.FeatureType,
+		SortBy:      wai.SortBy,
+	}
+	due, retries := retry(wai.Attributes)
+	return wa, due, retries, wai.SendEmail
+}
+
+func manualImport(
+	kind imports.JobKind,
+	setup func(interface{}) (interface{}, time.Time, int, bool),
+) func(interface{}, *http.Request, *sql.Conn) (JSONResult, error) {
+
+	return func(input interface{}, req *http.Request, _ *sql.Conn) (
+		jr JSONResult, err error) {
+
+		what, due, retries, sendEmail := setup(input)
+
+		var serialized string
+		if serialized, err = common.ToJSONString(what); err != nil {
+			return
+		}
+
+		session, _ := auth.GetSession(req)
+
+		var jobID int64
+		if jobID, err = imports.AddJob(
+			kind,
+			due, retries,
+			session.User,
+			sendEmail,
+			serialized,
+		); err != nil {
+			return
+		}
+
+		log.Printf("info: added import #%d to queue\n", jobID)
+
+		result := struct {
+			ID int64 `json:"id"`
+		}{
+			ID: jobID,
+		}
+
+		jr = JSONResult{
+			Code:   http.StatusCreated,
+			Result: &result,
+		}
+		return
+	}
+}
--- a/pkg/controllers/proxy.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/controllers/proxy.go	Tue Jan 15 10:07:10 2019 +0100
@@ -118,7 +118,7 @@
 ) {
 	switch enc := h.Get("Content-Encoding"); {
 	case strings.Contains(enc, "gzip"):
-		log.Println("gzip compression")
+		log.Println("info: gzip compression")
 		return func(r io.Reader) (io.ReadCloser, error) {
 				return gzip.NewReader(r)
 			},
@@ -126,7 +126,7 @@
 				return gzip.NewWriter(w), nil
 			}
 	case strings.Contains(enc, "deflate"):
-		log.Println("Deflate compression")
+		log.Println("info: deflate compression")
 		return func(r io.Reader) (io.ReadCloser, error) {
 				return flate.NewReader(r), nil
 			},
@@ -134,7 +134,7 @@
 				return flate.NewWriter(w, flate.DefaultCompression)
 			}
 	default:
-		log.Println("No content compression")
+		log.Println("info: no content compression")
 		return func(r io.Reader) (io.ReadCloser, error) {
 				if r2, ok := r.(io.ReadCloser); ok {
 					return r2, nil
@@ -183,13 +183,12 @@
 				w.Close()
 				pw.Close()
 				force.Close()
-				log.Printf("rewrite took %s\n", time.Since(start))
+				log.Printf("info: rewrite took %s\n", time.Since(start))
 			}()
 			if err := rewrite(suffix, w, r); err != nil {
-				log.Printf("rewrite failed: %v\n", err)
+				log.Printf("error: rewrite failed: %v\n", err)
 				return
 			}
-			log.Println("rewrite successful")
 		}(resp.Body)
 
 		resp.Body = pr
--- a/pkg/controllers/routes.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/controllers/routes.go	Tue Jan 15 10:07:10 2019 +0100
@@ -26,6 +26,7 @@
 	"gemma.intevation.de/gemma/pkg/models"
 )
 
+// BindRoutes binds all the API endpoints to the exposed router.
 func BindRoutes(m *mux.Router) {
 
 	api := m.PathPrefix("/api").Subrouter()
@@ -171,19 +172,48 @@
 	api.Handle("/imports/soundingresult", waterwayAdmin(
 		http.HandlerFunc(importSoundingResult))).Methods(http.MethodPost)
 
+	api.Handle("/imports/approvedgm", waterwayAdmin(
+		http.HandlerFunc(importApprovedGaugeMeasurements))).Methods(http.MethodPost)
+
 	api.Handle("/imports/bottleneck", waterwayAdmin(&JSONHandler{
 		Input:  func() interface{} { return new(models.BottleneckImport) },
-		Handle: importBottleneck,
+		Handle: manualImport(imports.BNJobKind, importBottleneck),
+		NoConn: true,
 	})).Methods(http.MethodPost)
 
 	api.Handle("/imports/gaugemeasurement", waterwayAdmin(&JSONHandler{
 		Input:  func() interface{} { return new(models.GaugeMeasurementImport) },
-		Handle: importGaugeMeasurement,
+		Handle: manualImport(imports.GMJobKind, importGaugeMeasurement),
+		NoConn: true,
+	})).Methods(http.MethodPost)
+
+	api.Handle("/imports/fairwayavailability", waterwayAdmin(&JSONHandler{
+		Input:  func() interface{} { return new(models.FairwayAvailabilityImport) },
+		Handle: manualImport(imports.FAJobKind, importFairwayAvailability),
+		NoConn: true,
+	})).Methods(http.MethodPost)
+
+	api.Handle("/imports/waterwayaxis", waterwayAdmin(&JSONHandler{
+		Input:  func() interface{} { return new(models.WaterwayAxisImport) },
+		Handle: manualImport(imports.WXJobKind, importWaterwayAxis),
+		NoConn: true,
+	})).Methods(http.MethodPost)
+
+	api.Handle("/imports/waterwayarea", waterwayAdmin(&JSONHandler{
+		Input:  func() interface{} { return new(models.WaterwayAreaImport) },
+		Handle: manualImport(imports.WAJobKind, importWaterwayArea),
+		NoConn: true,
 	})).Methods(http.MethodPost)
 
 	// Import scheduler configuration
+	api.Handle("/imports/config/{id:[0-9]+}/run",
+		waterwayAdmin(&JSONHandler{
+			Handle: runImportConfig,
+		})).Methods(http.MethodGet)
+
 	api.Handle("/imports/config/{id:[0-9]+}",
 		waterwayAdmin(&JSONHandler{
+			Input:  func() interface{} { return new(imports.Config) },
 			Handle: modifyImportConfig,
 		})).Methods(http.MethodPatch)
 
--- a/pkg/controllers/srimports.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/controllers/srimports.go	Tue Jan 15 10:07:10 2019 +0100
@@ -161,10 +161,30 @@
 
 	session, _ := auth.GetSession(req)
 
+	sendEmail := req.FormValue("email") != ""
+
+	var due time.Time
+	if d := req.FormValue("due"); d != "" {
+		var err error
+		if due, err = time.Parse("2006-01-02T15:04:05", d); err != nil {
+			log.Printf("error: %v\n", err)
+		}
+	}
+
+	retries := -1
+	if r := req.FormValue("retries"); r != "" {
+		var err error
+		if retries, err = strconv.Atoi(r); err != nil {
+			log.Printf("error: %v\n", err)
+			retries = -1
+		}
+	}
+
 	jobID, err := imports.AddJob(
 		imports.SRJobKind,
+		due, retries,
 		session.User,
-		false, false,
+		sendEmail,
 		serialized)
 
 	if err != nil {
--- a/pkg/controllers/user.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/controllers/user.go	Tue Jan 15 10:07:10 2019 +0100
@@ -113,9 +113,21 @@
 		return
 	}
 
+	ctx := req.Context()
+
+	// Remove scheduled tasks.
+	ids, err2 := scheduler.ScheduledUserIDs(ctx, db, user)
+	if err2 == nil {
+		if len(ids) > 0 {
+			go func() { scheduler.UnbindByIDs(ids) }()
+		}
+	} else {
+		log.Printf("error: %v\n", err2)
+	}
+
 	var res sql.Result
 
-	if res, err = db.ExecContext(req.Context(), deleteUserSQL, user); err != nil {
+	if res, err = db.ExecContext(ctx, deleteUserSQL, user); err != nil {
 		return
 	}
 
@@ -129,7 +141,6 @@
 
 	// Running in a go routine should not be necessary.
 	go func() { auth.Sessions.Logout(user) }()
-	go func() { scheduler.UnbindUser(user) }()
 
 	jr = JSONResult{Code: http.StatusNoContent}
 	return
@@ -207,7 +218,6 @@
 	if user != newUser.User {
 		// Running in a go routine should not be necessary.
 		go func() { auth.Sessions.Logout(string(user)) }()
-		go func() { scheduler.UnbindUser(string(user)) }()
 	}
 
 	jr = JSONResult{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/imports/agm.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,327 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package imports
+
+import (
+	"bufio"
+	"context"
+	"database/sql"
+	"encoding/csv"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+
+	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/models"
+)
+
+type ApprovedGaugeMeasurements struct {
+	Dir string `json:"dir"`
+}
+
+// GMAPJobKind is the unique name of an approved gauge measurements import job.
+const AGMJobKind JobKind = "agm"
+
+type agmJobCreator struct{}
+
+func init() {
+	RegisterJobCreator(AGMJobKind, agmJobCreator{})
+}
+
+func (agmJobCreator) AutoAccept() bool { return false }
+
+func (agmJobCreator) Description() string {
+	return "approved gauge measurements"
+}
+
+func (agmJobCreator) Create(_ JobKind, data string) (Job, error) {
+	agm := new(ApprovedGaugeMeasurements)
+	if err := common.FromJSONString(data, agm); err != nil {
+		return nil, err
+	}
+	return agm, nil
+}
+
+func (agmJobCreator) Depends() []string {
+	return []string{
+		"gauges",
+		"gauge_measurements",
+	}
+}
+
+const (
+	// delete the old  and keep the new measures.
+	agmStageDoneDeleteSQL = `
+WITH staged AS (
+  SELECT key
+  FROM waterway.track_imports
+  WHERE import_id = $1 AND
+        relation = 'waterway.gauge_measurements'::regclass
+),
+to_delete AS (
+  SELECT o.id AS id
+  FROM waterway.gauge_measurements o
+  JOIN waterway.gauge_measurements n
+    ON n.fk_gauge_id = o.fk_gauge_id AND n.measure_date = o.measure_date
+    WHERE n.id     IN (SELECT key FROM staged)
+	  AND o.id NOT IN (SELECT key FROM staged)
+)
+DELETE FROM waterway.gauge_measurements WHERE id IN (SELECT id from to_delete)`
+
+	agmStageDoneSQL = `
+UPDATE waterway.gauge_measurements SET staging_done = true
+WHERE id IN (
+  SELECT key FROM waterway.track_imports
+  WHERE import_id = $1 AND
+    relation = 'waterway.gauge_measurements'::regclass)`
+)
+
+func (agmJobCreator) StageDone(
+	ctx context.Context,
+	tx *sql.Tx,
+	id int64,
+) error {
+	_, err := tx.ExecContext(ctx, agmStageDoneDeleteSQL, id)
+	if err == nil {
+		_, err = tx.ExecContext(ctx, agmStageDoneSQL, id)
+	}
+	return err
+}
+
+// CleanUp removes the folder containing the CSV file with the
+// the approved gauge measurements.
+func (agm *ApprovedGaugeMeasurements) CleanUp() error {
+	return os.RemoveAll(agm.Dir)
+}
+
+func guessDate(s string) (time.Time, error) {
+	var err error
+	var t time.Time
+	for _, layout := range [...]string{
+		"02.01.2006 15:04",
+		"2006-01-02T15:04:05-07:00",
+	} {
+		if t, err = time.Parse(layout, s); err == nil {
+			break
+		}
+	}
+	return t, err
+}
+
+// Do executes the actual approved gauge measurements import.
+func (agm *ApprovedGaugeMeasurements) Do(
+	ctx context.Context,
+	importID int64,
+	conn *sql.Conn,
+	feedback Feedback,
+) (interface{}, error) {
+
+	start := time.Now()
+
+	f, err := os.Open(filepath.Join(agm.Dir, "agm.csv"))
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	r := csv.NewReader(bufio.NewReader(f))
+	r.Comma = ';'
+	r.ReuseRecord = true
+
+	headers, err := r.Read()
+	if err != nil {
+		return nil, err
+	}
+
+	headerIndices := map[string]int{}
+
+	for i, f := range headers {
+		headerIndices[strings.Replace(
+			strings.ToLower(
+				strings.TrimSpace(f)), " ", "_", -1)] = i
+	}
+
+	var missing []string
+
+	for _, m := range [...]string{
+		"fk_gauge_id",
+		"measure_date",
+		"from", // "sender",
+		"language_code",
+		"country_code",
+		"date_issue",
+		"reference_code",
+		"value", // "water_level",
+		"predicted",
+		// "is_waterlevel",
+		"value_min",
+		"value_max",
+		"date_info",
+		"originator", // "source_organization",
+	} {
+		if _, found := headerIndices[m]; !found {
+			missing = append(missing, m)
+		}
+	}
+
+	if len(missing) > 0 {
+		return nil, fmt.Errorf("Missing columns: %s", strings.Join(missing, ", "))
+	}
+
+	inCm, _ := rescale("cm")
+	scaler := func(row []string) (func(float32) float32, error) {
+		idx, found := headerIndices["unit"]
+		if !found {
+			return inCm, nil
+		}
+		unit := row[idx]
+		if unit == "cm" {
+			return inCm, nil
+		}
+		s, err := rescale(unit)
+		return s, err
+	}
+
+	tx, err := conn.BeginTx(ctx, nil)
+	if err != nil {
+		return nil, err
+	}
+	defer tx.Rollback()
+
+	insertStmt, err := tx.PrepareContext(ctx, insertGMSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer insertStmt.Close()
+	trackStmt, err := tx.PrepareContext(ctx, trackImportSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer trackStmt.Close()
+
+	ids := []int64{}
+
+	args := make([]interface{}, 19)
+
+	args[18] = false // staging_done
+
+lines:
+	for line := 1; ; line++ {
+
+		row, err := r.Read()
+		switch {
+		case err == io.EOF || len(row) == 0:
+			break lines
+		case err != nil:
+			return nil, fmt.Errorf("CSV parsing failed: %v", err)
+		}
+		convert, err := scaler(row)
+		if err != nil {
+			return nil, fmt.Errorf("line %d: %v", line, err)
+		}
+
+		gids := row[headerIndices["fk_gauge_id"]]
+		gid, err := models.IsrsFromString(gids)
+		if err != nil {
+			return nil, fmt.Errorf("Invalid ISRS code line %d: %v", line, err)
+		}
+
+		args[0] = gid.CountryCode
+		args[1] = gid.LoCode
+		args[2] = gid.FairwaySection
+		args[3] = gid.Orc
+		args[4] = gid.Hectometre
+
+		md, err := guessDate(row[headerIndices["measure_date"]])
+		if err != nil {
+			return nil, fmt.Errorf("Invalid 'measure_date' line %d: %v", line, err)
+		}
+		args[5] = md
+
+		args[6] = row[headerIndices["from"]]
+		args[7] = row[headerIndices["language_code"]]
+		args[8] = row[headerIndices["country_code"]]
+
+		dis, err := guessDate(row[headerIndices["date_issue"]])
+		if err != nil {
+			return nil, fmt.Errorf("Invalid 'date_issue' line %d: %v", line, err)
+		}
+		args[9] = dis
+
+		args[10] = row[headerIndices["reference_code"]]
+
+		value, err := strconv.ParseFloat(row[headerIndices["value"]], 32)
+		if err != nil {
+			return nil, fmt.Errorf("Invalid 'value' line %d: %v", line, err)
+		}
+		args[11] = convert(float32(value))
+
+		predicted := strings.ToLower(row[headerIndices["predicted"]]) == "true"
+		args[12] = predicted
+
+		args[13] = true // is_waterlevel
+
+		valueMin, err := strconv.ParseFloat(row[headerIndices["value_min"]], 32)
+		if err != nil {
+			return nil, fmt.Errorf("Invalid 'value_min' line %d: %v", line, err)
+		}
+		args[14] = convert(float32(valueMin))
+
+		valueMax, err := strconv.ParseFloat(row[headerIndices["value_max"]], 32)
+		if err != nil {
+			return nil, fmt.Errorf("Invalid 'value_max' line %d: %v", line, err)
+		}
+		args[15] = convert(float32(valueMax))
+
+		din, err := guessDate(row[headerIndices["date_info"]])
+		if err != nil {
+			return nil, fmt.Errorf("Invalid 'date_info' line %d: %v", line, err)
+		}
+		args[16] = din
+
+		args[17] = row[headerIndices["originator"]]
+
+		// args[18] (staging_done) is set to true outside the loop.
+
+		var id int64
+		if err := insertStmt.QueryRowContext(ctx, args...).Scan(&id); err != nil {
+			return nil, fmt.Errorf("Failed to insert line %d: %v", line, err)
+		}
+		ids = append(ids, id)
+
+		if _, err := trackStmt.ExecContext(
+			ctx, importID, "waterway.gauge_measurements", id,
+		); err != nil {
+			return nil, err
+		}
+	}
+
+	if err := tx.Commit(); err != nil {
+		return nil, fmt.Errorf("Commit failed: %v", err)
+	}
+
+	feedback.Info("Importing approved gauge measurements took %s",
+		time.Since(start))
+
+	summary := struct {
+		IDs []int64 `json:"ids"`
+	}{
+		IDs: ids,
+	}
+	return &summary, nil
+}
--- a/pkg/imports/bn.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/imports/bn.go	Tue Jan 15 10:07:10 2019 +0100
@@ -25,18 +25,24 @@
 	"gemma.intevation.de/gemma/pkg/soap/ifbn"
 )
 
+// Bottleneck is an import job to import
+// bottlenecks from an IFBN SOAP service.
 type Bottleneck struct {
-	URL      string `json:"url"`
-	Insecure bool   `json:"insecure"`
+	// URL is the URL of the SOAP service.
+	URL string `json:"url"`
+	// Insecure indicates if HTTPS traffic
+	// should validate certificates or not.
+	Insecure bool `json:"insecure"`
 }
 
+// BNJobKind is the import queue type identifier.
 const BNJobKind JobKind = "bn"
 
 const (
 	hasBottleneckSQL = `
 SELECT true FROM waterway.bottlenecks WHERE bottleneck_id = $1`
 
-	insertSQL = `
+	insertBottleneckSQL = `
 INSERT INTO waterway.bottlenecks (
   bottleneck_id,
   fk_g_fid,
@@ -79,6 +85,10 @@
 	RegisterJobCreator(BNJobKind, bnJobCreator{})
 }
 
+func (bnJobCreator) Description() string { return "bottlenecks" }
+
+func (bnJobCreator) AutoAccept() bool { return false }
+
 func (bnJobCreator) Create(_ JobKind, data string) (Job, error) {
 	bn := new(Bottleneck)
 	if err := common.FromJSONString(data, bn); err != nil {
@@ -89,13 +99,12 @@
 
 func (bnJobCreator) Depends() []string {
 	return []string{
-		"waterway.gauges",
-		"waterway.bottlenecks",
+		"gauges",
+		"bottlenecks",
 	}
 }
 
 const (
-	// TODO: waterway.bottlenecks needs an integer id column.
 	bnStageDoneSQL = `
 UPDATE waterway.bottlenecks SET staging_done = true
 WHERE id IN (
@@ -115,7 +124,7 @@
 }
 
 // CleanUp of a bottleneck import is a NOP.
-func (bn *Bottleneck) CleanUp() error { return nil }
+func (*Bottleneck) CleanUp() error { return nil }
 
 var rblbRe = regexp.MustCompile(`(..)_(..)`)
 
@@ -174,7 +183,7 @@
 		stmt **sql.Stmt
 	}{
 		{hasBottleneckSQL, &hasStmt},
-		{insertSQL, &insertStmt},
+		{insertBottleneckSQL, &insertStmt},
 		{trackImportSQL, &trackStmt},
 	} {
 		var err error
@@ -241,7 +250,7 @@
 		); err != nil {
 			return nil, err
 		}
-		feedback.Info("Inserted '%s'into database", bn.OBJNAM)
+		feedback.Info("Inserted '%s' into database", bn.OBJNAM)
 	}
 	if len(nids) == 0 {
 		feedback.Error("No new bottlenecks found")
@@ -253,7 +262,6 @@
 		feedback.Info("Import of bottlenecks was successful")
 	}
 
-	// TODO: needs to be filled more useful.
 	summary := struct {
 		Bottlenecks []string `json:"bottlenecks"`
 	}{
--- a/pkg/imports/config.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/imports/config.go	Tue Jan 15 10:07:10 2019 +0100
@@ -14,35 +14,58 @@
 package imports
 
 import (
+	"context"
+	"database/sql"
 	"encoding/json"
 	"fmt"
 
 	"github.com/robfig/cron"
+
+	"gemma.intevation.de/gemma/pkg/auth"
+	"gemma.intevation.de/gemma/pkg/common"
 )
 
 type (
-	CronSpec   string
+	// CronSpec is a string containing a cron line.
+	CronSpec string
+
+	// ImportKind is a string which has to be one
+	// of the registered import types.
 	ImportKind string
 
+	// Config is JSON serialized form of a import configuration.
 	Config struct {
-		Kind       ImportKind `json:"kind"`
-		SendEMail  bool       `json:"send-email"`
-		AutoAccept bool       `json:"auto-accept"`
-		Cron       *CronSpec  `json:"cron"`
-		URL        *string    `json:"url"`
+		// Kind is the import type.
+		Kind ImportKind `json:"kind"`
+		// SendEMail indicates if a mail should be be send
+		// when the import was changed to states
+		// 'pending' or 'failed'.
+		SendEMail bool `json:"send-email"`
+		// Cron is the cron schedule
+		// of this configuration if this value is not
+		// nil. If nil the import is not scheduled.
+		Cron *CronSpec `json:"cron"`
+		// URL is an optional URL used by the import.
+		URL *string `json:"url"`
+		// Attributes are optional key/value pairs for a configuration.
+		Attributes common.Attributes `json:"attributes,omitempty"`
 	}
 
+	// IDConfig is the same as Config with an ID.
+	// Mainly used for server delivered configurations.
 	IDConfig struct {
-		ID         int64      `json:"id"`
-		User       string     `json:"user"`
-		Kind       ImportKind `json:"kind"`
-		SendEMail  bool       `json:"send-email"`
-		AutoAccept bool       `json:"auto-accept"`
-		Cron       *CronSpec  `json:"cron,omitempty"`
-		URL        *string    `json:"url,omitempty"`
+		ID         int64             `json:"id"`
+		User       string            `json:"user"`
+		Kind       ImportKind        `json:"kind"`
+		SendEMail  bool              `json:"send-email"`
+		Cron       *CronSpec         `json:"cron,omitempty"`
+		URL        *string           `json:"url,omitempty"`
+		Attributes common.Attributes `json:"attributes,omitempty"`
 	}
 )
 
+// UnmarshalJSON checks if the incoming string
+// is a registered import type.
 func (ik *ImportKind) UnmarshalJSON(data []byte) error {
 	var s string
 	if err := json.Unmarshal(data, &s); err != nil {
@@ -58,6 +81,8 @@
 	return nil
 }
 
+// UnmarshalJSON checks if the incoming string is
+// a valid cron line.
 func (cs *CronSpec) UnmarshalJSON(data []byte) error {
 	var spec string
 	if err := json.Unmarshal(data, &spec); err != nil {
@@ -67,5 +92,94 @@
 		return err
 	}
 	*cs = CronSpec(spec)
+
 	return nil
 }
+
+const (
+	configUser = "sys_admin"
+
+	loadConfigSQL = `
+SELECT
+  username,
+  kind,
+  send_email,
+  cron,
+  url
+FROM waterway.import_configuration
+WHERE id = $1`
+
+	loadConfigAttributesSQL = `
+SELECT k, v
+FROM waterway.import_configuration_attributes
+WHERE import_configuration_id = $1`
+)
+
+// LoadIDConfigContext loads an import configuration from database.
+func LoadIDConfigContext(ctx context.Context, conn *sql.Conn, id int64) (*IDConfig, error) {
+
+	cfg := &IDConfig{ID: id}
+	var kind ImportKind
+	var cron, url sql.NullString
+	err := conn.QueryRowContext(ctx, loadConfigSQL, id).Scan(
+		&cfg.User,
+		&kind,
+		&cfg.SendEMail,
+		&cron,
+		&url,
+	)
+
+	switch {
+	case err == sql.ErrNoRows:
+		return nil, nil
+	case err != nil:
+		return nil, err
+	}
+
+	cfg.Kind = ImportKind(kind)
+	if cron.Valid {
+		c := CronSpec(cron.String)
+		cfg.Cron = &c
+	}
+	if url.Valid {
+		cfg.URL = &url.String
+	}
+	// load the extra attributes.
+	rows, err := conn.QueryContext(ctx, loadConfigAttributesSQL, id)
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close()
+	var attributes common.Attributes
+	for rows.Next() {
+		var k, v string
+		if err = rows.Scan(&k, &v); err != nil {
+			return nil, err
+		}
+		if attributes == nil {
+			attributes = common.Attributes{}
+		}
+		attributes[k] = v
+	}
+	if err = rows.Err(); err != nil {
+		return nil, err
+	}
+	if len(attributes) > 0 {
+		cfg.Attributes = attributes
+	}
+	return cfg, nil
+}
+
+func loadIDConfig(id int64) (*IDConfig, error) {
+	return loadIDConfigContext(context.Background(), id)
+}
+
+func loadIDConfigContext(ctx context.Context, id int64) (*IDConfig, error) {
+	var cfg *IDConfig
+	err := auth.RunAs(ctx, configUser, func(conn *sql.Conn) error {
+		var err error
+		cfg, err = LoadIDConfigContext(ctx, conn, id)
+		return err
+	})
+	return cfg, err
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/imports/email.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,91 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package imports
+
+import (
+	"context"
+	"database/sql"
+	"log"
+	"strings"
+	"text/template"
+
+	"gemma.intevation.de/gemma/pkg/auth"
+	"gemma.intevation.de/gemma/pkg/config"
+	"gemma.intevation.de/gemma/pkg/misc"
+)
+
+const (
+	selectEmailSQL = `SELECT email_address FROM users.list_users WHERE username = $1`
+
+	importNotificationMailSubject = `import notification mail`
+)
+
+var (
+	importNotificationMailTmpl = template.Must(
+		template.New("notification").Parse(`Dear {{ .User }},
+
+a {{ .Description }} import on server {{ .Server }} triggered
+this email notification.
+
+{{ if eq .State "accepted" }}The imported data were successfully integrated into the database.{{ end -}}
+{{ if eq .State "failed" }}The import failed for some reasons.{{ end -}}
+{{ if eq .State "pending" }}The imported data could be integrated into the database
+but your final decision is needed.{{ end }}
+
+Please follow this link to have a closer look at the details:
+
+{{ .Server }}/#/?{{ if eq .State "pending" }}review{{ else }}importlog{{ end }}={{ .ID }}
+
+Best regards
+    Your service team`))
+)
+
+func sendNotificationMail(user, description, state string, id int64) {
+	config.WaitReady()
+
+	ctx := context.Background()
+	var email string
+	if err := auth.RunAs(ctx, user,
+		func(conn *sql.Conn) error {
+			return conn.QueryRowContext(ctx, selectEmailSQL, user).Scan(&email)
+		},
+	); err != nil {
+		log.Printf("error: %v\n", err)
+		return
+	}
+
+	data := struct {
+		User        string
+		Description string
+		Server      string
+		State       string
+		ID          int64
+	}{
+		User:        user,
+		Description: description,
+		Server:      config.ExternalURL(),
+		State:       state,
+		ID:          id,
+	}
+
+	var body strings.Builder
+	if err := importNotificationMailTmpl.Execute(&body, &data); err != nil {
+		log.Printf("error: %v\n", err)
+		return
+	}
+
+	if err := misc.SendMail(email, importNotificationMailSubject, body.String()); err != nil {
+		log.Printf("error: %v\n", err)
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/imports/fa.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,460 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Raimund Renkert <raimund.renkert@intevation.de>
+
+package imports
+
+import (
+	"context"
+	"database/sql"
+	"errors"
+	"time"
+
+	"github.com/jackc/pgx/pgtype"
+
+	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/models"
+	"gemma.intevation.de/gemma/pkg/soap/ifaf"
+)
+
+// FairwayAvailability imports fairway availability data
+// from an IFAF SOAP service.
+type FairwayAvailability struct {
+	// URL is the URL of the SOAP service.
+	URL string `json:"url"`
+	// Insecure indicates if HTTPS traffic
+	// should validate certificates or not.
+	Insecure bool `json:"insecure"`
+}
+
+// FAJobKind is import queue type identifier.
+const FAJobKind JobKind = "fa"
+
+const (
+	listBottlenecksSQL = `
+SELECT
+  bottleneck_id,
+  responsible_country
+FROM waterway.bottlenecks
+WHERE responsible_country = users.current_user_country()
+  AND staging_done = true
+`
+	latestMeasureDateSQL = `
+SELECT
+	measure_date
+FROM waterway.effective_fairway_availability
+ORDER BY measure_date DESC LIMIT 1
+`
+	listFairwayAvailabilitySQL = `
+SELECT
+  fa.id,
+  bn.bottleneck_id,
+  fa.surdat
+FROM waterway.fairway_availability fa
+JOIN waterway.bottlenecks bn ON bn.id = fa.bottleneck_id
+`
+	insertFASQL = `
+INSERT INTO waterway.fairway_availability (
+  position_code,
+  bottleneck_id,
+  surdat,
+  critical,
+  date_info,
+  source_organization
+) VALUES (
+  $1,
+  (SELECT id FROM waterway.bottlenecks WHERE bottleneck_id = $2),
+  $3,
+  $4,
+  $5,
+  $6
+)
+RETURNING id`
+
+	insertBnPdfsSQL = `
+INSERT INTO waterway.bottleneck_pdfs (
+  fairway_availability_id,
+  profile_pdf_filename,
+  profile_pdf_url,
+  pdf_generation_date,
+  source_organization
+) VALUES (
+  $1,
+  $2,
+  $3,
+  $4,
+  $5
+) ON CONFLICT ON CONSTRAINT bottleneck_pdfs_pkey DO NOTHING`
+	insertEFASQL = `
+INSERT INTO waterway.effective_fairway_availability (
+  fairway_availability_id,
+  measure_date,
+  level_of_service,
+  available_depth_value,
+  available_width_value,
+  water_level_value,
+  measure_type,
+  source_organization,
+  forecast_generation_time,
+  value_lifetime
+) VALUES (
+  $1,
+  $2,
+  (SELECT
+    level_of_service
+  FROM levels_of_service
+  WHERE name = $3),
+  $4,
+  $5,
+  $6,
+  $7,
+  $8,
+  $9,
+  $10
+) ON CONFLICT ON CONSTRAINT effective_fairway_availability_pkey DO NOTHING`
+	insertFAVSQL = `
+INSERT INTO waterway.fa_reference_values (
+  fairway_availability_id,
+  level_of_service,
+  fairway_depth,
+  fairway_width,
+  fairway_radius,
+  shallowest_spot
+) VALUES (
+  $1,
+  (SELECT
+    level_of_service
+  FROM levels_of_service
+  WHERE name = $2),
+  $3,
+  $4,
+  $5,
+  ST_MakePoint($6, $7)::geography
+)ON CONFLICT ON CONSTRAINT fa_reference_values_pkey DO NOTHING`
+)
+
+type faJobCreator struct{}
+
+func init() {
+	RegisterJobCreator(FAJobKind, faJobCreator{})
+}
+
+func (faJobCreator) Description() string {
+	return "fairway availability"
+}
+
+func (faJobCreator) Create(_ JobKind, data string) (Job, error) {
+	fa := new(FairwayAvailability)
+	if err := common.FromJSONString(data, fa); err != nil {
+		return nil, err
+	}
+	return fa, nil
+}
+
+func (faJobCreator) Depends() []string {
+	return []string{
+		"bottlenecks",
+		"fairway_availability",
+		"bottleneck_pdfs",
+		"effective_fairway_availability",
+		"fa_reference_values",
+		"levels_of_service",
+	}
+}
+
+func (faJobCreator) AutoAccept() bool { return true }
+
+// StageDone moves the imported fairway availablities out of the staging area.
+// Currently doing nothing.
+func (faJobCreator) StageDone(context.Context, *sql.Tx, int64) error {
+	return nil
+}
+
+// CleanUp of a fairway availablities import is a NOP.
+func (*FairwayAvailability) CleanUp() error { return nil }
+
+// Do executes the actual fairway availability import.
+func (fa *FairwayAvailability) Do(
+	ctx context.Context,
+	importID int64,
+	conn *sql.Conn,
+	feedback Feedback,
+) (interface{}, error) {
+
+	// Get available bottlenecks from database for use as filter in SOAP request
+	var rows *sql.Rows
+
+	rows, err := conn.QueryContext(ctx, listBottlenecksSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close()
+
+	bottlenecks := []models.Bottleneck{}
+
+	for rows.Next() {
+		var bn models.Bottleneck
+		if err = rows.Scan(
+			&bn.ID,
+			&bn.ResponsibleCountry,
+		); err != nil {
+			return nil, err
+		}
+		bottlenecks = append(bottlenecks, bn)
+	}
+	if err = rows.Err(); err != nil {
+		return nil, err
+	}
+
+	var faRows *sql.Rows
+	faRows, err = conn.QueryContext(ctx, listFairwayAvailabilitySQL)
+	if err != nil {
+		return nil, err
+	}
+	fairwayAvailabilities := map[models.UniqueFairwayAvailability]int64{}
+	for faRows.Next() {
+		var id int64
+		var bnId string
+		var sd time.Time
+		if err = faRows.Scan(
+			&id,
+			&bnId,
+			&sd,
+		); err != nil {
+			return nil, err
+		}
+		key := models.UniqueFairwayAvailability{
+			BottleneckId: bnId,
+			Surdat:       sd,
+		}
+		fairwayAvailabilities[key] = id
+	}
+	if err = faRows.Err(); err != nil {
+		return nil, err
+	}
+
+	var latestDate pgtype.Timestamp
+	err = conn.QueryRowContext(ctx, latestMeasureDateSQL).Scan(&latestDate)
+	switch {
+	case err == sql.ErrNoRows:
+		latestDate = pgtype.Timestamp{
+			// Fill Database with data of the last 5 days. Change this to a more useful value.
+			Time: time.Now().AddDate(0, 0, -5),
+		}
+	case err != nil:
+		return nil, err
+	}
+
+	faids, err := fa.doForFAs(ctx, bottlenecks, fairwayAvailabilities, latestDate, conn, feedback)
+	if err != nil {
+		feedback.Error("Error processing data: %s", err)
+	}
+	if len(faids) == 0 {
+		feedback.Info("No new fairway availablity data found")
+		return nil, nil
+	}
+	feedback.Info("Processed %d fairway availabilities", len(faids))
+	// TODO: needs to be filled more useful.
+	summary := struct {
+		FairwayAvailabilities []string `json:"fairwayAvailabilities"`
+	}{
+		FairwayAvailabilities: faids,
+	}
+	return &summary, err
+}
+
+func (fa *FairwayAvailability) doForFAs(
+	ctx context.Context,
+	bottlenecks []models.Bottleneck,
+	fairwayAvailabilities map[models.UniqueFairwayAvailability]int64,
+	latestDate pgtype.Timestamp,
+	conn *sql.Conn,
+	feedback Feedback,
+) ([]string, error) {
+	start := time.Now()
+
+	client := ifaf.NewFairwayAvailabilityService(fa.URL, fa.Insecure, nil)
+
+	var bnIds []string
+	for _, bn := range bottlenecks {
+		bnIds = append(bnIds, bn.ID)
+	}
+	var period ifaf.RequestedPeriod
+	period.Date_start = latestDate.Time
+	period.Date_end = time.Now()
+
+	ids := ifaf.ArrayOfString{
+		String: bnIds,
+	}
+
+	req := &ifaf.Get_bottleneck_fa{
+		Bottleneck_id: &ids,
+		Period:        &period,
+	}
+	resp, err := client.Get_bottleneck_fa(req)
+	if err != nil {
+		feedback.Error("%v", err)
+		return nil, err
+	}
+
+	if resp.Get_bottleneck_faResult == nil {
+		err := errors.New("no fairway availabilities found")
+		return nil, err
+	}
+
+	result := resp.Get_bottleneck_faResult
+
+	tx, err := conn.BeginTx(ctx, nil)
+	if err != nil {
+		return nil, err
+	}
+	defer tx.Rollback()
+
+	insertFAStmt, err := tx.PrepareContext(ctx, insertFASQL)
+	if err != nil {
+		return nil, err
+	}
+	defer insertFAStmt.Close()
+	insertBnPdfsStmt, err := tx.PrepareContext(ctx, insertBnPdfsSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer insertBnPdfsStmt.Close()
+	insertEFAStmt, err := tx.PrepareContext(ctx, insertEFASQL)
+	if err != nil {
+		return nil, err
+	}
+	defer insertEFAStmt.Close()
+	insertFAVStmt, err := tx.PrepareContext(ctx, insertFAVSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer insertFAVStmt.Close()
+
+	var faIDs []string
+	var faID int64
+	feedback.Info("Found %d fairway availabilities", len(result.FairwayAvailability))
+	for _, faRes := range result.FairwayAvailability {
+		uniqueFa := models.UniqueFairwayAvailability{
+			BottleneckId: faRes.Bottleneck_id,
+			Surdat:       faRes.SURDAT,
+		}
+		var found bool
+		if faID, found = fairwayAvailabilities[uniqueFa]; !found {
+			err = insertFAStmt.QueryRowContext(
+				ctx,
+				faRes.POSITION,
+				faRes.Bottleneck_id,
+				faRes.SURDAT,
+				faRes.Critical,
+				faRes.Date_Info,
+				faRes.Source,
+			).Scan(&faID)
+			if err != nil {
+				return nil, err
+			}
+			fairwayAvailabilities[uniqueFa] = faID
+		}
+		feedback.Info("Processing for Bottleneck %s", faRes.Bottleneck_id)
+		faIDs = append(faIDs, faRes.Bottleneck_id)
+		if faRes.Bottleneck_PDFs != nil {
+			bnPdfCount := 0
+			for _, bnPdfs := range faRes.Bottleneck_PDFs.PdfInfo {
+				res, err := insertBnPdfsStmt.ExecContext(
+					ctx,
+					faID,
+					bnPdfs.ProfilePdfFilename,
+					bnPdfs.ProfilePdfURL,
+					bnPdfs.PDF_Generation_Date,
+					bnPdfs.Source,
+				)
+				if err != nil {
+					return nil, err
+				}
+				affected, err := res.RowsAffected()
+				if err == nil {
+					bnPdfCount += int(affected)
+				} else {
+					bnPdfCount++
+				}
+			}
+			feedback.Info("Add %d Pdfs", bnPdfCount)
+		}
+		if faRes.Effective_fairway_availability != nil {
+			efaCount := 0
+			for _, efa := range faRes.Effective_fairway_availability.EffectiveFairwayAvailability {
+				los := efa.Level_of_Service
+				fgt := efa.Forecast_generation_time
+				if efa.Forecast_generation_time.Status == pgtype.Undefined {
+					fgt = pgtype.Timestamp{
+						Status: pgtype.Null,
+					}
+				}
+				res, err := insertEFAStmt.ExecContext(
+					ctx,
+					faID,
+					efa.Measure_date,
+					string(*los),
+					efa.Available_depth_value,
+					efa.Available_width_value,
+					efa.Water_level_value,
+					efa.Measure_type,
+					efa.Source,
+					fgt.Get(),
+					efa.Value_lifetime,
+				)
+				if err != nil {
+					return nil, err
+				}
+				affected, err := res.RowsAffected()
+				if err == nil {
+					efaCount += int(affected)
+				} else {
+					efaCount++
+				}
+			}
+			feedback.Info("Add %d Effective Fairway Availability", efaCount)
+		}
+
+		if faRes.Reference_values != nil {
+			rvCount := 0
+			for _, fav := range faRes.Reference_values.ReferenceValue {
+				res, err := insertFAVStmt.ExecContext(
+					ctx,
+					faID,
+					fav.Level_of_Service,
+					fav.Fairway_depth,
+					fav.Fairway_width,
+					fav.Fairway_radius,
+					fav.Shallowest_spot_Lat,
+					fav.Shallowest_spot_Lon,
+				)
+				if err != nil {
+					return nil, err
+				}
+				affected, err := res.RowsAffected()
+				if err == nil {
+					rvCount += int(affected)
+				} else {
+					rvCount++
+				}
+			}
+			feedback.Info("Add %d Reference Values", rvCount)
+		}
+	}
+	feedback.Info("Storing fairway availabilities took %s", time.Since(start))
+	if err = tx.Commit(); err == nil {
+		feedback.Info("Import of fairway availabilities was successful")
+	}
+
+	return faIDs, nil
+}
--- a/pkg/imports/fwsched.go	Tue Jan 15 09:54:46 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-// This is Free Software under GNU Affero General Public License v >= 3.0
-// without warranty, see README.md and license for details.
-//
-// SPDX-License-Identifier: AGPL-3.0-or-later
-// License-Filename: LICENSES/AGPL-3.0.txt
-//
-// Copyright (C) 2018 by via donau
-//   – Österreichische Wasserstraßen-Gesellschaft mbH
-// Software engineering by Intevation GmbH
-//
-// Author(s):
-//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
-
-package imports
-
-import (
-	"log"
-
-	"gemma.intevation.de/gemma/pkg/scheduler"
-)
-
-func init() {
-	scheduler.RegisterAction("fw", scheduledFW)
-}
-
-func scheduledFW(user string, cfgID *int64) {
-	log.Println("info: scheduled FW import")
-	// TODO: Implement me!
-}
--- a/pkg/imports/gm.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/imports/gm.go	Tue Jan 15 10:07:10 2019 +0100
@@ -10,12 +10,15 @@
 //
 // Author(s):
 //  * Raimund Renkert <raimund.renkert@intevation.de>
+
 package imports
 
 import (
 	"context"
 	"database/sql"
 	"errors"
+	"fmt"
+	"strings"
 	"time"
 
 	"gemma.intevation.de/gemma/pkg/common"
@@ -23,11 +26,17 @@
 	"gemma.intevation.de/gemma/pkg/soap/nts"
 )
 
+// GaugeMeasurement is an import job to import
+// gauges measurement data from a NtS SOAP service.
 type GaugeMeasurement struct {
-	URL      string `json:"url"`
-	Insecure bool   `json:"insecure"`
+	// URL is the URL of the SOAP service.
+	URL string `json:"url"`
+	// Insecure indicates if HTTPS traffic
+	// should validate certificates or not.
+	Insecure bool `json:"insecure"`
 }
 
+// GMJobKind is the import queue type identifier.
 const GMJobKind JobKind = "gm"
 
 const (
@@ -41,23 +50,23 @@
 FROM waterway.gauges
 WHERE (location).country_code = users.current_user_country()`
 
-	hasGaugeMeasurementSQL = `
-SELECT true FROM waterway.gauge_measurements WHERE fk_gauge_id = $1`
-
 	insertGMSQL = `
 INSERT INTO waterway.gauge_measurements (
   fk_gauge_id,
   measure_date,
   sender,
   language_code,
+  country_code,
   date_issue,
+  reference_code,
   water_level,
   predicted,
   is_waterlevel,
   value_min,
   value_max,
   date_info,
-  source_organization
+  source_organization,
+  staging_done
 ) VALUES(
   ($1, $2, $3, $4, $5),
   $6,
@@ -70,7 +79,10 @@
   $13,
   $14,
   $15,
-  $16
+  $16,
+  $17,
+  $18,
+  $19
 )
 RETURNING id`
 )
@@ -81,6 +93,10 @@
 	RegisterJobCreator(GMJobKind, gmJobCreator{})
 }
 
+func (gmJobCreator) Description() string {
+	return "gauge measurements"
+}
+
 func (gmJobCreator) Create(_ JobKind, data string) (Job, error) {
 	gm := new(GaugeMeasurement)
 	if err := common.FromJSONString(data, gm); err != nil {
@@ -91,23 +107,21 @@
 
 func (gmJobCreator) Depends() []string {
 	return []string{
-		"waterway.gauges",
-		"waterway.gauge_measurements",
+		"gauges",
+		"gauge_measurements",
 	}
 }
 
+func (gmJobCreator) AutoAccept() bool { return true }
+
 // StageDone moves the imported gauge measurement out of the staging area.
 // Currently doing nothing.
-func (gmJobCreator) StageDone(
-	ctx context.Context,
-	tx *sql.Tx,
-	id int64,
-) error {
+func (gmJobCreator) StageDone(context.Context, *sql.Tx, int64) error {
 	return nil
 }
 
 // CleanUp of a gauge measurement import is a NOP.
-func (gm *GaugeMeasurement) CleanUp() error { return nil }
+func (*GaugeMeasurement) CleanUp() error { return nil }
 
 // Do executes the actual bottleneck import.
 func (gm *GaugeMeasurement) Do(
@@ -149,7 +163,8 @@
 	// TODO get date_issue for selected gauges
 	gids, err := gm.doForGM(ctx, gauges, conn, feedback)
 	if err != nil {
-		feedback.Error("Error processing %d gauges: %s", len(gauges), err)
+		feedback.Error("Error processing %d gauges: %v", len(gauges), err)
+		return nil, err
 	}
 	if len(gids) == 0 {
 		feedback.Info("No new gauge measurements found")
@@ -164,6 +179,32 @@
 	return &summary, err
 }
 
+// rescale returns a scaling function to bring the unit all to cm.
+func rescale(unit string) (func(float32) float32, error) {
+
+	var scale float32
+
+	switch strings.ToLower(unit) {
+	case "mm":
+		scale = 0.1
+	case "cm":
+		scale = 1.0
+	case "dm":
+		scale = 10.0
+	case "m":
+		scale = 100.0
+	case "hm":
+		scale = 10000.0
+	case "km":
+		scale = 100000.0
+	default:
+		return nil, fmt.Errorf("unknown unit '%s'", unit)
+	}
+
+	fn := func(x float32) float32 { return scale * x }
+	return fn, nil
+}
+
 func (gm *GaugeMeasurement) doForGM(
 	ctx context.Context,
 	gauges []models.GaugeMeasurement,
@@ -225,7 +266,25 @@
 				feedback.Warn("Invalid ISRS code %v", err)
 				continue
 			}
+			var referenceCode string
+			if wrm.Reference_code == nil {
+				feedback.Info("'Reference_code' not specified. Assuming 'ZPG'")
+				referenceCode = "ZPG"
+			} else {
+				referenceCode = string(*wrm.Reference_code)
+			}
 			for _, measure := range wrm.Measure {
+				var unit string
+				if measure.Unit == nil {
+					feedback.Info("'Unit' not specified. Assuming 'cm'")
+					unit = "cm"
+				} else {
+					unit = string(*measure.Unit)
+				}
+				convert, err := rescale(unit)
+				if err != nil {
+					return nil, err
+				}
 				isWaterlevel := *measure.Measure_code == nts.Measure_code_enumWAL
 				err = insertStmt.QueryRowContext(
 					ctx,
@@ -237,14 +296,17 @@
 					measure.Measuredate,
 					msg.Identification.From,
 					msg.Identification.Language_code,
+					msg.Identification.Country_code,
 					msg.Identification.Date_issue,
-					measure.Value,
+					referenceCode,
+					convert(measure.Value),
 					measure.Predicted,
 					isWaterlevel,
-					measure.Value_min,
-					measure.Value_max,
+					convert(measure.Value_min),
+					convert(measure.Value_max),
 					msg.Identification.Date_issue,
 					msg.Identification.Originator,
+					true, // staging_done
 				).Scan(&gid)
 				if err != nil {
 					return nil, err
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/imports/misc.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package imports
+
+import (
+	"fmt"
+	"strings"
+)
+
+type stringCounter map[string]int
+
+func (sc stringCounter) String() string {
+	var b strings.Builder
+	for t, c := range sc {
+		if b.Len() > 0 {
+			b.WriteString(", ")
+		}
+		b.WriteString(fmt.Sprintf("%s: %d", t, c))
+	}
+	return b.String()
+}
--- a/pkg/imports/polygon.go	Tue Jan 15 09:54:46 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-// This is Free Software under GNU Affero General Public License v >= 3.0
-// without warranty, see README.md and license for details.
-//
-// SPDX-License-Identifier: AGPL-3.0-or-later
-// License-Filename: LICENSES/AGPL-3.0.txt
-//
-// Copyright (C) 2018 by via donau
-//   – Österreichische Wasserstraßen-Gesellschaft mbH
-// Software engineering by Intevation GmbH
-//
-// Author(s):
-//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
-
-package imports
-
-import (
-	"bytes"
-	"encoding/binary"
-	"fmt"
-	"math"
-
-	shp "github.com/jonas-p/go-shp"
-)
-
-type (
-	point struct {
-		X float64
-		Y float64
-	}
-	lineString []point
-	polygon    []lineString
-)
-
-const (
-	wkbNDR     byte   = 1
-	wkbPolygon uint32 = 3
-)
-
-func shapeToPolygon(s shp.Shape) (polygon, error) {
-	switch p := s.(type) {
-	case *shp.Polygon:
-		return toPolygon(p.NumParts, p.Parts, p.Points), nil
-	case *shp.PolygonZ:
-		return toPolygon(p.NumParts, p.Parts, p.Points), nil
-	case *shp.PolygonM:
-		return toPolygon(p.NumParts, p.Parts, p.Points), nil
-	}
-	return nil, fmt.Errorf("Unsupported shape type %T", s)
-}
-
-func toPolygon(numParts int32, parts []int32, points []shp.Point) polygon {
-	out := make(polygon, numParts)
-	var pos int32
-
-	for i := range out {
-		var howMany int32
-		if i+1 >= len(parts) {
-			howMany = int32(len(points)) - pos
-		} else {
-			howMany = parts[i+1] - parts[i]
-		}
-
-		line := make(lineString, howMany)
-		for j := int32(0); j < howMany; j, pos = j+1, pos+1 {
-			p := &points[pos]
-			line[j] = point{p.X, p.Y}
-		}
-		out[i] = line
-	}
-	return out
-}
-
-func (p polygon) asWKB() []byte {
-	if p == nil {
-		return nil
-	}
-	// pre-calculate size to avoid reallocations.
-	size := 1 + 4 + 4
-	for _, ring := range p {
-		size += 4 + len(ring)*2*8
-	}
-
-	buf := bytes.NewBuffer(make([]byte, 0, size))
-
-	binary.Write(buf, binary.LittleEndian, wkbNDR)
-	binary.Write(buf, binary.LittleEndian, wkbPolygon)
-	binary.Write(buf, binary.LittleEndian, uint32(len(p)))
-
-	for _, ring := range p {
-		binary.Write(buf, binary.LittleEndian, uint32(len(ring)))
-		for _, v := range ring {
-			binary.Write(buf, binary.LittleEndian, math.Float64bits(v.X))
-			binary.Write(buf, binary.LittleEndian, math.Float64bits(v.Y))
-		}
-	}
-
-	return buf.Bytes()
-}
--- a/pkg/imports/queue.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/imports/queue.go	Tue Jan 15 10:07:10 2019 +0100
@@ -42,6 +42,15 @@
 		Error(fmt string, args ...interface{})
 	}
 
+	// RetryError is an error type to signal that
+	// the import should be tried again.
+	RetryError struct {
+		// Message is the error message.
+		Message string
+		// When is the new scheduled execution time.
+		When time.Time
+	}
+
 	// Job is the central abstraction of an import job
 	// run by the import queue.
 	Job interface {
@@ -66,6 +75,8 @@
 	// JobCreator is used to bring a job to life as it is stored
 	// in pure meta-data form to the database.
 	JobCreator interface {
+		// Description is the long name of the import.
+		Description() string
 		// Create build the actual job.
 		// kind is the name of the import type.
 		// data is a free form string to pass arguments to the creation
@@ -80,15 +91,18 @@
 		// (state = accepted). This can be used to finalize the imported
 		// data to move it e.g from the staging area.
 		StageDone(context.Context, *sql.Tx, int64) error
+		// AutoAccept indicates that imports of this kind
+		// don't need a review.
+		AutoAccept() bool
 	}
 
 	idJob struct {
-		id         int64
-		kind       JobKind
-		user       string
-		sendEmail  bool
-		autoAccept bool
-		data       string
+		id        int64
+		kind      JobKind
+		user      string
+		trysLeft  sql.NullInt64
+		sendEmail bool
+		data      string
 	}
 )
 
@@ -129,33 +143,36 @@
 	insertJobSQL = `
 INSERT INTO waterway.imports (
   kind,
+  due,
+  trys_left,
   username,
   send_email,
-  auto_accept,
   data
 ) VALUES (
   $1,
-  $2,
+  COALESCE($2, CURRENT_TIMESTAMP),
   $3,
   $4,
-  $5
+  $5,
+  $6
 ) RETURNING id`
 
 	selectJobSQL = `
 SELECT
   id,
   kind,
+  trys_left,
   username,
   send_email,
-  auto_accept,
   data
 FROM waterway.imports
-WHERE state = 'queued'::waterway.import_state AND enqueued IN (
-  SELECT min(enqueued)
-  FROM waterway.imports
-  WHERE state = 'queued'::waterway.import_state AND
-  kind = ANY($1)
-)
+WHERE
+  due <= CURRENT_TIMESTAMP + interval '5 seconds' AND
+  state = 'queued'::waterway.import_state AND enqueued IN (
+    SELECT min(enqueued)
+    FROM waterway.imports
+    WHERE state = 'queued'::waterway.import_state AND
+    kind = ANY($1))
 LIMIT 1`
 
 	updateStateSQL = `
@@ -184,6 +201,11 @@
 	go iqueue.importLoop()
 }
 
+// Error makes RetryError an error.
+func (re *RetryError) Error() string {
+	return re.Message
+}
+
 func (q *importQueue) registerJobCreator(kind JobKind, jc JobCreator) {
 	q.creatorsMu.Lock()
 	defer q.creatorsMu.Unlock()
@@ -201,7 +223,7 @@
 	return iqueue.importKindNames()
 }
 
-// HasImportKind checks if the import queue supports a given kind.
+// HasImportKindName checks if the import queue supports a given kind.
 func HasImportKindName(kind string) bool {
 	return iqueue.hasImportKindName(kind)
 }
@@ -234,6 +256,13 @@
 	return names
 }
 
+func (idj *idJob) trys() int {
+	if !idj.trysLeft.Valid {
+		return -1
+	}
+	return int(idj.trysLeft.Int64)
+}
+
 func (q *importQueue) jobCreator(kind JobKind) JobCreator {
 	q.creatorsMu.Lock()
 	defer q.creatorsMu.Unlock()
@@ -242,20 +271,30 @@
 
 func (q *importQueue) addJob(
 	kind JobKind,
+	due time.Time,
+	trysLeft int,
 	user string,
-	sendEmail, autoAccept bool,
+	sendEmail bool,
 	data string,
 ) (int64, error) {
 	ctx := context.Background()
 	var id int64
-	err := auth.RunAs(ctx, queueUser, func(conn *sql.Conn) error {
+	if due.IsZero() {
+		due = time.Now()
+	}
+	var tl sql.NullInt64
+	if trysLeft >= 0 {
+		tl = sql.NullInt64{Int64: int64(trysLeft), Valid: true}
+	}
+	err := auth.RunAs(ctx, user, func(conn *sql.Conn) error {
 		return conn.QueryRowContext(
 			ctx,
 			insertJobSQL,
 			string(kind),
+			due,
+			tl,
 			user,
 			sendEmail,
-			autoAccept,
 			data).Scan(&id)
 	})
 	if err == nil {
@@ -268,10 +307,18 @@
 }
 
 // AddJob adds a job to the global import queue to be executed
-// as soon as possible. This is gone in a separate Go routine
+// as soon as possible after due.
+// This is gone in a separate Go routine
 // so this will not block.
-func AddJob(kind JobKind, user string, sendEmail, autoAccept bool, data string) (int64, error) {
-	return iqueue.addJob(kind, user, sendEmail, autoAccept, data)
+func AddJob(
+	kind JobKind,
+	due time.Time,
+	trysLeft int,
+	user string,
+	sendEmail bool,
+	data string,
+) (int64, error) {
+	return iqueue.addJob(kind, due, trysLeft, user, sendEmail, data)
 }
 
 type logFeedback int64
@@ -284,7 +331,7 @@
 		return err
 	})
 	if err != nil {
-		log.Printf("logging failed: %v\n", err)
+		log.Printf("error: logging failed: %v\n", err)
 	}
 }
 
@@ -355,9 +402,9 @@
 		if err = tx.QueryRowContext(ctx, selectJobSQL, &kinds).Scan(
 			&ji.id,
 			&ji.kind,
+			&ji.trysLeft,
 			&ji.user,
 			&ji.sendEmail,
-			&ji.autoAccept,
 			&ji.data,
 		); err != nil {
 			return err
@@ -425,7 +472,7 @@
 	// re-enqueue the jobs that are in state running.
 	// They where in progess when the server went down.
 	if err := reEnqueueRunning(); err != nil {
-		log.Printf("re-enqueuing failed: %v", err)
+		log.Printf("error: re-enqueuing failed: %v", err)
 	}
 
 	for {
@@ -434,7 +481,7 @@
 
 		for {
 			if idj, err = q.fetchJob(); err != nil && err != sql.ErrNoRows {
-				log.Printf("db error: %v\n", err)
+				log.Printf("error: db: %v\n", err)
 			}
 			if idj != nil {
 				break
@@ -445,7 +492,7 @@
 			}
 		}
 
-		log.Printf("starting import #%d\n", idj.id)
+		log.Printf("info: starting import #%d\n", idj.id)
 
 		jc := q.jobCreator(idj.kind)
 		if jc == nil {
@@ -500,25 +547,52 @@
 			if errDo != nil {
 				feedback.Error("error do: %v", errDo)
 			}
-			errCleanup := survive(job.CleanUp)()
-			if errCleanup != nil {
-				feedback.Error("error cleanup: %v", errCleanup)
+			// Should we try again?
+			retry, shouldRetry := errDo.(*RetryError)
+
+			if shouldRetry && idj.trysLeft.Valid { // NULL -> limit less
+				if idj.trysLeft.Int64--; idj.trysLeft.Int64 <= 0 {
+					shouldRetry = false
+				}
+			}
+
+			var errCleanup error
+			if !shouldRetry { // cleanup debris
+				errCleanup = survive(job.CleanUp)()
+				if errCleanup != nil {
+					feedback.Error("error cleanup: %v", errCleanup)
+				}
 			}
 
 			var state string
 			switch {
 			case errDo != nil || errCleanup != nil:
 				state = "failed"
-			case idj.autoAccept:
+			case jc.AutoAccept():
 				state = "accepted"
 			default:
 				state = "pending"
 			}
 			if err := updateStateSummary(ctx, idj.id, state, summary); err != nil {
-				log.Printf("setting state of job %d failed: %v\n", idj.id, err)
+				log.Printf("error: setting state of job %d failed: %v\n", idj.id, err)
+			}
+			log.Printf("info: import #%d finished: %s\n", idj.id, state)
+			if idj.sendEmail {
+				go sendNotificationMail(idj.user, jc.Description(), state, idj.id)
 			}
-			// TODO: Send email if sendEmail is set.
-			log.Printf("import #%d finished: %s\n", idj.id, state)
+
+			if shouldRetry {
+				nid, err := q.addJob(
+					idj.kind,
+					retry.When, idj.trys(),
+					idj.user, idj.sendEmail,
+					idj.data)
+				if err != nil {
+					log.Printf("error: retry enqueue failed: %v\n", err)
+				} else {
+					log.Printf("info: re-enqueued job with id %d\n", nid)
+				}
+			}
 		}(jc, idj)
 	}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/imports/scheduled.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,167 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package imports
+
+import (
+	"context"
+	"database/sql"
+	"errors"
+	"fmt"
+	"log"
+
+	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/scheduler"
+)
+
+// JobKindSetups maps JobKinds to special setup functions.
+var JobKindSetups = map[JobKind]func(*IDConfig) (interface{}, error){
+
+	GMJobKind: func(cfg *IDConfig) (interface{}, error) {
+		log.Println("info: schedule 'gm' import")
+		insecure := cfg.Attributes.Bool("insecure")
+		return &GaugeMeasurement{
+			URL:      *cfg.URL,
+			Insecure: insecure,
+		}, nil
+	},
+
+	FAJobKind: func(cfg *IDConfig) (interface{}, error) {
+		log.Println("info: schedule 'fa' import")
+		insecure := cfg.Attributes.Bool("insecure")
+		return &FairwayAvailability{
+			URL:      *cfg.URL,
+			Insecure: insecure,
+		}, nil
+	},
+
+	BNJobKind: func(cfg *IDConfig) (interface{}, error) {
+		log.Println("info: schedule 'bn' import")
+		insecure := cfg.Attributes.Bool("insecure")
+		return &Bottleneck{
+			URL:      *cfg.URL,
+			Insecure: insecure,
+		}, nil
+	},
+
+	WXJobKind: func(cfg *IDConfig) (interface{}, error) {
+		log.Println("info: schedule 'wx' import")
+		ft, found := cfg.Attributes.Get("feature-type")
+		if !found {
+			return nil, errors.New("cannot find 'feature-type' attribute")
+		}
+		sb, found := cfg.Attributes.Get("sort-by")
+		if !found {
+			return nil, errors.New("cannot find 'sort-by' attribute")
+		}
+		return &WaterwayAxis{
+			URL:         *cfg.URL,
+			FeatureType: ft,
+			SortBy:      sb,
+		}, nil
+	},
+
+	WAJobKind: func(cfg *IDConfig) (interface{}, error) {
+		log.Println("info: schedule 'wa' import")
+		ft, found := cfg.Attributes.Get("feature-type")
+		if !found {
+			return nil, errors.New("cannot find 'feature-type' attribute")
+		}
+		sb, found := cfg.Attributes.Get("sort-by")
+		if !found {
+			return nil, errors.New("cannot find 'sort-by' attribute")
+		}
+		return &WaterwayArea{
+			URL:         *cfg.URL,
+			FeatureType: ft,
+			SortBy:      sb,
+		}, nil
+	},
+}
+
+func init() {
+	run := func(cfgID int64) {
+		jobID, err := RunConfiguredImport(cfgID)
+		if err != nil {
+			log.Printf("error: running scheduled import failed: %v\n", err)
+			return
+		}
+		log.Printf("info: added import #%d to queue\n", jobID)
+	}
+
+	for kind := range JobKindSetups {
+		scheduler.RegisterAction(string(kind), run)
+	}
+}
+
+// RunConfiguredImportContext runs an import configured from the database.
+func RunConfiguredImportContext(ctx context.Context, conn *sql.Conn, id int64) (int64, error) {
+	cfg, err := LoadIDConfigContext(ctx, conn, id)
+	return runConfiguredImport(id, cfg, err)
+}
+
+// RunConfiguredImport runs an import configured from the database.
+func RunConfiguredImport(id int64) (int64, error) {
+	cfg, err := loadIDConfig(id)
+	return runConfiguredImport(id, cfg, err)
+}
+
+func runConfiguredImport(id int64, cfg *IDConfig, err error) (int64, error) {
+
+	if err != nil {
+		return 0, err
+	}
+	if cfg == nil {
+		return 0, fmt.Errorf("no config found for id %d.\n", id)
+	}
+	if cfg.URL == nil {
+		return 0, errors.New("error: No URL specified")
+	}
+
+	kind := JobKind(cfg.Kind)
+
+	setup := JobKindSetups[kind]
+	if setup == nil {
+		return 0, fmt.Errorf("unknown job kind: %s", cfg.Kind)
+	}
+
+	what, err := setup(cfg)
+	if err != nil {
+		return 0, err
+	}
+
+	var serialized string
+	if serialized, err = common.ToJSONString(what); err != nil {
+		return 0, err
+	}
+
+	due, _ := cfg.Attributes.Time("due")
+
+	retries, found := cfg.Attributes.Int("retries")
+	if !found {
+		retries = -1
+	}
+
+	var jobID int64
+	if jobID, err = AddJob(
+		kind,
+		due, retries,
+		cfg.User,
+		cfg.SendEMail,
+		serialized,
+	); err != nil {
+		return 0, err
+	}
+
+	return jobID, nil
+}
--- a/pkg/imports/sr.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/imports/sr.go	Tue Jan 15 10:07:10 2019 +0100
@@ -73,6 +73,10 @@
 	RegisterJobCreator(SRJobKind, srJobCreator{})
 }
 
+func (srJobCreator) Description() string { return "sounding results" }
+
+func (srJobCreator) AutoAccept() bool { return false }
+
 func (srJobCreator) Create(_ JobKind, data string) (Job, error) {
 	sr := new(SoundingResult)
 	if err := common.FromJSONString(data, sr); err != nil {
@@ -83,9 +87,9 @@
 
 func (srJobCreator) Depends() []string {
 	return []string{
-		"waterway.sounding_results",
-		"waterway.sounding_results_contour_lines",
-		"waterway.bottlenecks",
+		"sounding_results",
+		"sounding_results_contour_lines",
+		"bottlenecks",
 	}
 }
 
@@ -424,7 +428,7 @@
 	return loadXYZReader(r, feedback)
 }
 
-func loadBoundary(z *zip.ReadCloser) (polygon, error) {
+func loadBoundary(z *zip.ReadCloser) (polygonSlice, error) {
 	shpF := common.FindInZIP(z, ".shp")
 	if shpF == nil {
 		return nil, nil
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/imports/wa.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,282 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package imports
+
+import (
+	"context"
+	"database/sql"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"strconv"
+	"time"
+
+	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/wfs"
+)
+
+// WaterwayArea is an import job to import
+// the waterway area in form of polygon geometries
+// and attribute data from a WFS service.
+type WaterwayArea struct {
+	// URL the GetCapabilities URL of the WFS service.
+	URL string `json:"url"`
+	// FeatureType selects the feature type of the WFS service.
+	FeatureType string `json:"feature-type"`
+	// SortBy works around misconfigured services to
+	// establish a sort order to get the features.
+	SortBy string `json:"sort-by"`
+}
+
+// WAJobKind is the import queue type identifier.
+const WAJobKind JobKind = "wa"
+
+type waJobCreator struct{}
+
+func init() {
+	RegisterJobCreator(WAJobKind, waJobCreator{})
+}
+
+func (waJobCreator) Description() string { return "waterway area" }
+
+func (waJobCreator) AutoAccept() bool { return true }
+
+func (waJobCreator) Create(_ JobKind, data string) (Job, error) {
+	wa := new(WaterwayArea)
+	if err := common.FromJSONString(data, wa); err != nil {
+		return nil, err
+	}
+	return wa, nil
+}
+
+func (waJobCreator) Depends() []string {
+	return []string{
+		"waterway_area",
+	}
+}
+
+// StageDone is a NOP for waterway area imports.
+func (waJobCreator) StageDone(context.Context, *sql.Tx, int64) error {
+	return nil
+}
+
+// CleanUp for waterway area imports is a NOP.
+func (*WaterwayArea) CleanUp() error { return nil }
+
+type waterwayAreaProperties struct {
+	Catccl *string `json:"ienc_catccl"`
+	Dirimp *string `json:"ienc_dirimp"`
+}
+
+const (
+	deleteWaterwayAreaSQL = `
+WITH resp AS (
+  SELECT best_utm(area::geometry) AS t,
+         ST_Transform(area::geometry, best_utm(area::geometry)) AS a
+  FROM users.responsibility_areas
+  WHERE country = users.current_user_country()
+)
+DELETE FROM waterway.waterway_area
+WHERE ST_Covers(
+  (SELECT a FROM resp),
+  ST_Transform(area::geometry, (SELECT t FROM resp)))
+`
+	insertWaterwayAreaSQL = `
+WITH resp AS (
+  SELECT best_utm(area::geometry) AS t,
+         ST_Transform(area::geometry, best_utm(area::geometry)) AS a
+  FROM users.responsibility_areas
+  WHERE country = users.current_user_country()
+)
+INSERT INTO waterway.waterway_area (area, catccl, dirimp)
+SELECT ST_Transform(clipped.geom, 4326)::geography, $3, $4 FROM (
+    SELECT (ST_Dump(
+       ST_Intersection(
+         (SELECT a FROM resp),
+         ST_Transform(
+           ST_GeomFromWKB($1, $2::integer),
+           (SELECT t FROM resp)
+         )
+       )
+     )).geom AS geom
+  ) AS clipped
+  WHERE clipped.geom IS NOT NULL
+`
+)
+
+// Do executes the actual waterway axis import.
+func (wx *WaterwayArea) Do(
+	ctx context.Context,
+	importID int64,
+	conn *sql.Conn,
+	feedback Feedback,
+) (interface{}, error) {
+
+	start := time.Now()
+
+	feedback.Info("Import waterway area")
+
+	feedback.Info("Loading capabilities from %s", wx.URL)
+	caps, err := wfs.GetCapabilities(wx.URL)
+	if err != nil {
+		feedback.Error("Loading capabilities failed: %v", err)
+		return nil, err
+	}
+
+	ft := caps.FindFeatureType(wx.FeatureType)
+	if ft == nil {
+		return nil, fmt.Errorf("Unknown feature type '%s'", wx.FeatureType)
+	}
+
+	feedback.Info("Found feature type '%s", wx.FeatureType)
+
+	epsg, err := wfs.CRSToEPSG(ft.DefaultCRS)
+	if err != nil {
+		feedback.Error("Unsupported CRS name '%s'", ft.DefaultCRS)
+		return nil, err
+	}
+
+	if wx.SortBy != "" {
+		feedback.Info("Features will be sorted by '%s'", wx.SortBy)
+	}
+
+	urls, err := wfs.GetFeaturesGET(
+		caps, wx.FeatureType, "application/json", wx.SortBy)
+	if err != nil {
+		feedback.Error("Cannot create GetFeature URLs. %v", err)
+		return nil, err
+	}
+
+	tx, err := conn.BeginTx(ctx, nil)
+	if err != nil {
+		return nil, err
+	}
+	defer tx.Rollback()
+
+	insertStmt, err := tx.PrepareContext(ctx, insertWaterwayAreaSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer insertStmt.Close()
+
+	// Delete the old features.
+	if _, err := tx.ExecContext(ctx, deleteWaterwayAreaSQL); err != nil {
+		return nil, err
+	}
+
+	var (
+		unsupported       = stringCounter{}
+		missingProperties int
+		badProperties     int
+		features          int
+	)
+
+	if err := wfs.DownloadURLs(urls, func(r io.Reader) error {
+		rfc, err := wfs.ParseRawFeatureCollection(r)
+		if err != nil {
+			return fmt.Errorf("parsing GetFeature document failed: %v", err)
+		}
+		if rfc.CRS != nil {
+			crsName := rfc.CRS.Properties.Name
+			if epsg, err = wfs.CRSToEPSG(crsName); err != nil {
+				feedback.Error("Unsupported CRS: %d", crsName)
+				return err
+			}
+		}
+
+		// No features -> ignore.
+		if rfc.Features == nil {
+			return nil
+		}
+
+		feedback.Info("Using EPSG: %d", epsg)
+
+		for _, feature := range rfc.Features {
+			if feature.Properties == nil || feature.Geometry.Coordinates == nil {
+				missingProperties++
+				continue
+			}
+
+			var props waterwayAreaProperties
+
+			if err := json.Unmarshal(*feature.Properties, &props); err != nil {
+				badProperties++
+				continue
+			}
+
+			var catccl sql.NullInt64
+			if props.Catccl != nil {
+				if value, err := strconv.ParseInt(*props.Catccl, 10, 64); err == nil {
+					catccl = sql.NullInt64{Int64: value, Valid: true}
+				}
+			}
+			var dirimp sql.NullInt64
+			if props.Dirimp != nil {
+				if value, err := strconv.ParseInt(*props.Dirimp, 10, 64); err == nil {
+					dirimp = sql.NullInt64{Int64: value, Valid: true}
+				}
+			}
+
+			switch feature.Geometry.Type {
+			case "Polygon":
+				var p polygonSlice
+				if err := json.Unmarshal(*feature.Geometry.Coordinates, &p); err != nil {
+					return err
+				}
+				if _, err := insertStmt.ExecContext(
+					ctx,
+					p.asWKB(),
+					epsg,
+					catccl,
+					dirimp,
+				); err != nil {
+					return err
+				}
+				features++
+			default:
+				unsupported[feature.Geometry.Type]++
+			}
+		}
+		return nil
+	}); err != nil {
+		feedback.Error("Downloading features failed: %v", err)
+		return nil, err
+	}
+
+	if features == 0 {
+		err := errors.New("No features found")
+		feedback.Error("%v", err)
+		return nil, err
+	}
+
+	if badProperties > 0 {
+		feedback.Warn("Bad properties: %d", badProperties)
+	}
+
+	if missingProperties > 0 {
+		feedback.Warn("Missing properties: %d", missingProperties)
+	}
+
+	if len(unsupported) != 0 {
+		feedback.Warn("Unsupported types found: %s", unsupported)
+	}
+
+	if err = tx.Commit(); err == nil {
+		feedback.Info("Storing %d features took %s",
+			features, time.Since(start))
+	}
+
+	return nil, err
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/imports/wkb.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,131 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package imports
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"math"
+
+	shp "github.com/jonas-p/go-shp"
+)
+
+type (
+	lineSlice    [][]float64
+	polygonSlice [][][]float64
+)
+
+const (
+	wkbNDR byte = 1
+
+	wkbLineString uint32 = 2
+	wkbPolygon    uint32 = 3
+)
+
+func (l lineSlice) asWKB() []byte {
+
+	size := 1 + 4 + 4 + len(l)*(2*8)
+
+	buf := bytes.NewBuffer(make([]byte, 0, size))
+
+	binary.Write(buf, binary.LittleEndian, wkbNDR)
+	binary.Write(buf, binary.LittleEndian, wkbLineString)
+	binary.Write(buf, binary.LittleEndian, uint32(len(l)))
+
+	for _, c := range l {
+		var lat, lon float64
+		if len(c) > 0 {
+			lat = c[0]
+		}
+		if len(c) > 1 {
+			lon = c[1]
+		}
+		binary.Write(buf, binary.LittleEndian, math.Float64bits(lat))
+		binary.Write(buf, binary.LittleEndian, math.Float64bits(lon))
+	}
+
+	return buf.Bytes()
+}
+
+func (p polygonSlice) asWKB() []byte {
+	if p == nil {
+		return nil
+	}
+	// pre-calculate size to avoid reallocations.
+	size := 1 + 4 + 4
+	for _, ring := range p {
+		size += 4 + len(ring)*2*8
+	}
+
+	buf := bytes.NewBuffer(make([]byte, 0, size))
+
+	binary.Write(buf, binary.LittleEndian, wkbNDR)
+	binary.Write(buf, binary.LittleEndian, wkbPolygon)
+	binary.Write(buf, binary.LittleEndian, uint32(len(p)))
+
+	for _, ring := range p {
+		binary.Write(buf, binary.LittleEndian, uint32(len(ring)))
+		for _, v := range ring {
+			var lat, lon float64
+			if len(v) > 0 {
+				lat = v[0]
+			}
+			if len(v) > 1 {
+				lon = v[1]
+			}
+			binary.Write(buf, binary.LittleEndian, math.Float64bits(lat))
+			binary.Write(buf, binary.LittleEndian, math.Float64bits(lon))
+		}
+	}
+
+	return buf.Bytes()
+}
+
+func shapeToPolygon(s shp.Shape) (polygonSlice, error) {
+	switch p := s.(type) {
+	case *shp.Polygon:
+		return toPolygon(p.NumParts, p.Parts, p.Points), nil
+	case *shp.PolygonZ:
+		return toPolygon(p.NumParts, p.Parts, p.Points), nil
+	case *shp.PolygonM:
+		return toPolygon(p.NumParts, p.Parts, p.Points), nil
+	}
+	return nil, fmt.Errorf("Unsupported shape type %T", s)
+}
+
+func toPolygon(numParts int32, parts []int32, points []shp.Point) polygonSlice {
+	out := make(polygonSlice, numParts)
+	var pos int32
+
+	for i := range out {
+		var howMany int32
+		if i+1 >= len(parts) {
+			howMany = int32(len(points)) - pos
+		} else {
+			howMany = parts[i+1] - parts[i]
+		}
+
+		line := make([][]float64, howMany)
+		vertices := make([]float64, 2*howMany)
+		for j := int32(0); j < howMany; j, pos = j+1, pos+1 {
+			p := &points[pos]
+			vertex := vertices[j*2 : j*2+2]
+			vertex[0], vertex[1] = p.X, p.Y
+			line[j] = vertex
+		}
+		out[i] = line
+	}
+	return out
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/imports/wx.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,291 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package imports
+
+import (
+	"context"
+	"database/sql"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"time"
+
+	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/wfs"
+)
+
+// WaterwayAxis is an import job to import
+// the waterway axes in form of line string geometries
+// and attribute data from a WFS service.
+type WaterwayAxis struct {
+	// URL the GetCapabilities URL of the WFS service.
+	URL string `json:"url"`
+	// FeatureType selects the feature type of the WFS service.
+	FeatureType string `json:"feature-type"`
+	// SortBy works around misconfigured services to
+	// establish a sort order to get the features.
+	SortBy string `json:"sort-by"`
+}
+
+// WXJobKind is the import queue type identifier.
+const WXJobKind JobKind = "wx"
+
+type wxJobCreator struct{}
+
+func init() {
+	RegisterJobCreator(WXJobKind, wxJobCreator{})
+}
+
+func (wxJobCreator) Description() string { return "waterway axis" }
+
+func (wxJobCreator) AutoAccept() bool { return true }
+
+func (wxJobCreator) Create(_ JobKind, data string) (Job, error) {
+	wx := new(WaterwayAxis)
+	if err := common.FromJSONString(data, wx); err != nil {
+		return nil, err
+	}
+	return wx, nil
+}
+
+func (wxJobCreator) Depends() []string {
+	return []string{
+		"waterway_axis",
+	}
+}
+
+// StageDone is a NOP for waterway axis imports.
+func (wxJobCreator) StageDone(context.Context, *sql.Tx, int64) error {
+	return nil
+}
+
+// CleanUp for waterway axis imports is a NOP.
+func (*WaterwayAxis) CleanUp() error { return nil }
+
+type waterwayAxisProperties struct {
+	ObjNam  string  `json:"hydro_objnam"`
+	NObjNnm *string `json:"hydro_nobjnm"`
+}
+
+const (
+	deleteWaterwayAxisSQL = `
+WITH resp AS (
+  SELECT best_utm(area::geometry) AS t,
+         ST_Transform(area::geometry, best_utm(area::geometry)) AS a
+  FROM users.responsibility_areas
+  WHERE country = users.current_user_country()
+)
+DELETE FROM waterway.waterway_axis
+WHERE ST_Covers(
+  (SELECT a FROM resp),
+  ST_Transform(wtwaxs::geometry, (SELECT t FROM resp)))
+`
+
+	insertWaterwayAxisSQL = `
+WITH resp AS (
+  SELECT best_utm(area::geometry) AS t,
+         ST_Transform(area::geometry, best_utm(area::geometry)) AS a
+  FROM users.responsibility_areas
+  WHERE country = users.current_user_country()
+)
+INSERT INTO waterway.waterway_axis (wtwaxs, objnam, nobjnam)
+SELECT ST_Transform(clipped.geom, 4326)::geography, $3, $4 FROM (
+    SELECT (ST_Dump(
+       ST_Intersection(
+         (SELECT a FROM resp),
+         ST_Transform(
+           ST_GeomFromWKB($1, $2::integer),
+           (SELECT t FROM resp)
+         )
+       )
+     )).geom AS geom
+  ) AS clipped
+  WHERE clipped.geom IS NOT NULL
+`
+)
+
+// Do executes the actual waterway axis import.
+func (wx *WaterwayAxis) Do(
+	ctx context.Context,
+	importID int64,
+	conn *sql.Conn,
+	feedback Feedback,
+) (interface{}, error) {
+
+	start := time.Now()
+
+	feedback.Info("Import waterway axis")
+
+	feedback.Info("Loading capabilities from %s", wx.URL)
+	caps, err := wfs.GetCapabilities(wx.URL)
+	if err != nil {
+		feedback.Error("Loading capabilities failed: %v", err)
+		return nil, err
+	}
+
+	ft := caps.FindFeatureType(wx.FeatureType)
+	if ft == nil {
+		return nil, fmt.Errorf("Unknown feature type '%s'", wx.FeatureType)
+	}
+
+	feedback.Info("Found feature type '%s", wx.FeatureType)
+
+	epsg, err := wfs.CRSToEPSG(ft.DefaultCRS)
+	if err != nil {
+		feedback.Error("Unsupported CRS name '%s'", ft.DefaultCRS)
+		return nil, err
+	}
+
+	if wx.SortBy != "" {
+		feedback.Info("Features will be sorted by '%s'", wx.SortBy)
+	}
+
+	urls, err := wfs.GetFeaturesGET(
+		caps, wx.FeatureType, "application/json", wx.SortBy)
+	if err != nil {
+		feedback.Error("Cannot create GetFeature URLs. %v", err)
+		return nil, err
+	}
+
+	tx, err := conn.BeginTx(ctx, nil)
+	if err != nil {
+		return nil, err
+	}
+	defer tx.Rollback()
+
+	insertStmt, err := tx.PrepareContext(ctx, insertWaterwayAxisSQL)
+	if err != nil {
+		return nil, err
+	}
+	defer insertStmt.Close()
+
+	// Delete the old features.
+	if _, err := tx.ExecContext(ctx, deleteWaterwayAxisSQL); err != nil {
+		return nil, err
+	}
+
+	var (
+		unsupported       = stringCounter{}
+		missingProperties int
+		badProperties     int
+		features          int
+	)
+
+	if err := wfs.DownloadURLs(urls, func(r io.Reader) error {
+		rfc, err := wfs.ParseRawFeatureCollection(r)
+		if err != nil {
+			return fmt.Errorf("parsing GetFeature document failed: %v", err)
+		}
+		if rfc.CRS != nil {
+			crsName := rfc.CRS.Properties.Name
+			if epsg, err = wfs.CRSToEPSG(crsName); err != nil {
+				feedback.Error("Unsupported CRS: %d", crsName)
+				return err
+			}
+		}
+
+		// No features -> ignore.
+		if rfc.Features == nil {
+			return nil
+		}
+
+		feedback.Info("Using EPSG: %d", epsg)
+
+		for _, feature := range rfc.Features {
+			if feature.Properties == nil || feature.Geometry.Coordinates == nil {
+				missingProperties++
+				continue
+			}
+
+			var props waterwayAxisProperties
+
+			if err := json.Unmarshal(*feature.Properties, &props); err != nil {
+				badProperties++
+				continue
+			}
+
+			var nobjnam sql.NullString
+			if props.NObjNnm != nil {
+				nobjnam = sql.NullString{String: *props.NObjNnm, Valid: true}
+			}
+
+			switch feature.Geometry.Type {
+			case "LineString":
+				var l lineSlice
+				if err := json.Unmarshal(*feature.Geometry.Coordinates, &l); err != nil {
+					return err
+				}
+				if _, err := insertStmt.ExecContext(
+					ctx,
+					l.asWKB(),
+					epsg,
+					props.ObjNam,
+					nobjnam,
+				); err != nil {
+					return err
+				}
+				features++
+			case "MultiLineString":
+				var ls []lineSlice
+				if err := json.Unmarshal(*feature.Geometry.Coordinates, &ls); err != nil {
+					return err
+				}
+				for _, l := range ls {
+					if _, err := insertStmt.ExecContext(
+						ctx,
+						l.asWKB(),
+						epsg,
+						props.ObjNam,
+						nobjnam,
+					); err != nil {
+						return err
+					}
+					features++
+				}
+			default:
+				unsupported[feature.Geometry.Type]++
+			}
+		}
+		return nil
+	}); err != nil {
+		feedback.Error("Downloading features failed: %v", err)
+		return nil, err
+	}
+
+	if features == 0 {
+		err := errors.New("No features found")
+		feedback.Error("%v", err)
+		return nil, err
+	}
+
+	if badProperties > 0 {
+		feedback.Warn("Bad properties: %d", badProperties)
+	}
+
+	if missingProperties > 0 {
+		feedback.Warn("Missing properties: %d", missingProperties)
+	}
+
+	if len(unsupported) != 0 {
+		feedback.Warn("Unsupported types found: %s", unsupported)
+	}
+
+	if err = tx.Commit(); err == nil {
+		feedback.Info("Storing %d features took %s",
+			features, time.Since(start))
+	}
+
+	return nil, err
+}
--- a/pkg/models/bn.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/models/bn.go	Tue Jan 15 10:07:10 2019 +0100
@@ -13,7 +13,16 @@
 
 package models
 
+import "gemma.intevation.de/gemma/pkg/common"
+
 type BottleneckImport struct {
-	URL      string `json:"url"`
-	Insecure bool   `json:"insecure"`
+	URL        string            `json:"url"`
+	Insecure   bool              `json:"insecure"`
+	SendEmail  bool              `json:"send-email"`
+	Attributes common.Attributes `json:"attributes,omitempty"`
 }
+
+type Bottleneck struct {
+	ID                 string
+	ResponsibleCountry string
+}
--- a/pkg/models/cross.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/models/cross.go	Tue Jan 15 10:07:10 2019 +0100
@@ -155,7 +155,7 @@
 
 func (lc GeoJSONLineCoordinates) AsWKB() []byte {
 
-	size := 1 + 4 + 4 + len(lc)*(1+4+2*8)
+	size := 1 + 4 + 4 + len(lc)*(2*8)
 
 	buf := bytes.NewBuffer(make([]byte, 0, size))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/models/fa.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,34 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Raimund Renkert <raimund.renkert@intevation.de>
+
+package models
+
+import (
+	"time"
+
+	"gemma.intevation.de/gemma/pkg/common"
+)
+
+// FairwayAvailabilityImport contains data used to define the endpoint
+type FairwayAvailabilityImport struct {
+	URL       string `json:"url"`
+	Insecure  bool   `json:"insecure"`
+	SendEmail bool   `json:"send-email"`
+	// Attributes are optional attributes.
+	Attributes common.Attributes `json:"attributes,omitempty"`
+}
+
+type UniqueFairwayAvailability struct {
+	BottleneckId string
+	Surdat       time.Time
+}
--- a/pkg/models/gauge.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/models/gauge.go	Tue Jan 15 10:07:10 2019 +0100
@@ -18,12 +18,17 @@
 	"fmt"
 	"strconv"
 	"time"
+
+	"gemma.intevation.de/gemma/pkg/common"
 )
 
 // GaugeMeasurementImport contains data used to define the endpoint
 type GaugeMeasurementImport struct {
-	URL      string `json:"url"`
-	Insecure bool   `json:"insecure"`
+	URL       string `json:"url"`
+	Insecure  bool   `json:"insecure"`
+	SendEmail bool   `json:"send-email"`
+	// Attributes are optional attributes.
+	Attributes common.Attributes `json:"attributes,omitempty"`
 }
 
 // GaugeMeasurement holds information about a gauge and the latest measurement
--- a/pkg/models/user.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/models/user.go	Tue Jan 15 10:07:10 2019 +0100
@@ -23,11 +23,17 @@
 )
 
 type (
-	Email    string
-	Country  string
-	Role     string
+	// Email is a string formed by a valid EMail address.
+	Email string
+	// Country is a valid country 2 letter code.
+	Country string
+	// Role is a string with a valid gemma role.
+	Role string
+	// UserName is a string forming a valid user name.
 	UserName string
 
+	// BoundingBox is a spatial bounding box of user's
+	// responsibility area.
 	BoundingBox struct {
 		X1 float64 `json:"x1"`
 		Y1 float64 `json:"y1"`
@@ -35,6 +41,7 @@
 		Y2 float64 `json:"y2"`
 	}
 
+	// User is a serialized JSON form of user data.
 	User struct {
 		User     UserName     `json:"user"`
 		Role     Role         `json:"role"`
@@ -44,6 +51,7 @@
 		Extent   *BoundingBox `json:"extent"`
 	}
 
+	// PWResetUser is send to request a password reset for a user.
 	PWResetUser struct {
 		User string `json:"user"`
 	}
@@ -65,6 +73,7 @@
 	errNoEmailAddress = errors.New("Not a valid email address")
 )
 
+// UnmarshalJSON ensures that the given string forms a valid email address.
 func (e *Email) UnmarshalJSON(data []byte) error {
 	var s string
 	if err := json.Unmarshal(data, &s); err != nil {
@@ -77,10 +86,12 @@
 	return nil
 }
 
+// Value implements the driver.Valuer interface.
 func (e Email) Value() (driver.Value, error) {
 	return string(e), nil
 }
 
+// Scan implements the sql.Scanner interface.
 func (e *Email) Scan(src interface{}) (err error) {
 	if s, ok := src.(string); ok {
 		*e = Email(s)
@@ -92,10 +103,12 @@
 
 var errNoValidUser = errors.New("Not a valid user")
 
+// IsValid checks if a given user name is valid.
 func (u UserName) IsValid() bool {
 	return u != ""
 }
 
+// UnmarshalJSON ensures that the given string forms a valid user name.
 func (u *UserName) UnmarshalJSON(data []byte) error {
 	var s string
 	if err := json.Unmarshal(data, &s); err != nil {
@@ -108,6 +121,7 @@
 	return errNoValidUser
 }
 
+// Scan implements the sql.Scanner interface.
 func (u *UserName) Scan(src interface{}) (err error) {
 	if s, ok := src.(string); ok {
 		*u = UserName(s)
@@ -125,6 +139,8 @@
 	errNoValidCountry = errors.New("Not a valid country")
 )
 
+// UnmarshalJSON ensures that the given string forms a valid
+// two letter country code.
 func (c *Country) UnmarshalJSON(data []byte) error {
 	var s string
 	if err := json.Unmarshal(data, &s); err != nil {
@@ -140,10 +156,12 @@
 	return errNoValidCountry
 }
 
+// Value implements the driver.Valuer interface.
 func (c Country) Value() (driver.Value, error) {
 	return string(c), nil
 }
 
+// Scan implements the sql.Scanner interfaces.
 func (c *Country) Scan(src interface{}) (err error) {
 	if s, ok := src.(string); ok {
 		*c = Country(s)
@@ -162,10 +180,12 @@
 	errNoValidRole = errors.New("Not a valid role")
 )
 
+// Value implements the driver.Valuer interface.
 func (r Role) Value() (driver.Value, error) {
 	return string(r), nil
 }
 
+// Scan implements the sql.Scanner interface.
 func (r *Role) Scan(src interface{}) (err error) {
 	if s, ok := src.(string); ok {
 		*r = Role(s)
@@ -175,6 +195,7 @@
 	return
 }
 
+// UnmarshalJSON ensure that the given string is a valid user name.
 func (r *Role) UnmarshalJSON(data []byte) error {
 	var s string
 	if err := json.Unmarshal(data, &s); err != nil {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/models/waterway.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,48 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package models
+
+import "gemma.intevation.de/gemma/pkg/common"
+
+type (
+	// WaterwayAxisImport specifies an import of the waterway axis.
+	WaterwayAxisImport struct {
+		// URL is the capabilities URL of the WFS.
+		URL string `json:"url"`
+		// FeatureType is the layer to use.
+		FeatureType string `json:"feature-type"`
+		// SortBy sorts the feature by this key.
+		SortBy string `json:"sort-by"`
+		// SendEmail is set to true if an email should be send after
+		// importing the axis.
+		SendEmail bool `json:"send-email"`
+		// Attributes are optional attributes.
+		Attributes common.Attributes `json:"attributes,omitempty"`
+	}
+
+	// WaterwayAreaImport specifies an import of the waterway area.
+	WaterwayAreaImport struct {
+		// URL is the capabilities URL of the WFS.
+		URL string `json:"url"`
+		// FeatureType is the layer to use.
+		FeatureType string `json:"feature-type"`
+		// SortBy sorts the feature by this key.
+		SortBy string `json:"sort-by"`
+		// SendEmail is set to true if an email should be send after
+		// importing the axis.
+		SendEmail bool `json:"send-email"`
+		// Attributes are optional attributes.
+		Attributes common.Attributes `json:"attributes,omitempty"`
+	}
+)
--- a/pkg/octree/builder.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/octree/builder.go	Tue Jan 15 10:07:10 2019 +0100
@@ -22,6 +22,7 @@
 	"github.com/golang/snappy"
 )
 
+// Builder is used to turn a TIN into an Octree.
 type Builder struct {
 	t      *Tin
 	nodes  int
@@ -57,10 +58,12 @@
 	}
 }
 
+// NewBuilder creates a new Builder for a TIN.
 func NewBuilder(t *Tin) *Builder {
 	return &Builder{t: t}
 }
 
+// Build builds the Octree.
 func (tb *Builder) Build() {
 
 	triangles := make([]int32, len(tb.t.Triangles))
@@ -72,9 +75,9 @@
 
 	tb.buildRecursive(triangles, tb.t.Min, tb.t.Max, 0)
 	tb.index[0] = int32(len(tb.index))
-	log.Printf("num nodes: %d\n", tb.index[0])
+	log.Printf("info: num nodes: %d\n", tb.index[0])
 
-	log.Printf("nodes: %d leaves: %d index %d\n",
+	log.Printf("info: nodes: %d leaves: %d index %d\n",
 		tb.nodes, tb.leaves, tb.index[0])
 }
 
@@ -144,7 +147,7 @@
 	return int32(pos)
 }
 
-func (tb *Builder) Serialize(w io.Writer) error {
+func (tb *Builder) serialize(w io.Writer) error {
 	var buf [binary.MaxVarintLen32]byte
 
 	if err := binary.Write(w, binary.LittleEndian, tb.index[0]); err != nil {
@@ -167,7 +170,7 @@
 
 		last = x
 	}
-	log.Printf("compressed octree index in bytes: %d (%d)\n",
+	log.Printf("info: compressed octree index in bytes: %d (%d)\n",
 		written, 4*len(tb.index))
 
 	return nil
@@ -175,15 +178,16 @@
 
 func (tb *Builder) writeTo(w io.Writer) error {
 	out := snappy.NewBufferedWriter(w)
-	if err := tb.t.Serialize(out); err != nil {
+	if err := tb.t.serialize(out); err != nil {
 		return err
 	}
-	if err := tb.Serialize(out); err != nil {
+	if err := tb.serialize(out); err != nil {
 		return err
 	}
 	return out.Flush()
 }
 
+// Bytes serializes an Octree into a byte slice.
 func (tb *Builder) Bytes() ([]byte, error) {
 	var buf bytes.Buffer
 	if err := tb.writeTo(&buf); err != nil {
@@ -192,6 +196,7 @@
 	return buf.Bytes(), nil
 }
 
+// Tree returns an Octree from the Builder.
 func (tb *Builder) Tree() *Tree {
 	return &Tree{
 		EPSG:      tb.t.EPSG,
--- a/pkg/octree/cache.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/octree/cache.go	Tue Jan 15 10:07:10 2019 +0100
@@ -31,6 +31,9 @@
 		tree     *Tree
 		access   time.Time
 	}
+
+	// Cache holds Octrees for a defined amount of time in memory
+	// before they are released.
 	Cache struct {
 		sync.Mutex
 		entries map[cacheKey]*cacheEntry
@@ -87,6 +90,7 @@
 	}
 }
 
+// FromCache fetches an Octree from the global Octree cache.
 func FromCache(
 	ctx context.Context,
 	conn *sql.Conn,
@@ -135,7 +139,7 @@
 		}
 	}
 
-	tree, err := Deserialize(data)
+	tree, err := deserialize(data)
 	if err != nil {
 		return nil, err
 	}
--- a/pkg/octree/contours.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/octree/contours.go	Tue Jan 15 10:07:10 2019 +0100
@@ -19,6 +19,8 @@
 	"sync"
 )
 
+// ContourResult stores an calculated iso line for a given height.
+// Is used as a future variable in the concurrent iso line calculation.
 type ContourResult struct {
 	Height float64
 	Lines  MultiLineStringZ
@@ -28,6 +30,8 @@
 	cond *sync.Cond
 }
 
+// NewContourResult prepares a future variable to later hold
+// the result of the iso line calculation.
 func NewContourResult(height float64) *ContourResult {
 	cr := ContourResult{Height: height}
 	cr.cond = sync.NewCond(&cr.mu)
@@ -56,6 +60,10 @@
 	cr.cond.Signal()
 }
 
+// DoContours calculates the iso line for the given heights.
+// This is done concurrently.
+// It is guaranteed that the results are given to the store
+// function in order of the original heights values.
 func DoContours(tree *Tree, heights []float64, store func(*ContourResult)) {
 
 	contours := make([]*ContourResult, len(heights))
--- a/pkg/octree/loader.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/octree/loader.go	Tue Jan 15 10:07:10 2019 +0100
@@ -18,7 +18,6 @@
 	"bytes"
 	"encoding/binary"
 	"log"
-	"os"
 
 	"github.com/golang/snappy"
 )
@@ -30,7 +29,7 @@
 		return nil, err
 	}
 
-	log.Printf("EPSG: %d\n", tree.EPSG)
+	log.Printf("info: EPSG: %d\n", tree.EPSG)
 
 	if err := tree.Min.Read(r); err != nil {
 		return nil, err
@@ -40,7 +39,7 @@
 		return nil, err
 	}
 
-	log.Printf("BBOX: [[%f, %f, %f], [%f, %f, %f]]\n",
+	log.Printf("info: BBOX: [[%f, %f, %f], [%f, %f, %f]]\n",
 		tree.Min.X, tree.Min.Y, tree.Min.Z,
 		tree.Max.X, tree.Max.Y, tree.Max.Z)
 
@@ -49,7 +48,7 @@
 		return nil, err
 	}
 
-	log.Printf("vertices: %d\n", numVertices)
+	log.Printf("info: vertices: %d\n", numVertices)
 
 	vertices := make([]Vertex, numVertices)
 	tree.vertices = vertices
@@ -65,7 +64,7 @@
 		return nil, err
 	}
 
-	log.Printf("triangles: %d\n", numTriangles)
+	log.Printf("info: triangles: %d\n", numTriangles)
 
 	indices := make([]int32, 3*numTriangles)
 	triangles := make([][]int32, numTriangles)
@@ -93,7 +92,7 @@
 		return nil, err
 	}
 
-	log.Printf("num nodes: %d\n", numNodes)
+	log.Printf("info: num nodes: %d\n", numNodes)
 
 	tree.index = make([]int32, numNodes)
 	entries := tree.index[1:]
@@ -112,19 +111,7 @@
 	return tree, nil
 }
 
-func LoadTree(fname string) (*Tree, error) {
-
-	f, err := os.Open(fname)
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-	return loadReader(
-		bufio.NewReader(
-			snappy.NewReader(f)))
-}
-
-func Deserialize(data []byte) (*Tree, error) {
+func deserialize(data []byte) (*Tree, error) {
 	return loadReader(
 		bufio.NewReader(
 			snappy.NewReader(
--- a/pkg/octree/tin.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/octree/tin.go	Tue Jan 15 10:07:10 2019 +0100
@@ -32,17 +32,26 @@
 	errTooLessPoints = errors.New("Too less points")
 )
 
+// Tin stores a mesh of triangles with common vertices.
 type Tin struct {
-	EPSG      uint32
-	Vertices  []Vertex
+	// EPSG holds the projection.
+	EPSG uint32
+	// Vertices are the shared vertices.
+	Vertices []Vertex
+	// Triangles are the triangles.
 	Triangles [][]int32
 
+	// Min is the lower left corner of the bbox.
 	Min Vertex
+	// Max is the upper right corner of the bbox.
 	Max Vertex
 }
 
+// FromWKB constructs the TIN from a WKB representation.
+// Shared vertices are identified and referenced by the
+// same index.
 func (t *Tin) FromWKB(data []byte) error {
-	log.Printf("data length %d\n", len(data))
+	log.Printf("info: data length %d\n", len(data))
 
 	r := bytes.NewReader(data)
 
@@ -166,7 +175,7 @@
 		triangles = append(triangles, triangle)
 	}
 
-	log.Printf("bbox: [[%f, %f], [%f, %f]]\n",
+	log.Printf("info: bbox: [[%f, %f], [%f, %f]]\n",
 		min.X, min.Y, max.X, max.Y)
 
 	*t = Tin{
@@ -201,6 +210,8 @@
 	loadTinByIDSQL = tinSQLPrefix + `WHERE id = $2` + tinSQLSuffix
 )
 
+// GenerateTinByID generated a TIN by triangulating a point cloud
+// from the database.
 func GenerateTinByID(
 	ctx context.Context,
 	conn *sql.Conn,
@@ -219,6 +230,7 @@
 	return &tin, nil
 }
 
+// Scan implements the sql.Scanner interface.
 func (t *Tin) Scan(raw interface{}) error {
 	if raw == nil {
 		return nil
@@ -230,7 +242,7 @@
 	return t.FromWKB(data)
 }
 
-func (t *Tin) Serialize(w io.Writer) error {
+func (t *Tin) serialize(w io.Writer) error {
 
 	if err := binary.Write(w, binary.LittleEndian, t.EPSG); err != nil {
 		return err
@@ -253,7 +265,7 @@
 			return err
 		}
 	}
-	log.Printf("vertices %d (%d)\n", len(t.Vertices), len(t.Vertices)*3*8)
+	log.Printf("info: vertices %d (%d)\n", len(t.Vertices), len(t.Vertices)*3*8)
 
 	if err := binary.Write(
 		w, binary.LittleEndian, uint32(len(t.Triangles))); err != nil {
@@ -277,7 +289,7 @@
 			last = idx
 		}
 	}
-	log.Printf("compressed tin indices in bytes: %d (%d)\n",
+	log.Printf("info: compressed tin indices in bytes: %d (%d)\n",
 		written, 3*4*len(t.Triangles))
 
 	return nil
--- a/pkg/octree/tree.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/octree/tree.go	Tue Jan 15 10:07:10 2019 +0100
@@ -17,14 +17,18 @@
 	"math"
 )
 
+// Tree is an Octree holding triangles.
 type Tree struct {
+	// EPSG is the projection.
 	EPSG uint32
 
 	vertices  []Vertex
 	triangles [][]int32
 	index     []int32
 
+	// Min is the lower left corner of the bbox.
 	Min Vertex
+	// Max is the upper right corner of the bbox.
 	Max Vertex
 }
 
@@ -35,6 +39,7 @@
 	{0.5, 0.5, 1.0, 1.0},
 }
 
+// Vertical does a vertical cross cut from (x1, y1) to (x2, y2).
 func (ot *Tree) Vertical(x1, y1, x2, y2 float64, fn func(*Triangle)) {
 
 	box := Box2D{
@@ -70,26 +75,28 @@
 		stack = stack[:len(stack)-1]
 
 		if top.pos > 0 { // node
-			for i := int32(0); i < 4; i++ {
-				a := ot.index[top.pos+i]
-				b := ot.index[top.pos+i+4]
-				if a == 0 && b == 0 {
-					continue
-				}
-				dx := top.X2 - top.X1
-				dy := top.Y2 - top.Y1
-				nbox := Box2D{
-					dx*scale[i][0] + top.X1,
-					dy*scale[i][1] + top.Y1,
-					dx*scale[i][2] + top.X1,
-					dy*scale[i][3] + top.Y1,
-				}
-				if nbox.Intersects(box) && nbox.IntersectsPlane(line) {
-					if a != 0 {
-						stack = append(stack, frame{a, nbox})
+			if index := ot.index[top.pos:]; len(index) > 7 {
+				for i := 0; i < 4; i++ {
+					a := index[i]
+					b := index[i+4]
+					if a == 0 && b == 0 {
+						continue
 					}
-					if b != 0 {
-						stack = append(stack, frame{b, nbox})
+					dx := top.X2 - top.X1
+					dy := top.Y2 - top.Y1
+					nbox := Box2D{
+						dx*scale[i][0] + top.X1,
+						dy*scale[i][1] + top.Y1,
+						dx*scale[i][2] + top.X1,
+						dy*scale[i][3] + top.Y1,
+					}
+					if nbox.Intersects(box) && nbox.IntersectsPlane(line) {
+						if a != 0 {
+							stack = append(stack, frame{a, nbox})
+						}
+						if b != 0 {
+							stack = append(stack, frame{b, nbox})
+						}
 					}
 				}
 			}
@@ -123,6 +130,7 @@
 	}
 }
 
+// Horizontal does a horizontal cross cut.
 func (ot *Tree) Horizontal(h float64, fn func(*Triangle)) {
 
 	if h < ot.Min.Z || ot.Max.Z < h {
@@ -156,11 +164,13 @@
 			} else {
 				max = mid
 			}
-			stack = append(stack,
-				frame{ot.index[pos+0], min, max},
-				frame{ot.index[pos+1], min, max},
-				frame{ot.index[pos+2], min, max},
-				frame{ot.index[pos+3], min, max})
+			if index := ot.index[pos:]; len(index) > 3 {
+				stack = append(stack,
+					frame{index[0], min, max},
+					frame{index[1], min, max},
+					frame{index[2], min, max},
+					frame{index[3], min, max})
+			}
 		} else { // leaf
 			pos = -pos - 1
 			n := ot.index[pos]
--- a/pkg/octree/vertex.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/octree/vertex.go	Tue Jan 15 10:07:10 2019 +0100
@@ -23,20 +23,30 @@
 )
 
 type (
+	// Vertex is a 3D vertex.
 	Vertex struct {
 		X float64
 		Y float64
 		Z float64
 	}
 
+	// Triangle is a triangle consisting of three vertices.
 	Triangle [3]Vertex
 
+	// Line is a line defined by first vertex on that line
+	// and the second being the direction.
 	Line [2]Vertex
 
-	MultiPointZ      []Vertex
-	LineStringZ      []Vertex
+	// MultiPointZ is a set of vertices.
+	MultiPointZ []Vertex
+
+	// LineStringZ is a line string formed of vertices.
+	LineStringZ []Vertex
+
+	// MultiLineStringZ is a set of line strings.
 	MultiLineStringZ []LineStringZ
 
+	// Box2D is 2D area from (X1, Y1) to (X2, Y2).
 	Box2D struct {
 		X1 float64
 		Y1 float64
@@ -44,6 +54,7 @@
 		Y2 float64
 	}
 
+	// Plane2D is a 2D plane (a line in 2D space).
 	Plane2D struct {
 		A float64
 		B float64
@@ -51,6 +62,8 @@
 	}
 )
 
+// Minimize adjust this vertex v to hold the minimum
+// values component-wise of v and w.
 func (v *Vertex) Minimize(w Vertex) {
 	if w.X < v.X {
 		v.X = w.X
@@ -63,6 +76,8 @@
 	}
 }
 
+// Maximize adjust this vertex v to hold the maximum
+// values component-wise of v and w.
 func (v *Vertex) Maximize(w Vertex) {
 	if w.X > v.X {
 		v.X = w.X
@@ -75,6 +90,7 @@
 	}
 }
 
+// Sub returns (v - w) component-wise.
 func (v Vertex) Sub(w Vertex) Vertex {
 	return Vertex{
 		v.X - w.X,
@@ -83,6 +99,7 @@
 	}
 }
 
+// Add returns (v + w) component-wise.
 func (v Vertex) Add(w Vertex) Vertex {
 	return Vertex{
 		v.X + w.X,
@@ -91,6 +108,7 @@
 	}
 }
 
+// Scale returns s*v component-wise.
 func (v Vertex) Scale(s float64) Vertex {
 	return Vertex{
 		s * v.X,
@@ -99,6 +117,8 @@
 	}
 }
 
+// Interpolate returns a function that return s*v2 + v1
+// component-wise.
 func Interpolate(v1, v2 Vertex) func(Vertex) Vertex {
 	v2 = v2.Sub(v1)
 	return func(s Vertex) Vertex {
@@ -110,10 +130,13 @@
 	}
 }
 
+// Less returns if one of v component is less than the
+// corresponing component in w.
 func (v Vertex) Less(w Vertex) bool {
 	return v.X < w.X || v.Y < w.Y || v.Z < w.Z
 }
 
+// NewLine return a line of point/direction.
 func NewLine(p1, p2 Vertex) Line {
 	return Line{
 		p2.Sub(p1),
@@ -121,10 +144,13 @@
 	}
 }
 
+// Eval returns the vertex for t*l[0] + l[1].
 func (l Line) Eval(t float64) Vertex {
 	return l[0].Scale(t).Add(l[1])
 }
 
+// IntersectHorizontal returns the intersection point
+// for a given z value.
 func (l Line) IntersectHorizontal(h float64) Vertex {
 	t := (h - l[1].Z) / l[0].Z
 	return l.Eval(t)
@@ -140,6 +166,11 @@
 	return 0
 }
 
+// IntersectHorizontal calculates the line string that
+// results when cutting a triangle a a certain height.
+// Can be empty (on intersection),
+// one vertex (only touching an vertex) or
+// two vertices (real intersection).
 func (t *Triangle) IntersectHorizontal(h float64) LineStringZ {
 	sides := [3]int{
 		side(t[0].Z, h),
@@ -213,12 +244,17 @@
 	}
 }
 
+// EpsEquals returns true if v and w are equal component-wise
+// with the values within a epsilon range.
 func (v Vertex) EpsEquals(w Vertex) bool {
 	const eps = 1e-5
 	return math.Abs(v.X-w.X) < eps &&
 		math.Abs(v.Y-w.Y) < eps && math.Abs(v.Z-w.Z) < eps
 }
 
+// JoinOnLine joins the the elements of a given multi line string
+// under the assumption that the segments are all on the line segment
+// from (x1, y1) to (x2, y2).
 func (mls MultiLineStringZ) JoinOnLine(x1, y1, x2, y2 float64) MultiLineStringZ {
 
 	position := linearScale(x1, y1, x2, y2)
@@ -264,11 +300,13 @@
 		out = append(out, curr)
 	}
 
-	log.Printf("ignored parts: %d\n", ignored)
+	log.Printf("info: ignored parts: %d\n", ignored)
 
 	return out
 }
 
+// Write writes a Vertex as three 64 bit values in little endian order
+// to the given writer.
 func (v *Vertex) Write(w io.Writer) error {
 	if err := binary.Write(
 		w, binary.LittleEndian, math.Float64bits(v.X)); err != nil {
@@ -282,6 +320,8 @@
 		w, binary.LittleEndian, math.Float64bits(v.Z))
 }
 
+// Read fills this vertex with three 64 bit values stored as
+// little endian from the given reader.
 func (v *Vertex) Read(r io.Reader) error {
 	var buf [8]byte
 	b := buf[:]
@@ -300,6 +340,7 @@
 	return nil
 }
 
+// AsWKB returns the WKB representation of the given multi line string.
 func (mls MultiLineStringZ) AsWKB() []byte {
 
 	// pre-calculate size to avoid reallocations.
@@ -328,6 +369,8 @@
 	return buf.Bytes()
 }
 
+// AsWKB2D returns the WKB representation of the given multi line string
+// leaving the z component out.
 func (mls MultiLineStringZ) AsWKB2D() []byte {
 
 	// pre-calculate size to avoid reallocations.
@@ -355,7 +398,7 @@
 	return buf.Bytes()
 }
 
-// Join joins two lines leaving the first of the secoung out.
+// Join joins two lines leaving the first of the second out.
 func (ls LineStringZ) Join(other LineStringZ) LineStringZ {
 	nline := make(LineStringZ, len(ls)+len(other)-1)
 	copy(nline, ls)
@@ -363,6 +406,8 @@
 	return nline
 }
 
+// Merge merges line segments of a given multi line string
+// by finding common start and end vertices.
 func (mls MultiLineStringZ) Merge() MultiLineStringZ {
 
 	var out MultiLineStringZ
@@ -467,15 +512,13 @@
 	return out
 }
 
+// Intersects checks if two Box2Ds intersect.
 func (a Box2D) Intersects(b Box2D) bool {
 	return !(a.X2 < a.X1 || a.X2 < b.X1 ||
 		a.Y2 < a.Y1 || a.Y2 < b.Y1)
 }
 
-func (a Box2D) Mid() (float64, float64) {
-	return (a.X2-a.X1)*0.5 + a.X1, (a.Y2-a.Y1)*0.5 + a.Y1
-}
-
+// Xi returns the i-th x component.
 func (a Box2D) Xi(i int) float64 {
 	if i == 0 {
 		return a.X1
@@ -483,6 +526,7 @@
 	return a.X2
 }
 
+// Yi returns the i-th y component.
 func (a Box2D) Yi(i int) float64 {
 	if i == 0 {
 		return a.Y1
@@ -490,6 +534,7 @@
 	return a.Y2
 }
 
+// NewPlane2D creates a new Plane2D from two given points.
 func NewPlane2D(x1, y1, x2, y2 float64) Plane2D {
 	b := x2 - x1
 	a := -(y2 - y1)
@@ -503,6 +548,9 @@
 	return Plane2D{a, b, c}
 }
 
+// Eval determines the distance of a given point
+// from the plane. The sign of the result indicates
+// the sideness.
 func (p Plane2D) Eval(x, y float64) float64 {
 	return p.A*x + p.B*y + p.C
 }
@@ -516,6 +564,8 @@
 	return s | 1
 }
 
+// IntersectsPlane checks if a Box2D intersects with
+// a given Plane2D.
 func (a Box2D) IntersectsPlane(p Plane2D) bool {
 	var s int
 	for i := 0; i < 2; i++ {
@@ -537,6 +587,7 @@
 	return false
 }
 
+// Cross calculates the cross product of two vertices.
 func (v Vertex) Cross(w Vertex) Vertex {
 	return Vertex{
 		v.Y*w.Z - v.Z*w.Y,
@@ -545,6 +596,9 @@
 	}
 }
 
+// Intersection calcultes the 2D intersection point of
+// two Plane2Ds. If they do not intersect the returned
+// bool flags is set to false.
 func (p Plane2D) Intersection(o Plane2D) (float64, float64, bool) {
 
 	u1 := Vertex{p.A, p.B, p.C}
@@ -559,6 +613,7 @@
 	return plane.X / plane.Z, plane.Y / plane.Z, true
 }
 
+// VerticalLine is a 2D line segment.
 type VerticalLine struct {
 	x1 float64
 	y1 float64
@@ -568,6 +623,7 @@
 	line Plane2D
 }
 
+// NewVerticalLine creates a new 2D line segment.
 func NewVerticalLine(x1, y1, x2, y2 float64) *VerticalLine {
 	return &VerticalLine{
 		x1:   x1,
@@ -605,6 +661,7 @@
 
 func inRange(a float64) bool { return 0 <= a && a <= 1 }
 
+// Intersection intersects a line segment with a triangle.
 func (vl *VerticalLine) Intersection(t *Triangle) LineStringZ {
 
 	var out LineStringZ
@@ -780,6 +837,7 @@
 	return out
 }
 
+// AsWKB returns a WKB representation of the given point cloud.
 func (mpz MultiPointZ) AsWKB() []byte {
 	size := 1 + 4 + 4 + len(mpz)*(1+4+3*8)
 
--- a/pkg/scheduler/boot.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/scheduler/boot.go	Tue Jan 15 10:07:10 2019 +0100
@@ -26,9 +26,13 @@
 	bootRole = "sys_admin"
 
 	selectImportConfSQL = `
-SELECT id, username, kind, cron
+SELECT id, username, cron
 FROM waterway.import_configuration
 WHERE cron IS NOT NULL`
+
+	scheduledIDsSQL = `
+SELECT id from waterway.import_configuration
+WHERE username = $1 AND cron IS NOT NULL`
 )
 
 func init() { go boot() }
@@ -57,13 +61,12 @@
 				var id int64
 				if err = rows.Scan(
 					&id,
-					&ba.User,
 					&ba.Name,
 					&ba.Spec,
 				); err != nil {
 					return false, err
 				}
-				ba.CfgID = &id
+				ba.CfgID = id
 				return true, nil
 			})
 			if err != nil {
@@ -75,3 +78,28 @@
 		log.Printf("error: %v\n", err)
 	}
 }
+
+// ScheduledUserIDs returns the IDs with a schedule for a given user.
+func ScheduledUserIDs(
+	ctx context.Context,
+	conn *sql.Conn,
+	user string,
+) (map[int64]struct{}, error) {
+	ids := map[int64]struct{}{}
+	rows, err := conn.QueryContext(ctx, scheduledIDsSQL, user)
+	if err != nil {
+		return nil, nil
+	}
+	defer rows.Close()
+	for rows.Next() {
+		var id int64
+		if err := rows.Scan(&id); err != nil {
+			return nil, err
+		}
+		ids[id] = struct{}{}
+	}
+	if err := rows.Err(); err != nil {
+		return nil, err
+	}
+	return ids, nil
+}
--- a/pkg/scheduler/scheduler.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/scheduler/scheduler.go	Tue Jan 15 10:07:10 2019 +0100
@@ -14,24 +14,19 @@
 package scheduler
 
 import (
-	"errors"
 	"log"
 	"sync"
 
 	"github.com/robfig/cron"
 )
 
-// ErrNoSuchAction if no fitting action was found.
-var ErrNoSuchAction = errors.New("No such action")
-
-// Action is called with a user and an optional configuration id.
-type Action func(user string, cfgID *int64)
+// Action is called with a configuration id.
+type Action func(cfgID int64)
 
 type userAction struct {
 	scheduler *scheduler
-	user      string
 	name      string
-	cfgID     *int64
+	cfgID     int64
 }
 
 type scheduler struct {
@@ -43,7 +38,7 @@
 // Run implements cron.Job.
 func (ua *userAction) Run() {
 	if a := ua.scheduler.action(ua.name); a != nil {
-		a(ua.user, ua.cfgID)
+		a(ua.cfgID)
 	} else {
 		log.Printf("warn: scheduled action '%s' not found.", ua.name)
 	}
@@ -65,13 +60,12 @@
 }
 
 // BoundAction is a complete set of infos for
-// an action to be bound to a user, schedule and
-// optional configuration id.
+// an action to be bound to a schedule and
+// configuration id.
 type BoundAction struct {
 	Name  string
 	Spec  string
-	User  string
-	CfgID *int64
+	CfgID int64
 }
 
 // BootActions setup the global scheduler with a set
@@ -99,8 +93,6 @@
 		}
 		job := &userAction{
 			scheduler: s,
-			user:      ba.User,
-			name:      ba.Name,
 			cfgID:     ba.CfgID,
 		}
 		cr.Schedule(schedule, job)
@@ -116,16 +108,16 @@
 	return nil
 }
 
-// BindAction binds a named action to a user, a cron spec and
-// an optional configuration id.
-func BindAction(name, spec, user string, cfgID *int64) error {
-	return global.bindAction(name, spec, user, cfgID)
+// BindAction binds a named action to a cron spec and
+// a configuration id.
+func BindAction(name, spec string, cfgID int64) error {
+	return global.bindAction(name, spec, cfgID)
 }
 
 // UnbindAction unbinds a named action from a user and
-// an optional configuration id.
-func UnbindAction(name, user string, cfgID *int64) {
-	global.unbindAction(name, user, cfgID)
+// a configuration id.
+func UnbindAction(name string, cfgID int64) {
+	global.unbindAction(name, cfgID)
 }
 
 // UnbindByID unbinds all schedules with a given id.
@@ -133,9 +125,9 @@
 	global.unbindByID(cfgID)
 }
 
-// UnbindUser unbinds all schedules for a given user.
-func UnbindUser(user string) {
-	global.unbindUser(user)
+// UnbindByIDs unbinds all schedules for a given user.
+func UnbindByIDs(ids map[int64]struct{}) {
+	global.unbindByIDs(ids)
 }
 
 // HasAction asks if there is an action with a given name.
@@ -149,11 +141,7 @@
 	return s.actions[name] != nil
 }
 
-func sameCfgID(a, b *int64) bool {
-	return (a == nil && b == nil) || (a != nil && b != nil && *a == *b)
-}
-
-func (s *scheduler) unbindUser(user string) {
+func (s *scheduler) unbindByIDs(ids map[int64]struct{}) {
 	s.mu.Lock()
 	defer s.mu.Unlock()
 
@@ -166,8 +154,7 @@
 	var found bool
 	for _, entry := range entries {
 		ua := entry.Job.(*userAction)
-		if ua.user == user {
-			found = true
+		if _, found = ids[ua.cfgID]; found {
 			break
 		}
 	}
@@ -179,7 +166,7 @@
 	s.cr = cron.New()
 	for _, entry := range entries {
 		ua := entry.Job.(*userAction)
-		if ua.user != user {
+		if _, found := ids[ua.cfgID]; !found {
 			s.cr.Schedule(entry.Schedule, entry.Job)
 		}
 	}
@@ -195,7 +182,7 @@
 	var found bool
 	for _, entry := range entries {
 		ua := entry.Job.(*userAction)
-		if ua.cfgID != nil && *ua.cfgID == cfgID {
+		if ua.cfgID == cfgID {
 			found = true
 			break
 		}
@@ -209,14 +196,14 @@
 	s.cr = cron.New()
 	for _, entry := range entries {
 		ua := entry.Job.(*userAction)
-		if ua.cfgID == nil || *ua.cfgID != cfgID {
+		if ua.cfgID != cfgID {
 			s.cr.Schedule(entry.Schedule, entry.Job)
 		}
 	}
 	s.cr.Start()
 }
 
-func (s *scheduler) unbindAction(name, user string, cfgID *int64) {
+func (s *scheduler) unbindAction(name string, cfgID int64) {
 	s.mu.Lock()
 	defer s.mu.Unlock()
 
@@ -225,8 +212,8 @@
 	var found *userAction
 	for _, entry := range entries {
 		ua := entry.Job.(*userAction)
-		if ua.name == name && ua.user == user && sameCfgID(cfgID, ua.cfgID) {
-			// Already have such a user/action/cfg tuple  -> re-schedule.
+		if ua.name == name && cfgID == ua.cfgID {
+			// Already have such a action/cfg tuple  -> re-schedule.
 			found = ua
 			break
 		}
@@ -247,7 +234,7 @@
 	s.cr.Start()
 }
 
-func (s *scheduler) bindAction(name, spec, user string, cfgID *int64) error {
+func (s *scheduler) bindAction(name, spec string, cfgID int64) error {
 
 	schedule, err := cron.Parse(spec)
 	if err != nil {
@@ -262,7 +249,7 @@
 	var found *userAction
 	for _, entry := range entries {
 		ua := entry.Job.(*userAction)
-		if ua.name == name && ua.user == user && sameCfgID(cfgID, ua.cfgID) {
+		if ua.name == name && cfgID == ua.cfgID {
 			// Already have such a user/action/cfg tuple  -> re-schedule.
 			found = ua
 			break
@@ -271,7 +258,7 @@
 
 	if found == nil {
 		// Add to current plan.
-		job := &userAction{scheduler: s, user: user, name: name, cfgID: cfgID}
+		job := &userAction{scheduler: s, name: name, cfgID: cfgID}
 		s.cr.Schedule(schedule, job)
 	} else {
 		// If found re-build all.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/soap/erdms/service.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,2499 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+package erdms
+
+import (
+	"encoding/xml"
+	"time"
+
+	"gemma.intevation.de/gemma/pkg/soap"
+)
+
+// against "unused imports"
+var _ time.Time
+var _ xml.Name
+
+// adn (dgs goods) internal adn code (unnr + seqnr: to make each adn good unique)
+type AdnCodeType string
+
+// adn class and classifications codes
+type AdnClassType string
+
+// adn (dgs) labels applicable for a dgs good
+type AdnLabelType string
+
+// Older CBS (number) code (3 digits) use by statistics organisations (backw comp) but replaced by newer iso 3166 (2 letters).
+type CbscountryCodeType string
+
+// iso 6346 container type (code)
+type ContIdType string
+
+// containertype textual description
+type ContNameType string
+
+// indication (flag) wheater shiptype code is a single ship or a transport combination
+type CombinationFlagType bool
+
+// Country iso 3166 code (2 alpha)
+type CountryCodeType string
+
+// Country iso 3166 code (3 alpha)
+type CountryCode3Type string
+
+// Countryname type (name of the country)
+type CountryNameType string
+
+// Country iso 3166 numcode (3 digits)
+type CountryIsoNumType string
+
+// techn directive craft type code (eu hull db)
+type CraftTypeType string
+
+// inland cones 0,1,2,3,V (as used for DGS goods and cones calculations)
+type ConesType string
+
+const (
+	ConesType0 ConesType = "0"
+
+	ConesType1 ConesType = "1"
+
+	ConesType2 ConesType = "2"
+
+	ConesType3 ConesType = "3"
+
+	ConesTypeV ConesType = "V"
+)
+
+// dimension type (length, width, draught etc) in [cm] (no decimals)
+type DimType int64
+
+// older 2 digit dvk shiptype code (replaced by unrec
+type DvkTypeType string
+
+// record erased (not actual anymore) flag type
+type ErasedType bool
+
+// eri location code type as used for eri_locations
+type ErilocCodeType string
+
+// eri location name type as used in eri_locations
+type ErilocNameType string
+
+// flags 0,B,V (dang goods indication seagoing vessels)
+type FlagsType string
+
+const (
+	FlagsType0 FlagsType = "0"
+
+	FlagsTypeB FlagsType = "B"
+
+	FlagsTypeV FlagsType = "V"
+)
+
+// fairway code (text)
+type FwCodeType string
+
+// ADN dangerous goodnames, description
+type GoodDgsNameType string
+
+// non-dangerous goodnames, description
+type GoodNameType string
+
+// ADN dangerous good synonym name,description
+type GoodSynType string
+
+// HS code as used by customs
+type HsCodeType string
+
+// hectometre code (hectomere in [hm] (no decimals) on the fairway)
+type KmCodeType string
+
+// lastupdate, last modification date time of this record
+type LastupdateType time.Time
+
+// one of the supported languages (basic and additional set), based on ISO 639-1
+type LangType string
+
+const (
+	LangTypeXX LangType = "%%"
+
+	LangTypeLc LangType = "lc"
+
+	LangTypeNl LangType = "nl"
+
+	LangTypeDe LangType = "de"
+
+	LangTypeFr LangType = "fr"
+
+	LangTypeEn LangType = "en"
+
+	LangTypeBg LangType = "bg"
+
+	LangTypeCs LangType = "cs"
+
+	LangTypeDa LangType = "da"
+
+	LangTypeEl LangType = "el"
+
+	LangTypeEs LangType = "es"
+
+	LangTypeEt LangType = "et"
+
+	LangTypeFi LangType = "fi"
+
+	LangTypeHu LangType = "hu"
+
+	LangTypeIt LangType = "it"
+
+	LangTypeLt LangType = "lt"
+
+	LangTypeLv LangType = "lv"
+
+	LangTypePl LangType = "pl"
+
+	LangTypePt LangType = "pt"
+
+	LangTypeRo LangType = "ro"
+
+	LangTypeSk LangType = "sk"
+
+	LangTypeSl LangType = "sl"
+
+	LangTypeSv LangType = "sv"
+
+	LangTypeHr LangType = "hr"
+
+	LangTypeRu LangType = "ru"
+
+	LangTypeSr LangType = "sr"
+)
+
+// lat long (WGS decimal [.] coordinates) coordinate type
+type LatlonType float64
+
+// un locode (2 country + 3 location code)
+type LoCodeType string
+
+// Number of possible (departure) exist (routes) for a location
+type LocExitsType int32
+
+// VTS/IVS (code)name active in certain area and acting as a reporting point (when departing from that location)
+type LocVtsCodeType string
+
+// location type, terminal type (a number indicating type of location,terminal)
+type LocTypeType int32
+
+// lloyds flag code for a certain country (seagoing)
+type LloydsflagType string
+
+// NST code (corresponing nst2007 EU statistics codes for goods).
+type NstCodeType string
+
+// NtS (Notices to Skippers) code/Value datatype
+type NtsCodeType string
+
+// NtS name/description (belonging to a ntsCode) datatype
+type NtsNameType string
+
+// NtS subtype (sub data type, there are several nts tables)
+type NtstypeType string
+
+// ADN dangerous good packing group I, II, III
+type PackGrpType string
+
+// UN rec 21 inner package code
+type PackIdType string
+
+// Un rec 21 inner package name/description
+type PackNameType string
+
+// Password type (belonging to a user, used to identify a user and its role and home country).
+type PasswordType string
+
+// quay type (terminals), indicating quay nrs/id's
+type QuayType string
+
+// record counter (nr of records available or in a set)
+type RecCountType int64
+
+// reftype Type (reftool data reftype, such as: risidx, eri_location, eri_hscode, nts_data)
+type ReftypeType string
+
+const (
+	ReftypeTypeRis_idx ReftypeType = "ris_idx"
+
+	ReftypeTypeEri_location ReftypeType = "eri_location"
+
+	ReftypeTypeEri_hscode ReftypeType = "eri_hscode"
+
+	ReftypeTypeEri_adncode ReftypeType = "eri_adncode"
+
+	ReftypeTypeEri_conttype ReftypeType = "eri_conttype"
+
+	ReftypeTypeEri_packtype ReftypeType = "eri_packtype"
+
+	ReftypeTypeEri_shiptype ReftypeType = "eri_shiptype"
+
+	ReftypeTypeEri_country ReftypeType = "eri_country"
+
+	ReftypeTypeNts_barrage ReftypeType = "nts_barrage"
+
+	ReftypeTypeNts_communication ReftypeType = "nts_communication"
+
+	ReftypeTypeNts_country ReftypeType = "nts_country"
+
+	ReftypeTypeNts_direction ReftypeType = "nts_direction"
+
+	ReftypeTypeNts_direction_max ReftypeType = "nts_direction_max"
+
+	ReftypeTypeNts_direction_min ReftypeType = "nts_direction_min"
+
+	ReftypeTypeNts_gui_labels ReftypeType = "nts_gui_labels"
+
+	ReftypeTypeNts_ice_accessibility ReftypeType = "nts_ice_accessibility"
+
+	ReftypeTypeNts_ice_condition ReftypeType = "nts_ice_condition"
+
+	ReftypeTypeNts_ice_classification ReftypeType = "nts_ice_classification"
+
+	ReftypeTypeNts_ice_situation ReftypeType = "nts_ice_situation"
+
+	ReftypeTypeNts_indication ReftypeType = "nts_indication"
+
+	ReftypeTypeNts_interval ReftypeType = "nts_interval"
+
+	ReftypeTypeNts_language ReftypeType = "nts_language"
+
+	ReftypeTypeNts_limitation ReftypeType = "nts_limitation"
+
+	ReftypeTypeNts_measure ReftypeType = "nts_measure"
+
+	ReftypeTypeNts_position ReftypeType = "nts_position"
+
+	ReftypeTypeNts_reason ReftypeType = "nts_reason"
+
+	ReftypeTypeNts_reference ReftypeType = "nts_reference"
+
+	ReftypeTypeNts_regime ReftypeType = "nts_regime"
+
+	ReftypeTypeNts_reporting ReftypeType = "nts_reporting"
+
+	ReftypeTypeNts_subject ReftypeType = "nts_subject"
+
+	ReftypeTypeNts_tag ReftypeType = "nts_tag"
+
+	ReftypeTypeNts_target_group ReftypeType = "nts_target_group"
+
+	ReftypeTypeNts_type ReftypeType = "nts_type"
+
+	ReftypeTypeNts_weather_category ReftypeType = "nts_weather_category"
+
+	ReftypeTypeNts_weather_class ReftypeType = "nts_weather_class"
+
+	ReftypeTypeNts_weather_direction ReftypeType = "nts_weather_direction"
+
+	ReftypeTypeNts_weather_item ReftypeType = "nts_weather_item"
+)
+
+// RefData record version numbering (automaically, starts with 1 and increments on updates, requesting version 0=dont care)
+type RefrecVersionType int64
+
+// remarks string (remarks about the maintance of a record or any other remarks)
+type RemarksType string
+
+// ris index (ISRS) code type (full ris index code)
+type RisCodeType string
+
+// locationames as used in the ris index
+type RislocNameType string
+
+// ris idx related ENC's type as used in ris idx (list of ENC id's)
+type RisrelencType string
+
+// ris idx object code type (single code for a junction, termcode etc padded), subpart of the ris idx.
+type RisobjCodeType string
+
+// ris idx communication information TXTDSC
+type RiscomminfoType string
+
+// ris idx object function code type (junction, berths etc)
+type RisobjfuncType string
+
+// ris idx section node id
+type RissectnodeType string
+
+// ris idx national Gauge Code type (can be utilised to store any national coding/id/link for gauges)
+type RisgaugeidType string
+
+// ris idx applicability from /  to km (in hectometres (no decimals))
+type RisapplikmType int64
+
+// ris idx reference level code (indicating the ref level)
+type RisreflevelcodeType string
+
+// ris idx reference level value [cm]
+type RisreflevelvalueType int64
+
+// ris idx geod reference
+type RisgeodrefType string
+
+// ris idx zero point [cm]
+type RiszeropointType int64
+
+// ris idx category of time schedule (cattab)
+type RiscatoftimeschedType string
+
+// ris idx for ship type
+type RisforshiptypeType string
+
+// ris idx use of ship useshp
+type RisuseofshipType string
+
+// ris idx link to external XML file
+type RislinkextxmlType string
+
+// UNrec 28 shiptype (4 digits)
+type ShipTypeType string
+
+// shiptype name (textual) description
+type ShiptypeNameType string
+
+// source string, to specify the source of this record/data or the update.
+type SourceType string
+
+// ADN signal code (to group dgs for cones/flags calculations)
+type SignalCodeType string
+
+// terminal code type (remark: termcode is the only part of eri locs with variable length, historical reasons).
+type TermCodeType string
+
+// unlocode countrycode part (first 2 of unlocode) as used in ris idx
+type UnlocCCType string
+
+// unlocode location code part (last 3 of unlocode) as used in ris idx
+type UnlocLCType string
+
+// UN nr (4 digits) adn nr for identifying ADN dangerous goods (according CCNR)
+type UnnrType string
+
+// reftool username(reftool accountname) type, to idetify a user and its role.
+type UserNameType string
+
+// cargo weight type, integer nr (units [tons], [kg]) depending on element)
+type WeightType int64
+
+// adn warning (dgs) card id
+type WarnIdType string
+
+// adn warning card
+type WarnCardType string
+
+type MatchByCode struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ matchByCode"`
+
+	*MatchByCodeType
+}
+
+type MatchByCodeResponse struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ matchByCodeResponse"`
+
+	*MatchByCodeResponseType
+}
+
+type MatchByName struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ matchByName"`
+
+	*MatchByNameType
+}
+
+type MatchByNameResponse struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ matchByNameResponse"`
+
+	*MatchByNameResponseType
+}
+
+type GetDataXML struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getDataXML"`
+
+	*GetDataXMLType
+}
+
+type GetDataXMLResponse struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getDataXMLResponse"`
+
+	*GetDataXMLResponseType
+}
+
+type GetMutations struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getMutations"`
+
+	*GetMutationsType
+}
+
+type GetMutationsResponse struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getMutationsResponse"`
+
+	*GetMutationsResponseType
+}
+
+type GetRisDataXML struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getRisDataXML"`
+
+	*GetRisDataXMLType
+}
+
+type GetRisDataXMLResponse struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getRisDataXMLResponse"`
+
+	*GetRisDataXMLResponseType
+}
+
+type MutateDataXML struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ mutateDataXML"`
+
+	*MutateDataXMLType
+}
+
+type MutateDataXMLResponse struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ mutateDataXMLResponse"`
+
+	*MutateDataXMLResponseType
+}
+
+type RequestMutationXML struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ requestMutationXML"`
+
+	*RequestMutationXMLType
+}
+
+type RequestMutationXMLResponse struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ requestMutationXMLResponse"`
+
+	*RequestMutationXMLResponseType
+}
+
+type MatchByCodeType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ matchByCodeType"`
+
+	Reftype *ReftypeType `xml:"reftype,omitempty"`
+
+	Code string `xml:"code,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+}
+
+type MatchByCodeResponseType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ matchByCodeResponseType"`
+
+	// Indicates how many records are available/were found
+	// (due limitations less records can be returned/available in the resulting xml structure).
+	RecCount *RecCountType `xml:"recCount,omitempty"`
+
+	RefdataReturn []*RefdataReturnType `xml:"refdataReturn,omitempty"`
+}
+
+type MatchByNameType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ matchByNameType"`
+
+	Reftype *ReftypeType `xml:"reftype,omitempty"`
+
+	Lang *LangType `xml:"lang,omitempty"`
+
+	Name string `xml:"name,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+}
+
+type MatchByNameResponseType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ matchByNameResponseType"`
+
+	// Indicates how many records are available/were found
+	// (due limitations less records can be returned/available in the resulting xml structure).
+	RecCount *RecCountType `xml:"recCount,omitempty"`
+
+	RefdataReturn []*RefdataReturnType `xml:"refdataReturn,omitempty"`
+}
+
+type GetMutationsType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getMutationsType"`
+
+	Reftype *ReftypeType `xml:"reftype,omitempty"`
+
+	// from, to in datetime format in UTC time
+	FromDate time.Time `xml:"fromDate,omitempty"`
+
+	ToDate time.Time `xml:"toDate,omitempty"`
+}
+
+type GetMutationsResponseType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getMutationsResponseType"`
+
+	// Indicate how many records are available/were found.
+	RecCount *RecCountType `xml:"recCount,omitempty"`
+
+	RefdataReturn []*RefdataReturnType `xml:"refdataReturn,omitempty"`
+}
+
+type GetDataXMLType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getDataXMLType"`
+
+	Reftype *ReftypeType `xml:"reftype,omitempty"`
+
+	Subcode string `xml:"subcode,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+}
+
+type GetDataXMLResponseType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getDataXMLResponseType"`
+
+	// Indicates how many records are available/were found.
+	RecCount *RecCountType `xml:"recCount,omitempty"`
+
+	RefdataReturn []*RefdataReturnType `xml:"refdataReturn,omitempty"`
+}
+
+type GetRisDataXMLType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getRisDataXMLType"`
+
+	Subcode string `xml:"subcode,omitempty"`
+
+	Funcode string `xml:"funcode,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+}
+
+type GetRisDataXMLResponseType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ getRisDataXMLResponseType"`
+
+	// Indicates how many records are available/were found.
+	RecCount *RecCountType `xml:"recCount,omitempty"`
+
+	RisdataReturn []*Ris_idxType `xml:"risdataReturn,omitempty"`
+}
+
+type MutateDataXMLType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ mutateDataXMLType"`
+
+	Username *UserNameType `xml:"username,omitempty"`
+
+	Password *PasswordType `xml:"password,omitempty"`
+
+	Reftype *ReftypeType `xml:"reftype,omitempty"`
+
+	RefData *RefdataReturnType `xml:"refData,omitempty"`
+}
+
+type MutateDataXMLResponseType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ mutateDataXMLResponseType"`
+
+	*StatReturnType
+}
+
+type RequestMutationXMLType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ requestMutationXMLType"`
+
+	Username *UserNameType `xml:"username,omitempty"`
+
+	Password *PasswordType `xml:"password,omitempty"`
+
+	Reftype *ReftypeType `xml:"reftype,omitempty"`
+
+	InUserList bool `xml:"inUserList,omitempty"`
+
+	RefDataReqMut *RefdataReqMutType `xml:"refDataReqMut,omitempty"`
+}
+
+type RequestMutationXMLResponseType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ requestMutationXMLResponseType"`
+
+	*StatReturnType
+}
+
+type ExceptionType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ exception"`
+
+	// exception code
+	Exception int32 `xml:"exception,omitempty"`
+
+	// exception message in English
+	Message string `xml:"message,omitempty"`
+}
+
+type RefdataReturnType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ refdataReturnType"`
+
+	Reftype struct {
+		Value *ReftypeType
+	} `xml:"reftype,omitempty"`
+
+	Ris_idx *Ris_idxType `xml:"ris_idx,omitempty"`
+
+	Eri_location *Eri_locationType `xml:"eri_location,omitempty"`
+
+	Eri_hscode *Eri_hscodeType `xml:"eri_hscode,omitempty"`
+
+	Eri_adncode struct {
+		*Eri_adncodeType
+	} `xml:"eri_adncode,omitempty"`
+
+	Eri_conttype *Eri_conttypeType `xml:"eri_conttype,omitempty"`
+
+	Eri_packtype *Eri_packtypeType `xml:"eri_packtype,omitempty"`
+
+	Eri_shiptype *Eri_shiptypeType `xml:"eri_shiptype,omitempty"`
+
+	Eri_country *Eri_countryType `xml:"eri_country,omitempty"`
+
+	// NtS element is only available in the return refdata structure.
+	// It is not available in the Req Mutation datastructure because we can not mutate nts data (not allowed)!
+	Nts_data *Nts_dataType `xml:"nts_data,omitempty"`
+}
+
+type RefdataReqMutType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ refdataReqMutType"`
+
+	// BE SURE to edit the basic (simple)types, DONT edit any of the subelements from here!
+	Reftype *ReftypeType `xml:"reftype,omitempty"`
+
+	Ris_idx *Ris_idxReqMutType `xml:"ris_idx,omitempty"`
+
+	Eri_location *Eri_locationReqMutType `xml:"eri_location,omitempty"`
+
+	Eri_hscode *Eri_hscodeReqMutType `xml:"eri_hscode,omitempty"`
+
+	Eri_adncode *Eri_adncodeReqMutType `xml:"eri_adncode,omitempty"`
+
+	Eri_conttype *Eri_conttypeReqMutType `xml:"eri_conttype,omitempty"`
+
+	Eri_packtype *Eri_packtypeReqMutType `xml:"eri_packtype,omitempty"`
+
+	Eri_shiptype *Eri_shiptypeReqMutType `xml:"eri_shiptype,omitempty"`
+
+	Eri_country *Eri_countryReqMutType `xml:"eri_country,omitempty"`
+}
+
+type StatReturnType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ statReturnType"`
+
+	// 0=ok, 1=warning, 2=error
+	Err int32 `xml:"err,omitempty"`
+
+	Message struct {
+	} `xml:"message,omitempty"`
+}
+
+type Ris_idxType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ ris_idxType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	RisidxCode *RisCodeType `xml:"risidxCode,omitempty"`
+
+	CodeOld *RisCodeType `xml:"codeOld,omitempty"`
+
+	UnlocCC *UnlocCCType `xml:"unlocCC,omitempty"`
+
+	UnlocLC *UnlocLCType `xml:"unlocLC,omitempty"`
+
+	WwsectCode *FwCodeType `xml:"wwsectCode,omitempty"`
+
+	Objcode *RisobjCodeType `xml:"objcode,omitempty"`
+
+	Hectomt *KmCodeType `xml:"hectomt,omitempty"`
+
+	Objfunc *RisobjfuncType `xml:"objfunc,omitempty"`
+
+	Objname struct {
+		Loc *RislocNameType `xml:"Loc,omitempty"`
+	} `xml:"objname,omitempty"`
+
+	Locname struct {
+		Loc *RislocNameType `xml:"Loc,omitempty"`
+	} `xml:"locname,omitempty"`
+
+	Wwname struct {
+		Loc *RislocNameType `xml:"Loc,omitempty"`
+	} `xml:"wwname,omitempty"`
+
+	Routename struct {
+		Loc *RislocNameType `xml:"Loc,omitempty"`
+	} `xml:"routename,omitempty"`
+
+	Relrisindex *RisCodeType `xml:"relrisindex,omitempty"`
+
+	Sectionnode *RissectnodeType `xml:"sectionnode,omitempty"`
+
+	Lat *LatlonType `xml:"lat,omitempty"`
+
+	Lon *LatlonType `xml:"lon,omitempty"`
+
+	Relenc *RisrelencType `xml:"relenc,omitempty"`
+
+	Comminfo *RiscomminfoType `xml:"comminfo,omitempty"`
+
+	Gaugeid *RisgaugeidType `xml:"gaugeid,omitempty"`
+
+	Vesselconvlength *DimType `xml:"vesselconvlength,omitempty"`
+
+	Vesselconvbreadth *DimType `xml:"vesselconvbreadth,omitempty"`
+
+	Vesselconvdraught *DimType `xml:"vesselconvdraught,omitempty"`
+
+	Vesselconvairdraught *DimType `xml:"vesselconvairdraught,omitempty"`
+
+	Availablelength *DimType `xml:"availablelength,omitempty"`
+
+	Clearancewidth *DimType `xml:"clearancewidth,omitempty"`
+
+	Availabledepth *DimType `xml:"availabledepth,omitempty"`
+
+	Clearanceheight *DimType `xml:"clearanceheight,omitempty"`
+
+	Applicabilityfromkm *RisapplikmType `xml:"applicabilityfromkm,omitempty"`
+
+	Applicabilitytokm *RisapplikmType `xml:"applicabilitytokm,omitempty"`
+
+	Reflevel1code *RisreflevelcodeType `xml:"reflevel1code,omitempty"`
+
+	Reflevel1value *RisreflevelvalueType `xml:"reflevel1value,omitempty"`
+
+	Reflevel2code *RisreflevelcodeType `xml:"reflevel2code,omitempty"`
+
+	Reflevel2value *RisreflevelvalueType `xml:"reflevel2value,omitempty"`
+
+	Reflevel3code *RisreflevelcodeType `xml:"reflevel3code,omitempty"`
+
+	Reflevel3value *RisreflevelvalueType `xml:"reflevel3value,omitempty"`
+
+	Zeropoint *RiszeropointType `xml:"zeropoint,omitempty"`
+
+	Geodref *RisgeodrefType `xml:"geodref,omitempty"`
+
+	Catoftimesched *RiscatoftimeschedType `xml:"catoftimesched,omitempty"`
+
+	Forshiptype *RisforshiptypeType `xml:"forshiptype,omitempty"`
+
+	Foruseofship *RisuseofshipType `xml:"foruseofship,omitempty"`
+
+	LnktoextXMfiletimesched *RislinkextxmlType `xml:"lnktoextXMfiletimesched,omitempty"`
+
+	LnktoextXMfilepastime *RislinkextxmlType `xml:"lnktoextXMfilepastime,omitempty"`
+
+	Vesselconvlength2 *DimType `xml:"vesselconvlength2,omitempty"`
+
+	Vesselconvbreadth2 *DimType `xml:"vesselconvbreadth2,omitempty"`
+
+	Vesselconvdraught2 *DimType `xml:"vesselconvdraught2,omitempty"`
+
+	Vesselconvairdraught2 *DimType `xml:"vesselconvairdraught2,omitempty"`
+
+	Availablelength2 *DimType `xml:"availablelength2,omitempty"`
+
+	Clearancewidth2 *DimType `xml:"clearancewidth2,omitempty"`
+
+	Availabledepth2 *DimType `xml:"availabledepth2,omitempty"`
+
+	Clearanceheight2 *DimType `xml:"clearanceheight2,omitempty"`
+
+	Vesselconvlength3 *DimType `xml:"vesselconvlength3,omitempty"`
+
+	Vesselconvbreadth3 *DimType `xml:"vesselconvbreadth3,omitempty"`
+
+	Vesselconvdraught3 *DimType `xml:"vesselconvdraught3,omitempty"`
+
+	Vesselconvairdraught3 *DimType `xml:"vesselconvairdraught3,omitempty"`
+
+	Availablelength3 *DimType `xml:"availablelength3,omitempty"`
+
+	Clearancewidth3 *DimType `xml:"clearancewidth3,omitempty"`
+
+	Availabledepth3 *DimType `xml:"availabledepth3,omitempty"`
+
+	Clearanceheight3 *DimType `xml:"clearanceheight3,omitempty"`
+
+	Catoftimesched2 *RiscatoftimeschedType `xml:"catoftimesched2,omitempty"`
+
+	Forshiptype2 *RisforshiptypeType `xml:"forshiptype2,omitempty"`
+
+	Foruseofship2 *RisuseofshipType `xml:"foruseofship2,omitempty"`
+
+	LnktoextXMfiletimesched2 *RislinkextxmlType `xml:"lnktoextXMfiletimesched2,omitempty"`
+
+	LnktoextXMfilepastime2 *RislinkextxmlType `xml:"lnktoextXMfilepastime2,omitempty"`
+
+	Catoftimesched3 *RiscatoftimeschedType `xml:"catoftimesched3,omitempty"`
+
+	Forshiptype3 *RisforshiptypeType `xml:"forshiptype3,omitempty"`
+
+	Foruseofship3 *RisuseofshipType `xml:"foruseofship3,omitempty"`
+
+	LnktoextXMfiletimesched3 *RislinkextxmlType `xml:"lnktoextXMfiletimesched3,omitempty"`
+
+	LnktoextXMfilepastime3 *RislinkextxmlType `xml:"lnktoextXMfilepastime3,omitempty"`
+
+	Startdate *LastupdateType `xml:"startdate,omitempty"`
+
+	Enddate *LastupdateType `xml:"enddate,omitempty"`
+
+	Infodate *LastupdateType `xml:"infodate,omitempty"`
+
+	// specific Ris idx remarks, reasons for change (descriptions as received with the ris idx)
+	RisidxRemarks *RemarksType `xml:"risidxRemarks,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	// remarks regarding the maintance of the ris idx
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_locationType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_locationType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	ErilocCode *ErilocCodeType `xml:"erilocCode,omitempty"`
+
+	CodeOld *ErilocCodeType `xml:"codeOld,omitempty"`
+
+	RisCode *RisCodeType `xml:"risCode,omitempty"`
+
+	LoCode *LoCodeType `xml:"loCode,omitempty"`
+
+	FwCode *FwCodeType `xml:"fwCode,omitempty"`
+
+	TermCode *TermCodeType `xml:"termCode,omitempty"`
+
+	KmCode *KmCodeType `xml:"kmCode,omitempty"`
+
+	Name struct {
+		Loc *ErilocNameType `xml:"Loc,omitempty"`
+
+		NL *ErilocNameType `xml:"NL,omitempty"`
+
+		DE *ErilocNameType `xml:"DE,omitempty"`
+
+		FR *ErilocNameType `xml:"FR,omitempty"`
+
+		EN *ErilocNameType `xml:"EN,omitempty"`
+	} `xml:"name,omitempty"`
+
+	LocType *LocTypeType `xml:"locType,omitempty"`
+
+	Termname struct {
+		Loc *ErilocNameType `xml:"Loc,omitempty"`
+
+		NL *ErilocNameType `xml:"NL,omitempty"`
+
+		DE *ErilocNameType `xml:"DE,omitempty"`
+
+		FR *ErilocNameType `xml:"FR,omitempty"`
+
+		EN *ErilocNameType `xml:"EN,omitempty"`
+	} `xml:"termname,omitempty"`
+
+	QuayFrom *QuayType `xml:"quayFrom,omitempty"`
+
+	QuayTo *QuayType `xml:"quayTo,omitempty"`
+
+	TermType *LocTypeType `xml:"termType,omitempty"`
+
+	Lat *LatlonType `xml:"lat,omitempty"`
+
+	Lon *LatlonType `xml:"lon,omitempty"`
+
+	// VTS/IVS (code) acting as the default reporting (receiving) point (when departing from this llocation)
+	IvsVTSCode *LocVtsCodeType `xml:"ivsVTSCode,omitempty"`
+
+	// Nr of possible exits (routes) when departing from this location >1 means a reporting or routepoint has to be specified.
+	Exits *LocExitsType `xml:"exits,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_hscodeType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_hscodeType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	HsCode *HsCodeType `xml:"hsCode,omitempty"`
+
+	CodeOld *HsCodeType `xml:"codeOld,omitempty"`
+
+	Name struct {
+		Loc *GoodNameType `xml:"Loc,omitempty"`
+
+		NL *GoodNameType `xml:"NL,omitempty"`
+
+		DE *GoodNameType `xml:"DE,omitempty"`
+
+		FR *GoodNameType `xml:"FR,omitempty"`
+
+		EN *GoodNameType `xml:"EN,omitempty"`
+
+		BG *GoodNameType `xml:"BG,omitempty"`
+
+		CS *GoodNameType `xml:"CS,omitempty"`
+
+		DA *GoodNameType `xml:"DA,omitempty"`
+
+		EL *GoodNameType `xml:"EL,omitempty"`
+
+		ES *GoodNameType `xml:"ES,omitempty"`
+
+		ET *GoodNameType `xml:"ET,omitempty"`
+
+		FI *GoodNameType `xml:"FI,omitempty"`
+
+		HU *GoodNameType `xml:"HU,omitempty"`
+
+		IT *GoodNameType `xml:"IT,omitempty"`
+
+		LT *GoodNameType `xml:"LT,omitempty"`
+
+		LV *GoodNameType `xml:"LV,omitempty"`
+
+		PL *GoodNameType `xml:"PL,omitempty"`
+
+		PT *GoodNameType `xml:"PT,omitempty"`
+
+		RO *GoodNameType `xml:"RO,omitempty"`
+
+		SK *GoodNameType `xml:"SK,omitempty"`
+
+		SL *GoodNameType `xml:"SL,omitempty"`
+
+		SV *GoodNameType `xml:"SV,omitempty"`
+
+		HR *GoodNameType `xml:"HR,omitempty"`
+
+		RU *GoodNameType `xml:"RU,omitempty"`
+
+		SR *GoodNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	NstCode *NstCodeType `xml:"nstCode,omitempty"`
+
+	// English (NST2007) description.
+	NstName *GoodNameType `xml:"nstName,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_adncodeType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_adncodeType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	AdnCode *AdnCodeType `xml:"adnCode,omitempty"`
+
+	CodeOld *AdnCodeType `xml:"codeOld,omitempty"`
+
+	Unnr *UnnrType `xml:"unnr,omitempty"`
+
+	AdnClass *AdnClassType `xml:"adnClass,omitempty"`
+
+	AdnClassif *AdnClassType `xml:"adnClassif,omitempty"`
+
+	ImoClass *AdnClassType `xml:"imoClass,omitempty"`
+
+	PackGrp *PackGrpType `xml:"packGrp,omitempty"`
+
+	Name struct {
+		Loc *GoodDgsNameType `xml:"Loc,omitempty"`
+
+		NL *GoodDgsNameType `xml:"NL,omitempty"`
+
+		DE *GoodDgsNameType `xml:"DE,omitempty"`
+
+		FR *GoodDgsNameType `xml:"FR,omitempty"`
+
+		EN *GoodDgsNameType `xml:"EN,omitempty"`
+
+		BG *GoodDgsNameType `xml:"BG,omitempty"`
+
+		CS *GoodDgsNameType `xml:"CS,omitempty"`
+
+		DA *GoodDgsNameType `xml:"DA,omitempty"`
+
+		EL *GoodDgsNameType `xml:"EL,omitempty"`
+
+		ES *GoodDgsNameType `xml:"ES,omitempty"`
+
+		ET *GoodDgsNameType `xml:"ET,omitempty"`
+
+		FI *GoodDgsNameType `xml:"FI,omitempty"`
+
+		HU *GoodDgsNameType `xml:"HU,omitempty"`
+
+		IT *GoodDgsNameType `xml:"IT,omitempty"`
+
+		LT *GoodDgsNameType `xml:"LT,omitempty"`
+
+		LV *GoodDgsNameType `xml:"LV,omitempty"`
+
+		PL *GoodDgsNameType `xml:"PL,omitempty"`
+
+		PT *GoodDgsNameType `xml:"PT,omitempty"`
+
+		RO *GoodDgsNameType `xml:"RO,omitempty"`
+
+		SK *GoodDgsNameType `xml:"SK,omitempty"`
+
+		SL *GoodDgsNameType `xml:"SL,omitempty"`
+
+		SV *GoodDgsNameType `xml:"SV,omitempty"`
+
+		HR *GoodDgsNameType `xml:"HR,omitempty"`
+
+		RU *GoodDgsNameType `xml:"RU,omitempty"`
+
+		SR *GoodDgsNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Syn struct {
+		Loc *GoodSynType `xml:"Loc,omitempty"`
+
+		NL *GoodSynType `xml:"NL,omitempty"`
+
+		DE *GoodSynType `xml:"DE,omitempty"`
+
+		FR *GoodSynType `xml:"FR,omitempty"`
+
+		EN *GoodSynType `xml:"EN,omitempty"`
+
+		BG *GoodSynType `xml:"BG,omitempty"`
+
+		CS *GoodSynType `xml:"CS,omitempty"`
+
+		DA *GoodSynType `xml:"DA,omitempty"`
+
+		EL *GoodSynType `xml:"EL,omitempty"`
+
+		ES *GoodSynType `xml:"ES,omitempty"`
+
+		ET *GoodSynType `xml:"ET,omitempty"`
+
+		FI *GoodSynType `xml:"FI,omitempty"`
+
+		HU *GoodSynType `xml:"HU,omitempty"`
+
+		IT *GoodSynType `xml:"IT,omitempty"`
+
+		LT *GoodSynType `xml:"LT,omitempty"`
+
+		LV *GoodSynType `xml:"LV,omitempty"`
+
+		PL *GoodSynType `xml:"PL,omitempty"`
+
+		PT *GoodSynType `xml:"PT,omitempty"`
+
+		RO *GoodSynType `xml:"RO,omitempty"`
+
+		SK *GoodSynType `xml:"SK,omitempty"`
+
+		SL *GoodSynType `xml:"SL,omitempty"`
+
+		SV *GoodSynType `xml:"SV,omitempty"`
+
+		HR *GoodSynType `xml:"HR,omitempty"`
+
+		RU *GoodSynType `xml:"RU,omitempty"`
+
+		SR *GoodSynType `xml:"SR,omitempty"`
+	} `xml:"syn,omitempty"`
+
+	HsCode *HsCodeType `xml:"hsCode,omitempty"`
+
+	NstCode *NstCodeType `xml:"nstCode,omitempty"`
+
+	// 0, 1, 2, 3, V
+	ConesBulk *ConesType `xml:"conesBulk,omitempty"`
+
+	ConesTank *ConesType `xml:"conesTank,omitempty"`
+
+	ConesCont *ConesType `xml:"conesCont,omitempty"`
+
+	// 0, B, V
+	FlagsBulk *FlagsType `xml:"flagsBulk,omitempty"`
+
+	FlagsTank *FlagsType `xml:"flagsTank,omitempty"`
+
+	WarnCard *WarnCardType `xml:"warnCard,omitempty"`
+
+	WarnId *WarnIdType `xml:"warnId,omitempty"`
+
+	Label1 *AdnLabelType `xml:"label1,omitempty"`
+
+	Label2 *AdnLabelType `xml:"label2,omitempty"`
+
+	Label3 *AdnLabelType `xml:"label3,omitempty"`
+
+	MaxWeightCodeInlandBulkCont *SignalCodeType `xml:"maxWeightCodeInlandBulkCont,omitempty"`
+
+	// max weight in kg
+	MaxWeightInlandBulkCont *WeightType `xml:"maxWeightInlandBulkCont,omitempty"`
+
+	SignalCodeInlandCont *SignalCodeType `xml:"signalCodeInlandCont,omitempty"`
+
+	// min weight in kg
+	MinWeightInlandCont *WeightType `xml:"minWeightInlandCont,omitempty"`
+
+	SignalCodeInlandExcemp *SignalCodeType `xml:"signalCodeInlandExcemp,omitempty"`
+
+	// min weight in kg
+	MinWeightInlandExcemp *WeightType `xml:"minWeightInlandExcemp,omitempty"`
+
+	SignalCodeSeaBulk *SignalCodeType `xml:"signalCodeSeaBulk,omitempty"`
+
+	// min weight in kg
+	MinWeightSeaBulk *WeightType `xml:"minWeightSeaBulk,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_conttypeType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_conttypeType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	ContId *ContIdType `xml:"contId,omitempty"`
+
+	CodeOld *ContIdType `xml:"codeOld,omitempty"`
+
+	// dimensions in cm
+	Length *DimType `xml:"length,omitempty"`
+
+	Width *DimType `xml:"width,omitempty"`
+
+	Height *DimType `xml:"height,omitempty"`
+
+	// empty weight in kg
+	Weight *WeightType `xml:"weight,omitempty"`
+
+	Name struct {
+		Loc *ContNameType `xml:"Loc,omitempty"`
+
+		NL *ContNameType `xml:"NL,omitempty"`
+
+		DE *ContNameType `xml:"DE,omitempty"`
+
+		FR *ContNameType `xml:"FR,omitempty"`
+
+		EN *ContNameType `xml:"EN,omitempty"`
+
+		BG *ContNameType `xml:"BG,omitempty"`
+
+		CS *ContNameType `xml:"CS,omitempty"`
+
+		DA *ContNameType `xml:"DA,omitempty"`
+
+		EL *ContNameType `xml:"EL,omitempty"`
+
+		ES *ContNameType `xml:"ES,omitempty"`
+
+		ET *ContNameType `xml:"ET,omitempty"`
+
+		FI *ContNameType `xml:"FI,omitempty"`
+
+		HU *ContNameType `xml:"HU,omitempty"`
+
+		IT *ContNameType `xml:"IT,omitempty"`
+
+		LT *ContNameType `xml:"LT,omitempty"`
+
+		LV *ContNameType `xml:"LV,omitempty"`
+
+		PL *ContNameType `xml:"PL,omitempty"`
+
+		PT *ContNameType `xml:"PT,omitempty"`
+
+		RO *ContNameType `xml:"RO,omitempty"`
+
+		SK *ContNameType `xml:"SK,omitempty"`
+
+		SL *ContNameType `xml:"SL,omitempty"`
+
+		SV *ContNameType `xml:"SV,omitempty"`
+
+		HR *ContNameType `xml:"HR,omitempty"`
+
+		RU *ContNameType `xml:"RU,omitempty"`
+
+		SR *ContNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_packtypeType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_packtypeType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	PackId *PackIdType `xml:"packId,omitempty"`
+
+	CodeOld *PackIdType `xml:"codeOld,omitempty"`
+
+	Name struct {
+		Loc *PackNameType `xml:"Loc,omitempty"`
+
+		NL *PackNameType `xml:"NL,omitempty"`
+
+		DE *PackNameType `xml:"DE,omitempty"`
+
+		FR *PackNameType `xml:"FR,omitempty"`
+
+		EN *PackNameType `xml:"EN,omitempty"`
+
+		BG *PackNameType `xml:"BG,omitempty"`
+
+		CS *PackNameType `xml:"CS,omitempty"`
+
+		DA *PackNameType `xml:"DA,omitempty"`
+
+		EL *PackNameType `xml:"EL,omitempty"`
+
+		ES *PackNameType `xml:"ES,omitempty"`
+
+		ET *PackNameType `xml:"ET,omitempty"`
+
+		FI *PackNameType `xml:"FI,omitempty"`
+
+		HU *PackNameType `xml:"HU,omitempty"`
+
+		IT *PackNameType `xml:"IT,omitempty"`
+
+		LT *PackNameType `xml:"LT,omitempty"`
+
+		LV *PackNameType `xml:"LV,omitempty"`
+
+		PL *PackNameType `xml:"PL,omitempty"`
+
+		PT *PackNameType `xml:"PT,omitempty"`
+
+		RO *PackNameType `xml:"RO,omitempty"`
+
+		SK *PackNameType `xml:"SK,omitempty"`
+
+		SL *PackNameType `xml:"SL,omitempty"`
+
+		SV *PackNameType `xml:"SV,omitempty"`
+
+		HR *PackNameType `xml:"HR,omitempty"`
+
+		RU *PackNameType `xml:"RU,omitempty"`
+
+		SR *PackNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_shiptypeType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_shiptypeType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	ShipType *ShipTypeType `xml:"shipType,omitempty"`
+
+	CodeOld *ShipTypeType `xml:"codeOld,omitempty"`
+
+	DvkType *DvkTypeType `xml:"dvkType,omitempty"`
+
+	CraftType *CraftTypeType `xml:"craftType,omitempty"`
+
+	// True = transport cominination type, false=single ship
+	Combination *CombinationFlagType `xml:"combination,omitempty"`
+
+	Name struct {
+		Loc *ShiptypeNameType `xml:"Loc,omitempty"`
+
+		NL *ShiptypeNameType `xml:"NL,omitempty"`
+
+		DE *ShiptypeNameType `xml:"DE,omitempty"`
+
+		FR *ShiptypeNameType `xml:"FR,omitempty"`
+
+		EN *ShiptypeNameType `xml:"EN,omitempty"`
+
+		BG *ShiptypeNameType `xml:"BG,omitempty"`
+
+		CS *ShiptypeNameType `xml:"CS,omitempty"`
+
+		DA *ShiptypeNameType `xml:"DA,omitempty"`
+
+		EL *ShiptypeNameType `xml:"EL,omitempty"`
+
+		ES *ShiptypeNameType `xml:"ES,omitempty"`
+
+		ET *ShiptypeNameType `xml:"ET,omitempty"`
+
+		FI *ShiptypeNameType `xml:"FI,omitempty"`
+
+		HU *ShiptypeNameType `xml:"HU,omitempty"`
+
+		IT *ShiptypeNameType `xml:"IT,omitempty"`
+
+		LT *ShiptypeNameType `xml:"LT,omitempty"`
+
+		LV *ShiptypeNameType `xml:"LV,omitempty"`
+
+		PL *ShiptypeNameType `xml:"PL,omitempty"`
+
+		PT *ShiptypeNameType `xml:"PT,omitempty"`
+
+		RO *ShiptypeNameType `xml:"RO,omitempty"`
+
+		SK *ShiptypeNameType `xml:"SK,omitempty"`
+
+		SL *ShiptypeNameType `xml:"SL,omitempty"`
+
+		SV *ShiptypeNameType `xml:"SV,omitempty"`
+
+		HR *ShiptypeNameType `xml:"HR,omitempty"`
+
+		RU *ShiptypeNameType `xml:"RU,omitempty"`
+
+		SR *ShiptypeNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_countryType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_countryType"`
+
+	// UN country ISO code 2 chars. Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	CountryCode *CountryCodeType `xml:"countryCode,omitempty"`
+
+	CodeOld *CountryCodeType `xml:"codeOld,omitempty"`
+
+	CbsCode *CbscountryCodeType `xml:"cbsCode,omitempty"`
+
+	CountryIsoCode3 *CountryCode3Type `xml:"countryIsoCode3,omitempty"`
+
+	CountryIsoNum *CountryIsoNumType `xml:"countryIsoNum,omitempty"`
+
+	LloydsFlag *LloydsflagType `xml:"lloydsFlag,omitempty"`
+
+	Name struct {
+		Loc *CountryNameType `xml:"Loc,omitempty"`
+
+		NL *CountryNameType `xml:"NL,omitempty"`
+
+		DE *CountryNameType `xml:"DE,omitempty"`
+
+		FR *CountryNameType `xml:"FR,omitempty"`
+
+		EN *CountryNameType `xml:"EN,omitempty"`
+
+		BG *CountryNameType `xml:"BG,omitempty"`
+
+		CS *CountryNameType `xml:"CS,omitempty"`
+
+		DA *CountryNameType `xml:"DA,omitempty"`
+
+		EL *CountryNameType `xml:"EL,omitempty"`
+
+		ES *CountryNameType `xml:"ES,omitempty"`
+
+		ET *CountryNameType `xml:"ET,omitempty"`
+
+		FI *CountryNameType `xml:"FI,omitempty"`
+
+		HU *CountryNameType `xml:"HU,omitempty"`
+
+		IT *CountryNameType `xml:"IT,omitempty"`
+
+		LT *CountryNameType `xml:"LT,omitempty"`
+
+		LV *CountryNameType `xml:"LV,omitempty"`
+
+		PL *CountryNameType `xml:"PL,omitempty"`
+
+		PT *CountryNameType `xml:"PT,omitempty"`
+
+		RO *CountryNameType `xml:"RO,omitempty"`
+
+		SK *CountryNameType `xml:"SK,omitempty"`
+
+		SL *CountryNameType `xml:"SL,omitempty"`
+
+		SV *CountryNameType `xml:"SV,omitempty"`
+
+		HR *CountryNameType `xml:"HR,omitempty"`
+
+		RU *CountryNameType `xml:"RU,omitempty"`
+
+		SR *CountryNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Nts_dataType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ nts_dataType"`
+
+	// Just a string (no enum) to return nts data type of the nts_data returned!
+	// reftype already contains datatype.
+	Ntstype *NtstypeType `xml:"ntstype,omitempty"`
+
+	Ntscode *NtsCodeType `xml:"ntscode,omitempty"`
+
+	CodeOld *NtsCodeType `xml:"codeOld,omitempty"`
+
+	Name struct {
+		Loc *NtsNameType `xml:"Loc,omitempty"`
+
+		NL *NtsNameType `xml:"NL,omitempty"`
+
+		DE *NtsNameType `xml:"DE,omitempty"`
+
+		EN *NtsNameType `xml:"EN,omitempty"`
+
+		FR *NtsNameType `xml:"FR,omitempty"`
+
+		BG *NtsNameType `xml:"BG,omitempty"`
+
+		CS *NtsNameType `xml:"CS,omitempty"`
+
+		DA *NtsNameType `xml:"DA,omitempty"`
+
+		EL *NtsNameType `xml:"EL,omitempty"`
+
+		ES *NtsNameType `xml:"ES,omitempty"`
+
+		ET *NtsNameType `xml:"ET,omitempty"`
+
+		FI *NtsNameType `xml:"FI,omitempty"`
+
+		HU *NtsNameType `xml:"HU,omitempty"`
+
+		IT *NtsNameType `xml:"IT,omitempty"`
+
+		LT *NtsNameType `xml:"LT,omitempty"`
+
+		LV *NtsNameType `xml:"LV,omitempty"`
+
+		PL *NtsNameType `xml:"PL,omitempty"`
+
+		PT *NtsNameType `xml:"PT,omitempty"`
+
+		RO *NtsNameType `xml:"RO,omitempty"`
+
+		SK *NtsNameType `xml:"SK,omitempty"`
+
+		SL *NtsNameType `xml:"SL,omitempty"`
+
+		SV *NtsNameType `xml:"SV,omitempty"`
+
+		HR *NtsNameType `xml:"HR,omitempty"`
+
+		RU *NtsNameType `xml:"RU,omitempty"`
+
+		SR *NtsNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Ris_idxReqMutType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ ris_idxReqMutType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	RisidxCode *RisCodeType `xml:"risidxCode,omitempty"`
+
+	CodeOld *RisCodeType `xml:"codeOld,omitempty"`
+
+	UnlocCC *UnlocCCType `xml:"unlocCC,omitempty"`
+
+	UnlocLC *UnlocLCType `xml:"unlocLC,omitempty"`
+
+	WwsectCode *FwCodeType `xml:"wwsectCode,omitempty"`
+
+	Objcode *RisobjCodeType `xml:"objcode,omitempty"`
+
+	Hectomt *KmCodeType `xml:"hectomt,omitempty"`
+
+	Objfunc *RisobjfuncType `xml:"objfunc,omitempty"`
+
+	Objname struct {
+		Loc *RislocNameType `xml:"Loc,omitempty"`
+	} `xml:"objname,omitempty"`
+
+	Locname struct {
+		Loc *RislocNameType `xml:"Loc,omitempty"`
+	} `xml:"locname,omitempty"`
+
+	Wwname struct {
+		Loc *RislocNameType `xml:"Loc,omitempty"`
+	} `xml:"wwname,omitempty"`
+
+	Routename struct {
+		Loc *RislocNameType `xml:"Loc,omitempty"`
+	} `xml:"routename,omitempty"`
+
+	Relrisindex *RisCodeType `xml:"relrisindex,omitempty"`
+
+	Sectionnode *RissectnodeType `xml:"sectionnode,omitempty"`
+
+	Lat *LatlonType `xml:"lat,omitempty"`
+
+	Lon *LatlonType `xml:"lon,omitempty"`
+
+	Relenc *RisrelencType `xml:"relenc,omitempty"`
+
+	Comminfo *RiscomminfoType `xml:"comminfo,omitempty"`
+
+	Gaugeid *RisgaugeidType `xml:"gaugeid,omitempty"`
+
+	Vesselconvlength *DimType `xml:"vesselconvlength,omitempty"`
+
+	Vesselconvbreadth *DimType `xml:"vesselconvbreadth,omitempty"`
+
+	Vesselconvdraught *DimType `xml:"vesselconvdraught,omitempty"`
+
+	Vesselconvairdraught *DimType `xml:"vesselconvairdraught,omitempty"`
+
+	Availablelength *DimType `xml:"availablelength,omitempty"`
+
+	Clearancewidth *DimType `xml:"clearancewidth,omitempty"`
+
+	Availabledepth *DimType `xml:"availabledepth,omitempty"`
+
+	Clearanceheight *DimType `xml:"clearanceheight,omitempty"`
+
+	Applicabilityfromkm *RisapplikmType `xml:"applicabilityfromkm,omitempty"`
+
+	Applicabilitytokm *RisapplikmType `xml:"applicabilitytokm,omitempty"`
+
+	Reflevel1code *RisreflevelcodeType `xml:"reflevel1code,omitempty"`
+
+	Reflevel1value *RisreflevelvalueType `xml:"reflevel1value,omitempty"`
+
+	Reflevel2code *RisreflevelcodeType `xml:"reflevel2code,omitempty"`
+
+	Reflevel2value *RisreflevelvalueType `xml:"reflevel2value,omitempty"`
+
+	Reflevel3code *RisreflevelcodeType `xml:"reflevel3code,omitempty"`
+
+	Reflevel3value *RisreflevelvalueType `xml:"reflevel3value,omitempty"`
+
+	Zeropoint *RiszeropointType `xml:"zeropoint,omitempty"`
+
+	Geodref *RisgeodrefType `xml:"geodref,omitempty"`
+
+	Catoftimesched *RiscatoftimeschedType `xml:"catoftimesched,omitempty"`
+
+	Forshiptype *RisforshiptypeType `xml:"forshiptype,omitempty"`
+
+	Foruseofship *RisuseofshipType `xml:"foruseofship,omitempty"`
+
+	LnktoextXMfiletimesched *RislinkextxmlType `xml:"lnktoextXMfiletimesched,omitempty"`
+
+	LnktoextXMfilepastime *RislinkextxmlType `xml:"lnktoextXMfilepastime,omitempty"`
+
+	Vesselconvlength2 *DimType `xml:"vesselconvlength2,omitempty"`
+
+	Vesselconvbreadth2 *DimType `xml:"vesselconvbreadth2,omitempty"`
+
+	Vesselconvdraught2 *DimType `xml:"vesselconvdraught2,omitempty"`
+
+	Vesselconvairdraught2 *DimType `xml:"vesselconvairdraught2,omitempty"`
+
+	Availablelength2 *DimType `xml:"availablelength2,omitempty"`
+
+	Clearancewidth2 *DimType `xml:"clearancewidth2,omitempty"`
+
+	Availabledepth2 *DimType `xml:"availabledepth2,omitempty"`
+
+	Clearanceheight2 *DimType `xml:"clearanceheight2,omitempty"`
+
+	Vesselconvlength3 *DimType `xml:"vesselconvlength3,omitempty"`
+
+	Vesselconvbreadth3 *DimType `xml:"vesselconvbreadth3,omitempty"`
+
+	Vesselconvdraught3 *DimType `xml:"vesselconvdraught3,omitempty"`
+
+	Vesselconvairdraught3 *DimType `xml:"vesselconvairdraught3,omitempty"`
+
+	Availablelength3 *DimType `xml:"availablelength3,omitempty"`
+
+	Clearancewidth3 *DimType `xml:"clearancewidth3,omitempty"`
+
+	Availabledepth3 *DimType `xml:"availabledepth3,omitempty"`
+
+	Clearanceheight3 *DimType `xml:"clearanceheight3,omitempty"`
+
+	Catoftimesched2 *RiscatoftimeschedType `xml:"catoftimesched2,omitempty"`
+
+	Forshiptype2 *RisforshiptypeType `xml:"forshiptype2,omitempty"`
+
+	Foruseofship2 *RisuseofshipType `xml:"foruseofship2,omitempty"`
+
+	LnktoextXMfiletimesched2 *RislinkextxmlType `xml:"lnktoextXMfiletimesched2,omitempty"`
+
+	LnktoextXMfilepastime2 *RislinkextxmlType `xml:"lnktoextXMfilepastime2,omitempty"`
+
+	Catoftimesched3 *RiscatoftimeschedType `xml:"catoftimesched3,omitempty"`
+
+	Forshiptype3 *RisforshiptypeType `xml:"forshiptype3,omitempty"`
+
+	Foruseofship3 *RisuseofshipType `xml:"foruseofship3,omitempty"`
+
+	LnktoextXMfiletimesched3 *RislinkextxmlType `xml:"lnktoextXMfiletimesched3,omitempty"`
+
+	LnktoextXMfilepastime3 *RislinkextxmlType `xml:"lnktoextXMfilepastime3,omitempty"`
+
+	Startdate *LastupdateType `xml:"startdate,omitempty"`
+
+	Enddate *LastupdateType `xml:"enddate,omitempty"`
+
+	Infodate *LastupdateType `xml:"infodate,omitempty"`
+
+	// specific Ris idx remarks/reasons for change, as received with the ris idx
+	RisidxRemarks *RemarksType `xml:"risidxRemarks,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	// remarks regarding the maintance of the ris idx
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_locationReqMutType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_locationReqMutType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	ErilocCode *ErilocCodeType `xml:"erilocCode,omitempty"`
+
+	CodeOld *ErilocCodeType `xml:"codeOld,omitempty"`
+
+	RisCode *RisCodeType `xml:"risCode,omitempty"`
+
+	LoCode *LoCodeType `xml:"loCode,omitempty"`
+
+	FwCode *FwCodeType `xml:"fwCode,omitempty"`
+
+	TermCode *TermCodeType `xml:"termCode,omitempty"`
+
+	KmCode *KmCodeType `xml:"kmCode,omitempty"`
+
+	Name struct {
+		Loc *ErilocNameType `xml:"Loc,omitempty"`
+
+		NL *ErilocNameType `xml:"NL,omitempty"`
+
+		DE *ErilocNameType `xml:"DE,omitempty"`
+
+		FR *ErilocNameType `xml:"FR,omitempty"`
+
+		EN *ErilocNameType `xml:"EN,omitempty"`
+	} `xml:"name,omitempty"`
+
+	LocType *LocTypeType `xml:"locType,omitempty"`
+
+	Termname struct {
+		Loc *ErilocNameType `xml:"Loc,omitempty"`
+
+		NL *ErilocNameType `xml:"NL,omitempty"`
+
+		DE *ErilocNameType `xml:"DE,omitempty"`
+
+		FR *ErilocNameType `xml:"FR,omitempty"`
+
+		EN *ErilocNameType `xml:"EN,omitempty"`
+	} `xml:"termname,omitempty"`
+
+	QuayFrom *QuayType `xml:"quayFrom,omitempty"`
+
+	QuayTo *QuayType `xml:"quayTo,omitempty"`
+
+	TermType *LocTypeType `xml:"termType,omitempty"`
+
+	Lat *LatlonType `xml:"lat,omitempty"`
+
+	Lon *LatlonType `xml:"lon,omitempty"`
+
+	IvsVTSCode *LocVtsCodeType `xml:"ivsVTSCode,omitempty"`
+
+	Exits *LocExitsType `xml:"exits,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_hscodeReqMutType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_hscodeReqMutType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	HsCode *HsCodeType `xml:"hsCode,omitempty"`
+
+	CodeOld *HsCodeType `xml:"codeOld,omitempty"`
+
+	Name struct {
+		Loc *GoodNameType `xml:"Loc,omitempty"`
+
+		NL *GoodNameType `xml:"NL,omitempty"`
+
+		DE *GoodNameType `xml:"DE,omitempty"`
+
+		FR *GoodNameType `xml:"FR,omitempty"`
+
+		EN *GoodNameType `xml:"EN,omitempty"`
+
+		BG *GoodNameType `xml:"BG,omitempty"`
+
+		CS *GoodNameType `xml:"CS,omitempty"`
+
+		DA *GoodNameType `xml:"DA,omitempty"`
+
+		EL *GoodNameType `xml:"EL,omitempty"`
+
+		ES *GoodNameType `xml:"ES,omitempty"`
+
+		ET *GoodNameType `xml:"ET,omitempty"`
+
+		FI *GoodNameType `xml:"FI,omitempty"`
+
+		HU *GoodNameType `xml:"HU,omitempty"`
+
+		IT *GoodNameType `xml:"IT,omitempty"`
+
+		LT *GoodNameType `xml:"LT,omitempty"`
+
+		LV *GoodNameType `xml:"LV,omitempty"`
+
+		PL *GoodNameType `xml:"PL,omitempty"`
+
+		PT *GoodNameType `xml:"PT,omitempty"`
+
+		RO *GoodNameType `xml:"RO,omitempty"`
+
+		SK *GoodNameType `xml:"SK,omitempty"`
+
+		SL *GoodNameType `xml:"SL,omitempty"`
+
+		SV *GoodNameType `xml:"SV,omitempty"`
+
+		HR *GoodNameType `xml:"HR,omitempty"`
+
+		RU *GoodNameType `xml:"RU,omitempty"`
+
+		SR *GoodNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	NstCode *NstCodeType `xml:"nstCode,omitempty"`
+
+	NstName *GoodNameType `xml:"nstName,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_adncodeReqMutType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_adncodeReqMutType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	AdnCode *AdnCodeType `xml:"adnCode,omitempty"`
+
+	CodeOld *AdnCodeType `xml:"codeOld,omitempty"`
+
+	Unnr *UnnrType `xml:"unnr,omitempty"`
+
+	AdnClass *AdnClassType `xml:"adnClass,omitempty"`
+
+	AdnClassif *AdnClassType `xml:"adnClassif,omitempty"`
+
+	ImoClass *AdnClassType `xml:"imoClass,omitempty"`
+
+	PackGrp *PackGrpType `xml:"packGrp,omitempty"`
+
+	Name struct {
+		Loc *GoodDgsNameType `xml:"Loc,omitempty"`
+
+		NL *GoodDgsNameType `xml:"NL,omitempty"`
+
+		DE *GoodDgsNameType `xml:"DE,omitempty"`
+
+		FR *GoodDgsNameType `xml:"FR,omitempty"`
+
+		EN *GoodDgsNameType `xml:"EN,omitempty"`
+
+		BG *GoodDgsNameType `xml:"BG,omitempty"`
+
+		CS *GoodDgsNameType `xml:"CS,omitempty"`
+
+		DA *GoodDgsNameType `xml:"DA,omitempty"`
+
+		EL *GoodDgsNameType `xml:"EL,omitempty"`
+
+		ES *GoodDgsNameType `xml:"ES,omitempty"`
+
+		ET *GoodDgsNameType `xml:"ET,omitempty"`
+
+		FI *GoodDgsNameType `xml:"FI,omitempty"`
+
+		HU *GoodDgsNameType `xml:"HU,omitempty"`
+
+		IT *GoodDgsNameType `xml:"IT,omitempty"`
+
+		LT *GoodDgsNameType `xml:"LT,omitempty"`
+
+		LV *GoodDgsNameType `xml:"LV,omitempty"`
+
+		PL *GoodDgsNameType `xml:"PL,omitempty"`
+
+		PT *GoodDgsNameType `xml:"PT,omitempty"`
+
+		RO *GoodDgsNameType `xml:"RO,omitempty"`
+
+		SK *GoodDgsNameType `xml:"SK,omitempty"`
+
+		SL *GoodDgsNameType `xml:"SL,omitempty"`
+
+		SV *GoodDgsNameType `xml:"SV,omitempty"`
+
+		HR *GoodDgsNameType `xml:"HR,omitempty"`
+
+		RU *GoodDgsNameType `xml:"RU,omitempty"`
+
+		SR *GoodDgsNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Syn struct {
+		Loc *GoodSynType `xml:"Loc,omitempty"`
+
+		NL *GoodSynType `xml:"NL,omitempty"`
+
+		DE *GoodSynType `xml:"DE,omitempty"`
+
+		FR *GoodSynType `xml:"FR,omitempty"`
+
+		EN *GoodSynType `xml:"EN,omitempty"`
+
+		BG *GoodSynType `xml:"BG,omitempty"`
+
+		CS *GoodSynType `xml:"CS,omitempty"`
+
+		DA *GoodSynType `xml:"DA,omitempty"`
+
+		EL *GoodSynType `xml:"EL,omitempty"`
+
+		ES *GoodSynType `xml:"ES,omitempty"`
+
+		ET *GoodSynType `xml:"ET,omitempty"`
+
+		FI *GoodSynType `xml:"FI,omitempty"`
+
+		HU *GoodSynType `xml:"HU,omitempty"`
+
+		IT *GoodSynType `xml:"IT,omitempty"`
+
+		LT *GoodSynType `xml:"LT,omitempty"`
+
+		LV *GoodSynType `xml:"LV,omitempty"`
+
+		PL *GoodSynType `xml:"PL,omitempty"`
+
+		PT *GoodSynType `xml:"PT,omitempty"`
+
+		RO *GoodSynType `xml:"RO,omitempty"`
+
+		SK *GoodSynType `xml:"SK,omitempty"`
+
+		SL *GoodSynType `xml:"SL,omitempty"`
+
+		SV *GoodSynType `xml:"SV,omitempty"`
+
+		HR *GoodSynType `xml:"HR,omitempty"`
+
+		RU *GoodSynType `xml:"RU,omitempty"`
+
+		SR *GoodSynType `xml:"SR,omitempty"`
+	} `xml:"syn,omitempty"`
+
+	HsCode *HsCodeType `xml:"hsCode,omitempty"`
+
+	NstCode *NstCodeType `xml:"nstCode,omitempty"`
+
+	// 0, 1, 2, 3, V (Inland)
+	ConesBulk *ConesType `xml:"conesBulk,omitempty"`
+
+	ConesTank *ConesType `xml:"conesTank,omitempty"`
+
+	ConesCont *ConesType `xml:"conesCont,omitempty"`
+
+	// 0, B, V (Seagoing)
+	FlagsBulk *FlagsType `xml:"flagsBulk,omitempty"`
+
+	FlagsTank *FlagsType `xml:"flagsTank,omitempty"`
+
+	WarnCard *WarnCardType `xml:"warnCard,omitempty"`
+
+	WarnId *WarnIdType `xml:"warnId,omitempty"`
+
+	Label1 *AdnLabelType `xml:"label1,omitempty"`
+
+	Label2 *AdnLabelType `xml:"label2,omitempty"`
+
+	Label3 *AdnLabelType `xml:"label3,omitempty"`
+
+	MaxWeightCodeInlandBulkCont *SignalCodeType `xml:"maxWeightCodeInlandBulkCont,omitempty"`
+
+	// max weight in kg
+	MaxWeightInlandBulkCont *WeightType `xml:"maxWeightInlandBulkCont,omitempty"`
+
+	SignalCodeInlandCont *SignalCodeType `xml:"signalCodeInlandCont,omitempty"`
+
+	// min weight in kg
+	MinWeightInlandCont *WeightType `xml:"minWeightInlandCont,omitempty"`
+
+	SignalCodeInlandExcemp *SignalCodeType `xml:"signalCodeInlandExcemp,omitempty"`
+
+	// min weight in kg
+	MinWeightInlandExcemp *WeightType `xml:"minWeightInlandExcemp,omitempty"`
+
+	SignalCodeSeaBulk *SignalCodeType `xml:"signalCodeSeaBulk,omitempty"`
+
+	// min weight in kg
+	MinWeightSeaBulk *WeightType `xml:"minWeightSeaBulk,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_conttypeReqMutType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_conttypeReqMutType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	ContId *ContIdType `xml:"contId,omitempty"`
+
+	CodeOld *ContIdType `xml:"codeOld,omitempty"`
+
+	// dimensions in cm
+	Length *DimType `xml:"length,omitempty"`
+
+	Width *DimType `xml:"width,omitempty"`
+
+	Height *DimType `xml:"height,omitempty"`
+
+	// empty weight in kg
+	Weight *DimType `xml:"weight,omitempty"`
+
+	Name struct {
+		Loc *ContNameType `xml:"Loc,omitempty"`
+
+		NL *ContNameType `xml:"NL,omitempty"`
+
+		DE *ContNameType `xml:"DE,omitempty"`
+
+		FR *ContNameType `xml:"FR,omitempty"`
+
+		EN *ContNameType `xml:"EN,omitempty"`
+
+		BG *ContNameType `xml:"BG,omitempty"`
+
+		CS *ContNameType `xml:"CS,omitempty"`
+
+		DA *ContNameType `xml:"DA,omitempty"`
+
+		EL *ContNameType `xml:"EL,omitempty"`
+
+		ES *ContNameType `xml:"ES,omitempty"`
+
+		ET *ContNameType `xml:"ET,omitempty"`
+
+		FI *ContNameType `xml:"FI,omitempty"`
+
+		HU *ContNameType `xml:"HU,omitempty"`
+
+		IT *ContNameType `xml:"IT,omitempty"`
+
+		LT *ContNameType `xml:"LT,omitempty"`
+
+		LV *ContNameType `xml:"LV,omitempty"`
+
+		PL *ContNameType `xml:"PL,omitempty"`
+
+		PT *ContNameType `xml:"PT,omitempty"`
+
+		RO *ContNameType `xml:"RO,omitempty"`
+
+		SK *ContNameType `xml:"SK,omitempty"`
+
+		SL *ContNameType `xml:"SL,omitempty"`
+
+		SV *ContNameType `xml:"SV,omitempty"`
+
+		HR *ContNameType `xml:"HR,omitempty"`
+
+		RU *ContNameType `xml:"RU,omitempty"`
+
+		SR *ContNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_packtypeReqMutType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_packtypeReqMutType"`
+
+	// Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	PackId *PackIdType `xml:"packId,omitempty"`
+
+	CodeOld *PackIdType `xml:"codeOld,omitempty"`
+
+	Name struct {
+		Loc *PackNameType `xml:"Loc,omitempty"`
+
+		NL *PackNameType `xml:"NL,omitempty"`
+
+		DE *PackNameType `xml:"DE,omitempty"`
+
+		FR *PackNameType `xml:"FR,omitempty"`
+
+		EN *PackNameType `xml:"EN,omitempty"`
+
+		BG *PackNameType `xml:"BG,omitempty"`
+
+		CS *PackNameType `xml:"CS,omitempty"`
+
+		DA *PackNameType `xml:"DA,omitempty"`
+
+		EL *PackNameType `xml:"EL,omitempty"`
+
+		ES *PackNameType `xml:"ES,omitempty"`
+
+		ET *PackNameType `xml:"ET,omitempty"`
+
+		FI *PackNameType `xml:"FI,omitempty"`
+
+		HU *PackNameType `xml:"HU,omitempty"`
+
+		IT *PackNameType `xml:"IT,omitempty"`
+
+		LT *PackNameType `xml:"LT,omitempty"`
+
+		LV *PackNameType `xml:"LV,omitempty"`
+
+		PL *PackNameType `xml:"PL,omitempty"`
+
+		PT *PackNameType `xml:"PT,omitempty"`
+
+		RO *PackNameType `xml:"RO,omitempty"`
+
+		SK *PackNameType `xml:"SK,omitempty"`
+
+		SL *PackNameType `xml:"SL,omitempty"`
+
+		SV *PackNameType `xml:"SV,omitempty"`
+
+		HR *PackNameType `xml:"HR,omitempty"`
+
+		RU *PackNameType `xml:"RU,omitempty"`
+
+		SR *PackNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_shiptypeReqMutType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_shiptypeReqMutType"`
+
+	// UN rec 28. Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	ShipType *ShipTypeType `xml:"shipType,omitempty"`
+
+	CodeOld *ShipTypeType `xml:"codeOld,omitempty"`
+
+	DvkType *DvkTypeType `xml:"dvkType,omitempty"`
+
+	CraftType *CraftTypeType `xml:"craftType,omitempty"`
+
+	// True = transport cominination type, false=single ship
+	Combination *CombinationFlagType `xml:"combination,omitempty"`
+
+	Name struct {
+		Loc *ShiptypeNameType `xml:"Loc,omitempty"`
+
+		NL *ShiptypeNameType `xml:"NL,omitempty"`
+
+		DE *ShiptypeNameType `xml:"DE,omitempty"`
+
+		FR *ShiptypeNameType `xml:"FR,omitempty"`
+
+		EN *ShiptypeNameType `xml:"EN,omitempty"`
+
+		BG *ShiptypeNameType `xml:"BG,omitempty"`
+
+		CS *ShiptypeNameType `xml:"CS,omitempty"`
+
+		DA *ShiptypeNameType `xml:"DA,omitempty"`
+
+		EL *ShiptypeNameType `xml:"EL,omitempty"`
+
+		ES *ShiptypeNameType `xml:"ES,omitempty"`
+
+		ET *ShiptypeNameType `xml:"ET,omitempty"`
+
+		FI *ShiptypeNameType `xml:"FI,omitempty"`
+
+		HU *ShiptypeNameType `xml:"HU,omitempty"`
+
+		IT *ShiptypeNameType `xml:"IT,omitempty"`
+
+		LT *ShiptypeNameType `xml:"LT,omitempty"`
+
+		LV *ShiptypeNameType `xml:"LV,omitempty"`
+
+		PL *ShiptypeNameType `xml:"PL,omitempty"`
+
+		PT *ShiptypeNameType `xml:"PT,omitempty"`
+
+		RO *ShiptypeNameType `xml:"RO,omitempty"`
+
+		SK *ShiptypeNameType `xml:"SK,omitempty"`
+
+		SL *ShiptypeNameType `xml:"SL,omitempty"`
+
+		SV *ShiptypeNameType `xml:"SV,omitempty"`
+
+		HR *ShiptypeNameType `xml:"HR,omitempty"`
+
+		RU *ShiptypeNameType `xml:"RU,omitempty"`
+
+		SR *ShiptypeNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type Eri_countryReqMutType struct {
+	XMLName xml.Name `xml:"http://rwsreftool/ eri_countryReqMutType"`
+
+	// UN country ISO code 2 chars. Be sure to edit, change the basic Simpletypes, dont edit any of the (sub)elements from here!!!
+	CountryCode *CountryCodeType `xml:"countryCode,omitempty"`
+
+	CodeOld *CountryCodeType `xml:"codeOld,omitempty"`
+
+	CbsCode *CbscountryCodeType `xml:"cbsCode,omitempty"`
+
+	CountryIsoCode3 *CountryCode3Type `xml:"countryIsoCode3,omitempty"`
+
+	CountryIsoNum *CountryIsoNumType `xml:"countryIsoNum,omitempty"`
+
+	LloydsFlag *LloydsflagType `xml:"lloydsFlag,omitempty"`
+
+	Name struct {
+		Loc *CountryNameType `xml:"Loc,omitempty"`
+
+		NL *CountryNameType `xml:"NL,omitempty"`
+
+		DE *CountryNameType `xml:"DE,omitempty"`
+
+		FR *CountryNameType `xml:"FR,omitempty"`
+
+		EN *CountryNameType `xml:"EN,omitempty"`
+
+		BG *CountryNameType `xml:"BG,omitempty"`
+
+		CS *CountryNameType `xml:"CS,omitempty"`
+
+		DA *CountryNameType `xml:"DA,omitempty"`
+
+		EL *CountryNameType `xml:"EL,omitempty"`
+
+		ES *CountryNameType `xml:"ES,omitempty"`
+
+		ET *CountryNameType `xml:"ET,omitempty"`
+
+		FI *CountryNameType `xml:"FI,omitempty"`
+
+		HU *CountryNameType `xml:"HU,omitempty"`
+
+		IT *CountryNameType `xml:"IT,omitempty"`
+
+		LT *CountryNameType `xml:"LT,omitempty"`
+
+		LV *CountryNameType `xml:"LV,omitempty"`
+
+		PL *CountryNameType `xml:"PL,omitempty"`
+
+		PT *CountryNameType `xml:"PT,omitempty"`
+
+		RO *CountryNameType `xml:"RO,omitempty"`
+
+		SK *CountryNameType `xml:"SK,omitempty"`
+
+		SL *CountryNameType `xml:"SL,omitempty"`
+
+		SV *CountryNameType `xml:"SV,omitempty"`
+
+		HR *CountryNameType `xml:"HR,omitempty"`
+
+		RU *CountryNameType `xml:"RU,omitempty"`
+
+		SR *CountryNameType `xml:"SR,omitempty"`
+	} `xml:"name,omitempty"`
+
+	Source *SourceType `xml:"source,omitempty"`
+
+	Remarks *RemarksType `xml:"remarks,omitempty"`
+
+	Version *RefrecVersionType `xml:"version,omitempty"`
+
+	Erased *ErasedType `xml:"erased,omitempty"`
+
+	Lastupdate *LastupdateType `xml:"lastupdate,omitempty"`
+}
+
+type RefWeb interface {
+
+	// Error can be either of the following types:
+	//
+	//   - exception
+
+	MatchByCode(request *MatchByCode) (*MatchByCodeResponse, error)
+
+	// Error can be either of the following types:
+	//
+	//   - exception
+
+	MatchByName(request *MatchByName) (*MatchByNameResponse, error)
+
+	// Error can be either of the following types:
+	//
+	//   - exception
+
+	GetMutations(request *GetMutations) (*GetMutationsResponse, error)
+
+	// Error can be either of the following types:
+	//
+	//   - exception
+
+	GetDataXML(request *GetDataXML) (*GetDataXMLResponse, error)
+
+	// Error can be either of the following types:
+	//
+	//   - exception
+
+	GetRisDataXML(request *GetRisDataXML) (*GetRisDataXMLResponse, error)
+
+	// Error can be either of the following types:
+	//
+	//   - exception
+
+	MutateDataXML(request *MutateDataXML) (*MutateDataXMLResponse, error)
+
+	// Error can be either of the following types:
+	//
+	//   - exception
+
+	RequestMutationXML(request *RequestMutationXML) (*RequestMutationXMLResponse, error)
+}
+
+type refWeb struct {
+	client *soap.SOAPClient
+}
+
+func NewRefWeb(client *soap.SOAPClient) RefWeb {
+	return &refWeb{
+		client: client,
+	}
+}
+
+func (service *refWeb) MatchByCode(request *MatchByCode) (*MatchByCodeResponse, error) {
+	response := new(MatchByCodeResponse)
+	err := service.client.Call("", request, response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}
+
+func (service *refWeb) MatchByName(request *MatchByName) (*MatchByNameResponse, error) {
+	response := new(MatchByNameResponse)
+	err := service.client.Call("", request, response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}
+
+func (service *refWeb) GetMutations(request *GetMutations) (*GetMutationsResponse, error) {
+	response := new(GetMutationsResponse)
+	err := service.client.Call("", request, response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}
+
+func (service *refWeb) GetDataXML(request *GetDataXML) (*GetDataXMLResponse, error) {
+	response := new(GetDataXMLResponse)
+	err := service.client.Call("", request, response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}
+
+func (service *refWeb) GetRisDataXML(request *GetRisDataXML) (*GetRisDataXMLResponse, error) {
+	response := new(GetRisDataXMLResponse)
+	err := service.client.Call("", request, response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}
+
+func (service *refWeb) MutateDataXML(request *MutateDataXML) (*MutateDataXMLResponse, error) {
+	response := new(MutateDataXMLResponse)
+	err := service.client.Call("", request, response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}
+
+func (service *refWeb) RequestMutationXML(request *RequestMutationXML) (*RequestMutationXMLResponse, error) {
+	response := new(RequestMutationXMLResponse)
+	err := service.client.Call("", request, response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/soap/ifaf/service.go	Tue Jan 15 10:07:10 2019 +0100
@@ -0,0 +1,935 @@
+// This is Free Software under GNU Affero General Public License v >= 3.0
+// without warranty, see README.md and license for details.
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// License-Filename: LICENSES/AGPL-3.0.txt
+//
+// Copyright (C) 2018 by via donau
+//   – Österreichische Wasserstraßen-Gesellschaft mbH
+// Software engineering by Intevation GmbH
+//
+// Author(s):
+//  * Raimund Renkert <raimund.renkert@intevation.de>
+
+package ifaf
+
+import (
+	"crypto/tls"
+	"encoding/xml"
+	"time"
+
+	"github.com/jackc/pgx/pgtype"
+
+	"gemma.intevation.de/gemma/pkg/soap"
+)
+
+// against "unused imports"
+var _ time.Time
+var _ xml.Name
+
+type Get_bottleneck_fa struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/fairwayavailability/3.0 get_bottleneck_fa"`
+
+	Bottleneck_id *ArrayOfString `xml:"bottleneck_id,omitempty"`
+
+	Period *RequestedPeriod `xml:"period,omitempty"`
+}
+
+type Get_bottleneck_faResponse struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/fairwayavailability/3.0 get_bottleneck_faResponse"`
+
+	Get_bottleneck_faResult *ArrayOfFairwayAvailability `xml:"get_bottleneck_faResult,omitempty"`
+}
+
+type Get_stretch_fa struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/fairwayavailability/3.0 get_stretch_fa"`
+
+	ISRS *ArrayOfISRSPair `xml:"ISRS,omitempty"`
+
+	Period *RequestedPeriod `xml:"period,omitempty"`
+}
+
+type Get_stretch_faResponse struct {
+	XMLName xml.Name `xml:"http://www.ris.eu/fairwayavailability/3.0 get_stretch_faResponse"`
+
+	Get_stretch_faResult *ArrayOfFairwayAvailability `xml:"get_stretch_faResult,omitempty"`
+}
+
+type ArrayOfFairwayAvailability struct {
+	FairwayAvailability []*FairwayAvailability `xml:"FairwayAvailability,omitempty"`
+}
+
+type FairwayAvailability struct {
+	Bottleneck_id string `xml:"bottleneck_id,omitempty"`
+
+	SURDAT time.Time `xml:"SURDAT,omitempty"`
+
+	POSITION *PositionEnum `xml:"POSITION,omitempty"`
+
+	Reference_values *ArrayOfReferenceValue `xml:"Reference_values,omitempty"`
+
+	AdditionalData *ArrayOfKeyValuePair `xml:"AdditionalData,omitempty"`
+
+	Critical bool `xml:"Critical,omitempty"`
+
+	Bottleneck_PDFs *ArrayOfPdfInfo `xml:"Bottleneck_PDFs,omitempty"`
+
+	Effective_fairway_availability *ArrayOfEffectiveFairwayAvailability `xml:"Effective_fairway_availability,omitempty"`
+
+	Date_Info time.Time `xml:"Date_Info,omitempty"`
+
+	Source string `xml:"Source,omitempty"`
+}
+
+type ArrayOfPdfInfo struct {
+	PdfInfo []*PdfInfo `xml:"PdfInfo,omitempty"`
+}
+
+type PdfInfo struct {
+	ProfilePdfFilename string `xml:"ProfilePdfFilename,omitempty"`
+
+	ProfilePdfURL string `xml:"ProfilePdfURL,omitempty"`
+
+	PDF_Generation_Date time.Time `xml:"PDF_Generation_Date,omitempty"`
+
+	Source string `xml:"Source,omitempty"`
+}
+
+type ArrayOfEffectiveFairwayAvailability struct {
+	EffectiveFairwayAvailability []*EffectiveFairwayAvailability `xml:"EffectiveFairwayAvailability,omitempty"`
+}
+
+type EffectiveFairwayAvailability struct {
+	Available_depth_value int32 `xml:"Available_depth_value,omitempty"`
+
+	Available_width_value int32 `xml:"Available_width_value,omitempty"`
+
+	Water_level_value int32 `xml:"Water_level_value,omitempty"`
+
+	Measure_date time.Time `xml:"Measure_date,omitempty"`
+
+	Measure_type *MeasureType `xml:"Measure_type,omitempty"`
+
+	Source string `xml:"Source,omitempty"`
+
+	Level_of_Service *LosEnum `xml:"Level_of_Service,omitempty"`
+
+	Forecast_generation_time pgtype.Timestamp `xml:"Forecast_generation_time,omitempty"`
+
+	Value_lifetime time.Time `xml:"Value_lifetime,omitempty"`
+}
+
+type ArrayOfReferenceValue struct {
+	ReferenceValue []*ReferenceValue `xml:"ReferenceValue,omitempty"`
+}
+
+type ReferenceValue struct {
+	Fairway_depth int32 `xml:"fairway_depth,omitempty"`
+
+	Fairway_width int32 `xml:"fairway_width,omitempty"`
+
+	Fairway_radius int32 `xml:"fairway_radius,omitempty"`
+
+	Shallowest_spot_Lat float64 `xml:"Shallowest_spot_Lat,omitempty"`
+
+	Shallowest_spot_Lon float64 `xml:"Shallowest_spot_Lon,omitempty"`
+
+	Level_of_Service *LosEnum `xml:"Level_of_Service,omitempty"`
+}
+
+type ErrorCode string
+
+const (
+
+	// <summary> Description: message type not supported, Explanation:
+	// web service does not support the requested message type
+	// </summary>
+	ErrorCodeE010 ErrorCode = "e010"
+
+	// <summary> Description: syntax error in request, Explanation:
+	// request violates the schema for requests </summary>
+	ErrorCodeE100 ErrorCode = "e100"
+
+	// <summary> Description: incorrect message type, Explanation: given
+	// message type is not known </summary>
+	ErrorCodeE110 ErrorCode = "e110"
+
+	// <summary> Description: incorrect type-specific parameters,
+	// Explanation: type-specific parameters are erroneous </summary>
+	ErrorCodeE120 ErrorCode = "e120"
+
+	// <summary> Description: operation not known, Explanation: the
+	// requested operation is unknown </summary>
+	ErrorCodeE200 ErrorCode = "e200"
+
+	// <summary> Description: requested method or operation is not
+	// implemented </summary>
+	ErrorCodeE210 ErrorCode = "e210"
+
+	// <summary> Description: data source unavailable, Explanation: data
+	// source of the web service for is temporarily unavailable
+	// </summary>
+	ErrorCodeE300 ErrorCode = "e300"
+
+	// <summary> Description: too many results for request, Explanation:
+	// server is unable to handle number of results </summary>
+	ErrorCodeE310 ErrorCode = "e310"
+
+	// <summary> Description: unexpected or other error
+	// </summary>
+	ErrorCodeE999 ErrorCode = "e999"
+)
+
+type CountryCode string
+
+const (
+	CountryCodeAF CountryCode = "AF"
+
+	CountryCodeAX CountryCode = "AX"
+
+	CountryCodeAL CountryCode = "AL"
+
+	CountryCodeDZ CountryCode = "DZ"
+
+	CountryCodeAS CountryCode = "AS"
+
+	CountryCodeAD CountryCode = "AD"
+
+	CountryCodeAO CountryCode = "AO"
+
+	CountryCodeAI CountryCode = "AI"
+
+	CountryCodeAQ CountryCode = "AQ"
+
+	CountryCodeAG CountryCode = "AG"
+
+	CountryCodeAR CountryCode = "AR"
+
+	CountryCodeAM CountryCode = "AM"
+
+	CountryCodeAW CountryCode = "AW"
+
+	CountryCodeAU CountryCode = "AU"
+
+	CountryCodeAT CountryCode = "AT"
+
+	CountryCodeAZ CountryCode = "AZ"
+
+	CountryCodeBS CountryCode = "BS"
+
+	CountryCodeBH CountryCode = "BH"
+
+	CountryCodeBD CountryCode = "BD"
+
+	CountryCodeBB CountryCode = "BB"
+
+	CountryCodeBY CountryCode = "BY"
+
+	CountryCodeBE CountryCode = "BE"
+
+	CountryCodeBZ CountryCode = "BZ"
+
+	CountryCodeBJ CountryCode = "BJ"
+
+	CountryCodeBM CountryCode = "BM"
+
+	CountryCodeBT CountryCode = "BT"
+
+	CountryCodeBO CountryCode = "BO"
+
+	CountryCodeBQ CountryCode = "BQ"
+
+	CountryCodeBA CountryCode = "BA"
+
+	CountryCodeBW CountryCode = "BW"
+
+	CountryCodeBV CountryCode = "BV"
+
+	CountryCodeBR CountryCode = "BR"
+
+	CountryCodeIO CountryCode = "IO"
+
+	CountryCodeBN CountryCode = "BN"
+
+	CountryCodeBG CountryCode = "BG"
+
+	CountryCodeBF CountryCode = "BF"
+
+	CountryCodeBI CountryCode = "BI"
+
+	CountryCodeCV CountryCode = "CV"
+
+	CountryCodeKH CountryCode = "KH"
+
+	CountryCodeCM CountryCode = "CM"
+
+	CountryCodeCA CountryCode = "CA"
+
+	CountryCodeKY CountryCode = "KY"
+
+	CountryCodeCF CountryCode = "CF"
+
+	CountryCodeTD CountryCode = "TD"
+
+	CountryCodeCL CountryCode = "CL"
+
+	CountryCodeCN CountryCode = "CN"
+
+	CountryCodeCX CountryCode = "CX"
+
+	CountryCodeCC CountryCode = "CC"
+
+	CountryCodeCO CountryCode = "CO"
+
+	CountryCodeKM CountryCode = "KM"
+
+	CountryCodeCG CountryCode = "CG"
+
+	CountryCodeCD CountryCode = "CD"
+
+	CountryCodeCK CountryCode = "CK"
+
+	CountryCodeCR CountryCode = "CR"
+
+	CountryCodeCI CountryCode = "CI"
+
+	CountryCodeHR CountryCode = "HR"
+
+	CountryCodeCU CountryCode = "CU"
+
+	CountryCodeCW CountryCode = "CW"
+
+	CountryCodeCY CountryCode = "CY"
+
+	CountryCodeCZ CountryCode = "CZ"
+
+	CountryCodeDK CountryCode = "DK"
+
+	CountryCodeDJ CountryCode = "DJ"
+
+	CountryCodeDM CountryCode = "DM"
+
+	CountryCodeDO CountryCode = "DO"
+
+	CountryCodeEC CountryCode = "EC"
+
+	CountryCodeEG CountryCode = "EG"
+
+	CountryCodeSV CountryCode = "SV"
+
+	CountryCodeGQ CountryCode = "GQ"
+
+	CountryCodeER CountryCode = "ER"
+
+	CountryCodeEE CountryCode = "EE"
+
+	CountryCodeET CountryCode = "ET"
+
+	CountryCodeFK CountryCode = "FK"
+
+	CountryCodeFO CountryCode = "FO"
+
+	CountryCodeFJ CountryCode = "FJ"
+
+	CountryCodeFI CountryCode = "FI"
+
+	CountryCodeFR CountryCode = "FR"
+
+	CountryCodeGF CountryCode = "GF"
+
+	CountryCodePF CountryCode = "PF"
+
+	CountryCodeTF CountryCode = "TF"
+
+	CountryCodeGA CountryCode = "GA"
+
+	CountryCodeGM CountryCode = "GM"
+
+	CountryCodeGE CountryCode = "GE"
+
+	CountryCodeDE CountryCode = "DE"
+
+	CountryCodeGH CountryCode = "GH"
+
+	CountryCodeGI CountryCode = "GI"
+
+	CountryCodeGR CountryCode = "GR"
+
+	CountryCodeGL CountryCode = "GL"
+
+	CountryCodeGD CountryCode = "GD"
+
+	CountryCodeGP CountryCode = "GP"
+
+	CountryCodeGU CountryCode = "GU"
+
+	CountryCodeGT CountryCode = "GT"
+
+	CountryCodeGG CountryCode = "GG"
+
+	CountryCodeGN CountryCode = "GN"
+
+	CountryCodeGW CountryCode = "GW"
+
+	CountryCodeGY CountryCode = "GY"
+
+	CountryCodeHT CountryCode = "HT"
+
+	CountryCodeHM CountryCode = "HM"
+
+	CountryCodeVA CountryCode = "VA"
+
+	CountryCodeHN CountryCode = "HN"
+
+	CountryCodeHK CountryCode = "HK"
+
+	CountryCodeHU CountryCode = "HU"
+
+	CountryCodeIS CountryCode = "IS"
+
+	CountryCodeIN CountryCode = "IN"
+
+	CountryCodeID CountryCode = "ID"
+
+	CountryCodeIR CountryCode = "IR"
+
+	CountryCodeIQ CountryCode = "IQ"
+
+	CountryCodeIE CountryCode = "IE"
+
+	CountryCodeIM CountryCode = "IM"
+
+	CountryCodeIL CountryCode = "IL"
+
+	CountryCodeIT CountryCode = "IT"
+
+	CountryCodeJM CountryCode = "JM"
+
+	CountryCodeJP CountryCode = "JP"
+
+	CountryCodeJE CountryCode = "JE"
+
+	CountryCodeJO CountryCode = "JO"
+
+	CountryCodeKZ CountryCode = "KZ"
+
+	CountryCodeKE CountryCode = "KE"
+
+	CountryCodeKI CountryCode = "KI"
+
+	CountryCodeKP CountryCode = "KP"
+
+	CountryCodeKR CountryCode = "KR"
+
+	CountryCodeKW CountryCode = "KW"
+
+	CountryCodeKG CountryCode = "KG"
+
+	CountryCodeLA CountryCode = "LA"
+
+	CountryCodeLV CountryCode = "LV"
+
+	CountryCodeLB CountryCode = "LB"
+
+	CountryCodeLS CountryCode = "LS"
+
+	CountryCodeLR CountryCode = "LR"
+
+	CountryCodeLY CountryCode = "LY"
+
+	CountryCodeLI CountryCode = "LI"
+
+	CountryCodeLT CountryCode = "LT"
+
+	CountryCodeLU CountryCode = "LU"
+
+	CountryCodeMO CountryCode = "MO"
+
+	CountryCodeMK CountryCode = "MK"
+
+	CountryCodeMG CountryCode = "MG"
+
+	CountryCodeMW CountryCode = "MW"
+
+	CountryCodeMY CountryCode = "MY"
+
+	CountryCodeMV CountryCode = "MV"
+
+	CountryCodeML CountryCode = "ML"
+
+	CountryCodeMT CountryCode = "MT"
+
+	CountryCodeMH CountryCode = "MH"
+
+	CountryCodeMQ CountryCode = "MQ"
+
+	CountryCodeMR CountryCode = "MR"
+
+	CountryCodeMU CountryCode = "MU"
+
+	CountryCodeYT CountryCode = "YT"
+
+	CountryCodeMX CountryCode = "MX"
+
+	CountryCodeFM CountryCode = "FM"
+
+	CountryCodeMD CountryCode = "MD"
+
+	CountryCodeMC CountryCode = "MC"
+
+	CountryCodeMN CountryCode = "MN"
+
+	CountryCodeME CountryCode = "ME"
+
+	CountryCodeMS CountryCode = "MS"
+
+	CountryCodeMA CountryCode = "MA"
+
+	CountryCodeMZ CountryCode = "MZ"
+
+	CountryCodeMM CountryCode = "MM"
+
+	CountryCodeNA CountryCode = "NA"
+
+	CountryCodeNR CountryCode = "NR"
+
+	CountryCodeNP CountryCode = "NP"
+
+	CountryCodeNL CountryCode = "NL"
+
+	CountryCodeNC CountryCode = "NC"
+
+	CountryCodeNZ CountryCode = "NZ"
+
+	CountryCodeNI CountryCode = "NI"
+
+	CountryCodeNE CountryCode = "NE"
+
+	CountryCodeNG CountryCode = "NG"
+
+	CountryCodeNU CountryCode = "NU"
+
+	CountryCodeNF CountryCode = "NF"
+
+	CountryCodeMP CountryCode = "MP"
+
+	CountryCodeNO CountryCode = "NO"
+
+	CountryCodeOM CountryCode = "OM"
+
+	CountryCodePK CountryCode = "PK"
+
+	CountryCodePW CountryCode = "PW"
+
+	CountryCodePS CountryCode = "PS"
+
+	CountryCodePA CountryCode = "PA"
+
+	CountryCodePG CountryCode = "PG"
+
+	CountryCodePY CountryCode = "PY"
+
+	CountryCodePE CountryCode = "PE"
+
+	CountryCodePH CountryCode = "PH"
+
+	CountryCodePN CountryCode = "PN"
+
+	CountryCodePL CountryCode = "PL"
+
+	CountryCodePT CountryCode = "PT"
+
+	CountryCodePR CountryCode = "PR"
+
+	CountryCodeQA CountryCode = "QA"
+
+	CountryCodeRE CountryCode = "RE"
+
+	CountryCodeRO CountryCode = "RO"
+
+	CountryCodeRU CountryCode = "RU"
+
+	CountryCodeRW CountryCode = "RW"
+
+	CountryCodeBL CountryCode = "BL"
+
+	CountryCodeSH CountryCode = "SH"
+
+	CountryCodeKN CountryCode = "KN"
+
+	CountryCodeLC CountryCode = "LC"
+
+	CountryCodeMF CountryCode = "MF"
+
+	CountryCodePM CountryCode = "PM"
+
+	CountryCodeVC CountryCode = "VC"
+
+	CountryCodeWS CountryCode = "WS"
+
+	CountryCodeSM CountryCode = "SM"
+
+	CountryCodeST CountryCode = "ST"
+
+	CountryCodeSA CountryCode = "SA"
+
+	CountryCodeSN CountryCode = "SN"
+
+	CountryCodeRS CountryCode = "RS"
+
+	CountryCodeSC CountryCode = "SC"
+
+	CountryCodeSL CountryCode = "SL"
+
+	CountryCodeSG CountryCode = "SG"
+
+	CountryCodeSX CountryCode = "SX"
+
+	CountryCodeSK CountryCode = "SK"
+
+	CountryCodeSI CountryCode = "SI"
+
+	CountryCodeSB CountryCode = "SB"
+
+	CountryCodeSO CountryCode = "SO"
+
+	CountryCodeZA CountryCode = "ZA"
+
+	CountryCodeGS CountryCode = "GS"
+
+	CountryCodeSS CountryCode = "SS"
+
+	CountryCodeES CountryCode = "ES"
+
+	CountryCodeLK CountryCode = "LK"
+
+	CountryCodeSD CountryCode = "SD"
+
+	CountryCodeSR CountryCode = "SR"
+
+	CountryCodeSJ CountryCode = "SJ"
+
+	CountryCodeSZ CountryCode = "SZ"
+
+	CountryCodeSE CountryCode = "SE"
+
+	CountryCodeCH CountryCode = "CH"
+
+	CountryCodeSY CountryCode = "SY"
+
+	CountryCodeTW CountryCode = "TW"
+
+	CountryCodeTJ CountryCode = "TJ"
+
+	CountryCodeTZ CountryCode = "TZ"
+
+	CountryCodeTH CountryCode = "TH"
+
+	CountryCodeTL CountryCode = "TL"
+
+	CountryCodeTG CountryCode = "TG"
+
+	CountryCodeTK CountryCode = "TK"
+
+	CountryCodeTO CountryCode = "TO"
+
+	CountryCodeTT CountryCode = "TT"
+
+	CountryCodeTN CountryCode = "TN"
+
+	CountryCodeTR CountryCode = "TR"
+
+	CountryCodeTM CountryCode = "TM"
+
+	CountryCodeTC CountryCode = "TC"
+
+	CountryCodeTV CountryCode = "TV"
+
+	CountryCodeUG CountryCode = "UG"
+
+	CountryCodeUA CountryCode = "UA"
+
+	CountryCodeAE CountryCode = "AE"
+
+	CountryCodeGB CountryCode = "GB"
+
+	CountryCodeUS CountryCode = "US"
+
+	CountryCodeUM CountryCode = "UM"
+
+	CountryCodeUY CountryCode = "UY"
+
+	CountryCodeUZ CountryCode = "UZ"
+
+	CountryCodeVU CountryCode = "VU"
+
+	CountryCodeVE CountryCode = "VE"
+
+	CountryCodeVN CountryCode = "VN"
+
+	CountryCodeVG CountryCode = "VG"
+
+	CountryCodeVI CountryCode = "VI"
+
+	CountryCodeWF CountryCode = "WF"
+
+	CountryCodeEH CountryCode = "EH"
+
+	CountryCodeYE CountryCode = "YE"
+
+	CountryCodeZM CountryCode = "ZM"
+
+	CountryCodeZW CountryCode = "ZW"
+)
+
+type CoverageEnum string
+
+const (
+	CoverageEnumCrossProfiles CoverageEnum = "CrossProfiles"
+
+	CoverageEnumLongitudinalProfiles CoverageEnum = "LongitudinalProfiles"
+
+	CoverageEnumFairway CoverageEnum = "Fairway"
+
+	CoverageEnumRiver CoverageEnum = "River"
+
+	CoverageEnumRiverBanks CoverageEnum = "RiverBanks"
+)
+
+type DepthReferenceEnum string
+
+const (
+	DepthReferenceEnumNAP DepthReferenceEnum = "NAP"
+
+	DepthReferenceEnumKP DepthReferenceEnum = "KP"
+
+	DepthReferenceEnumFZP DepthReferenceEnum = "FZP"
+
+	DepthReferenceEnumADR DepthReferenceEnum = "ADR"
+
+	DepthReferenceEnumTAW DepthReferenceEnum = "TAW"
+
+	DepthReferenceEnumPUL DepthReferenceEnum = "PUL"
+
+	DepthReferenceEnumNGM DepthReferenceEnum = "NGM"
+
+	DepthReferenceEnumETRS DepthReferenceEnum = "ETRS"
+
+	DepthReferenceEnumPOT DepthReferenceEnum = "POT"
+
+	DepthReferenceEnumLDC DepthReferenceEnum = "LDC"
+
+	DepthReferenceEnumHDC DepthReferenceEnum = "HDC"
+
+	DepthReferenceEnumZPG DepthReferenceEnum = "ZPG"
+
+	DepthReferenceEnumGLW DepthReferenceEnum = "GLW"
+
+	DepthReferenceEnumHSW DepthReferenceEnum = "HSW"
+
+	DepthReferenceEnumLNW DepthReferenceEnum = "LNW"
+
+	DepthReferenceEnumHNW DepthReferenceEnum = "HNW"
+
+	DepthReferenceEnumIGN DepthReferenceEnum = "IGN"
+
+	DepthReferenceEnumWGS DepthReferenceEnum = "WGS"
+
+	DepthReferenceEnumRN DepthReferenceEnum = "RN"
+
+	DepthReferenceEnumHBO DepthReferenceEnum = "HBO"
+)
+
+type LimitingFactorEnum string
+
+const (
+	LimitingFactorEnumDepth LimitingFactorEnum = "depth"
+
+	LimitingFactorEnumWidth LimitingFactorEnum = "width"
+
+	LimitingFactorEnumCurveRadius LimitingFactorEnum = "curveRadius"
+)
+
+type LosEnum string
+
+const (
+	LosEnumNotAvailable LosEnum = "NotAvailable"
+
+	LosEnumLOS1 LosEnum = "LOS1"
+
+	LosEnumLOS2 LosEnum = "LOS2"
+
+	LosEnumLOS3 LosEnum = "LOS3"
+)
+
+type MaterialEnum string
+
+const (
+	MaterialEnumGravel MaterialEnum = "Gravel"
+
+	MaterialEnumRocky MaterialEnum = "Rocky"
+
+	MaterialEnumStone MaterialEnum = "Stone"
+
+	MaterialEnumAndesite MaterialEnum = "Andesite"
+
+	MaterialEnumSleazyAndesite MaterialEnum = "SleazyAndesite"
+
+	MaterialEnumSandyGravel MaterialEnum = "SandyGravel"
+
+	MaterialEnumMarl MaterialEnum = "Marl"
+
+	MaterialEnumSand MaterialEnum = "Sand"
+
+	MaterialEnumSarmatianLimestone MaterialEnum = "SarmatianLimestone"
+
+	MaterialEnumSandstonePeaks MaterialEnum = "SandstonePeaks"
+
+	MaterialEnumRoughSandyGravel MaterialEnum = "RoughSandyGravel"
+)
+
+type MeasureType string
+
+const (
+	MeasureTypeMeasured MeasureType = "Measured"
+
+	MeasureTypeForecasted MeasureType = "Forecasted"
+
+	MeasureTypeMinimumGuaranteed MeasureType = "MinimumGuaranteed"
+)
+
+type PositionEnum string
+
+const (
+	PositionEnumRedBuoy PositionEnum = "RedBuoy"
+
+	PositionEnumGreenBuoy PositionEnum = "GreenBuoy"
+
+	PositionEnumRightBank PositionEnum = "RightBank"
+
+	PositionEnumLeftBank PositionEnum = "LeftBank"
+
+	PositionEnumMiddle PositionEnum = "Middle"
+
+	PositionEnumAll PositionEnum = "All"
+)
+
+type SurtypEnum string
+
+const (
+	SurtypEnumMultibeam SurtypEnum = "Multibeam"
+
+	SurtypEnumSinglebeam SurtypEnum = "Singlebeam"
+
+	SurtypEnumADCP SurtypEnum = "ADCP"
+
+	SurtypEnumInspectionTour SurtypEnum = "InspectionTour"
+)
+
+type Error struct {
+	Detail string `xml:"detail,omitempty"`
+
+	Error_code *ErrorCode `xml:"error_code,omitempty"`
+}
+
+type ArrayOfMaterial struct {
+	Material []*MaterialEnum `xml:"Material,omitempty"`
+}
+
+type ArrayOfKeyValuePair struct {
+	KeyValuePair []*KeyValuePair `xml:"KeyValuePair,omitempty"`
+}
+
+type KeyValuePair struct {
+	Key string `xml:"Key,omitempty"`
+
+	Value string `xml:"Value,omitempty"`
+}
+
+type ArrayOfISRSPair struct {
+	ISRSPair []*ISRSPair `xml:"ISRSPair,omitempty"`
+}
+
+type ISRSPair struct {
+	FromISRS string `xml:"fromISRS,omitempty"`
+
+	ToISRS string `xml:"toISRS,omitempty"`
+}
+
+type RequestedPeriod struct {
+	Date_start time.Time `xml:"http://www.ris.eu/wamos/common/3.0 Date_start,omitempty"`
+
+	Date_end time.Time `xml:"http://www.ris.eu/wamos/common/3.0 Date_end,omitempty"`
+
+	Value_interval int32 `xml:"http://www.ris.eu/wamos/common/3.0 Value_interval,omitempty"`
+}
+
+type ArrayOfString struct {
+	String []string `xml:"http://www.ris.eu/wamos/common/3.0 string,omitempty"`
+}
+
+type Char int32
+
+type Duration *Duration
+
+type Guid string
+
+type IFairwayAvailabilityService interface {
+
+	// Error can be either of the following types:
+	//
+	//   - ErrorFault
+
+	Get_bottleneck_fa(request *Get_bottleneck_fa) (*Get_bottleneck_faResponse, error)
+
+	// Error can be either of the following types:
+	//
+	//   - ErrorFault
+
+	Get_stretch_fa(request *Get_stretch_fa) (*Get_stretch_faResponse, error)
+}
+
+type FairwayAvailabilityService struct {
+	client *soap.SOAPClient
+}
+
+func NewFairwayAvailabilityService(url string, tls bool, auth *soap.BasicAuth) *FairwayAvailabilityService {
+	if url == "" {
+		url = ""
+	}
+	client := soap.NewSOAPClient(url, tls, auth)
+	return &FairwayAvailabilityService{
+		client: client,
+	}
+}
+
+func NewFairwayAvailabilityServiceWithTLS(url string, tlsCfg *tls.Config, auth *soap.BasicAuth) *FairwayAvailabilityService {
+	if url == "" {
+		url = ""
+	}
+	client := soap.NewSOAPClientWithTLSConfig(url, tlsCfg, auth)
+
+	return &FairwayAvailabilityService{
+		client: client,
+	}
+}
+
+func (service *FairwayAvailabilityService) Get_bottleneck_fa(request *Get_bottleneck_fa) (*Get_bottleneck_faResponse, error) {
+	response := new(Get_bottleneck_faResponse)
+	err := service.client.Call("http://www.ris.eu/fairwayavailability/3.0/IFairwayAvailabilityService/get_bottleneck_fa", request, response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}
+
+func (service *FairwayAvailabilityService) Get_stretch_fa(request *Get_stretch_fa) (*Get_stretch_faResponse, error) {
+	response := new(Get_stretch_faResponse)
+	err := service.client.Call("http://www.ris.eu/fairwayavailability/3.0/IFairwayAvailabilityService/get_stretch_fa", request, response)
+	if err != nil {
+		return nil, err
+	}
+
+	return response, nil
+}
--- a/pkg/wfs/capabilities.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/wfs/capabilities.go	Tue Jan 15 10:07:10 2019 +0100
@@ -15,6 +15,7 @@
 
 import (
 	"encoding/xml"
+	"errors"
 	"io"
 	"regexp"
 	"strconv"
@@ -22,15 +23,19 @@
 	"golang.org/x/net/html/charset"
 )
 
+// Keyword stores a value.
 type Keyword struct {
 	XMLName xml.Name `xml:"http://www.opengis.net/ows/1.1 Keyword"`
 	Value   string   `xml:",cdata"`
 }
+
+// Keywords stores a list of keywords.
 type Keywords struct {
 	XMLName  xml.Name  `xml:"http://www.opengis.net/ows/1.1 Keywords"`
 	Keywords []Keyword `xml:"Keyword"`
 }
 
+// ServiceIdentification contains meta informations about a WFS.
 type ServiceIdentification struct {
 	XMLName            xml.Name `xml:"http://www.opengis.net/ows/1.1 ServiceIdentification"`
 	Title              string
@@ -40,48 +45,58 @@
 	ServiceTypeVersion string
 }
 
+// Get stores the link to the GET method
 type Get struct {
 	XMLName xml.Name `xml:"http://www.opengis.net/ows/1.1 Get"`
 	HRef    string   `xml:"http://www.w3.org/1999/xlink href,attr"`
 }
 
+// Post stores the link to the POST method.
 type Post struct {
 	XMLName xml.Name `xml:"http://www.opengis.net/ows/1.1 Post"`
 	HRef    string   `xml:"http://www.w3.org/1999/xlink href,attr"`
 }
 
+// HTTP is a container for HTTP methods.
 type HTTP struct {
 	XMLName xml.Name `xml:"http://www.opengis.net/ows/1.1 HTTP"`
 	Get     *Get     `xml:"Get"`
 	Post    *Post    `xml:"Post"`
 }
 
+// DCP wraps the HTTP container.
 type DCP struct {
 	XMLName xml.Name `xml:"http://www.opengis.net/ows/1.1 DCP"`
 	HTTP    HTTP     `xml:"HTTP"`
 }
 
+// Value is a simple string value.
 type Value struct {
 	XMLName xml.Name `xml:"http://www.opengis.net/ows/1.1 Value"`
 	Value   string   `xml:",cdata"`
 }
 
+// AllowedValues is list positive list of values.
 type AllowedValues struct {
 	XMLName xml.Name `xml:"http://www.opengis.net/ows/1.1 AllowedValues"`
 	Values  []Value  `xml:"Value"`
 }
 
+// Parameter is a named parameter with a list of allowed values.
 type Parameter struct {
 	XMLName       xml.Name      `xml:"http://www.opengis.net/ows/1.1 Parameter"`
 	Name          string        `xml:"name,attr"`
 	AllowedValues AllowedValues `xml:"AllowedValues"`
 }
 
+// DefaultValue is the default value of a constraint.
 type DefaultValue struct {
 	XMLName xml.Name `xml:"http://www.opengis.net/ows/1.1 DefaultValue"`
 	Value   string   `xml:",cdata"`
 }
 
+// Constraint is a named constraint with a list of allowed values
+// and a default value.
 type Constraint struct {
 	XMLName       xml.Name      `xml:"http://www.opengis.net/ows/1.1 Constraint"`
 	Name          string        `xml:"name,attr"`
@@ -89,6 +104,7 @@
 	DefaultValue  *DefaultValue `xml:"DefaultValue"`
 }
 
+// Operation contains informations of a WFS operation.
 type Operation struct {
 	XMLName     xml.Name      `xml:"http://www.opengis.net/ows/1.1 Operation"`
 	Name        string        `xml:"name,attr"`
@@ -97,18 +113,21 @@
 	Constraints []*Constraint `xml:"Constraint"`
 }
 
+// OperationsMetadata is list of operations and constraints.
 type OperationsMetadata struct {
 	XMLName     xml.Name      `xml:"http://www.opengis.net/ows/1.1 OperationsMetadata"`
 	Operations  []*Operation  `xml:"Operation"`
 	Constraints []*Constraint `xml:"Constraint"`
 }
 
+// WGS84BoundingBox is a bounding box feature type in WGS84.
 type WGS84BoundingBox struct {
 	XMLName     xml.Name `xml:"http://www.opengis.net/ows/1.1 WGS84BoundingBox"`
 	LowerCorner string   `xml:"LowerCorner"`
 	UpperCorner string   `xml:"UpperCorner"`
 }
 
+// FeatureType is layer served by the WFS:
 type FeatureType struct {
 	XMLName          xml.Name          `xml:"http://www.opengis.net/wfs/2.0 FeatureType"`
 	Name             string            `xml:"Name"`
@@ -134,6 +153,7 @@
 	Namespaces       []xml.Name        `xml:"-"`
 }
 
+// UnmarshalXML implements xml.Unmarshaler for better namespace handling.
 func (ft *FeatureType) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
 	// Filter out the namespaces for this feature type.
 	var ns []xml.Name
@@ -151,11 +171,13 @@
 	return nil
 }
 
+// FeatureTypeList is the list of layers served by the WFS.
 type FeatureTypeList struct {
 	XMLName      xml.Name       `xml:"http://www.opengis.net/wfs/2.0 FeatureTypeList"`
 	FeatureTypes []*FeatureType `xml:"FeatureType"`
 }
 
+// Capabilities is the top level metadata struct.
 type Capabilities struct {
 	XMLName xml.Name `xml:"http://www.opengis.net/wfs/2.0 WFS_Capabilities"`
 
@@ -166,6 +188,8 @@
 	FeatureTypeList       FeatureTypeList
 }
 
+// FindOperation searches the capabilities for a specifc operation.
+// Returns nil if not found.
 func (c *Capabilities) FindOperation(name string) *Operation {
 	for _, op := range c.OperationsMetadata.Operations {
 		if op.Name == name {
@@ -175,8 +199,9 @@
 	return nil
 }
 
-func (o *Operation) SupportsHits() bool {
-	for _, p := range o.Parameters {
+// SupportsHits checks if a operation supports the hits request.
+func (op *Operation) SupportsHits() bool {
+	for _, p := range op.Parameters {
 		if p.Name == "resultType" {
 			for _, av := range p.AllowedValues.Values {
 				if av.Value == "hits" {
@@ -188,8 +213,9 @@
 	return false
 }
 
-func (o *Operation) SupportsOutputFormat(formats ...string) bool {
-	for _, p := range o.Parameters {
+// SupportsOutputFormat checks if one of the given formats is supported.
+func (op *Operation) SupportsOutputFormat(formats ...string) bool {
+	for _, p := range op.Parameters {
 		if p.Name == "outputFormat" {
 			for _, av := range p.AllowedValues.Values {
 				for _, f := range formats {
@@ -203,8 +229,10 @@
 	return false
 }
 
-func (o *Operation) FeaturesPerPage() (int, bool) {
-	for _, c := range o.Constraints {
+// FeaturesPerPage returns the number of features per page.
+// Returns if paging is not supported by the operation.
+func (op *Operation) FeaturesPerPage() (int, bool) {
+	for _, c := range op.Constraints {
 		if c.Name == "CountDefault" {
 			if c.DefaultValue != nil {
 				if v, err := strconv.Atoi(c.DefaultValue.Value); err == nil {
@@ -222,6 +250,8 @@
 	return 0, false
 }
 
+// FindFeatureType searches the layers for a given name.
+// Returns nil if not found.
 func (c *Capabilities) FindFeatureType(name string) *FeatureType {
 	for _, ft := range c.FeatureTypeList.FeatureTypes {
 		if ft.Name == name {
@@ -231,6 +261,8 @@
 	return nil
 }
 
+// FindParameter searches for named parameter. Returns nil
+// if not found.
 func (op *Operation) FindParameter(name string) *Parameter {
 	for _, p := range op.Parameters {
 		if p.Name == name {
@@ -240,7 +272,8 @@
 	return nil
 }
 
-const WFS2_0_0 = "2.0.0"
+// WFS200 is dotted version string of version 2.0.0.
+const WFS200 = "2.0.0"
 
 var versionRe = regexp.MustCompile(`(\d+)\.(\d+)\.(\d+)`)
 
@@ -294,6 +327,8 @@
 	return a
 }
 
+// HighestWFSVersion figures out the highest supported WFS version.
+// Defaults to def.
 func (c *Capabilities) HighestWFSVersion(def string) string {
 	op := c.FindOperation("GetCapabilities")
 	if op == nil {
@@ -315,6 +350,22 @@
 	return max
 }
 
+var (
+	// ErrInvalidCRS is returned if a given string is not valid CRS URN.
+	ErrInvalidCRS = errors.New("Invalid CRS string")
+	crsRe         = regexp.MustCompile(`urn:ogc:def:crs:EPSG:[^:]*:(\d+)`)
+)
+
+// CRSToEPSG extracts the EPSG code from a given CRS URN string.
+func CRSToEPSG(s string) (int, error) {
+	m := crsRe.FindStringSubmatch(s)
+	if m == nil {
+		return 0, ErrInvalidCRS
+	}
+	return strconv.Atoi(m[1])
+}
+
+// ParseCapabilities constructs a capabilities document from an io.Reader.
 func ParseCapabilities(r io.Reader) (*Capabilities, error) {
 
 	decoder := xml.NewDecoder(r)
--- a/pkg/wfs/download.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/wfs/download.go	Tue Jan 15 10:07:10 2019 +0100
@@ -1,4 +1,4 @@
-// This is Free Software under GNU Affero General Public License v >= 3.0
+// This is Free Software under GNU Affero General Public License v >= 3.0.Reader.
 // without warranty, see README.md and license for details.
 //
 // SPDX-License-Identifier: AGPL-3.0-or-later
@@ -28,13 +28,20 @@
 )
 
 var (
-	ErrNoSuchFeatureType        = errors.New("No such feature type")
-	ErrGetFeatureNotSupported   = errors.New("GetFeature not supported")
-	ErrMethodGetNotSupported    = errors.New("GET not supported")
-	ErrNoNumberMatchedFound     = errors.New("No numberMatched attribute found")
+	// ErrNoSuchFeatureType is returned when a feature is not supported.
+	ErrNoSuchFeatureType = errors.New("No such feature type")
+	// ErrGetFeatureNotSupported is returned when GetFeature is not supported.
+	ErrGetFeatureNotSupported = errors.New("GetFeature not supported")
+	// ErrMethodGetNotSupported is returned when the GET is not supported.
+	ErrMethodGetNotSupported = errors.New("GET not supported")
+	// ErrNoNumberMatchedFound is returned if feature count cannot be extracted.
+	ErrNoNumberMatchedFound = errors.New("No numberMatched attribute found")
+	// ErrOutputFormatNotSupported is returned if a output format is
+	// not supported.
 	ErrOutputFormatNotSupported = errors.New("Output format not supported")
 )
 
+// GetCapabilities downloads a capabilities document for a given URL.
 func GetCapabilities(capURL string) (*Capabilities, error) {
 
 	base, err := url.Parse(capURL)
@@ -95,6 +102,8 @@
 	return *result.NumberMatched, nil
 }
 
+// GetFeaturesGET constructs a list of URLs to get features
+// for a given feature type from a WFS servers.
 func GetFeaturesGET(
 	caps *Capabilities,
 	featureTypeName,
@@ -133,7 +142,7 @@
 		return nil, ErrOutputFormatNotSupported
 	}
 
-	wfsVersion := caps.HighestWFSVersion(WFS2_0_0)
+	wfsVersion := caps.HighestWFSVersion(WFS200)
 
 	featuresPerPage, supportsPaging := op.FeaturesPerPage()
 
@@ -157,7 +166,7 @@
 	}
 
 	var downloadURLs []string
-	wfs2 := !versionIsLess(wfsVersion, WFS2_0_0)
+	wfs2 := !versionIsLess(wfsVersion, WFS200)
 
 	addNS := func(v url.Values) {
 		if len(feature.Namespaces) == 0 {
@@ -250,6 +259,8 @@
 	return handler(resp.Body)
 }
 
+// DownloadURLs does the actual GetFeature requests downloads
+// and hands the resulting io.Readers over to the given handler.
 func DownloadURLs(urls []string, handler func(io.Reader) error) error {
 	for _, url := range urls {
 		if err := downloadURL(url, handler); err != nil {
--- a/pkg/wfs/rawfeaturecollection.go	Tue Jan 15 09:54:46 2019 +0100
+++ b/pkg/wfs/rawfeaturecollection.go	Tue Jan 15 10:07:10 2019 +0100
@@ -18,6 +18,8 @@
 	"io"
 )
 
+// RawFeatureCollection is a template for a feature collection
+// returned by a WFS server.
 type RawFeatureCollection struct {
 	CRS *struct {
 		Properties struct {
@@ -33,6 +35,7 @@
 	} `json:"features"`
 }
 
+// ParseRawFeatureCollection turns a io.Reader into raw feature collection.
 func ParseRawFeatureCollection(r io.Reader) (*RawFeatureCollection, error) {
 	rfc := new(RawFeatureCollection)
 	if err := json.NewDecoder(r).Decode(rfc); err != nil {
--- a/schema/auth.sql	Tue Jan 15 09:54:46 2019 +0100
+++ b/schema/auth.sql	Tue Jan 15 10:07:10 2019 +0100
@@ -77,8 +77,7 @@
 DECLARE the_table varchar;
 BEGIN
     FOREACH the_table IN ARRAY ARRAY[
-       -- 'gauge_measurements', XXX Removed since this table has currently no
-    -- staging
+        'gauge_measurements',
         'sections_stretches',
         'waterway_profiles',
         'fairway_dimensions',
@@ -143,6 +142,10 @@
 -- Staging area
 -- TODO: add all relevant tables here
 
+CREATE POLICY same_country ON waterway.gauge_measurements
+    FOR ALL TO waterway_admin
+    USING ((fk_gauge_id).country_code = users.current_user_country());
+
 CREATE POLICY responsibility_area ON waterway.bottlenecks
     FOR ALL TO waterway_admin
     USING (utm_covers(area));
@@ -151,6 +154,34 @@
     FOR ALL TO waterway_admin
     USING (utm_covers(area));
 
+-- Imports and import config
+
+CREATE POLICY same_country ON waterway.imports
+    FOR ALL TO waterway_admin
+    USING (users.current_user_country() = (
+        SELECT country FROM users.list_users lu
+            WHERE lu.username = imports.username));
+ALTER table waterway.imports ENABLE ROW LEVEL SECURITY;
+
+-- The job running the import queue is running as sys_admin and login users
+-- with that role should see all imports anyhow
+CREATE POLICY read_all ON waterway.imports
+    FOR SELECT TO sys_admin
+    USING (true);
+CREATE POLICY update_all ON waterway.imports
+    FOR UPDATE TO sys_admin
+    USING (true);
+
+CREATE POLICY parent_allowed ON waterway.import_logs
+    FOR ALL TO waterway_admin
+    USING (import_id IN (SELECT id FROM waterway.imports));
+ALTER table waterway.import_logs ENABLE ROW LEVEL SECURITY;
+
+CREATE POLICY parent_allowed ON waterway.track_imports
+    FOR ALL TO waterway_admin
+    USING (import_id IN (SELECT id FROM waterway.imports));
+ALTER table waterway.track_imports ENABLE ROW LEVEL SECURITY;
+
 CREATE POLICY import_configuration_policy ON waterway.import_configuration
     FOR ALL TO waterway_admin
     USING (
@@ -158,6 +189,10 @@
             SELECT country FROM users.list_users lu
             WHERE lu.username = waterway.import_configuration.username));
 
+CREATE POLICY import_configuration_policy_sys_admin ON waterway.import_configuration
+    FOR ALL TO sys_admin
+    USING (true);
+
 ALTER table waterway.import_configuration ENABLE ROW LEVEL SECURITY;
 
 COMMIT;
--- a/schema/demo-data/published_services.sql	Tue Jan 15 09:54:46 2019 +0100
+++ b/schema/demo-data/published_services.sql	Tue Jan 15 10:07:10 2019 +0100
@@ -16,4 +16,6 @@
     ('waterway.distance_marks_geoserver'),
     ('waterway.sounding_results_contour_lines_geoserver'),
     ('waterway.bottlenecks'),
-    ('waterway.bottleneck_overview')
+    ('waterway.bottleneck_overview'),
+    ('waterway.waterway_axis'),
+    ('waterway.waterway_area')
--- a/schema/gemma.sql	Tue Jan 15 09:54:46 2019 +0100
+++ b/schema/gemma.sql	Tue Jan 15 10:07:10 2019 +0100
@@ -139,9 +139,13 @@
 );
 
 CREATE TABLE levels_of_service (
-    level_of_service smallint PRIMARY KEY
+    level_of_service smallint PRIMARY KEY,
+    name varchar(4)
 );
-INSERT INTO levels_of_service VALUES (1), (2), (3);
+INSERT INTO levels_of_service (
+    level_of_service,
+    name
+) VALUES (1, 'LOS1'), (2, 'LOS2'), (3, 'LOS3');
 
 CREATE TABLE riverbed_materials (
     material varchar PRIMARY KEY
@@ -264,14 +268,12 @@
         id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
         fk_gauge_id isrs NOT NULL REFERENCES gauges,
         measure_date timestamp with time zone NOT NULL,
-        -- PRIMARY KEY (fk_gauge_id, measure_date),
         country_code char(2) NOT NULL REFERENCES countries,
         -- TODO: add relations to stuff provided as enumerations
         sender varchar NOT NULL, -- "from" attribute from DRC
         language_code varchar NOT NULL REFERENCES language_codes,
         date_issue timestamp with time zone NOT NULL,
-        -- reference_code varchar(4) NOT NULL REFERENCES depth_references,
-        -- XXX: Always ZPG?
+        reference_code varchar(4) NOT NULL REFERENCES depth_references,
         water_level double precision NOT NULL,
         predicted boolean NOT NULL,
         is_waterlevel boolean NOT NULL,
@@ -281,11 +283,11 @@
         value_max double precision, -- XXX: NOT NULL if predicted?
         --- TODO: Add a double range type for checking?
         date_info timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
-        source_organization varchar NOT NULL -- "originator"
-        -- XXX removed staging done temporarily. Currently imported raw data is
-        -- not staged. When importing approved gauge measurements uncomment this
-        -- and add policy to allow select on this table for waterway_admin
-        -- staging_done boolean NOT NULL DEFAULT false
+        source_organization varchar NOT NULL, -- "originator"
+        staging_done boolean NOT NULL DEFAULT false,
+        -- So we can have a staged and
+        -- a non-staged fk_gauge_id/measure_date pair.
+        UNIQUE (fk_gauge_id, measure_date, staging_done)
     )
     CREATE TRIGGER gauge_measurements_date_info
         BEFORE UPDATE ON gauge_measurements
@@ -298,7 +300,8 @@
         objnam varchar NOT NULL,
         nobjnam varchar
     )
-    CREATE UNIQUE INDEX ON waterway_axis ((ST_GeoHash(wtwaxs, 23)))
+    -- TODO: @tom: Why did you choose this index kind?
+    -- CREATE UNIQUE INDEX ON waterway_axis ((ST_GeoHash(wtwaxs, 23)))
 
     -- This table allows linkage between 1D ISRS location codes and 2D space
     -- e.g. for cutting bottleneck area out of waterway area based on virtual
@@ -554,10 +557,19 @@
                 ON UPDATE CASCADE,
         kind varchar NOT NULL,
         send_email boolean NOT NULL DEFAULT false,
-        auto_accept boolean NOT NULL DEFAULT false,
         cron varchar,
         url  varchar
     )
+
+    CREATE TABLE import_configuration_attributes (
+        import_configuration_id int NOT NULL
+          REFERENCES import_configuration(id)
+            ON DELETE CASCADE
+            ON UPDATE CASCADE,
+        k VARCHAR NOT NULL,
+        v TEXT NOT NULL,
+        UNIQUE (import_configuration_id, k)
+    )
 ;
 
 -- Configure primary keys for geoserver views
@@ -575,11 +587,13 @@
 );
 
 CREATE TABLE waterway.imports (
-    id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
-    state waterway.import_state NOT NULL DEFAULT 'queued',
-    enqueued timestamp NOT NULL DEFAULT now(),
-    kind  varchar NOT NULL,
-    username varchar NOT NULL
+    id        int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
+    state     waterway.import_state NOT NULL DEFAULT 'queued',
+    kind      varchar   NOT NULL,
+    enqueued  timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    due       timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    trys_left int,
+    username  varchar   NOT NULL
         REFERENCES internal.user_profiles(username)
             ON DELETE CASCADE
             ON UPDATE CASCADE,
@@ -588,9 +602,8 @@
             ON DELETE SET NULL
             ON UPDATE CASCADE,
     send_email boolean NOT NULL DEFAULT false,
-    auto_accept boolean NOT NULL DEFAULT false,
-    data TEXT,
-    summary TEXT
+    data       TEXT,
+    summary    TEXT
 );
 
 CREATE INDEX enqueued_idx ON waterway.imports(enqueued, state);
--- a/schema/isrs_functions.sql	Tue Jan 15 09:54:46 2019 +0100
+++ b/schema/isrs_functions.sql	Tue Jan 15 10:07:10 2019 +0100
@@ -1,3 +1,17 @@
+-- This is Free Software under GNU Affero General Public License v >= 3.0
+-- without warranty, see README.md and license for details.
+
+-- SPDX-License-Identifier: AGPL-3.0-or-later
+-- License-Filename: LICENSES/AGPL-3.0.txt
+
+-- Copyright (C) 2018 by via donau
+--   – Österreichische Wasserstraßen-Gesellschaft mbH
+-- Software engineering by Intevation GmbH
+
+-- Author(s):
+--  * Tom Gottfried <tom@intevation.de>
+--  * Sascha Wilde <wilde@intevation.de>
+
 -- Clip an area to a stretch given by a pair of ISRS location codes.
 -- Uses the table waterway.distance_marks_virtual to map ISRS location codes
 -- to their geo-location and the table waterway.waterway_axis to retrieve
@@ -49,7 +63,7 @@
                         FROM axis) AS lines,
                     (SELECT ST_Collect(from_point.geom, to_point.geom) AS pts
                         FROM from_point, to_point) AS points
-                WHERE ST_Covers(lines.line, points.pts)),
+                WHERE ST_Covers(ST_Buffer(lines.line, 0.0001), points.pts)),
         axis_substring AS (
             -- Use linear referencing to clip axis between distance marks
             SELECT ST_LineSubstring(