[FEATURE] Add SQL Logging to AdminPanel 89/57889/12
authorSusanne Moog <susanne.moog@typo3.org>
Tue, 7 Aug 2018 19:15:34 +0000 (21:15 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Thu, 23 Aug 2018 11:13:04 +0000 (13:13 +0200)
To better debug websites SQL logging has been added to the admin panel.
SQL queries will be logged whenever the admin panel is installed and
activated for the current user and request.

Queries using query parameters are displayed with all occuring parameter
values (grouped by the main query). To find where queries came from a
short backtrace has additionally been added to the query logging.

The logging itself has been implemented using the doctrine query
logging functionality.

Resolves: #84609
Releases: master
Change-Id: I84eebc8a23d6fa15c20dc48781409d4ab03f1bb1
Reviewed-on: https://review.typo3.org/57889
Reviewed-by: Benjamin Kott <benjamin.kott@outlook.com>
Tested-by: Benjamin Kott <benjamin.kott@outlook.com>
Reviewed-by: Willi Wehmeier <wwwehmeier@gmail.com>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
19 files changed:
Build/Resources/Public/Sass/adminpanel.scss
typo3/sysext/adminpanel/Classes/Controller/MainController.php
typo3/sysext/adminpanel/Classes/Hooks/RenderHook.php
typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php [new file with mode: 0644]
typo3/sysext/adminpanel/Classes/Log/InMemoryLogWriter.php
typo3/sysext/adminpanel/Classes/Middleware/AdminPanelInitiator.php
typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php [new file with mode: 0644]
typo3/sysext/adminpanel/Classes/Modules/Debug/QueryInformation.php [new file with mode: 0644]
typo3/sysext/adminpanel/Classes/Utility/MemoryUtility.php [new file with mode: 0644]
typo3/sysext/adminpanel/Classes/Utility/StateUtility.php [new file with mode: 0644]
typo3/sysext/adminpanel/Configuration/RequestMiddlewares.php
typo3/sysext/adminpanel/Resources/Private/Language/locallang.xlf
typo3/sysext/adminpanel/Resources/Private/Language/locallang_debug.xlf
typo3/sysext/adminpanel/Resources/Private/Templates/Modules/Debug/QueryInformation.html [new file with mode: 0644]
typo3/sysext/adminpanel/Resources/Public/Css/adminpanel.css
typo3/sysext/adminpanel/Resources/Public/JavaScript/AdminPanel.js
typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php [new file with mode: 0644]
typo3/sysext/adminpanel/ext_localconf.php
typo3/sysext/core/Documentation/Changelog/master/Feature-84609-AddSQLLogModuleToAdminPanel.rst [new file with mode: 0644]

index 3c1293b..e6ccba5 100644 (file)
@@ -3,7 +3,6 @@
 // ===========
 // Contains all needed styles for the Admin Panel.
 //
-
 //
 // Load Variables
 //
@@ -16,6 +15,7 @@
 $adminPanel-zindex: 99990;
 $adminPanel-zindex-backdrop: 99991;
 $adminPanel-zindex-bar: 99992;
+$adminPanel-zindex-popup: 99994;
 $adminPanel-prefix: '#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel';
 $adminPanel-bg: $gray-darker;
 $adminPanel-color: $gray-lighter;
@@ -67,6 +67,10 @@ $adminPanel-input-border-radius: 2px;
 $adminPanel-input-vertical-padding: 1.25em;
 $adminPanel-input-horizontal-padding: 0.75em;
 
+// Progress
+$adminPanel-progress-default: #333;
+$adminPanel-progress-green: #629755;
+
 //
 // Mixins
 //
@@ -87,6 +91,13 @@ $adminPanel-input-horizontal-padding: 0.75em;
 }
 
 //
+// NoScroll
+//
+body.typo3-adminPanel-noscroll {
+    overflow: hidden;
+}
+
+//
 // Reset
 //
 #{$adminPanel-prefix} {
@@ -515,9 +526,12 @@ $adminPanel-input-horizontal-padding: 0.75em;
     .typo3-adminPanel-row {
         display: flex;
         flex-wrap: wrap;
-        padding: 0.25em 0;
-        margin-left: -0.75em;
-        margin-right: -0.75em;
+        padding: 8px 0;
+    }
+
+    .typo3-adminPanel-row-nowrap {
+        flex-wrap: nowrap;
+        justify-content: space-between;
     }
 
     .typo3-adminPanel-row-header {
@@ -527,10 +541,26 @@ $adminPanel-input-horizontal-padding: 0.75em;
     }
 
     .typo3-adminPanel-col {
-        padding: 0.25em 0.75em;
+        padding: 0 10px;
         word-break: break-all;
     }
 
+    .typo3-adminPanel-col-icon {
+        width: 34px;
+        flex-shrink: 0;
+        flex-grow: 0;
+    }
+
+    .typo3-adminPanel-col-auto {
+        flex-grow: 1;
+    }
+
+    .typo3-adminPanel-col-ellipsis {
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+    }
+
     @for $i from 1 through 12 {
         .typo3-adminPanel-col-#{$i} {
             @include make-col($i);
@@ -649,10 +679,34 @@ $adminPanel-input-horizontal-padding: 0.75em;
         }
     }
 
+    .typo3-adminPanel-table-cell-icon {
+        width: 34px;
+    }
+
+    .typo3-adminPanel-table-cell-icon {
+        width: 34px;
+        min-width: 34px;
+        white-space: nowrap;
+    }
+
+    .typo3-adminPanel-table-cell-time {
+        width: 250px;
+        min-width: 250px;
+        white-space: nowrap;
+    }
+
     .typo3-adminPanel-table-cell-key {
         width: 19%;
     }
 
+    .typo3-adminPanel-table-cell-space {
+        width: 100%;
+    }
+
+    .typo3-adminPanel-table-cell-break {
+        word-wrap: break-word;
+    }
+
     .typo3-adminPanel-table-cell-nowrap {
         white-space: nowrap;
     }
@@ -844,7 +898,7 @@ $adminPanel-input-horizontal-padding: 0.75em;
             display: block;
             border-radius: $adminPanel-input-border-radius;
             border: 1px solid $adminPanel-input-border;
-            background: $adminPanel-input-bg url("data:image/svg+xml;charset=utf8, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'><path fill='#333' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>") no-repeat right 0.75em center;
+            background: $adminPanel-input-bg url("data:image/svg+xml;charset=utf8, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'><path fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>") no-repeat right 0.75em center;
             background-size: 8px 10px;
             appearance: none;
 
@@ -950,3 +1004,169 @@ $adminPanel-input-horizontal-padding: 0.75em;
         }
     }
 }
+
+//
+// Progress
+//
+#{$adminPanel-prefix} {
+    .typo3-adminPanel-progress {
+        position: relative;
+        height: 1.5em;
+    }
+
+    .typo3-adminPanel-progress-bar {
+        position: absolute;
+        top: 0;
+        left: 0;
+        height: 100%;
+        width: 100%;
+        background-color: $adminPanel-progress-default;
+    }
+
+    .typo3-adminPanel-progress-bar-green {
+        background-color: $adminPanel-progress-green;
+    }
+
+    .typo3-adminPanel-progress-value {
+        text-align: right;
+    }
+}
+
+//
+// Zoom
+//
+#{$adminPanel-prefix} {
+    .typo3-adminPanel-zoom {
+        position: absolute;
+        z-index: $adminPanel-zindex-popup;
+        background-color: #fafafa;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        display: none;
+        flex-direction: column;
+    }
+
+    .typo3-adminPanel-zoom-show {
+        display: flex;
+    }
+
+    .typo3-adminPanel-zoom-header {
+        padding: 20px;
+        border-bottom: 1px solid #dadada;
+    }
+
+    .typo3-adminPanel-zoom-body {
+        padding: 20px;
+        height: 100%;
+        overflow: auto;
+
+        > *:first-child {
+            margin-top: 0;
+        }
+
+        > *:last-child {
+            margin-bottom: 0;
+        }
+    }
+}
+
+//
+// SQL
+//
+#{$adminPanel-prefix} {
+    .typo3-adminPanel-sql-col-count {
+        text-align: right;
+        width: 90px;
+        flex-shrink: 0;
+    }
+
+    .typo3-adminPanel-sql-col-time {
+        width: 250px;
+        flex-shrink: 0;
+    }
+
+    .typo3-adminPanel-sql-header {
+        color: $gray;
+        border-bottom: 1px solid $gray-light;
+    }
+
+    .typo3-adminPanel-sql-queries-header {
+        color: $gray;
+        border-bottom: 1px solid $gray-light;
+    }
+
+    .typo3-adminPanel-sql-query-ellipsis {
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+    }
+
+    > .typo3-adminPanel-sql-panel {
+        border-bottom: 1px dashed $gray-light;
+
+        &:nth-child(2n+1) {
+            background: $gray-lighter;
+        }
+    }
+
+    .typo3-adminPanel-bar {
+        display: flex;
+        height: auto;
+        overflow: hidden; // force rounded corners by cropping it
+        font-size: $font-size-small;
+
+        .typo3-adminPanel-bar-value {
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+            color: $gray-darker;
+            text-align: left;
+            white-space: nowrap;
+            background-color: $adminPanel-bar-color;
+            transition: all 0.5s ease;
+            width: 0;
+        }
+    }
+}
+
+//
+// SQL Statement
+//
+#{$adminPanel-prefix} {
+    .typo3-adminPanel-sql-statement {
+        margin: 1em 0;
+        padding: 0.75em 1em;
+        font-family: $font-family-monospace;
+        background: #f2f2f2;
+        font-size: $font-size-small;
+    }
+}
+
+//
+// SQL Backtrace
+//
+#{$adminPanel-prefix} {
+    .typo3-adminPanel-sql-backtrace {
+        margin: 1em 0;
+    }
+
+    .typo3-adminPanel-sql-backtrace-item {
+        margin: 1px 0;
+        padding: 0.75em 1em;
+        background-color: #f2f2f2;
+        font-family: $font-family-monospace;
+        word-break: break-word;
+    }
+
+    .typo3-adminPanel-sql-backtrace-item-function,
+    .typo3-adminPanel-sql-backtrace-item-file {
+        display: block;
+    }
+
+    .typo3-adminPanel-sql-backtrace-item-file {
+        opacity: 0.5;
+        font-size: 0.8em;
+    }
+}
index a3a5ebe..b347901 100644 (file)
@@ -58,7 +58,7 @@ class MainController implements SingletonInterface
     /**
      * @var array
      */
