diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..ac11628315211606f2a1533aad4915c62a08364b --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,45 @@ +image: alpine:latest + +js_doc: + image: node:latest + stage: build + before_script: + - npm install -g jsdoc + script: + - mkdir -p docs/JSDoc + - jsdoc -c jsdoc.json + artifacts: + paths: + - docs/JSDoc + only: + - master + +php_doc: + image: php:7.4-cli + stage: build + before_script: + - apt update && apt install wget -y + - wget https://www.phpdoc.org/phpDocumentor.phar + script: + - mkdir -p docs/phpDoc + - php phpDocumentor.phar -c phpdoc.dist.xml + after_script: + - rm phpDocumentor.phar + artifacts: + paths: + - docs/phpDoc + only: + - master + +pages: + stage: deploy + script: + - mkdir .public + - echo "SecDoc Code Dokumentation

SecDoc Code Dokumentation

" > .public/index.html + - cp -r docs/* .public + - mv .public public + artifacts: + paths: + - public + only: + - master diff --git a/assets/ajax/DBCon.class.php b/assets/ajax/DBCon.class.php index 4744fe600f1e984fc2c2d28f2477f737d5ea5769..ff22e3b1d4b13c82bc2fc7eae10ee77f6b5269de 100755 --- a/assets/ajax/DBCon.class.php +++ b/assets/ajax/DBCon.class.php @@ -1623,7 +1623,7 @@ FROM ebene_rollen INNER JOIN tom_rollen ON ebene_rollen.RoleID = tom_rollen.RoleID INNER JOIN toms ON tom_rollen.TOMID = toms.Identifier - LEFT OUTER JOIN toms_desc ON toms.Identifier LIKE toms_desc.Identifier || '%' + LEFT OUTER JOIN toms_desc ON toms.Identifier LIKE toms_desc.Identifier || '.%' WHERE EbeneID = ? ORDER BY toms.Identifier ASC;"); $sth->execute([$tier]); $tomRows = $sth->fetchAll(); @@ -1631,7 +1631,7 @@ if(count($tomRows) === 0) { $sth = $this->pdo->prepare("SELECT DISTINCT toms.Identifier AS Identifier, Category, Subcategory, Title, toms.Description AS Description, Risklevel, toms_desc.Description AS CatDesc, Objective AS CatObjective, Delimit AS CatDelimit, toms_desc.URL AS CatURL FROM toms - LEFT OUTER JOIN toms_desc ON toms.Identifier LIKE toms_desc.Identifier || '%' + LEFT OUTER JOIN toms_desc ON toms.Identifier LIKE toms_desc.Identifier || '.%' ORDER BY toms.Identifier ASC;"); $sth->execute(); $tomRows = $sth->fetchAll(); @@ -1640,7 +1640,7 @@ else { $sth = $this->pdo->prepare("SELECT DISTINCT toms.Identifier AS Identifier, Category, Subcategory, Title, toms.Description AS Description, Risklevel, toms_desc.Description AS CatDesc, Objective AS CatObjective, Delimit AS CatDelimit, toms_desc.URL AS CatURL FROM toms - LEFT OUTER JOIN toms_desc ON toms.Identifier LIKE toms_desc.Identifier || '%' + LEFT OUTER JOIN toms_desc ON toms.Identifier LIKE toms_desc.Identifier || '.%' ORDER BY toms.Identifier ASC;"); $sth->execute(); $tomRows = $sth->fetchAll(); diff --git a/docs/JSDoc/dsbview.js.html b/docs/JSDoc/dsbview.js.html deleted file mode 100644 index d4d5d1f536f7ebbf1d7e383abe063da690022751..0000000000000000000000000000000000000000 --- a/docs/JSDoc/dsbview.js.html +++ /dev/null @@ -1,464 +0,0 @@ - - - - - JSDoc: Source: dsbview.js - - - - - - - - - - -
- -

Source: dsbview.js

- - - - - - -
-
-
/**
- * dsbview.js - Funktionen für die DSB-Ansicht
- *
- * @file Umfasst die Funktionalitäten der DSB-Ansicht
- *
- * @requires assets/js/mains.js
- * @requires assets/js/datatables.min.js
- * @requires assets/js/datatables_german.json
- *
- * @author Thorsten Küfer <thorsten.kuefer@uni-muenster.de>
- * @author Dustin Gawron <dustin.gawron@uni-muenster.de>
- * @copyright (c) 2018-2020 Westfälische Wilhelms-Universität Münster
- * @license AGPL-3.0-or-later <https://www.gnu.org/licenses/agpl.html>
- */
-
- /**
-  * Aktuell ausgewählte Ebene
-  * @global
-  * @type {Number}
-  */
- let selectedTier = 1;
-
-/**
- * Erstellt und läd die kombinierte PDF der Verfahren herunter.
- * @return {undefined}
- */
-function getCombinedPDF() {
- setOverlay();
-
- $.post(backendPath, JSON.stringify({'action':'gencombinedpdf', 'debug': debug})).done((data) => {
-   if(!data['success']) {
-     showError('Laden der PDF-Datei', data['error']);
-     return;
-   }
-
-   // Base64 Kodierung umkehren und Blob zum Download erstellen
-   let pdfData = atob(data['data']['pdf'].replace(/\s/g, ''));
-   let pdfBuffer = new Uint8Array(new ArrayBuffer(pdfData.length));
-   for(let i=0; i < pdfData.length; i++) {
-     pdfBuffer[i] = pdfData.charCodeAt(i);
-   }
-   let blob = new Blob([pdfBuffer], {type: "application/pdf"});
-   let lastUpdate = new Date();
-   let fileTitle = 'SecDoc_VVT_' + lastUpdate.getFullYear() + ('0' + (lastUpdate.getMonth() + 1)).slice(-2) + ('0' + lastUpdate.getDate()).slice(-2) + ('0' + lastUpdate.getHours()).slice(-2) + ('0' + lastUpdate.getMinutes()).slice(-2) + '.pdf';
-
-   // PDF-Anzeige starten (Unterscheidung, ob Edge genutzt wird)
-   if(window.navigator && window.navigator.msSaveOrOpenBlob) {
-     window.navigator.msSaveOrOpenBlob(blob, fileTitle);
-   }
-   else {
-     let url = window.URL.createObjectURL(blob);
-     let download = $('<a></a>');
-     download.attr('href', url).attr('download', fileTitle).addClass('hidden');;
-     $('body').append(download);
-     download[0].click();
-     window.URL.revokeObjectURL(url);
-     download.remove();
-   }
- }).fail((jqXHR, error, errorThrown) => {
-   showError('Laden der PDF-Datei', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
- }).always(() => {
-   setOverlay(false);
- });
-}
-
-/**
- * Erstellt und läd die komplette PDF zu einer Verarbeitungstätigkeit mit allen Abhängigkeiten herunter.
- * @param  {Number} docId ID der Verarbeitungstätigkeit
- * @return {undefined}
- */
-function getCompletePDF(docId) {
- setOverlay();
-
- $.post(backendPath, JSON.stringify({'action':'gencompletepdf', 'id': docId, 'debug': debug})).done((data) => {
-   if(!data['success']) {
-     showError('Laden der PDF', data['error']);
-     return;
-   }
-
-   // Base64 Kodierung umkehren und Blob zum Download erstellen
-   let pdfData = atob(data['data']['pdf'].replace(/\s/g, ''));
-   let pdfBuffer = new Uint8Array(new ArrayBuffer(pdfData.length));
-   for(let i=0; i < pdfData.length; i++) {
-     pdfBuffer[i] = pdfData.charCodeAt(i);
-   }
-   let blob = new Blob([pdfBuffer], {type: "application/pdf"});
-   let lastUpdate = new Date();
-   let typeName = {1: 'Verarbeitungstätigkeit', 2: 'IT-Verfahren', 3: 'Fachapplikation', 4: 'Übergreifende_Massnahme'};
-   let fileTitle = 'SecDoc_' + typeName[data['data']['type']] + '_(komplett)_' + docId + '_' + data['data']['title'].substr(0, 30) + '_' + lastUpdate.getFullYear() + ('0' + (lastUpdate.getMonth() + 1)).slice(-2) + ('0' + lastUpdate.getDate()).slice(-2) + ('0' + lastUpdate.getHours()).slice(-2) + ('0' + lastUpdate.getMinutes()).slice(-2);
-   fileTitle = fileTitle.replace(/[/\\?%*:|"<>\.,;=\s]/g, '_');
-   fileTitle += '.pdf';
-
-   // PDF-Anzeige starten (Unterscheidung, ob Edge genutzt wird)
-   if(window.navigator && window.navigator.msSaveOrOpenBlob) {
-     window.navigator.msSaveOrOpenBlob(blob, fileTitle);
-   }
-   else {
-     let url = window.URL.createObjectURL(blob);
-     let download = $('<a></a>');
-     download.attr('href', url).attr('download', fileTitle).addClass('hidden');;
-     $('body').append(download);
-     download[0].click();
-     window.URL.revokeObjectURL(url);
-     download.remove();
-   }
- }).fail((jqXHR, error, errorThrown) => {
-   showError('Laden der PDF', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
- }).always(() => {
-   setOverlay(false);
- });
-}
-
-/**
- * Holt die aktuelle Liste der Dokumentationen und erzeugt die Tabellen.
- * @param  {number} tier Nummer der Ebene
- * @return {undefined}
- */
-function loadTables(tier) {
-  setOverlay(true);
-
-  $.get(backendPath, { 'action': 'listdsb', 'debug': debug }).done((data) => {
-    if(!data['success']) {
-      showError('Abrufen der Verfahrensliste', data['error']);
-      setSaveLabel('none');
-      return;
-    }
-
-    var abgTable = $('#abgeschlossen tbody').first();
-    var inbTable = $('#inbearbeitung tbody').first();
-
-    $('#abgeschlossen table').DataTable().destroy();
-    $('#inbearbeitung table').DataTable().destroy();
-
-    $('#abgeschlossen table').off();
-    $('#inbearbeitung table').off();
-
-    abgTable.empty();
-    inbTable.empty();
-
-    // Für jedes Verfahren einen Tabelleneinträg anlegen
-    for(var c=0; c < data['count']; c++) {
-      if(parseInt(data['data'][c]['Typ']) !== tier) continue;
-
-      let lastUpdate = data['data'][c]['Aktualisierung'] ? formatDate(new Date(data['data'][c]['Aktualisierung'].replace(' ', 'T'))) : 'Unbekannt';
-
-      var newEntry = $('<tr></tr>');
-      newEntry.append('<td style="width: 16px;"></td>');
-      newEntry.append('<td>' + data['data'][c]['Bezeichnung'] + ' <i data-toggle="tooltip" class="fa fa-info-circle" title="' + data['data'][c]['Beschreibung'] + '"></i></td>');
-      newEntry.append('<td>' + data['data'][c]['Fachabteilung'] + '</td>');
-      newEntry.append('<td>' + (data['data'][c]['FachKontakt'] ? data['data'][c]['FachKontakt'] : '-- nicht angegeben --') + '</td>');
-      newEntry.append('<td>' + (data['data'][c]['TechKontakt'] ? data['data'][c]['TechKontakt'] : '-- nicht angegeben --') + '</td>');
-      newEntry.append('<td>' + data['data'][c]['Erstelldatum'] + '</td>');
-      newEntry.append('<td data-order="' + (data['data'][c]['Aktualisierung'] ? new Date(data['data'][c]['Aktualisierung'].replace(' ', 'T')).getTime() : new Date().getTime()) + '">' + lastUpdate + ' <i class="fa fa-history cursor-progress revisionload" data-id="' + data['data'][c]['ID'] + '"></i></td>');
-      newEntry.append('<td><textarea class="form-control comment" data-id="' + data['data'][c]['ID'] + '" style="resize: both;">' + htmlDecode(data['data'][c]['DSBKommentar']) + '</textarea></td>');
-      newEntry.append('<td><div class="btn-group inline"><a class="btn" href="?id=' + data['data'][c]['ID'] + (debug ? '&debug=true' : '') + '" target="_blank"><i class="fa fa-edit"></i> Bearbeiten</a><a class="btn" href="?copy=' + data['data'][c]['ID'] + (debug ? '&debug=true' : '') + '" target="_blank"><i class="fa fa-copy"></i> Kopieren</a><button type="button" class="btn pdfdownload" data-id="' + data['data'][c]['ID'] + '" ' + (data['data'][c]['PDF'] ? '' : 'disabled') + '><i class="fa fa-file-pdf-o"></i> ' + (parseInt(data['data'][c]['Status']) === 0 ? 'Letzte abgeschlossene PDF anzeigen' : 'PDF anzeigen') + '</button></div> <button type="button" data-id="' + data['data'][c]['ID'] +'" data-name="' + data['data'][c]['Bezeichnung'] +'" class="btn del btn-danger"><i class="fa fa-minus"></i> Löschen</button></td>');
-
-      if(parseInt(data['data'][c]['Status']) === 0) {
-        inbTable.append(newEntry);
-      }
-      else {
-        if(parseInt(data['data'][c]['Typ']) === 1 || parseInt(data['data'][c]['Typ']) === 3 || parseInt(data['data'][c]['Typ']) === 2) newEntry.find('.pdfdownload').closest('div').append('<button type="button" class="btn completepdf" data-id="' + data['data'][c]['ID'] + '" ' + (data['data'][c]['PDF'] ? '' : 'disabled') + '><i class="fa fa-file-pdf-o"></i> Vollständige PDF erzeugen</button>');
-        abgTable.append(newEntry);
-      }
-    }
-
-    // Event-Listener zum Speichern von Änderungen an den Kommentaren
-    $('#abgeschlossen table, #inbearbeitung table').on('input change', 'textarea.comment', function(event) {
-      let tar = $(event.target);
-      let timeout = 5000;
-      clearTimeout(tar.data('timer'));
-
-      // Bei onchange direkt abspeichern
-      if(event.type === 'change') {
-        timeout = 0;
-      }
-      tar.data('timer', setTimeout(function() {
-        // DOM aktualisieren
-        tar[0].innerHTML = tar.val();
-
-        // Aktuellen Wert aus dem DOM in DataTables übernehmen
-        tar.closest('table').DataTable().cell(tar.closest('td')).data(tar.closest('td').html());
-
-        setSaveLabel('saving');
-        $.post(backendPath, JSON.stringify({'action':'updatecomment', 'id': tar.data('id'), 'data': { 'comment': htmlEncode(tar.val()) }, 'debug': debug})).done((data) => {
-          if(!data['success']) {
-            showError('Speichern des Kommentars', data['error']);
-            setSaveLabel('failed');
-            return;
-          }
-          setSaveLabel('saved');
-        }).fail((jqXHR, error, errorThrown) => {
-          showError('Speichern des Kommentars', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-          setSaveLabel('failed');
-        });
-      }, timeout));
-    });
-
-    // PDF-Download ermöglichen
-    $('#abgeschlossen table, #inbearbeitung table').on('click', 'button.pdfdownload', function(event) {
-      getPDFFromServer($(event.target).data('id'));
-    });
-
-    $('#abgeschlossen table, #inbearbeitung table').on('click', 'button.completepdf', function(event) {
-      getCompletePDF($(event.target).data('id'));
-    });
-
-    // Handler für das Löschen von Verfahren
-    $('#abgeschlossen table, #inbearbeitung table').on('click', 'button.del', function() {
-      var confirmed = confirm('Achtung: Von diesem Verfahren könnten andere Verfahren abhängen! Wollen Sie das Verfahren "' + $(this).data('name') + '" wirklich löschen?');
-      if(confirmed) {
-        deleteFromServer($(this).data('id'));
-        let row = $(this).parents('tr');
-        if(row.hasClass('child')) row = row.prev();
-        $(this).parents('table').DataTable().row(row).remove().draw();
-      }
-    });
-
-    // DataTables anpassen und initialisieren
-    /**
-     * Formatiert die Tabelle für den Druck um (ersetzt die Eingabefelder und Tooltips)
-     * @private
-     * @param {String} inner  Inneres HTML einer Tabellenzelle
-     * @param {Number} rowdex Zeilennummer
-     * @param {Number} coldex Spaltennummer
-     * @return {String} Formatiertes HTML für den Druck
-     */
-    function printFormat(inner, rowdex, coldex) {
-      if(coldex === 0) return htmlEncode($.parseHTML(inner)[0].textContent);
-      if(coldex === 6) return htmlEncode($($.parseHTML(inner)).val());
-      return inner;
-    }
-
-    /**
-     * Formatiert die Tabelle für die PDF-Ausgabe um (ersetzt die Eingabefelder und Tooltips)
-     * @private
-     * @param {String} inner  Inneres HTML einer Tabellenzelle
-     * @param {Number} rowdex Zeilennummer
-     * @param {Number} coldex Spaltennummer
-     * @return {String} Formatiertes HTML für den Druck
-     */
-    function pdfFormat(inner, rowdex, coldex) {
-      if(coldex === 0) return $.parseHTML(inner)[0].textContent;
-      if(coldex === 6) return $($.parseHTML(inner)).val();
-      return inner;
-    }
-
-    $.extend(true, $.fn.dataTable.defaults, {
-        language: {
-          url: 'assets/js/datatables_german.json'
-        },
-        columnDefs: [
-          {
-            targets: 'no-sort',
-            orderable: false
-          },
-          {
-            className: 'control',
-            orderable: false,
-            targets:   0
-          }
-        ],
-        responsive: {
-          details: {
-            type: 'column',
-            target: 'td:not(:has(textarea))'
-          }
-        },
-        autoWidth: false,
-        order: [ 1, 'asc' ],
-        dom: "<'row'<'col-sm-4'l><'col-sm-4 text-center'B><'col-sm-4'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>"
-    });
-
-    $('#abgeschlossen table').DataTable({
-      buttons: [{
-          extend: 'print',
-          title: 'Abgeschlossene Verfahren',
-          text: '<i class="fa fa-print"> Tabelle drucken',
-          exportOptions: {
-            stripHtml: false,
-            columns: ':not(.no-print)',
-            format: {
-              body: printFormat
-            }
-          }
-        },
-        {
-          extend: 'pdfHtml5',
-          title: 'Abgeschlossene Verfahren',
-          text: '<i class="fa fa-file-pdf-o"> Tabelle als PDF speichern',
-          orientation: 'landscape',
-          exportOptions: {
-            stripHtml: false,
-            columns: ':not(.no-print)',
-            format: {
-              body: pdfFormat
-            }
-          }
-        }
-      ]
-    });
-    $('#inbearbeitung table').DataTable({
-      buttons: [{
-          extend: 'print',
-          title: 'Verfahren in Bearbeitung',
-          text: '<i class="fa fa-print"> Tabelle drucken',
-          exportOptions: {
-            stripHtml: false,
-            columns: ':not(.no-print)',
-            format: {
-              body: printFormat
-            }
-          }
-        },
-        {
-          extend: 'pdfHtml5',
-          title: 'Verfahren in Bearbeitung',
-          text: '<i class="fa fa-file-pdf-o"> Tabelle als PDF speichern',
-          orientation: 'landscape',
-          exportOptions: {
-            stripHtml: false,
-            columns: ':not(.no-print)',
-            format: {
-              body: pdfFormat
-            }
-          }
-        }
-      ]
-    });
-
-    // Tooltips intialisieren
-    $('#content').find('[data-toggle="tooltip"]').tooltip({container: 'body'});
-
-    $('#content').find('i.revisionload').on('mouseover', (evt) => {
-      let evtTarget = $(evt.target);
-
-      if(!evtTarget.hasClass('revisionload')) return;
-
-      evtTarget.addClass('hover');
-      evtTarget.removeClass('revisionload');
-
-      $.get(backendPath, {'action': 'listrevisions', 'debug': debug, 'id':  evtTarget.data('id')}).done((data) => {
-        if(!data['success']) {
-          evtTarget.prop('title', '<Fehler beim Holen der Revisionen>');
-        }
-        else {
-          let revisions = $('<div><p>Letzte 5 Revisionen:</p><ul></ul></div>');
-          let revList   = revisions.find('ul');
-          for(let c=0; c < data['count'] && c < 5; c++) {
-            revList.append('<li>#' + data['data'][c]['Revision'] + ' - ' + data['data'][c]['Date'] + ' - ' + data['data'][c]['Editor'] + (data['data'][c]['Comment'] !== '' ? ' - ' + data['data'][c]['Comment'] : ''));
-          }
-          if(data['count'] === 0) revList.replaceWith('<Keine Revisionen vorhanden>');
-          evtTarget.prop('title', revisions[0].outerHTML);
-        }
-      }).fail((jqXHR, error, errorThrown) => {
-        evtTarget.prop('title', '<Fehler beim Holen der Revisionen>');
-      }).always(() => {
-        evtTarget.removeClass('cursor-progress').addClass('cursor-help');
-        evtTarget.tooltip({container: 'body', html: true});
-        if(evtTarget.hasClass('hover')) evtTarget.tooltip('show');
-      });
-    });
-    $('#content').find('i.revisionload').on('mouseleave', (evt) => { $(evt.target).removeClass('hover'); });
-
-    // Tabellengröße anpassen, wenn der Tab gewechselt wird
-    $('a[data-toggle="tab"]').on("shown.bs.tab", function (e) {
-      $($.fn.dataTable.tables(true)).DataTable().columns.adjust().responsive.recalc();
-    });
-
-    setSaveLabel('refreshed');
-  }).fail((jqXHR, error, errorThrown) => {
-    showError('Abrufen der Verfahrensliste', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-    setSaveLabel('none');
-  }).always(() => {
-    setOverlay(false);
-  });
-}
-
-
-
-// Statistiken holen und anzeigen
-$.get(backendPath, { 'action': 'getstats', 'debug': debug }).done((data) => {
-  if(!data['success']) {
-    showError('Abrufen der Statistiken', data['error']);
-    return;
-  }
-
-  var newEntry = $('<tr></tr>');
-  newEntry.append('<td>' + data['data']['gesamt'] + '</td>');
-  newEntry.append('<td>' + data['data']['inbearbeitung'] + '</td>');
-  newEntry.append('<td>' + data['data']['abgeschlossen'] + '</td>');
-  newEntry.append('<td>' + data['data']['gelöscht'] + '</td>');
-  newEntry.append('<td>' + data['data']['zuletztbearbeitet'] + '</td>');
-
-  $('#statistik tbody').append(newEntry);
-}).fail((jqXHR, error, errorThrown) => {
-  showError('Abrufen der Statistiken', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-  setSaveLabel('none');
-});
-
-// Tabellen das erste Mal befüllen
-loadTables(selectedTier);
-
-// Button für kombinierte PDF initialisieren
-$('#getCombinedPDF').click(() => {getCombinedPDF();});
-
-// Ebenen-Auswahl intialisieren
-$('input[name="select_ebene"]').change(function() {
-  selectedTier = parseInt($(this).val());
-  loadTables(selectedTier);
-});
-
-// Timer beenden
-console.timeEnd('Gesamte Vorbereitungszeit');
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/JSDoc/fonts/OpenSans-Bold-webfont.eot b/docs/JSDoc/fonts/OpenSans-Bold-webfont.eot deleted file mode 100644 index 5d20d916338a5890a033952e2e07ba7380f5a7d3..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-Bold-webfont.eot and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-Bold-webfont.svg b/docs/JSDoc/fonts/OpenSans-Bold-webfont.svg deleted file mode 100644 index 3ed7be4bc5b2908326eddde6a32eff453a5cb319..0000000000000000000000000000000000000000 --- a/docs/JSDoc/fonts/OpenSans-Bold-webfont.svg +++ /dev/null @@ -1,1830 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/JSDoc/fonts/OpenSans-Bold-webfont.woff b/docs/JSDoc/fonts/OpenSans-Bold-webfont.woff deleted file mode 100644 index 1205787b0ed50db71ebd4f8a7f85d106721ff258..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-Bold-webfont.woff and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-BoldItalic-webfont.eot b/docs/JSDoc/fonts/OpenSans-BoldItalic-webfont.eot deleted file mode 100644 index 1f639a15ff3cc66d3b22b55a7f28a8cf0d821b03..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-BoldItalic-webfont.eot and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-BoldItalic-webfont.svg b/docs/JSDoc/fonts/OpenSans-BoldItalic-webfont.svg deleted file mode 100644 index 6a2607b9dafcfd369a5440b1e6c2d5e30579ea66..0000000000000000000000000000000000000000 --- a/docs/JSDoc/fonts/OpenSans-BoldItalic-webfont.svg +++ /dev/null @@ -1,1830 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/JSDoc/fonts/OpenSans-BoldItalic-webfont.woff b/docs/JSDoc/fonts/OpenSans-BoldItalic-webfont.woff deleted file mode 100644 index ed760c0628b6a0026041f5b8bba466a0471fd2e0..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-BoldItalic-webfont.woff and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-Italic-webfont.eot b/docs/JSDoc/fonts/OpenSans-Italic-webfont.eot deleted file mode 100644 index 0c8a0ae06ed09f6a7be1b84defae7ccda65cc2e0..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-Italic-webfont.eot and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-Italic-webfont.svg b/docs/JSDoc/fonts/OpenSans-Italic-webfont.svg deleted file mode 100644 index e1075dcc2464f8a8f913383e3891da709b9feeb8..0000000000000000000000000000000000000000 --- a/docs/JSDoc/fonts/OpenSans-Italic-webfont.svg +++ /dev/null @@ -1,1830 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/JSDoc/fonts/OpenSans-Italic-webfont.woff b/docs/JSDoc/fonts/OpenSans-Italic-webfont.woff deleted file mode 100644 index ff652e64356b538c001423b6aedefcf1ee66cd17..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-Italic-webfont.woff and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-Light-webfont.eot b/docs/JSDoc/fonts/OpenSans-Light-webfont.eot deleted file mode 100644 index 14868406aa7d728a88d63963f119635813b5d30e..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-Light-webfont.eot and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-Light-webfont.svg b/docs/JSDoc/fonts/OpenSans-Light-webfont.svg deleted file mode 100644 index 11a472ca8a5111187b4269b1407bbfd8dcf8fffd..0000000000000000000000000000000000000000 --- a/docs/JSDoc/fonts/OpenSans-Light-webfont.svg +++ /dev/null @@ -1,1831 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/JSDoc/fonts/OpenSans-Light-webfont.woff b/docs/JSDoc/fonts/OpenSans-Light-webfont.woff deleted file mode 100644 index e786074813a27d0a7a249047832988d5bf0fe756..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-Light-webfont.woff and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-LightItalic-webfont.eot b/docs/JSDoc/fonts/OpenSans-LightItalic-webfont.eot deleted file mode 100644 index 8f445929ffb03b50e98c2a2f7d831a0cb1b276a2..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-LightItalic-webfont.eot and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-LightItalic-webfont.svg b/docs/JSDoc/fonts/OpenSans-LightItalic-webfont.svg deleted file mode 100644 index 431d7e35463dc240b890917ddd533219b2a9ae2e..0000000000000000000000000000000000000000 --- a/docs/JSDoc/fonts/OpenSans-LightItalic-webfont.svg +++ /dev/null @@ -1,1835 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/JSDoc/fonts/OpenSans-LightItalic-webfont.woff b/docs/JSDoc/fonts/OpenSans-LightItalic-webfont.woff deleted file mode 100644 index 43e8b9e6cc061ff17fd2903075cbde12715512b3..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-LightItalic-webfont.woff and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-Regular-webfont.eot b/docs/JSDoc/fonts/OpenSans-Regular-webfont.eot deleted file mode 100644 index 6bbc3cf58cb011a6b4bf3cb1612ce212608f7274..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-Regular-webfont.eot and /dev/null differ diff --git a/docs/JSDoc/fonts/OpenSans-Regular-webfont.svg b/docs/JSDoc/fonts/OpenSans-Regular-webfont.svg deleted file mode 100644 index 25a3952340fc727f6571e182d63a7938a2f27b32..0000000000000000000000000000000000000000 --- a/docs/JSDoc/fonts/OpenSans-Regular-webfont.svg +++ /dev/null @@ -1,1831 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/JSDoc/fonts/OpenSans-Regular-webfont.woff b/docs/JSDoc/fonts/OpenSans-Regular-webfont.woff deleted file mode 100644 index e231183dce4c7b452afc9e7799586fd285e146f4..0000000000000000000000000000000000000000 Binary files a/docs/JSDoc/fonts/OpenSans-Regular-webfont.woff and /dev/null differ diff --git a/docs/JSDoc/global.html b/docs/JSDoc/global.html deleted file mode 100644 index 8be2435b0ae649a4182c363c86efe10160597c21..0000000000000000000000000000000000000000 --- a/docs/JSDoc/global.html +++ /dev/null @@ -1,8943 +0,0 @@ - - - - - JSDoc: Global - - - - - - - - - - -
- -

Global

- - - - - - -
- -
- -

- - -
- -
-
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - - - - - - - - -

Members

- - - -

autoSaveTimer :Number

- - - - -
- JS Interval Timer für regelmäßigen Autosave -
- - - -
Type:
-
    -
  • - -Number - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

autoSaveWait :Number

- - - - -
- Zeit zwischen Autosaves -
- - - -
Type:
-
    -
  • - -Number - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

backendPath :String

- - - - -
- Relativer Pfad zur verwaltung.php -
- - - -
Type:
-
    -
  • - -String - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

canEdit :Boolean

- - - - -
- Gibt an, ob das geladene Verfahren bearbeitet werden kann -
- - - -
Type:
-
    -
  • - -Boolean - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

changedFields :Array

- - - - -
- Liste der IDs aller veränderten Felder seit dem letzten Speichern -
- - - -
Type:
-
    -
  • - -Array - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

changedValues :Boolean

- - - - -
- Gibt an, ob Eingaben geändert wurden seit dem letzten Laden/Speichern -
- - - -
Type:
-
    -
  • - -Boolean - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

copyId :Boolean

- - - - -
- Gibt an, ob ein Verfahren kopiert werden soll -
- - - -
Type:
-
    -
  • - -Boolean - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

copyIdMain :Number

- - - - -
- ID der Dokumentation, die kopiert werden soll -
- - - -
Type:
-
    -
  • - -Number - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

debug :Boolean

- - - - -
- Steuert die Debug-Ausgaben -
- - - -
Type:
-
    -
  • - -Boolean - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

endlessCounts :Object

- - - - -
- Maping von Countern für jede endlose Tabelle -
- - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

endlessTables :Array

- - - - -
- Tabellen IDs für die endlosen Tabellen -
- - - -
Type:
-
    -
  • - -Array - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

endlessTemplates :Object

- - - - -
- Mapping von Templates für jede endlose Tabelle -
- - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

getUserPromise :Promise

- - - - -
- Promise für die Abfrage des eingeloggten Nutzers -
- - - -
Type:
-
    -
  • - -Promise - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

globalClear :Boolean

- - - - -
- Wird auf true gesetzt, wenn der Wizard zurückgesetzt wird (z.B. über "Neue Dokumentation") -
- - - -
Type:
-
    -
  • - -Boolean - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

loadId :Number

- - - - -
- Übergebene ID eines Verfahrens -
- - - -
Type:
-
    -
  • - -Number - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

loadIdMain :Number

- - - - -
- ID der Dokumentation, die geladen werden soll -
- - - -
Type:
-
    -
  • - -Number - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

markedAsFinished :Boolean

- - - - -
- Gibt an, ob das Verfahren als abgeschlossen markiert wurde -
- - - -
Type:
-
    -
  • - -Boolean - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - -
- JQuery Object des Modal-Elements -
- - - -
Type:
-
    -
  • - -jQuery-Object - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

mode :String

- - - - -
- Speichert den aktuellen Bearbeitungs-Modus (entweder IT-Verfahren, Fachapplikation Verarbeitungstätigkeit) -
- - - -
Type:
-
    -
  • - -String - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

modeMapping :Object

- - - - -
- Mapping des Typs -
- - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

modeName :Array

- - - - -
- Lesbarer Name des Modus; genutzt für die Ersetzung in Texten -
- - - -
Type:
-
    -
  • - -Array - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

modeNum :Number

- - - - -
- Interne Nummerierung für die Dokumentations-Modi -
- - - -
Type:
-
    -
  • - -Number - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

page :String

- - - - -
- Angabe der Ziel-Unterseite -
- - - -
Type:
-
    -
  • - -String - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

promises :Array

- - - - -
- Sammlung von Promises für AJAX-Anfragen, die zu Beginn durchgeführt werden müssen -
- - - -
Type:
-
    -
  • - -Array - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

selectedTier :Number

- - - - -
- Aktuell ausgewählte Ebene -
- - - -
Type:
-
    -
  • - -Number - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

status :Number

- - - - -
- Gibt an, welchen Status das Verfahren hat -
- - - -
Type:
-
    -
  • - -Number - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

statusMapping :Object

- - - - -
- Mapping für die Stati von Verfahren -
- - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

statusSymbolMapping :Object

- - - - -
- Mapping für Status Symbole -
- - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

tomsMapping :Array

- - - - -
- Mapping für die Liste der TOMs -
- - - -
Type:
-
    -
  • - -Array - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

typeaheadCache :Object

- - - - -
- Cache für die Typeahead-Funktionen -
- - - -
Type:
-
    -
  • - -Object - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

userCanDSB :Boolean

- - - - -
- Gibt an, ob der Nutzer die Rolle eines Datenschutzbeauftragten annehmen kann -
- - - -
Type:
-
    -
  • - -Boolean - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

userIsDSB :Boolean

- - - - -
- Gibt an, ob der Nutzer ein Datenschutzbeauftragter ist -
- - - -
Type:
-
    -
  • - -Boolean - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

userIsManager :Boolean

- - - - -
- Gibt an, ob der Nutzer ein Bereichsleiter ist -
- - - -
Type:
-
    -
  • - -Boolean - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - -

version :String

- - - - -
- Aktuelle Versions-Nummer -
- - - -
Type:
-
    -
  • - -String - - -
  • -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - -

Methods

- - - - - - - -

addTableRow(table) → {undefined}

- - - - - - -
- Fügt eine Zeile in einer endlosen Tabelle hinzu (nutzt die globale Variablen 'endlessTables', 'endlessTemplates' und 'endlessCounts') -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
table - - -String - - - - Eindeutiger Tabellenname (DOM Element ID)
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

copyFromServer(id) → {undefined}

- - - - - - -
- Kopiert den Inhalt eines Verfahrens in ein neues Verfahren -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
id - - -type - - - - Eindeutige ID des Verfahrens
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

debugLog(msg, obj) → {undefined}

- - - - - - -
- Generiert eine Debug-Ausgabe, falls der globale debug-Parameter 'true' ist -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
msg - - -Object - - - - - - Ausgabenachricht (kann null sein) (wird mittels console.log(msg) ausgegeben)
obj - - -Object - - - - - - null - - (optional) Objekt, was formatiert ausgegeben werden soll (wird mittels console.table(obj) ausgegeben)
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

deleteFromServer(id) → {undefined}

- - - - - - -
- Löscht ein Verfahren vom Server -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
id - - -type - - - - Eindeutige ID des Verfahrens
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

exportJSON() → {undefined}

- - - - - - -
- Exportiert die aktuell geladene Dokumentation als JSON-Datei -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

filterTOMList(risklevel, showFinished) → {undefined}

- - - - - - -
- Filtert die Liste der TOMs anhand des gewählten Risikolevels -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
risklevel - - -Number - - - - - - Risikolevel des Verfahrens
showFinished - - -Boolean - - - - - - true - - (optional) Bearbeitete Massnahmen einblenden
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

formatBytes(bytes, decimals) → {String}

- - - - - - -
- Wandelt Dateigrößen in Bytes in eine lesbare Größenanzeige um -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
bytes - - -Number - - - - - - Dateigröße in Bytes
decimals - - -Number - - - - - - 2 - - (optional) Nachkommanstellen
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - -
See:
-
- -
- - - -
- - - - - - - - - - - - - - - -
Returns:
- - -
- Dateigröße (human-readable) -
- - - -
-
- Type -
-
- -String - - -
-
- - - - - - - - - - - - - -

formatDate(dateToFormat) → {String}

- - - - - - -
- Datum in ein gut lesbares Format bringen. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
dateToFormat - - -Date - - - - Datumsobjekt
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - -
- Gut lesbares Datum als String -
- - - -
-
- Type -
-
- -String - - -
-
- - - - - - - - - - - - - -

generateTOMList() → {undefined}

- - - - - - -
- Legt die Auswahlliste für TOMs an -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

genHTMLforPDF(draft) → {String}

- - - - - - -
- Generiert den HTML-Code-Auschnitt für die PDF-Generierung -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
draft - - -boolean - - - - - - false - - Zeigt an, ob ein Abschluss- oder Entwurfs-Dokument erstellt wird
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - -
- HTML-Code -
- - - -
-
- Type -
-
- -String - - -
-
- - - - - - - - - - - - - -

getCombinedPDF() → {undefined}

- - - - - - -
- Erstellt und läd die kombinierte PDF der Verfahren herunter. -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

getCompletePDF(docId) → {undefined}

- - - - - - -
- Erstellt und läd die komplette PDF zu einer Verarbeitungstätigkeit mit allen Abhängigkeiten herunter. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
docId - - -Number - - - - ID der Verarbeitungstätigkeit
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

getPDFFromServer(id, draft) → {undefined}

- - - - - - -
- Fragt die PDF für das Verfahren mit der übergebenen ID an und öffnet einen "Öffnen/Speichern"-Dialog -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
id - - -Number - - - - - - ID für die gewünschte PDF
draft - - -Boolean - - - - - - false - - (optional) Wenn true wird die letzte Draft-Version der PDF zurückgegeben
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

GetURLParameter(sParam) → {String|Boolean}

- - - - - - -
- Liest Parameter aus der URL -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
sParam - - -String - - - - Parametername
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - -
See:
-
- -
- - - -
- - - - - - - - - - - - - - - -
Returns:
- - -
- Gibt den Wert des Parameters zurück oder false, falls der Parameter nicht gesetzt ist -
- - - -
-
- Type -
-
- -String -| - -Boolean - - -
-
- - - - - - -
Example
- -
// Gibt 0 zurück, wenn die aktuelle URL "...?id=0" ist
GetURLParamter('id');
- - - - - - - - - -

htmlDecode(input) → {String}

- - - - - - -
- Ersetzt HTML-Entities durch Symbole, um sie korrekt darzustellen in Eingabefeldern -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
input - - -String - - - - Eingabestring
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - -
See:
-
- -
- - - -
- - - - - - - - - - - - - - - -
Returns:
- - -
- Eingabestring mit ersetzten HTML-Entities -
- - - -
-
- Type -
-
- -String - - -
-
- - - - - - -
Example
- -
// Gibt "<h1>" zurück
htmlDecode('&lt;h1&gt;');
- - - - - - - - - -

htmlEncode(unsafe) → {String}

- - - - - - -
- Ersetzt Symbole (&, <, > ", ') durch HTML-Entities, um HTML-Code Injection zu verhindern -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
unsafe - - -String - - - - Eingabestring
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - -
See:
-
- -
- - - -
- - - - - - - - - - - - - - - -
Returns:
- - -
- Eingabestring mit ersetzten Symbolen -
- - - -
-
- Type -
-
- -String - - -
-
- - - - - - -
Example
- -
// Gibt "&lt;h1&gt;" zurück
htmlEncode('<h1>');
- - - - - - - - - -

importJSON(file) → {undefined}

- - - - - - -
- Importiert eine JSON-Datei in die aktuelle Dokumentation -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
file - - -Object - - - - Verweis auf Datei vom Dateidialog
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

initEndlessTables() → {undefined}

- - - - - - -
- Initialisiert die endlosen Tabellen (nutzt die globale Variablen 'endlessTables', 'endlessTemplates' und 'endlessCounts') -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

initTypeahead(node) → {null|Object}

- - - - - - -
- Initialisiert das Typeahead-Plugin auf dem Element node -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
node - - -Object - - - - DOM-Element oder jQuery-Objekt
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -null -| - -Object - - -
-
- - - - - - - - - - - - - -

loadDocuments() → {undefined}

- - - - - - -
- Listet angehängte Dokumente auf. -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

loadEmpty() → {undefined}

- - - - - - -
- Lädt ein leeres, neues Verfahren und setzt dazu alle Eingabefelder zurück -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

loadFromJSON(values) → {Boolean}

- - - - - - -
- Liest ein JSON-String ein und stellt die Eingaben wieder her (wenn keine passenden Felder gefunden werden, werden diese ignoriert) -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
values - - -String - - - - JSON-String mit Namen der Eingabefelder als Schlüssel
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Boolean - - -
-
- - - - - - - - - - - - - -

loadFromServer(id) → {undefined}

- - - - - - -
- Fragt ein Verfahren am Server an und läd es in die Vorlage -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
id - - -Number - - - - Eindeutige ID des Verfahrens
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

loadSubpage() → {undefined}

- - - - - - -
- Läd die angefragte Unterseite und Informationen über den aktuell eingeloggten Nutzer -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

loadTables(tier) → {undefined}

- - - - - - -
- Holt die aktuelle Liste der Dokumentationen und erzeugt die Tabellen. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
tier - - -number - - - - Nummer der Ebene
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

myFinish() → {undefined}

- - - - - - -
- Wird ausgeführt, wenn der Wizard mit dem letzten Button beendet wird (genutzt in paper-bootstrap-wizard.js) -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

myInit() → {undefined}

- - - - - - -
- Wird ausgeführt, wenn der Wizard gestartet wird (genutzt in paper-bootstrap-wizard.js) -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

myNext(tab, nav, idx) → {undefined}

- - - - - - -
- Wird ausgeführt, wenn der nächste Tab gewählt wird (genutzt in paper-bootstrap-wizard.js) -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
tab - - -Object - - - -
nav - - -Object - - - -
idx - - -Number - - - -
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

myPrevious(tab, nav, idx) → {undefined}

- - - - - - -
- Wird ausgeführt, wenn zum vorherigen Tab zurückgekehrt wird (genutzt in paper-bootstrap-wizard.js) -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
tab - - -Object - - - -
nav - - -Object - - - -
idx - - -Number - - - -
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

myTabChange(tab, nav, idx) → {undefined}

- - - - - - -
- Wird ausgeführt, wenn ein Tab verlassen wird (genutzt in paper-bootstrap-wizard.js) -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
tab - - -Object - - - -
nav - - -Object - - - -
idx - - -Number - - - -
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

myTabClick(tab, navigation, index) → {undefined}

- - - - - - -
- Wird ausgeführt, falls ein Tab geklickt wird (genutzt in paper-bootstrap-wizard.js) -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
tab - - -type - - - -
navigation - - -type - - - -
index - - -type - - - -
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

removeTableRows(table, onlyEmpty) → {undefined}

- - - - - - -
- Entfernt alle Reihen einer endlosen Tabelle (nutzt die globale Variablen 'endlessTables', 'endlessTemplates' und 'endlessCounts') -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
table - - -String - - - - - - Eindeutiger Tabellenname (DOM Element ID)
onlyEmpty - - -Boolean - - - - - - false - - (optional) Entfernt nur leere Zeilen, wenn true
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

saveAsObject() → {Object}

- - - - - - -
- Gibt die Eingaben in Input-Feldern als strukturierstes Objekt zurück mit den Namen als Schlüssel -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Object - - -
-
- - - - - - -
Example
- -
{ "meta_id":0, "allgemein_bezeichnung":"Test Verfahren", ... }
- - - - - - - - - -

saveOnServer() → {Promise|Boolean}

- - - - - - -
- Sendet die aktuellen Eingaben an den Server und versucht diese abzuspeichern -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - -
- Sollte das Formular fehlende Elemente enhalten oder das Speichern abgelehnt werden false, sonst das Promise-Objekt der Ajax-Anfrage -
- - - -
-
- Type -
-
- -Promise -| - -Boolean - - -
-
- - - - - - - - - - - - - -

setOverlay(active) → {undefined}

- - - - - - -
- Aktiviert oder daktiviert das Overlay während Ladevorgängen -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
active - - -Boolean - - - - - - true - - True aktiviert das Overlay, false deaktiviert es
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

setSaveLabel(action, currDate) → {undefined}

- - - - - - -
- Setzt das Label zum aktuellen Speicher-Status -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
action - - -String - - - - Aktueller Speicherstatus
currDate - - -Date - - - - (optional) Aktuelles Datum
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

showDocumentAddDialog(docID, fileref, description, attach) → {undefined}

- - - - - - -
- Zeigt den Dokumenten-Verwaltungs-Dialog an. -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
docID - - -Number - - - - - - (optional) Dokumenten-ID
fileref - - -String - - - - - - (optional) Dateiname
description - - -String - - - - - - (optional) Dokumenten-Beschreibung
attach - - -Boolean - - - - - - false - - (optional) An Abschluss-PDF anhängen?
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

showError(action, message, httperror) → {undefined}

- - - - - - -
- Zeigt dem Nutzer eine Fehlermeldung an -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
action - - -String - - - - - - Aktion, bei der der Fehler aufgetreten ist
message - - -String - - - - - - false - - (optional) Fehlermeldung
httperror - - -Object - - - - - - false - - (optional) Objekt der Form {'jqXHR':..., 'error':..., 'errorThrown':...} für HTTP Fehlermeldungen
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

showImportDialog() → {undefined}

- - - - - - -
- Zeigt einen Dialog zum JSON-Import an -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

showVerfahrensliste(startup) → {undefined}

- - - - - - -
- Zeigt eine Liste aller Verfahren an, auf die der Nutzer Zugriff hat -
- - - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDefaultDescription
startup - - -Boolean - - - - - - false - - (optional) Gibt an, ob es sich um den Aufruf beim Laden der Seite handelt (wird nur geladen falls editierbare Verfahren vorhanden) oder ein manueller Aufruf
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -

toggleTOMList() → {undefined}

- - - - - - -
- Übernimmt das Ein- und Ausblenden von TOMs nach Kategorien. -
- - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Source:
-
- - - - - - - -
- - - - - - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - - - - - - - - - -
- -
- - - - -
- - - -
- - - - - - - \ No newline at end of file diff --git a/docs/JSDoc/index.html b/docs/JSDoc/index.html deleted file mode 100644 index 9b090dbfead1da939a7db2e21173d5ba5e66b449..0000000000000000000000000000000000000000 --- a/docs/JSDoc/index.html +++ /dev/null @@ -1,421 +0,0 @@ - - - - - JSDoc: Home - - - - - - - - - - -
- -

Home

- - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - -
- -
- -

dsbview.js

- - -
- -
-
- - -
Umfasst die Funktionalitäten der DSB-Ansicht
- - - - - -
- - - - - - - - - - - - - - - - - - -
Author:
-
- -
- - - - - - - - -
License:
-
  • AGPL-3.0-or-later
- - - - - -
Source:
-
- - - - - - - -
- - - - -
- - - - -

Requires

- -
    -
  • module:assets/js/mains.js
  • - -
  • module:assets/js/datatables.min.js
  • - -
  • module:assets/js/datatables_german.json
  • -
- - - - - - - - - - - - - - - - - -
- -
- - - - - - - -
- -
- -

main.js

- - -
- -
-
- - -
Kapselt die zentralen Funktionen und steuert das Laden der Unterseiten
- - - - - -
- - - - - - - - - - - - - - - - - - -
Author:
-
- -
- - - - - - - - -
License:
-
  • AGPL-3.0-or-later
- - - - - -
Source:
-
- - - - - - - -
- - - - -
- - - - -

Requires

- -
    -
  • module:assets/js/jquery-3.4.1.min.js
  • -
- - - - - - - - - - - - - - - - - -
- -
- - - - - - - -
- -
- -

wizard.js

- - -
- -
-
- - -
Setzt die dynamischen Funktionen der Verfahrenseingabe um und ergänzt den Wizard
- - - - - -
- - - - - - - - - - - - - - - - - - -
Author:
-
- -
- - - - - - - - -
License:
-
  • AGPL-3.0-or-later
- - - - - -
Source:
-
- - - - - - - -
- - - - -
- - - - -

Requires

- -
    -
  • module:assets/js/main.js
  • - -
  • module:assets/js/bootstrap-select.min.js
  • - -
  • module:assets/js/jquery.typeahead.min.js
  • - -
  • module:assets/js/jquery.validate.min.js
  • - -
  • module:assets/js/datatables.min.js
  • - -
  • module:assets/js/datatables_german.json
  • -
- - - - - - - - - - - - - - - - - -
- -
- - - - -
- - - -
- - - - - - - \ No newline at end of file diff --git a/docs/JSDoc/main.js.html b/docs/JSDoc/main.js.html deleted file mode 100644 index 51abcc46202709b8024fc3ca8e68a72a3ba973fa..0000000000000000000000000000000000000000 --- a/docs/JSDoc/main.js.html +++ /dev/null @@ -1,566 +0,0 @@ - - - - - JSDoc: Source: main.js - - - - - - - - - - -
- -

Source: main.js

- - - - - - -
-
-
/**
- * main.js - Zentrale Funktionen für das secdoc-Tool
- *
- * @file Kapselt die zentralen Funktionen und steuert das Laden der Unterseiten
- *
- * @requires assets/js/jquery-3.4.1.min.js
- *
- * @author Thorsten Küfer <thorsten.kuefer@uni-muenster.de>
- * @author Dustin Gawron <dustin.gawron@uni-muenster.de>
- * @copyright (c) 2018-2020 Westfälische Wilhelms-Universität Münster
- * @license AGPL-3.0-or-later <https://www.gnu.org/licenses/agpl.html>
- */
-
-// Zeitmessung starten
-console.time('Gesamte Vorbereitungszeit');
-
-/*
- * Globale Variablen initialisieren
- */
-// Allgemeine Variablen
-/**
- * Steuert die Debug-Ausgaben
- * @global
- * @type {Boolean}
- */
-var debug = (GetURLParameter('debug') === 'true' || GetURLParameter('debug') == 1) ? true : false;
-
-/**
- * Aktuelle Versions-Nummer
- * @global
- * @type {String}
- */
-var version = '';
-
-/**
- * Angabe der Ziel-Unterseite
- * @global
- * @type {String}
- */
-var page = ['dsbview', 'home', 'login', 'wizit', 'wizproc', 'wizapp', 'wizmeasures'].includes(GetURLParameter('page')) ? GetURLParameter('page') : 'home';
-
-/**
- * ID der Dokumentation, die geladen werden soll
- * @type {Number}
- */
-var loadIdMain = GetURLParameter('id') === false ? 0 : parseInt(GetURLParameter('id'));
-
-/**
- * ID der Dokumentation, die kopiert werden soll
- * @type {Number}
- */
-var copyIdMain = GetURLParameter('copy') === false ? 0 : parseInt(GetURLParameter('copy'));
-
-/**
- * Gibt an, ob der Nutzer ein Datenschutzbeauftragter ist
- * @global
- * @type {Boolean}
- */
-var userIsDSB = false;
-
-/**
- * Gibt an, ob der Nutzer die Rolle eines Datenschutzbeauftragten annehmen kann
- * @global
- * @type {Boolean}
- */
-var userCanDSB = false;
-
-/**
- * Gibt an, ob der Nutzer ein Bereichsleiter ist
- * @global
- * @type {Boolean}
- */
-var userIsManager = false;
-
-/**
- * Relativer Pfad zur verwaltung.php
- * @global
- * @type {String}
- */
-var backendPath = 'assets/ajax/verwaltung.php';
-
-/**
- * JQuery Object des Modal-Elements
- * @global
- * @type {jQuery-Object}
- */
-var modal = $('#modalWindow'); // Modal-Fenster für Meldungen/Fehler
-
-/**
- * Promise für die Abfrage des eingeloggten Nutzers
- * @global
- * @type {Promise}
- */
-var getUserPromise = Promise.resolve();
-
-// Mappings
-/**
- * Mapping für die Stati von Verfahren
- * @global
- * @type {Object}
- */
-var statusMapping = {'0': 'In Bearbeitung', '1': 'Zur Freigabe', '2': 'In Betrieb', '9': 'Unbekannt'};
-
-/**
- * Mapping für Status Symbole
- * @global
- * @type {Object}
- */
-var statusSymbolMapping = {'0': 'fa-pencil-square-o', '2': 'fa-check-square-o', '9': 'fa-question'};
-
-/*
- * Debug Modus initialisieren
- */
-var reqNumber = 0;
-if(debug) {
-  $('#debug').removeClass('hidden');
-  // Zeitmessung und Debugausgaben für Ajax-Anfragen initialisieren
-  $(document).ajaxSend((event, request, settings) => { console.time('Anfragezeit für Request #' + reqNumber + ' - ' + settings.type + ':' + settings.url); settings.reqNumber = reqNumber; reqNumber++; });
-  $(document).ajaxComplete((event, request, settings) => {
-    console.timeEnd('Anfragezeit für Request #' + settings.reqNumber + ' - ' + settings.type + ':' + settings.url);
-    debugLog(null, {'settings.url': settings.url, 'settings.type': settings.type, 'settings.async': settings.async, 'settings.crossDomain': settings.crossDomain, 'request.readyState': request.readyState, 'request.responseText': request.responseText, 'request.status': request.status});
-    if(request.responseJSON && request.responseJSON['debug']) {
-      $('#debug').find('pre').append(request.responseJSON['debug']);
-    }
-  });
-}
-
-/*
- * Ausgabe wichtiger Variablen zu Debug-Zwecken
- */
-debugLog('URL Parameter:', {'debug': debug});
-debugLog('Backend Pfade:', {'verwaltung.php': backendPath});
-
-/*
- * Hilfsfunktionen
- */
-/**
- * Liest Parameter aus der URL
- * @see {@link https://stackoverflow.com/a/21903119 Stackoverflow}
- * @example
- * // Gibt 0 zurück, wenn die aktuelle URL "...?id=0" ist
- * GetURLParamter('id');
- * @param {String} sParam Parametername
- * @returns {String|Boolean} Gibt den Wert des Parameters zurück oder false, falls der Parameter nicht gesetzt ist
- */
-function GetURLParameter(sParam) {
-    var sPageURL = window.location.search.substring(1);
-    var sURLVariables = sPageURL.split('&');
-    for (var i = 0; i < sURLVariables.length; i++) {
-        var sParameterName = sURLVariables[i].split('=');
-        if (sParameterName[0] === sParam) return sParameterName[1];
-    }
-    return false;
-}
-
-/**
- * Ersetzt Symbole (&, <, > ", ') durch HTML-Entities, um HTML-Code Injection zu verhindern
- * @see {@link https://stackoverflow.com/a/6234804 Stackoverflow}
- * @example
- * // Gibt "&lt;h1&gt;" zurück
- * htmlEncode('<h1>');
- * @param {String} unsafe Eingabestring
- * @return {String} Eingabestring mit ersetzten Symbolen
- */
-function htmlEncode(unsafe) {
-    return unsafe
-         .replace(/&/g, "&amp;")
-         .replace(/</g, "&lt;")
-         .replace(/>/g, "&gt;")
-         .replace(/"/g, "&quot;")
-         .replace(/'/g, "&#039;");
-}
-
-/**
- * Ersetzt HTML-Entities durch Symbole, um sie korrekt darzustellen in Eingabefeldern
- * @see {@link https://stackoverflow.com/a/34064434 Stackoverflow}
- * @example
- * // Gibt "<h1>" zurück
- * htmlDecode('&lt;h1&gt;');
- * @param {String} input Eingabestring
- * @return {String} Eingabestring mit ersetzten HTML-Entities
- */
-function htmlDecode(input) {
-  var doc = new DOMParser().parseFromString(input, "text/html");
-  return doc.documentElement.textContent;
-}
-
-/**
- * Wandelt Dateigrößen in Bytes in eine lesbare Größenanzeige um
- * @see {@link https://stackoverflow.com/a/18650828}
- * @param  {Number} bytes    Dateigröße in Bytes
- * @param  {Number} decimals (optional) Nachkommanstellen
- * @return {String} Dateigröße (human-readable)
- */
-function formatBytes(bytes, decimals = 2) {
-    if (bytes === 0) return '0 Bytes';
-
-    const k = 1024;
-    const dm = decimals < 0 ? 0 : decimals;
-    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
-
-    const i = Math.floor(Math.log(bytes) / Math.log(k));
-
-    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
-}
-
-/**
- * Datum in ein gut lesbares Format bringen.
- * @param  {Date} dateToFormat Datumsobjekt
- * @return {String} Gut lesbares Datum als String
- */
-function formatDate(dateToFormat) {
-  let currDate      = new Date();
-  let formattedDate = '';
-
-  if(dateToFormat.getFullYear() === currDate.getFullYear() && dateToFormat.getMonth() === currDate.getMonth() && dateToFormat.getDate() === currDate.getDate()) {
-    formattedDate = 'Heute ';
-    formattedDate += ('0' + dateToFormat.getHours()).slice(-2) + ':' + ('0' + dateToFormat.getMinutes()).slice(-2) + ':' + ('0' + dateToFormat.getSeconds()).slice(-2);
-  }
-  else if(dateToFormat.getFullYear() === currDate.getFullYear() && dateToFormat.getMonth() === currDate.getMonth() && dateToFormat.getDate() === (currDate.getDate() - 1)) {
-    formattedDate = 'Gestern ';
-    formattedDate += ('0' + dateToFormat.getHours()).slice(-2) + ':' + ('0' + dateToFormat.getMinutes()).slice(-2) + ':' + ('0' + dateToFormat.getSeconds()).slice(-2);
-  }
-  else {
-    let dateOptions = { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' };
-    formattedDate = dateToFormat.toLocaleDateString('de-DE', dateOptions);
-  }
-
-  return formattedDate;
-}
-
-/**
- * Generiert eine Debug-Ausgabe, falls der globale debug-Parameter 'true' ist
- * @param {Object} msg Ausgabenachricht (kann null sein) (wird mittels console.log(msg) ausgegeben)
- * @param {Object} obj (optional) Objekt, was formatiert ausgegeben werden soll (wird mittels console.table(obj) ausgegeben)
- * @return {undefined}
- */
-function debugLog(msg, obj = null) {
-  if(!debug) return;
-  if(msg !== null) console.debug(msg);
-  if(obj !== null) console.table(obj);
-}
-
-/**
- * Setzt das Label zum aktuellen Speicher-Status
- * @param {String} action Aktueller Speicherstatus
- * @param {Date} currDate (optional) Aktuelles Datum
- * @returns {undefined}
- */
-function setSaveLabel(action, currDate = new Date()) {
-  var saveTime = formatDate(currDate);
-  $('#successLabel, #savingLabel, #failedLabel, #refreshedLabel').addClass('hidden');
-  switch(action) {
-    case 'saving':
-      $('#savingLabel').removeClass('hidden');
-      break;
-
-    case 'saved':
-      $('#saveTime').text(saveTime);
-      $('#successLabel').removeClass('hidden');
-      break;
-
-    case 'failed':
-      $('#failedLabel').removeClass('hidden');
-      break;
-
-    case 'refreshed':
-      $('#loadTime').text(saveTime);
-      $('#refreshedLabel').removeClass('hidden');
-      break;
-  }
-}
-
-/**
- * Aktiviert oder daktiviert das Overlay während Ladevorgängen
- * @param {Boolean} active True aktiviert das Overlay, false deaktiviert es
- * @returns {undefined}
- */
-function setOverlay(active = true) {
-  if(active) $('.loadingOverlay').removeClass('hidden');
-  if(!active) $('.loadingOverlay').addClass('hidden');
-}
-
-/**
- * Zeigt dem Nutzer eine Fehlermeldung an
- * @param {String} action    Aktion, bei der der Fehler aufgetreten ist
- * @param {String} message   (optional) Fehlermeldung
- * @param {Object} httperror (optional) Objekt der Form {'jqXHR':..., 'error':..., 'errorThrown':...} für HTTP Fehlermeldungen
- * @returns {undefined}
- */
-function showError(action, message = false, httperror = false) {
-  console.error('Fehler beim ' + action + ' - Fehlermeldung: ' + message + (httperror ? (' - HTTP Error: ' + httperror) : ''));
-  modal.find('.modal-title').html('<i class="fa fa-exclamation-circle"></i> Fehler');
-  if(message) {
-    modal.find('.modal-body').html('<div class="alert alert-danger"><h3>Beim ' + action + ' ist ein Fehler aufgetreten!</h3><p><strong>Fehlermeldung:</strong> ' + message + '</p></div>');
-  }
-  else {
-    if(httperror !== false) {
-      if(httperror.jqXHR.status === 401) {
-        modal.find('.modal-body').html('<div class="alert alert-danger"><h3>Beim ' + action + ' ist ein Fehler aufgetreten!</h3><p><strong>Fehlermeldung:</strong> Sie sind nicht angemeldet! Bitte erneut anmelden: <a class="btn btn-success btn-fill" href="index.html" target="_blank">Anmelden</a></p></div>');
-      }
-      else if(httperror.jqXHR.status === 403) {
-        modal.find('.modal-body').html('<div class="alert alert-danger"><h3>Beim ' + action + ' ist ein Fehler aufgetreten!</h3><p><strong>Fehlermeldung:</strong> Sie besitzen nicht die notwendigen Nutzergruppen, um diese SecDoc-Instanz zu verwenden!</p></div>');
-      }
-      else {
-        modal.find('.modal-body').html('<div class="alert alert-danger"><h3>Beim ' + action + ' ist ein Fehler aufgetreten!</h3><p><strong>Fehlermeldung:</strong> HTTP Code: ' + httperror.jqXHR.status + ' Fehler: ' + httperror.error + ' - ' + httperror.errorThrown + '</p></div>');
-      }
-    }
-    else {
-      modal.find('.modal-body').html('<div class="alert alert-danger"><h3>Beim ' + action + ' ist ein unbekannter Fehler aufgetreten! Bitte versuchen Sie es in Kürze erneut!</h3></div>');
-    }
-  }
-  modal.find('.modal-body').append('<p><button type="button" class="center-block btn btn-danger" data-dismiss="modal" aria-label="Close">Schließen</button></p>');
-  modal.modal();
-  modal.find('button[aria-label=Close]').focus();
-}
-
-/**
- * Fragt die PDF für das Verfahren mit der übergebenen ID an und öffnet einen "Öffnen/Speichern"-Dialog
- * @param {Number}  id    ID für die gewünschte PDF
- * @param {Boolean} draft (optional) Wenn true wird die letzte Draft-Version der PDF zurückgegeben
- * @return {undefined}
- */
-function getPDFFromServer(id, draft = false) {
-  setOverlay();
-
-  $.post(backendPath, JSON.stringify({'action':'getpdf', 'id': id, 'data': {'draft': draft}, 'debug': debug})).done((data) => {
-    if(!data['success']) {
-      showError('Laden der PDF', data['error']);
-      return;
-    }
-
-    if(!draft && data['data']['status'] === 0) {
-      modal.find('.modal-title').html('<i class="fa fa-info-circle"></i> Hinweis');
-      modal.find('.modal-body').html('<div class="alert alert-warning"><p>Da sich das Verfahren wieder im Zustand "In Bearbeitung" befindet, stimmen die Angaben in der PDF-Datei unter Umständen nicht mehr mit der aktualisierten Version überein! Die PDF-Datei wird nur bei einem erneuten Abschluss des Verfahrens aktualisiert.</p></div>');
-      modal.find('.modal-body').append('<p><button type="button" class="center-block btn btn-danger" data-dismiss="modal" aria-label="Close">Schließen</button></p>');
-      modal.modal();
-    }
-
-    // Base64 Kodierung umkehren und Blob zum Download erstellen
-    let pdfData = atob(data['data']['pdf'].replace(/\s/g, ''));
-    let pdfBuffer = new Uint8Array(new ArrayBuffer(pdfData.length));
-    for(let i=0; i < pdfData.length; i++) {
-      pdfBuffer[i] = pdfData.charCodeAt(i);
-    }
-    let blob = new Blob([pdfBuffer], {type: "application/pdf"});
-    let lastUpdate = data['data']['lastupdate'] ? new Date(data['data']['lastupdate'].replace(' ', 'T')) : new Date();  // Safari benötigt das Format YYYY-MM-DDTHH:MM:SS (mit T)
-    let typeName = {1: 'Verarbeitungstätigkeit', 2: 'IT-Verfahren', 3: 'Fachapplikation', 4: 'Übergreifende_Massnahme'};
-    let fileTitle = 'SecDoc_' + typeName[data['data']['type']] + '_' + id + '_' + data['data']['title'].replace(/\W/g, '_').substr(0, 40) + '_' + lastUpdate.getFullYear() + ('0' + (lastUpdate.getMonth() + 1)).slice(-2) + ('0' + lastUpdate.getDate()).slice(-2) + ('0' + lastUpdate.getHours()).slice(-2) + ('0' + lastUpdate.getMinutes()).slice(-2) + (draft ? '_DRAFT' : '' );
-    fileTitle = fileTitle.replace(/[/\\?%*:|"<>\.,;=\s]/g, '_');
-    fileTitle += '.pdf';
-
-    // PDF-Anzeige starten (Unterscheidung, ob Edge genutzt wird)
-    if(window.navigator && window.navigator.msSaveOrOpenBlob) {
-      window.navigator.msSaveOrOpenBlob(blob, fileTitle);
-    }
-    else {
-      let url = window.URL.createObjectURL(blob);
-      let download = $('<a></a>');
-      download.attr('href', url).attr('download', fileTitle).addClass('hidden');;
-      $('body').append(download);
-      download[0].click();
-      window.URL.revokeObjectURL(url);
-      download.remove();
-    }
-  }).fail((jqXHR, error, errorThrown) => {
-    showError('Laden der PDF-Datei', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-  }).always(() => {
-    setOverlay(false);
-  });
-}
-
-/**
- * Löscht ein Verfahren vom Server
- * @param {type} id Eindeutige ID des Verfahrens
- * @returns {undefined}
- */
-function deleteFromServer(id) {
-  $.get(backendPath, { 'action': 'delete', 'id': id, 'debug': debug }).done(function(data) {
-    if(!data['success']) {
-      showError('Löschen der Dokumentation', data['error']);
-    }
-  }).fail((jqXHR, error, errorThrown) => {
-    showError('Löschen der Dokumentation', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-  });
-}
-
-/*
- * Login-Unterseite laden
- */
-function loadLogin() {
-  $.get('assets/html/login.inc.html').done((data) => { $('#content').html(data); }).fail((jqXHR, error, errorThrown) => {
-    showError('Laden der Unterseite "' + page + '"', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-    setOverlay(false);
-  });
-}
-
-/**
- * Läd die angefragte Unterseite und Informationen über den aktuell eingeloggten Nutzer
- * @return {undefined}
- */
-function loadSubpage() {
-  $('#loginLabel').removeClass('hidden');
-  $('#logoutLabel').removeClass('hidden');
-
-  /*
-   * Nutzerkennung holen und anzeigen
-   */
-  getUserPromise = $.getJSON(backendPath + '?action=searchperson' + (debug ? '&debug=true' : '')).done((data) => {
-    if(data.length !== 0 && data['data'].length !== 0) {
-      version = data['version'];
-      userIsDSB = data['data'][0]['userIsDSB'];
-      userCanDSB = data['data'][0]['userCanDSB'];
-      userIsManager = data['data'][0]['userIsManager'];
-
-      $('#userLabel').text(data['data'][0]['name'] + (userIsDSB ? ' (Rolle: DSB/ISB)' : ' (Rolle: Nutzer)'));
-      $('#userLabel').attr('title', 'Kennung: ' + data['data'][0]['value']);
-
-      if(userCanDSB) {
-        $('#roleLabel').find('span').text(userIsDSB ? 'Nutzer' : 'DSB/ISB');
-        $('#roleLabel').removeClass('hidden').click(() => {
-          document.cookie = version.replace(/\W/g, '_') + '_dsb=' + (userIsDSB ? '0' : '1') + '; SameSite=Strict';
-          location.reload(true);
-        });
-      }
-    }
-    else {
-      console.error('Fehler beim Abruf der Nutzerkennung! Antwort: ' + data);
-      $('#userLabel').text('Unbekannt');
-    }
-    console.info(version);
-    $('#footer_version').text(version);
-  }).fail((jqXHR, error, errorThrown) => {
-    console.error('Fehler beim Abruf der Nutzerkennung! HTTP Code: ' + jqXHR.status + ' Fehler: ' + error + ' - ' + errorThrown);
-    $('#userLabel').text('Unbekannt');
-  });
-
-  /*
-   * Angefragte Unterseite laden
-   */
-  if(page === 'home' && (loadIdMain > 0 || copyIdMain > 0)) {
-    $.getJSON(backendPath + '?action=get&id=' + (copyIdMain ? copyIdMain : loadIdMain)+ (debug ? '&debug=true' : '')).done((data) => {
-      if(data['success']) {
-        page = 'home';
-        if(parseInt(data['data'][0]['Typ']) === 1) page = 'wizproc';
-        if(parseInt(data['data'][0]['Typ']) === 2) page = 'wizit';
-        if(parseInt(data['data'][0]['Typ']) === 3) page = 'wizapp';
-        if(parseInt(data['data'][0]['Typ']) === 4) page = 'wizmeasures';
-
-        $.get('assets/html/' + page + '.inc.html?' + Date.now()).done((data) => { $('#content').html(data); }).fail((jqXHR, error, errorThrown) => {
-          showError('Laden der Unterseite "' + page + '"', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-          setOverlay(false);
-        });
-      }
-      else {
-        showError('Laden der Dokumentation', data['error']);
-        $.get('assets/html/' + page + '.inc.html?' + Date.now()).done((data) => { $('#content').html(data); }).fail((jqXHR, error, errorThrown) => {
-          showError('Laden der Unterseite "' + page + '"', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-          setOverlay(false);
-        });
-      }
-    }).fail((jqXHR, error, errorThrown) => {
-      showError('Laden der Dokumentation', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-      setOverlay(false);
-    });
-  }
-  else {
-    $.get('assets/html/' + page + '.inc.html?' + Date.now()).done((data) => { $('#content').html(data); }).fail((jqXHR, error, errorThrown) => {
-      showError('Laden der Unterseite "' + page + '"', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-      setOverlay(false);
-    });
-  }
-}
-
-/*
- * Logout Button
- */
-$('#logoutLabel').click(() => {
-  setOverlay(true);
-  $.getJSON(backendPath + '?action=logout' + (debug ? '&debug=true' : '')).done((data) => {
-    if(data['success']) {
-      $(window).off('beforeunload'); // Meldung vor dem Verlassen der Seite abschalten
-      window.location.replace('index.html');
-    }
-    else {
-      showError('Abmelden', 'Funktion nicht verfügbar bei externer Anmeldung!');
-      setOverlay(false);
-    }
-  }).fail((jqXHR, error, errorThrown) => {
-    showError('Abmelden', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-    setOverlay(false);
-  });
-});
-
-/*
- * Überprüfen ob der Nutzer eingeloggt ist
- */
-$.getJSON(backendPath + '?action=loggedin' + (debug ? '&debug=true' : '')).done((data) => {
-  if(data.length !== 0 && data['success']) {
-    if(data['maintenance']) {
-      $('#maintenanceAlert').removeClass('hidden');
-      if(data['maintenanceMessage'] !== '') $('#maintenanceMessage').text(data['maintenanceMessage']);
-    }
-    loadSubpage();
-  }
-  else {
-    showError('Laden', 'Ein interner Fehler ist aufgetreten! Bitte wenden Sie sich an den Administrator.');
-    setOverlay(false);
-  }
-}).fail((jqXHR, error, errorThrown) => {
-  if(jqXHR.status === 403) {
-    showError('Laden', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-  }
-  loadLogin();
-});
-
-
-
- - - - -
- - - -
- - - - - - - diff --git a/docs/JSDoc/scripts/linenumber.js b/docs/JSDoc/scripts/linenumber.js deleted file mode 100644 index 4354785cea73f847d719e42cca760d5714b2e197..0000000000000000000000000000000000000000 --- a/docs/JSDoc/scripts/linenumber.js +++ /dev/null @@ -1,25 +0,0 @@ -/*global document */ -(() => { - const source = document.getElementsByClassName('prettyprint source linenums'); - let i = 0; - let lineNumber = 0; - let lineId; - let lines; - let totalLines; - let anchorHash; - - if (source && source[0]) { - anchorHash = document.location.hash.substring(1); - lines = source[0].getElementsByTagName('li'); - totalLines = lines.length; - - for (; i < totalLines; i++) { - lineNumber++; - lineId = `line${lineNumber}`; - lines[i].id = lineId; - if (lineId === anchorHash) { - lines[i].className += ' selected'; - } - } - } -})(); diff --git a/docs/JSDoc/scripts/prettify/Apache-License-2.0.txt b/docs/JSDoc/scripts/prettify/Apache-License-2.0.txt deleted file mode 100644 index d645695673349e3947e8e5ae42332d0ac3164cd7..0000000000000000000000000000000000000000 --- a/docs/JSDoc/scripts/prettify/Apache-License-2.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/docs/JSDoc/scripts/prettify/lang-css.js b/docs/JSDoc/scripts/prettify/lang-css.js deleted file mode 100644 index 041e1f59067977554f29146ed51c13bcf509f0af..0000000000000000000000000000000000000000 --- a/docs/JSDoc/scripts/prettify/lang-css.js +++ /dev/null @@ -1,2 +0,0 @@ -PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", -/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/docs/JSDoc/scripts/prettify/prettify.js b/docs/JSDoc/scripts/prettify/prettify.js deleted file mode 100644 index eef5ad7e6a07676b3919146d583d1c190bf1e163..0000000000000000000000000000000000000000 --- a/docs/JSDoc/scripts/prettify/prettify.js +++ /dev/null @@ -1,28 +0,0 @@ -var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; -(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= -[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), -l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, -q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, -q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, -"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), -a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} -for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], -"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], -H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], -J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ -I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), -["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", -/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), -["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", -hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= -!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p th:last-child { border-right: 1px solid #ddd; } - -.ancestors, .attribs { color: #999; } -.ancestors a, .attribs a -{ - color: #999 !important; - text-decoration: none; -} - -.clear -{ - clear: both; -} - -.important -{ - font-weight: bold; - color: #950B02; -} - -.yes-def { - text-indent: -1000px; -} - -.type-signature { - color: #aaa; -} - -.name, .signature { - font-family: Consolas, Monaco, 'Andale Mono', monospace; -} - -.details { margin-top: 14px; border-left: 2px solid #DDD; } -.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } -.details dd { margin-left: 70px; } -.details ul { margin: 0; } -.details ul { list-style-type: none; } -.details li { margin-left: 30px; padding-top: 6px; } -.details pre.prettyprint { margin: 0 } -.details .object-value { padding-top: 0; } - -.description { - margin-bottom: 1em; - margin-top: 1em; -} - -.code-caption -{ - font-style: italic; - font-size: 107%; - margin: 0; -} - -.source -{ - border: 1px solid #ddd; - width: 80%; - overflow: auto; -} - -.prettyprint.source { - width: inherit; -} - -.source code -{ - font-size: 100%; - line-height: 18px; - display: block; - padding: 4px 12px; - margin: 0; - background-color: #fff; - color: #4D4E53; -} - -.prettyprint code span.line -{ - display: inline-block; -} - -.prettyprint.linenums -{ - padding-left: 70px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.prettyprint.linenums ol -{ - padding-left: 0; -} - -.prettyprint.linenums li -{ - border-left: 3px #ddd solid; -} - -.prettyprint.linenums li.selected, -.prettyprint.linenums li.selected * -{ - background-color: lightyellow; -} - -.prettyprint.linenums li * -{ - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; -} - -.params .name, .props .name, .name code { - color: #4D4E53; - font-family: Consolas, Monaco, 'Andale Mono', monospace; - font-size: 100%; -} - -.params td.description > p:first-child, -.props td.description > p:first-child -{ - margin-top: 0; - padding-top: 0; -} - -.params td.description > p:last-child, -.props td.description > p:last-child -{ - margin-bottom: 0; - padding-bottom: 0; -} - -.disabled { - color: #454545; -} diff --git a/docs/JSDoc/styles/prettify-jsdoc.css b/docs/JSDoc/styles/prettify-jsdoc.css deleted file mode 100644 index 5a2526e374846d0c80af0c06c25d25215463a0d9..0000000000000000000000000000000000000000 --- a/docs/JSDoc/styles/prettify-jsdoc.css +++ /dev/null @@ -1,111 +0,0 @@ -/* JSDoc prettify.js theme */ - -/* plain text */ -.pln { - color: #000000; - font-weight: normal; - font-style: normal; -} - -/* string content */ -.str { - color: #006400; - font-weight: normal; - font-style: normal; -} - -/* a keyword */ -.kwd { - color: #000000; - font-weight: bold; - font-style: normal; -} - -/* a comment */ -.com { - font-weight: normal; - font-style: italic; -} - -/* a type name */ -.typ { - color: #000000; - font-weight: normal; - font-style: normal; -} - -/* a literal value */ -.lit { - color: #006400; - font-weight: normal; - font-style: normal; -} - -/* punctuation */ -.pun { - color: #000000; - font-weight: bold; - font-style: normal; -} - -/* lisp open bracket */ -.opn { - color: #000000; - font-weight: bold; - font-style: normal; -} - -/* lisp close bracket */ -.clo { - color: #000000; - font-weight: bold; - font-style: normal; -} - -/* a markup tag name */ -.tag { - color: #006400; - font-weight: normal; - font-style: normal; -} - -/* a markup attribute name */ -.atn { - color: #006400; - font-weight: normal; - font-style: normal; -} - -/* a markup attribute value */ -.atv { - color: #006400; - font-weight: normal; - font-style: normal; -} - -/* a declaration */ -.dec { - color: #000000; - font-weight: bold; - font-style: normal; -} - -/* a variable name */ -.var { - color: #000000; - font-weight: normal; - font-style: normal; -} - -/* a function name */ -.fun { - color: #000000; - font-weight: bold; - font-style: normal; -} - -/* Specify class=linenums on a pre to get line numbering */ -ol.linenums { - margin-top: 0; - margin-bottom: 0; -} diff --git a/docs/JSDoc/styles/prettify-tomorrow.css b/docs/JSDoc/styles/prettify-tomorrow.css deleted file mode 100644 index b6f92a78db990ec1dc52e032452a979b8c216a85..0000000000000000000000000000000000000000 --- a/docs/JSDoc/styles/prettify-tomorrow.css +++ /dev/null @@ -1,132 +0,0 @@ -/* Tomorrow Theme */ -/* Original theme - https://github.com/chriskempson/tomorrow-theme */ -/* Pretty printing styles. Used with prettify.js. */ -/* SPAN elements with the classes below are added by prettyprint. */ -/* plain text */ -.pln { - color: #4d4d4c; } - -@media screen { - /* string content */ - .str { - color: #718c00; } - - /* a keyword */ - .kwd { - color: #8959a8; } - - /* a comment */ - .com { - color: #8e908c; } - - /* a type name */ - .typ { - color: #4271ae; } - - /* a literal value */ - .lit { - color: #f5871f; } - - /* punctuation */ - .pun { - color: #4d4d4c; } - - /* lisp open bracket */ - .opn { - color: #4d4d4c; } - - /* lisp close bracket */ - .clo { - color: #4d4d4c; } - - /* a markup tag name */ - .tag { - color: #c82829; } - - /* a markup attribute name */ - .atn { - color: #f5871f; } - - /* a markup attribute value */ - .atv { - color: #3e999f; } - - /* a declaration */ - .dec { - color: #f5871f; } - - /* a variable name */ - .var { - color: #c82829; } - - /* a function name */ - .fun { - color: #4271ae; } } -/* Use higher contrast and text-weight for printable form. */ -@media print, projection { - .str { - color: #060; } - - .kwd { - color: #006; - font-weight: bold; } - - .com { - color: #600; - font-style: italic; } - - .typ { - color: #404; - font-weight: bold; } - - .lit { - color: #044; } - - .pun, .opn, .clo { - color: #440; } - - .tag { - color: #006; - font-weight: bold; } - - .atn { - color: #404; } - - .atv { - color: #060; } } -/* Style */ -/* -pre.prettyprint { - background: white; - font-family: Consolas, Monaco, 'Andale Mono', monospace; - font-size: 12px; - line-height: 1.5; - border: 1px solid #ccc; - padding: 10px; } -*/ - -/* Specify class=linenums on a pre to get line numbering */ -ol.linenums { - margin-top: 0; - margin-bottom: 0; } - -/* IE indents via margin-left */ -li.L0, -li.L1, -li.L2, -li.L3, -li.L4, -li.L5, -li.L6, -li.L7, -li.L8, -li.L9 { - /* */ } - -/* Alternate shading for lines */ -li.L1, -li.L3, -li.L5, -li.L7, -li.L9 { - /* */ } diff --git a/docs/JSDoc/wizard.js.html b/docs/JSDoc/wizard.js.html deleted file mode 100644 index 0113beeff76b9033ba5df42d8313d84ec4625b85..0000000000000000000000000000000000000000 --- a/docs/JSDoc/wizard.js.html +++ /dev/null @@ -1,2823 +0,0 @@ - - - - - JSDoc: Source: wizard.js - - - - - - - - - - -
- -

Source: wizard.js

- - - - - - -
-
-
/**
- * wizard.js - Funktionen für den Verfahrens-Wizard
- *
- * @file Setzt die dynamischen Funktionen der Verfahrenseingabe um und ergänzt den Wizard
- *
- * @requires assets/js/main.js
- * @requires assets/js/bootstrap-select.min.js
- * @requires assets/js/jquery.typeahead.min.js
- * @requires assets/js/jquery.validate.min.js
- * @requires assets/js/datatables.min.js
- * @requires assets/js/datatables_german.json
- *
- * @author Thorsten Küfer <thorsten.kuefer@uni-muenster.de>
- * @author Dustin Gawron <dustin.gawron@uni-muenster.de>
- * @copyright (c) 2018-2020 Westfälische Wilhelms-Universität Münster
- * @license AGPL-3.0-or-later <https://www.gnu.org/licenses/agpl.html>
- */
-
-// Zeitmessung starten
-console.time('Gesamte Vorbereitungszeit für Wizard');
-
-/*
- * Variablen initialisieren
- */
-// Allgemeine Variablen
-/**
- * Übergebene ID eines Verfahrens
- * @global
- * @type {Number}
- */
-var loadId = GetURLParameter('id') === false ? 0 : parseInt(GetURLParameter('id'));
-
-/**
- * Gibt an, ob ein Verfahren kopiert werden soll
- * @global
- * @type {Boolean}
- */
-var copyId = GetURLParameter('copy') === false ? false : parseInt(GetURLParameter('copy'));
-
-/**
- * Gibt an, ob das geladene Verfahren bearbeitet werden kann
- * @global
- * @type {Boolean}
- */
-var canEdit = true;
-
-/**
- * Speichert den aktuellen Bearbeitungs-Modus (entweder IT-Verfahren, Fachapplikation Verarbeitungstätigkeit)
- * @global
- * @type {String}
- */
-var mode = ['wizit', 'wizproc', 'wizapp', 'wizmeasures'].includes(page) ? page : 'wizproc';
-
-/**
- * Mapping des Typs
- * @global
- * @type {Object}
- */
-let modeMapping = {
-  1: ['Verarbeitungstätigkeit', 'Verarbeitungstätigkeiten', 'Die', 'eine', 'einer'],
-  2: ['IT-Verfahren', 'IT-Verfahren', 'Das', 'ein', 'einem'],
-  3: ['Fachapplikation', 'Fachapplikationen', 'Die', 'eine', 'einer'],
-  4: ['übergreifende Massnahme', 'übergreifende Massnahmen', 'Die', 'eine', 'einer']
-};
-
-/**
- * Interne Nummerierung für die Dokumentations-Modi
- * @global
- * @type {Number}
- */
-let modeNum = 0;
-if(mode === 'wizproc')       modeNum = 1;
-if(mode === 'wizapp')        modeNum = 3;
-if(mode === 'wizit')         modeNum = 2;
-if(mode === 'wizmeasures')   modeNum = 4;
-
-/**
- * Lesbarer Name des Modus; genutzt für die Ersetzung in Texten
- * @global
- * @type {Array}
- */
-var modeName = modeMapping[modeNum];
-
-/**
- * Gibt an, ob Eingaben geändert wurden seit dem letzten Laden/Speichern
- * @global
- * @type {Boolean}
- */
-var changedValues = false;
-
-/**
- * Liste der IDs aller veränderten Felder seit dem letzten Speichern
- * @global
- * @type {Array}
- */
-var changedFields = [];
-
-/**
- * Gibt an, ob das Verfahren als abgeschlossen markiert wurde
- * @global
- * @type {Boolean}
- */
-var markedAsFinished = false;
-
-/**
- * Gibt an, welchen Status das Verfahren hat
- * @global
- * @type {Number}
- */
-var status = 0;
-
-/**
- * Sammlung von Promises für AJAX-Anfragen, die zu Beginn durchgeführt werden müssen
- * @global
- * @type {Array}
- */
-var promises = [];
-
-/**
- * JS Interval Timer für regelmäßigen Autosave
- * @global
- * @type {Number}
- */
-var autoSaveTimer = 0;
-
-/**
- * Zeit zwischen Autosaves
- * @global
- * @type {Number}
- */
-var autoSaveWait = 600000;
-
-/**
- * Wird auf true gesetzt, wenn der Wizard zurückgesetzt wird (z.B. über "Neue Dokumentation")
- * @global
- * @type {Boolean}
- */
-var globalClear = false;
-
-// Mappings
-/**
- * Mapping für die Liste der TOMs
- * @global
- * @type {Array}
- */
-var tomsMapping = [];
-
-// Variablen für die Typeahead-Funktion
-/**
- * Cache für die Typeahead-Funktionen
- * @global
- * @type {Object}
- */
-var typeaheadCache = {};
-
-// Variablen für die endlosen Tabellen
-/**
- * Tabellen IDs für die endlosen Tabellen
- * @global
- * @type {Array}
- */
-var endlessTables = $.map($('table[data-tool="endlessTable"]'), function(table) { return $(table).attr('id'); });
-
-/**
- * Mapping von Templates für jede endlose Tabelle
- * @global
- * @type {Object}
- */
-var endlessTemplates = {};
-
-/**
- * Maping von Countern für jede endlose Tabelle
- * @global
- * @type {Object}
- */
-var endlessCounts = {};
-
-/*
- * JQuery Validator Einstellungen
- */
-jQuery.extend(jQuery.validator.messages, {
-    required: "Dieses Feld muss ausgefüllt werden!"
-});
-/* jQuery Validator funktioniert nicht bei Eingabefeldern mit gleichem name-Attribut...
-jQuery.validator.addMethod("forcelistselection", function(value, element) {
-  if($(element).closest('td').find('input[type=hidden]').val() === "") return false;
-  return true;
-}, "Es muss zwingend ein Element aus den Vorschlägen gewählt werden!");
-*/
-var validator = $('.wizard-card form').validate();
-
-/*
- * Notwendige Variablen vom Server holen
- */
-// Cache entfernen; erschwert nur die Aktualisierung von TOMs ohne großen Geschwindigkeitsvorteil
-if(localStorage.getItem('tom_cache_' + (document.location.host + document.location.pathname).replace(/\W/g, '_')) !== null) {
-  localStorage.removeItem('tom_cache_' + (document.location.host + document.location.pathname).replace(/\W/g, '_'));
-}
-
-// TOM Liste holen
-promises[0] = $.getJSON(backendPath + '?action=gettoms&data={"tier":' + modeNum + '}' + (debug ? '&debug=true' : '')).done((data) => {
-  if(!data['success']) {
-    showError('Holen der TOMs', data['error']);
-    return;
-  }
-
-  if(data['data'].length === 0) {
-    showError('Holen der TOMs', 'TOM Liste ist leer!');
-    return;
-  }
-
-  tomsMapping = data['data'];
-  // Nach Identifier sortieren
-  tomsMapping = tomsMapping.sort((a,b) =>  a.Identifier.localeCompare(b.Identifier, 'en', { numeric: true }));
-
-  let itTOMList = false;
-  tomsMapping.some((elem) => {
-    if(parseInt(elem['Mode']) === 1) {
-      itTOMList = true;
-      return true;
-    }
-  });
-}).fail((jqXHR, error, errorThrown) => {
-  showError('Holen der TOMs', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-});
-
-/*
- * Funktionen für den BSWizard
- */
-/**
- * Wird ausgeführt, wenn der Wizard gestartet wird (genutzt in {@link paper-bootstrap-wizard.js})
- * @returns {undefined}
- */
-function myInit() {
-  debugLog('Wizard begonnen...');
-}
-
-/**
- * Wird ausgeführt, falls ein Tab geklickt wird (genutzt in {@link paper-bootstrap-wizard.js})
- * @param {type} tab
- * @param {type} navigation
- * @param {type} index
- * @return {undefined}
- */
-function myTabClick(tab, navigation, index) {
-  var $valid = validator.form();
-  if (!$valid) {
-    validator.focusInvalid();
-    return false;
-  }
-  return true;
-}
-
-/**
- * Wird ausgeführt, wenn der nächste Tab gewählt wird (genutzt in {@link paper-bootstrap-wizard.js})
- * @param {Object} tab
- * @param {Object} nav
- * @param {Number} idx
- * @returns {undefined}
- */
-function myNext(tab, nav, idx) {
-  let $valid = validator.form();
-  if (!$valid) {
-    validator.focusInvalid();
-    return false;
-  }
-
-  debugLog('Speichere Tab ' + $(tab).text().trim());
-
-  // Nur neu abspeichern, wenn etwas geändert wurde
-  var savePromise = Promise.resolve();
-  if(changedValues) {
-    savePromise = saveOnServer();
-  }
-
-  if(!savePromise) {
-    return false;
-  }
-
-  return true;
-}
-
-/**
- * Wird ausgeführt, wenn zum vorherigen Tab zurückgekehrt wird (genutzt in {@link paper-bootstrap-wizard.js})
- * @param {Object} tab
- * @param {Object} nav
- * @param {Number} idx
- * @returns {undefined}
- */
-function myPrevious(tab, nav, idx) {
-  debugLog('Abbruch von Tab ' + $(tab).text().trim());
-}
-
-/**
- * Wird ausgeführt, wenn ein Tab verlassen wird (genutzt in {@link paper-bootstrap-wizard.js})
- * @param {Object} tab
- * @param {Object} nav
- * @param {Number} idx
- * @returns {undefined}
- */
-function myTabChange(tab, nav, idx) {
-  debugLog('Verlasse Tab ' + $(tab).text().trim());
-}
-
-/**
- * Wird ausgeführt, wenn der Wizard mit dem letzten Button beendet wird (genutzt in {@link paper-bootstrap-wizard.js})
- * @returns {undefined}
- */
-function myFinish() {
-  debugLog('Wizard beendet...');
-  setOverlay();
-  // Nur neu abspeichern, wenn etwas geändert wurde
-  var savePromise = Promise.resolve();
-  if(changedValues) {
-    savePromise = saveOnServer();
-  }
-
-  if(!savePromise) {
-    setOverlay(false);
-    return;
-  }
-  else {
-    savePromise.then(() => {
-      /*
-      // Bestätigung zum Abschluss erfragen
-      var confirmFinish = confirm('Wollen Sie die Dokumentation abschließen? Im Anschluss wird eine PDF-Version generiert und per E-Mail an alle eingetragenen Ansprechpartner und Ersteller verschickt.');
-      if(!confirmFinish) {
-        setOverlay(false);
-        return;
-      }
-      */
-
-      // Zeigt eine Fehlermeldung an, wenn Datenkategorien ohne Betroffene vorhanden sind (nur bei Verarbeitungstätigkeiten)
-      let currentState = saveAsObject();
-      if(mode === 'wizproc' && currentState.daten_kategorien_nummer !== undefined) {
-        let usedCats = new Set([]);
-        if(currentState.daten_personen_kategorie !== undefined) {
-          usedCats = new Set([].concat(...currentState.daten_personen_kategorie));
-        }
-        let knownCats = new Set([].concat(...currentState.daten_kategorien_nummer));
-        if(usedCats.size !== knownCats.size) {
-          let missCats = [...knownCats].filter(x => !usedCats.has(x));
-          showError('Abschließen des Verfahrens', 'Es sind Datenkategorien (' + missCats.join(', ') + ') vorhanden, die keinem Betroffenen zugeordnet sind! Bitte tragen Sie die entsprechenden Betroffenen ein und verknüpfen diese oder löschen Sie die nicht benötigten Kategorien.');
-          setOverlay(false);
-          return;
-        }
-      }
-
-      setOverlay(false);
-
-      // Revisions-Kommentar abfragen
-      modal.find('.modal-title').html('<i class="fa fa-archive"></i> Abschluss der Dokumentation');
-      let modalBody = modal.find('.modal-body');
-      modalBody.html('<p>Mit dem Abschluss wird eine neue Revision der Dokumentation angelegt. Es wird eine abschließende PDF-Version generiert und per E-Mail an alle eingetragenen Ansprechpartner und Ersteller verschickt. Sie können optional einen Kommentar zur aktuellen Bearbeitung angeben.</p>');
-      modalBody.append('<div class="form-group"><label>Kommentar</label><textarea class="form-control" id="finishComment" placeholder="Beschreibt die aktuellen Änderungen"></textarea></div>')
-      modalBody.append('<p><button type="button" class="center-block btn btn-fill btn-danger btn-wd" id="confirmFinish"><i class="fa fa-check-circle"></i> Abschließen</button></p>');
-
-      modalBody.find('#confirmFinish').click((evt) => {
-        $(evt.target).prop('disabled', true);
-        setOverlay();
-
-        // HTML-Code für PDF-Version generieren
-        let pdfCode = genHTMLforPDF();
-
-        // Abschluss API Aufruf
-        $.post(backendPath, JSON.stringify({'action': 'finish', 'debug': debug, 'id':  loadId, 'data': { 'title': $('[name="allgemein_bezeichnung"]').val(), 'pdfCode': pdfCode, 'lastupdate': $('[name="meta_lastupdate"]').val(), 'comment': modalBody.find('#finishComment').val()} })).done((data) => {
-          if(!data['success']) {
-            showError('Abschließen des Verfahrens', data['error']);
-            return;
-          }
-          markedAsFinished = true;
-          status = 2;
-
-          let statusSymbol = status in statusSymbolMapping ? ' <i data-toggle="tooltip" class="fa ' + statusSymbolMapping[status] + '" title="' + statusMapping[status]  + '"></i>' : '';
-          $('#title').find('i').replaceWith(statusSymbol);
-          $('#title').find('i').tooltip();
-
-          modal.find('.modal-title').html('<i class="fa fa-check-circle"></i> Dokumentation abgeschlossen');
-          var modalBody = modal.find('.modal-body');
-          modalBody.html('<p>Hiermit wurde die Dokumentation als abgeschlossen gekennzeichnet.</p>');
-          if(data['genpdf'] && data['genmail']) modalBody.append('<p class="alert alert-success">Die eingetragenen Ansprechpartner wurden per E-Mail informiert und haben eine PDF-Version der Dokumentation erhalten. Die PDF wurde abgespeichert und kann über den folgenden Knopf oder jederzeit in der Liste der ' + modeName[1] + ' heruntergeladen werden.<br /><button class="center-block btn" id="download_pdf">PDF herunterladen</button></p>');
-          if(mode === 'wizproc' && data['gentxt']) modalBody.append('<p class="alert alert-success">Es wurde ein Include-Baustein zur Verwendung in Webseiten bzw. Webanwendungen als Ergänzung zur zentralen Datenschutzerklärung erstellt. Sie können den passenden Text im Webserverpark mit Hilfe von SSI per <code>&lt;!--#include virtual="/sys/secdoc/' + loadId + '.txt" --&gt;</code> bzw. PHP per <code>readfile("/www/data/sys/includes/secdoc/' + loadId + '.txt")</code> einbinden.</p>');
-          if(!data['genpdf']) modalBody.append('<p class="alert alert-danger">Bei der Erstellung der PDF-Datei ist ein Fehler aufgetreten, bitte versuchen Sie es später erneut.</p>');
-          if(!data['genmail']) modalBody.append('<p class="alert alert-danger">Beim Verschicken der E-Mail ist ein Fehler aufgetreten, bitte versuchen Sie es später erneut.</p>');
-          if(mode === 'wizproc' && !data['gentxt']) modalBody.append('<p class="alert alert-danger">Beim Erzeugen des Informations-Textes zum Einbinden in Webseiten ist ein Fehler aufgetreten, bitte versuchen Sie es später erneut.</p>');
-          modalBody.append('<p>Die Dokumentation kann jederzeit aktualisiert werden und über den "Abschluss"-Knopf eine neue E-Mail sowie PDF-Datei erzeugt werden.</p>');
-          modalBody.append('<p><button type="button" class="center-block btn btn-danger" data-dismiss="modal" aria-label="Close">Schließen</button></p>');
-
-          modalBody.find('#download_pdf').click((evt) => {
-            getPDFFromServer(loadId);
-          });
-
-          modal.modal();
-        }).fail((jqXHR, error, errorThrown) => {
-          showError('Abschließen des Verfahrens', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-        }).always(() => { setOverlay(false); });
-      });
-
-      modal.modal();
-    });
-  }
-}
-
-/*
- * Hilfsfunktionen
- */
-/**
- * Zeigt eine Liste aller Verfahren an, auf die der Nutzer Zugriff hat
- * @param {Boolean} startup (optional) Gibt an, ob es sich um den Aufruf beim Laden der Seite handelt (wird nur geladen falls editierbare Verfahren vorhanden) oder ein manueller Aufruf
- * @returns {undefined}
- */
-function showVerfahrensliste(startup = false) {
-  console.time('Verfahrensliste laden');
-  var show = true;
-  modal.find('.modal-title').html('<i class="fa fa-list"></i> Liste bestehender ' + modeName[1]);
-  var modalBody = modal.find('.modal-body');
-  modalBody.html('<p>Wählen Sie eine Dokumentation aus der Liste, um sie zu bearbeiten oder einzusehen, oder legen Sie eine neue Dokumentation an.</p>');
-  modalBody.append('<ul class="nav nav-tabs" role="tablist"><li role="presentation" class="active"><a href="#listeditable" aria-controls="listeditable" role="tab" data-toggle="tab"><i class="fa fa-edit"></i> Editierbare ' + modeName[1] + '</a></li><li role="presentation"><a href="#listreadable" aria-controls="listreadable" role="tab" data-toggle="tab"><i class="fa fa-eye"></i> Einsehbare ' + modeName[1] + '</a></li></ul>');
-  modalBody.append('<div class="tab-content" style="min-height: auto;"><div role="tabpanel" class="tab-pane active" id="listeditable"><p style="padding-top:10px; padding-left:10px">Hier werden alle ' + modeName[1] + ' gelistet, die Sie bearbeiten können.</p></div><div role="tabpanel" class="tab-pane" id="listreadable"><p style="padding-top:10px; padding-left:10px">Hier werden alle ' + modeName[1] + ' gelistet, auf die Sie nur lesend zugreifen können.</p></div></div>');
-  modalBody.find('#listeditable').append('<div class="col-sm-12 table-responsive"><table id="editableprocesses" class="table table-striped table-hover btn-table"><thead><tr><th class="no-sort no-print"></th><th>Bezeichnung</th><th>Organisationseinheit</th><th>Status</th><th>Letzter Bearbeiter</th><th>Letzte Aktualisierung</th><th class="no-sort none"></th></tr></thead><tbody></tbody></table></div>');
-  modalBody.find('#listreadable').append('<div class="col-sm-12 table-responsive"><table id="readableprocesses" class="table table-striped table-hover btn-table"><thead><tr><th class="no-sort no-print"></th><th>Bezeichnung</th><th>Organisationseinheit</th><th>Status</th><th>Letzte Aktualisierung</th><th class="no-sort none"></th></tr></thead><tbody></tbody></table></div>');
-
-  $.get(backendPath, { 'action': 'list', 'debug': debug }).done((data) => {
-    if(!data['success']) {
-      showError('Abrufen der Verfahrensliste', data['error']);
-      return;
-    }
-
-    // Nicht anzeigen, falls keine Verfahren vorhanden
-    if(startup && data['count'] === 0) {
-      show = false;
-      return;
-    }
-
-    let modeCount = 0;
-
-    for(var c=0; c < data['count']; c++) {
-      // Filter nach Ebene
-      let currType = parseInt(data['data'][c]['Typ']);
-      if(currType === 1 && mode !== 'wizproc')     continue;
-      if(currType === 2 && mode !== 'wizit')       continue;
-      if(currType === 3 && mode !== 'wizapp')      continue;
-      if(currType === 4 && mode !== 'wizmeasures') continue;
-
-      modeCount++;
-
-      let currId = parseInt(data['data'][c]['ID']);
-      let newEntry = $('<tr></tr>');
-      let statusSymbol = data['data'][c]['Status'] in statusSymbolMapping ? ' <i class="fa ' + statusSymbolMapping[data['data'][c]['Status']] + '"></i>' : '';
-      let statusName   = data['data'][c]['Status'] in statusMapping ? statusMapping[data['data'][c]['Status']] : statusMapping['9'];
-      let lastUpdate   = data['data'][c]['Aktualisierung'] ? formatDate(new Date(data['data'][c]['Aktualisierung'].replace(' ', 'T'))) : 'Unbekannt';
-
-      // Editierbare/Eigene Verfahren
-      if(data['data'][c]['Editierbar'] === true) {
-        newEntry.append('<td style="width: 16px;"></td>');
-        newEntry.append('<td>' + data['data'][c]['Bezeichnung'] + ' <i data-toggle="tooltip" class="fa fa-info-circle" title="' + data['data'][c]['Beschreibung'] + '"></i></td>');
-        newEntry.append('<td>' + data['data'][c]['Fachabteilung']  + '</td>');
-        newEntry.append('<td>' + statusName + statusSymbol + '</td>');
-        newEntry.append('<td>' + data['data'][c]['LetzterBearbeiter'] + ' <i data-toggle="tooltip" class="fa fa-info-circle" title="' + (data['data'][c]['BearbeiterDetails'] ? data['data'][c]['BearbeiterDetails'] : '<Keine Details vorhanden>') + '"></i></td>');
-        newEntry.append('<td data-order="' + (data['data'][c]['Aktualisierung'] ? new Date(data['data'][c]['Aktualisierung'].replace(' ', 'T')).getTime() : new Date().getTime()) + '">' + lastUpdate + ' <i class="fa fa-history cursor-progress revisionload" data-id="' + currId + '"></i></td>');
-        newEntry.append('<td><div class="btn-group inline"><a class="btn" href="?id=' + currId + (debug ? '&debug=true' : '') + '" target="_blank"><i class="fa fa-edit"></i> Bearbeiten</a><a class="btn" href="?copy=' + currId + '" target="_blank"><i class="fa fa-copy"></i> Kopieren</a><button type="button" title="Die PDF-Version repräsentiert das zuletzt abgeschlossene Verfahren!" data-id="' + currId + '" class="btn pdfdownload" ' + (data['data'][c]['PDF'] ? '' : 'disabled') + '><i class="fa fa-file-pdf-o"></i> ' + (parseInt(data['data'][c]['Status']) === 0 ? 'Letzte abgeschlossene PDF anzeigen' : 'PDF anzeigen') + '</button></div> <button type="button" data-id="' + currId +'" data-name="' + data['data'][c]['Bezeichnung'] +'" class="btn del btn-danger" ' + (data['data'][c]['Löschbar'] === true ? '' : 'disabled')  + '><i class="fa fa-minus"></i> Löschen</button></td>');
-        modalBody.find('#editableprocesses tbody').append(newEntry);
-      }
-      else {
-        newEntry.append('<td style="width: 16px;"></td>');
-        newEntry.append('<td>' + data['data'][c]['Bezeichnung'] + ' <i data-toggle="tooltip" class="fa fa-info-circle" title="' + data['data'][c]['Beschreibung'] + '"></i></td>');
-        newEntry.append('<td>' + data['data'][c]['Fachabteilung']  + '</td>');
-        newEntry.append('<td>' + statusName + statusSymbol + '</td>');
-        newEntry.append('<td data-order="' + (data['data'][c]['Aktualisierung'] ? new Date(data['data'][c]['Aktualisierung'].replace(' ', 'T')).getTime() : new Date().getTime()) + '">' + lastUpdate + ' <i class="fa fa-history cursor-progress revisionload" data-id="' + currId + '"></i></td>');
-        newEntry.append('<td><div class="btn-group inline"><a class="btn" href="?id=' + currId + (debug ? '&debug=true' : '') + '" target="_blank"><i class="fa fa-edit"></i> Anzeigen</a><a class="btn" href="?copy=' + currId + '" target="_blank"><i class="fa fa-copy"></i> Kopieren</a><button type="button" data-id="' + currId + '" class="btn pdfdownload" ' + (data['data'][c]['PDF'] ? '' : 'disabled') + '><i class="fa fa-file-pdf-o"></i> ' + (parseInt(data['data'][c]['Status']) === 0 ? 'Letzte abgeschlossene PDF anzeigen' : 'PDF anzeigen') + '</button></div></td>');
-        modalBody.find('#readableprocesses tbody').append(newEntry);
-      }
-    }
-
-    if(modeCount === 0) {
-      show = false;
-      return;
-    }
-
-    // Handler für PDF-Anzeige
-    modalBody.off('click', 'button.pdfdownload');
-    modalBody.on('click', 'button.pdfdownload', function(event){
-      getPDFFromServer($(event.target).data('id'));
-    });
-
-    // Handler für das Löschen von Verfahren
-    modalBody.off('click', 'button.del');
-    modalBody.on('click', 'button.del', function() {
-      var confirmed = confirm('Achtung: Von diesem Verfahren könnten andere Verfahren abhängen! Wollen Sie das Verfahren "' + $(this).data('name') + '" wirklich löschen?');
-      if(confirmed) {
-        deleteFromServer($(this).data('id'));
-        let row = $(this).parents('tr');
-        if(row.hasClass('child')) row = row.prev();
-        $(this).parents('table').DataTable().row(row).remove().draw();
-        if(parseInt($(this).data('id')) === loadId) loadEmpty(); // Leere das geladene Verfahren nur, wenn es das gelöschte ist
-      }
-    });
-
-    // Tooltips und DataTables initialisieren
-    modalBody.find('i.revisionload').on('mouseover', (evt) => {
-      let evtTarget = $(evt.target);
-
-      if(!evtTarget.hasClass('revisionload')) return;
-
-      evtTarget.addClass('hover');
-      evtTarget.removeClass('revisionload');
-
-      $.get(backendPath, {'action': 'listrevisions', 'debug': debug, 'id':  evtTarget.data('id')}).done((data) => {
-        if(!data['success']) {
-          evtTarget.prop('title', '<Fehler beim Holen der Revisionen>');
-        }
-        else {
-          let revisions = $('<div><p>Letzte 5 Revisionen:</p><ul></ul></div>');
-          let revList   = revisions.find('ul');
-          for(let c=0; c < data['count'] && c < 5; c++) {
-            let revDate = formatDate(new Date(data['data'][c]['Date'].replace(' ', 'T')));
-            revList.append('<li>#' + data['data'][c]['Revision'] + ' - ' + revDate + ' - ' + data['data'][c]['Editor'] + (data['data'][c]['Comment'] !== '' ? ' - ' + data['data'][c]['Comment'] : ''));
-          }
-          if(data['count'] === 0) revList.replaceWith('<Keine Revisionen vorhanden>');
-          evtTarget.prop('title', revisions[0].outerHTML);
-        }
-      }).fail((jqXHR, error, errorThrown) => {
-        evtTarget.prop('title', '<Fehler beim Holen der Revisionen>');
-      }).always(() => {
-        evtTarget.removeClass('cursor-progress').addClass('cursor-help');
-        evtTarget.tooltip({container: 'body', html: true});
-        if(evtTarget.hasClass('hover')) evtTarget.tooltip('show');
-      });
-    });
-    modalBody.find('i.revisionload').on('mouseleave', (evt) => { $(evt.target).removeClass('hover'); });
-
-    modalBody.find('[data-toggle="tooltip"]').tooltip({container: 'body'});
-    modalBody.find('table').DataTable({
-      language: {
-        url: 'assets/js/datatables_german.json'
-      },
-      columnDefs: [
-        {
-          targets: 'no-sort',
-          orderable: false
-        },
-        {
-          className: 'control',
-          orderable: false,
-          targets:   0
-        }
-      ],
-      responsive: {
-        details: {
-          type: 'column',
-          target: 'tr'
-        }
-      },
-      order: [ 1, 'asc' ],
-      autoWidth: false
-    });
-  }).fail((jqXHR, error, errorThrown) => {
-    showError('Abrufen der Verfahrensliste', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-  }).always(() => {
-    $('#showVerfahrensliste').prop('disabled', false);
-    setOverlay(false);
-    console.timeEnd('Verfahrensliste laden');
-    if(show) {
-      modalBody.append('<p><button type="button" class="btn btn-success btn-fill loadEmpty"><i class="fa fa-plus"></i> Neue Dokumentation für ' + modeName[0] + '  anlegen</button><button type="button" class="btn btn-danger ml pull-right" data-dismiss="modal" aria-label="Close">Schließen</button></p>');
-      modalBody.find('.loadEmpty').click(function() {
-        if(!canEdit) {
-          window.location.href = "?page=" + mode;
-        }
-        else {
-          history.replaceState({}, document.title, window.location.href.split('?')[0]);
-          loadEmpty();
-          modal.modal('hide');
-        }
-      });
-      modal.modal();
-    }
-  });
-}
-
-/*
- * Speicher- und Ladefunktionen
- */
-/**
- * Lädt ein leeres, neues Verfahren und setzt dazu alle Eingabefelder zurück
- * @returns {undefined}
- */
-function loadEmpty() {
-  console.time('Leeres Verfahren laden');
-  setOverlay();
-  globalClear = true;
-
-  if(changedValues) {
-    let confirmClear = confirm('Es sind noch ungespeicherte Änderungen vorhanden, die beim Leeren der Dokumentation verloren gehen. Wollen Sie wirklich fortfahren?');
-
-    if(!confirmClear) {
-      setSaveLabel('failed');
-      setOverlay(false);
-      globalClear = false;
-      console.timeEnd('Leeres Verfahren laden');
-      return;
-    }
-  }
-
-  // ID leeren
-  loadId = 0;
-  $('input[name=meta_id]').val(loadId);
-
-  // Status zurücksetzen
-  status = 0;
-  markedAsFinished = false;
-
-  // Felder wieder bearbeitbar machen
-  $('#content').find('input, textarea, select, button[id!="showVerfahrensliste"]').prop('disabled', false);
-  canEdit = true;
-
-  // Tabellen, Eingabefelder und Checkboxen zurücksetzen
-  endlessTables.forEach(function(table) {
-    removeTableRows(table);
-  });
-  $('input[type=text], textarea').not('[name$="_nummer[]"]').val('');
-  $('input[type=checkbox]:not(#showFinishedTOMs)').prop('checked', false).trigger('change');
-  $('.wizard-navigation li a').first().click();
-  endlessTables.forEach(function(table) {
-    addTableRow(table);
-  });
-  $('#abschluss_vonabhaengig tbody tr').remove();
-
-  // Clear title
-  document.title = document.title.split(' - ').slice(-1)[0];
-  let emptyTitle = 'Dokumentation einer Verarbeitungstätigkeit';
-  if(mode === 'wizapp')       emptyTitle = 'Dokumentation einer Fachapplikation';
-  if(mode === 'wizit')        emptyTitle = 'Dokumentation eines IT-Verfahrens';
-  if(mode === 'wizmeasures')  emptyTitle = 'Dokumentation von übergreifenden Massnahmen';
-  let statusSymbol = status in statusSymbolMapping ? ' <i data-toggle="tooltip" class="fa ' + statusSymbolMapping[status] + '" title="' + statusMapping[status]  + '"></i>' : '';
-  $('#title').text(emptyTitle).append(statusSymbol).find('i').tooltip();
-
-  setSaveLabel('failed');
-  setOverlay(false);
-  globalClear = false;
-  console.timeEnd('Leeres Verfahren laden');
-}
-
-/**
- * Gibt die Eingaben in Input-Feldern als strukturierstes Objekt zurück mit den Namen als Schlüssel
- * @example { "meta_id":0, "allgemein_bezeichnung":"Test Verfahren", ... }
- * @returns {Object}
- */
-function saveAsObject() {
-  var output = {};
-  var inputs = $('form').find('input[type!=button], textarea, select, checkbox');
-  for (var inp of inputs) {
-    inp = $(inp);
-    var name = inp.attr('name');
-    if (name === '' || name === undefined) continue;
-    if (name.slice(-2) === '[]') {
-      name = name.slice(0, -2);
-      if (!(name in output)) output[name] = [];
-      if (inp[0].type === 'checkbox') {
-        output[name].push(inp.prop('checked') ? inp.val() : '0');
-      }
-      else if (inp[0].type === 'radio') {
-        if(inp.prop('checked')) output[name].push(inp.val());
-      }
-      else {
-        output[name].push(inp.val());
-      }
-    } else {
-      if (inp[0].type === 'checkbox') {
-        output[name] = inp.prop('checked') ? inp.val() : '0';
-      }
-      else if (inp[0].type === 'radio') {
-        if(inp.prop('checked')) output[name] = inp.val();
-      }
-      else {
-        output[name] = inp.val();
-      }
-    }
-  }
-  return output;
-}
-
-/**
- * Liest ein JSON-String ein und stellt die Eingaben wieder her (wenn keine passenden Felder gefunden werden, werden diese ignoriert)
- * @param {String} values JSON-String mit Namen der Eingabefelder als Schlüssel
- * @returns {Boolean}
- */
-function loadFromJSON(values, keepAccess = false) {
-  let missingFields = [];
-
-  endlessTables.forEach(function(table) {
-    if(keepAccess && ['meta_gruppen', 'meta_nutzer'].includes(table)) return;
-    removeTableRows(table);
-  });
-
-  try {
-    values = JSON.parse(values);
-  } catch(e) {
-    showError('Laden der Dokumentation', 'Kein gültiges JSON - ' + e);
-    return false;
-  }
-
-  // Fallback für fehlende TOM Kategorie Auswahlfelder
-  let tomFields = Object.keys(values).filter((elem) => (elem.search('massnahmen_') >= 0));
-  tomFields.forEach((id) => {
-    id = id.split('_')[1];
-    if(['risiko', 'vertraulichkeit', 'integritaet', 'verfuegbarkeit'].includes(id)) return;
-    let tomEntry = tomsMapping.filter((elem) => (elem.Identifier === id));
-    if(tomEntry.length === 0) return;
-    let targetSubcategory = ('tom_toggle_' + tomEntry[0]['Category'].trim() + '_' + (tomEntry[0]['Subcategory'].trim() ? tomEntry[0]['Subcategory'].trim() : 'all')).replace(/\W/g, '_');
-    $('input[name="' + targetSubcategory + '"]:not(:checked)').prop('checked', true).trigger('change');
-  });
-
-  var extendedTables = [];
-  Object.keys(values).forEach(function(val, idx) {
-    if(Array.isArray(values[val])) {
-      var table = val.substring(0,val.lastIndexOf('_'));
-      if(!extendedTables.includes(table)) {
-        for(let c = 0; c < values[val].length; c++) {
-          addTableRow(table);
-        }
-        extendedTables.push(table);
-      }
-
-      var inputs = $('#' + table).find('[name="' + val + '[]"]');
-
-      if(inputs.length === 0) {
-        debugLog('Konnte keine Eingabefelder mit Namen "' + val + '" finden! Überspringe...');
-        missingFields.push(htmlEncode(val));
-        return true;
-      }
-
-      for(let c = 0; c < values[val].length; c++) {
-        if(inputs[c].type === 'checkbox') {
-          if(values[val][c] !== '0' && !$(inputs[c]).prop('checked')) $(inputs[c]).prop('checked', true).trigger('change');
-        }
-        else if(inputs[c].type === 'radio') {
-          let fieldsPerValue = inputs.length / values[val].length;
-          for(let d = 0; d < fieldsPerValue; d++) {
-            if(inputs[c * fieldsPerValue + d].value === values[val][c] && !$(inputs[c * fieldsPerValue + d]).prop('checked')) $(inputs[c * fieldsPerValue + d]).prop('checked', true).trigger('change');
-          }
-        }
-        else {
-          if(!Array.isArray(values[val][c])) values[val][c] = htmlDecode(values[val][c]);
-          $(inputs[c]).val(values[val][c]).trigger('change');
-        }
-      }
-    }
-    else {
-      var inp = $('[name="' + val + '"]');
-      if(inp.length === 1) {
-        if(inp[0].type === 'checkbox') {
-          if(values[val] !== '0' && !inp.prop('checked')) inp.prop('checked', true).trigger('change');
-        }
-        else {
-          if(!Array.isArray(values[val])) values[val] = htmlDecode(values[val]);
-          inp.val(values[val]);
-        }
-      }
-      else if(inp.length > 1 && inp[0].type === 'radio') {
-        for(let c = 0; c < inp.length; c++) {
-          if(inp[c].value === values[val] && !$(inp[c]).prop('checked')) $(inp[c]).prop('checked', true).trigger('change');
-        }
-      }
-      else {
-        debugLog('Keine passenden oder mehrere Eingabefelder mit Namen "' + val + '" gefunden! Überspringe...');
-        missingFields.push(htmlEncode(val));
-      }
-    }
-  });
-  $('select.selectpicker, select[data-tool=selectpicker]').selectpicker('refresh');
-  $('select.selectpicker, select[data-tool=selectpicker]').selectpicker('render');
-
-  // Meldung über gespeicherte Eingabefelder, die nicht mehr vorhanden sind anzeigen (nur DSB)
-  if(userIsDSB && missingFields.length > 0) {
-    let missingFieldsHTML = '<li>' + missingFields.join('</li><li>') + '</li>';
-    showError('Zuordnen gespeicherter Felder', 'Folgende gespeicherte Felder existieren nicht mehr und die eingegebenen Daten gehen beim Speichern verloren: <ul>' + missingFieldsHTML + '</ul>');
-  }
-
-  // Angehängte Dokumente laden
-  loadDocuments();
-
-  return true;
-}
-
-/**
- * Sendet die aktuellen Eingaben an den Server und versucht diese abzuspeichern
- * @returns {Promise|Boolean} Sollte das Formular fehlende Elemente enhalten oder das Speichern abgelehnt werden false, sonst das Promise-Objekt der Ajax-Anfrage
- */
-function saveOnServer() {
-  setSaveLabel('saving');
-  var idField = $('input[name=meta_id]');
-  var currentState = saveAsObject();
-
-  // Zeigt eine Fehlermeldung an, falls notwendige Felder leer sind
-  if(!validator.form()) {
-    setSaveLabel('failed');
-    var errorList = $('<ul></ul>');
-    $(validator.toShow).each(function() {
-      errorList.append('<li>' + $(this).closest('.form-group').find('label').first().text().trim() + '</li>');
-    });
-    validator.focusInvalid();
-    showError('Speichern der Dokumentation', 'Es wurden nicht alle notwendigen Felder ausgefüllt:' + errorList[0].outerHTML);
-    return false;
-  }
-
-  // Zeigt eine Fehlermeldung an, wenn für die Zugriffsberechtigungen manuelle Eingaben genommen wurden
-  let foundInvalidHidden = false;
-  $('input[name="meta_gruppen_kennung[]"], input[name="meta_nutzer_kennung[]"]').each(function() {
-    if($(this).val() === '' && $(this).parent().find('input[name="meta_gruppen_name[]"], input[name="meta_nutzer_name[]"]').val() !== '') foundInvalidHidden = true;
-  });
-
-  if(foundInvalidHidden) {
-    setSaveLabel('failed');
-    showError('Speichern der Dokumentation', 'Es wurden nicht alle Gruppen- bzw. Nutzerkennungen für die Zugriffsberechtigungen korrekt ausgewählt! Bitte überprüfen Sie die Eingaben und nutzen Sie nur Vorschläge aus der Liste.');
-    return false;
-  }
-
-  // Falls ID == 0 wird ein neues Verfahren auf dem Server angelegt
-  if(!loadId) {
-    return $.post(backendPath, JSON.stringify({'action':'create', 'debug': debug, 'data': currentState})).done(function(data) {
-      if(data['success']) {
-        loadId = parseInt(data['data']['ID']);
-        idField.val(loadId);
-        history.replaceState({}, document.title, window.location.href.split('?')[0] + '?id=' + loadId);
-        setSaveLabel('saved', new Date(data['data']['Date'].replace(' ', 'T')));  // Safari benötigt das Format YYYY-MM-DDTHH:MM:SS (mit T)
-        $('input[name="meta_lastupdate"]').val(data['data']['Date']);
-        changedValues = false;
-        changedFields = [];
-      }
-      else {
-        showError('Anlegen der Dokumentation', data['error']);
-        setSaveLabel('failed');
-      }
-    }).fail((jqXHR, error, errorThrown) => {
-      showError('Anlegen der Dokumentation', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-      setSaveLabel('failed');
-    });
-  }
-  // Falls die ID != 0 ist, wird ein vorhandenes Verfahren aktualisiert
-  else {
-    // Erfragt eine Bestätigung, falls das Verfahren bereits im Betrieb sein sollte
-    if(markedAsFinished) {
-      var confirmSave = confirm('Wenn Sie die aktuellen Änderungen abspeichern, wird der Status auf "In Bearbeitung" zurückgesetzt. Wollen Sie wirklich fortfahren?');
-      if(!confirmSave) {
-        setSaveLabel('failed');
-        return false;
-      }
-    }
-
-    return $.post(backendPath, JSON.stringify({'action':'update', 'debug': debug, 'id': loadId, 'data': currentState})).done(function(data) {
-      if(!data['success']) {
-        let errorText = data['error'];
-
-        if(errorText.includes('bearbeitet')) {
-          let unsavedChanges = $('<div></div>').append('<p><h4>Übersicht der ungespeicherten Änderungen</h4><table class="table table-bordered bg-info"><thead><tr><th>Feld</th><th>Inhalt</th></tr></thead><tbody></tbody></table></p>');
-          let changedFieldsCopy = [...new Set(changedFields)];
-          let changedFieldsRest = [];
-
-          changedFieldsCopy.forEach((x, idx) => {
-            let fieldName = $('[name="' + x + '"]').first().closest('div.form-group').find('label').text();
-            if(!fieldName) fieldName = $('[name="' + x + '"]').first().closest('table').closest('div').prev().find('h1, h2, h3, h4, h5, h6, .info-text').text();
-
-            if(fieldName) {
-              let val = htmlEncode($('[name="' + x + '"]').val());
-
-              if(x.includes('[]')) val = 'Tabelle verändert';
-
-              unsavedChanges.find('tbody').append('<tr><td>' + htmlEncode(fieldName) + '</td><td>' + val + '</td></tr>');
-            }
-            else {
-              changedFieldsRest.push(x);
-            }
-          });
-
-          changedFieldsRest.forEach((x, idx) => {
-            if(x.includes('tom_toggle_')) {
-              if($('[name="' + x + '"]').prop('checked')) {
-                unsavedChanges.find('tbody').append('<tr><td>TOM Kategorie ausgewählt</td><td>' + htmlEncode($('[name="' + x + '"]').parent().text()) + '</td></tr>');
-              }
-              else {
-                unsavedChanges.find('tbody').append('<tr><td>TOM Kategorie abgewählt</td><td>' + htmlEncode($('[name="' + x + '"]').parent().text()) + '</td></tr>');
-              }
-            }
-            else if(x.includes('massnahmen_') && x !== 'massnahmen_risiko') {
-              if($('[name="' + x + '"]').prop('nodeName') === 'SELECT') {
-                let val = 'Nein';
-                switch($('[name="' + x + '"]').val()) {
-                  case '1': val = 'Ja'; break;
-                  case '0': val = 'Nein'; break;
-                  case '2': val = 'Teilweise'; break;
-                  case '4': val = 'Entbehrlich'; break;
-                }
-                unsavedChanges.find('tbody').append('<tr><td>Umsetzung Massnahme ' + htmlEncode($('[name="' + x + '"]').closest('tr').find('td').first().text()) + '</td><td>' + val + '</td></tr>');
-              }
-              else {
-                unsavedChanges.find('tbody').append('<tr><td>Kommentar Massnahme ' + htmlEncode($('[name="' + x + '"]').closest('tr').find('td').first().text()) + '</td><td>' + htmlEncode($('[name="' + x + '"]').val()) + '</td></tr>');
-              }
-            }
-            else {
-              unsavedChanges.find('tbody').append('<tr><td>' + htmlEncode(x) + '</td><td>' + htmlEncode($('[name="' + x + '"]').val()) + '</td></tr>');
-            }
-          });
-
-          errorText = errorText + '<br />' + unsavedChanges.html();
-        }
-
-        showError('Speichern der Dokumentation', errorText);
-        setSaveLabel('failed');
-      }
-      else {
-        setSaveLabel('saved', new Date(data['data']['Date'].replace(' ', 'T')));  // Safari benötigt das Format YYYY-MM-DDTHH:MM:SS (mit T)
-        $('input[name="meta_lastupdate"]').val(data['data']['Date']);
-        history.replaceState({}, document.title, window.location.href.split('?')[0] + '?id=' + loadId);
-        changedValues = false;
-        changedFields = [];
-
-        // Hinweis anzeigen, falls Status zurückgesetzt wurde
-        if(markedAsFinished) {
-          modal.find('.modal-title').html('<i class="fa fa-power-off"></i> Status zurückgesetzt');
-          modal.find('.modal-body').html('<p>' + (mode === 'wizproc' ? 'Die Verarbeitungstätigkeit' : 'Das IT-Verfahren') + ' wurde zurück auf "In Bearbeitung" gesetzt und muss erneut abgeschlossen werden, um erneut als "In Betrieb" gekennzeichnet zu werden.</p>');
-          modal.find('.modal-body').append('<p><button type="button" class="center-block btn btn-danger" data-dismiss="modal" aria-label="Close">Schließen</button></p>');
-          modal.modal();
-          markedAsFinished = false;
-
-          // Status aktualisieren
-          status = 0;
-          let statusText = status in statusMapping ? statusMapping[status] : statusMapping['9'];
-          let statusSymbol = status in statusSymbolMapping ? ' <i data-toggle="tooltip" class="fa ' + statusSymbolMapping[status] + '" title="' + statusText + '"></i>' : '';
-          $('#title').find('i').replaceWith(statusSymbol);
-          $('#title').find('i').tooltip();
-        }
-      }
-    }).fail((jqXHR, error, errorThrown) => {
-      showError('Speichern der Dokumentation', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-      setSaveLabel('failed');
-    });
-  }
-}
-
-/**
- * Fragt ein Verfahren am Server an und läd es in die Vorlage
- * @param {Number} id Eindeutige ID des Verfahrens
- * @returns {undefined}
- */
-function loadFromServer(id) {
-  console.time('Verfahren laden');
-  setOverlay();
-  $.post(backendPath, JSON.stringify({'action':'get', 'id': id, 'debug': debug})).done(function(data) {
-    if(data['success']) {
-      if(!data['data'][0]['JSON']) {
-        loadId = false;
-        showError('Laden der Dokumentation', 'Kein JSON-Inhalt zum Laden verfügbar!');
-        return;
-      }
-      loadFromJSON(data['data'][0]['JSON']);
-      markedAsFinished = (parseInt(data['data'][0]['Status']) === 2);
-      status = parseInt(data['data'][0]['Status']);
-      loadId = parseInt(data['data'][0]['ID']);
-      $('input[name="meta_id"]').val(loadId);
-
-      if(!data['data'][0]['Editierbar']) {
-        canEdit = false;
-        $('#content').find('input, textarea, select, button[id!="showVerfahrensliste"]').prop('disabled', true);
-        $('#content > .tab-content > .tab-pane > div').appendTo('#content > .tab-content > .tab-pane:first()');
-        $('#content > .wizard-navigation, #content > .wizard-footer div').remove();
-        $('#content > .tab-content').css('padding-top', '0px');
-        $('#autosaveLabel').addClass('hidden');
-      }
-
-      lastSaveDate = data['data'][0]['Aktualisierung'];
-      if(!lastSaveDate) {
-        let currDate = new Date();
-        lastSaveDate = currDate.toISOString();
-      }
-
-      $('input[name="meta_lastupdate"]').val(lastSaveDate);
-      setSaveLabel('saved', new Date(lastSaveDate.replace(' ', 'T')));  // Safari benötigt das Format YYYY-MM-DDTHH:MM:SS (mit T)
-
-      document.title = htmlDecode(data['data'][0]['Bezeichnung']) + ' - ' + document.title.split(' - ').slice(-1)[0];
-      let statusSymbol = status in statusSymbolMapping ? ' <i data-toggle="tooltip" class="fa ' + statusSymbolMapping[status] + '" title="' + statusMapping[status]  + '"></i>' : '';
-      $('#title').text(' Dokumentation von ' + htmlDecode(data['data'][0]['Bezeichnung'])).append(statusSymbol).find('i').tooltip();
-      changedValues = false;
-      changedFields = [];
-
-      // Abhängigkeiten bei IT-Verfahren anzeigen
-      if(userIsDSB) {
-        $('#abschluss_vonabhaengig tbody tr').remove();
-        $.get(backendPath, { 'action': 'dependencies', 'id':  loadId, 'debug': debug}).done(function(data) {
-          if(!data['success']) {
-            console.error('Fehler beim Abruf der abhängigen Verfahren! Fehler: ' + data['error']);
-            return;
-          }
-
-          data['data'].forEach(dependant => {
-            let dependantType = 'Verarbeitungstätigkeit';
-            if(dependant['type'] === 2) dependantType = 'IT-Verfahren';
-            if(dependant['type'] === 3) dependantType = 'Fachapplikation';
-            if(dependant['type'] === 4) dependantType = 'Übergreifende Massnahmen';
-
-            let statusText = dependant['status'] in statusMapping ? statusMapping[dependant['status']] : statusMapping['9'];
-            let statusSymbol = dependant['status'] in statusSymbolMapping ? ' <i data-toggle="tooltip" class="fa ' + statusSymbolMapping[dependant['status']] + '" title="' + statusText + '"></i>' : '';
-
-            $('#abschluss_vonabhaengig tbody').append('<tr><td>' + htmlDecode(dependant['name']) + statusSymbol + '</td><td>' + dependantType + '</td><td><a class="btn" href="?id=' + dependant['id'] + '" target="_blank">Anzeigen</a></td></tr>');
-          });
-
-          $('#abschluss_vonabhaengig tbody').find('i[data-toggle="tooltip"]').tooltip();
-        }).fail((jqXHR, error, errorThrown) => {
-          console.error('Fehler beim Abruf von abhängigen Verfahren! HTTP Code: ' + jqXHR.status + ' Fehler: ' + error + ' - ' + errorThrown);
-        });
-      }
-
-      // Revisionen anzeigen
-      if(userIsDSB) {
-        $('#abschluss_revisionen tbody tr').remove();
-        $.get(backendPath, { 'action': 'listrevisions', 'id':  loadId, 'debug': debug}).done(function(data) {
-          if(!data['success']) {
-            console.error('Fehler beim Abruf der Revisionen! Fehler: ' + data['error']);
-            return;
-          }
-
-          data['data'].forEach(revision => {
-            let date = formatDate(new Date(revision['Date'].replace(' ', 'T')));
-            $('#abschluss_revisionen tbody').append('<tr><td>' + revision['Revision'] + '</td><td>' + date + '</td><td>' + revision['Editor'] + '</td><td>' + revision['Comment'] + '</td></tr>');
-          });
-        }).fail((jqXHR, error, errorThrown) => {
-          console.error('Fehler beim Abruf der Revisionen! HTTP Code: ' + jqXHR.status + ' Fehler: ' + error + ' - ' + errorThrown);
-        });
-      }
-    }
-    else {
-      loadId = 0;
-      showError('Laden der Dokumentation', data['error']);
-    }
-  }).fail((jqXHR, error, errorThrown) => {
-    loadId = false;
-    showError('Laden der Dokumentation', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-  }).always(() => { setOverlay(false); console.timeEnd('Verfahren laden'); });
-}
-
-/**
- * Kopiert den Inhalt eines Verfahrens in ein neues Verfahren
- * @param {type} id Eindeutige ID des Verfahrens
- * @returns {undefined}
- */
-function copyFromServer(id) {
-  console.time('Verfahren kopieren');
-  setOverlay();
-  $.post(backendPath, JSON.stringify({'action':'get', 'id': id, 'debug': debug})).done(function(data) {
-    if(data['success']) {
-      setSaveLabel('failed');
-      loadFromJSON(data['data'][0]['JSON']);
-      loadId = 0;
-      $('input[name=meta_id]').val(loadId);
-      $('input[name=allgemein_bezeichnung]').val('[Kopie] ' + $('input[name=allgemein_bezeichnung]').val()); /* Kopie vor Bezeichnung setzen */
-      history.replaceState({}, document.title, window.location.href.split('?')[0]);
-      changedValues = true;
-      changedFields = ['allgemein_bezeichnung'];
-    }
-    else {
-      showError('Kopieren der Dokumentation', data['error']);
-    }
-  }).fail((jqXHR, error, errorThrown) => {
-    showError('Kopieren der Dokumentation', false, {'jqXHR': jqXHR, 'error': error, 'errorThrown': errorThrown});
-  }).always(() => { setOverlay(false); console.timeEnd('Verfahren kopieren'); });
-}
-
-/**
- * Generiert den HTML-Code-Auschnitt für die PDF-Generierung
- * @param {boolean} draft Zeigt an, ob ein Abschluss- oder Entwurfs-Dokument erstellt wird
- * @returns {String} HTML-Code
- */
-function genHTMLforPDF(draft = false) {
-  console.time('HTML-Code-Generierung für PDF-Datei');
-
-  /* Bearbeitete TOMs wieder einblenden */
-  $('#showFinishedTOMs:not(:checked)').prop('checked', true).trigger('change');
-
-  /* Alle leeren Tabellenzeilen entfernen */
-  endlessTables.forEach(function(table) {
-    removeTableRows(table, true);
-  });
-
-  var toSend = $('<div></div>');
-
-  /* Überschrift */
-  toSend.append('<h2 class="text-center">Dokumentation ' + ( mode === 'wizproc' ? 'der Verarbeitungstätigkeit' : ( mode === 'wizapp' ? 'der Fachapplikation' : ( mode === 'wizmeasures' ? 'der übergreifenden Massnahmen' : 'des IT-Verfahrens' ) ) ) + '</h2>');
-  toSend.append('<h3 class="text-center">' + htmlEncode($('[name="allgemein_bezeichnung"]').val()) + '</h3>');
-
-  /* Nr. und Änderungsinfo */
-  toSend.append('<table class="table"><tbody><tr><td class="text-left">Nr.: <span style="background-color: lightyellow">' + loadId + '</span></td><td class="text-center">Letzter Bearbeiter: <span style="background-color: lightyellow">$lasteditor$</span></td><td class="text-right">Letzte Aktualisierung: <span style="background-color: lightyellow">$lastedited$</span></td></tr></tbody></table>');
-
-  /* Daten aus Wizard einsammeln */
-  $('#content').children('.tab-content').children('.tab-pane').each(function(idx) {
-    toSend.append($(this).clone().addClass('active'));
-  });
-
-  /* Maßnahmen Eingabefelder aus Bootstrap-Accordion holen
-  toSend.find('textarea[name="massnahmen_vertraulichkeit"], textarea[name="massnahmen_integritaet"], textarea[name="massnahmen_verfuegbarkeit"]').each(function() {
-    $(this).closest('.printHide').before($(this));
-  });
-  */
-
-  /* TOM Liste formatieren */
-  toSend.find('#tom_accordion').find('.panel-collapse').each(function() {
-    if($(this).closest('.panel').hasClass('hidden')) {
-      $(this).closest('.panel').prev('h6').remove();
-      $(this).remove();
-      return;
-    }
-
-    $(this).removeClass('collapse');
-    $(this).closest('.panel').before($(this));
-  });
-
-  if(draft) {
-    toSend.find('#tom_accordion').find('option').each(function() {
-      let selectName = $(this).closest('select')[0].name;
-      let selectedValue = $('select[name="' + selectName + '"]').val(); // .val() funktioniert in Kopie nicht richtig, deswegen Abfrage im Live-DOM
-
-      if(this.value === '-1') return;
-
-      if(this.value === selectedValue) {
-        $(this).closest('td').append('<p>&#9746; ' + this.text + '</p>');
-      }
-      else {
-        $(this).closest('td').append('<p>&#9744; ' + this.text + '</p>');
-      }
-    });
-    toSend.find('#tom_accordion').find('div.bootstrap-select').remove();
-  }
-
-  /* Nur TOMs in der PDF anzeigen, die dem Risiko entsprechen */
-  let currRiskLevel = parseInt($('[name="massnahmen_risiko"]:checked').val());
-  toSend.find('#tom_accordion').find('tr').each(function() {
-    if(parseInt($(this).data('risk')) > currRiskLevel) $(this).remove();
-  });
-
-  /* Ausgeblendete, bearbeitete TOMs wieder anzeigen */
-  toSend.find('#tom_accordion tr.hidden').removeClass('hidden');
-  toSend.find('#showFinishedTOMs').closest('div').remove();
-
-  /* Bei Abschluss-PDF unbearbeitete Massnahmen entfernen */
-  if(!draft) toSend.find('#tom_accordion select').each(function() {
-    if($('select[name="' + this.name + '"]').val() === '-1') $(this).closest('tr').remove();
-  });
-
-  /* Bei Abschluss-PDF Volltexte entfernen */
-  if(!draft) toSend.find('#tom_accordion').find('tbody td:nth-child(2) div.tom_desc').remove();
-  if(!draft) toSend.find('#tom_accordion').find('tbody td:nth-child(2) p').removeClass('strong');
-  if(!draft) toSend.find('#tom_accordion').find('.panel-body > p, .panel-body > a').remove();
-
-  /* Leere TOM-Kategorien entfernen */
-  if(!draft) toSend.find('#tom_accordion table').each(function() {
-    if($(this).find('tbody tr').length === 0) {
-      $(this).closest('.panel-collapse').prev('h6').remove();
-      $(this).closest('.panel-collapse').remove();
-    }
-  });
-
-  /* Hinweis-Text bei keinen ausgewählten TOMs */
-  if(toSend.find('#toggletoms').find('input[type=checkbox]:checked').length === 0 || toSend.find('#tom_accordion').find('tr').length === 0) {
-    toSend.find('#tom_accordion').append('<p class="text-center"><strong>Es wurden keine Technischen und Organisatorischen Maßnahmen ausgewählt.</strong></p>');
-  }
-
-  /* Link hinzufügen */
-  let baseURL = window.location.href.split('?')[0].replace(/x?sso/i, 'www');
-  let link = baseURL + '?id=' + loadId;
-  toSend.append('<div class="text-center"><p class="info-text text-ul">Dokumentation online einsehen</p><p><a href="$docurl$">$docurl$</a></p></div>');
-
-  /* Platzhalter für Revisionen Hinzufügen */
-  toSend.append('<div>$docrevisions$</div>');
-
-  /* Links in Abhängigkeiten anpassen */
-  toSend.find('table#abschluss_vonabhaengig tr, table#abschluss_abhaengigkeit tr, table#itverfahren_abhaengigkeit tr, table#verarbeitung_abhaengigkeit tr, table#massnahmen_abhaengigkeit tr').each(function(idx) {
-    let abhLnk = $(this).find('td:last a');
-    if(abhLnk.attr('href') === undefined) {
-      abhLnk.detach();
-    }
-    else {
-      abhLnk.attr('href', '$baseurl$' + abhLnk.attr('href'));
-    }
-  });
-
-  toSend.find('table#abschluss_abhaengigkeit tr, table#itverfahren_abhaengigkeit tr, table#verarbeitung_abhaengigkeit tr, table#massnahmen_abhaengigkeit tr').each(function(idx) {
-    $(this).find('td:last button').remove();
-    $(this).append($(this).find('td:last, th:last').clone());
-  });
-
-  /* Layout-Anpassungen (Buttons durch Text ersetzen, Typeahead und andere aktive Elemente entschärfen) */
-  toSend.find('select[data-tool="selectpicker"], select.selectpicker, [id$="_add"], .typeahead__cancel-button, .typeahead__hint, .typeahead__result').remove();
-  toSend.find('table[data-tool="endlessTable"] tr').each(function(idx) {
-      $(this).find('th:last, td:last').remove();
-  });
-  toSend.find('table[data-tool="endlessTable"]').each(function(idx){
-    var tbl = $(this);
-    if(tbl.find('tr').length < 2) {
-      if(['abschluss_abhaengigkeit', 'itverfahren_abhaengigkeit', 'verarbeitung_abhaengigkeit', 'massnahmen_abhaengigkeit'].includes(this.id)) {
-        tbl.parent().replaceWith('<div class="col-sm-offset-1 col-sm-10"><p>Es wurden keine Abhängigkeiten angegeben.</p></div>');
-      }
-      else {
-        tbl.parent().prev().remove();
-        tbl.parent().remove();
-      }
-    }
-  });
-
-  /* HTML in Eingabefeldern entschärfen */
-  toSend.find('input, textarea').each(function(idx){
-    $(this).val(htmlEncode($(this).val()));
-  });
-
-  /* Eingabeelemente durch gelb hinterlegten Text ersetzen */
-  toSend.find('input[type!=checkbox][type!=hidden][type!=radio], select').replaceWith(function() { if($(this).parents('td').length>0) { return '<p>' + $(this).val() + '</p>'; } else { return '<p style="background-color: lightyellow">' + $(this).val() + '</p>'; }});
-  toSend.find('textarea').replaceWith(function() { if($(this).parents('td').length>0) { return '<p>' + $(this).val().replace(/(?:\r\n|\r|\n)/g, '<br />') + '</p>'; } else { return '<p style="background-color: lightyellow">' + $(this).val().replace(/(?:\r\n|\r|\n)/g, '<br />') + '</p>'; }});
-
-  /* Radio-Elemente formatieren */
-  toSend.find('input[type=radio]:not(:checked)').closest('label').remove();
-  toSend.find('input[type=radio]').remove();
-
-  /* Weitere Design-Anpassunge */
-  toSend.find('.printHide').remove();
-  toSend.find('.printOnly').removeClass('hidden');
-  toSend.find('h5').addClass('text-center');
-  toSend.find('table, td, th').attr('style', 'border: 1px solid darkgray; padding: 5px;');
-  toSend.find('th').css('background-color', 'lightgray');
-  //toSend.find('#systeme_klienten, #systeme_server').find('label').attr('style', 'font-style: italic;');  // funktioniert nicht
-  toSend.find('#systeme_klienten, #systeme_server').find('label').replaceWith(function() { return '<span style="font-style: italic; text-decoration: underline">' + $(this).text() + '</span>'; });
-  toSend.find('input[type=checkbox]').each(function(idx) {
-    var checkbox = $(this);
-
-    checkbox.parent().parent().attr('style', 'margin: 5px;');
-    if(checkbox.prop('checked')) {
-      if(checkbox.attr('name') === 'daten_kategorien_besonders[]') {
-        checkbox.replaceWith('<span><span style="color: green;">&#10004;</span> Ja</span>');
-        return;
-      }
-
-      checkbox.replaceWith('<span style="color: green;">&#10004;</span>');
-    }
-    else {
-      if(checkbox.attr('name').search(/massnahmen/g) > -1) {
-        checkbox.replaceWith('<span style="color: red;">&#10006;</span>');
-        return;
-      }
-
-      if(checkbox.attr('name') === 'abschluss_datenschutz_folgeabschaetzung') {
-        checkbox.parent().replaceWith('<label><span style="color: red;">&#10006;</span> Es ist keine Datenschutzfolgeabschätzung notwendig</label>');
-        return;
-      }
-
-      if(checkbox.attr('name') === 'daten_kategorien_besonders[]') {
-        checkbox.replaceWith('<span>Nein</span>');
-        return;
-      }
-
-      checkbox.parent().parent().addClass('hidden');
-
-      if(['allgemein_verantwortlich_extern'].includes(checkbox.attr('name'))) {
-        checkbox.closest('div').prev().addClass('hidden');
-      }
-    }
-  });
-
-  /* Ergebnis-HTML für mpdf holen */
-  var htmlCode = toSend[0].outerHTML;
-  console.timeEnd('HTML-Code-Generierung für PDF-Datei');
-  return htmlCode;
-}
-
-/**
- * Exportiert die aktuell geladene Dokumentation als JSON-Datei
- * @return {undefined}
- */
-function exportJSON() {
-  setOverlay(true);
-
-  // Aktuelle Dokumentation in JSON umwandeln
-  let currObj  = saveAsObject();
-  let fieldsToRemove = [
-    'meta_id',
-    'meta_lastupdate',
-    'allgemein_typ',
-    'abschluss_abhaengigkeit_id',
-    'itverfahren_abhaengigkeit_id',
-    'verarbeitung_abhaengigkeit_id',
-    'massnahmen_abhaengigkeit_id',
-    'meta_gruppen_kennung',
-    'meta_gruppen_name',
-    'meta_gruppen_schreiben',
-    'meta_nutzer_kennung',
-    'meta_nutzer_name',
-    'meta_nutzer_schreiben',
-    'allgemein_fachlich_kennung',
-    'allgemein_technisch_kennung'
-  ];
-  let fieldsToReassign = [
-    'abschluss_abhaengigkeit_name',
-    'itverfahren_abhaengigkeit_name',
-    'verarbeitung_abhaengigkeit_name',
-    'massnahmen_abhaengigkeit_name',
-    'allgemein_fachlich_name',
-    'allgemein_technisch_name'
-  ];
-
-  let lastUpdate = currObj['meta_lastupdate'] ? new Date(currObj['meta_lastupdate'].replace(' ', 'T')) : new Date();
-
-  // Unnötige Felder entfernen
-  fieldsToRemove.forEach((field) => { delete currObj[field]; });
-
-  // Anmerkung für Abhängigkeiten
-  fieldsToReassign.forEach((field) => {
-    if(currObj[field] !== undefined) {
-      if(Array.isArray(currObj[field])) {
-        currObj[field].forEach((entry, idx) => { currObj[field][idx] = "(ERSETZEN) " + entry; });
-      }
-      else {
-        currObj[field] = "(ERSETZEN) " + currObj[field];
-      }
-    }
-  });
-
-  try {
-    let currJSON = JSON.stringify(currObj);
-    let dataStr  = "data:text/json;charset=utf-8," + encodeURIComponent(currJSON);
-
-    // Download-Dialog für JSON-Date
-    let download = $('<a></a>');
-
-    download.attr('href', dataStr).attr('download', 'SecDoc_' + modeName[0] + '_' + loadId + '_' + currObj.allgemein_bezeichnung.replace(/\W/g, '_').substr(0, 40) + '_' + lastUpdate.getFullYear() + ('0' + (lastUpdate.getMonth() + 1)).slice(-2) + ('0' + lastUpdate.getDate()).slice(-2) + ('0' + lastUpdate.getHours()).slice(-2) + ('0' + lastUpdate.getMinutes()).slice(-2) + '.json').addClass('hidden');
-    $('body').append(download);
-    download[0].click();
-    download.remove();
-  } catch(e) {
-    showError('Exportieren', e);
-  }
-  setOverlay(false);
-}
-
-/**
- * Importiert eine JSON-Datei in die aktuelle Dokumentation
- * @param {Object} file Verweis auf Datei vom Dateidialog
- * @return {undefined}
- */
-function importJSON(file) {
-  setOverlay(true);
-
-  let fileReader = new FileReader();
-  fileReader.onload = (evt) => {
-    let nameToLoad = '';
-
-    try {
-      let jsonObj = JSON.parse(evt.target.result);
-
-      if(jsonObj['allgemein_bezeichnung'] === undefined) throw new Error('Keine gültige SecDoc Dokumentation');
-
-      nameToLoad = jsonObj['allgemein_bezeichnung'];
-    } catch(e) {
-      showError('Importieren', 'Die gewählte Datei kann nicht verarbeitet werden! - ' + e);
-      return;
-    }
-
-    if(loadId !== 0) {
-      modal.find('.modal-title').html('<i class="fa fa-upload"></i> Import einer Dokumentation');
-      modal.find('.modal-body').html('<div class="alert alert-warning">Sie haben bereits eine Dokumentation geladen. Soll eine neue Dokumentation angelegt oder die aktuell geladene Dokumentation überschrieben werden?<br/><i class="fa fa-info-circle"></i> <strong>Hinweis:</strong> Evtl. gesetzte Zugriffsberechtigungen auf der letzten Seite werden nicht überschrieben.</div>');
-      modal.find('.modal-body').append('<div class="text-center"><button id="importEmptyBtn" class="btn btn-success">Neue Dokumentation</button><button id="importCurrBtn" class="btn btn-danger ml">Vorhandene überschreiben</button></div>');
-      modal.modal();
-
-      modal.find('#importEmptyBtn').click(() => { triggerLoadJSON(true); });
-      if(canEdit) {
-        modal.find('#importCurrBtn').click(() => { triggerLoadJSON(false); });
-      }
-      else {
-        modal.find('#importCurrBtn').prop('disabled', true);
-      }
-    }
-    else {
-      triggerLoadJSON(true);
-    }
-
-    function triggerLoadJSON(createNew) {
-      modal.modal('hide');
-      setOverlay(true);
-
-      if(createNew) {
-        loadEmpty();
-      }
-      else {
-        $('#toggletoms').find('input[name^="tom_toggle"]').prop('checked', false).trigger('change');
-      }
-
-      if(loadFromJSON(evt.target.result, true)) {
-        modal.find('.modal-title').html('<i class="fa fa-check-circle"></i> Import erfolgreich');
-        modal.find('.modal-body').html('<div class="alert alert-success">Der Import wurde erfolgreich durchgeführt. Die Änderungen müssen zum Übernehmen abgespeichert werden.</div>');
-        modal.find('.modal-body').append('<p class="text-center"><button type="button" class="btn btn-danger ml" data-dismiss="modal" aria-label="Close">Schließen</button></p>');
-        modal.modal();
-      }
-      else {
-        showError('Importieren', 'Eventuell ist die Datei beschädigt oder im falschen Format!');
-      }
-      setOverlay(false);
-    }
-  };
-
-  fileReader.onerror = (e) => {
-    showError('Importieren', 'Die gewählte Datei konnte nicht gelesen werden! - ' + e);
-  };
-
-  fileReader.readAsText(file);
-
-  setOverlay(false);
-}
-
-/**
- * Zeigt einen Dialog zum JSON-Import an
- * @return {undefined}
- */
-function showImportDialog() {
-  setOverlay(true);
-
-  modal.find('.modal-title').html('<i class="fa fa-upload"></i> Import einer Dokumentation');
-  let modalBody = modal.find('.modal-body');
-  modalBody.html('<div class="form-group"><label for="importFile">JSON Datei zum Importieren auswählen</label><input type="file" id="importFile" accept=".json,application/json" class="btn center-block hidden" /><div id="dropFile" class="text-center alert alert-info"></div></div>');
-  modalBody.find('#dropFile').append('<p class="text-center"><i class="fa fa-file fa-2x"></i></p><p class="text-center">Klicken für Auswahldialog oder Datei per Drag&Drop hineinziehen...</p>');
-  modalBody.append('<p class="text-center"><button type="button" class="btn btn-danger ml" data-dismiss="modal" aria-label="Close">Schließen</button></p>');
-
-  modalBody.find('#dropFile').on('dragover', (evt) => {
-    evt.preventDefault();
-    evt.stopPropagation();
-    modalBody.find('#dropFile').removeClass('alert-info').addClass('alert-success');
-  });
-  modalBody.find('#dropFile').on('dragleave', (evt) => {
-    evt.preventDefault();
-    evt.stopPropagation();
-    modalBody.find('#dropFile').removeClass('alert-success').addClass('alert-info');
-  });
-  modalBody.find('#dropFile').on('drop', (evt) => {
-    evt.preventDefault();
-    evt.stopPropagation();
-
-    if(evt.originalEvent.dataTransfer.files.length > 0) {
-      importJSON(evt.originalEvent.dataTransfer.files[0]);
-    }
-
-    modalBody.find('#dropFile').removeClass('alert-success').addClass('alert-info');
-
-  });
-  modalBody.find('#dropFile').click(() => { modalBody.find('#importFile').click(); });
-
-  modalBody.find('#importFile').change((evt) => {
-    importJSON(evt.target.files[0]);
-  });
-
-  modal.modal();
-
-  setOverlay(false);
-}
-
-/*
- * Typeahead Funktionen
- */
-/**
- * Initialisiert das Typeahead-Plugin auf dem Element node
- * @param {Object} node DOM-Element oder jQuery-Objekt
- * @returns {null|Object}
- */
-function initTypeahead(node) {
-  node = $(node);
-  var nodeData = node.data();
-  var newTypeahead = null;
-  var forceSelectError = 'Es muss zwingend ein Eintrag aus den Vorschlägen gewählt werden!';
-
-  // Überprüfen, ob Typeahead auf dem Element nicht schon initialisiert wurde
-  if(nodeData['typeahead']) {
-    return null;
-  }
-
-  // Überprüft ob eine explizite URL gegeben ist, sonst wird die hinterlegte verwaltung.php genutzt
-  if(nodeData['url'] === undefined) {
-    nodeData['url'] = backendPath + '?action=' + nodeData['action'] + (debug ? '&debug=true' : '') + '&search=';
-    if(nodeData['path'] === undefined) nodeData['path'] = 'data';
-  }
-  else {
-    if(nodeData['path'] === undefined) nodeData['path'] = '';
-  }
-
-  // Fügt einen onChange-Listener an, damit das versteckte Feld geleert wird bei Änderung
-  if(nodeData['hiddenfield']) {
-    node.change(function() {
-      $(this).closest('.typeahead__container').parent().find('input[name="' + nodeData['hiddenfield'] + '"]').val('').trigger('change');
-    });
-
-    if(nodeData['mustselectitem']) {
-      $(node).parent().find('input[name="' + nodeData['hiddenfield'] + '"]').change(function(evt) {
-        if($(evt.target).val() === "") {
-          $(node).addClass('customError');
-          if($(node).closest('.typeahead__container').parent().find('span.error').length === 0) $(node).closest('.typeahead__container').after('<span class="error">' + forceSelectError + '</span>');
-        }
-        else {
-          $(node).removeClass('customError');
-          $(node).closest('.typeahead__container').parent().find('span.error').remove();
-        }
-      });
-    }
-  }
-
-  // Fügt die notwendigen Element um das Input-Element herum ein
-  node.prop('autocomplete', 'off');
-  node.wrap('<div class="typeahead__container"><div class="typeahead__field"><span class="typeahead__query"></span></div></div>');
-  node.data('typeahead', 1);
-
-  /**
-   * Eigene Filterfunktion für Typeahead zur Filterung nach mehreren getrennten Suchbegriffen (durchsucht alle im JSON vorhandenen Felder)
-   * @private
-   * @param {Object} item       Aktuelles Element
-   * @param {String} displayKey Anzuzeigender Schlüssel
-   * @returns {undefined|Boolean} True, wenn das Element in der Auswahl auftauchen soll, undefined wenn nicht
-   */
-  function customFilter(item, displayKey) {
-    var lowcaseQuery = this.query.toLowerCase().trim();
-    var itemKeys = Object.keys(item);
-    var split = lowcaseQuery.split(' ');
-    var found = undefined;
-
-    // Aktuelle Dokumentation aus Auswahllisten filtern
-    if(Number.parseInt(item.value) === loadId) return undefined;
-
-    for(let c=0; c < itemKeys.length; c++) {
-      if(item[itemKeys[c]] !== null && item[itemKeys[c]].toLowerCase().search(lowcaseQuery.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')) > -1) {
-        found = true;
-        break;
-      }
-    }
-
-    if(found) {
-      return true;
-    }
-    else if(split.length > 1) {
-      found = true;
-      for(let c=0; c < split.length; c++) {
-        var foundinKeys = false;
-        for(let k=0; k < itemKeys.length; k++) {
-          if(item[itemKeys[k]].toLowerCase().search(split[c].replace(/[.*+?^${}()|[\]\\]/g, '\\$&')) > -1) {
-            foundinKeys = true;
-            break;
-          }
-        }
-        if(!foundinKeys) {
-          found = undefined;
-          break;
-        }
-      }
-      return found;
-    }
-    return undefined;
-  };
-
-  /**
-   * Sortiert die Auswahlmöglichkeiten in Typeahead nach der Position des ersten Suchbegriffs
-   * @private
-   * @param {Object} node  Typeahead-Node
-   * @param {array}  data  Zu sortierende Daten
-   * @param {String} group Anzeigegruppe
-   * @param {String} path  Pfad zum Label
-   * @returns {array} Sortierte/Modifizierte Elemente zur Anzeige
-   */
-  function onPopulateSourceCustom(node, data, group, path) {
-    var search = this.query.trim().split(' ')[0].toLowerCase();
-    data.sort((a,b) => {
-        var foundA = a['label'].toLowerCase().search(search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
-        var foundB = b['label'].toLowerCase().search(search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
-        if(foundA === -1) foundA = 200;
-        if(foundB === -1) foundB = 200;
-        if(foundA !== foundB) return foundA - foundB;
-        else return a['label'].toLowerCase().localeCompare(b['label'].toLowerCase());
-      });
-    return data;
-  };
-
-  newTypeahead = node.typeahead({
-    dynamic: (nodeData['dynamic'] === true ? true : false),
-    delay: (nodeData['dynamic'] === true ? 1000 : 100),
-    searchOnFocus: true,
-    minLength: nodeData['minlength'] !== undefined ? nodeData['minlength'] : 3,
-    maxItem: nodeData['maxitem'] || 25,
-    order: nodeData['order'] || null,
-    hint: true,
-    cancelButton: true,
-    display: nodeData['display'] || 'label',
-    cache: (nodeData['dynamic'] === true ? false : (nodeData['cache'] !== undefined ? nodeData['cache'] : true)),
-    filter: customFilter,
-    source: ((nodeData['dynamic'] === true) ?
-      { // Dynamische Datenabfrage
-        ajax: function(query) {
-          return {
-            url: nodeData['url'] + query,
-            dataType: 'json',
-            path: nodeData['path']
-          }
-        }
-        /*
-        data: function() {
-          if(!typeaheadCache[nodeData['url']]) {
-            typeaheadCache[nodeData['url']] = {};
-          }
-
-          var query = this.query.toLowerCase();
-          if(query === '') query = '<empty>';
-
-          // Falls der Cache ausgeschaltet ist, wird nur die leere Suche gespeichert (Damit die eigene Kennung zumindest gecached wird)
-          if(nodeData['cache'] === false && query !== '<empty>') {
-            var temp = $.getJSON(nodeData['url'] + this.query);
-            temp.path = 'data';
-            return temp;
-          }
-          else {
-            // Durchsucht den Cache nach Teilausdrücken (wenn die Anfrage 'test' bereits gecached ist, ist auch bereits das Ergebnis für 'test1' vorhanden)
-            var qfound = false;
-            for(var qlen = query.length; qlen >= this.options.minLength && !qfound; qlen--) {
-              var qpart = query.slice(0,qlen);
-              if(qpart in typeaheadCache[nodeData['url']]) qfound = qpart;
-            }
-
-            if(qfound) {
-              var json = typeaheadCache[nodeData['url']][qfound].responseJSON;
-              return json;
-            }
-            else {
-              var temp = $.getJSON(nodeData['url'] + this.query);
-              typeaheadCache[nodeData['url']][query] = temp;
-              return temp;
-            }
-          }
-        }*/
-      } :
-      { // Einmal alle Daten holen und dann cachen lassen
-        [window.location.origin + '/' + nodeData['url'] + '_' + nodeData['path']]: {
-          data: [{"label": "-- keine --"}],
-          ajax: {
-            type: 'GET',
-            url: nodeData['url'],
-            path: nodeData['path']
-          }
-        }
-      }
-    ),
-    callback: {
-      onPopulateSource: ((nodeData['dynamic'] === true) ? onPopulateSourceCustom : null),
-      onClick: function(node, a, item, even) {
-      },
-      onClickAfter: function(node, a, item, event) {
-        $(node).trigger('change');
-        if(nodeData['hiddenfield']) {
-          $(node).closest('.typeahead__container').parent().find('input[name="' + nodeData['hiddenfield'] + '"]').val(item.value).trigger('change');
-        }
-      },
-      onCancel: function(node, a, item, event) {
-        $(node).trigger('change');
-        if(nodeData['hiddenfield']) {
-          $(node).closest('.typeahead__container').parent().find('input[name="' + nodeData['hiddenfield'] + '"]').val('').trigger('change');
-        }
-      },
-      onSubmit: function(node, form, item, event) {
-        event.preventDefault();
-      },
-      onSearch:  function(node, query) {
-        $('.typeahead__list').remove();
-      }
-    }
-  });
-
-  node.focus(function(evt) {
-    $('.typeahead__container').each(function(idx, elem) {
-      if($(elem).find('input[name="' + evt.target.name + '"]').length > 0) return;
-      $(elem).find('.typeahead__list').remove();
-    });
-  });
-
-  return newTypeahead;
-}
-
-
-/*
- * Funktionen für die endlosen Tabellen
- */
-/**
- * Initialisiert die endlosen Tabellen (nutzt die globale Variablen 'endlessTables', 'endlessTemplates' und 'endlessCounts')
- * @return {undefined}
- */
-function initEndlessTables() {
-  endlessTables.forEach(function(table) {
-    endlessTemplates[table] = $('#' + table + ' tbody tr').clone(true);
-    endlessCounts[table] = 0;
-    $('#' + table + ' tbody tr').detach();
-
-    $('#' + table + '_add').click(function() {
-      addTableRow(table);
-    });
-
-    addTableRow(table);
-  });
-}
-
-/**
- * Fügt eine Zeile in einer endlosen Tabelle hinzu (nutzt die globale Variablen 'endlessTables', 'endlessTemplates' und 'endlessCounts')
- * @param {String} table Eindeutiger Tabellenname (DOM Element ID)
- * @returns {undefined}
- */
-function addTableRow(table) {
-  if(!(table in endlessTemplates)) {
-    console.error('Tabelle "' + table + '" nicht gefunden! Überspringe...');
-    return;
-  }
-  // Neue Zeile aus dem Template hinzufügen
-  endlessCounts[table]++;
-  var clone = endlessTemplates[table].clone(true);
-  $('#' + table + ' tbody').append(clone);
-
-  // Focus auf das erste Eingabefeld nach der Nummerierung setzen
-  clone.children('td:nth-child(2)').children('input[type=text], textarea').first().focus();
-
-  // Bootstrap Select initialisieren
-  clone.find('select[data-tool="selectpicker"]').selectpicker({
-    iconBase: 'fa',
-    tickIcon: 'fa-check',
-    noneSelectedText: 'Bitte auswählen',
-    actionsBox: true,
-    deselectAllText: 'Keine',
-    selectAllText: 'Alle'
-  });
-
-  // Typeahead initialisieren
-  clone.find('input[data-tool="typeahead"]').each(function(key, value) {
-    initTypeahead(value);
-  });
-
-  // Tooltips initialisieren
-  clone.find('i[data-toggle="tooltip"]').tooltip();
-
-  // DSBOnly Elemente sichtbar machen
-  if(userIsDSB) {
-    clone.find('.dsbOnly').removeClass('dsbOnly');
-  }
-
-  // Fall 1: Die aktuelle Tabelle wird nicht automatisch durchnummeriert
-  if(clone.find('input[name="' + table + '_nummer[]"]').length !== 1) {
-    // Delete Funktion an den neuen Button binden
-    clone.find('.' + table + '_del').click(function() {
-      $(this).parents('tr').detach();
-      endlessCounts[table]--;
-    });
-  }
-  // Fall 2: Die aktuelle Tabelle wird automatisch nummeriert
-  else {
-    // Nummerierung anpassen
-    var rowNum = endlessCounts[table];
-    clone.find('input[name="' + table + '_nummer[]"]').val(rowNum);
-
-    // Neue Reihe als Option zu nutzenden Auswahlfeldern hinzufügen
-    var newOpt = '<option value="' + rowNum + '">' + rowNum + '</option>';
-    $('select.nutzt_' + table + '_nummer').append(newOpt);
-    endlessTables.forEach(function(tempTable) {
-      $(endlessTemplates[tempTable]).find('select.nutzt_' + table + '_nummer').append(newOpt); // Templates aktualisieren
-    });
-
-    if(rowNum > 1) {
-      $('select.nutzt_' + table + '_nummer').selectpicker('refresh');
-    }
-
-    // Eingaben in das erste Eingabefeld werden in den Optionen als Hilfe angezeigt
-    clone.children('td:nth-child(2)').find('input[type=text], textarea').first().change(function() {
-      var currVal = $(this).val();
-      var currNum = $(this).closest('tr').find('input[name="' + table + '_nummer[]"]').val();
-
-      $('select.nutzt_' + table + '_nummer option[value="' + currNum + '"]').text(currNum + ' - ' + currVal);
-      endlessTables.forEach(function(tempTable) {
-        $(endlessTemplates[tempTable]).find('select.nutzt_' + table + '_nummer option[value="' + currNum + '"]').text(currNum + ' - ' + currVal); // Templates aktualisieren
-      });
-
-      // Selectpicker aktualisieren
-      $('select.nutzt_' + table + '_nummer').selectpicker('refresh');
-    });
-
-    // Delete Funktion an den neuen Button binden
-    clone.find('.' + table + '_del').click(function(evt, force = false) {
-      var currNum = parseInt($(this).closest('tr').find('input[name="' + table + '_nummer[]"]').val());
-      var usedIn = $('select.nutzt_' + table + '_nummer option[value=' + currNum + ']:selected').closest('table');
-
-      // Sollte die zu löschende Zeile noch referenziert werden, wird eine Bestätigung erfragt
-      if(usedIn.length > 0 && !force) {
-        let usedInTitles = [];
-        let confirmed = false;
-
-        usedIn.each(function() {
-          usedInTitles.push($(this).closest('div').prevAll().find('h5, h6').last().text());
-        });
-
-        confirmed = confirm('Achtung: Dieser Eintrag wird noch in anderen Tabellen referenziert (' + usedInTitles.join(', ') + '). Sind Sie sich sicher, dass die Referenzen gelöscht werden sollen?');
-        if(!confirmed) return;
-      }
-
-      $('select.nutzt_' + table + '_nummer option[value=' + currNum + ']').detach();
-      endlessTables.forEach(function(tempTable) {
-        $(endlessTemplates[tempTable]).find('select.nutzt_' + table + '_nummer option[value=' + currNum + ']').detach(); // Zeile in den Optionen der Templates, die sie nutzen, löschen
-      });
-
-      // Nummerierung aller folgenden Tabellenzeilen anpassen
-      var rows = $(this).closest('tbody').find('tr');
-      for(var c = currNum; c < endlessCounts[table]; c++) {
-        $(rows[c]).find('input[name="' + table + '_nummer[]"]').val(c);
-        var currLabel = $(rows[c]).children('td:nth-child(2)').find('input[type=text], textarea').first().val();
-        $('select.nutzt_' + table + '_nummer option[value=' + (c+1) + ']').val(c).text(c + ' - ' + currLabel);
-        endlessTables.forEach(function(tempTable) {
-          $(endlessTemplates[tempTable]).find('select.nutzt_' + table + '_nummer option[value=' + (c+1) + ']').val(c).html(c + ' - ' + currLabel);
-        });
-      }
-
-      // Selectpicker aktualisieren
-      $('select.nutzt_' + table + '_nummer').selectpicker('refresh');
-
-      // Zeile wird entfernt
-      endlessCounts[table]--;
-      $(this).parents('tr').detach();
-    });
-  }
-}
-
-/**
- * Entfernt alle Reihen einer endlosen Tabelle (nutzt die globale Variablen 'endlessTables', 'endlessTemplates' und 'endlessCounts')
- * @param {String}  table     Eindeutiger Tabellenname (DOM Element ID)
- * @param {Boolean} onlyEmpty (optional) Entfernt nur leere Zeilen, wenn true
- * @returns {undefined}
- */
-function removeTableRows(table, onlyEmpty = false) {
-  if(onlyEmpty) {
-    $('#' + table + ' tbody tr').filter(function() {
-      var emptyRow = true;
-      $(this).find('input[type!=button][type!=checkbox][type!=hidden][type!=number], textarea, select[class$="_nummer"]').each(function() {
-        var jqThis = $(this);
-        var thisVal = jqThis.val();
-        if(!jqThis.prop("readonly") && !jqThis.prop("disabled") && thisVal.length > 0) {
-          emptyRow = false;
-          return false;
-        }
-      });
-      return emptyRow;
-    }).each(function() {
-      $(this).find('.' + table + '_del').trigger('click', ['true']);
-    });
-  }
-  else {
-    $('#' + table + ' tbody tr').each(function() {
-      $(this).find('.' + table + '_del').trigger('click', ['true']);
-    });
-  }
-}
-
-/**
- * Legt die Auswahlliste für TOMs an
- * @return {undefined}
- */
-function generateTOMList() {
-  let toggleHeading = $('#toggletoms > ul').first();
-  let toggleTab = $('#toggletoms > div').first();
-  let tempTOMs = tomsMapping.slice();
-
-  tempTOMs.sort((a, b) => (a.Category + ' - ' + a.Subcategory).localeCompare(b.Category + ' - ' + b.Subcategory));
-
-  tempTOMs.forEach(function(row) {
-    // Auswahlliste für Kategorien erstellen
-    let targetToggleCategory = ('tom_toggle_' + row['Category'].trim()).replace(/\W/g, '_');
-    let catDelimit = row['CatDelimit'] ? '<i data-toggle="tooltip" title="' + row['CatDelimit'] + '" class="fa fa-question-circle-o fa-lg"></i>' : '';
-
-    if($('#' + targetToggleCategory).length !== 1) {
-      toggleHeading.append('<li role="presentation"><a href="#' + targetToggleCategory + '" aria-controls="technical" role="tab" data-toggle="tab">' + row['Category'].trim() + '</a></li>');
-      toggleTab.append('<div role="tabpanel" class="tab-pane" id="' + targetToggleCategory + '"></div>');
-      $('#' + targetToggleCategory).append('<div class="checkbox"><label><input type="checkbox" data-category="' + row['Category'] + '" data-subcategory="' + row['Subcategory'] + '" data-target="tom_category_' + row['Category'].trim().replace(/\W/g, '_') + '" name="' + targetToggleCategory + '_all" value="1">Gesamte Kategorie ' + catDelimit + '</label></div>');
-    }
-
-    if(row['Subcategory'].trim() !== '') {
-      let targetSubcategory = ('tom_toggle_' + row['Category'].trim() + '_' + row['Subcategory'].trim()).replace(/\W/g, '_');
-
-      if($('input[name="' + targetSubcategory + '"]').length !== 1) {
-        $('#' + targetToggleCategory).append('<div class="checkbox"><label><input type="checkbox" data-category="' + row['Category'] + '" data-subcategory="' + row['Subcategory'] + '" data-target="tom_category_' + (row['Category'].trim() + ' - ' + row['Subcategory'].trim()).replace(/\W/g, '_') + '" name="' + targetSubcategory + '" value="1">' + row['Subcategory'].trim() + ' ' + catDelimit + '</label></div>');
-        $('#' + targetToggleCategory).find('input[name="' + targetToggleCategory + '_all"]').closest('div').detach();
-      }
-    }
-  });
-
-  // Ersten Tab der Auswahlliste auf aktiv setzen
-  toggleHeading.find('li').first().addClass('active');
-  toggleTab.find('div').first().addClass('active');
-
-  // Listener für toggleTOMList()
-  toggleTab.find('input[type="checkbox"]').change((evt) => { return toggleTOMList(evt); });
-
-  // Listener zum Aufklappen von Accordions (zur Anpassung der Textarea Höhe)
-  $('#tom_accordion').on('shown.bs.collapse', (evt) => {
-    $(evt.target).find('textarea').each((idx, elem) => {
-      let targetCat = $(elem);
-      targetCat.height(targetCat.parent().innerHeight() - 16 - (idx === 0 ? 23 : 22));
-    });
-  });
-
-  // Tooltips aktivieren
-  $('#toggletoms').find('[data-toggle="tooltip"]').tooltip({
-    placement: 'auto',
-    html: true
-  });
-}
-
-/**
- * Filtert die Liste der TOMs anhand des gewählten Risikolevels
- * @param  {Number}  risklevel    Risikolevel des Verfahrens
- * @param  {Boolean} showFinished (optional) Bearbeitete Massnahmen einblenden
- * @return {undefined}
- */
-function filterTOMList(risklevel, showFinished = true) {
-  let riskTexts = {
-    '1': 'Der Schutzbedarf ' + (modeNum === 2 ? 'des ' + modeName[0] + 's' : 'der ' + modeName[0]) + ' ist <em>niedrig</em>. Es sind die <em>Basis</em>-Anforderungen umzusetzen, sofern nicht gravierende Gründe dagegen sprechen.',
-    '2': 'Der Schutzbedarf ' + (modeNum === 2 ? 'des ' + modeName[0] + 's' : 'der ' + modeName[0]) + ' ist <em>normal</em>. Es sind die <em>Basis</em>- sowie die <em>Standard</em>-Anforderungen umzusetzen, sofern sie nicht durch mindestens gleichwertige Alternativen oder die bewusste Akzeptanz des Restrisikos ersetzt werden.',
-    '3': 'Der Schutzbedarf ' + (modeNum === 2 ? 'des ' + modeName[0] + 's' : 'der ' + modeName[0]) + ' ist <em>hoch</em>. Es sind die <em>Basis</em>- sowie die <em>Standard</em>-Anforderungen umzusetzen. Darüber hinaus stellen die Anforderungen bei <em>erhöhtem</em> Schutzbedarf exemplarische Vorschläge dar, was zur Absicherung sinnvoll umzusetzen ist.'
-  };
-  let tomRows = $('#tom_accordion').find('tbody tr');
-
-  // Risikotext anzeigen
-  $('#riskText').html(riskTexts[risklevel]);
-
-  // TOMs ausblenden
-  tomRows.each(function() {
-    let tomRisklevel = parseInt($(this).data('risk'));
-    if(tomRisklevel <= risklevel) $(this).removeClass('hidden');
-    if(tomRisklevel > risklevel) $(this).addClass('hidden');
-
-    if(!showFinished && $(this).find('select').val() !== '-1') $(this).addClass('hidden');
-  });
-
-  $('#tom_accordion').find('div.panel').each((idx, elem) => {
-    $(elem).removeClass('hidden');
-
-    if($(elem).find('tbody tr:not(.hidden)').length === 0) $(elem).addClass('hidden');
-  });
-}
-
-/**
- * Übernimmt das Ein- und Ausblenden von TOMs nach Kategorien.
- * @return {undefined}
- */
-function toggleTOMList(evt) {
-  let evtTarget = $(evt.target);
-  let toggleCategory = evtTarget.data('category');
-  let toggleSubcategory = evtTarget.data('subcategory');
-
-  if(evtTarget[0].checked) {
-    tomsMapping.forEach(function(row) {
-      if(row['Category'] !== toggleCategory || row['Subcategory'] !== toggleSubcategory) return;
-
-      let targetID = 'tom_accordion';
-      let targetElem = $('#' + targetID);
-      let tomCategory = row['Category'].trim() + (row['Subcategory'] ? ' - ' + row['Subcategory'].trim() : '');
-      let targetCategory = 'tom_category_' + tomCategory.replace(/\W/g, '_');
-      let tomUrl = row['URL'] ? row['URL'] : '';
-
-      if($('#' + targetCategory).length !== 1) {
-        let inserted = false;
-        // Alphabetisch an der richtigen Stelle einfügen (anhand Kategorie + Subkategorie)
-        targetElem.find('.panel-heading').each(function(idx, elem) {
-          if(elem.id.localeCompare('heading_' + targetCategory) === 1) {
-            // Hinweis: <span class="snip"></span> ist Platzhalter für Aufteilung des HTMLs bei der PDF-Generierung (MPDF hat ein Limit für die HTML Länge)
-            $(elem).parent('div').prev('h6').before('<span class="snip"></span><h6 class="info-text text-ul-dot printOnly hidden"><a href="' + tomUrl + '" target="_blank" rel="noopener noreferrer">' + tomCategory + '</a></h6>');
-            $(elem).parent('div').prev('h6').before('<div class="panel panel-default printHide"><div class="panel-heading" role="tab" id="heading_' + targetCategory + '"><h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#' + targetID + '" href="#' + targetCategory + '" aria-expanded="true" aria-controls="' + targetCategory + '">' + tomCategory + '</a></h4></div></div>');
-            inserted = true;
-            return false;
-          }
-        });
-
-        // Unten einfügen falls korrekte Stelle zum Einfügen nicht gefunden
-        if(!inserted) {
-          // Hinweis: <span class="snip"></span> ist Platzhalter für Aufteilung des HTMLs bei der PDF-Generierung (MPDF hat ein Limit für die HTML Länge)
-          targetElem.append('<span class="snip"></span><h6 class="info-text text-ul-dot printOnly hidden"><a href="' + tomUrl + '" target="_blank" rel="noopener noreferrer">' + tomCategory + '</a></h6>');
-          targetElem.append('<div class="panel panel-default printHide"><div class="panel-heading" role="tab" id="heading_' + targetCategory + '"><h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#' + targetID + '" href="#' + targetCategory + '" aria-expanded="true" aria-controls="' + targetCategory + '">' + tomCategory + '</a></h4></div></div>');
-        }
-
-        // Tabelle vorbereiten und einfügen
-        let anforderungDesc = 'Als <em>Sicherheitsanforderung</em> werden Anforderungen für den organisatorischen, personellen, infrastrukturellen und technischen Bereich bezeichnet, deren Erfüllung zur Erhöhung der Informationssicherheit notwendig ist bzw. dazu beiträgt. Eine Sicherheitsanforderung beschreibt also, was getan werden muss, um ein bestimmtes Niveau bezüglich der Informationssicherheit zu erreichen. Wie die Anforderungen im konkreten Fall erfüllt werden, muss in der entsprechenden Sicherheitsmaßnahme beschrieben werden. (<em>Im englischen Sprachraum wird für Sicherheitsanforderungen häufig der Begriff „control“ verwendet.</em>)<br />Der IT-Grundschutz unterscheidet zwischen Basis-Anforderungen, Standard-Anforderungen und Anforderungen bei erhöhtem Schutzbedarf. <em>Basis-Anforderungen</em> (grün) sind fundamental und stets umzusetzen, sofern nicht gravierende Gründe dagegen sprechen. <em>Standard-Anforderungen</em> (gelb) sind für den normalen Schutzbedarf grundsätzlich umzusetzen, sofern sie nicht durch mindestens gleichwertige Alternativen oder die bewusste Akzeptanz des Restrisikos ersetzt werden. <em>Anforderungen bei erhöhtem Schutzbedarf</em> (rot) sind exemplarische Vorschläge, was bei entsprechendem Schutzbedarf zur Absicherung sinnvoll umzusetzen ist.';
-        let statusDesc = 'Als Antworten bezüglich des <em>Umsetzungsstatus</em> der einzelnen Anforderungen kommen folgende Aussagen in Betracht:<ul><li><strong>Ja</strong> - Zu der Anforderung wurden geeignete Maßnahmen vollständig, wirksam und angemessen umgesetzt.</li><li><strong>Teilweise</strong> - Die Anforderung wurde nur teilweise umgesetzt.</li><li><strong>Nein</strong> - Die Anforderung wurde noch nicht erfüllt, also geeignete Maßnahmen sind größtenteils noch nicht umgesetzt worden.</li><li><strong>Entbehrlich</strong> - Die Erfüllung der Anforderung ist in der vorgeschlagenen Art nicht notwendig, weil die Anforderung im betrachteten Informationsverbund nicht relevant ist (z. B. weil Dienste nicht aktiviert wurden) oder bereits durch Alternativmaßnahmen erfüllt wurde. Wenn Basisanforderungen nicht erfüllt werden, bleibt grundsätzlich ein erhöhtes Risiko bestehen.</ul>';
-        let massnahmeDesc = 'Als <em>Sicherheitsmaßnahme</em> (kurz Maßnahme) werden alle Aktionen bezeichnet, die dazu dienen, um Sicherheitsrisiken zu steuern und um diesen entgegenzuwirken. Dies schließt sowohl organisatorische, als auch personelle, technische oder infrastrukturelle Sicherheitsmaßnahmen ein. Sicherheitsmaßnahmen dienen zur Erfüllung von Sicherheitsanforderungen. Synonym werden auch die Begriffe Sicherheitsvorkehrung oder Schutzmaßnahme benutzt. (<em>Im englischen Sprachraum werden die Begriffe „safeguard“, „security measure“ oder „measure“ verwendet.</em>)';
-        let catURL = row['CatURL'] ? '<a href="' + row['CatURL'] + '" target="_blank" rel="noopener noreferrer"><i class="fa fa-external-link" style="cursor: pointer;" data-toggle="tooltip" title="Zum BSI Grundschutz-Katalog"></i></a>' : '';
-        let catObjective = row['CatObjective'] ? '<p>' + row['CatObjective'] + ' ' + catURL + '</p>' : '';
-
-        $('#heading_' + targetCategory).after('<div id="' + targetCategory + '" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading_' + targetCategory + '"><div class="panel-body"></div></div>');
-        if(catObjective) $('#' + targetCategory).find('.panel-body').append(catObjective);
-        $('#' + targetCategory).find('.panel-body').append('<table class="table table-striped table-hover"><thead><tr class="text-nowrap"><th class="col-sm-auto">Anforderung <i data-toggle="tooltip" data-html="true" title="' + anforderungDesc + '" class="fa fa-question-circle-o fa-lg"></i></th><th class="col-sm-5">Beschreibung</th><th class="col-sm-auto">Umsetzung <i data-toggle="tooltip" title="' + statusDesc + '" class="fa fa-question-circle-o fa-lg"></i></th><th class="col-sm-4">Maßnahme <i data-toggle="tooltip" data-html="true" title="' + massnahmeDesc + '" class="fa fa-question-circle-o fa-lg"></i></th></tr></thead><tbody></tbody></table>');
-        $('#heading_' + targetCategory + ', #heading_' + targetCategory + ' a').click((evt) => {
-          if(evt.target.nodeName === "A") return;
-          $(evt.target).find('a').click();
-        });
-      }
-
-      // Alle TOMs in die passende Tabelle einfügen
-      let className = row['Risklevel'] == 1 ? 'success' : row['Risklevel'] == 2 ? 'warning' : 'danger';
-      let tomID = row['Identifier'].trim().replace(/ /g, '_');
-
-      // Titel einblenden, falls vorhanden (bei ENISA gibt es nur die Beschreibung)
-      let tomContent = row['Title'] ? ('<p class="strong">' + row['Title'] + ' </p><div class="tom_desc">' + row['Description'] + '</div>') : (row['Description']);
-      let tableBody = $('#' + targetCategory).find('tbody');
-
-      // Identifier als Link falls URL vorhanden
-      let tomIdentifier = row['Identifier'];
-
-      // Umsetzung
-      let tomDropdown = $('<select data-tool="selectpicker" name="massnahmen_' + tomID + '"></select>')
-        .append('<option value="-1" selected>Unbearbeitet</option>')
-        .append('<option value="1">Ja</option>')
-        .append('<option value="0">Nein</option>')
-        .append('<option value="2">Teilweise</option>')
-        .append('<option value="4">Entbehrlich</option>');
-
-      // Tabellenzeile einfügen
-      tableBody.append('<tr data-risk="' + row['Risklevel'] + '" class="' + className + '"><td>' + tomIdentifier + '<br /><em><span class="hidden printOnly">' + (row['Risklevel'] == 1 ? 'Basis' : row['Risklevel'] == 2 ? 'Standard' : 'Erhöht') + '</span><em></td><td>' + tomContent + '</td><td>' + tomDropdown[0].outerHTML + '</td><td><textarea rows="5" name="massnahmen_' + tomID + '_kommentar" class="form-control" placeholder="Beschreibung der Sicherheitsmaßnahme, Erläuterung bzw. Begründung"></textarea></td></tr>');
-
-      if(tomContent.includes('ENTFALLEN')) {
-        tableBody.find('tr').last().find('textarea').prop('disabled', true);
-        tableBody.find('tr').last().find('select').replaceWith('ENTFALLEN');
-      }
-    });
-
-    // Tooltips aktivieren
-    $('#tom_accordion').find('[data-toggle="tooltip"]').tooltip({
-      placement: 'auto',
-      html: true
-    });
-
-    // Selectpicker aktivieren
-    $('#tom_accordion').find('select[data-tool="selectpicker"]').selectpicker();
-
-    // Risikofilter anwenden
-    filterTOMList(parseInt($('[name=massnahmen_risiko]:checked').val()));
-  }
-  else {
-    // Überprüfen ob Eingaben verloren gehen beim Abwählen
-    let hasContent = false;
-
-    $('#' + evtTarget.data('target')).find('textarea').each(function(idx, elem) {
-      if($(elem).val() !== '') {
-        hasContent = true;
-        return false;
-      }
-    });
-
-    if(!hasContent) {
-      $('#' + evtTarget.data('target')).find('select').each(function(idx, elem) {
-        if($(elem).val() !== '0') {
-          hasContent = true;
-          return false;
-        }
-      });
-    }
-
-    if(!hasContent || globalClear) {
-      $('#' + evtTarget.data('target')).parent('div').prev('h6').detach();
-      $('#' + evtTarget.data('target')).parent('div').detach();
-    }
-    else {
-      let confirmUncheck = confirm('Im Baustein "' + evtTarget.closest('label').text().trim() + '" wurden bereits Massnahmen bearbeitet, deren Inhalt beim Abwählen verloren geht. Wollen Sie den Baustein wirklich abwählen?');
-
-      if(!confirmUncheck) {
-        evtTarget[0].checked = true;
-        evt.preventDefault();
-        return false;
-      }
-      else {
-        $('#' + evtTarget.data('target')).parent('div').prev('h6').detach();
-        $('#' + evtTarget.data('target')).parent('div').detach();
-      }
-    }
-  }
-}
-
-/**
- * Zeigt den Dokumenten-Verwaltungs-Dialog an.
- *
- * @param  {Number}  docID       (optional) Dokumenten-ID
- * @param  {String}  fileref     (optional) Dateiname
- * @param  {String}  description (optional) Dokumenten-Beschreibung
- * @param  {Boolean} attach      (optional) An Abschluss-PDF anhängen?
- * @return {undefined}
- */
-function showDocumentAddDialog(docID = -1, fileref = '', description = '', attach = false) {
-  if(loadId === 0) {
-    showError('Anhängen eines Dokuments', 'Die Dokumentation muss mindestens einmal abgespeichert werden, bevor Dokumente angehängt werden können.');
-    return;
-  }
-
-  /**
-   * Läd eine ausgewählte Datei hoch als Base64 String.
-   *
-   * @private
-   * @param  {Blob}    file        Datei
-   * @param  {Number}  docID       (optional) Dokumenten-ID
-   * @param  {String}  description (optional) Dokumenten-Beschreibung
-   * @param  {Boolean} attach      (optional) An Abschluss-PDF anhängen?
-   * @return {undefined}
-   */
-  function uploadFile(file, docID = -1, description = '', attach = false) {
-    setOverlay(true);
-
-    if(file === undefined) {
-      $.post(backendPath, JSON.stringify({'action': 'updateDocument', 'debug': debug, 'data': {'docid': docID, 'description': description, 'attach': attach}})).done(function(data) {
-        if(data['success']) {
-          loadDocuments();
-        }
-        else {
-          showError('Anhängen eines Dokuments', data['error']);
-        }
-        setOverlay(false);
-      }).fail((jqXHR, error, errorThrown) => {
-        showError('Anhängen eines Dokuments', false, {'jq