diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..2b792f5
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,21 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Python: Remote Attach to QGIS",
+ "type": "debugpy",
+ "request": "attach",
+ "connect": {
+ "host": "127.0.0.1",
+ "port": 5678
+ },
+ "pathMappings": [
+ {
+ "localRoot": "${workspaceFolder}",
+ "remoteRoot": "${workspaceFolder}"
+ }
+ ],
+ "justMyCode": true
+ }
+ ]
+}
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..c9ae57b
--- /dev/null
+++ b/__init__.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# import debugpy
+
+# _debugger_started = False
+
+def classFactory(iface):
+ from .main import Plan41
+ # start_debugger()
+ return Plan41(iface)
+
+# def start_debugger():
+# global _debugger_started
+
+# if _debugger_started:
+# return # Schon gestartet – nichts tun
+
+# try:
+# debugpy.listen(5678)
+# _debugger_started = True
+# print("Debugger wartet auf Verbindung...")
+# except RuntimeError:
+# print("Debugger läuft bereits – Verbindung wird erwartet...")
+
+# if debugpy.is_client_connected():
+# print("Debugger verbunden – Plugin läuft")
+# else:
+# try:
+# debugpy.wait_for_client()
+# print("Debugger verbunden – Plugin läuft")
+# except RuntimeError as e:
+# print(f"Fehler beim Warten auf Debugger: {e}")
diff --git a/assets/20250908_134217_image.png b/assets/20250908_134217_image.png
new file mode 100644
index 0000000..b921c45
Binary files /dev/null and b/assets/20250908_134217_image.png differ
diff --git a/assets/20250908_134247_image.png b/assets/20250908_134247_image.png
new file mode 100644
index 0000000..076ca7e
Binary files /dev/null and b/assets/20250908_134247_image.png differ
diff --git a/icons/icon.png b/icons/icon.png
new file mode 100644
index 0000000..a4cdc61
Binary files /dev/null and b/icons/icon.png differ
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..bb9e81f
--- /dev/null
+++ b/main.py
@@ -0,0 +1,81 @@
+# Import grundlegender Qt- und QGIS-Komponenten
+from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, Qt
+from qgis.PyQt.QtGui import QIcon
+from qgis.PyQt.QtWidgets import QAction, QMessageBox
+from qgis.utils import plugins
+
+# Import der generierten Ressourcen (z. B. Icons)
+from .resources import *
+
+# Import der gemeinsamen UI-Klasse für Menü und Symbolleiste
+from .shared import UI
+from .shared import DockManager
+
+# Import des Dockwidgets, das beim Ausführen des Plugins angezeigt wird
+from .ui.sn_plan41_dockwidget import Plan41DockWidget
+import os.path
+
+class Plan41:
+ """
+ Hauptklasse des Plugins. Verwaltet die Initialisierung, GUI-Integration und das Dockwidget.
+ """
+
+ def __init__(self, iface):
+ # iface: QGIS-Schnittstelle zur Interaktion mit der Anwendung
+ self.iface = iface
+ self.plugin_dir = os.path.dirname(__file__) # Pfad zum Plugin-Verzeichnis
+
+ self.actions = [] # Platzhalter für spätere Aktionsverwaltung (optional)
+ self.pluginIsActive = False # Statusflag, ob das Plugin aktiv ist
+ self.dockwidget = None # Referenz auf das Dockwidget
+
+ def initGui(self):
+ """
+ Wird beim Laden des Plugins aufgerufen. Fügt Menüeintrag und Symbolleistenaktion hinzu.
+ """
+ self.action_text = "Plan 41" # Einheitlicher Text für Menü und Toolbar
+ icon = QIcon(":/sn_plugin1/icons/icon.png") # Icon aus Ressourcen laden
+ self.ui = UI() # Gemeinsame UI-Instanz für Menü und Toolbar
+ self.ui.add_action(self.action_text, self.run, icon, tooltip="Öffnet Plan41")
+
+ def onClosePlugin(self):
+ """
+ Wird aufgerufen, wenn das Dockwidget geschlossen wird. Setzt den Aktivitätsstatus zurück.
+ """
+ self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)
+ self.pluginIsActive = False
+
+ def unload(self):
+ """
+ Wird beim Deaktivieren des Plugins aufgerufen. Entfernt Menü- und Toolbar-Eintrag.
+ """
+ self.ui.remove_action(self.action_text)
+
+ def run(self):
+ """
+ Wird beim Klick auf Menüeintrag oder Symbolleistenaktion ausgeführt.
+ Zeigt das Dockwidget an.
+ """
+
+ if 'sn_basis' not in plugins:
+ QMessageBox.warning(None, "Abhängigkeit fehlt",
+ "Das Plugin 'LNO Sachsen | Basisfunktionen' ist nicht installiert oder nicht aktiviert.\nBitte installieren und aktivieren, um fortzufahren.")
+ return # Plugin nicht starten
+ # Prüfen, ob das eigene Dockwidget existiert und aktuell sichtbar ist
+ dock_visible = self.dockwidget is not None and self.dockwidget.isVisible()
+
+ if not dock_visible:
+ # Pluginstatus setzen, damit z. B. beim Schließen korrekt zurückgesetzt werden kann
+ self.pluginIsActive = True
+
+ # Falls noch kein Dockwidget existiert, wird es jetzt erzeugt
+ if self.dockwidget is None:
+ self.dockwidget = Plan41DockWidget()
+ self.dockwidget.closingPlugin.connect(self.onClosePlugin)
+
+ # Dock anzeigen und ggf. andere Docks schließen
+ from .shared.dockmanager import DockManager
+ DockManager.show(self.dockwidget)
+ else:
+ # Falls das eigene Dock bereits sichtbar ist, wird keine Aktion ausgeführt
+ pass
diff --git a/metadata.txt b/metadata.txt
new file mode 100644
index 0000000..f2f76c9
--- /dev/null
+++ b/metadata.txt
@@ -0,0 +1,21 @@
+[general]
+name=LNO Sachsen | Plan41
+qgisMinimumVersion=3.0
+description=Dieses Plugin ist ein Test
+version=25.10.1
+author=Michael Otto
+email=michael.otto@landkreis-mittelsachsen.de
+
+about=Provide a brief description of the plugin and its purpose.
+
+hasProcessingProvider=no
+tags=python
+
+category=Plugins
+icon=icon.png
+experimental=True
+
+deprecated=False
+
+server=False
+
diff --git a/resources.py b/resources.py
new file mode 100644
index 0000000..5a9d74d
--- /dev/null
+++ b/resources.py
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+
+# Resource object code
+#
+# Created by: The Resource Compiler for PyQt5 (Qt v5.15.2)
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore
+
+qt_resource_data = b"\
+\x00\x00\x02\x5f\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\
+\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0e\xc3\x00\x00\x0e\xc3\
+\x01\xc7\x6f\xa8\x64\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\
+\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\
+\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\xec\x49\x44\
+\x41\x54\x58\x85\xed\x96\x4f\x4b\x54\x51\x18\xc6\x7f\x8f\xdc\x60\
+\x5c\x95\x21\x8c\x90\xe4\xd4\xa2\x75\x9b\x5c\xe7\x4a\x23\x62\x08\
+\xdc\xda\xa6\x0f\x20\x41\x0b\x21\x68\x53\x8b\x96\x2e\x12\xa1\x6d\
+\xa0\x5f\x20\x12\xbf\x80\x6e\x5a\x24\x09\x6e\x24\xff\x20\xa1\x09\
+\xb3\xc9\x9c\x19\x32\xde\x16\xf7\x1d\x3a\x5c\xef\xf5\xde\x1c\x1d\
+\x25\xe6\x85\xcb\xb9\xf7\x37\xef\xb9\xef\x73\xce\x79\xce\x99\x2b\
+\xe0\x07\x50\xe2\x62\xa2\x1e\x01\x57\x80\x3e\xa0\xd9\xe1\xe2\x25\
+\xe0\x7b\xe4\x0f\x47\x66\xf6\xab\x93\xd5\x25\x45\x00\x3d\x9d\x2c\
+\x9a\x16\x5d\x01\x97\x5f\x80\xa4\x3e\x49\x6f\x25\x55\x03\x56\x96\
+\x34\x23\x69\xec\x84\x7e\x77\x24\xcd\x4a\x7a\x93\x57\xa3\x01\x94\
+\xcc\x8c\xb4\x0b\xb8\x0f\x18\xf0\x22\x60\x0f\x9d\x3d\x4b\xc9\x8f\
+\x80\x49\xe0\xc0\x73\xf6\x33\xde\xdb\x0b\xd4\x8b\x2c\xc1\x2d\x6f\
+\x37\x02\x36\xe4\xed\x66\x62\xd4\x77\x81\x4f\xc0\x34\xf0\xb9\xc0\
+\xbb\x89\xf2\x53\xa8\x14\x15\x00\xbc\x06\xae\x02\x8f\x81\x65\x60\
+\xf7\xd4\x02\x24\x8d\x00\xa3\x40\x6b\x9d\x9f\x04\x3e\x78\xe0\xed\
+\x53\x49\x4b\x66\x36\xe7\xcf\x2f\x81\x35\x33\xab\x4b\x2a\xe7\x15\
+\x6f\x45\xaa\x07\x80\x57\x40\x0d\x38\x02\x7e\xfb\x7d\x2d\x85\x7d\
+\xc8\x58\xe3\x32\x05\x3c\x90\x29\x20\x48\xdc\xf4\x51\x85\xec\x1b\
+\xb0\x92\xd5\xe7\x5f\x04\x9c\x68\x42\x3f\xaf\x6f\x00\x5b\x01\x2b\
+\x01\x03\x21\x6b\x27\xf2\x76\xc1\x20\xb1\x4f\xb6\x03\x56\x01\x94\
+\x60\xa7\x8e\x54\x13\x4a\xea\xf1\x42\xf7\x1c\xfd\x94\x74\xdb\xef\
+\x87\x03\x36\x64\x66\x6d\xcf\xc4\x31\x0f\x78\x61\x2b\x78\x55\xda\
+\xf1\x40\xd6\x36\xfc\x02\x8c\x03\x13\x40\x15\x98\x02\xbe\xfa\x6f\
+\x13\xc0\x23\xe0\x39\xb1\x41\x77\xce\x7c\x06\x02\x95\xef\x7d\x14\
+\x03\x01\x9b\x77\x76\xfd\xdc\x77\x01\xf1\x89\xd7\x04\xf6\x12\xec\
+\xc0\xcc\x6a\xed\x8e\x1c\xf2\x77\xc1\x4d\x60\xdb\x5c\x72\x20\x20\
+\xd5\x78\x92\xde\x49\x32\x49\xc6\xdf\x63\xb8\xbf\xc5\x24\x35\x25\
+\xf5\x86\x7d\xf2\xfe\x0b\x16\x80\xf5\x04\xfb\x08\xac\x66\xe4\x2f\
+\x12\x4f\x7b\x56\x1c\x92\xf8\xf8\x15\xb1\x07\xae\x99\x59\x23\x47\
+\xcc\x99\x86\xcf\x44\xed\xf2\x7f\x11\x75\x05\x74\x05\xfc\xf7\x02\
+\x5a\x07\x51\x5d\xd2\x45\xd4\x6f\xfc\x01\xf3\xb6\x83\x46\x54\x23\
+\xdb\x20\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
+"
+
+qt_resource_name = b"\
+\x00\x0a\
+\x07\x34\x98\xd1\
+\x00\x73\
+\x00\x6e\x00\x5f\x00\x70\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\x00\x31\
+\x00\x05\
+\x00\x6f\xa6\x53\
+\x00\x69\
+\x00\x63\x00\x6f\x00\x6e\x00\x73\
+\x00\x08\
+\x0a\x61\x5a\xa7\
+\x00\x69\
+\x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
+"
+
+qt_resource_struct_v1 = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
+\x00\x00\x00\x1a\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\
+\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+"
+
+qt_resource_struct_v2 = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x1a\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x01\x99\x28\x6e\x23\x10\
+"
+
+qt_version = [int(v) for v in QtCore.qVersion().split('.')]
+if qt_version < [5, 8, 0]:
+ rcc_version = 1
+ qt_resource_struct = qt_resource_struct_v1
+else:
+ rcc_version = 2
+ qt_resource_struct = qt_resource_struct_v2
+
+def qInitResources():
+ QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
diff --git a/resources.qrc b/resources.qrc
new file mode 100644
index 0000000..ea9d1ea
--- /dev/null
+++ b/resources.qrc
@@ -0,0 +1,5 @@
+
+
+ icons/icon.png
+
+
diff --git a/scripts/compile.bat b/scripts/compile.bat
new file mode 100644
index 0000000..c6f2bb6
--- /dev/null
+++ b/scripts/compile.bat
@@ -0,0 +1,11 @@
+@echo off
+REM Wechsle ins Plugin-Hauptverzeichnis (eine Ebene über /scripts)
+cd /d %~dp0\..
+
+call "C:\Program Files\QGIS 3.34.5\bin\o4w_env.bat"
+
+REM Kompiliere die Ressourcen-Datei
+pyrcc5 resources.qrc -o resources.py
+
+@echo on
+echo Ressourcen wurden erfolgreich kompiliert.
diff --git a/shared/__init__.py b/shared/__init__.py
new file mode 100644
index 0000000..5c187ed
--- /dev/null
+++ b/shared/__init__.py
@@ -0,0 +1,2 @@
+from .ui import UI
+from .dockmanager import DockManager
\ No newline at end of file
diff --git a/shared/dockmanager.py b/shared/dockmanager.py
new file mode 100644
index 0000000..04812be
--- /dev/null
+++ b/shared/dockmanager.py
@@ -0,0 +1,60 @@
+from qgis.PyQt.QtCore import Qt
+from qgis.PyQt.QtWidgets import QDockWidget
+from qgis.utils import iface
+import inspect
+
+class DockManager:
+ """
+ Zeigt ein Dockwidget an und schließt alle anderen mit dem Namensschema 'sn_dock_'.
+ Der Dockname wird automatisch aus dem Pluginmodul abgeleitet.
+ """
+
+ # Standard-Dockbereich: Rechts (wie die Verarbeitungswerkzeuge)
+ default_area = Qt.RightDockWidgetArea
+
+ @classmethod
+ def show(cls, dock_widget, area=None):
+ # Falls kein Bereich übergeben wurde, verwende den Standardwert
+ if area is None:
+ area = cls.default_area
+
+ # Pluginname automatisch aus dem Modulpfad ableiten (z. B. 'sn_plugin1' → 'plugin1')
+ caller_module = inspect.getmodule(inspect.stack()[1][0])
+ full_module_name = caller_module.__name__ # z. B. 'sn_plugin1.main'
+ plugin_name = full_module_name.split('.')[0] # → 'sn_plugin1'
+ dock_name = f"sn_dock_{plugin_name.replace('sn_', '')}" # → 'sn_dock_plugin1'
+
+ # Objektname für das Dock setzen, damit es eindeutig identifizierbar ist
+ dock_widget.setObjectName(dock_name)
+
+ # Nur rechts andocken erlauben, wie bei der Toolbox
+ dock_widget.setAllowedAreas(Qt.RightDockWidgetArea)
+
+ # Dock-Features setzen: schließbar und verschiebbar
+ dock_widget.setFeatures(QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetMovable)
+
+ # Alle vorhandenen Dockwidgets im Hauptfenster durchsuchen
+ # und solche mit dem Namensschema 'sn_dock_' schließen – außer dem aktuellen
+ all_docks = iface.mainWindow().findChildren(QDockWidget)
+ for widget in all_docks:
+ if widget.objectName().startswith("sn_dock_") and widget != dock_widget:
+ try:
+ iface.removeDockWidget(widget)
+ widget.close()
+ except Exception:
+ pass # Fehler beim Schließen ignorieren (z. B. falls bereits entfernt)
+
+ # Neues Dock anzeigen
+ iface.addDockWidget(area, dock_widget)
+
+ # Tabifizierung verhindern – andere Docks im selben Bereich entfernen
+ for widget in iface.mainWindow().findChildren(QDockWidget):
+ if widget != dock_widget and iface.mainWindow().dockWidgetArea(widget) == area:
+ iface.mainWindow().removeDockWidget(widget)
+
+ # Breite setzen wie bei der Toolbox (optional, anpassbar)
+ dock_widget.setMinimumWidth(300)
+ dock_widget.setMaximumWidth(400)
+
+ # Höhe nicht erzwingen – Qt passt sie automatisch an
+ dock_widget.show()
diff --git a/shared/ui.py b/shared/ui.py
new file mode 100644
index 0000000..a839fbc
--- /dev/null
+++ b/shared/ui.py
@@ -0,0 +1,75 @@
+from qgis.PyQt.QtWidgets import QMenu, QToolBar, QAction
+from qgis.PyQt.QtGui import QIcon
+from qgis.utils import iface
+
+_shared_toolbar = None # globale Toolbar-Instanz
+_shared_menu = None # globale Menü-Instanz
+
+class UI:
+ TITLE = "LNO Sachsen"
+
+ def __init__(self):
+ self.menu = self._get_or_create_menu()
+ self.toolbar = self._get_or_create_toolbar()
+
+ def _get_or_create_menu(self):
+ global _shared_menu
+ if _shared_menu:
+ return _shared_menu
+
+ menubar = iface.mainWindow().menuBar()
+ for action in menubar.actions():
+ if action.menu() and action.text() == self.TITLE:
+ _shared_menu = action.menu()
+ return _shared_menu
+
+ menu = QMenu(self.TITLE, iface.mainWindow())
+ menu.setObjectName(self.TITLE)
+ menubar.addMenu(menu)
+ _shared_menu = menu
+ return menu
+
+ def _get_or_create_toolbar(self):
+ global _shared_toolbar
+ if _shared_toolbar:
+ return _shared_toolbar
+
+ main_window = iface.mainWindow()
+ toolbar = main_window.findChild(QToolBar, self.TITLE)
+ if not toolbar:
+ toolbar = QToolBar(self.TITLE, main_window)
+ toolbar.setObjectName(self.TITLE)
+ main_window.addToolBar(toolbar)
+
+ _shared_toolbar = toolbar
+ return toolbar
+
+ def add_action(self, text, callback, icon=None, tooltip=None):
+ # Menüeintrag
+ if not any(a.text() == text for a in self.menu.actions()):
+ action = QAction(icon, text, iface.mainWindow()) if icon else QAction(text, iface.mainWindow())
+ if tooltip:
+ action.setToolTip(tooltip)
+ action.triggered.connect(callback)
+ self.menu.addAction(action)
+
+ # Symbolleistenaktion
+ if not any(a.text() == text for a in self.toolbar.actions()):
+ action = QAction(icon, text, iface.mainWindow()) if icon else QAction(text, iface.mainWindow())
+ if tooltip:
+ action.setToolTip(tooltip)
+ action.triggered.connect(callback)
+ self.toolbar.addAction(action)
+
+ def remove_action(self, text):
+ # Menüeintrag entfernen
+ for act in self.menu.actions():
+ if act.text() == text:
+ self.menu.removeAction(act)
+ break
+
+ # Symbolleistenaktion entfernen
+ for act in self.toolbar.actions():
+ if act.text() == text:
+ self.toolbar.removeAction(act)
+ break
diff --git a/ui/__init__.py b/ui/__init__.py
new file mode 100644
index 0000000..df40a90
--- /dev/null
+++ b/ui/__init__.py
@@ -0,0 +1 @@
+from .tab_plan41 import TabPlan41Widget
\ No newline at end of file
diff --git a/ui/sn_plan41_dockwidget.py b/ui/sn_plan41_dockwidget.py
new file mode 100644
index 0000000..8f7f8cd
--- /dev/null
+++ b/ui/sn_plan41_dockwidget.py
@@ -0,0 +1,31 @@
+from qgis.PyQt.QtWidgets import QDockWidget, QTabWidget, QVBoxLayout, QWidget
+from qgis.PyQt.QtCore import pyqtSignal
+
+from sn_basis.ui.tab_projekt import TabProjektWidget
+
+from ..ui import TabPlan41Widget
+
+class Plan41DockWidget(QDockWidget):
+
+ closingPlugin = pyqtSignal()
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ self.setWindowTitle("LNO Sachsen | Plan 41")
+
+ container = QWidget()
+ layout = QVBoxLayout(container)
+
+ self.tabWidget = QTabWidget()
+ layout.addWidget(self.tabWidget)
+
+ self.setWidget(container)
+
+ # Tabs hinzufügen
+ self.tabWidget.addTab(TabPlan41Widget(self), "Plan 41")
+ self.tabWidget.addTab(TabProjektWidget(self), "Projekt")
+
+ def closeEvent(self, event):
+ self.closingPlugin.emit()
+ event.accept()
\ No newline at end of file
diff --git a/ui/tab_plan41.py b/ui/tab_plan41.py
new file mode 100644
index 0000000..9a944af
--- /dev/null
+++ b/ui/tab_plan41.py
@@ -0,0 +1,12 @@
+# tab_info.py
+from qgis.PyQt import uic
+from qgis.PyQt.QtWidgets import QWidget
+import os
+
+FORM_CLASS, _ = uic.loadUiType(os.path.join(
+ os.path.dirname(__file__), 'tab_plan41.ui'))
+
+class TabPlan41Widget(QWidget, FORM_CLASS):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.setupUi(self)
diff --git a/ui/tab_plan41.ui b/ui/tab_plan41.ui
new file mode 100644
index 0000000..b6c4c32
--- /dev/null
+++ b/ui/tab_plan41.ui
@@ -0,0 +1,32 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 538
+ 295
+
+
+
+ Form
+
+
+
+
+ 40
+ 50
+ 47
+ 13
+
+
+
+ Plan41
+
+
+
+
+
+