-    private $adminPanelModuleConfiguration;
+    protected $adminPanelModuleConfiguration;
 
     /**
      * @param ModuleLoader $moduleLoader
index 7ed79b0..21d4db5 100644 (file)
@@ -17,7 +17,7 @@ namespace TYPO3\CMS\Adminpanel\Hooks;
  */
 
 use TYPO3\CMS\Adminpanel\Controller\MainController;
-use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
+use TYPO3\CMS\Adminpanel\Utility\StateUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 
@@ -40,9 +40,7 @@ class RenderHook
     public function renderAdminPanel(array $params, TypoScriptFrontendController $pObj): void
     {
         if (
-            $pObj->isBackendUserLoggedIn() &&
-            $GLOBALS['BE_USER'] instanceof FrontendBackendUserAuthentication &&
-            isset($GLOBALS['BE_USER']->getTSConfig()['admPanel.']['enable.']) &&
+            StateUtility::isActivated() &&
             !$GLOBALS['BE_USER']->extAdminConfig['hide'] && $pObj->config['config']['admPanel']
         ) {
             $mainController = GeneralUtility::makeInstance(MainController::class);
diff --git a/typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php b/typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php
new file mode 100644 (file)
index 0000000..870a5bc
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+declare(strict_types = 1);
+
+namespace TYPO3\CMS\Adminpanel\Log;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Doctrine\DBAL\Logging\SQLLogger;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
+use TYPO3\CMS\Adminpanel\Utility\MemoryUtility;
+
+/**
+ * Doctrine SQL Logger implementation for recording queries for the admin panel
+ */
+class DoctrineSqlLogger implements SQLLogger, LoggerAwareInterface
+{
+    use LoggerAwareTrait;
+
+    /**
+     * Executed SQL queries.
+     *
+     * @var array
+     */
+    protected $queries = [];
+
+    /**
+     * If Debug Stack is enabled (log queries) or not.
+     *
+     * @var bool
+     */
+    protected $enabled = true;
+
+    /**
+     * @var float
+     */
+    protected $start;
+
+    /**
+     * @var int
+     */
+    protected $currentQuery = 0;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function startQuery($sql, array $params = null, array $types = null)
+    {
+        if ($this->enabled && MemoryUtility::isMemoryConsumptionTooHigh()) {
+            $this->enabled = false;
+            $this->logger->warning('SQL Logging consumed too much memory, aborted. Not all queries have been recorded.');
+        }
+        if ($this->enabled) {
+            $this->start = microtime(true);
+            $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 7);
+            // remove this method
+            array_shift($backtrace);
+            // remove doctrine execute query
+            array_shift($backtrace);
+            // remove queryBuilder execute
+            array_shift($backtrace);
+            $this->queries[++$this->currentQuery] = [
+                'sql' => $sql,
+                'params' => $params,
+                'types' => $types,
+                'executionMS' => 0,
+                'backtrace' => $backtrace
+            ];
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function stopQuery()
+    {
+        if ($this->enabled) {
+            $this->queries[$this->currentQuery]['executionMS'] = microtime(true) - $this->start;
+        }
+    }
+
+    /**
+     * @return array
+     */
+    public function getQueries(): array
+    {
+        return $this->queries;
+    }
+}
index 1617a06..8e17017 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Adminpanel\Log;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Adminpanel\Utility\MemoryUtility;
 use TYPO3\CMS\Core\Log\LogLevel;
 use TYPO3\CMS\Core\Log\LogRecord;
 use TYPO3\CMS\Core\Log\Writer\AbstractWriter;
@@ -29,8 +30,6 @@ class InMemoryLogWriter extends AbstractWriter
 {
     public static $log = [];
 
-    private const MINIMAL_PERCENT_OF_FREE_MEMORY = 0.30;
-
     private static $memoryLock = false;
 
     /**
@@ -48,7 +47,7 @@ class InMemoryLogWriter extends AbstractWriter
         }
 
         // Guard: Memory Usage
-        if (!self::$memoryLock && $this->isMemoryConsumptionTooHigh()) {
+        if (!self::$memoryLock && MemoryUtility::isMemoryConsumptionTooHigh()) {
             $this->lockWriter();
             return $this;
         }
@@ -59,24 +58,6 @@ class InMemoryLogWriter extends AbstractWriter
     }
 
     /**
-     * Checks memory usage used in current process - this is no guarantee for not running out of memory
-     * but should prevent memory exhaustion due to the InMemoryLogger in most cases.
-     *
-     * The logger will stop logging once the amount of free memory falls below the threshold (see
-     * MINIMAL_PERCENT_OF_FREE_MEMORY const).
-     *
-     * @return bool
-     */
-    protected function isMemoryConsumptionTooHigh(): bool
-    {
-        $iniLimit = ini_get('memory_limit');
-        $memoryLimit = $iniLimit === '-1' ? -1 : GeneralUtility::getBytesFromSizeMeasurement($iniLimit);
-        $freeMemory = $memoryLimit - memory_get_usage(true);
-
-        return $memoryLimit > 0 && $freeMemory < (self::MINIMAL_PERCENT_OF_FREE_MEMORY * $memoryLimit);
-    }
-
-    /**
      * Lock writer and add a info message that there may potentially be more entries.
      */
     protected function lockWriter(): void
index d2b2cfc..9c6ca7f 100644 (file)
@@ -21,8 +21,8 @@ use Psr\Http\Message\ServerRequestInterface;
 use Psr\Http\Server\MiddlewareInterface;
 use Psr\Http\Server\RequestHandlerInterface;
 use TYPO3\CMS\Adminpanel\Controller\MainController;
+use TYPO3\CMS\Adminpanel\Utility\StateUtility;
 use TYPO3\CMS\Adminpanel\View\AdminPanelView;
-use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -36,6 +36,7 @@ class AdminPanelInitiator implements MiddlewareInterface
      * Initialize the adminPanel if
      * - backend user is logged in
      * - at least one adminpanel functionality is enabled
+     * - admin panel is open
      *
      * @param ServerRequestInterface $request
      * @param RequestHandlerInterface $handler
@@ -43,28 +44,15 @@ class AdminPanelInitiator implements MiddlewareInterface
      */
     public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
     {
-        if ($GLOBALS['BE_USER'] instanceof FrontendBackendUserAuthentication) {
+        if (StateUtility::isActivated() && StateUtility::isOpen()) {
+            $adminPanelController = GeneralUtility::makeInstance(
+                MainController::class
+            );
+            $adminPanelController->initialize($request);
+            // legacy handling
             $beUser = $GLOBALS['BE_USER'];
-            // set legacy config
-            $beUser->extAdminConfig = $beUser->getTSConfig()['admPanel.'] ?? [];
-            $adminPanelConfiguration = $beUser->extAdminConfig;
-            if (isset($adminPanelConfiguration['enable.']) &&
-                ($beUser->uc['AdminPanel']['display_top'] ?? false)
-            ) {
-                // only initialize if at least one module is enabled.
-                foreach ($adminPanelConfiguration['enable.'] as $value) {
-                    if ($value) {
-                        $adminPanelController = GeneralUtility::makeInstance(
-                            MainController::class
-                        );
-                        $adminPanelController->initialize($request);
-                        // legacy handling
-                        $beUser->adminPanel = GeneralUtility::makeInstance(AdminPanelView::class);
-                        $beUser->extAdmEnabled = true;
-                        break;
-                    }
-                }
-            }
+            $beUser->adminPanel = GeneralUtility::makeInstance(AdminPanelView::class);
+            $beUser->extAdmEnabled = true;
         }
         return $handler->handle($request);
     }
diff --git a/typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php b/typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php
new file mode 100644 (file)
index 0000000..cb19610
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+declare(strict_types = 1);
+
+namespace TYPO3\CMS\Adminpanel\Middleware;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use TYPO3\CMS\Adminpanel\Log\DoctrineSqlLogger;
+use TYPO3\CMS\Adminpanel\Utility\StateUtility;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Enable sql logging for the admin panel
+ *
+ * @internal
+ */
+class SqlLogging implements MiddlewareInterface
+{
+
+    /**
+     * Enable SQL Logging as early as possible to catch all queries if the admin panel is active
+     */
+    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+    {
+        if (StateUtility::isActivated() && StateUtility::isOpen()) {
+            $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
+            $connection = $connectionPool->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
+            $connection->getConfiguration()->setSQLLogger(GeneralUtility::makeInstance(DoctrineSqlLogger::class));
+        }
+        return $handler->handle($request);
+    }
+}
diff --git a/typo3/sysext/adminpanel/Classes/Modules/Debug/QueryInformation.php b/typo3/sysext/adminpanel/Classes/Modules/Debug/QueryInformation.php
new file mode 100644 (file)
index 0000000..7a0b360
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+declare(strict_types = 1);
+
+namespace TYPO3\CMS\Adminpanel\Modules\Debug;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Adminpanel\Log\DoctrineSqlLogger;
+use TYPO3\CMS\Adminpanel\Modules\AbstractSubModule;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Fluid\View\StandaloneView;
+
+/**
+ * Admin Panel Query Information module for showing SQL Queries
+ */
+class QueryInformation extends AbstractSubModule
+{
+    /**
+     * Identifier for this Sub-module,
+     * for example "preview" or "cache"
+     *
+     * @return string
+     */
+    public function getIdentifier(): string
+    {
+        return 'debug_queryinformation';
+    }
+
+    /**
+     * Sub-Module label
+     *
+     * @return string
+     */
+    public function getLabel(): string
+    {
+        return $this->getLanguageService()->sL(
+            'LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.queryInformation.label'
+        );
+    }
+
+    /**
+     * @return string Returns content of admin panel
+     * @throws \UnexpectedValueException
+     * @throws \InvalidArgumentException
+     * @throws \Doctrine\DBAL\DBALException
+     */
+    public function getContent(): string
+    {
+        $view = new StandaloneView();
+        $view->setTemplatePathAndFilename(
+            'typo3/sysext/adminpanel/Resources/Private/Templates/Modules/Debug/QueryInformation.html'
+        );
+        $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
+        $connection = $connectionPool->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
+        $logger = $connection->getConfiguration()->getSQLLogger();
+        $this->getLanguageService()->includeLLFile('EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf');
+        if ($logger instanceof DoctrineSqlLogger) {
+            $queries = $logger->getQueries();
+            $this->queryCount = \count($queries);
+            $groupedQueries = $this->groupQueries($queries);
+            $totalTime = array_sum(array_column($queries, 'executionMS')) * 1000;
+            $view->assign('queries', $groupedQueries ?? [])->assign('totalTime', $totalTime);
+        }
+        return $view->render();
+    }
+
+    /**
+     * @param array $queries
+     * @return array
+     */
+    protected function groupQueries(array $queries): array
+    {
+        $groupedQueries = [];
+        foreach ($queries as $query) {
+            $identifier = sha1($query['sql']) . sha1(implode(',', $query['backtrace']));
+            if (is_array($query['params'])) {
+                foreach ($query['params'] as $k => $param) {
+                    if (is_array($param)) {
+                        $query['params'][$k] = implode(',', $param);
+                    }
+                }
+            }
+            if (isset($groupedQueries[$identifier])) {
+                $groupedQueries[$identifier]['count']++;
+                $groupedQueries[$identifier]['time'] += ($query['executionMS'] * 1000);
+                $groupedQueries[$identifier]['queries'][] = $query;
+            } else {
+                $groupedQueries[$identifier] = [
+                    'sql' => $query['sql'],
+                    'time' => $query['executionMS'] * 1000,
+                    'count' => 1,
+                    'queries' => [
+                        $query,
+                    ],
+                ];
+            }
+        }
+        uasort(
+            $groupedQueries,
+            function ($a, $b) {
+                return $b['time'] <=> $a['time'];
+            }
+        );
+        return $groupedQueries;
+    }
+}
diff --git a/typo3/sysext/adminpanel/Classes/Utility/MemoryUtility.php b/typo3/sysext/adminpanel/Classes/Utility/MemoryUtility.php
new file mode 100644 (file)
index 0000000..64d32e1
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+declare(strict_types = 1);
+
+namespace TYPO3\CMS\Adminpanel\Utility;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Helper class to keep track of memory consumption in loggers to reduce risk of running out of memory
+ *
+ * @internal
+ */
+class MemoryUtility
+{
+    private const MINIMAL_PERCENT_OF_FREE_MEMORY = 0.30;
+
+    /**
+     * Checks memory usage used in current process - this is no guarantee for not running out of memory
+     * but should prevent memory exhaustion due to the admin panel in most cases.
+     * The loggers will stop logging once the amount of free memory falls below the threshold (see
+     * MINIMAL_PERCENT_OF_FREE_MEMORY const).
+     *
+     * @return bool
+     */
+    public static function isMemoryConsumptionTooHigh(): bool
+    {
+        $iniLimit = ini_get('memory_limit');
+        $memoryLimit = $iniLimit === '-1' ? -1 : GeneralUtility::getBytesFromSizeMeasurement($iniLimit);
+        $freeMemory = $memoryLimit - memory_get_usage(true);
+
+        return $memoryLimit > 0 && $freeMemory < (self::MINIMAL_PERCENT_OF_FREE_MEMORY * $memoryLimit);
+    }
+}
diff --git a/typo3/sysext/adminpanel/Classes/Utility/StateUtility.php b/typo3/sysext/adminpanel/Classes/Utility/StateUtility.php
new file mode 100644 (file)
index 0000000..7cb3ba5
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+declare(strict_types = 1);
+
+namespace TYPO3\CMS\Adminpanel\Utility;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
+
+/**
+ * Helper class to check if the admin panel is enabled and active from outside
+ *
+ * Useful for initialization, checks in early hooks or middleware implementations
+ */
+class StateUtility
+{
+    /**
+     * Checks if adminPanel was configured to be shown
+     *
+     * @return bool
+     */
+    public static function isActivated(): bool
+    {
+        $beUser = $GLOBALS['BE_USER'] ?? null;
+        if ($beUser instanceof FrontendBackendUserAuthentication) {
+            $adminPanelConfiguration = $beUser->getTSConfig()['admPanel.'] ?? [];
+            // set legacy config
+            $beUser->extAdminConfig = $adminPanelConfiguration;
+            if (isset($adminPanelConfiguration['enable.'])) {
+                // only enabled if at least one module is enabled.
+                return (bool)array_filter($adminPanelConfiguration['enable.']);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if admin panel was activated
+     * (switched "on" via GUI)
+     *
+     * @return bool
+     */
+    public static function isOpen(): bool
+    {
+        $beUser = $GLOBALS['BE_USER'] ?? null;
+        return (bool)($beUser->uc['AdminPanel']['display_top'] ?? false);
+    }
+}
index ffa8eb1..24e22fb 100644 (file)
@@ -18,5 +18,13 @@ return [
                 'typo3/cms-frontend/backend-user-authentication',
             ]
         ],
+        'typo3/cms-adminpanel/sql-logging' => [
+            'target' => \TYPO3\CMS\Adminpanel\Middleware\SqlLogging::class,
+            'after' => [
+                'typo3/cms-frontend/tsfe',
+                'typo3/cms-frontend/authentication',
+                'typo3/cms-frontend/backend-user-authentication',
+            ]
+        ],
     ]
 ];
index 053299b..c1274d9 100644 (file)
                        <trans-unit id="settings.updateButtonLabel">
                                <source>Update Settings</source>
                        </trans-unit>
+                       <trans-unit id="button.close">
+                               <source>Close</source>
+                       </trans-unit>
+                       <trans-unit id="button.view">
+                               <source>View</source>
+                       </trans-unit>
                </body>
        </file>
 </xliff>
index 844ae93..c877637 100644 (file)
                        <trans-unit id="submodule.log.noEntries">
                                <source>No log entries.</source>
                        </trans-unit>
+                       <trans-unit id="submodule.queryInformation.label">
+                               <source>Query Information</source>
+                       </trans-unit>
+                       <trans-unit id="submodule.queryInformation.query">
+                               <source>Query</source>
+                       </trans-unit>
+                       <trans-unit id="submodule.queryInformation.queries">
+                               <source>Queries</source>
+                       </trans-unit>
+                       <trans-unit id="submodule.queryInformation.backtrace">
+                               <source>Backtrace</source>
+                       </trans-unit>
+                       <trans-unit id="submodule.queryInformation.doctrineDebug">
+                               <source>SQL Debug</source>
+                       </trans-unit>
+                       <trans-unit id="submodule.queryInformation.sqlQuery">
+                               <source>SQL Query</source>
+                       </trans-unit>
+                       <trans-unit id="submodule.queryInformation.queryCount">
+                               <source>Count</source>
+                       </trans-unit>
+                       <trans-unit id="submodule.queryInformation.queryTime">
+                               <source>Total Time [ms]</source>
+                       </trans-unit>
                </body>
        </file>
 </xliff>
diff --git a/typo3/sysext/adminpanel/Resources/Private/Templates/Modules/Debug/QueryInformation.html b/typo3/sysext/adminpanel/Resources/Private/Templates/Modules/Debug/QueryInformation.html
new file mode 100644 (file)
index 0000000..eca6384
--- /dev/null
@@ -0,0 +1,95 @@
+<html xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
+<div class="typo3-adminPanel-sql">
+    <div class="typo3-adminPanel-row typo3-adminPanel-row-nowrap typo3-adminPanel-sql-header">
+        <div class="typo3-adminPanel-col typo3-adminPanel-col-icon"></div>
+        <div class="typo3-adminPanel-col typo3-adminPanel-col-ellipsis typo3-adminPanel-col-auto">
+            <f:translate key="LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.queryInformation.sqlQuery"/>
+        </div>
+        <div class="typo3-adminPanel-col typo3-adminPanel-sql-col-count">
+            <f:translate key="LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.queryInformation.queryCount"/>
+        </div>
+        <div class="typo3-adminPanel-col typo3-adminPanel-sql-col-time">
+            <f:translate key="LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.queryInformation.queryTime"/>
+        </div>
+    </div>
+    <f:for each="{queries}" as="queryCollection" iteration="queryCollectionIteration">
+        <div class="typo3-adminPanel-row typo3-adminPanel-row-nowrap">
+            <div class="typo3-adminPanel-col typo3-adminPanel-col-icon">
+                <a href="#" title="{f:translate(key:'LLL:EXT:adminpanel/Resources/Private/Language/locallang.xlf:button.view')}" data-typo3-zoom-target="queryCollection-{queryCollectionIteration.index}">
+                    <core:icon identifier="actions-document-view" alternativeMarkupIdentifier="inline"/>
+                </a>
+            </div>
+            <div class="typo3-adminPanel-col typo3-adminPanel-col-ellipsis typo3-adminPanel-col-auto">
+                {queryCollection.sql}
+            </div>
+            <div class="typo3-adminPanel-col typo3-adminPanel-sql-col-count">{queryCollection.count}</div>
+            <div class="typo3-adminPanel-col typo3-adminPanel-sql-col-time">
+                <div class="typo3-adminPanel-progress">
+                    <div class="typo3-adminPanel-progress-bar" style="width:{queryCollection.time / totalTime * 100}%;"></div>
+                    <div class="typo3-adminPanel-progress-value"><f:format.number decimals="2">{queryCollection.time}</f:format.number></div>
+                </div>
+            </div>
+        </div>
+        <div class="typo3-adminPanel-zoom"  data-typo3-zoom-id="queryCollection-{queryCollectionIteration.index}">
+            <div class="typo3-adminPanel-zoom-header">
+                <button class="typo3-adminPanel-btn" data-typo3-zoom-close="true">
+                    {f:translate(key:'LLL:EXT:adminpanel/Resources/Private/Language/locallang.xlf:button.close')}
+                </button>
+            </div>
+            <div class="typo3-adminPanel-zoom-body">
+                <h3 class="typo3-adminPanel-headline">{f:translate(key:'LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.queryInformation.query')}</h3>
+                <pre class="typo3-adminPanel-sql-statement">{queryCollection.sql}</pre>
+                <f:if condition="{queryCollection.queries}">
+                    <f:if condition="{queryCollection.queries.0.backtrace}">
+                        <f:alias map="{query: queryCollection.queries.0}">
+                            <h3 class="typo3-adminPanel-headline">{f:translate(key:'LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.queryInformation.backtrace')}</h3>
+                            <div class="typo3-adminPanel-sql-backtrace">
+                                <f:for each="{query.backtrace}" as="value">
+                                    <div class="typo3-adminPanel-sql-backtrace-item">
+                                        <span class="typo3-adminPanel-sql-backtrace-item-function">
+                                            {value.class}{value.type}{value.function}
+                                        </span>
+                                        <span class="typo3-adminPanel-sql-backtrace-item-file">
+                                            {value.file}:{value.line}
+                                        </span>
+                                    </div>
+                                </f:for>
+                            </div>
+                        </f:alias>
+                    </f:if>
+                    <h3 class="typo3-adminPanel-headline">{f:translate(key:'LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.queryInformation.queries')}</h3>
+                    <div class="typo3-adminPanel-table-overflow">
+                        <table class="typo3-adminPanel-table typo3-adminPanel-table-debug">
+                            <thead>
+                                <tr>
+                                    <f:for each="{queryCollection.queries.0.params}" as="value" iteration="param">
+                                        <th scope="col">dcValue{param.cycle}</th>
+                                    </f:for>
+                                    <th scope="col" class="typo3-adminPanel-table-cell-space"></th>
+                                    <th scope="col" class="typo3-adminPanel-table-cell-time"><f:translate key="LLL:EXT:adminpanel/Resources/Private/Language/locallang_debug.xlf:submodule.queryInformation.queryTime"/></th>
+                                </tr>
+                            </thead>
+                            <tbody>
+                                <f:for each="{queryCollection.queries}" as="query" iteration="iterator">
+                                    <tr>
+                                        <f:for each="{query.params}" as="value">
+                                            <td class="typo3-adminPanel-table-cell-break">{value}</td>
+                                        </f:for>
+                                        <td scope="col" class="typo3-adminPanel-table-cell-space"></td>
+                                        <td class="typo3-adminPanel-table-cell-time">
+                                            <div class="typo3-adminPanel-progress">
+                                                <div class="typo3-adminPanel-progress-bar" style="width:{query.executionMS * 1000 / totalTime * 100}%;"></div>
+                                                <div class="typo3-adminPanel-progress-value"><f:format.number decimals="2">{query.executionMS * 1000}</f:format.number></div>
+                                            </div>
+                                        </td>
+                                    </tr>
+                                </f:for>
+                            </tbody>
+                        </table>
+                    </div>
+                </f:if>
+            </div>
+        </div>
+    </f:for>
+</div>
+</html>
index 70d1bd9..61ef80d 100644 (file)
@@ -10,4 +10,4 @@
  * 
  * The TYPO3 project - inspiring people to share!
  */
-@font-face{font-family:TYPO3FontAwesome;src:url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.eot?v=4.6.3);src:url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.eot?#iefix&v=4.6.3) format("embedded-opentype"),url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.woff2?v=4.6.3) format("woff2"),url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.woff?v=4.6.3) format("woff"),url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.ttf?v=4.6.3) format("truetype"),url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular) format("svg");font-weight:400;font-style:normal}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel{z-index:99990}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel *{background:0 0;border:0;box-shadow:none;box-sizing:border-box;vertical-align:baseline;letter-spacing:normal;width:auto;height:auto;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:12px;font-weight:400;white-space:normal;margin:0;padding:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel *,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel :active,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel :focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel :hover{outline:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon{position:relative;display:inline-block;overflow:hidden;white-space:nowrap;vertical-align:-22%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon img,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon svg{display:block;height:100%;width:100%;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon *{display:block;line-height:inherit}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-markup{position:absolute;display:block;text-align:center;top:0;left:0;right:0;bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-overlay{position:absolute;bottom:0;right:0;height:68.75%;width:68.75%;text-align:center}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-color{fill:currentColor}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-spin .icon-markup{-webkit-animation:icon-spin 2s infinite linear;animation:icon-spin 2s infinite linear}@-webkit-keyframes icon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes icon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-state-disabled .icon-markup{opacity:.5}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-small{height:16px;width:16px;line-height:16px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-small .icon-unify{line-height:16px;font-size:14px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-small .icon-overlay .icon-unify{line-height:10px;font-size:9px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-default{height:32px;width:32px;line-height:32px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-default .icon-unify{line-height:32px;font-size:28px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-default .icon-overlay .icon-unify{line-height:20px;font-size:18px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-large{height:48px;width:48px;line-height:48px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-large .icon-unify{line-height:48px;font-size:42px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-large .icon-overlay .icon-unify{line-height:30px;font-size:26px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-actions-edit-copy-release,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-actions-edit-cut-release,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-dialog-error,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-current,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-permission-denied{color:#c83c3c}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-sorting-light-asc,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-sorting-light-desc{color:#fff}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-sorting-asc,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-sorting-desc{color:#737373}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-dialog-information{color:#6daae0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-dialog-ok,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-permission-granted{color:#79a548}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-dialog-notification{color:#333}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-dialog-warning{color:#e8a33d}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-backdrop{z-index:99991;content:'';position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,.5)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-message{padding:20px;background-color:#fff;border-left:3px solid #cacaca;margin-bottom:1em;box-shadow:0 0 1px rgba(0,0,0,.15)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-message-info{border-left-color:#538bb3}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-bar{z-index:99992;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row;flex-flow:row;-webkit-box-pack:stretch;-webkit-justify-content:stretch;justify-content:stretch;position:fixed;bottom:0;left:auto;right:0;height:37px;background-color:#424242;color:#fff;border-bottom:1px solid #383838}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel.typo3-adminPanel-active .typo3-adminPanel-bar{left:0}@media (min-width:768px){#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-bar{right:20px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel.typo3-adminPanel-active .typo3-adminPanel-bar{left:20px}}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module{display:-webkit-box;display:-webkit-flex;display:flex;padding:0 10px;-webkit-box-align:center;-webkit-align-items:center;align-items:center;border-right:1px solid #383838}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-settings{margin-left:auto}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-logo+.typo3-adminPanel-module-toggle{border-left:none}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-settings .typo3-adminPanel-module-trigger-label{display:none}@media (min-width:768px){#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-settings .typo3-adminPanel-module-trigger-label{display:block}}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-settings,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-toggle{border-left:1px solid #383838;border-right:none}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-group{width:100%;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:flex}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;padding:0 10px;margin-left:-10px;margin-right:-10px;font-size:12px;color:#fff;height:36px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger>span{white-space:nowrap}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger>span+span{margin-left:4px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-active .typo3-adminPanel-module-trigger{background-color:#525252}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-module-trigger],#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-trigger]{cursor:pointer}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-module-trigger]:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-module-trigger]:hover,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-trigger]:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-trigger]:hover{background-color:#525252}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger-icon .icon-color{fill:currentColor}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger-icon .icon-actions-edit-hide{color:#629755}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger-icon .icon-actions-edit-unhide{color:#c83c3c}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger-information{display:none;opacity:.5}@media (min-width:768px){#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger-information{display:block}}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content{display:none;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;position:fixed;bottom:37px;top:20vh;left:20px;right:20px;background-color:#fafafa;color:#333;border-bottom:1px solid #383838}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-main{position:relative;padding:20px;height:100%;overflow:auto}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-main>:first-child{margin-top:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-main>:last-child{margin-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-active .typo3-adminPanel-content{display:-webkit-box;display:-webkit-flex;display:flex}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header{position:relative;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;height:37px;-webkit-flex-shrink:0;flex-shrink:0;color:#333;background-color:#eaeaea}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header:before{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background-color:#dadada}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-item{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;height:37px;padding:0 10px;border-right:1px solid #dadada;border-bottom:1px solid #dadada}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel a.typo3-adminPanel-content-header-item{color:inherit;text-decoration:none;position:relative}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel a.typo3-adminPanel-content-header-item:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel a.typo3-adminPanel-content-header-item:hover{background-color:#e1e1e1}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel a.typo3-adminPanel-content-header-item.typo3-adminPanel-content-header-item-active{background-color:#fafafa}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel a.typo3-adminPanel-content-header-item.typo3-adminPanel-content-header-item-active:before{content:'';position:absolute;bottom:-1px;left:0;right:0;height:1px;background-color:#fafafa}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-title{position:relative;color:#fff;background-color:#424242;border-right:1px solid #383838}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-title:before{content:'';position:absolute;bottom:-1px;left:0;right:0;height:1px;background-color:#5e5e5e}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-title>span+span{margin-left:4px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-close,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-settings{cursor:pointer;border-right:0;border-left:1px solid #dadada}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-nav{width:100%;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:flex}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings{-webkit-flex-shrink:0;flex-shrink:0;max-height:50%;overflow-y:auto;display:none;background-color:#fafafa;padding:20px;border-bottom:1px solid #dadada;box-shadow:0 0 1px rgba(0,0,0,.1)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings.typo3-adminPanel-content-settings-active{display:block}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings-group>:first-child,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings>:first-child{margin-top:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings-group>:last-child,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings>:last-child{margin-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings-group+.typo3-adminPanel-content-settings-group{margin-top:20px;padding-top:20px;border-top:1px solid rgba(0,0,0,.1)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-panes{position:absolute;top:0;bottom:0;left:0;right:0;display:-webkit-box;display:-webkit-flex;display:flex}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-panes-item{display:none;overflow:auto;height:100%;width:100%;padding:20px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-panes-item>:first-child{margin-top:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-panes-item>:last-child{margin-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-panes-item-active{display:block}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-row{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;padding:.25em 0;margin-left:-.75em;margin-right:-.75em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-row-header>*{font-weight:700}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col{padding:.25em .75em;word-break:break-all}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-1{-webkit-box-flex:0;-webkit-flex:0 0 8.33333333%;flex:0 0 8.33333333%;max-width:8.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-2{-webkit-box-flex:0;-webkit-flex:0 0 16.66666667%;flex:0 0 16.66666667%;max-width:16.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-3{-webkit-box-flex:0;-webkit-flex:0 0 25%;flex:0 0 25%;max-width:25%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-4{-webkit-box-flex:0;-webkit-flex:0 0 33.33333333%;flex:0 0 33.33333333%;max-width:33.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-5{-webkit-box-flex:0;-webkit-flex:0 0 41.66666667%;flex:0 0 41.66666667%;max-width:41.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-6{-webkit-box-flex:0;-webkit-flex:0 0 50%;flex:0 0 50%;max-width:50%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-7{-webkit-box-flex:0;-webkit-flex:0 0 58.33333333%;flex:0 0 58.33333333%;max-width:58.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-8{-webkit-box-flex:0;-webkit-flex:0 0 66.66666667%;flex:0 0 66.66666667%;max-width:66.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-9{-webkit-box-flex:0;-webkit-flex:0 0 75%;flex:0 0 75%;max-width:75%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-10{-webkit-box-flex:0;-webkit-flex:0 0 83.33333333%;flex:0 0 83.33333333%;max-width:83.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-11{-webkit-box-flex:0;-webkit-flex:0 0 91.66666667%;flex:0 0 91.66666667%;max-width:91.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-12{-webkit-box-flex:0;-webkit-flex:0 0 100%;flex:0 0 100%;max-width:100%}@media (max-width:991px){#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-1{-webkit-box-flex:0;-webkit-flex:0 0 8.33333333%;flex:0 0 8.33333333%;max-width:8.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-2{-webkit-box-flex:0;-webkit-flex:0 0 16.66666667%;flex:0 0 16.66666667%;max-width:16.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-3{-webkit-box-flex:0;-webkit-flex:0 0 25%;flex:0 0 25%;max-width:25%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-4{-webkit-box-flex:0;-webkit-flex:0 0 33.33333333%;flex:0 0 33.33333333%;max-width:33.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-5{-webkit-box-flex:0;-webkit-flex:0 0 41.66666667%;flex:0 0 41.66666667%;max-width:41.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-6{-webkit-box-flex:0;-webkit-flex:0 0 50%;flex:0 0 50%;max-width:50%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-7{-webkit-box-flex:0;-webkit-flex:0 0 58.33333333%;flex:0 0 58.33333333%;max-width:58.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-8{-webkit-box-flex:0;-webkit-flex:0 0 66.66666667%;flex:0 0 66.66666667%;max-width:66.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-9{-webkit-box-flex:0;-webkit-flex:0 0 75%;flex:0 0 75%;max-width:75%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-10{-webkit-box-flex:0;-webkit-flex:0 0 83.33333333%;flex:0 0 83.33333333%;max-width:83.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-11{-webkit-box-flex:0;-webkit-flex:0 0 91.66666667%;flex:0 0 91.66666667%;max-width:91.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-12{-webkit-box-flex:0;-webkit-flex:0 0 100%;flex:0 0 100%;max-width:100%}}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-headline{font-weight:700;margin-top:1.5em;margin-bottom:.75em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel h1.typo3-adminPanel-headline{font-weight:400;font-size:1.75em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel h2.typo3-adminPanel-headline{font-weight:400;font-size:1.5em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel h3.typo3-adminPanel-headline{font-size:1.35em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel h4.typo3-adminPanel-headline{font-size:1.25em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-overflow{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #e0e0e0;box-shadow:0 0 1px rgba(0,0,0,.15)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-overflow .typo3-adminPanel-table{border:none}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table{width:100%;max-width:100%;background-color:#fff;display:table;border-collapse:separate;border-spacing:0;border:1px solid #e0e0e0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table thead tr{background-color:#e0e0e0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table thead td,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table thead th{border-top:none;font-family:Verdana,Arial,Helvetica,sans-serif}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table th{font-weight:700;text-align:inherit}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table th>span{font-weight:700}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table tr{font-family:inherit}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table td,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table th{padding:.75em;vertical-align:top;border-top:1px solid #dee2e6}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-debug tbody{font-family:monospace}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-debug tbody *{font-family:inherit}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-debug tbody td{word-wrap:break-word}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-cell-key{width:19%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-cell-nowrap{white-space:nowrap}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-group{display:-webkit-box;display:-webkit-flex;display:flex;margin:-5px;margin-bottom:1em;-webkit-flex-wrap:wrap;flex-wrap:wrap}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-group .typo3-adminPanel-card{margin:5px;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-shrink:0;flex-shrink:0;max-width:100%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card{background-color:#fff;margin-bottom:1em;box-shadow:0 0 1px rgba(0,0,0,.15)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-body>:first-child,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header>:first-child{margin-top:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-body>:last-child,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header>:last-child{margin-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;padding:20px;padding-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header-headline{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header-icon{position:relative;height:1em;width:1em;opacity:.75}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header-icon .icon{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header-text{padding-left:.5em;font-size:1.25em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-body{padding:20px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump{font-family:monospace;word-wrap:break-word;white-space:pre-wrap;position:relative;z-index:99999;word-break:break-all}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump-string{color:#75a75a}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump-string:after,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump-string:before{color:#bf6500;content:'"'}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump-float,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump-integer{color:#538bb3}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-group{display:block;margin:1.5em 0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-group-checkbox+.typo3-adminPanel-form-group-checkbox{margin-top:-.5em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox{padding-left:1.75em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-label{position:relative;cursor:pointer}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-label:before{position:absolute;top:0;left:-1.75em;display:block;width:1.25em;height:1.25em;pointer-events:none;content:'';-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dadada;border-radius:2px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-label:after{position:absolute;top:0;left:-1.75em;display:block;width:1.25em;height:1.25em;content:'';background-repeat:no-repeat;background-position:center center;background-size:50% 50%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-input{display:none}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-input:checked+.typo3-adminPanel-form-checkbox-label:before{background-color:#629755}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-input:checked+.typo3-adminPanel-form-checkbox-label:after{background-image:url("data:image/svg+xml;charset=utf8, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/></svg>")}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-select .typo3-adminPanel-form-select-label{margin-bottom:.5em;display:block}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-select .typo3-adminPanel-form-select-input{padding:.75em 3em .75em 1.25em;display:block;border-radius:2px;border:1px solid #dadada;background:#fff url("data:image/svg+xml;charset=utf8, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'><path fill='#333' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>") no-repeat right .75em center;background-size:8px 10px;-webkit-appearance:none;-moz-appearance:none;appearance:none}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-select .typo3-adminPanel-form-select-input:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-select .typo3-adminPanel-form-select-input:hover{border:1px solid #cacaca}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-datetime .typo3-adminPanel-form-datetime-label{margin-bottom:.5em;display:block}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-datetime .typo3-adminPanel-form-datetime-input-group{margin:-5px;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-datetime .typo3-adminPanel-form-datetime-input{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-shrink:0;flex-shrink:0;margin:5px;display:block;padding:.75em 1.25em;border-radius:2px;border:1px solid #dadada;background-color:#fff}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-datetime .typo3-adminPanel-form-datetime-input:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-datetime .typo3-adminPanel-form-datetime-input:hover{border:1px solid #cacaca}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn{position:relative;cursor:pointer;color:inherit;text-decoration:none;padding:.75em 1.25em;display:inline-block;background-color:rgba(0,0,0,.1);border:1px solid #dadada;border-radius:2px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn:hover{z-index:1;background-color:rgba(0,0,0,.15);border:1px solid #cacaca}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-primary{color:#fff;background-color:#538bb3;border:1px solid #417092}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-primary:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-primary:hover{background-color:#6597bb;border:1px solid #396381}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-group:after{content:'';display:table;clear:both}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-group .typo3-adminPanel-btn{border-radius:0;float:left}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-group .typo3-adminPanel-btn:first-child{border-radius:2px 0 0 2px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-group .typo3-adminPanel-btn:last-child{border-radius:0 2px 2px 0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-group .typo3-adminPanel-btn+.typo3-adminPanel-btn{margin-left:-1px}
\ No newline at end of file
+@font-face{font-family:TYPO3FontAwesome;src:url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.eot?v=4.6.3);src:url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.eot?#iefix&v=4.6.3) format("embedded-opentype"),url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.woff2?v=4.6.3) format("woff2"),url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.woff?v=4.6.3) format("woff"),url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.ttf?v=4.6.3) format("truetype"),url(../../../../../../typo3/sysext/backend/Resources/Public/Fonts/FontAwesome/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular) format("svg");font-weight:400;font-style:normal}body.typo3-adminPanel-noscroll{overflow:hidden}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel{z-index:99990}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel *{background:0 0;border:0;box-shadow:none;box-sizing:border-box;vertical-align:baseline;letter-spacing:normal;width:auto;height:auto;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:12px;font-weight:400;white-space:normal;margin:0;padding:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel *,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel :active,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel :focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel :hover{outline:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon{position:relative;display:inline-block;overflow:hidden;white-space:nowrap;vertical-align:-22%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon img,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon svg{display:block;height:100%;width:100%;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon *{display:block;line-height:inherit}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-markup{position:absolute;display:block;text-align:center;top:0;left:0;right:0;bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-overlay{position:absolute;bottom:0;right:0;height:68.75%;width:68.75%;text-align:center}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-color{fill:currentColor}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-spin .icon-markup{-webkit-animation:icon-spin 2s infinite linear;animation:icon-spin 2s infinite linear}@-webkit-keyframes icon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes icon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-state-disabled .icon-markup{opacity:.5}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-small{height:16px;width:16px;line-height:16px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-small .icon-unify{line-height:16px;font-size:14px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-small .icon-overlay .icon-unify{line-height:10px;font-size:9px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-default{height:32px;width:32px;line-height:32px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-default .icon-unify{line-height:32px;font-size:28px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-default .icon-overlay .icon-unify{line-height:20px;font-size:18px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-large{height:48px;width:48px;line-height:48px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-large .icon-unify{line-height:48px;font-size:42px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-size-large .icon-overlay .icon-unify{line-height:30px;font-size:26px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-actions-edit-copy-release,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-actions-edit-cut-release,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-dialog-error,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-current,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-permission-denied{color:#c83c3c}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-sorting-light-asc,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-sorting-light-desc{color:#fff}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-sorting-asc,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-sorting-desc{color:#737373}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-dialog-information{color:#6daae0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-dialog-ok,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-status-permission-granted{color:#79a548}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-dialog-notification{color:#333}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .icon-status-dialog-warning{color:#e8a33d}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-backdrop{z-index:99991;content:'';position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,.5)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-message{padding:20px;background-color:#fff;border-left:3px solid #cacaca;margin-bottom:1em;box-shadow:0 0 1px rgba(0,0,0,.15)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-message-info{border-left-color:#538bb3}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-bar{z-index:99992;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row;flex-flow:row;-webkit-box-pack:stretch;-webkit-justify-content:stretch;justify-content:stretch;position:fixed;bottom:0;left:auto;right:0;height:37px;background-color:#424242;color:#fff;border-bottom:1px solid #383838}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel.typo3-adminPanel-active .typo3-adminPanel-bar{left:0}@media (min-width:768px){#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-bar{right:20px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel.typo3-adminPanel-active .typo3-adminPanel-bar{left:20px}}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module{display:-webkit-box;display:-webkit-flex;display:flex;padding:0 10px;-webkit-box-align:center;-webkit-align-items:center;align-items:center;border-right:1px solid #383838}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-settings{margin-left:auto}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-logo+.typo3-adminPanel-module-toggle{border-left:none}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-settings .typo3-adminPanel-module-trigger-label{display:none}@media (min-width:768px){#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-settings .typo3-adminPanel-module-trigger-label{display:block}}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-settings,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-toggle{border-left:1px solid #383838;border-right:none}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-group{width:100%;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:flex}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;padding:0 10px;margin-left:-10px;margin-right:-10px;font-size:12px;color:#fff;height:36px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger>span{white-space:nowrap}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger>span+span{margin-left:4px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-active .typo3-adminPanel-module-trigger{background-color:#525252}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-module-trigger],#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-trigger]{cursor:pointer}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-module-trigger]:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-module-trigger]:hover,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-trigger]:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel [data-typo3-role=typo3-adminPanel-trigger]:hover{background-color:#525252}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger-icon .icon-color{fill:currentColor}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger-icon .icon-actions-edit-hide{color:#629755}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger-icon .icon-actions-edit-unhide{color:#c83c3c}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger-information{display:none;opacity:.5}@media (min-width:768px){#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-trigger-information{display:block}}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content{display:none;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;position:fixed;bottom:37px;top:20vh;left:20px;right:20px;background-color:#fafafa;color:#333;border-bottom:1px solid #383838}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-main{position:relative;padding:20px;height:100%;overflow:auto}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-main>:first-child{margin-top:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-main>:last-child{margin-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-module-active .typo3-adminPanel-content{display:-webkit-box;display:-webkit-flex;display:flex}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header{position:relative;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;height:37px;-webkit-flex-shrink:0;flex-shrink:0;color:#333;background-color:#eaeaea}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header:before{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background-color:#dadada}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-item{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;height:37px;padding:0 10px;border-right:1px solid #dadada;border-bottom:1px solid #dadada}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel a.typo3-adminPanel-content-header-item{color:inherit;text-decoration:none;position:relative}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel a.typo3-adminPanel-content-header-item:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel a.typo3-adminPanel-content-header-item:hover{background-color:#e1e1e1}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel a.typo3-adminPanel-content-header-item.typo3-adminPanel-content-header-item-active{background-color:#fafafa}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel a.typo3-adminPanel-content-header-item.typo3-adminPanel-content-header-item-active:before{content:'';position:absolute;bottom:-1px;left:0;right:0;height:1px;background-color:#fafafa}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-title{position:relative;color:#fff;background-color:#424242;border-right:1px solid #383838}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-title:before{content:'';position:absolute;bottom:-1px;left:0;right:0;height:1px;background-color:#5e5e5e}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-title>span+span{margin-left:4px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-close,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-header-settings{cursor:pointer;border-right:0;border-left:1px solid #dadada}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-nav{width:100%;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:flex}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings{-webkit-flex-shrink:0;flex-shrink:0;max-height:50%;overflow-y:auto;display:none;background-color:#fafafa;padding:20px;border-bottom:1px solid #dadada;box-shadow:0 0 1px rgba(0,0,0,.1)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings.typo3-adminPanel-content-settings-active{display:block}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings-group>:first-child,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings>:first-child{margin-top:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings-group>:last-child,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings>:last-child{margin-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-settings-group+.typo3-adminPanel-content-settings-group{margin-top:20px;padding-top:20px;border-top:1px solid rgba(0,0,0,.1)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-panes{position:absolute;top:0;bottom:0;left:0;right:0;display:-webkit-box;display:-webkit-flex;display:flex}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-panes-item{display:none;overflow:auto;height:100%;width:100%;padding:20px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-panes-item>:first-child{margin-top:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-panes-item>:last-child{margin-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-content-panes-item-active{display:block}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-row{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;padding:8px 0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-row-nowrap{-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-row-header>*{font-weight:700}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col{padding:0 10px;word-break:break-all}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-icon{width:34px;-webkit-flex-shrink:0;flex-shrink:0;-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-auto{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-1{-webkit-box-flex:0;-webkit-flex:0 0 8.33333333%;flex:0 0 8.33333333%;max-width:8.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-2{-webkit-box-flex:0;-webkit-flex:0 0 16.66666667%;flex:0 0 16.66666667%;max-width:16.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-3{-webkit-box-flex:0;-webkit-flex:0 0 25%;flex:0 0 25%;max-width:25%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-4{-webkit-box-flex:0;-webkit-flex:0 0 33.33333333%;flex:0 0 33.33333333%;max-width:33.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-5{-webkit-box-flex:0;-webkit-flex:0 0 41.66666667%;flex:0 0 41.66666667%;max-width:41.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-6{-webkit-box-flex:0;-webkit-flex:0 0 50%;flex:0 0 50%;max-width:50%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-7{-webkit-box-flex:0;-webkit-flex:0 0 58.33333333%;flex:0 0 58.33333333%;max-width:58.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-8{-webkit-box-flex:0;-webkit-flex:0 0 66.66666667%;flex:0 0 66.66666667%;max-width:66.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-9{-webkit-box-flex:0;-webkit-flex:0 0 75%;flex:0 0 75%;max-width:75%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-10{-webkit-box-flex:0;-webkit-flex:0 0 83.33333333%;flex:0 0 83.33333333%;max-width:83.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-11{-webkit-box-flex:0;-webkit-flex:0 0 91.66666667%;flex:0 0 91.66666667%;max-width:91.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-12{-webkit-box-flex:0;-webkit-flex:0 0 100%;flex:0 0 100%;max-width:100%}@media (max-width:991px){#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-1{-webkit-box-flex:0;-webkit-flex:0 0 8.33333333%;flex:0 0 8.33333333%;max-width:8.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-2{-webkit-box-flex:0;-webkit-flex:0 0 16.66666667%;flex:0 0 16.66666667%;max-width:16.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-3{-webkit-box-flex:0;-webkit-flex:0 0 25%;flex:0 0 25%;max-width:25%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-4{-webkit-box-flex:0;-webkit-flex:0 0 33.33333333%;flex:0 0 33.33333333%;max-width:33.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-5{-webkit-box-flex:0;-webkit-flex:0 0 41.66666667%;flex:0 0 41.66666667%;max-width:41.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-6{-webkit-box-flex:0;-webkit-flex:0 0 50%;flex:0 0 50%;max-width:50%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-7{-webkit-box-flex:0;-webkit-flex:0 0 58.33333333%;flex:0 0 58.33333333%;max-width:58.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-8{-webkit-box-flex:0;-webkit-flex:0 0 66.66666667%;flex:0 0 66.66666667%;max-width:66.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-9{-webkit-box-flex:0;-webkit-flex:0 0 75%;flex:0 0 75%;max-width:75%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-10{-webkit-box-flex:0;-webkit-flex:0 0 83.33333333%;flex:0 0 83.33333333%;max-width:83.33333333%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-11{-webkit-box-flex:0;-webkit-flex:0 0 91.66666667%;flex:0 0 91.66666667%;max-width:91.66666667%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-col-sm-12{-webkit-box-flex:0;-webkit-flex:0 0 100%;flex:0 0 100%;max-width:100%}}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-headline{font-weight:700;margin-top:1.5em;margin-bottom:.75em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel h1.typo3-adminPanel-headline{font-weight:400;font-size:1.75em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel h2.typo3-adminPanel-headline{font-weight:400;font-size:1.5em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel h3.typo3-adminPanel-headline{font-size:1.35em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel h4.typo3-adminPanel-headline{font-size:1.25em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-overflow{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #e0e0e0;box-shadow:0 0 1px rgba(0,0,0,.15)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-overflow .typo3-adminPanel-table{border:none}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table{width:100%;max-width:100%;background-color:#fff;display:table;border-collapse:separate;border-spacing:0;border:1px solid #e0e0e0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table thead tr{background-color:#e0e0e0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table thead td,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table thead th{border-top:none;font-family:Verdana,Arial,Helvetica,sans-serif}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table th{font-weight:700;text-align:inherit}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table th>span{font-weight:700}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table tr{font-family:inherit}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table td,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table th{padding:.75em;vertical-align:top;border-top:1px solid #dee2e6}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-debug tbody{font-family:monospace}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-debug tbody *{font-family:inherit}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-debug tbody td{word-wrap:break-word}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-cell-icon{width:34px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-cell-icon{width:34px;min-width:34px;white-space:nowrap}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-cell-time{width:250px;min-width:250px;white-space:nowrap}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-cell-key{width:19%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-cell-space{width:100%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-cell-break{word-wrap:break-word}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-table-cell-nowrap{white-space:nowrap}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-group{display:-webkit-box;display:-webkit-flex;display:flex;margin:-5px;margin-bottom:1em;-webkit-flex-wrap:wrap;flex-wrap:wrap}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-group .typo3-adminPanel-card{margin:5px;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-shrink:0;flex-shrink:0;max-width:100%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card{background-color:#fff;margin-bottom:1em;box-shadow:0 0 1px rgba(0,0,0,.15)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-body>:first-child,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header>:first-child{margin-top:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-body>:last-child,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header>:last-child{margin-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center;padding:20px;padding-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header-headline{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header-icon{position:relative;height:1em;width:1em;opacity:.75}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header-icon .icon{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-header-text{padding-left:.5em;font-size:1.25em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-card-body{padding:20px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump{font-family:monospace;word-wrap:break-word;white-space:pre-wrap;position:relative;z-index:99999;word-break:break-all}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump-string{color:#75a75a}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump-string:after,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump-string:before{color:#bf6500;content:'"'}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump-float,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-dump-integer{color:#538bb3}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-group{display:block;margin:1.5em 0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-group-checkbox+.typo3-adminPanel-form-group-checkbox{margin-top:-.5em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox{padding-left:1.75em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-label{position:relative;cursor:pointer}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-label:before{position:absolute;top:0;left:-1.75em;display:block;width:1.25em;height:1.25em;pointer-events:none;content:'';-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dadada;border-radius:2px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-label:after{position:absolute;top:0;left:-1.75em;display:block;width:1.25em;height:1.25em;content:'';background-repeat:no-repeat;background-position:center center;background-size:50% 50%}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-input{display:none}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-input:checked+.typo3-adminPanel-form-checkbox-label:before{background-color:#629755}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-checkbox-input:checked+.typo3-adminPanel-form-checkbox-label:after{background-image:url("data:image/svg+xml;charset=utf8, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/></svg>")}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-select .typo3-adminPanel-form-select-label{margin-bottom:.5em;display:block}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-select .typo3-adminPanel-form-select-input{padding:.75em 3em .75em 1.25em;display:block;border-radius:2px;border:1px solid #dadada;background:#fff url("data:image/svg+xml;charset=utf8, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'><path fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>") no-repeat right .75em center;background-size:8px 10px;-webkit-appearance:none;-moz-appearance:none;appearance:none}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-select .typo3-adminPanel-form-select-input:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-select .typo3-adminPanel-form-select-input:hover{border:1px solid #cacaca}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-datetime .typo3-adminPanel-form-datetime-label{margin-bottom:.5em;display:block}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-datetime .typo3-adminPanel-form-datetime-input-group{margin:-5px;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-datetime .typo3-adminPanel-form-datetime-input{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-shrink:0;flex-shrink:0;margin:5px;display:block;padding:.75em 1.25em;border-radius:2px;border:1px solid #dadada;background-color:#fff}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-datetime .typo3-adminPanel-form-datetime-input:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-form-datetime .typo3-adminPanel-form-datetime-input:hover{border:1px solid #cacaca}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn{position:relative;cursor:pointer;color:inherit;text-decoration:none;padding:.75em 1.25em;display:inline-block;background-color:rgba(0,0,0,.1);border:1px solid #dadada;border-radius:2px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn:hover{z-index:1;background-color:rgba(0,0,0,.15);border:1px solid #cacaca}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-primary{color:#fff;background-color:#538bb3;border:1px solid #417092}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-primary:focus,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-primary:hover{background-color:#6597bb;border:1px solid #396381}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-group:after{content:'';display:table;clear:both}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-group .typo3-adminPanel-btn{border-radius:0;float:left}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-group .typo3-adminPanel-btn:first-child{border-radius:2px 0 0 2px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-group .typo3-adminPanel-btn:last-child{border-radius:0 2px 2px 0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-btn-group .typo3-adminPanel-btn+.typo3-adminPanel-btn{margin-left:-1px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-progress{position:relative;height:1.5em}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-progress-bar{position:absolute;top:0;left:0;height:100%;width:100%;background-color:#333}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-progress-bar-green{background-color:#629755}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-progress-value{text-align:right}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-zoom{position:absolute;z-index:99994;background-color:#fafafa;top:0;left:0;width:100%;height:100%;display:none;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-zoom-show{display:-webkit-box;display:-webkit-flex;display:flex}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-zoom-header{padding:20px;border-bottom:1px solid #dadada}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-zoom-body{padding:20px;height:100%;overflow:auto}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-zoom-body>:first-child{margin-top:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-zoom-body>:last-child{margin-bottom:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-col-count{text-align:right;width:90px;-webkit-flex-shrink:0;flex-shrink:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-col-time{width:250px;-webkit-flex-shrink:0;flex-shrink:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-header{color:#737373;border-bottom:1px solid #d7d7d7}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-queries-header{color:#737373;border-bottom:1px solid #d7d7d7}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-query-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel>.typo3-adminPanel-sql-panel{border-bottom:1px dashed #d7d7d7}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel>.typo3-adminPanel-sql-panel:nth-child(2n+1){background:#f5f5f5}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-bar{display:-webkit-box;display:-webkit-flex;display:flex;height:auto;overflow:hidden;font-size:11px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-bar .typo3-adminPanel-bar-value{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center;color:#1e1e1e;text-align:left;white-space:nowrap;background-color:#fff;-webkit-transition:all .5s ease;transition:all .5s ease;width:0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-statement{margin:1em 0;padding:.75em 1em;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;background:#f2f2f2;font-size:11px}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-backtrace{margin:1em 0}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-backtrace-item{margin:1px 0;padding:.75em 1em;background-color:#f2f2f2;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;word-break:break-word}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-backtrace-item-file,#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-backtrace-item-function{display:block}#TSFE_ADMIN_PANEL_FORM.typo3-kidjls9dksoje.typo3-adminPanel .typo3-adminPanel-sql-backtrace-item-file{opacity:.5;font-size:.8em}
\ No newline at end of file
index e62f974..8242817 100644 (file)
@@ -22,6 +22,8 @@ function toggleAdminPanelState() {
 function renderBackdrop() {
   var adminPanel = document.querySelector('#TSFE_ADMIN_PANEL_FORM');
   var backdrop = document.createElement('div');
+  var body = document.querySelector('body');
+  body.classList.add('typo3-adminPanel-noscroll');
   backdrop.classList.add('typo3-adminPanel-backdrop');
   adminPanel.appendChild(backdrop);
   addBackdropListener();
@@ -29,6 +31,8 @@ function renderBackdrop() {
 
 function removeBackdrop() {
   var backdrop = document.querySelector('.typo3-adminPanel-backdrop');
+  var body = document.querySelector('body');
+  body.classList.remove('typo3-adminPanel-noscroll');
   if (backdrop !== null) {
     backdrop.remove();
   }
@@ -181,3 +185,35 @@ function initializeTabs() {
 }
 
 window.addEventListener('load', initializeAdminPanel, false);
+
+/**
+ * Zoom
+ */
+function initializeZooms() {
+  var zoomOpenTrigger = document.querySelectorAll('[data-typo3-zoom-target]');
+  var zoomCloseTrigger = document.querySelectorAll('[data-typo3-zoom-close]');
+
+  function openZoom(event) {
+    event.preventDefault();
+    var trigger = event.currentTarget;
+    var targetId = trigger.getAttribute('data-typo3-zoom-target');
+    var target = document.querySelector('[data-typo3-zoom-id=' + targetId + ']');
+    target.classList.add('typo3-adminPanel-zoom-show');
+  }
+
+  for (var i = 0; i < zoomOpenTrigger.length; i++) {
+    zoomOpenTrigger[i].addEventListener("click", openZoom)
+  }
+
+  function closeZoom(event) {
+    event.preventDefault();
+    var trigger = event.currentTarget;
+    var target = trigger.closest('[data-typo3-zoom-id]');
+    target.classList.remove('typo3-adminPanel-zoom-show');
+  }
+
+  for (var i = 0; i < zoomCloseTrigger.length; i++) {
+    zoomCloseTrigger[i].addEventListener("click", closeZoom)
+  }
+}
+window.addEventListener('load', initializeZooms, false);
diff --git a/typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php b/typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php
new file mode 100644 (file)
index 0000000..622464b
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+declare(strict_types = 1);
+
+namespace TYPO3\CMS\Adminpanel\Tests\Unit\Utility;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Adminpanel\Utility\StateUtility;
+use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
+
+class StateUtilityTest extends UnitTestCase
+{
+
+    /**
+     * @test
+     */
+    public function isEnabledReturnsFalseIfNoBackendUserExists(): void
+    {
+        $GLOBALS['BE_USER'] = false;
+        $isEnabled = StateUtility::isActivated();
+        self::assertFalse($isEnabled);
+    }
+
+    /**
+     * @test
+     */
+    public function isEnabledReturnsFalseIfNoBackendUserInFrontendContextIsLoggedIn(): void
+    {
+        $GLOBALS['BE_USER'] = $this->prophesize(BackendUserAuthentication::class)->reveal();
+        $isEnabled = StateUtility::isActivated();
+        self::assertFalse($isEnabled);
+    }
+
+    public function tsConfigEnabledDataProvider(): array
+    {
+        return [
+            '1 module enabled' => [
+                [
+                    'admPanel.' => [
+                        'enable.' => [
+                            'preview' => 1
+                        ]
+                    ]
+                ]
+            ],
+            'all modules enabled' => [
+                [
+                    'admPanel.' => [
+                        'enable.' => [
+                            'all' => 1
+                        ]
+                    ]
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider tsConfigEnabledDataProvider
+     * @param array $tsConfig
+     */
+    public function isEnabledReturnsTrueIfAtLeastOneModuleIsEnabled(array $tsConfig): void
+    {
+        $beUserProphecy = $this->prophesize(FrontendBackendUserAuthentication::class);
+        $beUserProphecy->getTSConfig()->willReturn($tsConfig);
+        $GLOBALS['BE_USER'] = $beUserProphecy->reveal();
+        $isEnabled = StateUtility::isActivated();
+        self::assertTrue($isEnabled);
+    }
+
+    public function tsConfigDisabledDataProvider(): array
+    {
+        return [
+            'no config set' => [
+                []
+            ],
+            'all modules disabled' => [
+                'admPanel.' => [
+                    'enable.' => [
+                        'all' => 0
+                    ]
+                ]
+            ],
+            'single module configured, disabled' => [
+                'admPanel.' => [
+                    'enable.' => [
+                        'preview' => 0
+                    ]
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider tsConfigDisabledDataProvider
+     * @param array $tsConfig
+     */
+    public function isEnabledReturnsFalseIfNoModulesEnabled(array $tsConfig): void
+    {
+        $beUserProphecy = $this->prophesize(FrontendBackendUserAuthentication::class);
+        $beUserProphecy->getTSConfig()->willReturn($tsConfig);
+        $GLOBALS['BE_USER'] = $beUserProphecy->reveal();
+        $isEnabled = StateUtility::isActivated();
+        self::assertFalse($isEnabled);
+    }
+}
index 29d6ff7..4f0a0c7 100644 (file)
@@ -47,10 +47,13 @@ $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules'] = [
         'after' => ['info'],
         'submodules' => [
             'log' => [
-                'module' => \TYPO3\CMS\Adminpanel\Modules\Debug\Log::class
-            ]
-        ]
-    ]
+                'module' => \TYPO3\CMS\Adminpanel\Modules\Debug\Log::class,
+            ],
+            'queryInformation' => [
+                'module' => \TYPO3\CMS\Adminpanel\Modules\Debug\QueryInformation::class,
+            ],
+        ],
+    ],
 ];
 
 $GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['adminPanel_save']
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-84609-AddSQLLogModuleToAdminPanel.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-84609-AddSQLLogModuleToAdminPanel.rst
new file mode 100644 (file)
index 0000000..5f1b72f
--- /dev/null
@@ -0,0 +1,26 @@
+.. include:: ../../Includes.txt
+
+==================================================
+Feature: #84609 - Add SQL Log Module to AdminPanel
+==================================================
+
+See :issue:`84609`
+
+Description
+===========
+
+A new AdminPanel module has been introduced which shows SQL queries done to generate the current page.
+The module includes a short trace of the query so developers may locate where it was initiated as well as - in case
+it's a prepared statement - the placeholder values to enable checking variations of the query.
+
+Logging of queries is done via the Doctrine SQL Logger capabilities and enabled whenever the AdminPanel is activated /
+open in the frontend. Logging is only done for the currently logged in backend user, this way the overall performance
+impact is negligible.
+
+
+Impact
+======
+
+The AdminPanel has a new sub module "Query Information" in the "Debug" section.
+
+.. index:: Backend, Database, Frontend, ext:adminpanel